参考链接
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;
} else
return 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,
};