📄 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
};
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 + -