📄 mpeg2dec.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 + -