打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
sdl2.0示例
userphoto

2016.07.02

关注
    1. // gcc -o testDrone2_video testDrone2_video.c -lavcodec -lavformat -lswscale -lSDL2
    2. // g++ -o testDrone2_video testDrone2_video.c -lavcodec -lavformat -lswscale -lSDL2


    3. #ifdef __cplusplus
    4. extern "C" {
    5. #endif


    6. #include "libavcodec/avcodec.h"
    7. #include "libavformat/avformat.h"
    8. #include "libswscale/swscale.h"


    9. #ifdef __cplusplus
    10. }
    11. #endif


    12. #include "SDL2/SDL.h"


    13. int main(int argc, char* argv[]) {
    14.   
    15.   // 3.0. Initializes the video subsystem *must be done before anything other!!
    16.   if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    17.     fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
    18.     return -1;
    19.   }
    20.   
    21.   // prepare variables
    22.   // decoding
    23.   char              *drone_addr = "http://192.168.1.1:5555";
    24.   AVFormatContext   *pFormatCtx = NULL;
    25.   AVCodecContext    *pCodecCtx;
    26.   AVCodec           *pCodec;
    27.   AVPacket          packet;
    28.   AVFrame           *pFrame;
    29.   int               terminate, frameDecoded;
    30.   
    31.   // converting
    32.   AVFrame           *pFrame_YUV420P;
    33.   uint8_t           *buffer_YUV420P;
    34.   struct SwsContext *pConvertCtx_YUV420P;
    35.   
    36.   AVFrame           *pFrame_BGR24;
    37.   uint8_t           *buffer_BGR24;
    38.   struct SwsContext *pConvertCtx_BGR24;
    39.   
    40.   // displaying
    41.   SDL_Window        *pWindow1;
    42.   SDL_Renderer      *pRenderer1;
    43.   SDL_Texture       *bmpTex1;
    44.   uint8_t           *pixels1;
    45.   int               pitch1, size1;
    46.   
    47.   SDL_Window        *pWindow2;
    48.   SDL_Renderer      *pRenderer2;
    49.   SDL_Texture       *bmpTex2;
    50.   uint8_t           *pixels2;
    51.   int               pitch2, size2;
    52.   
    53.   // SDL event handling
    54.   SDL_Event         event;
    55.    
    56.   // 1.1 Register all formats and codecs
    57.   av_register_all();
    58.   avcodec_register_all();
    59.   avformat_network_init();
    60.   
    61.   // 1.2. Open video file
    62.   while(avformat_open_input(&pFormatCtx, drone_addr, NULL, NULL) != 0)
    63.     printf("Could not open the video file\nRetrying...\n");
    64.   
    65.   // 1.3. Retrieve stream information
    66.   avformat_find_stream_info(pFormatCtx, NULL);
    67.   // Dump information about file to standard output
    68.   av_dump_format(pFormatCtx, 0, drone_addr, 0);
    69.   
    70.   // 1.4. Get a pointer to the codec context for the video stream
    71.   // and find the decoder for the video stream
    72.   pCodecCtx = pFormatCtx->streams[0]->codec;
    73.   pCodec    = avcodec_find_decoder(pCodecCtx->codec_id);
    74.   
    75.   // 1.5. Open Codec
    76.   avcodec_open2(pCodecCtx, pCodec, NULL);
    77.   
    78.   
    79.   // 2.1.1. Prepare format conversion for diplaying with SDL
    80.   // Allocate an AVFrame structure
    81.   pFrame_YUV420P = avcodec_alloc_frame();
    82.   if(pFrame_YUV420P == NULL) {
    83.     fprintf(stderr, "Could not allocate pFrame_YUV420P\n");
    84.     return -1;
    85.   }
    86.   // Determine required buffer size and allocate buffer
    87.   buffer_YUV420P = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P,
    88.                                             pCodecCtx->width, pCodecCtx->height));  
    89.   // Assign buffer to image planes
    90.   avpicture_fill((AVPicture *)pFrame_YUV420P, buffer_YUV420P,
    91.                       PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
    92.   // format conversion context
    93.   pConvertCtx_YUV420P = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
    94.                                        pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P,
    95.                                        SWS_SPLINE, NULL, NULL, NULL);
    96.   
    97.   // 2.2.1. Prepare format conversion for OpenCV
    98.   // Allocate an AVFrame structure
    99.   pFrame_BGR24 = avcodec_alloc_frame();
    100.   if(pFrame_BGR24 == NULL) {
    101.     fprintf(stderr, "Could not allocate pFrame_YUV420P\n");
    102.     return -1;
    103.   }
    104.   // Determine required buffer size and allocate buffer
    105.   buffer_BGR24 = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_BGR24,
    106.                                             pCodecCtx->width, pCodecCtx->height));  
    107.   // Assign buffer to image planes
    108.   avpicture_fill((AVPicture *)pFrame_BGR24, buffer_BGR24,
    109.                       PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);
    110.   // format conversion context
    111.   pConvertCtx_BGR24 = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
    112.                                      pCodecCtx->width, pCodecCtx->height, PIX_FMT_BGR24,
    113.                                      SWS_SPLINE, NULL, NULL, NULL);
    114.   
    115.   // 3.1.1 prepare SDL for YUV
    116.   // allocate window, renderer, texture
    117.   pWindow1    = SDL_CreateWindow( "YUV", 0, 0, pCodecCtx->width, pCodecCtx->height, SDL_WINDOW_SHOWN);  
    118.   pRenderer1  = SDL_CreateRenderer(pWindow1, -1, SDL_RENDERER_ACCELERATED);
    119.   bmpTex1     = SDL_CreateTexture(pRenderer1, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);
    120.   size1       = pCodecCtx->width * pCodecCtx->height;
    121.   if(pWindow1==NULL | pRenderer1==NULL | bmpTex1==NULL) {
    122.     fprintf(stderr, "Could not open window1\n%s\n", SDL_GetError());
    123.     return -1;
    124.   }
    125.   
    126.   // 3.2.1 prepare SDL for BGR
    127.   // allocate window, renderer, texture
    128.   pWindow2    = SDL_CreateWindow( "BGR", pCodecCtx->width+5, 0, pCodecCtx->width, pCodecCtx->height, SDL_WINDOW_SHOWN);  
    129.   pRenderer2  = SDL_CreateRenderer(pWindow2, -1, SDL_RENDERER_ACCELERATED);
    130.   bmpTex2     = SDL_CreateTexture(pRenderer2, SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);
    131.   size2       = pCodecCtx->width * pCodecCtx->height * 3;
    132.   if(pWindow2==NULL | pRenderer2==NULL | bmpTex2==NULL) {
    133.     fprintf(stderr, "Could not open window2\n%s\n", SDL_GetError());
    134.     return -1;
    135.   }
    136.   
    137.   // 1.6. get video frames
    138.   pFrame = avcodec_alloc_frame();
    139.   terminate = 0;
    140.   while(!terminate) {
    141.     // read frame
    142.     if(av_read_frame(pFormatCtx, &packet)<0) {
    143.       fprintf(stderr, "Could not read frame!\n");
    144.       continue;
    145.     }
    146.    
    147.     // decode the frame
    148.     if(avcodec_decode_video2(pCodecCtx, pFrame, &frameDecoded, &packet) < 0) {
    149.       fprintf(stderr, "Could not decode frame!\n");
    150.       continue;
    151.     }
    152.    
    153.     if (frameDecoded) {
    154.       // 2.1.2. convert frame to YUV for Displaying
    155.         sws_scale(pConvertCtx_YUV420P, (const uint8_t * const*)pFrame->data, pFrame->linesize, 0,
    156.                   pCodecCtx->height,   pFrame_YUV420P->data, pFrame_YUV420P->linesize);
    157.       // 2.2.2. convert frame to GRAYSCALE [or BGR] for OpenCV
    158.         sws_scale(pConvertCtx_BGR24,   (const uint8_t * const*)pFrame->data, pFrame->linesize, 0,
    159.                   pCodecCtx->height,   pFrame_BGR24->data,   pFrame_BGR24->linesize);


    160.       
    161.       // 3.1.2. copy converted YUV to SDL 2.0 texture
    162.       SDL_LockTexture(bmpTex1, NULL, (void **)&pixels1, &pitch1);
    163.      memcpy(pixels1,             pFrame_YUV420P->data[0], size1  );
    164.      memcpy(pixels1 + size1,     pFrame_YUV420P->data[2], size1/4);
    165.    memcpy(pixels1 + size1*5/4, pFrame_YUV420P->data[1], size1/4);
    166.       SDL_UnlockTexture(bmpTex1);
    167.       SDL_UpdateTexture(bmpTex1, NULL, pixels1, pitch1);
    168.       // refresh screen
    169.       SDL_RenderClear(pRenderer1);
    170.       SDL_RenderCopy(pRenderer1, bmpTex1, NULL, NULL);
    171.       SDL_RenderPresent(pRenderer1);
    172.       
    173.       // 3.2.2. copy converted BGR to SDL 2.0 texture
    174.       SDL_LockTexture(bmpTex2, NULL, (void **)&pixels2, &pitch2);
    175.      memcpy(pixels2,             pFrame_BGR24->data[0], size2);
    176.       SDL_UnlockTexture(bmpTex2);
    177.       SDL_UpdateTexture(bmpTex2, NULL, pixels2, pitch2);
    178.       // refresh screen
    179.       SDL_RenderClear(pRenderer2);
    180.       SDL_RenderCopy(pRenderer2, bmpTex2, NULL, NULL);
    181.       SDL_RenderPresent(pRenderer2);
    182.     }
    183.    
    184.     SDL_PollEvent(&event);
    185.     switch (event.type) {
    186.       case SDL_KEYDOWN:
    187.         terminate = 1;
    188.         break;
    189.     }
    190.   }
    191.   
    192.   // release
    193.   // *note SDL objects have to be freed before closing avcodec.
    194.   // otherwise it causes segmentation fault for some reason.
    195.   SDL_DestroyTexture(bmpTex1);
    196.   SDL_DestroyTexture(bmpTex2);
    197.   
    198.   SDL_DestroyRenderer(pRenderer1);
    199.   SDL_DestroyRenderer(pRenderer2);
    200.   
    201.   SDL_DestroyWindow(pWindow1);
    202.   SDL_DestroyWindow(pWindow2);
    203.   
    204.   av_free(pFrame_YUV420P);
    205.   av_free(buffer_YUV420P);
    206.   sws_freeContext(pConvertCtx_YUV420P);
    207.   
    208.   av_free(pFrame_BGR24);
    209.   av_free(buffer_BGR24);
    210.   sws_freeContext(pConvertCtx_BGR24);
    211.   
    212.   av_free(pFrame);
    213.   avcodec_close(pCodecCtx); // <- before freeing this, all other objects, allocated after this, must be freed
    214.   avformat_close_input(&pFormatCtx);
    215.   
    216.   SDL_Quit();
    217.   
    218.   return 0;
    219.   
    220. }





本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)
最简单的基于FFmpeg的内存读写的例子
最简单的视音频播放示例7:SDL2播放RGB/YUV
学习FFmpeg API – 解码视频
libavformat/libavcodec学习(转) - 视频开发 - 在路上........
关于ffmpeg如何提取视频的关键帧的问题
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服