📄 getpic.c
字号:
/* getpic.c, picture decoding *//* 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 "config.h"#include "global.h"/* private prototypes*/static void picture_data _ANSI_ARGS_((int framenum));static void macroblock_modes _ANSI_ARGS_((int *pmacroblock_type, int *pstwtype, int *pstwclass, int *pmotion_type, int *pmotion_vector_count, int *pmv_format, int *pdmv, int *pmvscale, int *pdct_type));static void Clear_Block _ANSI_ARGS_((int comp));static void Sum_Block _ANSI_ARGS_((int comp));static void Saturate _ANSI_ARGS_((short *bp));static void Add_Block _ANSI_ARGS_((int comp, int bx, int by, int dct_type, int addflag));static void Update_Picture_Buffers _ANSI_ARGS_((void));static void frame_reorder _ANSI_ARGS_((int bitstream_framenum, int sequence_framenum));static void Decode_SNR_Macroblock _ANSI_ARGS_((int *SNRMBA, int *SNRMBAinc, int MBA, int MBAmax, int *dct_type));static void motion_compensation _ANSI_ARGS_((int MBA, int macroblock_type, int motion_type, int PMV[2][2][2], int motion_vertical_field_select[2][2], int dmvector[2], int stwtype, int dct_type));static void skipped_macroblock _ANSI_ARGS_((int dc_dct_pred[3], int PMV[2][2][2], int *motion_type, int motion_vertical_field_select[2][2], int *stwtype, int *macroblock_type));static int slice _ANSI_ARGS_((int framenum, int MBAmax));static int start_of_slice _ANSI_ARGS_ ((int MBAmax, int *MBA, int *MBAinc, int dc_dct_pred[3], int PMV[2][2][2]));static int decode_macroblock _ANSI_ARGS_((int *macroblock_type, int *stwtype, int *stwclass, int *motion_type, int *dct_type, int PMV[2][2][2], int dc_dct_pred[3], int motion_vertical_field_select[2][2], int dmvector[2]));/* decode one frame or field picture */void Decode_Picture(bitstream_framenum, sequence_framenum)int bitstream_framenum, sequence_framenum;{ if (picture_structure==FRAME_PICTURE && Second_Field) { /* recover from illegal number of field pictures */ printf("odd number of field pictures\n"); Second_Field = 0; } /* IMPLEMENTATION: update picture buffer pointers */ Update_Picture_Buffers();#ifdef VERIFY Check_Headers(bitstream_framenum, sequence_framenum);#endif /* VERIFY */ /* ISO/IEC 13818-4 section 2.4.5.4 "frame buffer intercept method" */ /* (section number based on November 1995 (Dallas) draft of the conformance document) */ if(Ersatz_Flag) Substitute_Frame_Buffer(bitstream_framenum, sequence_framenum); /* form spatial scalable picture */ /* form spatial scalable picture */ /* ISO/IEC 13818-2 section 7.7: Spatial scalability */ if (base.pict_scal && !Second_Field) { Spatial_Prediction(); } /* decode picture data ISO/IEC 13818-2 section 6.2.3.7 */ picture_data(bitstream_framenum);
fprintf(fp_debug,"\n%d\n",bitstream_framenum);
fprintf(fp_debugx,"\n%d\n",bitstream_framenum);
fflush(fp_debug);
fflush(fp_debugx);
/* write or display current or previously decoded reference frame */ /* ISO/IEC 13818-2 section 6.1.1.11: Frame reordering */ frame_reorder(bitstream_framenum, sequence_framenum); if (picture_structure!=FRAME_PICTURE) Second_Field = !Second_Field;}/* decode all macroblocks of the current picture *//* stages described in ISO/IEC 13818-2 section 7 */static void picture_data(framenum)int framenum;{ int MBAmax; int ret; /* number of macroblocks per picture */ MBAmax = mb_width*mb_height; if (picture_structure!=FRAME_PICTURE) MBAmax>>=1; /* field picture has half as mnay macroblocks as frame */ for(;;) { if((ret=slice(framenum, MBAmax))<0) return; }}
/* decode all macroblocks of the current picture *//* ISO/IEC 13818-2 section 6.3.16 */static int slice(framenum, MBAmax)int framenum, MBAmax;{ int MBA; int MBAinc, macroblock_type, motion_type, dct_type; int dc_dct_pred[3]; int PMV[2][2][2]={0}, motion_vertical_field_select[2][2]={0}; int dmvector[2]={0}; int stwtype, stwclass; int SNRMBA, SNRMBAinc; int ret; MBA = 0; /* macroblock address */ MBAinc = 0;
fprintf(fp_debug,"\n");
if((ret=start_of_slice(MBAmax, &MBA, &MBAinc, dc_dct_pred, PMV))!=1) return(ret); if (Two_Streams && enhan.scalable_mode==SC_SNR) { SNRMBA=0; SNRMBAinc=0; } Fault_Flag=0; for (;;) { /* this is how we properly exit out of picture */ if (MBA>=MBAmax) return(-1); /* all macroblocks decoded *///#ifdef TRACE
// if (Trace_Flag)
// printf("frame %d, MB %d\n",framenum,MBA);
//#endif /* TRACE *///#ifdef DISPLAY
// if (!progressive_frame && picture_structure==FRAME_PICTURE
// && MBA==(MBAmax>>1) && framenum!=0 && Output_Type==T_X11
// && !Display_Progressive_Flag)
// {
// Display_Second_Field();
// }
//#endif ld = &base; if (MBAinc==0) { if (base.scalable_mode==SC_DP && base.priority_breakpoint==1) ld = &enhan; if (!Show_Bits(23) || Fault_Flag) /* next_start_code or fault */ {resync: /* if Fault_Flag: resynchronize to next next_start_code */ Fault_Flag = 0; return(0); /* trigger: go to next slice */ } else /* neither next_start_code nor Fault_Flag */ { if (base.scalable_mode==SC_DP && base.priority_breakpoint==1) ld = &enhan; /* decode macroblock address increment */ MBAinc = Get_macroblock_address_increment(); if (Fault_Flag) goto resync; } } if (MBA>=MBAmax) { /* MBAinc points beyond picture dimensions */ if (!Quiet_Flag) printf("Too many macroblocks in picture\n"); return(-1); }
// if (picture_coding_type == P_TYPE && MBA==754)
// {
// printf("%d %d %d",dc_dct_pred[0],dc_dct_pred[1],dc_dct_pred[2]);
// }
if (MBAinc==1) /* not skipped */ { ret = decode_macroblock(¯oblock_type, &stwtype, &stwclass, &motion_type, &dct_type, PMV, dc_dct_pred, motion_vertical_field_select, dmvector); if(ret==-1) return(-1); if(ret==0) goto resync; } else /* MBAinc!=1: skipped macroblock */ { /* ISO/IEC 13818-2 section 7.6.6 */ skipped_macroblock(dc_dct_pred, PMV, &motion_type, motion_vertical_field_select, &stwtype, ¯oblock_type); } /* SCALABILITY: SNR */ /* ISO/IEC 13818-2 section 7.8 */ /* NOTE: we currently ignore faults encountered in this routine */ if (Two_Streams && enhan.scalable_mode==SC_SNR) Decode_SNR_Macroblock(&SNRMBA, &SNRMBAinc, MBA, MBAmax, &dct_type);
// if (picture_coding_type == P_TYPE)
//if (picture_coding_type == B_TYPE && MBAinc!=1)
// {
// printf("[%d] %d::%d %d %d %d %d %d %d %d \n",MBAinc,MBA,PMV[0][0][0],PMV[0][0][1],PMV[0][1][0],PMV[0][1][1]
// ,PMV[1][0][0],PMV[1][0][1],PMV[1][1][0],PMV[1][1][1]);
// }
//printf("%d %d\n",macroblock_type & 0x0f,dct_type);
// if (picture_coding_type==P_TYPE ) //
// {
// printf("[%d] %d::%d %d %d %d %d %d %d %d %d\n",MBAinc,MBA,macroblock_type,motion_type,motion_vertical_field_select[0][0],
// motion_vertical_field_select[0][1],motion_vertical_field_select[1][0],motion_vertical_field_select[1][1],
// dmvector[0],dmvector[1],dct_type);
// }
//if (picture_coding_type == P_TYPE && MBA >700 && MBA<900)
// {
// //printf("%d::",MBA);
// for(ret = 0; ret<64; ret++)
// {
// fprintf(fp_debug,"%d ",ld->block[0][ret]);
// }
// fprintf(fp_debug,"\n");
// }
// if (!(macroblock_type & MACROBLOCK_INTRA))
// {
// fprintf(fp_debugx,"[%02x %02x][%d %d %d %d][%d,%d,%d,%d,%d,%d,%d,%d]\n",
// macroblock_type,motion_type,
// motion_vertical_field_select[0][0],motion_vertical_field_select[0][1],
// motion_vertical_field_select[1][0],motion_vertical_field_select[1][1],
// PMV[0][0][0],PMV[0][0][1],PMV[0][1][0],PMV[0][1][1],
// PMV[1][0][0],PMV[1][0][1],PMV[1][1][0],PMV[1][1][1]);
// fflush(fp_debugx);
// }
fprintf(fp_debug,"%4d:%2d\n",MBA,MBAinc); /* ISO/IEC 13818-2 section 7.6 */
//if (MBAinc==1)
//{
//if (!(macroblock_type & MACROBLOCK_INTRA))
// fprintf(fp_debug,"[%02x %02x %02x]",macroblock_type,motion_type,picture_structure); motion_compensation(MBA, macroblock_type, motion_type, PMV, motion_vertical_field_select, dmvector, stwtype, dct_type);
//}
// for(ret = 0; ret<64; ret++)
// {
// fprintf(fp_debug,"%d ",ld->block[0][ret]);
// }
// fprintf(fp_debug,"\n");
/* advance to next macroblock */ MBA++; MBAinc--; /* SCALABILITY: SNR */ if (Two_Streams && enhan.scalable_mode==SC_SNR) { SNRMBA++; SNRMBAinc--; } if (MBA>=MBAmax) return(-1); /* all macroblocks decoded */ }} /* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */static void macroblock_modes(pmacroblock_type,pstwtype,pstwclass, pmotion_type,pmotion_vector_count,pmv_format,pdmv,pmvscale,pdct_type) int *pmacroblock_type, *pstwtype, *pstwclass; int *pmotion_type, *pmotion_vector_count, *pmv_format, *pdmv, *pmvscale; int *pdct_type;{ int macroblock_type; int stwtype, stwcode, stwclass; int motion_type = 0; int motion_vector_count, mv_format, dmv, mvscale; int dct_type; static unsigned char stwc_table[3][4] = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; static unsigned char stwclass_table[9] = {0, 1, 2, 1, 1, 2, 3, 3, 4}; /* get macroblock_type */ macroblock_type = Get_macroblock_type(); if (Fault_Flag) return; /* get spatial_temporal_weight_code */ if (macroblock_type & MB_WEIGHT) { if (spatial_temporal_weight_code_table_index==0) stwtype = 4; else { stwcode = Get_Bits(2);//#ifdef TRACE
// if (Trace_Flag)
// {
// printf("spatial_temporal_weight_code (");
// Print_Bits(stwcode,2,2);
// printf("): %d\n",stwcode);
// }
//#endif /* TRACE */
stwtype = stwc_table[spatial_temporal_weight_code_table_index-1][stwcode]; } } else stwtype = (macroblock_type & MB_CLASS4) ? 8 : 0; /* SCALABILITY: derive spatial_temporal_weight_class (Table 7-18) */ stwclass = stwclass_table[stwtype]; /* get frame/field motion type */ if (macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD)) { if (picture_structure==FRAME_PICTURE) /* frame_motion_type */ { motion_type = frame_pred_frame_dct ? MC_FRAME : Get_Bits(2);//#ifdef TRACE
// if (!frame_pred_frame_dct && Trace_Flag)
// {
// printf("frame_motion_type (");
// Print_Bits(motion_type,2,2);
// printf("): %s\n",motion_type==MC_FIELD?"Field":
// motion_type==MC_FRAME?"Frame":
// motion_type==MC_DMV?"Dual_Prime":"Invalid");
// }
//#endif /* TRACE */
}
else /* field_motion_type */ { motion_type = Get_Bits(2);#ifdef TRACE if (Trace_Flag) { printf("field_motion_type ("); Print_Bits(motion_type,2,2); printf("): %s\n",motion_type==MC_FIELD?"Field": motion_type==MC_16X8?"16x8 MC": motion_type==MC_DMV?"Dual_Prime":"Invalid"); }#endif /* TRACE */ } } else if ((macroblock_type & MACROBLOCK_INTRA) && concealment_motion_vectors) { /* concealment motion vectors */ motion_type = (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD; }#if 0 else { printf("maroblock_modes(): unknown macroblock type\n"); motion_type = -1; }#endif /* derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */ if (picture_structure==FRAME_PICTURE) { motion_vector_count = (motion_type==MC_FIELD && stwclass<2) ? 2 : 1; mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD; } else { motion_vector_count = (motion_type==MC_16X8) ? 2 : 1; mv_format = MV_FIELD; } dmv = (motion_type==MC_DMV); /* dual prime */ /* field mv predictions in frame pictures have to be scaled * ISO/IEC 13818-2 section 7.6.3.1 Decoding the motion vectors * IMPLEMENTATION: mvscale is derived for later use in motion_vectors()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -