FFmpeg浅尝辄止(三)——小试视频解码

上一篇介绍了视频编码的小例子,视频解码跟编码差不多,只是要在视频文件中寻找视频流,找到后对流逐帧解码,就这样简单。闲言少叙,上code:

[cpp]  view plain  copy
  1. int main(int argc, char *argv[])  
  2. {  
  3.     AVFormatContext *pFormatCtx;  
  4.     int             i, videoStream;  
  5.     AVCodecContext  *pCodecCtx;  
  6.     AVCodec         *pCodec;  
  7.     AVFrame         *pFrame;   
  8.     AVFrame         *pFrameRGB;  
  9.     AVPacket        packet;  
  10.     int             frameFinished;  
  11.     int             numBytes;  
  12.     uint8_t         *buffer;  
  13.     struct SwsContext *img_convert_ctx;  
  14.   
  15.     if(argc < 2)  
  16.     {  
  17.         printf("Please provide a movie file\n");  
  18.         return -1;  
  19.     }  
  20.     // Register all formats and codecs  
  21.     // 初始化ffmpeg库  
  22.     av_register_all();  
  23.   
  24.     // Open video file  
  25.     if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)  
  26.         return -1; // Couldn't open file  
  27.   
  28.     // Retrieve stream information  
  29.     // 查找文件的流信息  
  30.     if(av_find_stream_info(pFormatCtx)<0)  
  31.         return -1; // Couldn't find stream information  
  32.   
  33.     // Dump information about file onto standard error  
  34.     // dump只是一个调试函数,输出文件的音、视频流的基本信息:帧率、分辨率、音频采样等等  
  35.     dump_format(pFormatCtx, 0, argv[1], 0);  
  36.   
  37.     // Find the first video stream  
  38.     // 遍历文件的流,找到第一个视频流,并记录流的编码信息  
  39.     videoStream=-1;  
  40.     for(i=0; i<pFormatCtx->nb_streams; i++)  
  41.     {  
  42.         if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)  
  43.         {  
  44.             videoStream=i;  
  45.             break;  
  46.         }  
  47.     }  
  48.     if(videoStream==-1)  
  49.         return -1; // Didn't find a video stream  
  50.   
  51.     // Get a pointer to the codec context for the video stream  
  52.     // 得到视频流编码的上下文指针  
  53.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;  
  54.   
  55.     // construct the scale context, conversing to PIX_FMT_RGB24  
  56.     // 根据编码信息设置渲染格式  
  57.     img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,   
  58.             pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);  
  59.     if(img_convert_ctx == NULL)  
  60.     {  
  61.         fprintf(stderr, "Cannot initialize the conversion context!\n");  
  62. //      exit(1);  
  63.         return -1;  
  64.     }  
  65.   
  66.     // Find the decoder for the video stream  
  67.     // 在库里面查找支持该格式的解码器  
  68.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);  
  69.     if(pCodec==NULL)  
  70.     {  
  71.         fprintf(stderr, "Unsupported codec!\n");  
  72.         return -1; // Codec not found  
  73.     }  
  74.     // Open codec  
  75.     // 打开解码器  
  76.     if(avcodec_open(pCodecCtx, pCodec)<0)  
  77.         return -1; // Could not open codec  
  78.   
  79.     // Allocate video frame  
  80.     // 分配一个帧指针,指向解码后的原始帧  
  81.     pFrame=avcodec_alloc_frame();  
  82.   
  83.     // Allocate an AVFrame structure  
  84.     // 分配一个帧指针,指向存放转换成rgb后的帧  
  85.     pFrameRGB=avcodec_alloc_frame();  
  86.     if(pFrameRGB==NULL)  
  87.         return -1;  
  88.   
  89.     // Determine required buffer size and allocate buffer  
  90.     numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);  
  91.     buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));  // buffer = new uint8_t[numBytes];  
  92.   
  93.     // Assign appropriate parts of buffer to image planes in pFrameRGB  
  94.     // Note that pFrameRGB is an AVFrame, but AVFrame is a superset  
  95.     // of AVPicture  
  96.     // 给pFrameRGB帧附加上分配的内存  
  97.     avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);  
  98.   
  99.     // Read frames and save first five frames to disk  
  100.     i=0;  
  101.     while(av_read_frame(pFormatCtx, &packet)>=0) // 读取一个帧  
  102.     {  
  103.         // Is this a packet from the video stream?  
  104.         if(packet.stream_index==videoStream)  
  105.         {  
  106.             // Decode video frame  
  107.             // 解码该帧  
  108.             avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size);  
  109.   
  110.             // Did we get a video frame?  
  111.             if(frameFinished)  
  112.             {  
  113.                 // Convert the image from its native format to RGB  
  114.                 // img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,   
  115.                 //              (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,   
  116.                 //              pCodecCtx->height);  
  117.                   
  118.                 // 把该帧转换成rgb  
  119.   
  120.                 // 如果只提取关键帧,加上这句  
  121.                 // if (pFrame->key_frame == 1)  
  122.                 sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);    
  123.                 // Save the frame to disk  
  124.                 // 保存前5帧  
  125.                 if(++i<=5)  
  126.                 {  
  127. //                  char pic[200];  
  128. //                  sprintf(pic,"pic%d.bmp",i);  
  129. //                  av_create_bmp(pic, pFrameRGB->data[0], pCodecCtx->width, pCodecCtx->height, 24);  
  130.                     SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);  
  131.                 }  
  132.             }  
  133.         }  
  134.   
  135.         // Free the packet that was allocated by av_read_frame  
  136.         // 释放读取的帧内存  
  137.         av_free_packet(&packet);  
  138.     }  
  139.   
  140.     // Free the RGB image  
  141.     av_free(buffer);  
  142.     av_free(pFrameRGB);  
  143.   
  144.     // Free the YUV frame  
  145.     av_free(pFrame);  
  146.   
  147.     // Close the codec  
  148.     avcodec_close(pCodecCtx);  
  149.   
  150.     // Close the video file  
  151.     av_close_input_file(pFormatCtx);  
  152.   
  153.     return 0;  
  154. }  

除了saveFrame函数都贴上来啦。感觉注释应该够了,不用我多费口舌了,so easy!

下载链接:http://download.csdn.net/detail/yang_xian521/4399108

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值