ffmpeg 源代码简单分析 : av_read_frame()

http://blog.csdn.net/leixiaohua1020/article/details/12678577

ffmpeg中的av_read_frame()的作用是读取码流中的音频若干帧或者视频一帧。例如,解码视频的时候,每解码一个视频帧,需要先调 用 av_read_frame()获得一帧视频的压缩数据,然后才能对该数据进行解码(例如H.264中一帧压缩数据通常对应一个NAL)。

对该函数源代码的分析是很久之前做的了,现在翻出来,用博客记录一下。

上代码之前,先参考了其他人对av_read_frame()的解释,在此做一个参考:


过av_read_packet(***),读取一个包,需要说明的是此函数必须是包含整数帧的,不存在半帧的情况,以ts流为例,是读取一个完整的
PES包(一个完整pes包包含若干视频或音频es包),读取完毕后,通过av_parser_parse2(***)分析出视频一帧(或音频若干帧),
返回,下次进入循环的时候,如果上次的数据没有完全取完,则st =
s->cur_st;不会是NULL,即再此进入av_parser_parse2(***)流程,而不是下面的
av_read_packet(**)流程,这样就保证了,如果读取一次包含了N帧视频数据(以视频为例),则调用
av_read_frame(***)N次都不会去读数据,而是返回第一次读取的数据,直到全部解析完毕。

http://hi.baidu.com/cuihuanyubupt/item/75f21dfbd2f18e1fff358229

Ffmpeg解析media容器过程

1)调用av_read_frame函数

如果packet_buffer存在数据,根据pts返回AVPacket

如果packet_buffer不存在数据调用函数av_read_frame_internal

在 ffmpeg中实现了将format格式的packet,最终转换成一帧帧的packet,并解析填充了packet的pts,dts,等信息,为最终解 码提供了重要的数据,av_read_frame_internal,调用av_read_packet,每次只读取一个包,然后直到parser完这个 包的所有数据,才开始读取下一个包,parser完的数据被保存在parser结构的数据缓冲中,这样即使av_read_packet读取的下一包和前 一包的流不一样,由于parser也不一样,所以实现了av_read_frame_internal这个函数调用,可以解析出不同流的es流,而 av_read_frame_internal函数除非出错否则必须解析出一帧数据才能返回

调用函数av_parser_parse2(***)分析出视频一帧(或音频若干帧)

2)ffmpeg对媒体容器格式封装在AVInputFormat结构体中,如:

AVInputFormat ff_w64_demuxer = {

"w64",

NULL_IF_CONFIG_SMALL("SonyWave64 format"),

sizeof(WAVContext),

w64_probe,

w64_read_header,

wav_read_packet,

NULL,

wav_read_seek,

.flags = AVFMT_GENERIC_INDEX,

.codec_tag = (const AVCodecTag*const []){ff_codec_wav_tags, 0},

};

对格式定义了read_header,read_packet,read_seek函数,来读数据

3)ffmpeg定义AVCodecParser用来对不同视频编码标准,分析出一个完整的一帧,如

AVCodecParser ff_h264_parser = {

{ CODEC_ID_H264 },

sizeof(H264Context),

init,

h264_parse,

close,

h264_split,

};

h.264的parser

4)h.264 decoder

AVCodec ff_h264_decoder = {
    "h264",
    AVMEDIA_TYPE_VIDEO,
    CODEC_ID_H264,
    sizeof(H264Context),
    ff_h264_decode_init,
    NULL,
    ff_h264_decode_end,
    decode_frame,
    /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY |
        CODEC_CAP_FRAME_THREADS |
        CODEC_CAP_SLICE_THREADS,
    .flush= flush_dpb,
    .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
    .init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
    .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),
    .profiles = NULL_IF_CONFIG_SMALL(profiles),
};

Ffmpeg解析media容器过程/ ffmpeg 源代码简单分析 : av_read_frame()的更多相关文章

  1. FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  2. FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  3. FFmpeg源代码简单分析:configure

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  4. FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  5. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  6. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  7. FFmpeg的HEVC解码器源代码简单分析:概述

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  8. FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  9. FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

随机推荐

  1. [转]ubuntu错误解决E: Sub-process /usr/bin/dpkg returned an error code (1)

    [转]ubuntu错误解决E: Sub-process /usr/bin/dpkg returned an error code (1) http://yanue.net/post-123.html ...

  2. 42.JTAG接口使用注意

    无论是客户反馈,还是自己亲身经历,USB-Blaster不能下载配置FPGA的情况时有出现.究其原因,大致有如下几条: 1. FPGA器件上的JTAG相关引脚出现故障: 2. USB-Blaster坏 ...

  3. 如何给ActiveX控件添加“事件”“属性”“标准事件”“自定义事件”等一些相关操作

    上一篇小编带大家熟悉了一下ActiveX的建立以及相关的概念,(http://blog.csdn.net/u014028070/article/details/38424611) 本文介绍下如何给控件 ...

  4. VC++ MFC 如何实现在编辑框中输出具有换行功能的文段 01

    很久不来写东西了,昨天睡觉前写个小工具,突然,这玩意不会换行怎么整... 首先是第一步,获取字符串的长度,转载自白乔的文章. ------------------------------------- ...

  5. nodejs tools

    1.supervisor npm install supervisor -g supervisor app.js cd public cd bin supervisor www http://www. ...

  6. Android下写一个永远不会被KILL掉的进程/服务

    Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用.当系统觉得当前的资源非常有限的时候,为了保证一些优先级高的程序能运行,就会杀掉一些 ...

  7. android 怎么动态设置button 的style

    网上找了很多,还是没有直接的解决办法,button没有setstyle这个方法.因此我的解决办法如下: 直接动态设置各个属性 Button themeBtn = new Button(this); t ...

  8. 【BZOJ】【3163】【HEOI2013】Eden的新背包问题

    多重背包/思路题 多次询问,每次从所有物品中忽略一件,问最大收益…… 这题我用的zyf的一个“暴力”做法,就是先预处理出来g1[i][j]表示1~i号物品花了j块钱的最大价值,g2[i][j]表示i~ ...

  9. log4j 配置实例

    1. http://hehongwei44.iteye.com/blog/1494999 2. http://maymay.iteye.com/blog/1275432 #log4j.rootLogg ...

  10. __int64 与long long 的区别 分类: Brush Mode 2014-08-14 10:22 64人阅读 评论(0) 收藏

    //为了和DSP兼容,TSint64和TUint64设置成TSint40和TUint40一样的数 //结果VC中还是认为是32位的,显然不合适 //typedef signed long int    ...