首页 > 代码库 > 代码实现分析mpeg-2文件

代码实现分析mpeg-2文件

1、概述

把上一篇文章中讲到的mpeg-2文件结构分析用代码实现,结合mpeg-2文件分析。才easy看懂。

2、代码

/*
*本程序主要分析MPEG-2文件
*作者:缪国凯(MK)
*821486004@qq.com
*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;
}


3、project下载地址

http://download.csdn.net/detail/dancing_night/8888147

代码实现分析mpeg-2文件