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 ...
随机推荐
- 控制公司 Controlling Companies
题目描述 有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分.(此处略去一句废话)据说,如果至少满足了以下三个条件之一,公司A就可以控制公司B了: 公司A = 公司B. 公司A拥 ...
- 51 nod 1023 石子归并 V3(GarsiaWachs算法)
1023 石子归并 V3基准时间限制:2 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一 ...
- [APIO2014]
T1.回文树裸题. #include<cstdio> #include<iostream> #define ll long long using namespace std; ...
- win7+Apache 设置域名指向本地文件夹
实现:浏览器地址栏输入 www.bnzoo.com 访问 D:/www 系统:win7旗舰版+Apache 步骤: 1.打开文件 C:\Windows\System32\drivers\etc\hos ...
- C语言 字符串 字符串处理操作 字符串与函数
字符数组的定义和初始化 宏常量+1 强调了字符串的最大强度 推荐忽略长度的定义 不能对所指向的存储单元内容修改,除非是字符串数组的定义 因为指针变量指向的是字符串数组的值,可以被修改. 未初始化 字 ...
- 小白的Python之路_day1
Python 与 java 对比,代码更为简洁. Python 3.X 版本 Hello World 程序: print("Hello World!") java Hello Wo ...
- java中的构造,封装
今天给大家讲一下面向对象中的构造,封装: 构造:构造方法有以下几个特点:1.方法名和类名一致.2.无返回类型.接下来的几种构造样式,直接上代码吧: //这是一个宠物类 有一个属性:名字(name) p ...
- vmware迁移到openstack的一些坑
title: 安全平台迁移 tags: 新建,模板,小书匠 grammar_cjkRuby: true --- 前言 主要有三个坑: 一是如果原先虚拟机没有安装virtio驱动,要设置设备驱动为ide ...
- eclipse安装和配置Gradle插件
配置: 首先下载Gradle:https://gradle.org/gradle-download/ 设置Gradle环境变量: GRADLE_HOME %GRADLE_HOME%\bin" ...
- Luogu P1919 【模板】A*B Problem升级版(FFT快速傅里叶_FFT
这其实就是一道裸的FFT 核心思想:把两个数拆成两个多项式用FFT相乘,再反序输出 py解法如下: input() print(int(input())*int(input())) 皮一下hihi f ...