ffmpeg工作流程分析-3

为掌握ffmpeg的工作流程,现以libavcodec下的ffmpeg/doc/examples/decoding_encoding.c中实现视频编码为例展示其工作过程。

libavcodec库是实现音频或视频的编码或解码,所有编解码CODEC的调用均有统一的格式,ffmpeg以公共的函数指针注册、调用和销毁
CODEC。

video_encode_example例程实现给定视频数据的编码,将编码后的码流写文件。所有avcodec的调用均使用统一的过程,首先是初始化avcodec_init(),所有CODEC库在使用前均需要调用该函数;然后是注册所有的CODEC,包括注册编码器REGISTER_ENCODER、解码器REGISTER_DECODER、编解码器REGISTER_ENCDEC等;最后使用CODEC,如video_encode_example。

1 初始化CODEC

调用ffmpeg的函数avcodec_init实现CODEC的初始化。

static av_cold void avcodec_init(void)
{
    static int initialized = 0; //静态变量标注初始化,只调用一次

    if (initialized != 0)
        return;
    initialized = 1;

    if (CONFIG_ME_CMP)
        ff_me_cmp_init_static();
}

为确保该初始化仅被调用一次,因此使用局部静态变量,记录以前的动作。初始化的任务是将“数字信号处理应用”中的静态表格初始化。其实就是一个数组,初始化其为0。
初始化的函数会在这里被调用:

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 注册CODEC

由于有诸多的CODEC,所以ffmpeg以公共的函数指针的方式,以统一的接口操作CODEC。首先AVCodec结构体定义了函数指针,某一个CODEC实例填充AVCodec结构的字段,然后用REGISTER_ENCODER注册该CODEC。


struct AVSubtitle;

/**
 * AVCodec.
 */
typedef struct AVCodec {
    /**
     * Name of the codec implementation.
     * The name is globally unique among encoders and among decoders (but an
     * encoder and a decoder can share the same name).
     * This is the primary way to find a codec from the user perspective.
     */
    const char *name;
    /**
     * Descriptive name for the codec, meant to be more human readable than name.
     * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
     */
    const char *long_name;
    enum AVMediaType type;
    enum AVCodecID id;
    /**
     * Codec capabilities.
     * see AV_CODEC_CAP_*
     */
    int capabilities;
    const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
    const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
    const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
    const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值