📄 mpeg2dec.cpp
字号:
/* mpeg2dec.c, main(), initialization, option processing *//* 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. * */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <fcntl.h>
#include "io.h"
#include "windowsx.h"
#include <math.h>
#define GLOBAL#include "config.h"#include "global.h"/* private prototypes */static int Headers (void);static void Initialize_Sequence (void);static void Initialize_Decoder (void);static void Deinitialize_Sequence (void);#if OLDstatic int Get_Val _ANSI_ARGS_((char *argv[]));#endif/* #define DEBUG */static void Clear_Options();#ifdef DEBUGstatic void Print_Options();#endif
long Bitstream_Framenum;
long Sequence_Framenum;
int Return_Value;
int ret;
///decode to bmp and yuv file/* IMPLEMENTAION specific rouintes */
unsigned char ccc[2048];
void Clear_Options()
{
Verbose_Flag = 0;
Output_Type = 0;
Output_Picture_Filename = " ";
hiQdither = 0;
Output_Type = 0;
Frame_Store_Flag = 0;
Spatial_Flag = 0;
Lower_Layer_Picture_Filename = " ";
Reference_IDCT_Flag = 0;
Trace_Flag = 0;
Quiet_Flag = 0;
Ersatz_Flag = 0;
Substitute_Picture_Filename = " ";
Two_Streams = 0;
Enhancement_Layer_Bitstream_Filename = " ";
Big_Picture_Flag = 0;
Main_Bitstream_Flag = 0;
Main_Bitstream_Filename = " ";
Verify_Flag = 0;
Stats_Flag = 0;
User_Data_Flag = 0;
System_Stream_Flag=0;
}
static void Initialize_Decoder(){ int i; /* Clip table */ // if (!(Clip=(unsigned char *)malloc(1024))) // Error("Clip[] malloc failed\n"); Clip=ccc; Clip += 384; for (i=-384; i<640; i++) Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i); /* IDCT */ if (Reference_IDCT_Flag) Initialize_Reference_IDCT(); else Initialize_Fast_IDCT();}/* mostly IMPLEMENTAION specific rouintes */static void Initialize_Sequence(){ int cc, size; static int Table_6_20[3] = {6,8,12}; /* check scalability mode of enhancement layer */ if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP)) Error("unsupported scalability mode\n"); /* force MPEG-1 parameters for proper decoder behavior */ /* see ISO/IEC 13818-2 section D.9.14 */ if (!base.MPEG2_Flag) { progressive_sequence = 1; progressive_frame = 1; picture_structure = FRAME_PICTURE; frame_pred_frame_dct = 1; chroma_format = CHROMA420; matrix_coefficients = 5; } /* round to nearest multiple of coded macroblocks */ /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
mb_width = (horizontal_size+15)/16; mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32) : (vertical_size+15)/16; Coded_Picture_Width = 16*mb_width; Coded_Picture_Height = 16*mb_height;
horizontal_size=Coded_Picture_Width;
vertical_size=Coded_Picture_Height;
horizontal_size=Coded_Picture_Width;
vertical_size=Coded_Picture_Height; /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */ Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width : Coded_Picture_Width>>1; Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height : Coded_Picture_Height>>1; /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */ block_count = Table_6_20[chroma_format-1]; for (cc=0; cc<3; cc++) { if (cc==0) size = Coded_Picture_Width*Coded_Picture_Height; else size = Chroma_Width*Chroma_Height; if (!backward_reference_frame[cc] && !(backward_reference_frame[cc] = (unsigned char *)malloc(size))) Error("backward_reference_frame[] malloc failed\n"); if (!forward_reference_frame[cc] && !(forward_reference_frame[cc] = (unsigned char *)malloc(size))) Error("forward_reference_frame[] malloc failed\n"); if (!auxframe[cc] && !(auxframe[cc] = (unsigned char *)malloc(size))) Error("auxframe[] malloc failed\n"); if(Ersatz_Flag) if (!substitute_frame[cc] && !(substitute_frame[cc] = (unsigned char *)malloc(size))) Error("substitute_frame[] malloc failed\n"); if (base.scalable_mode==SC_SPAT) { /* this assumes lower layer is 4:2:0 */ if (!llframe0[cc] && !(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) Error("llframe0 malloc failed\n"); if (!llframe1[cc] && !(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) Error("llframe1 malloc failed\n"); } } /* SCALABILITY: Spatial */ if (base.scalable_mode==SC_SPAT) { if (!lltmp && !(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short)))) Error("lltmp malloc failed\n"); }}
static void Initialize_Sequence1()
{
int cc, size;
static int Table_6_20[3] = {6,8,12};
/* check scalability mode of enhancement layer */
if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
Error("unsupported scalability mode\n");
/* force MPEG-1 parameters for proper decoder behavior */
/* see ISO/IEC 13818-2 section D.9.14 */
if (!base.MPEG2_Flag)
{
// MessageBox(NULL,NULL,"Initialize_Sequence1",MB_OK);
progressive_sequence = 1;
progressive_frame = 1;
picture_structure = FRAME_PICTURE;
frame_pred_frame_dct = 1;
chroma_format = CHROMA420;
matrix_coefficients = 5;
}
/* round to nearest multiple of coded macroblocks */
/* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
mb_width = (horizontal_size+15)/16;
mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
: (vertical_size+15)/16;
Coded_Picture_Width = 16*mb_width;
Coded_Picture_Height = 16*mb_height;
horizontal_size=Coded_Picture_Width;
vertical_size=Coded_Picture_Height;
/* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
: Coded_Picture_Width>>1;
Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
: Coded_Picture_Height>>1;
/* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
block_count = Table_6_20[chroma_format-1];
for (cc=0; cc<3; cc++)
{
if (cc==0)
size = Coded_Picture_Width*Coded_Picture_Height;
else
size = Chroma_Width*Chroma_Height;
// if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
// Error("backward_reference_frame[] malloc failed\n");
// if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
// Error("forward_reference_frame[] malloc failed\n");
// if (!(auxframe[cc] = (unsigned char *)malloc(size)))
// Error("auxframe[] malloc failed\n");
if(Ersatz_Flag)
if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
Error("substitute_frame[] malloc failed\n");
if (base.scalable_mode==SC_SPAT)
{
/* this assumes lower layer is 4:2:0 */
if(!llframe0[cc] && !(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
Error("llframe0 malloc failed\n");
if (!llframe1[cc] && !(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
Error("llframe1 malloc failed\n");
}
}
/* SCALABILITY: Spatial */
if (base.scalable_mode==SC_SPAT)
{
if (!lltmp && !(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
Error("lltmp malloc failed\n");
}
}void Error(char *text){
// AfxMessageBox(text); // fprintf(stderr,text); //exit(1);}/* Trace_Flag output */void Print_Bits(int code,int bits,int len){ int i; // for (i=0; i<len; i++) // printf("%d",(code>>(bits-1-i))&1);}#ifdef OLD/* this is an old routine used to convert command line arguments into integers */static int Get_Val(char *argv[]){ int val; if (sscanf(argv[1]+2,"%d",&val)!=1) return 0; while (isdigit(argv[1][2])) argv[1]++; return val;}#endifstatic int Headers(){ int ret;
ld=&base; /* return when end of sequence (0) or picture header has been parsed (1) */ ret = Get_Hdr(); return ret;}static void Deinitialize_Sequence(){ int i; /* clear flags */// base.MPEG2_Flag=0; for(i=0;i<3;i++) { free(backward_reference_frame[i]); free(forward_reference_frame[i]); free(auxframe[i]); if (base.scalable_mode==SC_SPAT) { free(llframe0[i]); free(llframe1[i]); } } if (base.scalable_mode==SC_SPAT) free(lltmp);}
long int crv_tab[256];
long int cbu_tab[256];
long int cgu_tab[256];
long int cgv_tab[256];
long int tab_76309[256];
int *clp = NULL;
extern void init_dither_tab()
{
int i;
long crv = Inverse_Table_6_9[matrix_coefficients][0];
long cbu = Inverse_Table_6_9[matrix_coefficients][1];
long cgu = Inverse_Table_6_9[matrix_coefficients][2];
long cgv = Inverse_Table_6_9[matrix_coefficients][3];
for (i = 0; i < 256; i++)
{
crv_tab[i] = (i - 128) * crv;
cbu_tab[i] = (i - 128) * cbu;
cgu_tab[i] = (i - 128) * cgu;
cgv_tab[i] = (i - 128) * cgv;
tab_76309[i] = 76309 * (i - 16);
}
}
HANDLE OpenMpeg2(char* infile, void *callback)
{
long code;
HANDLE hDecode;
environment_data *pDecode;
AUDIO=false;
SEQEND=false;
hDecode=GlobalAlloc(GHND,sizeof(environment_data));
if(!hDecode)
Error("alloc hDecode mem fail");
pDecode=(environment_data *)GlobalLock(hDecode);
pDecode->hFilesize=sizeof(environment_data);
ld = &base;
if ((base.Infile=_open(infile,O_RDONLY|O_BINARY))<0)
{
GlobalUnlock(hDecode);
return 0;
}
if(base.Infile != 0)
{
System_Stream_Flag = 0;
Initialize_Buffer();
if(SHOW_BITS(8)==0x47)
{
GlobalUnlock(hDecode);
return 0;
}
long i=0;
while(1)
{
i+=32;
next_start_code();
code = Get_Bits32();//Show_Bits(32);
switch(code)
{
case SEQUENCE_HEADER_CODE:
break;
case PACK_START_CODE:
System_Stream_Flag = 1;
break;
case VIDEO_ELEMENTARY_STREAM:
System_Stream_Flag = 1;
break;
// default:
// System_Stream_Flag = 1;
// return 0;
// break;
}
if(code==SEQUENCE_HEADER_CODE||System_Stream_Flag )
break;
if(i>2048)
{
GlobalUnlock(hDecode);
return 0;
}
}
_lseek(base.Infile, 0l, 0);
Initialize_Buffer();
}
if(base.Infile!=0)
{
lseek(base.Infile, 0l, 0);
}
Initialize_Buffer();
if(Two_Streams)
{
ld = &enhan;
if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
{
}
Initialize_Buffer();
ld = &base;
}
ld->mode=0;
pDecode->infile=base.Infile;
Initialize_Decoder();
Bitstream_Framenum = 0;
init_dither_tab();
GlobalUnlock(hDecode);
return hDecode;
}
void GetTotal(HANDLE hDecode,long* total)
{
long temp=0;
long lframe=0;
environment_data *pDecode;
pDecode=(environment_data *)GlobalLock(hDecode);
SEQEND=false;
//计算总帧数
//定位于文件尾后一定范围内
_lseeki64(pDecode->infile,-1*MaxFrame*(pDecode->N*10),SEEK_END);
BOOL FirstI=false;
while(Headers())
{
if(picture_coding_type==I_TYPE)
{
FirstI=true;
lframe=0; //组内序号归零
}
else if(picture_coding_type==P_TYPE||picture_coding_type==B_TYPE)
{
//若不是图像组首且为非连续解码,则继续寻找。
if(!FirstI)
continue;
lframe++;
}
if(SEQEND)
break;
}
SEQEND=false;
if(lframe>pDecode->N)
lframe=pDecode->N;
*total=((hour-thour)*3600+(minute-tminute)*60+(sec-tsec))*(int)(frame_rate+0.5)+(frame-tframe+1+lframe);
//若在范围内无播放时间信息,则遍历整个文件得到的总帧数
if(frame-tframe==0&&minute-tminute==0&&sec-tsec==0&&hour-thour==0)
{
SEQEND=false;
lseek(pDecode->infile, 0l, 0);
if(pDecode->infile!=0)
{
lseek(pDecode->infile, 0l, 0);
}
Initialize_Buffer();
while(1)
{
int code;
next_start_code();
code = Get_Bits32();
pDecode->infile=base.Infile;
if(code==PICTURE_START_CODE)
{
temp++;
}
if(code==SEQUENCE_END_CODE||SEQEND)
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -