ffmpeg简单分析字典参数AVDictionary的小秘密

ffmpeg简单分析字典参数AVDictionary的小秘密

  • 咱们在使用ffmpeg接口时发现有些接口是能够传递其余一些参数(AVDictionary)设置的,但这个AVDictionary究竟能够传递什么值,倒是不得而知
  • 好比这个接口,最后一个参数就是AVDictionary类型的
int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);
  • 那么咱们究竟能够传什么值呢,ffmpeg并无明确告诉你,开发者看到这个接口确定也是一脸懵,并且因为它是可空的,所以基本上会被使用者置空了,但咱们在网上搜索一些例子时,确实发现能够有一些参数设置的,并且这些参数设置确实能解决遇到的问题,所以不得不对这个AVDictionary进行研究下html

  • 网上通过一番搜索,发现源代码中有两个文件里的内容彷佛与AVDictionary有关系,咱们能够在线瞧一瞧web

    • 这是关于avformat的参数
    • https://www.ffmpeg.org/doxygen/trunk/libavformat_2options__table_8h-source.html
    • 这是关于avcodec的参数
    • http://www.ffmpeg.org/doxygen/trunk/libavcodec_2options__table_8h_source.html
  • 从这两个文件来看彷佛找到AVDictionary能够设置的值了,就是类型为AVOption的值,但后面发现这两个文件里包含的并不是ffmpeg支持的所有参数缓存

  • 偶然的机会看到了rtsp.c源代码,发现里面也有AVOption,这时就猜想这些参数可能分散在各个文件中,若是使用rtsp协议,那么可使用rtsp.c文件里的AVOption去设置AVDictionary,若是是mov,那么在movenc.c源代码中就声明了可用的AVOption,等等网络

  • 咱们须要根据具体使用的状况去查找(也终于明白了为啥ffmpeg对这个AVDictionary描述如此含糊的缘由,由于这个自己就很差描述)svg

AVOption

243  /** 244 * AVOption 245 */
  246 typedef struct AVOption {
  247     const char *name;
  248 
  249     /** 250 * short English help text 251 * @todo What about other languages? 252 */
  253     const char *help;
  254 
  255     /** 256 * The offset relative to the context structure where the option 257 * value is stored. It should be 0 for named constants. 258 */
  259     int offset;
  260     enum AVOptionType type;
  261 
  262     /** 263 * the default value for scalar options 264 */
  265     union {
  266         int64_t i64;
  267         double dbl;
  268         const char *str;
  269         /* TODO those are unused now */
  270         AVRational q;
  271     } default_val;
  272     double min;                 ///< minimum valid value for the option
  273     double max;                 ///< maximum valid value for the option
  274 
  275     int flags;
  276 #define AV_OPT_FLAG_ENCODING_PARAM  1   ///< a generic parameter which can be set by the user for muxing or encoding
  277 #define AV_OPT_FLAG_DECODING_PARAM  2   ///< a generic parameter which can be set by the user for demuxing or decoding
  278 #define AV_OPT_FLAG_AUDIO_PARAM     8
  279 #define AV_OPT_FLAG_VIDEO_PARAM     16
  280 #define AV_OPT_FLAG_SUBTITLE_PARAM  32
  281 /** 282 * The option is intended for exporting values to the caller. 283 */
  284 #define AV_OPT_FLAG_EXPORT          64
  285 /** 286 * The option may not be set through the AVOptions API, only read. 287 * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. 288 */
  289 #define AV_OPT_FLAG_READONLY        128
  290 #define AV_OPT_FLAG_BSF_PARAM       (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering
  291 #define AV_OPT_FLAG_RUNTIME_PARAM   (1<<15) ///< a generic parameter which can be set by the user at runtime
  292 #define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
  293 #define AV_OPT_FLAG_DEPRECATED      (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information
  294 //FIXME think about enc-audio, ... style flags
  295 
  296     /** 297 * The logical unit to which the option belongs. Non-constant 298 * options and corresponding named constants share the same 299 * unit. May be NULL. 300 */
  301     const char *unit;
  302 } AVOption;

已知的AVOption

  • 这里记录下笔者已经发现的AVOption
  • 须要注意的是,这些参数你均可以设置,但ffmpeg只会挑那些符合当前环境的参数去使用,例如你确实是在使用rtsp,那么关于rtsp的参数则会生效

avformat

  • https://www.ffmpeg.org/doxygen/trunk/libavformat_2options__table_8h-source.html
  • 在这里插入图片描述

avcodec

  • http://www.ffmpeg.org/doxygen/trunk/libavcodec_2options__table_8h_source.html
  • 这个实在太多了就不截图了

rtsp

mov

示例

  • 如下这个例子演示了AVDictionary在avformat_open_input里的使用,咱们能够看到,AVDictionary能够设置好多个,但最终用哪些彻底取决于ffmpeg,也就是说不是你设置什么就生效什么,万一你乱来呢,所以ffmpeg只会根据当前状况选择哪些符合的参数进行使用,最后能够经过AVDictionaryEntry 看看哪些参数是ffmpeg没用到的
AVDictionary* options = NULL;
av_dict_set(&options, "buffer_size", "1048576", 0);//设置缓存大小,1080p可将值调大,好比1MB; 524288=512KB 1048576=1MB
av_dict_set(&options, "aaa", "1048576", 0);//aaa纯粹是本身随便定的,所以ffmpeg不会识别它,会直接返回给咱们
av_dict_set(&options, "bbb", "1048576", 0);//bbb也是乱写的
//打开网络流或文件流 
if (avformat_open_input(&pFormatCtx, "rtsp://...", NULL, &options) != 0)	
{
	printf("Couldn't open input stream.\n");
	return;
}

//打印出那些未被消费的参数,如下会打印出aaa,bbb
AVDictionaryEntry *entry=NULL;
while (entry = av_dict_get(options, "", entry, AV_DICT_IGNORE_SUFFIX)) {
	log(AV_LOG_INFO, "Option %s not recognized by the demuxer,and the count is %d \n", entry->key, av_dict_count(options));
}

//最后释放掉 
av_dict_free(&options);

参考

  • FFmpeg接口-AVDictionary的使用介绍和源码分析 - 简书 https://www.jianshu.com/p/89f2da631e16