ffmpeg源码分析之av_register_all()

本文探讨了ffmpeg中的av_register_all()函数在初始化muxer、demuxer、encoder和decoder中的作用。它将这些组件以链表形式存储在全局变量中,如AVOutputFormat和AVInputFormat。以flv格式为例,详细说明了如何将flv_muxer和flv_demuxer注册到相应链表。此外,还提到了avcodec_register_all()在编码器和解码器注册过程中的功能,以及编码方式的不同注册方式。
摘要由CSDN通过智能技术生成

1.muxer/demuxer和ecoder/decoder在代码实现上有很多相同的地方,但是最大的差别是:

muxer/demuxer使用的结构是AVInputFormat/AVOutputFormat

  encoder/decoder用的是AVCodec结构

muxer/demuxer和ecoder/decoder相同的地方有:

 1>都是在av_register_all()中初始化的。

 2>都是以链表的形式保存在全局变量中

    muxer/demuxer分别保存在全局变量AVOutputForamt *first_oformat和

AVInputFormat *first_iforst中

    encoder/decoder都是保存在全局变量AVCodec *first_avcodec中。


以flv格式为例:

av_regeister_all()进行如下的操纵:将支持flv格式的flv_muxer和flv_demuxer变量分别注册到全局变量first_oformat和first_iformat链表的最后位置。



下面是具体的代码:

REGISTER_MUXDEMUX(FLV, flv);//
#define REGISTER_MUXDEMUX(FLV, flv) REGISTER_MUXER(FLV, flv); REGISTER_DEMUXER(FLB, x)

#define REGISTER_MUXER(X, x)//REGISTER_MUXER(FLV, flv)                                            \
{                                                                   \
   extern AVOutputFormat ff_flv_muxer;   //建立一个对象,将该对象保存到链表的尾部                      \
   if (CONFIG_FLV_MUXER)                                     \
       av_register_output_format(&ff_flv_muxer);                 \
}


libavformat文件中的Format.c中有两个全局变量:
/** head of registered input format linked list */
static AVInputFormat *first_iformat = NULL;//链表的头
/** head of registered output format linked list */
static AVOutputFormat *first_oformat = NULL;//head
static AVInputFormat **last_iformat = &first_iformat;//链表的尾
static AVOutputFormat **last_oformat = &first_oformat;//链表的尾

void av_register_output_format(AVOutputFormat *format)
{
    AVOutputFormat **p = last_oformat;

    format->next = NULL;
    /*遍历链表,初次调用的时候会令first_oformat指向format*/
    while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
        p = &(*p)->next;
    last_oformat = &format->next;    //(->为1级优先级,&为2级)
}


void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
{
    if (*ptr == oldval) {
        *ptr = newval;
        return oldval;
    }
    return *ptr;
}

同理:解复用也是一样的道理!

2.

av_register_all()中的avcodec_register_all()的分析:

通过该函数初始化encoder/decoder。

并不是每种编码方式都支持encode和decode,所以有以下三种注册方式:

#define REGISTER_ENCODER(FLV, flv)                                          \
    {                               
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值