📄 getpic.c
字号:
/************************************************************************ * * getpic.c, picture decoding for tmndecode (H.263 decoder) * Copyright (C) 1996 Telenor R&D, Norway * Karl Olav Lillevold <Karl.Lillevold@nta.no> * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Karl Olav Lillevold <Karl.Lillevold@nta.no> * Telenor Research and Development * P.O.Box 83 tel.: +47 63 84 84 00 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76 * * Robert Danielsen e-mail: Robert.Danielsen@nta.no * Telenor Research and Development www: http://www.nta.no/brukere/DVC/ * P.O.Box 83 tel.: +47 63 84 84 00 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76 * ************************************************************************//* * modified by Wayne Ellis BT Labs to run Annex E Arithmetic Decoding * <ellis_w_wayne@bt-web.bt.co.uk> * * based on mpeg2decode, (C) 1994, MPEG Software Simulation Group * and mpeg2play, (C) 1994 Stefan Eckart * <stefan@lis.e-technik.tu-muenchen.de> */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "config.h"#include "tmndec.h"#include "global.h"#include "indices.h" #include "sactbls.h"/* private prototypes*/static void getMBs _ANSI_ARGS_((int framenum));static void clearblock _ANSI_ARGS_((int comp));static int motion_decode _ANSI_ARGS_((int vec,int pmv));static int find_pmv _ANSI_ARGS_((int x, int y, int block, int comp));static void addblock _ANSI_ARGS_((int comp, int bx, int by,int addflag));static void reconblock_b _ANSI_ARGS_((int comp,int bx,int by,int mode,int bdx, int bdy));static void find_bidir_limits _ANSI_ARGS_((int vec, int *start, int*stop, int nhv));static void find_bidir_chroma_limits _ANSI_ARGS_((int vec, int *start, int*stop));static void make_edge_image _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int width, int height, int edge));void interpolate_image _ANSI_ARGS_((unsigned char *in, unsigned char *out, int width, int height));//定义的方式???/* decode one frame or field picture */void getpicture(framenum)int *framenum;{ int i; unsigned char *tmp; for (i=0; i<3; i++) { tmp = oldrefframe[i];//char类型的数组 oldrefframe[i] = refframe[i]; refframe[i] = tmp; newframe[i] = refframe[i]; }//交换? if (mv_outside_frame && *framenum > 0) { make_edge_image(oldrefframe[0],edgeframe[0],coded_picture_width, coded_picture_height,32); make_edge_image(oldrefframe[1],edgeframe[1],chrom_width, chrom_height,16); make_edge_image(oldrefframe[2],edgeframe[2],chrom_width, chrom_height,16); } getMBs(*framenum);//主要的变换函数 if (pb_frame) { if (expand && outtype == T_X11) { interpolate_image(bframe[0], exnewframe[0], coded_picture_width, coded_picture_height); interpolate_image(bframe[1], exnewframe[1], chrom_width, chrom_height); interpolate_image(bframe[2], exnewframe[2], chrom_width, chrom_height); storeframe(exnewframe, *framenum); } else storeframe(bframe,*framenum); *framenum += pb_frame;#ifdef USE_TIME if (framerate > 0) doframerate(1);#endif }// if (expand && outtype == T_X11) { interpolate_image(newframe[0], exnewframe[0], coded_picture_width, coded_picture_height); interpolate_image(newframe[1], exnewframe[1], chrom_width, chrom_height); interpolate_image(newframe[2], exnewframe[2], chrom_width, chrom_height); storeframe(exnewframe, *framenum); } else storeframe(newframe,*framenum);//保存当前解码的这一帧}/* decode all macroblocks of the current picture */static void getMBs(framenum)int framenum;{ int comp; int MBA, MBAmax; int bx, by; int COD=0,MCBPC, CBPY, CBP=0, CBPB=0, MODB=0, Mode=0, DQUANT; int COD_index, CBPY_index, MODB_index, DQUANT_index, MCBPC_index; int INTRADC_index, YCBPB_index, UVCBPB_index, mvdbx_index, mvdby_index; int mvx, mvy, mvy_index, mvx_index, pmv0, pmv1, xpos, ypos, gob, i,k; int mvdbx=0, mvdby=0, pmvdbx, pmvdby, gfid, YCBPB, UVCBPB, gobheader_read; int startmv,stopmv,offset,bsize,last_done=0,pCBP=0,pCBPB=0,pCOD=0; int DQ_tab[4] = {-1,-2,1,2}; short *bp; /* number of macroblocks per picture */ MBAmax = mb_width*mb_height; MBA = 0; /* macroblock address */ newgob = 0; /* mark MV's above the picture */ for (i = 1; i < mb_width+1; i++) { for (k = 0; k < 5; k++) { MV[0][k][0][i] = NO_VEC; MV[1][k][0][i] = NO_VEC; } modemap[0][i] = MODE_INTRA; } /* zero MV's on the sides of the picture */ for (i = 0; i < mb_height+1; i++) { for (k = 0; k < 5; k++) { MV[0][k][i][0] = 0; MV[1][k][i][0] = 0; MV[0][k][i][mb_width+1] = 0; MV[1][k][i][mb_width+1] = 0; } modemap[i][0] = MODE_INTRA; modemap[i][mb_width+1] = MODE_INTRA; } fault = 0; gobheader_read = 0; for (;;) { if (trace) printf("frame %d, MB %d\n",framenum,MBA); resync: /* This version of the decoder does not resync on every possible error, and it does not do all possible error checks. It is not difficult to make it much more error robust, but I do not think it is necessary to include this in the freely available version. */ if (fault) { printf("Warning: A Fault Condition Has Occurred - Resyncing \n"); startcode(); /* sync on new startcode */ fault = 0; } if (!(showbits(22)>>6)) { /* startcode */ startcode(); /* in case of byte aligned start code, ie. PSTUF, GSTUF or ESTUF is used */ if (showbits(22) == (32|SE_CODE)) { /* end of sequence */ if (!(syntax_arith_coding && MBA < MBAmax)) { return; } } else if ((showbits(22) == PSC<<5) ) { /* new picture */ if (!(syntax_arith_coding && MBA < MBAmax)) { return; } } else { if (!(syntax_arith_coding && MBA%mb_width)) { if (syntax_arith_coding) { /* SAC hack to finish GOBs which */ gob = (showbits(22) & 31); /* end with MBs coded with no bits */ if (gob * mb_width != MBA) goto finish_gob; } gob = getheader() - 1; if (gob > mb_height) { if (!quiet) printf("GN out of range\n"); return; } /* GFID is not allowed to change unless PTYPE in picture header changes */ gfid = getbits(2); /* NB: in error-prone environments the decoder can use this value to determine whether a picture header where the PTYPE has changed, has been lost */ quant = getbits(5); if (trace) printf("GQUANT: %d\n", quant); xpos = 0; ypos = gob; MBA = ypos * mb_width; newgob = 1; gobheader_read = 1; if (syntax_arith_coding) decoder_reset(); /* init. arithmetic decoder buffer after gob */ } } } finish_gob: /* SAC specific label */ if (!gobheader_read) { xpos = MBA%mb_width; ypos = MBA/mb_width; if (xpos == 0 && ypos > 0) newgob = 0; } else gobheader_read = 0; if (MBA>=MBAmax) return; /* all macroblocks decoded */ read_cod: if (syntax_arith_coding) { if (pict_type == PCT_INTER) { COD_index = decode_a_symbol(cumf_COD); COD = codtab[COD_index]; if (trace) { printf("Arithmetic Decoding Debug \n"); printf("COD Index: %d COD: %d \n", COD_index, COD); } } else COD = 0; /* COD not used in I-pictures, set to zero */ } else { if (pict_type == PCT_INTER) COD = showbits(1); else COD = 0; /* Intra picture -> not skipped */ } if (!COD) { /* COD == 0 --> not skipped */ if (syntax_arith_coding) { if (pict_type == PCT_INTER) { MCBPC_index = decode_a_symbol(cumf_MCBPC); MCBPC = mcbpctab[MCBPC_index]; } else { MCBPC_index = decode_a_symbol(cumf_MCBPC_intra); MCBPC = mcbpc_intratab[MCBPC_index]; } if (trace) printf("MCBPC Index: %d MCBPC: %d \n",MCBPC_index, MCBPC); } else { if (pict_type == PCT_INTER) flushbits(1); /* flush COD bit */ if (pict_type == PCT_INTRA) MCBPC = getMCBPCintra(); else MCBPC = getMCBPC(); } if (fault) goto resync; if (MCBPC == 255) { /* stuffing */ goto read_cod; /* read next COD without advancing MB count */ } else { /* normal MB data */ Mode = MCBPC & 7; /* MODB and CBPB */ if (pb_frame) { CBPB = 0; if (syntax_arith_coding) { MODB_index = decode_a_symbol(cumf_MODB); MODB = modb_tab[MODB_index]; } else MODB = getMODB(); if (trace) printf("MODB: %d\n", MODB); if (MODB == PBMODE_CBPB_MVDB) { if (syntax_arith_coding) { for(i=0; i<4; i++) { YCBPB_index = decode_a_symbol(cumf_YCBPB); YCBPB = ycbpb_tab[YCBPB_index]; CBPB |= (YCBPB << (6-1-i)); } for(i=4; i<6; i++) { UVCBPB_index = decode_a_symbol(cumf_UVCBPB); UVCBPB = uvcbpb_tab[UVCBPB_index]; CBPB |= (UVCBPB << (6-1-i)); } } else CBPB = getbits(6); if (trace) printf("CBPB = %d\n",CBPB); } } if (syntax_arith_coding) { if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { /* Intra */ CBPY_index = decode_a_symbol(cumf_CBPY_intra); CBPY = cbpy_intratab[CBPY_index]; } else { CBPY_index = decode_a_symbol(cumf_CBPY); CBPY = cbpytab[CBPY_index]; } if (trace) printf("CBPY Index: %d CBPY %d \n",CBPY_index, CBPY); } else CBPY = getCBPY(); /* Decode Mode and CBP */ if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) {/* Intra */ if (!syntax_arith_coding) CBPY = CBPY^15; /* needed in huffman coding only */ } CBP = (CBPY << 2) | (MCBPC >> 4); } if (Mode == MODE_INTER4V && !adv_pred_mode) if (!quiet) printf("8x8 vectors not allowed in normal prediction mode\n"); /* Could set fault-flag and resync */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -