【FFmpeg】avcodec_find_encoder和avcodec_find_decoder

发布于:2024-07-03 ⋅ 阅读:(14) ⋅ 点赞:(0)


FFmpeg相关记录:

示例工程:
【FFmpeg】调用ffmpeg库实现264软编
【FFmpeg】调用ffmpeg库实现264软解
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
【FFmpeg】调用ffmpeg库进行SDL2解码后渲染

流程分析:
【FFmpeg】编码链路上主要函数的简单分析
【FFmpeg】解码链路上主要函数的简单分析

结构体分析:
【FFmpeg】AVCodec结构体
【FFmpeg】AVCodecContext结构体
【FFmpeg】AVStream结构体
【FFmpeg】AVFormatContext结构体
【FFmpeg】AVIOContext结构体
【FFmpeg】AVPacket结构体

函数分析:
【FFmpeg】avformat_open_input函数
【FFmpeg】avformat_find_stream_info函数
【FFmpeg】avformat_alloc_output_context2函数
【FFmpeg】avio_open2函数
【FFmpeg】avformat_write_header函数
【FFmpeg】av_write_frame函数

1.avcodec_find_encoder

函数的功能是用于查找一个编码器,定义位于libavcodec\allcodecs.c,函数调用了find_codec查找一个编码器

const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
    return find_codec(id, av_codec_is_encoder);
}

find_codec的定义如下,其中先调用了remap_deprecated_codec_id进行id的重映射,随后调用av_codec_iterate从codec_list当中取出一个codec,随后判断这个codec的id是否与输入的id匹配,如果匹配再检查这个codec的编码能力(capabilities)是否是experimental,如果不是experimental则返回这个codec

static const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
{
    const AVCodec *p, *experimental = NULL;
    void *i = 0;

    id = remap_deprecated_codec_id(id);

    while ((p = av_codec_iterate(&i))) {
        if (!x(p))
            continue;
        if (p->id == id) {
            if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {
                experimental = p;
            } else
                return p;
        }
    }

    return experimental;
}

remap_deprecated_codec_id的定义如下,代码上这里并没有实现,只说在将来可能会做id的映射

static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id)
{
    switch(id){
        //This is for future deprecatec codec ids, its empty since
        //last major bump but will fill up again over time, please don't remove it
        default                                         : return id;
    }
}

av_codec_iterate用于遍历codec_list当中的codec,从中取出一个codec

const AVCodec *av_codec_iterate(void **opaque)
{
    uintptr_t i = (uintptr_t)*opaque;
    const FFCodec *c = codec_list[i];

    ff_thread_once(&av_codec_static_init, av_codec_init_static);

    if (c) {
        *opaque = (void*)(i + 1);
        return &c->p;
    }
    return NULL;
}

2.avcodec_find_decoder

avcodec_find_decoder用于查找一个合适的解码器,与avcodec_find_encoder是类似的,只是查找的是解码器。两个函数都调用了find_codec进行具体的查找任务,区别在于传入的参数,一个是av_codec_is_encoder,另一个是av_codec_is_decoder

const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
    return find_codec(id, av_codec_is_decoder);
}

3.小结

这两个函数的主要任务是根据输入的AVCodecID查找一个合适的编码器或者解码器,如果查找到的编解码器不是experimental的,即可以直接使用,则将当前查找到的编解码器返回

CSDN : https://blog.csdn.net/weixin_42877471
Github : https://github.com/DoFulangChen