⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg2dec.c

📁 DIRECTSHOW 开发指南电子书
💻 C
字号:
/* 
 *	Copyright (C) Chia-chen Kuo - Jan 2001
 *
 *  This file is part of DVD2AVI, a free MPEG-2 decoder
 *	
 *  DVD2AVI is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  DVD2AVI is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 */

#include "global.h"
#include "getbit.h"

static int ChromaFormat[4] = {
	0, 6, 8, 12
};

void InitialDecoder(void);
void InitSystem(void);
void UninitSystem(void);
void ResetSystem(void);
void CheckSequenceHeader(void);

void InitialDecoder()
{
	int i, size;

	mb_width = (horizontal_size+15)/16;
	mb_height = progressive_sequence ? (vertical_size+15)/16 : 2*((vertical_size+31)/32);

	Coded_Picture_Width = 16 * mb_width;
	Coded_Picture_Height = 16 * mb_height;

	Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width : Coded_Picture_Width>>1;
	Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height : Coded_Picture_Height>>1;

	block_count = ChromaFormat[chroma_format];

	hheightd2 = Coded_Picture_Height / 2 - 2;
	qheightd2 = Coded_Picture_Height / 4 - 2;
	hwidth = Coded_Picture_Width / 2;
	hwidthd8 = Coded_Picture_Width / 2 - 8;
	dwidth = Coded_Picture_Width * 2;
	qwidth = Coded_Picture_Width * 4;
	nwidth = Coded_Picture_Width * 9;

	for (i=0; i<3; i++)
	{
		if (i==0)
			size = Coded_Picture_Width * Coded_Picture_Height;
		else
			size = Chroma_Width * Chroma_Height;

		backward_reference_frame[i] = (unsigned char*)malloc(size);
		forward_reference_frame[i] = (unsigned char*)malloc(size);
		auxframe[i] = (unsigned char*)malloc(size);
	}

	u422 = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height/2);
	v422 = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height/2);
	u444 = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height);
	v444 = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height);
	rgb24 = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height*3);
	yuy2 = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height*2);
	lum = (unsigned char*)malloc(Coded_Picture_Width*Coded_Picture_Height);

	ZeroMemory(&birgb, sizeof(BITMAPINFOHEADER));
	birgb.biSize = sizeof(BITMAPINFOHEADER);
	birgb.biWidth = Coded_Picture_Width;
	birgb.biHeight = Coded_Picture_Height;
	birgb.biPlanes = 1;
	birgb.biBitCount = 24;
	birgb.biCompression = BI_RGB;
	birgb.biSizeImage = Coded_Picture_Width * Coded_Picture_Height * 3;

	biyuv = birgb;
	biyuv.biBitCount = 16;
	biyuv.biCompression = mmioFOURCC('Y','U','Y','2');
	biyuv.biSizeImage = Coded_Picture_Width * Coded_Picture_Height * 2;
}

void CheckSequenceHeader(void)
{
	if (!Check_Flag)
	{
		SetCacheChecking();
		Initialize_Buffer();

		while (!Check_Flag)
		{
			next_start_code();
			switch (Get_Bits(32))
			{
			case PACK_START_CODE:
				SystemStream_Flag = 1;
				break;

			case SEQUENCE_HEADER_CODE:
				sequence_header();
				InitialDecoder();
				Check_Flag = 1;
				break;
			}
		}
		
		Frame_Rate = (FO_Flag==FO_FILM) ? frame_rate*4/5 : frame_rate;
		
		ResetCacheChecking();   // Reuse the cache header
		Initialize_Buffer();
	}
}

void InitSystem(void)
{
	int  i;
	Stop_Flag = Rip_Flag = Fault_Flag = 0;
	Frame_Number = Second_Field = 0;
	VOB_ID = CELL_ID = 0;
	Bitrate_Meter = 0;
	SystemStream_Flag = 0;

	for (i = 0; i < 8; i++)
	{
		p_block[i] = (short *)malloc(sizeof(short)*64 + 64);
		block[i]   = (short *)((long)p_block[i] + 64 - (long)p_block[i]%64);
	}
	
	Initialize_REF_IDCT();
	Initialize_FPU_IDCT();
	
	iDCT_Flag  = IDCT_MMX;
	FO_Flag    = FO_NONE;
	Scale_Flag = TRUE;
	if (Scale_Flag)
	{
		YUVRGB_Scale  = 0x1000254310002543;
		YUVRGB_Offset = 0x0010001000100010;
	}
	else
	{
		YUVRGB_Scale  = 0x1000200010002000;
		YUVRGB_Offset = 0x0000000000000000;
	}

	Luminance_Flag     = 0;
	gIsPictureDecoding = FALSE;
	gIsEOS = FALSE; 
}

void UninitSystem(void)
{
	int i;
	if (Check_Flag)
	{
		for (i=0; i<3; i++)
		{
			free(backward_reference_frame[i]);
			free(forward_reference_frame[i]);
			free(auxframe[i]);
		}

		free(u422);
		free(v422);
		free(u444);
		free(v444);
		free(rgb24);
		free(yuy2);
		free(lum);
	}
	Check_Flag = 0;

	// Added by luqiming
	for (i = 0; i < 8; i++)
	{
		if (p_block[i])
		{
			free(p_block[i]);
			p_block[i] = 0;
		}		
	}
}

void ResetSystem(void)
{
	int  i, size;
	Stop_Flag = Rip_Flag = Fault_Flag = 0;
	Frame_Number = Second_Field = 0;
	VOB_ID = CELL_ID = 0;
	Bitrate_Meter = 0;

	// Reset all buffers
	if (Check_Flag)
	{
		for (i = 0; i < 3; i++)
		{
			if (i==0)
				size = Coded_Picture_Width * Coded_Picture_Height;
			else
				size = Chroma_Width * Chroma_Height;
			ZeroMemory(backward_reference_frame[i], size);
			ZeroMemory(forward_reference_frame[i], size);
			ZeroMemory(auxframe[i], size);
		}
		size = Coded_Picture_Width*Coded_Picture_Height;
		ZeroMemory(u422, size/2);
		ZeroMemory(v422, size/2);
		ZeroMemory(u444, size);
		ZeroMemory(v444, size);
		ZeroMemory(rgb24, size*3);
		ZeroMemory(yuy2, size*2);
		ZeroMemory(lum, size);
	}
	for (i = 0; i < 8; i++)
	{
		ZeroMemory(p_block[i], sizeof(short)*64 + 64);
	}

	Initialize_REF_IDCT();
	Initialize_FPU_IDCT();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -