1、概述
把上一篇文章中讲到的mpeg-2文件结构分析用代码实现,结合mpeg-2文件分析。才easy看懂。
2、代码
/*
*本程序主要分析MPEG-2文件
*作者:缪国凯(MK)
*[email protected]
*2015-7-8
*/ #include "stdafx.h" #define PRINTLOG PrintLog enum PESTYPE
{
AUDIOPES = 0,
VIDEOPES
}; void Pack_header(FILE *p);
void AnalysisSystemHeader(FILE *p);
void AnalysisPes(FILE *p, BYTE type);
void Sequence_header(FILE*p, WORD &length);
void Sequence_extension(FILE *p, WORD &length);
void Group_of_pictures_header(FILE *p, WORD &length);
void Picture_header(FILE *p, WORD &length);
void picture_coding_extension(FILE *p, WORD &length); FILE *pLogFile = NULL; void PrintLog (const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stdout,fmt,ap);//输出到屏幕
if (NULL != pLogFile)
{
vfprintf(pLogFile,fmt,ap);//输出一份到文件
}
va_end(ap);
} void help()
{
printf("**********************************************\n");
printf("Usage:\n");
printf(" mpeg2Container [inputfile] [logfile(default)]\n");
printf("\n");
printf("Examples: \n");
printf(" mpeg2Container test.mpg log.txt\n");
printf("or you can use like this: \n");
printf(" mpeg2Container test.mpg\n");
printf("the above command will write log with logFile.txt\n");
printf("**********************************************\n");
} int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
help();
return -1;
} if (argc >= 3)
{
pLogFile = fopen(argv[2], "w");
if (NULL == pLogFile)
{
PrintLog("can not write log file %s!\n", argv[2]);
}
}
else
{
pLogFile = fopen("logFile.txt", "w");
if (NULL == pLogFile)
{
PrintLog("can not write log file logFile.txt!\n");
}
} FILE *p = NULL;
p = fopen(argv[1], "rb");
if (NULL == p)
{
PrintLog("can not open input file!\n");
goto end;
}
BYTE tmp[4];
bool bFirstPack = true;
int address = 0;
while(1)
{
//把文件读取位置移动到能被2整除的位置
address = ftell(p);
if (address % 2 != 0)
{
fseek(p, -1, SEEK_CUR);
}
memset(tmp, 0, 4);
int sizet = fread(tmp, 1, 2, p);
if(2 != sizet)
{
break;
}
if (tmp[0] == 0x00 && tmp[1] == 0x00)
{
sizet = fread(tmp, 1, 2, p);
if(2 != sizet)
{
break;
} if (tmp[0] == 0x01 && tmp[1] == 0xBA)//Program Pack
{
PRINTLOG("this is a program pack-----adrees:0x%08x\n", ftell(p) - sizet -2);
Pack_header(p);
}
else if (tmp[0] == 0x01 && tmp[1] == 0xBB)//system header
{
PRINTLOG("this is a system pack-----adrees:0x%08x\n", ftell(p) - sizet - 2);
AnalysisSystemHeader(p);
}
else if (tmp[0] == 0x01 && tmp[1] == 0xB9)//end mark
{
PRINTLOG("this is the file end------adrees:0x%08x\n", ftell(p) - sizet - 2);
}
else if (tmp[0] == 0x01 && tmp[1] == 0xBE)//padding stream pes
{
PRINTLOG("this is a padding pes------adrees:0x%08x\n", ftell(p) - sizet - 2);
}
else if (tmp[0] == 0x01 && (tmp[1] >= 0xE0 && tmp[1] < 0xf0))//pes header 111x xxxx video
{
PRINTLOG("this is a video pes pack-----adrees:0x%08x\n", ftell(p) - sizet - 2);
AnalysisPes(p, VIDEOPES);
}
else if (tmp[0] == 0x01 && (tmp[1] >= 0xC0 && tmp[1] < 0xE0))//pes header 11xx xxxx audio
{
PRINTLOG("this is a audio pes pack-----adrees:0x%08x\n", ftell(p) - sizet - 2);
AnalysisPes(p, AUDIOPES);
}
else
{
//假设遇到 00 00 00 00,不倒回去 就会推断出错
fseek(p, -2, SEEK_CUR);
}
}
}
end:
if (NULL != pLogFile)
{
fclose(pLogFile);
}
if (NULL != p)
{
fclose(p);
}
return 0;
} 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;
}; void Pack_header(FILE *p)
{
//这个包没什么意义,就不解析了
} 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 : 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;
}; void AnalysisSystemHeader(FILE *p)
{
BYTE tmpL[2];
if (2 != fread(tmpL, 1, 2, p))
{
return;
}
WORD tmpLength = 0;
tmpLength |= tmpL[0] << 8;
tmpLength |= tmpL[1];
if (tmpLength >= 12)
{
fseek(p, -2, SEEK_CUR);
}
else
{
return;
} BYTE *tmp = new BYTE[sizeof(SystemHeader)];
memset(tmp, 0, sizeof(SystemHeader)); SystemHeader tmpSystemHeader;
memset(&tmpSystemHeader, 0, sizeof(SystemHeader));
int size = sizeof(SystemHeader);
size = /*sizeof(SystemHeader)*/14;
int sizet = size;
sizet = fread(tmp, 1, size, p);
if (size != sizet)
{
return;
}
tmpSystemHeader.head_length |= tmp[0] << 8;
tmpSystemHeader.head_length |= tmp[1]; tmpSystemHeader.marker1 |= tmp[2] >> 7;
tmpSystemHeader.rate_bound |= tmp[2] << 15;
tmpSystemHeader.rate_bound |= tmp[3] << 7;
tmpSystemHeader.rate_bound |= tmp[4] >> 1;
tmpSystemHeader.marker2 |= tmp[4]; tmpSystemHeader.audio_bound |= tmp[5] >> 2;
tmpSystemHeader.fixed_flag |= tmp[5] >> 1;
tmpSystemHeader.CSPS_flag |= tmp[5]; tmpSystemHeader.system_audio_local_flag |= tmp[6] >> 7;
tmpSystemHeader.system_video_local_flag |= tmp[6] >> 6;
tmpSystemHeader.marker3 |= tmp[6] >> 5;
tmpSystemHeader.video_bound |= tmp[6]; tmpSystemHeader.packet_rate_restriction_flag |= tmp[7] >> 7;
tmpSystemHeader.reserved |= tmp[7]; tmpSystemHeader.stream_id1 |= tmp[8]; tmpSystemHeader.paddingByte1 |= tmp[9] >> 6;
tmpSystemHeader.P_STD_buffer_bound_scale1 |= tmp[9] >> 5;
tmpSystemHeader.P_STD_buffer_size_bound1 |= tmp[9] << 8;
tmpSystemHeader.P_STD_buffer_size_bound1 |= tmp[10]; tmpSystemHeader.stream_id2 |= tmp[11]; tmpSystemHeader.paddingByte2 |= tmp[12] >> 6;
tmpSystemHeader.P_STD_buffer_bound_scale2 |= tmp[12] >> 5;
tmpSystemHeader.P_STD_buffer_size_bound2 |= tmp[12] << 8;
tmpSystemHeader.P_STD_buffer_size_bound2 |= tmp[13]; PRINTLOG("head_length = 0x%02x\n", tmpSystemHeader.head_length); PRINTLOG("marker1 = 0x%02x\n", tmpSystemHeader.marker1);
PRINTLOG("rate_bound = 0x%02x\n", tmpSystemHeader.rate_bound);
PRINTLOG("marker2 = 0x%02x\n", tmpSystemHeader.marker2); PRINTLOG("audio_bound = 0x%02x\n", tmpSystemHeader.audio_bound);
PRINTLOG("fixed_flag = 0x%02x\n", tmpSystemHeader.fixed_flag);
PRINTLOG("CSPS_flag = 0x%02x\n", tmpSystemHeader.CSPS_flag); PRINTLOG("system_audio_local_flag = 0x%02x\n", tmpSystemHeader.system_audio_local_flag);
PRINTLOG("system_video_local_flag = 0x%02x\n", tmpSystemHeader.system_video_local_flag);
PRINTLOG("marker3 = 0x%02x\n", tmpSystemHeader.marker3);
PRINTLOG("video_bound = 0x%02x\n", tmpSystemHeader.video_bound); PRINTLOG("packet_rate_restriction_flag = 0x%02x\n", tmpSystemHeader.packet_rate_restriction_flag);
PRINTLOG("reserved = 0x%02x\n", tmpSystemHeader.reserved); PRINTLOG("stream_id1 = 0x%02x\n", tmpSystemHeader.stream_id1); PRINTLOG("paddingByte1 = 0x%02x\n", tmpSystemHeader.paddingByte1);
PRINTLOG("P_STD_buffer_bound_scale1 = 0x%02x\n", tmpSystemHeader.P_STD_buffer_bound_scale1);
PRINTLOG("P_STD_buffer_size_bound1 = 0x%02x\n", tmpSystemHeader.P_STD_buffer_size_bound1); PRINTLOG("stream_id2 = 0x%02x\n", tmpSystemHeader.stream_id2); PRINTLOG("paddingByte2 = 0x%02x\n", tmpSystemHeader.paddingByte2);
PRINTLOG("P_STD_buffer_bound_scale2 = 0x%02x\n", tmpSystemHeader.P_STD_buffer_bound_scale2);
PRINTLOG("P_STD_buffer_size_bound2 = 0x%02x\n", tmpSystemHeader.P_STD_buffer_size_bound2); delete[] tmp;
} 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;
}; void AnalysisPes(FILE *p, BYTE type)
{
WORD length;
BYTE tmpL[2];
//read the header length
int sizet = fread(&tmpL, 1, 2, p);
if(2 != sizet)
{
return;
} length = tmpL[0] << 8 | tmpL[1];
PRINTLOG("length = %d\n", length); if (length >= 15)
{
fseek(p, -2, SEEK_CUR); BYTE *tmp = new BYTE[sizeof(PESPacket)];
PESPacket tmpPESPacket;
memset(&tmpPESPacket, 0, sizeof(PESPacket)); int size = /*sizeof(SequenceHeader)*/15;
int sizet = size; sizet = fread(tmp, 1, size, p);
length -= sizet;
if (size != sizet)
{
return;
}
tmpPESPacket.PES_packet_length = tmp[0] << 8 | tmp[1]; tmpPESPacket.paddingByte1 |= tmp[2] >> 6;
tmpPESPacket.scrambling_control |= tmp[2] >> 4;
tmpPESPacket.priority |= tmp[2] >> 3;
tmpPESPacket.alignment |= tmp[2] >> 2;
tmpPESPacket.copyright |= tmp[2] >> 1;
tmpPESPacket.original |= tmp[2]; tmpPESPacket.PTS_DTS_flag |= tmp[3] >> 6;
tmpPESPacket.ESCR_flag |= tmp[3] >> 5;
tmpPESPacket.ES_rate_flag |= tmp[3] >> 4;
tmpPESPacket.DSM_trick_mode_flag |= tmp[3] >> 3;
tmpPESPacket.additional_copy_info_flag |= tmp[3] >> 2;
tmpPESPacket.CRC_flag |= tmp[3] >> 1;
tmpPESPacket.extension_flag |= tmp[3]; tmpPESPacket.PES_header_data_length |= tmp[4]; tmpPESPacket.paddingByte2 |= tmp[5] >> 4;
tmpPESPacket.PTS_32_30 |= tmp[5] >> 1;
tmpPESPacket.marker1 |= tmp[5]; tmpPESPacket.PTS_29_15 |= tmp[6] << 7;
tmpPESPacket.PTS_29_15 |= tmp[7] >> 1;
tmpPESPacket.marker2 |= tmp[7]; tmpPESPacket.PTS_14_0 |= tmp[8] << 7;
tmpPESPacket.PTS_14_0 |= tmp[9] >> 1;
tmpPESPacket.marker3 |= tmp[9]; tmpPESPacket.paddingByte3 |= tmp[10] >> 4;
tmpPESPacket.DTS_32_30 |= tmp[10] >> 1;
tmpPESPacket.marker4 |= tmp[10]; tmpPESPacket.DTS_29_15 |= tmp[11] << 7;
tmpPESPacket.DTS_29_15 |= tmp[12] >> 1;
tmpPESPacket.marker5 |= tmp[12]; tmpPESPacket.DTS_14_0 |= tmp[13] << 7;
tmpPESPacket.DTS_14_0 |= tmp[14] >> 1;
tmpPESPacket.marker6 |= tmp[14]; PRINTLOG("PES_packet_length = 0x%04x\n", tmpPESPacket.PES_packet_length);
PRINTLOG("scrambling_control = 0x%04x\n", tmpPESPacket.scrambling_control);
PRINTLOG("priority = 0x%04x\n", tmpPESPacket.priority);
PRINTLOG("alignment = 0x%04x\n", tmpPESPacket.alignment);
PRINTLOG("copyright = 0x%04x\n", tmpPESPacket.copyright);
PRINTLOG("original = 0x%04x\n", tmpPESPacket.original);
PRINTLOG("PTS_DTS_flag = 0x%04x\n", tmpPESPacket.PTS_DTS_flag);
PRINTLOG("ESCR_flag = 0x%04x\n", tmpPESPacket.ESCR_flag);
PRINTLOG("ES_rate_flag = 0x%04x\n", tmpPESPacket.ES_rate_flag);
PRINTLOG("DSM_trick_mode_flag = 0x%04x\n", tmpPESPacket.DSM_trick_mode_flag);
PRINTLOG("additional_copy_info_flag = 0x%04x\n", tmpPESPacket.additional_copy_info_flag);
PRINTLOG("CRC_flag = 0x%04x\n", tmpPESPacket.CRC_flag);
PRINTLOG("extension_flag = 0x%04x\n", tmpPESPacket.extension_flag);
PRINTLOG("PES_header_data_length = 0x%04x\n", tmpPESPacket.PES_header_data_length); if (tmpPESPacket.PTS_DTS_flag == 3 || tmpPESPacket.PTS_DTS_flag == 2)
{
INT64 pts = 0;
pts |= tmpPESPacket.PTS_32_30 << 30;
pts |= tmpPESPacket.PTS_29_15 << 15;
pts |= tmpPESPacket.PTS_14_0;
PRINTLOG("PTS = 0x%04x\n", pts);
} if (tmpPESPacket.PTS_DTS_flag == 3)
{
INT64 dts = 0;
dts |= tmpPESPacket.DTS_32_30 << 30;
dts |= tmpPESPacket.DTS_29_15 << 15;
dts |= tmpPESPacket.DTS_14_0;
PRINTLOG("DTS = 0x%04x\n", dts);
} //有PESPacket不完整的情况(还没分析原因),这里跳回去。避免漏掉关键标志
fseek(p, -15, SEEK_CUR);
bool bHaveSequenceHeader = false;
bool bSequence_extension = false;
while(length > 4)
{
memset(tmp, 0, 8);
int sizet = fread(tmp, 1, 1, p);
length -= sizet;
if(1 != sizet)
{
break;
}
if (tmp[0] == 0x00)
{
memset(tmp, 0, 8);
int sizet = fread(tmp, 1, 3, p);
length -= sizet;
if(3 != sizet)
{
break;
} if (tmp[0] == 0x00 && tmp[1] == 0x01 && tmp[2] == 0xB3)//Sequence header
{
bHaveSequenceHeader = true;
PRINTLOG("this is a Sequence header-----adrees:0x%08x\n", ftell(p) - sizet - 1);
Sequence_header(p, length);
}
else if (tmp[0] == 0x00 && tmp[1] == 0x01 && tmp[2] == 0xB5)
{
if (bHaveSequenceHeader && !bSequence_extension)//Sequence extension
{
bSequence_extension = true;
PRINTLOG("this is a Sequence_extension-----adrees:0x%08x\n", ftell(p) - sizet - 1);
Sequence_extension(p, length);
}
else//picture_coding_extension
{
PRINTLOG("this is a picture coding extension-----adrees:0x%08x\n", ftell(p) - sizet - 1);
picture_coding_extension(p, length);
}
}
else if (tmp[0] == 0x00 && tmp[1] == 0x01 && tmp[2] == 0xB8)//Group_of_pictures_header
{
PRINTLOG("this is a Group_of_pictures_header-----adrees:0x%08x\n", ftell(p) - sizet - 1);
Group_of_pictures_header(p, length);
}
else if (tmp[0] == 0x00 && tmp[1] == 0x01 && tmp[2] == 0x00)//Picture_header
{
PRINTLOG("this is a Picture_header-----adrees:0x%08x\n", ftell(p) - sizet - 1);
Picture_header(p, length);
}
else
{
fseek(p, -3, SEEK_CUR);
length += 3;
}
}
}
delete[] tmp;
}
else
{
return;
}
} 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;
}; void Sequence_header(FILE*p, WORD &length)
{
if (length < sizeof(SequenceHeader))
{
return;
}
BYTE *tmp = new BYTE[sizeof(SequenceHeader)];
memset(tmp, 0, sizeof(SequenceHeader)); SequenceHeader tmpSequenceHeader;
memset(&tmpSequenceHeader, 0, sizeof(SequenceHeader));
int size = /*sizeof(SequenceHeader)*/8;
int sizet = size; sizet = fread(tmp, 1, size, p);
length -= sizet;
if (size != sizet)
{
return;
} tmpSequenceHeader.horizontal_size = tmp[0] << 4;
tmpSequenceHeader.horizontal_size |= tmp[1] >> 4; tmpSequenceHeader.vertical_size = tmp[2];
tmp[1] <<= 4;
tmpSequenceHeader.vertical_size |= tmp[1] << 4; tmpSequenceHeader.aspect_ratio_info = tmp[3] >> 4;
tmp[3] <<= 4;
tmpSequenceHeader.frame_rate = tmp[3] >> 4; tmpSequenceHeader.bit_rate = tmp[4] << 10;
tmpSequenceHeader.bit_rate |= tmp[5] << 2;
tmpSequenceHeader.bit_rate |= tmp[6] >> 6; tmpSequenceHeader.marker |= tmp[6] >> 5; tmpSequenceHeader.VBV_buffer_size = tmp[6] << 5;
tmpSequenceHeader.VBV_buffer_size |= tmp[7] >> 3; tmpSequenceHeader.constrained != tmp[7] >> 2;
tmpSequenceHeader.load_intra_Q_matrix != tmp[7] >> 1;
tmpSequenceHeader.paddingBit != tmp[7]; PRINTLOG("horizontal_size = 0x%04x\n", tmpSequenceHeader.horizontal_size);
PRINTLOG("vertical_size = 0x%04x\n", tmpSequenceHeader.vertical_size);
PRINTLOG("aspect_ratio_info = 0x%04x\n", tmpSequenceHeader.aspect_ratio_info);
PRINTLOG("frame_rate = 0x%04x\n", tmpSequenceHeader.frame_rate);
PRINTLOG("bit_rate = 0x%04x\n", tmpSequenceHeader.bit_rate);
PRINTLOG("VBV_buffer_size = 0x%04x\n", tmpSequenceHeader.VBV_buffer_size);
PRINTLOG("constrained = 0x%04x\n", tmpSequenceHeader.constrained);
PRINTLOG("load_intra_Q_matrix = 0x%04x\n", tmpSequenceHeader.load_intra_Q_matrix); delete[] tmp;
} 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;
}; void Sequence_extension(FILE *p, WORD &length)
{
int size = /*sizeof(SequenceExtension)*/3;
if (length < size)
{
return;
}
SequenceExtension tmpSequenceExtension;
memset(&tmpSequenceExtension, 0, sizeof(SequenceExtension)); BYTE *tmp = new BYTE[sizeof(SequenceExtension)];
memset(tmp, 0, sizeof(SequenceExtension)); int sizet = size;
sizet = fread(tmp, 1, size, p);
length -= sizet;
if (size != sizet)
{
return;
} tmpSequenceExtension.start_code_identifer = tmp[0] >> 4; //4bit 1th - 4th bit
tmpSequenceExtension.profile_level_escape |= tmp[0] >> 3; //1bit 5th bit tmpSequenceExtension.profile_level |= tmp[0] << 4; //7bit 6-8th bit
tmpSequenceExtension.profile_level |= tmp[1] >> 4; // 9-12th bit tmpSequenceExtension.progressive |= tmp[1] >> 3; //1bit 13th bit
tmpSequenceExtension.chroma |= tmp[1] >> 1; //2bit 14-15th bit tmpSequenceExtension.horiz_extension |= tmp[1] << 1; //2bit 16th bit
tmpSequenceExtension.horiz_extension |= tmp[2] >> 7; // 17th bit tmpSequenceExtension.vertical_extension |= tmp[2] >> 5; //2bit 18-19th bit PRINTLOG("start_code_identifer = 0x%04x\n", tmpSequenceExtension.start_code_identifer);
PRINTLOG("profile_level_escape = 0x%04x\n", tmpSequenceExtension.profile_level_escape);
PRINTLOG("profile_level = 0x%04x\n", tmpSequenceExtension.profile_level);
PRINTLOG("progressive = 0x%04x\n", tmpSequenceExtension.progressive);
PRINTLOG("chroma = 0x%04x\n", tmpSequenceExtension.chroma);
PRINTLOG("horiz_extension = 0x%04x\n", tmpSequenceExtension.horiz_extension);
PRINTLOG("vertical_extension = 0x%04x\n", tmpSequenceExtension.vertical_extension); delete[] tmp;
} struct GroupOfPicturesHeader
{
unsigned time_code : 25;
unsigned closed_gop : 1;
unsigned broken_link : 1;
}; void Group_of_pictures_header(FILE *p, WORD &length)
{
int size = /*sizeof(GroupOfPicturesHeader)*/4;
if (length < size)
{
return;
}
GroupOfPicturesHeader tmpGroupOfPicturesHeader;
memset(&tmpGroupOfPicturesHeader, 0, sizeof(GroupOfPicturesHeader)); BYTE *tmp = new BYTE[sizeof(GroupOfPicturesHeader)];
memset(tmp, 0, sizeof(GroupOfPicturesHeader)); int sizet = size;
sizet = fread(tmp, 1, size, p);
length -= sizet;
if (size != sizet)
{
return;
} tmpGroupOfPicturesHeader.time_code |= tmp[0] << 17;
tmpGroupOfPicturesHeader.time_code |= tmp[1] << 9;
tmpGroupOfPicturesHeader.time_code |= tmp[2] << 1;
tmpGroupOfPicturesHeader.time_code |= tmp[3] >> 7; tmpGroupOfPicturesHeader.closed_gop |= tmp[3] >> 6;
tmpGroupOfPicturesHeader.broken_link |= tmp[3] >> 5; PRINTLOG("time_code = 0x%04x\n", tmpGroupOfPicturesHeader.time_code);
PRINTLOG("closed_gop = 0x%04x\n", tmpGroupOfPicturesHeader.closed_gop);
PRINTLOG("broken_link = 0x%04x\n", tmpGroupOfPicturesHeader.broken_link); delete[] tmp;
} struct PictureHeader
{
unsigned temporal_reference : 10;
unsigned picture_coding_type : 3;
unsigned vbv_delay : 16;
unsigned extra_bit_piture : 1;
}; void Picture_header(FILE *p, WORD &length)
{
int size = /*sizeof(PictureHeader)*/4;
if (length < size)
{
return;
}
PictureHeader tmpPictureHeader;
memset(&tmpPictureHeader, 0, sizeof(PictureHeader)); BYTE *tmp = new BYTE[sizeof(PictureHeader)];
memset(tmp, 0, sizeof(PictureHeader)); int sizet = size;
sizet = fread(tmp, 1, size, p);
length -= sizet;
if (size != sizet)
{
return;
} tmpPictureHeader.temporal_reference |= tmp[0] << 2;
tmpPictureHeader.temporal_reference |= tmp[1] >> 6; tmpPictureHeader.picture_coding_type |= tmp[1] >> 3; tmpPictureHeader.vbv_delay |= tmp[1] << 13;
tmpPictureHeader.vbv_delay |= tmp[2] << 5;
tmpPictureHeader.vbv_delay |= tmp[3] >> 3; tmpPictureHeader.extra_bit_piture |= tmp[3] >> 2; PRINTLOG("temporal_reference = 0x%04x\n", tmpPictureHeader.temporal_reference);
PRINTLOG("picture_coding_type = 0x%04x\n", tmpPictureHeader.picture_coding_type);
PRINTLOG("vbv_delay = 0x%04x\n", tmpPictureHeader.vbv_delay);
PRINTLOG("extra_bit_piture = 0x%04x\n", tmpPictureHeader.extra_bit_piture); delete[] tmp;
} 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;
}; void picture_coding_extension(FILE *p, WORD &length)
{
int size = /*sizeof(PictureCodingExtension)*/5;
if (length < size)
{
return;
}
PictureCodingExtension tmpPictureCodingExtension;
memset(&tmpPictureCodingExtension, 0, sizeof(PictureCodingExtension)); BYTE *tmp = new BYTE[sizeof(PictureCodingExtension)];
memset(tmp, 0, sizeof(PictureCodingExtension)); int sizet = size;
sizet = fread(tmp, 1, size, p);
length -= sizet;
if (size != sizet)
{
return;
} tmpPictureCodingExtension.extension_start_code_identifier |= tmp[0] >> 4;
tmpPictureCodingExtension.f_code_0_0 |= tmp[0]; tmpPictureCodingExtension.f_code_0_1 |= tmp[1] >> 4;
tmpPictureCodingExtension.f_code_1_0 |= tmp[1]; tmpPictureCodingExtension.f_code_1_1 |= tmp[2] >> 4;
tmpPictureCodingExtension.intra_dc_presison |= tmp[2] >> 2;
tmpPictureCodingExtension.picture_structure |= tmp[2]; tmpPictureCodingExtension.top_field_first |= tmp[3] >> 7;
tmpPictureCodingExtension.frame_pred_frame_dct |= tmp[3] >> 6;
tmpPictureCodingExtension.concealment_motion_vectors |= tmp[3] >> 5;
tmpPictureCodingExtension.q_scale_type |= tmp[3] >> 4;
tmpPictureCodingExtension.intra_vlc_format |= tmp[3] >> 3;
tmpPictureCodingExtension.alternate_scan |= tmp[3] >> 2;
tmpPictureCodingExtension.repeat_first_field |= tmp[3] >> 1;
tmpPictureCodingExtension.chroma_420_type |= tmp[3]; tmpPictureCodingExtension.progressive_frame |= tmp[3] >> 6;
tmpPictureCodingExtension.composite_display_flag |= tmp[3] >> 4; PRINTLOG("extension_start_code_identifier = 0x%04x\n", tmpPictureCodingExtension.extension_start_code_identifier);
PRINTLOG("f_code_0_0 = 0x%04x\n", tmpPictureCodingExtension.f_code_0_0); PRINTLOG("f_code_0_1 = 0x%04x\n", tmpPictureCodingExtension.f_code_0_1);
PRINTLOG("f_code_1_0 = 0x%04x\n", tmpPictureCodingExtension.f_code_1_0); PRINTLOG("f_code_1_1 = 0x%04x\n", tmpPictureCodingExtension.f_code_1_1);
PRINTLOG("intra_dc_presison = 0x%04x\n", tmpPictureCodingExtension.intra_dc_presison);
PRINTLOG("picture_structure = 0x%04x\n", tmpPictureCodingExtension.picture_structure); PRINTLOG("top_field_first = 0x%04x\n", tmpPictureCodingExtension.top_field_first);
PRINTLOG("frame_pred_frame_dct = 0x%04x\n", tmpPictureCodingExtension.frame_pred_frame_dct);
PRINTLOG("concealment_motion_vectors = 0x%04x\n", tmpPictureCodingExtension.concealment_motion_vectors);
PRINTLOG("q_scale_type = 0x%04x\n", tmpPictureCodingExtension.q_scale_type);
PRINTLOG("intra_vlc_format = 0x%04x\n", tmpPictureCodingExtension.intra_vlc_format);
PRINTLOG("alternate_scan = 0x%04x\n", tmpPictureCodingExtension.alternate_scan);
PRINTLOG("repeat_first_field = 0x%04x\n", tmpPictureCodingExtension.repeat_first_field);
PRINTLOG("chroma_420_type = 0x%04x\n", tmpPictureCodingExtension.chroma_420_type); PRINTLOG("progressive_frame = 0x%04x\n", tmpPictureCodingExtension.progressive_frame);
PRINTLOG("composite_display_flag = 0x%04x\n", tmpPictureCodingExtension.composite_display_flag); delete[] tmp;
}