VS2008+ffmpeg_sdk 3.2 + sdl 播放视频(一)

最近研究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 plain copy
  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 plain copy
  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查看

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Qt是一个功能强大的C++跨平台应用程序开发框架,可以用于开发各种类型的应用程序,包括视频播放器。ffmpeg是一个开源的音视频解码库,可以对各种格式的音视频文件进行解码和编码。在Qt中,可以使用ffmpeg来实现视频播放功能。 要循环播放一个视频,需要在程序中实现如下步骤: 1. 使用Qt中的QMediaPlayer类来实现视频播放功能。QMediaPlayer类提供了很多方法来控制视频的播放、暂停、停止等功能。 2. 使用QFileDialog类来打开视频文件。QFileDialog类是Qt中提供的一个对话框类,可以用来选择文件和目录。 3. 在QMediaPlayer类中设置循环播放模式。可以使用setMedia或setPlaylist方法来设置视频文件或播放列表,并使用setPlaybackMode方法来设置循环播放模式。 4. 在程序中实现播放完成后的回调函数。可以使用QMediaPlayer类的signals和slots机制来连接视频播放完成信号和处理函数。在处理函数中,通过设置QMediaPlayer类的状态为Stopped状态,然后重新播放视频来实现循环播放。 5. 在Qt应用程序中实现一个主循环,用于处理事件和消息。可以使用QApplication类的exec方法来启动主循环。 6. 最后,编译和运行程序,在程序界面中选择要播放的视频文件,程序将会自动循环播放该视频。 ### 回答2: 要循环播放一个视频,可以使用Qt和FFmpeg库来实现。 首先,确保你已经成功地集成了Qt和FFmpeg库到你的项目中。 接下来,需要创建一个包含视频播放功能的Qt窗口。你可以使用Qt的视频播放器组件QMediaPlayer,或者使用FFmpeg提供的接口来实现自定义的播放器。 在窗口类的构造函数中,初始化视频播放器,并设置视频文件的路径。例如,使用QMediaPlayer的setMedia()函数来指定视频文件路径。 然后,将播放器与窗口中的视频显示区域关联起来。使用QMediaPlayer的setVideoOutput()函数,并传入一个用于显示视频的QWidget作为参数。 接下来,在Qt窗口的槽函数中,使用QMediaPlayer的play()函数来开始播放视频。 为了实现循环播放,可以在QMediaPlayer的信号finished()中重新播放视频。在finished()信号的槽函数中,调用QMediaPlayer的setPosition()函数,将视频播放位置重新设置为起始位置,然后再次调用play()函数开始重新播放。 最后,在窗口类的析构函数中,记得释放视频播放器的资源,例如调用QMediaPlayer的stop()函数停止播放,并释放关联的资源。 通过以上步骤,你就可以使用Qt和FFmpeg来实现循环播放一个视频了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值