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

📄 mpeg2dec.c

📁 DVD转换到AVI的源代码
💻 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
};

static void GOPBack(void);
static void InitialDecoder(void);

DWORD WINAPI MPEG2Dec(LPVOID n)
{
	int i, code;

	Stop_Flag = Rip_Flag = Fault_Flag = 0;
	Frame_Number = Second_Field = 0;
	VOB_ID = CELL_ID = 0;
	Sound_Max = 1; Bitrate_Meter = 0;

	for(i=0; i<CHANNEL; i++)
	{
		ZeroMemory(&mpa[i], sizeof(MPAStream));	
		ZeroMemory(&ac3[i], sizeof(AC3Stream));
	}

	ZeroMemory(&pcm, sizeof(struct PCMStream));
	ZeroMemory(&CH, sizeof(CH));

	switch (process.locate)
	{
		case LOCATE_FORWARD:
			process.startfile = process.file;
			process.startloc = (process.lba + 2) * BUFFER_SIZE;

			process.end = process.total - BUFFER_SIZE;
			process.endfile = File_Limit - 1;
			process.endloc = (process.length[File_Limit-1]/BUFFER_SIZE - 1) * BUFFER_SIZE;
			break;

		case LOCATE_BACKWARD:
			process.startfile = process.file;
			process.startloc = (process.lba - 2) * BUFFER_SIZE;

			process.end = process.total - BUFFER_SIZE;
			process.endfile = File_Limit - 1;
			process.endloc = (process.length[File_Limit-1]/BUFFER_SIZE - 1)*BUFFER_SIZE;

			GOPBack();
			break;

		case LOCATE_RIP:
			process.startfile = process.leftfile;
			process.startloc = process.leftlba * BUFFER_SIZE;
			process.endfile = process.rightfile;
			process.endloc = (process.rightlba - 1) * BUFFER_SIZE;

			process.run = 0;
			for (i=0; i<process.startfile; i++)
				process.run += process.length[i];
			process.start = process.run + process.startloc;

			process.end = 0;
			for (i=0; i<process.endfile; i++)
				process.end += process.length[i];
			process.end += process.endloc;
			break;
	}

	// search MPEG-2 Sequence Header
	if (!Check_Flag)
	{
		File_Flag = 0;
		_lseeki64(Infile[0], 0, SEEK_SET);
		Initialize_Buffer();

		while (!Check_Flag)
		{
			next_start_code();
			code = Get_Bits(32);

			switch (code)
			{
				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 * 0.8f : frame_rate;

	if (D2V_Flag)
	{
		fprintf(D2VFile, "\nSystem_Stream=%d\n", SystemStream_Flag);
		fprintf(D2VFile, "iDCT_Algorithm=%d\n", iDCT_Flag);
		fprintf(D2VFile, "YUVRGB_Scale=%d\n", Scale_Flag);
		if (Luminance_Flag)
		{
			fprintf(D2VFile, "Lum_Gain=%d\n", (short)LumGainMask);
			fprintf(D2VFile, "Lum_Offset=%d\n", (short)LumOffsetMask);
		}
		else
		{
			fprintf(D2VFile, "Lum_Gain=128\n");
			fprintf(D2VFile, "Lum_Offset=0\n");
		}
		fprintf(D2VFile, "Field_Operation=%d\n", FO_Flag);
		fprintf(D2VFile, "Frame_Rate=%d\n\n", (int)(Frame_Rate*1000));
		fprintf(D2VFile, "%d %X %d %X", process.leftfile, (int)process.leftlba, process.rightfile, (int)process.rightlba);
	}

	File_Flag = process.startfile;
	_lseeki64(Infile[process.startfile], (process.startloc/BUFFER_SIZE)*BUFFER_SIZE, SEEK_SET);
	Initialize_Buffer();

	process.op = 0;

	while (Get_Hdr() && picture_coding_type!=I_TYPE);		// search I

	Rip_Flag = 1;
	process.file = d2v_current.file;		// location
	process.lba = d2v_current.lba;

	Decode_Picture();

	while (Get_Hdr() && picture_coding_type==B_TYPE);		// search I or P

	Decode_Picture();

	process.op = timeGetTime();

	/* loop through the rest of the pictures in the sequence */
	while (Get_Hdr())
	{
		Decode_Picture();

		if (Stop_Flag)
		{
			Fault_Flag = 99;
			Write_Frame(NULL, d2v_current, 0);
		}
	}

	return 0;
}

static void GOPBack()
{
	int startfile;
	__int64 startloc, endloc;

	startfile = process.startfile;
	startloc = process.startloc;

	for (;;)
	{
		endloc = startloc + BUFFER_SIZE;
		startloc -= BUFFER_SIZE<<4;

		if (startloc > 0)
		{
			process.startfile = startfile;
			process.startloc = startloc;
		}
		else
		{
			process.startloc = 0;
			return;
		}

		_lseeki64(Infile[process.startfile], process.startloc, SEEK_SET);
		Initialize_Buffer();

		while (Get_Hdr() && _telli64(Infile[process.startfile]) <= endloc)
		{
			if (picture_coding_type==I_TYPE)
			{
				process.startfile = d2v_current.file;
				process.startloc = d2v_current.lba * BUFFER_SIZE;
				return;
			}
		}
	}
}

static void InitialDecoder()
{
	char *ext, szTemp[_MAX_PATH];
	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];

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

	ResizeWindow(Coded_Picture_Width, Coded_Picture_Height);

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

	CheckDirectDraw(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;

	// -----------------------------------------------------------------------------------------

	ext = strrchr(Infilename[0], '\\');
	strncpy(szTemp, ext+1, strlen(Infilename[0])-(int)(ext-Infilename[0]));
	sprintf(szBuffer, "DVD2AVI - %s", szTemp);

	if (File_Limit > 1)
	{
		strcat(szBuffer, " ~ ");
		ext = strrchr(Infilename[File_Limit-1], '\\');
		strncpy(szTemp, ext+1, strlen(Infilename[File_Limit-1])-(int)(ext-Infilename[File_Limit-1]));
		strcat(szBuffer, szTemp);
	}

	sprintf(szTemp, " %d x %d", Coded_Picture_Width, Coded_Picture_Height);
	strcat(szBuffer, szTemp);
	SetWindowText(hWnd, szBuffer);
}

⌨️ 快捷键说明

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