FFMPEG+SDL简单播放器

FFMPEG+SDL教程

 

原来的FFMPEG+SDL教程版本太久,所以改写了FFMPEG-0.5简单播,这里只改写了tutorial1和tutorial2。

 

tutor1:

[c-sharp]  view plain copy
  1. // arm-linux-gcc -o tutor1 tutor1.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib   
  2. // -lavdevice -lavutil -lavformat -lavcodec -lswscale -lamrnb -lamrwb -lfaac -lfaad -lmp3lame  
  3.  
  4.  
  5. #include "libavformat/avformat.h"  
  6. #include "libavcodec/avcodec.h"  
  7. #include "libswscale/swscale.h"  
  8.  
  9. #include <stdio.h>  
  10.   
  11. int main(int argc,char *argv[])  
  12. {  
  13.     AVFormatContext *pFormatCtx;  
  14.     AVCodecContext  *pCodecCtx;  
  15.     AVCodec         *pCodec;  
  16.     AVFrame     *pFrame;  
  17.     AVFrame         *pFrameRGB;  
  18.     AVPacket        packet;  
  19.     unsigned int    i;  
  20.     int             videoStream;  
  21.     int             frameFinished;  
  22.     int         numBytes;  
  23.     uint8_t         *buffer;  
  24.   
  25.     void SaveFrame(AVFrame *pFrame,int width,int height,int iFrame);  
  26.       
  27.     if(argc<2)  
  28.     {  
  29.         printf("please privide a movie file/n");  
  30.         return -1;  
  31.     }  
  32.     // Register all format and codec      
  33.     av_register_all();  
  34.       
  35.     // Open video file  
  36.     if(av_open_input_file(&pFormatCtx,argv[1],NULL,0,NULL)!=0)  
  37.     {  
  38.         return -1;  
  39.     }  
  40.   
  41.     // Retrieve stream information  
  42.     if(av_find_stream_info(pFormatCtx)<0)  
  43.     {  
  44.         return -1;    
  45.     }  
  46.   
  47.     // Dump information about file onto standard error  
  48.     dump_format(pFormatCtx,0,argv[1],0);  
  49.   
  50.     // Find the first video stream  
  51.     videoStream=-1;  
  52.     for(i=0;i<pFormatCtx->nb_streams;i++)  
  53.     {  
  54.         if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)  
  55.         {  
  56.             videoStream=i;  
  57.             break;  
  58.         }  
  59.     }  
  60.     if(videoStream==-1)  
  61.     {  
  62.         return -1;  
  63.     }  
  64.   
  65.     // Get a pointer to the codec context for the video stream  
  66.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;  
  67.       
  68.     // Find the decoder for the video stream  
  69.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);  
  70.     if(pCodec==NULL)  
  71.     {  
  72.         fprintf(stderr,"unsupportde codec/n");  
  73.         return -1;  
  74.     }  
  75.   
  76.     // Open codec  
  77.     if(avcodec_open(pCodecCtx,pCodec)<0)  
  78.     {  
  79.         return -1;    
  80.     }  
  81.   
  82.     // Allocate video frame  
  83.     pFrame=avcodec_alloc_frame();  
  84.   
  85.     // Allocate an AVFrame structure  
  86.     pFrameRGB=avcodec_alloc_frame();  
  87.     if(pFrameRGB==NULL)  
  88.     {  
  89.         return -1;  
  90.     }  
  91.   
  92.     // Detemine required buffer size and allocate buffer  
  93.     numBytes=avpicture_get_size(PIX_FMT_RGB24,pCodecCtx->width,  
  94.                     pCodecCtx->height);  
  95.     buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));  
  96.   
  97.     /* Assign appropriate parts of buffer to image planes in pFrameRGB 
  98.        Note that pFrameRGB is an AVFrame,but AVFrame is a superset of       
  99.            AVPicture */  
  100.     avpicture_fill((AVPicture *)pFrameRGB,buffer,PIX_FMT_RGB24,  
  101.                pCodecCtx->width,pCodecCtx->height);  
  102.     static struct SwsContext *img_convert_ctx;  
  103.     if(img_convert_ctx==NULL)  
  104.     {  
  105.         img_convert_ctx=sws_getContext(pCodecCtx->width,pCodecCtx->height,  
  106.                            pCodecCtx->pix_fmt,  
  107.                            pCodecCtx->width,pCodecCtx->height,  
  108.                            PIX_FMT_RGB24,  
  109.                            SWS_BICUBIC,NULL,NULL,NULL);  
  110.         if(img_convert_ctx==NULL)  
  111.         {  
  112.             fprintf(stderr,"cannot initialize the convertion/n");  
  113.             return -1;  
  114.         }  
  115.     }  
  116.   
  117.     // Read frames and save first frames to disk  
  118.     i=0;  
  119.     while(av_read_frame(pFormatCtx,&packet)>=0)  
  120.     {  
  121.         // Is this a packet from the video stream  
  122.         if(packet.stream_index==videoStream)  
  123.         {  
  124.             // Decode video frame  
  125.             avcodec_decode_video(pCodecCtx,pFrame,&frameFinished,  
  126.             packet.data,packet.size);  
  127.               
  128.             // Did wo get a video frame  
  129.             if(frameFinished)  
  130.             {  
  131.                 // Convert the image form its native format to RGB  
  132.                 sws_scale(img_convert_ctx,pFrame->data,pFrame->linesize,  
  133.                       0,pCodecCtx->height,pFrameRGB->data,  
  134.                       pFrameRGB->linesize);  
  135.                   
  136.                 // Save the frame to disk  
  137.                 if(++i<=1)  
  138.                 {  
  139.                     //printf("the pFrame %d/n",pFrame->linesize[0]);  
  140.                     //printf("format %s",pCodecCtx->pix_fmt);  
  141.                     //printf("the linesize %d/n",pFrameRGB->linesize[0]);  
  142.                     SaveFrame(pFrameRGB,pCodecCtx->width,  
  143.                     pCodecCtx->height,i);  
  144.                 }  
  145.             }  
  146.         }  
  147.         // Free the packet that was allocated by av_read_frame  
  148.         av_free_packet(&packet);          
  149.     }  
  150.   
  151.     // Free swscontext  
  152.     // sws_freeContext(img_convert_ctx);  
  153.   
  154.     // Free the RGB image  
  155.     av_free(buffer);  
  156.     av_free(pFrameRGB);  
  157.   
  158.     // Free the YUV frame  
  159.     av_free(pFrame);  
  160.   
  161.     // Close the codec  
  162.     avcodec_close(pCodecCtx);  
  163.       
  164.     // Close the codec  
  165.     av_close_input_file(pFormatCtx);  
  166.   
  167.     return 0;  
  168. }  
  169.   
  170. void SaveFrame(AVFrame *pFrame,int width,int height,int iFrame)  
  171. {  
  172.     FILE *pFile;  
  173.     char szFilename[32];  
  174.     int y;  
  175.   
  176.     // Open file  
  177.     sprintf(szFilename,"frame%d.ppm",iFrame);  
  178.     pFile=fopen(szFilename,"wb");  
  179.     if(pFile==NULL)  
  180.         return;  
  181.       
  182.     // Write header  
  183.     fprintf(pFile,"P6/n%d %d/n255/n",width,height);  
  184.   
  185.     // Write pixel data  
  186.     for(y=0;y<height;y++)  
  187.     {  
  188.         fwrite(pFrame->data[0]+y*pFrame->linesize[0],1,width*3,pFile);  
  189.     }  
  190.       
  191.     // Close file  
  192.     fclose(pFile);  
  193. }  

 

