代码实现:mpeg-2文件分析器代码实现ide
一个完整的MPEG-2文件就是一个PS流文件。spa
MPEG-2文件的构造格式以下图:.net
本身找个mpg文件打开,能够看到文件以0x0000 01B9结束(有些文件不标准没有),即MPEG_Program_end_code,以前有不少个0x0000 00BA字段,即为program pack的开始标志,program pack包的构造以下:rest
能够看出program pack由3部分组成:pack_header+system_header+PES_packets,其中system_header当且仅当pack是第一个数据包时才存在。system_header和PES_packets构造以下:code
对照文件内容,各字段顺序、长度以下:orm
pack_header: 起始地址:0x0000 0000(这个地址有可能由于文件不同而不同) 视频
标志:0x00 0x00 0x01 0xBA(4B)
struct PackHeader
{
unsigned paddingByte : 2;
unsigned program_clock_reference_base : 3;
unsigned marker1 : 1;
unsigned SCR_base1 : 15;
unsigned marker2 : 1;
unsigned SCR_base2 : 15;
unsigned marker3 : 1;
unsigned SCR_externsion : 9;
unsigned marker4 : 1;
unsigned mutiplex_rate : 22;
unsigned marker5 : 1;
unsigned marker6 : 1;
unsigned reserved : 5;
unsigned stuffing_length : 3;
};
system_header: 起始地址:0x0000 000eip
标志(4B):0x00 0x00 0x01 0xBB (4B)
struct SystemHeader//112bit
{
unsigned head_length : 16;
unsigned marker1 : 1;
unsigned rate_bound : 22;
unsigned marker2 : 1;
unsigned audio_bound : 6;
unsigned fixed_flag : 1;
unsigned CSPS_flag : 1;
unsigned system_audio_local_flag : 1;
unsigned system_video_local_flag : 1;
unsigned marker3 : 1;
unsigned video_bound : 5;
unsigned packet_rate_restriction_flag <span style="white-space:pre"> </span>: 1;
unsigned reserved : 7;
unsigned stream_id1 : 8;
unsigned paddingByte1 : 2;
unsigned P_STD_buffer_bound_scale1 : 1;
unsigned P_STD_buffer_size_bound1 : 13;
unsigned stream_id2 : 8;
unsigned paddingByte2 : 2;
unsigned P_STD_buffer_bound_scale2 : 1;
unsigned P_STD_buffer_size_bound2 : 13;
};
PES packet:起始地址:0x0000 0020
标志位(3B):0x 00 00 01
stream_id(1B):0xBE(BE为Padding stream)
PES_packet_length(2B):0x07 DA,跳过该长度的填充字节,恰好为下一个pack的起始标志:0x000001BA
从0x0800地址开始为第二个pack包,该包的构造格式为pack_header+PES,分析以下:
pack_header: 起始地址:0x0000 0800
(此包上面已经讲到,这里再也不赘述)
PES packet:起始地址:0x0000 080e
标志位(3B):0x 00 00 01
stream_id(1B):0xE0(视频)
struct PESPacket
{
unsigned PES_packet_length : 16;
unsigned paddingByte1 : 2;
unsigned scrambling_control : 2;
unsigned priority : 1;
unsigned alignment : 1;
unsigned copyright : 1;
unsigned original : 1;
unsigned PTS_DTS_flag : 2;
unsigned ESCR_flag : 1;
unsigned ES_rate_flag : 1;
unsigned DSM_trick_mode_flag : 1;
unsigned additional_copy_info_flag : 1;
unsigned CRC_flag : 1;
unsigned extension_flag : 1;
unsigned PES_header_data_length : 8;
unsigned paddingByte2 : 4;
unsigned PTS_32_30 : 3;//pts 的第32-30位
unsigned marker1 : 1;
unsigned PTS_29_15 : 15;//pts的第29-15位
unsigned marker2 : 1;
unsigned PTS_14_0 : 15;//pts的第14-0位(共33位)
unsigned marker3 : 1;
unsigned paddingByte3 : 4;
unsigned DTS_32_30 : 3;
unsigned marker4 : 1;
unsigned DTS_29_15 : 15;
unsigned marker5 : 1;
unsigned DTS_14_0 : 15;
unsigned marker6 : 1;
};
Video Sequence,其结构定义以下:
图中sequence_header,sequence entension等子内容定义以下:
对各字段顺序、长度分析以下:
sequence header:起始地址:0x0000 0821
标志位(4B):0x00 0x00 0x01 0xB3
struct SequenceHeader
{
unsigned horizontal_size : 12;
unsigned vertical_size : 12;
unsigned aspect_ratio_info : 4;
unsigned frame_rate : 4;
unsigned bit_rate : 18;
unsigned marker : 1;
unsigned VBV_buffer_size : 10;
unsigned constrained : 1;
unsigned load_intra_Q_matrix : 1;
unsigned paddingBit : 1;
};
sequence extension:起始地址:0x0000 082d;若是有这一项说明是MPEG-2文件,不然为MPEG-1文件
标志位(4B):0x0000 01B5
struct SequenceExtension
{
unsigned start_code_identifer : 4;
unsigned profile_level_escape : 1;
unsigned profile_level : 7;
unsigned progressive : 1;
unsigned chroma : 2;
unsigned horiz_extension : 2;
unsigned vertical_extension : 2;
};
接下来的数据是0x0000 01B8,说明该序列中没有extension&user data[i](extension data的开始符为0x0000 01B5,user data的开始符为0x0000 01B2),接下来的内容为Group of pictures header。
Group_of_pictures_header:起始地址:0x0000 0837
标志位(4B):0x0000 01B8
struct GroupOfPicturesHeader
{
unsigned time_code : 25;
unsigned closed_gop : 1;
unsigned broken_link : 1;
};
extension & user data[1]:无
picture header: 起始地址:0x0000 083F
标志位(4B):0x0000 0100
struct PictureHeader
{
unsigned temporal_reference : 10;
unsigned picture_coding_type : 3;
unsigned vbv_delay : 16;
unsigned extra_bit_piture : 1;
};
picture coding extension:起始地址:0x0000 0847
extension_start_code(4B):0x0000 01B5
struct PictureCodingExtension
{
unsigned extension_start_code_identifier : 4;
unsigned f_code_0_0 : 4;
unsigned f_code_0_1 : 4;
unsigned f_code_1_0 : 4;
unsigned f_code_1_1 : 4;
unsigned intra_dc_presison : 2;
unsigned picture_structure : 2;
unsigned top_field_first : 1;
unsigned frame_pred_frame_dct : 1;
unsigned concealment_motion_vectors : 1;
unsigned q_scale_type : 1;
unsigned intra_vlc_format : 1;
unsigned alternate_scan : 1;
unsigned repeat_first_field : 1;
unsigned chroma_420_type : 1;
unsigned progressive_frame : 2;
unsigned composite_display_flag : 2;
};
extension & user data[2]:无
picture data: 起始地址:0x0000 0850(暂时未分析,之后补上)