ffmpeg目录架构与基本框架机制
来源:互联网 发布:淘宝买白酒靠谱吗 编辑:程序博客网 时间:2024/06/02 05:26
目录架构:
libavcodec用于存放各个encode/decode模块,CODEC其实是Coder/Decoder的缩写,也就是编码解码器;用于各种类型声音/图像编解码
libavformat用于存放muxer/demuxer模块,对音频视频格式的解析;用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能;
其中库 libavcodec,libavformat用于对媒体文件进行处理,如格式的转换;
Libavfilter用于存放滤镜和滤镜相关的操作
libavutil集项工具,包含一些公共的工具函数;用于存放内存操作等辅助性模块,是一个通用的小型函数库,该库中实现了CRC校验码的产生,128位整数数学,最大公约数,整数开方,整数取对数,内存分配,大端小端格式的转换等功能
libavdevice:对输出输入设备的支持;
libpostproc:用于后期效果处理;
libswscale:用于视频场景比例缩放、色彩映射转换;
http://wenku.baidu.com/link?url=k6RO-Jj5maCIsihTrWrmAKf-BnY7oR5AzrCOOpSD44bTYpBipwbTyI3ExhSsDOARWm4MKgmzsxwVbT5GO24-fZ21MvG5DZsFghe3MHxPcfu —————几个关键结构体的简单介绍
http://www.cnblogs.com/tocy/p/ffmpeg-framework-analysis.html ——————插件的结构体定义的成员简单说明
http://blog.csdn.net/leixiaohua1020/article/details/12720427 ————ffmpeg面向对象简单探讨
http://blog.csdn.net/leixiaohua1020/article/details/11693997 —–FFMPEG中最关键的结构体之间的关系
整体上,ffmpeg的基本框架是使用类似面向对象的思想。整体的程序流程处理方式:
a. 注册 ——-实际上就是一个链表操作
b. 查找匹配——通过链表,找到指定的解码器、滤镜等
c. 底层插件赋值给上层—-实际上就是函数指针的利用,可以理解成父结构体保存一个指向子结构体的指针
编码器,解码器链表: —————–libavcodec/utils.c
static AVCodec *first_avcodec = NULL;
static AVCodec **last_avcodec = &first_avcodec;—–为什么需要二级指针?
滤镜链表: —————–libavfilter/avfilter.c
static AVFilter *first_filter;
static AVFilter **last_filter = &first_filter;
注册编码器nvenc简单分析:
void avcodec_register_all(void){....... REGISTER_ENCODER(NVENC_H264, nvenc_h264);.......}
#define REGISTER_ENCODER(X, x) { extern AVCodec ff_##x##_encoder; /*如果CONFIG_NVENC_H264_ENCODER有定义,注册*/ if (CONFIG_##X##_ENCODER) /*根据具体对象的声明名字注册进链表,例如ff_nvenc_h264_encoder*/ avcodec_register(&ff_##x##_encoder); }
av_cold void avcodec_register(AVCodec *codec){ AVCodec **p; avcodec_init(); p = last_avcodec; codec->next = NULL; /*调用avpriv_atomic_ptr_cas,将codec赋值给*p。也就是将新模块插进链表,last_avcodec指向链尾的next*/ 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);}
void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval){ void *ret; pthread_mutex_lock(&atomic_lock); ret = *ptr; if (ret == oldval) *ptr = newval; pthread_mutex_unlock(&atomic_lock); return ret;}
经过上述的操作后,实际上将下面结构体插进了链表:
AVCodec ff_nvenc_h264_encoder = { .name = "nvenc_h264", .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC H.264 encoder"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), .priv_class = &nvenc_h264_class, .defaults = defaults, .capabilities = AV_CODEC_CAP_DELAY, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = ff_nvenc_pix_fmts,};
在往后的代码中,通过调用类似的查找接口
AVCodec *avcodec_find_decoder(enum AVCodecID id){ return find_encdec(id, 0);}static AVCodec *find_encdec(enum AVCodecID id, int encoder){ AVCodec *p, *experimental = NULL; p = first_avcodec; id= remap_deprecated_codec_id(id); while (p) { if ((encoder ? av_codec_is_encoder(p) : av_codec_is_decoder(p)) && p->id == id) { if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) { experimental = p; } else return p; } p = p->next; } return experimental;}
或者AVCodec *avcodec_find_decoder_by_name(const char *name){ AVCodec *p; if (!name) return NULL; p = first_avcodec; while (p) { if (av_codec_is_decoder(p) && strcmp(name, p->name) == 0) return p; p = p->next; } return NULL;}
通过链表匹配,就能找到想要的解码器或者编码器
http://blog.csdn.net/leixiaohua1020/article/details/12677265—-注册的更详细描述
- ffmpeg目录架构与基本框架机制
- ffmpeg 架构介绍一:框架流程图
- ElasticSearch机制与架构
- 框架与系统架构
- 架构与框架
- 软件架构与框架
- 架构与框架
- 框架与架构
- web及tomcat基本目录文件架构
- Linux 目录架构及其一些基本命令
- [读书笔记]深入解析MapReduce架构设计与实现原理——CH4 Hadoop RPC基本框架
- 移动架构29_面向对象式手写数据库架构设计一(基本框架与插入数据)
- Kubernetes基本术语与架构
- Kubernetes基本术语与架构
- Hive 架构与基本组成
- DeepNet的基本框架和训练机制
- 类库、子系统、框架与架构
- 前端,架构,框架与库
- jQuery 数据 - jQuery.data() 方法
- 8 Bootstrapping
- jointJS(三)--找了一万年的link默认样式
- 一种临界区的实现
- android 手机app应用压力测试整理(一)
- ffmpeg目录架构与基本框架机制
- FreeMarker自定义TemplateDirectiveModel之重复提交&下拉列表
- Tips
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)
- 不使用中间变量,交换两个数值的三种方法
- 推送服务
- (十六)ReactNative 中获取当前文件的相对路径和相对路径
- 重新认识java(一) ---- 万物皆对象
- PHP短信验证功能