参考链接
-
FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()_雷霄骅的博客-CSDN博客_avcodec_find_encoder
avcodec_find_encoder
- avcodec_find_encoder()用于查找FFmpeg的编码器
- avcodec_find_encoder()的声明位于libavcodec\codec.h 版本差异
- avcodec_find_encoder()的源代码位于allcodecs.c 版本差异
- 函数的参数是一个编码器的ID,返回查找到的编码器(没有找到就返回NULL)
const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{return find_codec(id, av_codec_is_encoder);
}
avcodec_find_decoder
- avcodec_find_decoder()用于查找FFmpeg的解码器
- avcodec_find_decoder()的声明位于libavcodec\codec.h 版本差异
- avcodec_find_decoder()的源代码位于allcodecs.c 版本差异
-
函数的参数是一个解码器的ID,返回查找到的解码器(没有找到就返回NULL)
const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{return find_codec(id, av_codec_is_decoder);
}
函数调用关系图
- avcodec_find_encoder()和avcodec_find_decoder()的函数调用关系图如下所示。
find_encdec()
- find_encdec()中有一个循环,该循环会遍历AVCodec结构的链表,逐一比较输入的ID和每一个编码器的ID,直到找到ID取值相等的编码器。
- 在这里有几点需要注意:
- remap_deprecated_codec_id()用于将一些过时的编码器ID映射到新的编码器ID。
- 版本差异很大
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;} elsereturn p;}}return experimental;
}
av_codec_is_encoder()
- av_codec_is_encoder()是一个判断AVCodec是否为编码器的函数。如果是编码器,返回非0值,否则返回0。
-
从源代码可以看出,av_codec_is_encoder()判断了一下AVCodec是否包含了encode()或者encode_sub()接口函数。
int av_codec_is_encoder(const AVCodec *avcodec)
{const FFCodec *const codec = ffcodec(avcodec);return codec && (codec->cb_type == FF_CODEC_CB_TYPE_ENCODE ||codec->cb_type == FF_CODEC_CB_TYPE_ENCODE_SUB ||codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_PACKET);
}
enum FFCodecType {/* The codec is a decoder using the decode callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_DECODE,/* The codec is a decoder using the decode_sub callback;* subtitle codecs only. */FF_CODEC_CB_TYPE_DECODE_SUB,/* The codec is a decoder using the receive_frame callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_RECEIVE_FRAME,/* The codec is an encoder using the encode callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_ENCODE,/* The codec is an encoder using the encode_sub callback;* subtitle codecs only. */FF_CODEC_CB_TYPE_ENCODE_SUB,/* The codec is an encoder using the receive_packet callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_RECEIVE_PACKET,
};
枚举 FFCodecType {/* 编解码器是使用解码回调的解码器;* 仅限音频和视频编解码器。 */FF_CODEC_CB_TYPE_DECODE,/* 编解码器是使用 decode_sub 回调的解码器;* 仅字幕编解码器。 */FF_CODEC_CB_TYPE_DECODE_SUB,/* 编解码器是使用接收帧回调的解码器;* 仅限音频和视频编解码器。 */FF_CODEC_CB_TYPE_RECEIVE_FRAME,/* 编解码器是使用编码回调的编码器;* 仅限音频和视频编解码器。 */FF_CODEC_CB_TYPE_ENCODE,/* 编解码器是使用 encode_sub 回调的编码器;* 仅字幕编解码器。 */FF_CODEC_CB_TYPE_ENCODE_SUB,/* 编解码器是一个使用 receive_packet 回调的编码器;* 仅限音频和视频编解码器。 */FF_CODEC_CB_TYPE_RECEIVE_PACKET,
};
av_codec_is_decoder()
- av_codec_is_decoder()是一个判断AVCodec是否为解码器的函数。如果是解码器,返回非0值,否则返回0。
-
从源代码可以看出,av_codec_is_decoder()判断了一下AVCodec是否包含了decode()或者decode_sub()接口函数。
int av_codec_is_decoder(const AVCodec *avcodec)
{const FFCodec *const codec = ffcodec(avcodec);return codec && (codec->cb_type == FF_CODEC_CB_TYPE_DECODE ||codec->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB ||codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME);
}
enum FFCodecType {/* The codec is a decoder using the decode callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_DECODE,/* The codec is a decoder using the decode_sub callback;* subtitle codecs only. */FF_CODEC_CB_TYPE_DECODE_SUB,/* The codec is a decoder using the receive_frame callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_RECEIVE_FRAME,/* The codec is an encoder using the encode callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_ENCODE,/* The codec is an encoder using the encode_sub callback;* subtitle codecs only. */FF_CODEC_CB_TYPE_ENCODE_SUB,/* The codec is an encoder using the receive_packet callback;* audio and video codecs only. */FF_CODEC_CB_TYPE_RECEIVE_PACKET,
};