FFmpeg av_find_input_format函数剖析

简介:
AVInputFormat结构体
AVInputFormat 每种码流输入格式(例如h264,FLV, MKV, MP4, AVI)对应一个结构体,用来保存视音频的解码参数,目前以h264码流格式为例,描述结构体成员:
name:封装格式名称简写(short_name)[h264]
long_name:码流输入格式的长名称[raw H.264 video]
extensions:码流输入格式的扩展名[h26l,h264,264,avc]
raw_codec_id:码流输入格式ID[28]
read_packet:avformat-57.dll!0x000007fee101ca90 (加载符号以获取其他信息)
read_header:avformat-57.dll!0x000007fee101cb70 (加载符号以获取其他信息)

关键函数:int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
read_packet函数读取一个AVPacket,然后放在pkt,这个函数在进行分帧
av_read_frame函数的里面会被调用到,调用相应的解码器获取一帧的完整数据


问题:各种码流输入格式是什么时候被加载的?
回答:当第一次调用av_register_all的时候就会注册复用器,其中就包含了各种码流的输入格式的处理函数

查看调用关系
av_register_all
    register_all
        REGISTER_MUXDEMUX(H264,             h264);
            #define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x)

#define REGISTER_MUXER(X, x)                                            \
    {                                                                   \
        extern AVOutputFormat ff_##x##_muxer;                           \
        if (CONFIG_##X##_MUXER)                                         \
            av_register_output_format(&ff_##x##_muxer);                 \
    }

#define REGISTER_DEMUXER(X, x)                                          \
    {                                                                   \
        extern AVInputFormat ff_##x##_demuxer;                          \
        if (CONFIG_##X##_DEMUXER)                                       \
            av_register_input_format(&ff_##x##_demuxer);                \
    }

看看注册码流输入格式的函数
void av_register_input_format(AVInputFormat *format)
{
    AVInputFormat **p = last_iformat;

    // Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
    while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
        p = &(*p)->next;

    if (!format->next)
        last_iformat = &format->next;
}
其中关键的全局变量是
static AVInputFormat *first_iformat = NULL;
static AVInputFormat **last_iformat = &first_iformat;
保存了所有码流格式

AVInputFormat *av_iformat_next(const AVInputFormat *f)
{
    if (f)
        return f->next;
    else
        return first_iformat;
}

AVInputFormat *av_find_input_format(const char *short_name)
{
    AVInputFormat *fmt = NULL;
    while ((fmt = av_iformat_next(fmt)))//获取解码器的链表指针,
        if (av_match_name(short_name, fmt->name))//根据输入的码流格式简写,轮询链表查找解码器
            return fmt;
    return NULL;
}

在avformat_open_input函数优化篇就直接指定码流的输入格式,从而减少了探测码流格式的时间

参考
http://blog.csdn.net/leixiaohua1020/article/details/12677129

http://blog.csdn.net/neustar1/article/details/38231937


     本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1983060,如需转载请自行联系原作者




相关文章
|
1月前
FFmpeg中结构释放小函数
本文介绍了FFmpeg中用于释放不同结构体内存的泛化变参模板函数CleanUp,以及如何特化该模板以释放AVFormatContext、AVCodecContext、AVPacket、AVFrame和uint8_t*类型的内存,并提供了一个测试文件来演示这些函数的使用。
24 3
|
4月前
|
存储 编解码 容器
FFmpeg avformat_open_input() 函数返回错误protocol not found解决方法(实测有效!附简单FFMPEG的编解码流程)
我个人出现这个错误的时候是在打开文件时报的错误,开始以为我需要加上资源文件,那样QT确实能检测到文件的存在,但是在Debug中他是检测不到这个文件的。
479 1
|
6月前
|
编解码 算法 C++
【ffmpeg 基础函数】详解FFmpeg中的av_packet_ref函数
【ffmpeg 基础函数】详解FFmpeg中的av_packet_ref函数
64 0
|
6月前
|
编解码 测试技术
ffmpeg中的时间单位以及时间转换函数(av_q2d av_rescale_q)
ffmpeg中的时间单位以及时间转换函数(av_q2d av_rescale_q)
172 0
|
6月前
|
算法
FFmpeg关键函数介绍
FFmpeg关键函数介绍
48 0
|
6月前
|
API 开发工具 C语言
解决新版本ffmpeg找不到avpriv_io_delete函数等问题
解决新版本ffmpeg找不到avpriv_io_delete函数等问题
100 0
|
编解码 Android开发
【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
433 0
【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
|
Android开发 C++
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
224 0
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)