📄 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 "global.h"/* private prototypes*/static void picture_data (MPEG2_Decoder *dec, int framenum);static void macroblock_modes (MPEG2_Decoder *dec, 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 (MPEG2_Decoder *dec, int comp);static void Add_Block (MPEG2_Decoder *dec, int comp, int bx, int by, int dct_type, int addflag);static void Update_Picture_Buffers (MPEG2_Decoder *dec);static void frame_reorder (MPEG2_Decoder *dec, int bitstream_framenum, int sequence_framenum);static void motion_compensation (MPEG2_Decoder *dec, 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 (MPEG2_Decoder *dec, 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 (MPEG2_Decoder *dec, int framenum, int MBAmax);static int start_of_slice (MPEG2_Decoder *dec, int MBAmax, int *MBA, int *MBAinc, int dc_dct_pred[3], int PMV[2][2][2]);static int decode_macroblock (MPEG2_Decoder *dec, 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 */voidMPEG2_Decode_Picture(MPEG2_Decoder *dec, int bitstream_framenum, int sequence_framenum){ if (dec->picture_structure==FRAME_PICTURE && dec->Second_Field) { /* recover from illegal number of field pictures */ printf("odd number of field pictures\n"); dec->Second_Field = 0; } /* IMPLEMENTATION: update picture buffer pointers */ Update_Picture_Buffers(dec); /* decode picture data ISO/IEC 13818-2 section 6.2.3.7 */ picture_data(dec, bitstream_framenum); /* write or display current or previously decoded reference frame */ /* ISO/IEC 13818-2 section 6.1.1.11: Frame reordering */ frame_reorder(dec, bitstream_framenum, sequence_framenum); if (dec->picture_structure!=FRAME_PICTURE) dec->Second_Field = !dec->Second_Field;}/* decode all macroblocks of the current picture *//* stages described in ISO/IEC 13818-2 section 7 */static voidpicture_data(MPEG2_Decoder *dec, int framenum){ int MBAmax; int ret; /* number of macroblocks per picture */ MBAmax = dec->mb_width*dec->mb_height; if (dec->picture_structure!=FRAME_PICTURE) MBAmax>>=1; /* field picture has half as mnay macroblocks as frame */ for (;;) { if ((ret=slice(dec, framenum, MBAmax))<0) return; }}/* decode all macroblocks of the current picture *//* ISO/IEC 13818-2 section 6.3.16 */static intslice(MPEG2_Decoder *dec, int framenum, int MBAmax){ int MBA; int MBAinc, macroblock_type = 0, motion_type = 0, dct_type = 0; int dc_dct_pred[3]; int PMV[2][2][2], motion_vertical_field_select[2][2]; int dmvector[2]; int stwtype = 0, stwclass = 0; int ret; MBA = 0; /* macroblock address */ MBAinc = 0; if ((ret=start_of_slice(dec, MBAmax, &MBA, &MBAinc, dc_dct_pred, PMV))!=1) return(ret); dec->Fault_Flag=0; for (;;) { /* this is how we properly exit out of picture */ if (MBA>=MBAmax) return(-1); /* all macroblocks decoded */ if (MBAinc==0) { if (!MPEG2_Show_Bits(dec, 23) || dec->Fault_Flag) { /* MPEG2_next_start_code or fault */ resync: /* if dec->Fault_Flag: resynchronize to next MPEG2_next_start_code */ dec->Fault_Flag = 0; return(0); /* trigger: go to next slice */ } else { /* neither MPEG2_next_start_code nor dec->Fault_Flag */ /* decode macroblock address increment */ MBAinc = MPEG2_Get_macroblock_address_increment(dec); if (dec->Fault_Flag) goto resync; } } if (MBA>=MBAmax) { /* MBAinc points beyond picture dimensions */ if (!MPEG2_Quiet_Flag) printf("Too many macroblocks in picture\n"); return(-1); } if (MBAinc==1) { /* not skipped */ ret = decode_macroblock(dec, ¯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(dec, dc_dct_pred, PMV, &motion_type, motion_vertical_field_select, &stwtype, ¯oblock_type); } /* ISO/IEC 13818-2 section 7.6 */ motion_compensation(dec, MBA, macroblock_type, motion_type, PMV, motion_vertical_field_select, dmvector, stwtype, dct_type); /* advance to next macroblock */ MBA++; MBAinc--; if (MBA>=MBAmax) return(-1); /* all macroblocks decoded */ }}/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */static voidmacroblock_modes(MPEG2_Decoder *dec, int *pmacroblock_type, int *pstwtype, int *pstwclass, int *pmotion_type,int *pmotion_vector_count,int *pmv_format,int *pdmv,int *pmvscale,int *pdct_type){ int macroblock_type; int stwtype, stwclass; int motion_type = 0; int motion_vector_count, mv_format, dmv, mvscale; int dct_type; static unsigned char stwclass_table[9] = {0, 1, 2, 1, 1, 2, 3, 3, 4}; /* get macroblock_type */ macroblock_type = MPEG2_Get_macroblock_type(dec); if (dec->Fault_Flag) return; /* get spatial_temporal_weight_code */ if (macroblock_type & MB_WEIGHT) { stwtype = 4; } 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 (dec->picture_structure==FRAME_PICTURE) { /* frame_motion_type */ motion_type = dec->frame_pred_frame_dct ? MC_FRAME : MPEG2_Get_Bits(dec, 2); } else { /* field_motion_type */ motion_type = MPEG2_Get_Bits(dec, 2); } } else if ((macroblock_type & MACROBLOCK_INTRA) && dec->concealment_motion_vectors) { /* concealment motion vectors */ motion_type = (dec->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 (dec->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 MPEG2_motion_vectors() * it displaces the stage: * * if((mv_format=="field")&&(t==1)&&(picture_structure=="Frame picture")) * prediction = PMV[r][s][t] DIV 2; */ mvscale = ((mv_format==MV_FIELD) && (dec->picture_structure==FRAME_PICTURE)); /* get dct_type (frame DCT / field DCT) */ dct_type = (dec->picture_structure==FRAME_PICTURE) && (!dec->frame_pred_frame_dct) && (macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA)) ? MPEG2_Get_Bits(dec, 1) : 0; /* return values */ *pmacroblock_type = macroblock_type; *pstwtype = stwtype; *pstwclass = stwclass; *pmotion_type = motion_type; *pmotion_vector_count = motion_vector_count; *pmv_format = mv_format; *pdmv = dmv; *pmvscale = mvscale; *pdct_type = dct_type;}/* move/add 8x8-Block from block[comp] to backward_reference_frame *//* copy reconstructed 8x8 block from block[comp] to current_frame[] * ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data * This stage also embodies some of the operations implied by: * - ISO/IEC 13818-2 section 7.6.7: Combining predictions * - ISO/IEC 13818-2 section 6.1.3: Macroblock*/static voidAdd_Block(MPEG2_Decoder *dec, int comp,int bx,int by,int dct_type,int addflag){ int cc,i, j, iincr; unsigned char *rfp; short *bp; /* derive color component index */ /* equivalent to ISO/IEC 13818-2 Table 7-1 */ cc = (comp<4) ? 0 : (comp&1)+1; /* color component index */ if (cc==0) { /* luminance */ if (dec->picture_structure==FRAME_PICTURE) if (dct_type) { /* field DCT coding */ rfp = dec->current_frame[0] + dec->Coded_Picture_Width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3); iincr = (dec->Coded_Picture_Width<<1) - 8; } else { /* frame DCT coding */ rfp = dec->current_frame[0] + dec->Coded_Picture_Width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); iincr = dec->Coded_Picture_Width - 8; } else { /* field picture */ rfp = dec->current_frame[0] + (dec->Coded_Picture_Width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); iincr = (dec->Coded_Picture_Width<<1) - 8; } } else { /* chrominance */ /* scale coordinates */ if (dec->chroma_format!=CHROMA444) bx >>= 1; if (dec->chroma_format==CHROMA420) by >>= 1; if (dec->picture_structure==FRAME_PICTURE) { if (dct_type && (dec->chroma_format!=CHROMA420)) { /* field DCT coding */ rfp = dec->current_frame[cc] + dec->Chroma_Width*(by+((comp&2)>>1)) + bx + (comp&8); iincr = (dec->Chroma_Width<<1) - 8; } else { /* frame DCT coding */ rfp = dec->current_frame[cc] + dec->Chroma_Width*(by+((comp&2)<<2)) + bx + (comp&8); iincr = dec->Chroma_Width - 8; } } else { /* field picture */ rfp = dec->current_frame[cc] + (dec->Chroma_Width<<1)*(by+((comp&2)<<2)) + bx + (comp&8); iincr = (dec->Chroma_Width<<1) - 8; } } bp = dec->block[comp]; if (addflag) { for (i=0; i<8; i++) { for (j=0; j<8; j++) { *rfp = dec->Clip[*bp++ + *rfp]; rfp++; } rfp+= iincr; } } else { for (i=0; i<8; i++) { for (j=0; j<8; j++) *rfp++ = dec->Clip[*bp++ + 128]; rfp+= iincr; } }}/* IMPLEMENTATION: set scratch pad macroblock to zero */static voidClear_Block(MPEG2_Decoder *dec, int comp){ short *Block_Ptr; int i; Block_Ptr = dec->block[comp]; for (i=0; i<64; i++) *Block_Ptr++ = 0;}/* reuse old picture buffers as soon as they are no longer needed based on life-time axioms of MPEG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -