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

📄 vfapidec.c

📁 DVD转换到AVI的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
 *	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. 
 *
 */

#define GLOBAL
#include "global.h"
#include "vfapi.h"
#include "getbit.h"

#define MAX_FRAME_NUMBER	1000000
#define MAX_GOP_SIZE		1024

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

typedef struct {
	DWORD		number;
	int			file;
	__int64		position;
}	GOPLIST;
GOPLIST *GOPList[MAX_FRAME_NUMBER];

typedef struct {
	DWORD			top;
	DWORD			bottom;
	unsigned char	forward:1;
	unsigned char	backward:1;
}	FRAMELIST;
FRAMELIST *FrameList[MAX_FRAME_NUMBER];

static unsigned char *GOPBuffer[MAX_GOP_SIZE];
static BOOL Field_Order, Full_Frame;

__forceinline static void RGBCopyodd(unsigned char *src, unsigned char *dst, int pitch, int forward);
__forceinline static void RGBCopyeven(unsigned char *src, unsigned char *dst, int pitch, int forward);

int Open_D2VFAPI(char *path, D2VFAPI *out)
{
	DWORD i, j, size, code, type, tff, rff, film, ntsc, gop, top, bottom, mapping;
	int repeat_on, repeat_off, repeat_init;
	char ID[19], PASS[19] = "DVD2AVIProjectFile";

	ZeroMemory(out, sizeof(D2VFAPI));

	out->VF_File = fopen(path, "r");
	if (fgets(ID, 19, out->VF_File)==NULL)
		return 0;
	if (strcmp(ID, PASS))
		return 0;

	fscanf(out->VF_File, "%d", &File_Limit);

	i = File_Limit;
	while (i)
	{
		fscanf(out->VF_File, "%d ", &j);
		fgets(Infilename[File_Limit-i], j+1, out->VF_File);
		if ((Infile[File_Limit-i] = _open(Infilename[File_Limit-i], _O_RDONLY | _O_BINARY))==-1)
			return 0;
		i--;
	}

	fscanf(out->VF_File, "\nSystem_Stream=%d\n", &SystemStream_Flag);
	File_Flag = 0;
	_lseeki64(Infile[0], 0, SEEK_SET);

	Initialize_FPU_IDCT();
	Initialize_REF_IDCT();
	Initialize_Buffer();

	do
	{
		next_start_code();
		code = Get_Bits(32);
	}
	while (code!=SEQUENCE_HEADER_CODE);

	sequence_header();

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

	qheightd2 = Coded_Picture_Height / 4 - 2;
	hheightd2 = Coded_Picture_Height / 2 - 2;
	hwidth = Coded_Picture_Width / 2;
	hwidthd8 = Coded_Picture_Width / 2 - 8;
	dwidth = Coded_Picture_Width * 2;
	twidth = Coded_Picture_Width * 3;
	swidth = Coded_Picture_Width * 6;
	area = Coded_Picture_Width * Coded_Picture_Height;

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

	p_fTempArray = (void *)malloc(sizeof(float)*128 + 64);
	fTempArray = (void *)((long)p_fTempArray + 64 - (long)p_fTempArray%64);

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

	fscanf(out->VF_File, "iDCT_Algorithm=%d\n", &IDCT_Flag);
	fscanf(out->VF_File, "YUVRGB_Scale=%d\n", &Scale_Flag);

	if (Scale_Flag)
	{
		YUVRGB_Scale = 0x1000254310002543;
		YUVRGB_Offset = 0x0010001000100010;
	}
	else
	{
		YUVRGB_Scale = 0x1000200010002000;
		YUVRGB_Offset = 0x0000000000000000;
	}

	fscanf(out->VF_File, "Lum_Gain=%d\n", &i);
	fscanf(out->VF_File, "Lum_Offset=%d\n", &j);

	if (i==128 && j==0)
		Luminance_Flag = 0;
	else
	{
		Luminance_Flag = 1;
		LumGainMask = ((__int64)i<<48) + ((__int64)i<<32) + ((__int64)i<<16) + (__int64)i;
		LumOffsetMask = ((__int64)j<<48) + ((__int64)j<<32) + ((__int64)j<<16) + (__int64)j;

		lum = (unsigned char*)malloc(Coded_Picture_Width * Coded_Picture_Height);
	}

	fscanf(out->VF_File, "Field_Operation=%d\n", &FO_Flag);
	fscanf(out->VF_File, "Frame_Rate=%d\n\n", &(out->VF_FrameRate));

	fscanf(out->VF_File, "%d %X ", &i, &j);
	fscanf(out->VF_File, "%d %X", &i, &j);

	ntsc = film = top = bottom = gop = mapping = repeat_on = repeat_off = repeat_init = 0;

	while (fscanf(out->VF_File, "%d", &type) && type<9)
	{
		if (type==7)	// I frame
		{
			GOPList[gop] = calloc(1, sizeof(GOPLIST));
			GOPList[gop]->number = film;
			fscanf(out->VF_File, "%d %X", &(GOPList[gop]->file), &j);

			GOPList[gop]->position = (__int64)j*BUFFER_SIZE;
			gop ++;

			fscanf(out->VF_File, "%d", &j);
			tff = j>>1;
			rff = j & 1;
		}
		else	// P, B frame
		{
			tff = type>>1;
			rff = type & 1;
		}

		if (!film)
		{
			if (tff)
				Field_Order = 1;
			else
				Field_Order = 0;
		}

		if (FO_Flag==FO_FILM)
		{
			if (rff)
				repeat_on++;
			else
				repeat_off++;

			if (repeat_init)
			{
				if (repeat_off-repeat_on == 5)
				{
					repeat_on = repeat_off = 0;
				}
				else
				{
					FrameList[mapping] = calloc(1, sizeof(FRAMELIST));
					FrameList[mapping]->top = FrameList[mapping]->bottom = film;
					mapping ++;
				}

				if (repeat_on-repeat_off == 5)
				{
					repeat_on = repeat_off = 0;
					FrameList[mapping] = calloc(1, sizeof(FRAMELIST));
					FrameList[mapping]->top = FrameList[mapping]->bottom = film;
					mapping ++;
				}
			}
			else
			{
				if (repeat_off-repeat_on == 3)
				{
					repeat_on = repeat_off = 0;
					repeat_init = 1;
				}
				else
				{
					FrameList[mapping] = calloc(1, sizeof(FRAMELIST));
					FrameList[mapping]->top = FrameList[mapping]->bottom = film;
					mapping ++;
				}

				if (repeat_on-repeat_off == 3)
				{
					repeat_on = repeat_off = 0;
					repeat_init = 1;

					FrameList[mapping] = calloc(1, sizeof(FRAMELIST));
					FrameList[mapping]->top = FrameList[mapping]->bottom = film;
					mapping ++;
				}
			}
		}
		else
		{
			if (top)
			{
				FrameList[ntsc]->bottom = film;
				ntsc ++;
				FrameList[ntsc] = calloc(1, sizeof(FRAMELIST));
				FrameList[ntsc]->top = film;
			}
			else if (bottom)
			{
				FrameList[ntsc]->top = film;
				ntsc ++;
				FrameList[ntsc] = calloc(1, sizeof(FRAMELIST));
				FrameList[ntsc]->bottom = film;
			}
			else
			{
				FrameList[ntsc] = calloc(1, sizeof(FRAMELIST));
				FrameList[ntsc]->top = film;
				FrameList[ntsc]->bottom = film;
				ntsc ++;
			}

			if (rff)
			{
				if (!top && !bottom)
					FrameList[ntsc] = calloc(1, sizeof(FRAMELIST));

				if (tff)
				{
					FrameList[ntsc]->top = film;
					top = 1;
				}
				else
				{
					FrameList[ntsc]->bottom = film;
					bottom = 1;
				}

				if (top && bottom)
				{
					top = bottom = 0;
					ntsc ++;
				}
			}
		}

		film ++;
	}

	out->VF_FrameBound = film;
	film -= 2;

	if (FO_Flag==FO_FILM)
	{
		while (FrameList[mapping-1]->top >= film)
			mapping --;

		out->VF_FrameLimit = mapping;
	}
	else
	{
		if (FO_Flag==FO_SWAP)
		{
			Field_Order = !Field_Order;

			if (Field_Order)
				for (i=0; i<ntsc-1; i++)
					FrameList[i]->bottom = FrameList[i+1]->bottom;
			else
				for (i=0; i<ntsc-1; i++)
					FrameList[i]->top = FrameList[i+1]->top;
		}

		while ((FrameList[ntsc-1]->top >= film) || (FrameList[ntsc-1]->bottom >= film))
			ntsc --;

		out->VF_FrameLimit = ntsc;

		for (i=0; i<out->VF_FrameLimit-1; i++)
			if (FrameList[i]->top==FrameList[i+1]->top || FrameList[i]->top==FrameList[i+1]->bottom ||
				FrameList[i]->bottom==FrameList[i+1]->top || FrameList[i]->bottom==FrameList[i+1]->bottom)
			{
				FrameList[i]->forward = 1;
				FrameList[i+1]->backward = 1;
			}
	}

	Full_Frame = 1;
	for (i=0; i<out->VF_FrameLimit; i++)
		if (FrameList[i]->top!=FrameList[i]->bottom)
		{
			Full_Frame = 0;
			break;
		}

	out->VF_GOPNow = out->VF_GOPLimit = gop;
	out->VF_OldFrame = out->VF_FrameLimit;
	out->VF_FrameSize = Coded_Picture_Width * Coded_Picture_Height * 3;

⌨️ 快捷键说明

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