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—-注册的更详细描述

0 0
原创粉丝点击