FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()
=====================================================
FFmpeg的库函数源代码分析文章列表:
【架构图】
【通用】
FFmpeg 源代码简单分析:av_register_all()
FFmpeg 源代码简单分析:avcodec_register_all()
FFmpeg 源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)
FFmpeg 源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)
FFmpeg 源代码简单分析:av_find_decoder()和av_find_encoder()
FFmpeg 源代码简单分析:avcodec_open2()
FFmpeg 源代码简单分析:avcodec_close()
【解码】
图解FFMPEG打开媒体的函数avformat_open_input
FFmpeg 源代码简单分析:avformat_open_input()
FFmpeg 源代码简单分析:avformat_find_stream_info()
FFmpeg 源代码简单分析:av_read_frame()
FFmpeg 源代码简单分析:avcodec_decode_video2()
FFmpeg 源代码简单分析:avformat_close_input()
【编码】
FFmpeg 源代码简单分析:avformat_alloc_output_context2()
FFmpeg 源代码简单分析:avformat_write_header()
FFmpeg 源代码简单分析:avcodec_encode_video()
FFmpeg 源代码简单分析:av_write_frame()
FFmpeg 源代码简单分析:av_write_trailer()
【其它】
FFmpeg源代码简单分析:日志输出系统(av_log()等)
FFmpeg源代码简单分析:结构体成员管理系统-AVClass
FFmpeg源代码简单分析:结构体成员管理系统-AVOption
FFmpeg源代码简单分析:libswscale的sws_getContext()
FFmpeg源代码简单分析:libswscale的sws_scale()
FFmpeg源代码简单分析:libavdevice的avdevice_register_all()
FFmpeg源代码简单分析:libavdevice的gdigrab
【脚本】
【H.264】
=====================================================
本文记录FFmpeg的两个API函数:avcodec_find_encoder()和avcodec_find_decoder()。avcodec_find_encoder()用于查找FFmpeg的编码器,avcodec_find_decoder()用于查找FFmpeg的解码器。
avcodec_find_encoder()的声明位于libavcodec\avcodec.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);
函数的参数是一个编码器的ID,返回查找到的编码器(没有找到就返回NULL)。
avcodec_find_decoder()的声明也位于libavcodec\avcodec.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);
函数的参数是一个解码器的ID,返回查找到的解码器(没有找到就返回NULL)。
avcodec_find_encoder()函数最典型的例子可以参考:
最简单的基于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()的源代码位于libavcodec\utils.c,如下所示。
AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
return find_encdec(id, 1);
}
从源代码可以看出avcodec_find_encoder()调用了一个find_encdec(),注意它的第二个参数是0。
下面我们看一下find_encdec()的定义。
find_encdec()
find_encdec()的源代码位于libavcodec\utils.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()中有一个循环,该循环会遍历AVCodec结构的链表,逐一比较输入的ID和每一个编码器的ID,直到找到ID取值相等的编码器。
在这里有几点需要注意:
(1)first_avcodec是一个全局变量,存储AVCodec链表的第一个元素。
(2)remap_deprecated_codec_id()用于将一些过时的编码器ID映射到新的编码器ID。
(3)函数的第二个参数encoder用于确定查找编码器还是解码器。当该值为1的时候,用于查找编码器,此时会调用av_codec_is_encoder()判断AVCodec是否为编码器;当该值为0的时候,用于查找解码器,此时会调用av_codec_is_decoder()判断AVCodec是否为解码器。
av_codec_is_encoder()
av_codec_is_encoder()是一个判断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()判断了一下AVCodec是否包含了encode2()或者encode_sub()接口函数。
av_codec_is_decoder()
av_codec_is_decoder()是一个判断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()判断了一下AVCodec是否包含了decode()接口函数。
avcodec_find_decoder()
avcodec_find_decoder()的源代码位于libavcodec\utils.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
FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()的更多相关文章
- FFmpeg源代码简单分析:libavdevice的gdigrab
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:libavdevice的avdevice_register_all()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:configure
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:makefile
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:libswscale的sws_scale()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:libswscale的sws_getContext()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:结构体成员管理系统-AVOption
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:结构体成员管理系统-AVClass
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- FFmpeg源代码简单分析:日志输出系统(av_log()等)
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
随机推荐
- 2015 多校联赛 ——HDU5410(dp)
Sample Input 1 100 2 10 2 1 20 1 1 Sample Output 21 题意:共有m元钱和n种东西,求每种单价p,而且你买x个该种物品可以得到Ax+B个,求m元钱最 ...
- ●BZOJ 2560 串珠子
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2560 题解: 容斥,状压计数dp 首先求出一个数组 g[s] 表示集合内的点的连边方案数(两 ...
- MySql查询不区分大小写解决方案(两种)
当我们输入不管大小写都能查询到数据,例如:输入 aaa 或者aaA ,AAA都能查询同样的结果,说明查询条件对大小写不敏感. 解决方案一: 于是怀疑Mysql的问题.做个实验:直接使用客户端用sql查 ...
- Redis实现单点登录
http://blog.csdn.net/WuCourage/article/details/77802812
- prop与attr的区别
与prop一样attr也可以用来获取与设置元素的属性. 区别在于,对于自定义属性和选中属性的处理. 选中属性指的是 checked,selected 这2种属性 1. 对于自定义属性 attr能够获取 ...
- js将当前时间格式化为年-月-日 时:分:秒
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js页面刷新跳转的几种方式及区别
跳转常用方法: window.location.href="index.php"; window.history.back(-1);//类似于按钮,参数是负几,就后退几次. win ...
- Prometheus(转载)
Prometheus 系统监控方案 一 https://www.cnblogs.com/vovlie/p/Prometheus_CONCEPTS.html 最近一直在折腾时序类型的数据库,经过一段时间 ...
- 网易笔试题:浏览器中输入一个url后回车到返回页面信息的过程
You enter a URL into the browser输入一个url地址 The browser looks up the IP address for the domain name浏览器 ...
- 渗透测试环境DVWA搭建
一.DVWA介绍 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供 ...