📄 vfapidec.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.
*
*/
#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 + -