tutor2:

[c-sharp]  view plain copy
  1. // arm-linux-gcc -o tutor2 tutor2.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavdevice -lavutil -lavformat -lavcodec -lswscale -lamrnb -lamrwb -lfaac -lfaad -lmp3lame -lSDL  
  2.  
  3. #include "libavformat/avformat.h"  
  4. #include "libavcodec/avcodec.h"  
  5. #include "libswscale/swscale.h"  
  6.  
  7. #include "/usr/local/sdl/include/SDL/SDL.h"  
  8.  
  9. #include <stdio.h>  
  10. #include <string.h>  
  11.   
  12. int main(int argc,char *argv[])  
  13. {  
  14.     AVFormatContext *pFormatCtx;  
  15.     int i,videoStream;  
  16.     AVCodecContext *pCodecCtx;  
  17.     AVCodec *pCodec;  
  18.     AVFrame *pFrame;  
  19.     AVPacket packet;  
  20.     int frameFinished;  
  21.       
  22.     SDL_Surface *screen;      
  23.     SDL_Overlay *bmp;  
  24.     SDL_Rect rect;  
  25.     SDL_Event event;  
  26.   
  27.     if(argc<2)  
  28.     {  
  29.         printf("please input a movie file/n");  
  30.         return -1;  
  31.     }  
  32.       
  33.     av_register_all();  
  34.   
  35.     if(av_open_input_file(&pFormatCtx,argv[1],NULL,0,NULL)!=0)  
  36.         return -1;  
  37.   
  38.     if(av_find_stream_info(pFormatCtx)<0)  
  39.         return -1;  
  40.   
  41.     dump_format(pFormatCtx,0,argv[1],0);  
  42.   
  43.     videoStream=-1;  
  44.     for(i=0;i<pFormatCtx->nb_streams;i++)  
  45.     {  
  46.         if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)  
  47.         {  
  48.             videoStream=i;  
  49.         }  
  50.     }  
  51.     if(videoStream==-1)  
  52.         return -1;  
  53.   
  54.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;  
  55.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);  
  56.     if(pCodec==NULL)  
  57.     {  
  58.         fprintf(stderr,"unsupported codec/n");  
  59.         return -1;  
  60.     }  
  61.       
  62.     if(avcodec_open(pCodecCtx,pCodec)<0)  
  63.         return -1;  
  64.       
  65.     pFrame=avcodec_alloc_frame();  
  66.   
  67.     if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))  
  68.     {  
  69.         fprintf(stderr,"can not initialize SDL %s/n",SDL_GetError());  
  70.         return -1;  
  71.     }  
  72.   
  73.     // setvideomode with your actual screen pixel  
  74.     screen=SDL_SetVideoMode(240,320,0,0);     
  75.     //screen=SDL_SetVideoMode(pCodecCtx->width,pCodecCtx->height,0,0);  
  76.     if(!screen)  
  77.     {  
  78.         fprintf(stderr,"can not set video mode/n");  
  79.         return -1;  
  80.     }  
  81.       
  82.     bmp=SDL_CreateYUVOverlay(pCodecCtx->width,pCodecCtx->height,  
  83.         SDL_YV12_OVERLAY,screen);  
  84.   
  85.     static struct SwsContext *img_convert_ctx;  
  86.     if(img_convert_ctx==NULL)  
  87.     {  
  88.         // As we only generate a YUV420P picture,   
  89.         // we must convert it to the codec pixel format if needed         
  90.         img_convert_ctx=sws_getContext(pCodecCtx->width,pCodecCtx->height,  
  91.                                pCodecCtx->pix_fmt,  
  92.                                pCodecCtx->width,pCodecCtx->height,  
  93.                                PIX_FMT_YUV420P,  
  94.                 SWS_BICUBIC,NULL,NULL,NULL);  
  95.         if(img_convert_ctx==NULL)  
  96.         {  
  97.             fprintf(stderr,"can not initialize convert context/n");  
  98.             return -1;  
  99.         }  
  100.     }  
  101.   
  102.     while(av_read_frame(pFormatCtx,&packet)>=0)  
  103.     {  
  104.         if(packet.stream_index==videoStream)  
  105.         {  
  106.             avcodec_decode_video(pCodecCtx,pFrame,&frameFinished,  
  107.                           packet.data,packet.size);  
  108.             if(frameFinished)  
  109.             {  
  110.                 SDL_LockYUVOverlay(bmp);  
  111.                 AVPicture pict;  
  112.                 pict.data[0]=bmp->pixels[0];  
  113.                 pict.data[1]=bmp->pixels[2];  
  114.                 pict.data[2]=bmp->pixels[1];  
  115.   
  116.                 pict.linesize[0]=bmp->pitches[0];  
  117.                 pict.linesize[1]=bmp->pitches[2];  
  118.                 pict.linesize[2]=bmp->pitches[1];  
  119.   
  120.                 sws_scale(img_convert_ctx,pFrame->data,pFrame->linesize,  
  121.                       0,pCodecCtx->height,pict.data,pict.linesize);  
  122.                 SDL_UnlockYUVOverlay(bmp);  
  123.                 rect.x=0;  
  124.                 rect.y=0;  
  125.                 rect.w=pCodecCtx->width;  
  126.                 rect.h=pCodecCtx->height;  
  127.                 SDL_DisplayYUVOverlay(bmp,&rect);  
  128.                 // Sleep(60);  
  129.             }  
  130.         }  
  131.   
  132.         av_free_packet(&packet);  
  133.   
  134.         SDL_PollEvent(&event);  
  135.         switch(event.type)  
  136.         {  
  137.             case SDL_QUIT:SDL_Quit();  
  138.                       break;  
  139.             default:break;  
  140.         }  
  141.     }  
  142.     SDL_Quit();  
  143.   
  144.     av_free(pFrame);  
  145.     avcodec_close(pCodecCtx);  
  146.     av_close_input_file(pFormatCtx);  
  147.     return 0;  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值