DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

最近研究ffmpeg,在ubuntu下感觉不太好调试,老是找不到函数的声明。所以我就把他移到windows下用vs2008分析

关于环境的搭建,我参考了 http://hi.baidu.com/forever803/blog/item/ba90cdd2cca917093af3cf9e.html ,这里我把步骤整理一下,顺便奉上图文

第1步:

下载ffmpeg SDK3.2:点击下载,并解压。

第2步:

打开vs2008新建一个空的vc++项目

第3步:

新建一个C++源文件,test.cpp,输入简单代码测试一下

[html] view plaincopy
 
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. int main(){  
  4.     printf("aaaa\n");  
  5.     system("pause");  
  6.     return 0;  
  7. }  

按F5运行,打印输出aaaa,则没问题

第4步:

将解压出来的sdk下的include目录下的所有文件夹和文件拷到vc++工程目录下的test.cpp同一个目录。我的是(C:\Users\easou\Documents\Visual Studio 2008\Projects\testffmpeg\testffmpeg),此时,目录结构如下图

第5步:

 将解压出来的lib文件夹拷贝至tes.cpp同一目录下。

然后在vs2008里,单击工程右键->属性->常规->附加库目录  填入$(SolutionDir)\$(ProjectName)\lib

    
属性->链接器->  附加依赖项  填入avcodec.lib avdevice.lib avfilter.lib avformat.lib avutil.lib swscale.lib  点击确定

第6步:

将tutorial01.c的内容复制到test.cpp中,并修改相关引用路径,按F7编译。F5运行

tes.cpp代码:

[html] view plaincopy
 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #ifdef __cplusplus  
  5. extern "C" {  
  6. #endif  
  7.     #include "libavcodec/avcodec.h"  
  8.     #include "libavformat/avformat.h"  
  9.     #include "libswscale/swscale.h"  
  10. #ifdef __cplusplus  
  11. }  
  12. #endif  
  13.   
  14. void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {  
  15.   FILE *pFile;  
  16.   char szFilename[32];  
  17.   int  y;  
  18.     
  19.   // Open file  
  20.   sprintf(szFilename, "frame%d.ppm", iFrame);  
  21.   pFile=fopen(szFilename, "wb");  
  22.   if(pFile==NULL)  
  23.     return;  
  24.     
  25.   // Write header  
  26.   fprintf(pFile, "P6\n%d %d\n255\n", width, height);  
  27.     
  28.   // Write pixel data  
  29.   for(y=0; y<height; y++)  
  30.     fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);  
  31.     
  32.   // Close file  
  33.   fclose(pFile);  
  34. }  
  35.   
  36. int main() {  
  37.   AVFormatContext *pFormatCtx;  
  38.   int             i, videoStream;  
  39.   AVCodecContext  *pCodecCtx;  
  40.   AVCodec         *pCodec;  
  41.   AVFrame         *pFrame;   
  42.   AVFrame         *pFrameRGB;  
  43.   AVPacket        packet;  
  44.   int             frameFinished;  
  45.   int             numBytes;  
  46.   uint8_t         *buffer;  
  47.   static struct SwsContext *img_convert_ctx;  
  48.   char * filePath="test.mp4";  
  49.   // Register all formats and codecs  
  50.   av_register_all();  
  51.     // Open video file  
  52.   if(av_open_input_file(&pFormatCtx, filePath, NULL, 0, NULL)!=0)  
  53.     return -1; // Couldn't open file  
  54.     
  55.   // Retrieve stream information  
  56.   if(av_find_stream_info(pFormatCtx)<0)  
  57.     return -1; // Couldn't find stream information  
  58.     
  59.   // Dump information about file onto standard error  
  60.   dump_format(pFormatCtx, 0, filePath, 0);  
  61.     // Find the first video stream  
  62.   videoStream=-1;  
  63.   for(i=0; i<pFormatCtx->nb_streams; i++)  
  64.     if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {  
  65.       videoStream=i;  
  66.       break;  
  67.     }  
  68.   if(videoStream==-1)  
  69.     return -1; // Didn't find a video stream  
  70.       // Get a pointer to the codec context for the video stream  
  71.   pCodecCtx=pFormatCtx->streams[videoStream]->codec;  
  72.   
  73.     // Find the decoder for the video stream  
  74.   pCodec=avcodec_find_decoder(pCodecCtx->codec_id);  
  75.   if(pCodec==NULL) {  
  76.     fprintf(stderr, "Unsupported codec!\n");  
  77.     return -1; // Codec not found  
  78.   }  
  79.       // Open codec  
  80.   if(avcodec_open(pCodecCtx, pCodec)<0)  
  81.     return -1; // Could not open codec  
  82.   
  83.     // Allocate video frame  
  84.   pFrame=avcodec_alloc_frame();  
  85.     
  86.   // Allocate an AVFrame structure  
  87.   pFrameRGB=avcodec_alloc_frame();  
  88.   if(pFrameRGB==NULL)  
  89.     return -1;  
  90.   
  91.       
  92.   // Determine 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  
  99.   // of AVPicture  
  100.   avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,  
  101.          pCodecCtx->width, pCodecCtx->height);  
  102.   
  103.   // Read frames and save first five frames to disk  
  104.   i=0;  
  105.   while(av_read_frame(pFormatCtx, &packet)>=0) {  
  106.             if(packet.stream_index==videoStream) {  
  107.                       // Decode video frame  
  108.                  avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);  
  109.                    if(frameFinished) {  
  110.                             // Convert the image from its native format to RGB  
  111.                         img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);  
  112.                         // Convert the image from its native format to RGB  
  113. sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);  
  114.                         if(++i<=5)  
  115.                             SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,i);                  
  116.                    }  
  117.             }  
  118.                 // Free the packet that was allocated by av_read_frame  
  119.         av_free_packet(&packet);  
  120.   }  
  121.   // Free the RGB image  
  122.   av_free(buffer);  
  123.   av_free(pFrameRGB);  
  124.     
  125.   // Free the YUV frame  
  126.   av_free(pFrame);  
  127.     
  128.   // Close the codec  
  129.   avcodec_close(pCodecCtx);  
  130.     
  131.   // Close the video file  
  132.   av_close_input_file(pFormatCtx);  
  133.     
  134.   printf("执行完毕\n");  
  135.   system("pause");  
  136.   return 0;  
  137. }  



 

这里可能出现的问题比较多,主要有:

1、找不到stdint.h这个文件,将出现问题的头文件中的“include <stdint.h>”改为“include "stdint.h"”即可

2、无法解析的外部符号 _img_convert,参考文章http://witmax.cn/ffmpeg-img-convert.html

3、运行时会出现找不到avformat.dll的对话框,将sdk下的bin文件下的dll文件都拷贝到工程目录下的debug文件夹解决。

4、信息窗出现 testffmpeg.exe: 本机”已退出,返回值为 -1字样。检查一下,是否没有将你的test.mp4拷到tes.cpp同一个目录下,mp4文件网上随便找一个就可以。提供我的视频一个http://115.com/file/e7f1ylpy

最后按F5出现命令窗口如下,调试通过

到test.cpp文件的目录下看一下,多出了5个ppm文件

可以用acd查看

posted on 2014-09-11 23:23  DoubleLi  阅读(1293)  评论(1编辑  收藏  举报