【ffmpeg学习】利用SDL2.0显示ffmpeg解码出来的数据

http://dranger.com/ffmpeg/tutorial02.html

按照里面的代码学习时发现作者使用的SDL1.2已过时,在SDL官网下了SDL2.0版本,

发现tutorial02内的SDL_SetVideoMode函数以及SDL_Overlay结构体已经弃用,

经过一番google及SDL DEMO的学习,整理出下面可用代码


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // tutorial02.c  
  2. // A pedagogical video player that will stream through every video frame as fast as it can.  
  3. //  
  4. // This tutorial was written by Stephen Dranger (dranger@gmail.com).  
  5. //  
  6. // Code based on FFplay, Copyright (c) 2003 Fabrice Bellard,  
  7. // and a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)  
  8. // Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1  
  9. //  
  10. // Use the Makefile to build all examples.  
  11. //  
  12. // Run using  
  13. // tutorial02 myvideofile.mpg  
  14. //  
  15. // to play the video stream on your screen.  
  16.   
  17.   
  18. #include <libavcodec/avcodec.h>  
  19. #include <libavformat/avformat.h>  
  20. #include <libswscale/swscale.h>  
  21.   
  22. #include <SDL2/SDL.h>  
  23. #include <SDL2/SDL_thread.h>  
  24.   
  25. #ifdef __MINGW32__  
  26. #undef main /* Prevents SDL from overriding main() */  
  27. #endif  
  28.   
  29. #include <stdio.h>  
  30.   
  31. int  
  32. randomInt(int min, int max)  
  33. {  
  34.     return min + rand() % (max - min + 1);  
  35. }  
  36.   
  37. int main(int argc, char *argv[]) {  
  38.     AVFormatContext *pFormatCtx = NULL;  
  39.     int             i, videoStream;  
  40.     AVCodecContext  *pCodecCtx = NULL;  
  41.     AVCodec         *pCodec = NULL;  
  42.     AVFrame         *pFrame = NULL;  
  43.     AVPacket        packet;  
  44.     int             frameFinished;  
  45.     //float           aspect_ratio;  
  46.       
  47.     AVDictionary    *optionsDict = NULL;  
  48.     struct SwsContext *sws_ctx = NULL;  
  49.     //SDL_CreateTexture();  
  50.     SDL_Texture    *bmp = NULL;  
  51.     SDL_Window     *screen = NULL;  
  52.     SDL_Rect        rect;  
  53.     SDL_Event       event;  
  54.       
  55.     if(argc < 2) {  
  56.         fprintf(stderr, "Usage: test <file>\n");  
  57.         exit(1);  
  58.     }  
  59.     // Register all formats and codecs  
  60.     av_register_all();  
  61.       
  62.     if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  
  63.         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());  
  64.         exit(1);  
  65.     }  
  66.       
  67.     // Open video file  
  68.     if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)  
  69.         return -1; // Couldn't open file  
  70.       
  71.     // Retrieve stream information  
  72.     if(avformat_find_stream_info(pFormatCtx, NULL)<0)  
  73.         return -1; // Couldn't find stream information  
  74.       
  75.     // Dump information about file onto standard error  
  76.     av_dump_format(pFormatCtx, 0, argv[1], 0);  
  77.       
  78.     // Find the first video stream  
  79.     videoStream=-1;  
  80.     for(i=0; i<pFormatCtx->nb_streams; i++)  
  81.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {  
  82.             videoStream=i;  
  83.             break;  
  84.         }  
  85.     if(videoStream==-1)  
  86.         return -1; // Didn't find a video stream  
  87.       
  88.     // Get a pointer to the codec context for the video stream  
  89.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;  
  90.       
  91.     // Find the decoder for the video stream  
  92.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);  
  93.     if(pCodec==NULL) {  
  94.         fprintf(stderr, "Unsupported codec!\n");  
  95.         return -1; // Codec not found  
  96.     }  
  97.       
  98.     // Open codec  
  99.     if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0)  
  100.         return -1; // Could not open codec  
  101.       
  102.     // Allocate video frame  
  103.     pFrame=avcodec_alloc_frame();  
  104.       
  105.     AVFrame* pFrameYUV = avcodec_alloc_frame();  
  106.     if( pFrameYUV == NULL )  
  107.         return -1;  
  108.       
  109.     // Make a screen to put our videe  
  110. //#ifndef __DARWIN__  
  111. //    screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);  
  112. //#else  
  113. //    screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0);  
  114. //#endif  
  115. //    SDL_WM_SetCaption("My Game Window", "game");  
  116. //    SDL_Surface *screen = SDL_SetVideoMode(640, 480, 0, SDL_FULLSCREEN | SDL_OPENGL);  
  117.     screen = SDL_CreateWindow("My Game Window",  
  118.                               SDL_WINDOWPOS_UNDEFINED,  
  119.                               SDL_WINDOWPOS_UNDEFINED,  
  120.                               pCodecCtx->width,  pCodecCtx->height,  
  121.                               SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);  
  122.     SDL_Renderer *renderer = SDL_CreateRenderer(screen, -1, 0);  
  123.       
  124.       
  125.     if(!screen) {  
  126.         fprintf(stderr, "SDL: could not set video mode - exiting\n");  
  127.         exit(1);  
  128.     }  
  129.      
  130.     // Allocate a place to put our YUV image on that screen  
  131. //    bmp = SDL_CreateYUVOverlay(pCodecCtx->width,  
  132. //                               pCodecCtx->height,  
  133. //                               SDL_YV12_OVERLAY,  
  134. //                               screen);  
  135.     bmp = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_YV12,SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);  
  136.     //SDL_SetTextureBlendMode(bmp,SDL_BLENDMODE_BLEND );  
  137.       
  138.     sws_ctx =  
  139.     sws_getContext  
  140.     (  
  141.      pCodecCtx->width,  
  142.      pCodecCtx->height,  
  143.      pCodecCtx->pix_fmt,  
  144.      pCodecCtx->width,  
  145.      pCodecCtx->height,  
  146.      PIX_FMT_YUV420P,  
  147.      SWS_BILINEAR,  
  148.      NULL,  
  149.      NULL,  
  150.      NULL  
  151.      );  
  152.       
  153.     int numBytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width,  
  154.                                   pCodecCtx->height);  
  155.     uint8_t* buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));  
  156.       
  157.     avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P,  
  158.                    pCodecCtx->width, pCodecCtx->height);  
  159.       
  160.     // Read frames and save first five frames to disk  
  161.     i=0;  
  162.       
  163.     rect.x = 0;  
  164.     rect.y = 0;  
  165.     rect.w = pCodecCtx->width;  
  166.     rect.h = pCodecCtx->height;  
  167.       
  168.     while(av_read_frame(pFormatCtx, &packet)>=0) {  
  169.         // Is this a packet from the video stream?  
  170.         if(packet.stream_index==videoStream) {  
  171.             // Decode video frame  
  172.             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,  
  173.                                   &packet);  
  174.               
  175.             // Did we get a video frame?  
  176.             if(frameFinished) {  
  177.   
  178.                 sws_scale  
  179.                 (  
  180.                  sws_ctx,  
  181.                  (uint8_t const * const *)pFrame->data,  
  182.                  pFrame->linesize,  
  183.                  0,  
  184.                  pCodecCtx->height,  
  185.                  pFrameYUV->data,  
  186.                  pFrameYUV->linesize  
  187.                  );  
  188.                 iPitch 计算yuv一行数据占的字节数  
  189.                 SDL_UpdateTexture( bmp, &rect, pFrameYUV->data[0], pFrameYUV->linesize[0] );  
  190.                 SDL_RenderClear( renderer );  
  191.                 SDL_RenderCopy( renderer, bmp, &rect, &rect );  
  192.                 SDL_RenderPresent( renderer );  
  193.             }  
  194.             SDL_Delay(50);  
  195.             //Sleep(500);  
  196.         }  
  197.           
  198.         // Free the packet that was allocated by av_read_frame  
  199.         av_free_packet(&packet);  
  200.         SDL_PollEvent(&event);  
  201.         switch(event.type) {  
  202.             case SDL_QUIT:  
  203.                 SDL_Quit();  
  204.                 exit(0);  
  205.                 break;  
  206.             default:  
  207.                 break;  
  208.         }  
  209.           
  210.     }  
  211.       
  212.     SDL_DestroyTexture(bmp);  
  213.       
  214.     // Free the YUV frame  
  215.     av_free(pFrame);  
  216.     av_free(pFrameYUV);  
  217.     // Close the codec  
  218.     avcodec_close(pCodecCtx);  
  219.       
  220.     // Close the video file  
  221.     avformat_close_input(&pFormatCtx);  
  222.       
  223.     return 0;  
  224. }  

参考网站:

http://blog.csdn.net/dawdo222/article/details/8692834

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值