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

📄 getbit.c

📁 DVD转换到AVI的源代码
💻 C
字号:
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */

/*
 * Disclaimer of Warranty
 *
 * These software programs are available to the user without any license fee or
 * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
 * any and all warranties, whether express, implied, or statuary, including any
 * implied warranties or merchantability or of fitness for a particular
 * purpose.  In no event shall the copyright-holder be liable for any
 * incidental, punitive, or consequential damages of any kind whatsoever
 * arising from the use of these programs.
 *
 * This disclaimer of warranty extends to the user of these programs and user's
 * customers, employees, agents, transferees, successors, and assigns.
 *
 * The MPEG Software Simulation Group does not represent or warrant that the
 * programs furnished hereunder are free of infringement of any third-party
 * patents.
 *
 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
 * are subject to royalty fees to patent holders.  Many of these patents are
 * general enough such that they are unavoidable regardless of implementation
 * design.
 *
 */

/*
 * All modifications (mpeg2decode -> DVD2AVI) are Copyright (C) Chia-chen Kuo - Jan 2001
 */

#include "global.h"
#include "getbit.h"
#include "AC3Dec\ac3.h"

static unsigned char *FTType[5] = {
	"48KHz", "44.1KHz", "44.1KHz", "44.1KHz", "44.1KHz"
};

static unsigned char *AC3ModeDash[8] = {
	"1+1", "1_0", "2_0", "3_0", "2_1", "3_1", "2_2", "3_2"
};

static unsigned char PCM_Buffer[BUFFER_SIZE];
static short *ptrPCM_Buffer = (short*)PCM_Buffer;
static short *ptrAC3Dec_Buffer = (short*)AC3Dec_Buffer;

__forceinline static unsigned int Get_Short(void);

void Initialize_Buffer()
{
	Rdptr = Rdbfr + BUFFER_SIZE;
	Rdmax = Rdptr;

	if (SystemStream_Flag)
	{
		if (Rdptr >= Rdmax)
			Next_Packet();
		CurrentBfr = *Rdptr++ << 24;

		if (Rdptr >= Rdmax)
			Next_Packet();
		CurrentBfr += *Rdptr++ << 16;

		if (Rdptr >= Rdmax)
			Next_Packet();
		CurrentBfr += *Rdptr++ << 8;

		if (Rdptr >= Rdmax)
			Next_Packet();
		CurrentBfr += *Rdptr++;

		Fill_Next();
	}
	else
	{
		Fill_Buffer();

		CurrentBfr = (*Rdptr << 24) + (*(Rdptr+1) << 16) + (*(Rdptr+2) << 8) + *(Rdptr+3);
		Rdptr += 4;

		Fill_Next();
	}

	BitsLeft = 32;
}

