FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()
发布时间:2020-12-13 20:15:08 所属栏目:PHP教程 来源:网络整理
导读:本文记录FFmpeg的两个API函数:avcodec_find_encoder()和avcodec_find_decoder()。avcodec_find_encoder()用于查找FFmpeg的编码器,avcodec_find_decoder()用于查找FFmpeg的解码器。 avcodec_find_encoder()的声明位于libavcodecavcodec.h,以下所示。 /** *
本文记录FFmpeg的两个API函数:avcodec_find_encoder()和avcodec_find_decoder()。avcodec_find_encoder()用于查找FFmpeg的编码器,avcodec_find_decoder()用于查找FFmpeg的解码器。 avcodec_find_encoder()的声明位于libavcodecavcodec.h,以下所示。 /**
* Find a registered encoder with a matching codec ID.
*
* @param id AVCodecID of the requested encoder
* @return An encoder if one was found,NULL otherwise.
*/
AVCodec *avcodec_find_encoder(enum AVCodecID id); 函数的参数是1个编码器的ID,返回查找到的编码器(没有找到就返回NULL)。avcodec_find_decoder()的声明也位于libavcodecavcodec.h,以下所示。 /**
* Find a registered decoder with a matching codec ID.
*
* @param id AVCodecID of the requested decoder
* @return A decoder if one was found,NULL otherwise.
*/
AVCodec *avcodec_find_decoder(enum AVCodecID id); 函数的参数是1个解码器的ID,返回查找到的解码器(没有找到就返回NULL)。 最简单的基于FFMPEG的视频编码器(YUV编码为H.264) avcodec_find_decoder()函数最典型的例子可以参考: 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采取SDL2.0) 其实这两个函数的实质就是遍历AVCodec链表并且取得符合条件的元素。有关AVCodec链表的建立可以参考文章: ffmpeg 源代码简单分析 : av_register_all()函数调用关系图avcodec_find_encoder()和avcodec_find_decoder()的函数调用关系图以下所示。avcodec_find_encoder()avcodec_find_encoder()的源代码位于libavcodecutils.c,以下所示。AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
return find_encdec(id,1);
} 从源代码可以看出avcodec_find_encoder()调用了1个find_encdec(),注意它的第2个参数是0。 下面我们看1下find_encdec()的定义。 find_encdec()find_encdec()的源代码位于libavcodecutils.c,以下所示。static AVCodec *first_avcodec;
static AVCodec *find_encdec(enum AVCodecID id,int encoder)
{
AVCodec *p,*experimental = NULL;
p = first_avcodec;
id= remap_deprecated_codec_id(id);
while (p) {
if ((encoder ? av_codec_is_encoder(p) : av_codec_is_decoder(p)) &&
p->id == id) {
if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) {
experimental = p;
} else
return p;
}
p = p->next;
}
return experimental;
} find_encdec()中有1个循环,该循环会遍历AVCodec结构的链表,逐1比较输入的ID和每个编码器的ID,直到找到ID取值相等的编码器。 在这里有几点需要注意: (1)first_avcodec是1个全局变量,存储AVCodec链表的第1个元素。 (2)remap_deprecated_codec_id()用于将1些过时的编码器ID映照到新的编码器ID。 (3)函数的第2个参数encoder用于肯定查找编码器还是解码器。当该值为1的时候,用于查找编码器,此时会调用av_codec_is_encoder()判断AVCodec是不是为编码器;当该值为0的时候,用于查找解码器,此时会调用av_codec_is_decoder()判断AVCodec是不是为解码器。 av_codec_is_encoder()av_codec_is_encoder()是1个判断AVCodec是不是为编码器的函数。如果是编码器,返回非0值,否则返回0。/**
* @return a non-zero number if codec is an encoder,zero otherwise
*/
int av_codec_is_encoder(const AVCodec *codec); av_codec_is_encoder()源代码很简单,以下所示。int av_codec_is_encoder(const AVCodec *codec)
{
return codec && (codec->encode_sub || codec->encode2);
} 从源代码可以看出,av_codec_is_encoder()判断了1下AVCodec是不是包括了encode2()或encode_sub()接口函数。 av_codec_is_decoder()av_codec_is_decoder()是1个判断AVCodec是不是为解码器的函数。如果是解码器,返回非0值,否则返回0。/**
* @return a non-zero number if codec is a decoder,zero otherwise
*/
int av_codec_is_decoder(const AVCodec *codec); av_codec_is_decoder()源代码也很简单,以下所示。int av_codec_is_decoder(const AVCodec *codec)
{
return codec && codec->decode;
} 从源代码可以看出,av_codec_is_decoder()判断了1下AVCodec是不是包括了decode()接口函数。avcodec_find_decoder()avcodec_find_decoder()的源代码位于libavcodecutils.c,以下所示。AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
return find_encdec(id,0);
} 可以看出avcodec_find_decoder()一样调用了find_encdec(),只是第2个参数设置为0。因此不再详细分析。leixiaohua1020@126.com http://blog.csdn.net/leixiaohua1020 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |