Ffmpeg解析media容器过程/ ffmpeg 源代码简单分析 : av_read_frame()

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),
};

时间: 2025-01-04 11:26:24

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

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

===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg的HEVC解码器源代码简单分析:概述 FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分 FFmpeg的HEVC解码器源代码简单分析:解码器主干部分 FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU FFmpeg的HEVC解码器源代码简单

FFmpeg源代码简单分析:avformat_open_input()

本文简单分析FFmpeg中一个常用的函数:avformat_open_input().该函数用于打开多媒体数据并且获得一些相关的信息.它的声明位于libavformat\avformat.h,如下所示. /** * Open an input stream and read the header. The codecs are not opened. * The stream must be closed with avformat_close_input(). * * @param ps Po

(转)FFmpeg源代码简单分析:avformat_open_input()

目录(?)[+] ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 FFmpeg源代码结构图 - 编码 [通用] FFmpeg 源代码简单分析:av_register_all() FFmpeg 源代码简单分析:avcodec_register_all() FFmpeg 源代码简单分析:内存的分配和释放(av_malloc().av_free()等)

FFmpeg与libx264接口源代码简单分析

===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x264源代码简单分析:x264命令行工具(x264.exe) x264源代码简单分析:编码器主干部分-1 x264源代码简单分析:编码器主干部分-2 x264源代码简单分析:x264_slice_write() x264源代码简单分析:滤波(Filter)部分 x264源代码简单分析:宏块分析(Anal

FFmpeg源代码简单分析:av_write_trailer()

打算写两篇文章简单分析FFmpeg的写文件用到的3个函数avformat_write_header(),av_write_frame()以及av_write_trailer().这篇文章继续分析av_write_trailer(). av_write_trailer()用于输出文件尾,它的声明位于libavformat\avformat.h,如下所示. /** * Write the stream trailer to an output media file and free the * fi

(转)FFmpeg源代码简单分析:avformat_find_stream_info()

目录(?)[+] ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 FFmpeg源代码结构图 - 编码 [通用] FFmpeg 源代码简单分析:av_register_all() FFmpeg 源代码简单分析:avcodec_register_all() FFmpeg 源代码简单分析:内存的分配和释放(av_malloc().av_free()等)

FFmpeg的HEVC解码器源代码简单分析:解码器主干部分

本文分析FFmpeg的libavcodec中的HEVC解码器的主干部分."主干部分"是相对于"CTU解码". "环路滤波"这些细节部分而言的.它包含了HEVC解码器直到hls_decode_entry()前面的函数调用关系(hls_decode_entry()后面就是HEVC解码器的细节部分,主要包含了"CTU解码". "环路滤波"2个部分). 函数调用关系图 FFmpeg HEVC解码器主干部分在整个HE

FFmpeg的H.264解码器源代码简单分析:解码器主干部分

本文分析FFmpeg的H.264解码器的主干部分."主干部分"是相对于"熵解码"."宏块解码"."环路滤波"这些细节部分而言的.它包含了H.264解码器直到decode_slice()前面的函数调用关系(decode_slice()后面就是H.264解码器的细节部分,主要包含了"熵解码"."宏块解码"."环路滤波"3个部分). 函数调用关系图 解码器主干部分的源代码在

FFmpeg源代码简单分析:avformat_find_stream_info()

本文简单分析FFmpeg中一个常用的函数:avformat_find_stream_info().该函数可以读取一部分视音频数据并且获得一些相关的信息.avformat_find_stream_info()的声明位于libavformat\avformat.h,如下所示. /** * Read packets of a media file to get stream information. This * is useful for file formats with no headers s