void Next_Packet()
{
	static short volume;
	static int i, j, Packet_Length, Packet_Header_Length, size;
	static unsigned int code, AUDIO_ID, VOBCELL_Count, AC3_Track, MPA_Track;

	for (;;)
	{
		code = Get_Short();
		code = (code<<16) + Get_Short();

		// remove system layer byte stuffing
		while ((code & 0xffffff00) != 0x00000100)
			code = (code<<8) + Get_Byte();

		switch (code)
		{
			case PACK_START_CODE:
				Rdptr += 8;
				VOBCELL_Count = 0;
				break;

			case PRIVATE_STREAM_2:
				Packet_Length = Get_Short();

				if (++VOBCELL_Count==2)
				{
					Rdptr += 25;
					VOB_ID = Get_Short();
					CELL_ID = Get_Short();
					Rdptr += Packet_Length - 29;
				}
				else
					Rdptr += Packet_Length;
				break;

			case PRIVATE_STREAM_1:
				Packet_Length = Get_Short();

				Rdptr ++;
				code = Get_Byte();
				Packet_Header_Length = Get_Byte();

				if (code>=0x80)
				{
					code = Get_Byte();
					AudioPTS = (code & 0x0e) << 29;

					AudioPTS |= (Get_Short() & 0xfffe) << 14;
					AudioPTS |= (Get_Short()>>1) & 0x7fff;
					AudioPTS /= 90;

					Rdptr += Packet_Header_Length-5;
				}
				else
					Rdptr += Packet_Header_Length;

				AUDIO_ID = Get_Byte();
				Packet_Length -= Packet_Header_Length+4;

				if (AUDIO_ID>=SUB_AC3 && AUDIO_ID<SUB_AC3+CHANNEL)
				{
					Rdptr += 3; Packet_Length -= 3; AC3_Track = AUDIO_ID-SUB_AC3;

					if (!ac3[AC3_Track].rip && Rip_Flag && !CH[AC3_Track])
					{
						CH[AC3_Track] = FORMAT_AC3;

						code = Get_Byte();
						code = (code & 0xff)<<8 | Get_Byte();
						i = 0;

						while (code!=0xb77)
						{
							code = (code & 0xff)<<8 | Get_Byte();
							i++;
						}

						Get_Short();
						ac3[AC3_Track].rate = (Get_Byte()>>1) & 0x1f;
						Get_Byte();
						ac3[AC3_Track].mode = (Get_Byte()>>5) & 0x07;

						if ((Format_Flag==FORMAT_AC3 || !Format_Flag) && (AVI_Flag || D2V_Flag))
						{
							if (AC3_Flag==AUDIO_DECODE && AC3_Track==Track_Flag)
							{
								sprintf(szBuffer, "%s AC3 T%02d %sch %dKbps %s.wav", szOutput, Track_Flag+1, 
									AC3ModeDash[ac3[AC3_Track].mode], AC3Rate[ac3[AC3_Track].rate], FTType[SRC_Flag]);

								strcpy(pcm.filename, szBuffer);
								pcm.file = fopen(szBuffer, "wb");

								fwrite(WAVHeader, sizeof(WAVHeader), 1, pcm.file);
								pcm.delay = (AudioPTS-VideoPTS)*192;

								if (SRC_Flag)
								{
									DownWAV(pcm.file);
									InitialSRC();
								}

								if (pcm.delay > 0)
								{
									if (SRC_Flag)
										pcm.delay = ((int)(0.91875*pcm.delay)>>2)<<2;

									for (j=0; j<pcm.delay; j++)
										fputc(*szBlank, pcm.file);

									pcm.size += pcm.delay;
									pcm.delay = 0;
								}

								InitialAC3();
								size = ac3_decode_data(Rdptr-7, Packet_Length-i);

								if (-pcm.delay > size)
									pcm.delay += size;
								else
								{
									if (SRC_Flag)
										Wavefs44(pcm.file, size+pcm.delay, AC3Dec_Buffer-pcm.delay);
									else
										fwrite(AC3Dec_Buffer-pcm.delay, size+pcm.delay, 1, pcm.file);

									pcm.size += size+pcm.delay;
 									pcm.delay = 0;
								}

								ac3[AC3_Track].rip = 1;
							}
							else if (!AC3_Flag || (AC3_Flag==AUDIO_DEMUXONE && AC3_Track==Track_Flag))
							{
								sprintf(szBuffer, "%s AC3 T%02d %sch %dKbps DELAY %dms.ac3", szOutput, AC3_Track+1, 
									AC3ModeDash[ac3[AC3_Track].mode], AC3Rate[ac3[AC3_Track].rate], AudioPTS-VideoPTS);

								ac3[AC3_Track].file = fopen(szBuffer, "wb");

								fwrite(Rdptr-7, Packet_Length-i, 1, ac3[AC3_Track].file);

								ac3[AC3_Track].rip = 1;
							}
						}

						Rdptr -= 7+i;
					}
					else if (ac3[AC3_Track].rip)
					{
						if (AC3_Flag==AUDIO_DECODE)
						{
							size = ac3_decode_data(Rdptr, Packet_Length);

							if (-pcm.delay > size)
								pcm.delay += size;
							else
							{
								if (SRC_Flag)
									Wavefs44(pcm.file, size+pcm.delay, AC3Dec_Buffer-pcm.delay);
								else
								{
									fwrite(AC3Dec_Buffer-pcm.delay, size+pcm.delay, 1, pcm.file);

									if (Normalization_Flag)
										for (j=0; j<(size>>1); j++)
										{
											volume = ptrAC3Dec_Buffer[j];

											if (Sound_Max < volume)
												Sound_Max = volume; 
											else if (Sound_Max < -volume)
												Sound_Max = -volume;
										}
								}

								pcm.size += size+pcm.delay;
 								pcm.delay = 0;
							}
						}
						else
							fwrite(Rdptr, Packet_Length, 1, ac3[AC3_Track].file);
					}

					Rdptr += Packet_Length;
				}
				else if (AUDIO_ID-SUB_PCM == Track_Flag)
				{
					CH[Track_Flag] = FORMAT_LPCM;
					Rdptr += 6; Packet_Length -= 6;

					if (!pcm.rip && Rip_Flag)
					{
						if ((Format_Flag==FORMAT_LPCM || !Format_Flag) && (AVI_Flag || D2V_Flag))
						{
							pcm.delay = (AudioPTS-VideoPTS)*192;

							sprintf(szBuffer, "%s LPCM T%02d %s.wav", szOutput, Track_Flag+1, FTType[SRC_Flag]);
							strcpy(pcm.filename, szBuffer);

							pcm.file = fopen(szBuffer, "wb");
							fwrite(WAVHeader, sizeof(WAVHeader), 1, pcm.file);

							if (SRC_Flag)
							{
								DownWAV(pcm.file);
								InitialSRC();
							}

							if (pcm.delay > 0)
							{
								if (SRC_Flag)
									pcm.delay = ((int)(0.91875*pcm.delay)>>2)<<2;

								for (j=0; j<pcm.delay; j++)
									fputc(*szBlank, pcm.file);

								pcm.size += pcm.delay;
								pcm.delay = 0;
							}

							if (-pcm.delay > Packet_Length)
								pcm.delay += Packet_Length;
							else
							{
								for (j=0; j<Packet_Length; j+=2)
								{
									PCM_Buffer[j] = *(Rdptr+j+1);
									PCM_Buffer[j+1] = *(Rdptr+j);
								}

								if (SRC_Flag)
									Wavefs44(pcm.file, Packet_Length+pcm.delay, PCM_Buffer-pcm.delay);
								else
									fwrite(PCM_Buffer-pcm.delay, Packet_Length+pcm.delay, 1, pcm.file);

								pcm.size += Packet_Length+pcm.delay;
								pcm.delay = 0;
							}

							pcm.rip = 1;
						}
					}
					else if (pcm.rip)
					{
						if (-pcm.delay > Packet_Length)
							pcm.delay += Packet_Length;
						else
						{
							for (j=0; j<Packet_Length; j+=2)
							{
								PCM_Buffer[j] = *(Rdptr+j+1);
								PCM_Buffer[j+1] = *(Rdptr+j);
							}

							if (SRC_Flag)
								Wavefs44(pcm.file, Packet_Length+pcm.delay, PCM_Buffer-pcm.delay);
							else
							{
								fwrite(PCM_Buffer-pcm.delay, Packet_Length+pcm.delay, 1, pcm.file);
								
								if (Normalization_Flag)
									for (j=0; j<(Packet_Length>>1); j++)
									{
										volume = ptrPCM_Buffer[j];

										if (Sound_Max < volume)
											Sound_Max = volume; 
										else if (Sound_Max < -volume)
											Sound_Max = -volume;
									}
							}

							pcm.size += Packet_Length+pcm.delay;
							pcm.delay = 0;
						}
					}

					Rdptr += Packet_Length;
				}
				else if (AUDIO_ID-SUB_DTS == Track_Flag)
				{
					CH[Track_Flag] = FORMAT_DTS;
					Rdptr += Packet_Length;
				}
				else
					Rdptr += Packet_Length;
				break;

			case AUDIO_ELEMENTARY_STREAM_7:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_6:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_5:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_4:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_3:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_2:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_1:
				MPA_Track++;
			case AUDIO_ELEMENTARY_STREAM_0:
				Packet_Length = Get_Short();
				code = Get_Byte();

				if ((code & 0xc0)==0x80 && (Track_Flag==MPA_Track || !MPA_Flag))
				{
					CH[MPA_Track] = FORMAT_MPA;

					code = Get_Byte();
					Packet_Header_Length = Get_Byte();

					if (code>=0x80)
					{
						code = Get_Byte();

						AudioPTS = (code & 0x0e) << 29;
						AudioPTS |= (Get_Short() & 0xfffe) << 14;
						AudioPTS |= (Get_Short()>>1) & 0x7fff;
						AudioPTS /= 90;

						Rdptr += Packet_Header_Length-5;
					}
					else
						Rdptr += Packet_Header_Length;

					Packet_Length -= Packet_Header_Length+3;

					while (Rdptr >= (Rdbfr + BUFFER_SIZE))
					{
						Read = _read(Infile[File_Flag], Rdbfr, BUFFER_SIZE);

						if (Read < BUFFER_SIZE)
							Next_File();

						Rdptr -= BUFFER_SIZE;
					}

					if (!mpa[MPA_Track].rip && Rip_Flag)
					{
						if ((Format_Flag==FORMAT_MPA || !Format_Flag) && (AVI_Flag || D2V_Flag))
						{
							code = Get_Byte();
							code = (code & 0xff)<<8 | Get_Byte();
							i = 0;

							while (code<0xfff0)
							{
								code = (code & 0xff)<<8 | Get_Byte();
								i++;
							}

							sprintf(szBuffer, "%s MPA T%02d DELAY %dms.mpa", 
								szOutput, MPA_Track+1, AudioPTS-VideoPTS);

							mpa[MPA_Track].file = fopen(szBuffer, "wb");

							Rdptr -= 2; Packet_Length -= i;

							while (Packet_Length > 0)
							{
								if (Packet_Length+Rdptr > BUFFER_SIZE+Rdbfr)
								{
									fwrite(Rdptr, BUFFER_SIZE+Rdbfr-Rdptr, 1, mpa[MPA_Track].file);
									Packet_Length -= BUFFER_SIZE+Rdbfr-Rdptr;
									Read = _read(Infile[File_Flag], Rdbfr, BUFFER_SIZE);
									Rdptr = Rdbfr;
								}
								else
								{
									fwrite(Rdptr, Packet_Length, 1, mpa[MPA_Track].file);
									Rdptr += Packet_Length;
									Packet_Length = 0;
								}
							}

							mpa[MPA_Track].rip = 1;					
						}
						else
							Rdptr += Packet_Length;
					}
					else if (mpa[MPA_Track].rip)
					{
						while (Packet_Length > 0)
						{
							if (Packet_Length+Rdptr > BUFFER_SIZE+Rdbfr)
							{
								fwrite(Rdptr, BUFFER_SIZE+Rdbfr-Rdptr, 1, mpa[MPA_Track].file);
								Packet_Length -= BUFFER_SIZE+Rdbfr-Rdptr;
								Read = _read(Infile[File_Flag], Rdbfr, BUFFER_SIZE);
								Rdptr = Rdbfr;
							}
							else
							{
								fwrite(Rdptr, Packet_Length, 1, mpa[MPA_Track].file);
								Rdptr += Packet_Length;
								Packet_Length = 0;
							}
						}
					}
					else
						Rdptr += Packet_Length;
				}
				else
					Rdptr += Packet_Length-1;

				MPA_Track = 0;
				break;

			case VIDEO_ELEMENTARY_STREAM:
				Packet_Length = Get_Short();
				Rdmax = Rdptr + Packet_Length;

				code = Get_Byte();

				if ((code & 0xc0)==0x80)
				{
					code = Get_Byte();
					Packet_Header_Length = Get_Byte();

					if (code>=0x80 && !Rip_Flag)
					{
						code = Get_Byte();
						VideoPTS = (code & 0x0e) << 29;
						VideoPTS |= (Get_Short() & 0xfffe) << 14;
						VideoPTS |= (Get_Short()>>1) & 0x7fff;
						VideoPTS /= 90;

						Rdptr += Packet_Header_Length-5;
					}
					else
						Rdptr += Packet_Header_Length;

					Bitrate_Meter += Rdmax-Rdptr;
					return;
				}
				else
					Rdptr += Packet_Length-1;
				break;

			default:
				if (code>=SYSTEM_START_CODE)
				{
					Packet_Length = Get_Short();
					Rdptr += Packet_Length;
				}
				break;
		}
	}
}

