[9]【ffmpeg源码分析 1】av_register_all()和avcodec_register_all()
来源:互联网 发布:kk是什么软件 编辑:程序博客网 时间:2024/06/06 05:04
日期:2016.10.18
作者:isshe
github:github.com/isshe
邮箱:i.sshe@outlook.com
前言
接下来打算学习一下编解码,不过好像很难的样子, 希望能看懂。
1. av_register_all()
- 所在文件:allformats.c
- 主要代码:(每个宏只列举一个)
void av_register_all(void){ static int initialized; if (initialized) return; //注册编解码器 avcodec_register_all(); /* (de)muxers */ //注册复用器 REGISTER_MUXER (A64, a64); //注册解复用器 REGISTER_DEMUXER (AA, aa); //两个同时注册 REGISTER_MUXDEMUX(AC3, ac3);
1.1 REGISTER_MUXER宏
- 代码:
#define REGISTER_MUXER(X, x) \ { \ extern AVOutputFormat ff_##x##_muxer; \ if (CONFIG_##X##_MUXER) \ av_register_output_format(&ff_##x##_muxer); \ }
- “##”号起连接作用,例如:a##b = ab.
- ff_##x##_muxer, 一个与x对应的AVOutputFormat.
- 其实这些外部变量,一般定义的时候就赋了初值。(限于篇幅,具体的示例在下面编解码相关的地方)
1.1.1 av_register_output_format()
- 注册一个与该格式相应的AVFormat结构
- 相关代码:
//head of registered output format linked list static AVOutputFormat *first_oformat = NULL;static AVOutputFormat **last_oformat = &first_oformat;void av_register_output_format(AVOutputFormat *format){ AVOutputFormat **p = last_oformat; // Note, format could be added after the first 2 checks but that implies that *p is no longer NULL //检查链表中有无指定的format,没有就加入。 //在前面两个条件成立后才把format连接到p链表中。 while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format)) p = &(*p)->next; if (!format->next) last_oformat = &format->next;}
- last_oformat是一个二次指针。
- avpriv_atomic_ptr_cas把format放到p链表中。
- 遍历链表,把指定format加到链表后面。
1.2 REGISTER_DEMUXER 宏
- 和REGISTER_MUXER()类似。
1.3 REGISTER_MUXDEMUX 宏
- #define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x)
2. avcodec_register_all()
- 所在文件:allcodecs.c
- 主要代码:(每种情况列举一个)
void avcodec_register_all(void){ static int initialized; if (initialized) return; initialized = 1; //硬件加速器 /* hardware accelerators */ REGISTER_HWACCEL(H263_CUVID, h263_cuvid); //注意以下函数适用于视频和音频 //注册编码器 REGISTER_ENCODER(A64MULTI, a64multi); //注册解码器 REGISTER_DECODER(AASC, aasc); //两个同时注册 REGISTER_ENCDEC (ALIAS_PIX, alias_pix); //注册分析器???不懂 REGISTER_PARSER(AAC, aac);
2.1 REGISTER_HWACCEL 宏
- 注册硬件加速器宏
- 代码:
#define REGISTER_HWACCEL(X, x) \ { \ extern AVHWAccel ff_##x##_hwaccel; \ if (CONFIG_##X##_HWACCEL) \ av_register_hwaccel(&ff_##x##_hwaccel); \ }
- extern的那个变量在源码中没找着…
2.1.1 av_register_hwaccel()
- 注册硬件加速器的函数
- 代码:和前面的muter类似。
void av_register_hwaccel(AVHWAccel *hwaccel){ AVHWAccel **p = last_hwaccel; hwaccel->next = NULL; while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel)) p = &(*p)->next; last_hwaccel = &hwaccel->next;}
2.2 REGISTER_ENCODER宏
- 注册编码器的宏
- 代码:
#define REGISTER_ENCODER(X, x) \ { \ extern AVCodec ff_##x##_encoder; \ if (CONFIG_##X##_ENCODER) \ avcodec_register(&ff_##x##_encoder); \ }
2.2.1 ff_##x##_encoder变量
- 用aac示例:ff_aac_encoder变量
AVCodec ff_aac_encoder = { .name = "aac", .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACEncContext), .init = aac_encode_init, //初始化 .encode2 = aac_encode_frame, //编码函数 .close = aac_encode_end, // .defaults = aac_encode_defaults, .supported_samplerates = mpeg4audio_sample_rates, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &aacenc_class,};
- 可见,这些外部变量都是已经赋值好的,解码的【或其他】也类似。
- 下面调用的注册函数就是把这么一个结构放到链表中。
2.2.2 avcodec_register
- 注册编码器的函数
- 代码:
av_cold void avcodec_register(AVCodec *codec){ AVCodec **p; avcodec_init(); //!!! p = last_avcodec; codec->next = NULL; while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec)) p = &(*p)->next; last_avcodec = &codec->next; if (codec->init_static_data) codec->init_static_data(codec);}
2.3 REGISTER_DECODER 宏
- 和编码类似
2.4 REGISTER_ENCDEC 宏
- 同时注册解码和编码器
2.5 REGISTER_PARSER 宏
- 代码:
#define REGISTER_PARSER(X, x) \ { \ extern AVCodecParser ff_##x##_parser; \ if (CONFIG_##X##_PARSER) \ av_register_codec_parser(&ff_##x##_parser); \ }
av_register_codec_parser()
- 代码:
void av_register_codec_parser(AVCodecParser *parser){ do { parser->next = av_first_parser; } while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser));}
参考资料
- 雷神博文:av_register_all()
- 雷神博文:avcodec_register_all()
- ffmpeg-3.1.3源码
代码下载
- ffmpeg-3.1.3源码:http://download.csdn.net/detail/i_scream_/9657369
0 0
- [9]【ffmpeg源码分析 1】av_register_all()和avcodec_register_all()
- av_register_all,avcodec_register_all的源码分析
- ffmpeg源码简析(二)av_register_all(),avcodec_register_all()
- FFMpeg 源码分析(1)av_register_all()
- ffmpeg源码分析之av_register_all()
- ffmpeg源码分析--2.av_register_all
- FFmpeg源码剖析-通用:avcodec_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 函数简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- FFmpeg源码剖析-通用:av_register_all()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : av_register_all()
- 垂直水平居中的方法总结和适用场景
- 【数字图像处理】[2]--直方图均衡化
- 微软经典面试测试题和参考答案(变态) - TOMB RAIDER - CSDNBlog(转载)
- ansible.cfg 参数配置
- 值传递与引用传递的区别
- [9]【ffmpeg源码分析 1】av_register_all()和avcodec_register_all()
- hdu 1250 Hat's Fibonacci
- Could not find a storyboard named 'main' in bundle NSBundle
- 不需titleBar即可使用菜单
- Android常用控件——日期选择器
- 微信小程序例子——使用swiper组件实现图片切换
- JavaCC How to access non-terminal's TOKEN child
- 利用btrace在线监控java程序状态
- c++类中的this指针