威尼斯www.9778.com-威尼斯正版官方网站

vc2005编译ffmpeg以及ffplay

日期:2019-12-25编辑作者:编程人生

typedefstructAVOption{constchar*name;constchar*help;intoffset;enumAVOptionTypetype;union{int64_ti64;doubledbl;constchar*str;/*TODOthoseareunusednow*/AVRationalq;}default_val;doublemin;///minimumvalidvaluefortheoptiondoublemax;///maximumvalidvaluefortheoptionintflags;#defineAV_OPT_FLAG_ENCODING_PARAM1///agenericparameterwhichcanbesetbytheuserformuxingorencoding#defineAV_OPT_FLAG_DECODING_PARAM2///agenericparameterwhichcanbesetbytheuserfordemuxingordecoding#ifFF_API_OPT_TYPE_METADATA#defineAV_OPT_FLAG_METADATA4///somedataextractedorinsertedintothefileliketitle,comment,...#endif#defineAV_OPT_FLAG_AUDIO_PARAM8#defineAV_OPT_FLAG_VIDEO_PARAM16#defineAV_OPT_FLAG_SUBTITLE_PARAM32#defineAV_OPT_FLAG_EXPORT64#defineAV_OPT_FLAG_READONLY128#defineAV_OPT_FLAG_FILTERING_PARAM(116)///agenericparameterwhichcanbesetbytheuserforfilteringconstchar*unit;}AVOption;staticconstAVOptionoptions[]={{"preset","Settheencodingpreset(cf.x264--fullhelp)",OFFSET(preset),AV_OPT_TYPE_STRING,{.str="medium"},0,0,VE},{"tune","Tunetheencodingparams(cf.x264--fullhelp)",OFFSET(tune),AV_OPT_TYPE_威尼斯正版官方网站,STRING,{0},0,0,VE},{"profile","Setprofilerestrictions(cf.x264--fullhelp)",OFFSET(profile),AV_OPT_TYPE_STRING,{0},0,0,VE},{"fastfirstpass","Usefastsettingswhenencodingfirstpass",OFFSET(fastfirstpass),AV_OPT_TYPE_BOOL,{.i64=1},0,1,VE}}初始化.str和.i64出现errorC2059:语法错误:“.”

.简介:把上一篇文章中的demuxer加入ffmpeg源码中去,使可以用命令行方式调用自定义的demuxer

ffmpeg编译过程:
1 http://ffmpeg.zeranoe.com/builds/ 
下载官方提供的源码,win32库和dll。
2 新建vc2005 console空工程,把ffmpeg.h,ffmpeg.c,cmdutils.c,cmdutils.h,cmdutils_common_opts.h,
ffmpeg_filter.c,ffmpeg_opt.c加到工程。
3
从这里生成 config.h
4 从mingw下复制stdint.h和inttypes.h

5 把.h里的inline换成__inline

第一步:

在libavformat目录下新建mkdemuxer.c和mkdemuxer.h,代码如下:

mkdemuxer.c:

 

[cpp] view plain copy

 

  1. /*  
  2. *实现一个自己的demuxer并加入到demuxer链中去 
  3. *作者:缪国凯(MK)  
  4. *821486004@qq.com  
  5. *2015-6-3  
  6. */   
  7.   
  8. #include "mkdemuxer.h"  
  9.   
  10. typedef struct MKVideoDemuxerContext {  
  11.     const AVClass *pclass;     /**< Class for private options. */  
  12.     int width, height;        /**< Integers describing video size, set by a private option. */  
  13.     char *pixel_format;       /**< Set by a private option. */  
  14.     AVRational framerate;     /**< AVRational describing framerate, set by a private option. */  
  15. } MKVideoDemuxerContext;  
  16.   
  17. int mkvideo_read_header(AVFormatContext *ctx)  
  18. {  
  19.     MKVideoDemuxerContext *s = ctx->priv_data;  
  20.     enum AVPixelFormat pix_fmt;  
  21.     AVStream *st;  
  22.   
  23.     st = avformat_new_stream(ctx, NULL);  
  24.     if (!st)  
  25.         return AVERROR(ENOMEM);  
  26.   
  27.     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;  
  28.   
  29.     st->codec->codec_id = ctx->iformat->raw_codec_id;  
  30.   
  31.     //这里就简单的直接赋值为420p  
  32.     pix_fmt = AV_PIX_FMT_YUV420P;  
  33.   
  34.     st->time_base.num = s->framerate.den;  
  35.     st->time_base.den = s->framerate.num;  
  36.     st->pts_wrap_bits = 64;  
  37.       
  38.   
  39.     st->codec->width  = s->width;  
  40.     st->codec->height = s->height;  
  41.     st->codec->pix_fmt = pix_fmt;  
  42.   
  43.     AVRational tmpRa;  
  44.     tmpRa.den = 1;  
  45.     tmpRa.num = 8;  
  46.     st->codec->bit_rate = av_rescale_q(avpicture_get_size(st->codec->pix_fmt, s->width, s->height),  
  47.         tmpRa, st->time_base);  
  48.   
  49.     return 0;  
  50. }  
  51.   
  52. int mkvideo_read_packet(AVFormatContext *s, AVPacket *pkt)  
  53. {  
  54.     int packet_size, ret, width, height;  
  55.     AVStream *st = s->streams[0];  
  56.   
  57.     width = st->codec->width;  
  58.     height = st->codec->height;  
  59.   
  60.     packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);  
  61.     if (packet_size < 0)  
  62.         return -1;  
  63.   
  64.     ret = av_get_packet(s->pb, pkt, packet_size);  
  65.     pkt->pts = pkt->dts = pkt->pos / packet_size;  
  66.   
  67.     pkt->stream_index = 0;  
  68.     if (ret < 0)  
  69.         return ret;  
  70.       
  71.     return 0;  
  72. }  
  73.   
  74. #define OFFSET(x) offsetof(MKVideoDemuxerContext, x)  
  75. #define DEC AV_OPT_FLAG_DECODING_PARAM  
  76.   
  77. static const AVOption mk_options[] =   
  78. {  
  79.     { "video_size", "set frame size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },  
  80.     { "pixel_format", "set pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },  
  81.     { "framerate", "set frame rate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, DEC },  
  82.     { NULL },  
  83. };  
  84.   
  85. static const AVClass mk_demuxer_class = {  
  86.     .class_name = "mk video demuxer",  
  87.     .item_name  = av_default_item_name,  
  88.     .option     = mk_options,  
  89.     .version    = LIBAVUTIL_VERSION_INT,  
  90. };  
  91.   
  92. AVInputFormat ff_mk_demuxer = {  
  93.     .name           = "mk",  
  94.     .long_name      = NULL_IF_CONFIG_SMALL("MK Video Container"),  
  95.     .flags          = AVFMT_GENERIC_INDEX,  
  96.     .extensions     = "mk",   
  97.     .priv_class     = &mk_demuxer_class,      
  98.     .raw_codec_id   = AV_CODEC_ID_RAWVIDEO,  
  99.     .priv_data_size = sizeof(MKVideoDemuxerContext),  
  100.       
  101.     .read_header    = mkvideo_read_header,  
  102.     .read_packet    = mkvideo_read_packet,  
  103. };  

 

 

 

mkdemuxer.h:

 

[cpp] view plain copy

 

  1. /*  
  2. *实现一个自己的demuxer并加入到demuxer链中去 
  3. *作者:缪国凯(MK)  
  4. *821486004@qq.com  
  5. *2015-6-3  
  6. */   
  7.   
  8. #ifndef AVFORMAT_MKDEMUXER_H  
  9. #define AVFORMAT_MKDEMUXER_H  
  10.   
  11. #include "libavutil/opt.h"  
  12. #include "avformat.h"  
  13.   
  14. int mkvideo_read_header(AVFormatContext *ctx);  
  15. int mkvideo_read_packet(AVFormatContext *s, AVPacket *pkt);  
  16.   
  17. #endif //AVFORMAT_MKDEMUXER_H  

 

 

 

 

[cpp] view plaincopy

 

第二步:

在libavformat下的allformats.c的av_register_all里加入:

 

[cpp] view plain copy

 

  1. REGISTER_DEMUXER   (MK,              mk);//add ByMK for mk demuxer    

 

  1. #if defined(WIN32) && !defined(__cplusplus)  
  2. #define inline __inline  
  3. #endif  


project->[setting]->[c/c++]->Preprocessor definitions:编辑框里输入inline=__inline

第三步:

在libavformat目录下的makefile文件的# muxers/demuxers后加入:

 

[cpp] view plain copy

 

  1. OBJS-$(CONFIG_MK_DEMUXER)                  += mkdemuxer.o   

 

6 找不到colorspace.h等一些文件,从源码里找到复制过来。

7 有几个系统文件找不到,注释掉config.h相关定义,如

第四步:

在ffmpeg根目录的config.h里加入:

 

[cpp] view plain copy

 

  1. #define CONFIG_MK_DEMUXER 1    

 

 

 

 

第五步:

如果不想重新configure,则在ffmpeg根目录的config.mak文件中加入:

[cpp] view plain copy

 

  1. CONFIG_MK_DEMUXER=yes  

 

OK,按照正常的编译去编译ffmpeg,然后运行ffmpeg.exe输入ffmpeg -formats 看到有mk这个muxer了,如下:

 

[cpp] view plain copy

 

  1. DE mk              mk (MK Video Container)  
  2.  E mkvtimestamp_v2 extract pts as timecode v2 format, as defined by mkvtoolnix  
  3. DE mlp             raw MLP  
  4. D  mlv             Magic Lantern Video (MLV)  
  5. D  mm              American Laser Games MM  
  6. DE mmf             Yamaha SMAF  
  7.  E mov             QuickTime / MOV  

 

 

再试一下命令:ffmpeg -s 1280x720 -i test.mk -y test.avi。

注意:当.mk格式作为输入的时候,必须加输入参数-s 分辨率,就和yuv作为输入一样(因为从本质上讲就是yuv...)。

 

成功!OK,大功告成。

 

原理在上一篇的博文中已经讲到了,下一步,实现自己的encoder。

from:

[cpp] view plaincopy

 

  1. //#define HAVE_SYS_RESOURCE_H 1  

 

  另外,需要用到socket,修改:

[cpp] view plaincopy

 

  1. #define HAVE_WINSOCK2_H 1  
  2. #define HAVE_STRUCT_ADDRINFO 1  

7 print_all_libs_info 里找不到什么东西,就注释掉。

8参考
在config.h里面加上
#define PRIu64       "I64u"
#define PRId64       "I64d"


//#define AV_TIME_BASE_Q          (AVRational){1, AV_TIME_BASE}

改成

 #define AV_TIME_BASE_Q          _AVRational(1, AV_TIME_BASE)

再加:

 

[cpp] view plaincopy

 

  1. AVRational _AVRational(int num, int den) {  
  2. AVRational r = {num, den};  
  3. return r;  
  4. }  

 

或者,在用到AV_TIME_BASE_Q 的地方,手写AVRational r = {1,AV_TIME_BASE };,再用上这个r.

最麻烦就是const OptionDef options[] 这个数组的初值处理,主要是里面的函数,参考ffmpeg_vc5的代码,把每一行改成这样:{ "f",  HAS_ARG | OPT_STRING | OPT_OFFSET,   { (void*)OFFSET(format) },
就是把原来函数的地方{.fun = xxx}改成 {(void*)xxx}。编译通过了,常规的一些输入参数都好用。复杂的还没试。

最后会提示几个链接问题,手动加上const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB];
然后,在config.h里加:

[cpp] view plaincopy

 

  1. #define AVCONV_DATADIR "c:/ffmpeg1010/"  
  2.   
  3.   
  4. #define snprintf _snprintf  
  5. #define lrint(f) (f>=0?(int32_t)(f+(double)0.5):(int32_t)(f-(double)0.4))  
  6. #define lrintf(f) (f>=0?(int32_t)(f+(float)0.5):(int32_t)(f-(float)0.4))  
  7. #define llrintf(f) (f>=0?(int64_t)(f+(double)0.5):(int64_t)(f-(double)0.4))  
  8. #define llrint(f) (f>=0?(int64_t)(f+(float)0.5):(int64_t)(f-(float)0.4))  
  9.   
  10.   
  11. #define log2(x) (log(x) * 1.44269504088896340736)    

这个AVCONV_DATADIR 是随便写的,暂时还没用上。

到此,基本就完全成功了。编译出来,运行ffmpeg -i rtsp://xxx/test.264 out.mp4
保存的质量非常好。

 

ffplay编译过程

ffplay编译比ffmpeg简单的多,新建工程,加上代码,稍改几行就OK了。然后ffplay rtsp,出了一个黑窗口,播放效果不错。再新生成一个mfc工程,给sdl指定一个窗口,视频就在指定窗口播放了。不过这时有个问题,拖动窗口时,视频就花掉了。估计sdl需要一些参数,以后有空再研究了。

源码下载:

 

原文地址:

本文由威尼斯www.9778.com发布于编程人生,转载请注明出处:vc2005编译ffmpeg以及ffplay

关键词:

怎么使用com的回调

有2个类,CCDMAX和CCDMAXEvents。 classCCDMAX:publicCOleDispatchDriver{public:CCDMAX(){}//调用COleDispatchDriver默认构造函数CCDMAX(LPDISPAT...

详细>>

MFC操作word获取当前页的页码

COleVariantcovZero((short)0),covTrue((short)TRUE);wd.m_wdView.SetSeekView(10);//wdSeekCurrentPageFooter=10wd.m_wdParagraphFormat=wd.m_wdSel.GetParagrap...

详细>>

各位大佬,请帮忙看一下我这个程序,平台评测说是runtime erro

编了一个命令行输入式的矩阵计算器,是一个控制台程序,老师让改成可视化窗口式的程序,不太会,怎么在MFC中实...

详细>>

求助 cannot convert parameter 4 from &#x27;char [260]&#x27; to &#x2

CDatabasedb;charDB[MAX_PATH];sprintf(DB,"ODBC;DSN=User_odbc;UID="",PWD=""");//LPCTSTRch=(LPCTSTR)DB[MAX_PATH];//db.Open(NULL,FALSE,FALSE,ch);db.Open(NU...

详细>>