unsigned int Get_Bits_All(unsigned int N)
{
	N -= BitsLeft;
	Val = (CurrentBfr << (32 - BitsLeft)) >> (32 - BitsLeft);

	if (N)
		Val = (Val << N) + (NextBfr >> (32 - N));

	CurrentBfr = NextBfr;
	BitsLeft = 32 - N;
	Fill_Next();

	return Val;
}

void Flush_Buffer_All(unsigned int N)
{
	CurrentBfr = NextBfr;
	BitsLeft = BitsLeft + 32 - N;
	Fill_Next();
}

void Fill_Buffer()
{
	Read = _read(Infile[File_Flag], Rdbfr, BUFFER_SIZE);

	if (Read < BUFFER_SIZE)
		Next_File();

	Rdptr = Rdbfr;

	if (SystemStream_Flag)
		Rdmax -= BUFFER_SIZE;
	else
		Bitrate_Meter += Read;
}

void Next_File()
{
	int i;

	if (File_Flag < File_Limit-1)
	{
		File_Flag++;

		process.run = 0;
		for (i=0; i<File_Flag; i++)
			process.run += process.length[i];

		_lseeki64(Infile[File_Flag], 0, SEEK_SET);
		_read(Infile[File_Flag], Rdbfr + Read, BUFFER_SIZE - Read);
	}
	else
	{
		Fault_Flag = 98;
		Write_Frame(NULL, d2v_current, 0);
	}
}

static unsigned int Get_Short()
{
	unsigned int i = Get_Byte();
	return (i<<8) | Get_Byte();
}

⌨️ 快捷键说明

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