FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()
来源:互联网 发布:阿里云视频点播服务 编辑:程序博客网 时间:2024/06/08 16:10
=====================================================
FFmpeg的库函数源代码分析文章列表:
【架构图】
FFmpeg源代码结构图 - 解码
FFmpeg源代码结构图 - 编码
【通用】
FFmpeg 源代码简单分析:av_register_all()
FFmpeg 源代码简单分析:avcodec_register_all()
FFmpeg 源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)
FFmpeg 源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)
FFmpeg 源代码简单分析:avio_open2()
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
【脚本】
FFmpeg源代码简单分析:makefile
FFmpeg源代码简单分析:configure
【H.264】
FFmpeg的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)。
最简单的基于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函数简单分析:av_find_decoder()和av_find_encoder()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : av_read_frame()
- ffmpeg 源代码简单分析 : avcodec_decode_video2()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 :av_read_frame()
- ffmpeg源代码简单分析 :avcodec_decode_video2()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : av_read_frame()
- ffmpeg 源代码简单分析 : avcodec_decode_video2()
- ffmpeg 源代码简单分析 : av_register_all()
- ffmpeg 源代码简单分析 : avcodec_register_all()
- ffmpeg 源代码简单分析 : av_read_frame()
- ffmpeg 源代码简单分析 : avcodec_decode_video2()
- iOS开发网络数据之AFNetworking使用
- j2se线程使用的两种方法
- C++中的static关键字
- HTTP POST GET 本质区别详解
- Android命令行测试BT,WIFI,Sensor工作状态
- FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()
- 【javaSE】Date和Calendar类
- SSH整合例子 Struts2 Spring3 Hibernate3 注解
- 数据加密与保存
- android中的ViewPager+Fragment+RadioGroup导航样式的实现
- opencv三帧差分法运动检测
- Java并发编程:volatile关键字解析
- Android APK反编译就这么简单 详解(附图)
- tomcat8008端口被占用 (is used already)