📄 getpic.c
字号:
* Input: frame number * Returns: * Side effects: * * Date: 971102 Author: mikeg@ee.ubc.ca * * ***********************************************************************/ static void get_B_MBs (int framenum) { int comp; int MBA, MBAmax; int bx, by; int COD = 0, CBP = 0, Mode = 0, DQUANT; int xpos, ypos, gob, i; int mvfx = 0, mvfy = 0, mvbx = 0, mvby = 0, pmvf0, pmvf1, pmvb0, pmvb1; int gfid, gobheader_read; int last_done = 0, pCBP = 0, pCOD = 0; int DQ_tab[4] = {-1, -2, 1, 2}; short *bp; int true_B_cbp = 0, true_B_quant = 0, true_B_prediction_type; int CBPC = 0, CBPY = 0, tmp = 0; /* variables used in advanced intra coding mode */ int INTRA_AC_DC = 0; short *store_qcoeff; /* 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++) { MV[0][0][0][i] = NO_VEC; MV[1][0][0][i] = NO_VEC; MV[0][5][0][i] = NO_VEC; MV[1][5][0][i] = NO_VEC; modemap[0][i] = MODE_INTRA; predictionmap[0][i] = B_INTRA_PREDICTION; } /* zero MV's on the sides of the picture */ for (i = 0; i < mb_height + 1; i++) { MV[0][0][i][0] = 0; MV[1][0][i][0] = 0; MV[0][0][i][mb_width + 1] = 0; MV[1][0][i][mb_width + 1] = 0; MV[0][5][i][0] = 0; MV[1][5][i][0] = 0; MV[0][5][i][mb_width + 1] = 0; MV[1][5][i][mb_width + 1] = 0; modemap[i][0] = MODE_INTRA; modemap[i][mb_width + 1] = MODE_INTRA; predictionmap[i][0] = B_INTRA_PREDICTION; predictionmap[i][mb_width + 1] = B_INTRA_PREDICTION; } /* initialize the qcoeff used in advanced intra coding */ if (advanced_intra_coding) { /* store the qcoeff for the frame */ if ((store_qcoeff = (short *) calloc (64 * MBAmax * blk_cnt, sizeof (short))) == 0) { fprintf (stderr, "getMB(): Couldn't allocate store_qcoeff.\n"); exit (-1); } } fault = 0; gobheader_read = 0; for (;;) { if (trace) fprintf (trace_file, "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 (!(MBA < MBAmax)) { return; } } else if ((showbits (22) == PSC << 5)) { /* new picture */ if (!(MBA < MBAmax)) { return; } } else { if (!(MBA % mb_width)) { 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); if (trace) { fprintf (trace_file, "gfid: "); printbits (gfid, 2, 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) { fprintf (trace_file, "quant: "); printbits (quant, 5, 5); } xpos = 0; ypos = gob; MBA = ypos * mb_width; newgob = 1; gobheader_read = 1; } } } /* 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) { /* all macroblocks decoded */ return; }read_cod: COD = showbits (1); if (trace) { fprintf (trace_file, "COD : %d \n", COD); } if (!COD) { /* COD == 0 --> not skipped */ coded_map[ypos + 1][xpos + 1] = 1; /* flush COD bit */ flushbits (1); true_B_prediction_type = getMBTYPE (&true_B_cbp, &true_B_quant); if (fault) goto resync; if (B_EI_EP_STUFFING == true_B_prediction_type) { /* stuffing - read next COD without advancing MB count. */ goto read_cod; } if (B_INTRA_PREDICTION != true_B_prediction_type) { if (1 == true_B_quant) { Mode = MODE_INTER_Q; } else { Mode = MODE_INTER; } } else { if (1 == true_B_quant) { Mode = MODE_INTRA_Q; } else { Mode = MODE_INTRA; } } if (advanced_intra_coding && (B_INTRA_PREDICTION == true_B_prediction_type)) { /* get INTRA_AC_DC mode for annex I */ if (!showbits (1)) INTRA_AC_DC = getbits (1); else INTRA_AC_DC = getbits (2); if (trace) { fprintf (trace_file, "INTRA_AC_DC: %d\n", INTRA_AC_DC); } } if (1 == true_B_cbp) { CBPC = getscalabilityCBPC (); CBPY = getCBPY (); /* Decode Mode and CBP */ if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { /* Intra */ /* needed in huffman coding only */ CBPY = CBPY ^ 15; } /* Annex S.3 change */ else if (alternative_inter_VLC_mode && (CBPC == 3) ) CBPY = CBPY ^ 15; CBP = (CBPY << 2) | CBPC; } else { CBP = 0; } if (fault) goto resync; if (Mode == MODE_INTER_Q || Mode == MODE_INTRA_Q ) { /* Read DQUANT if necessary */ if (true_B_frame && true_B_quant) { if (!modified_quantization_mode) { DQUANT = getbits (2); quant += DQ_tab[DQUANT]; if (trace) { fprintf (trace_file, "DQUANT ("); printbits (DQUANT, 2, 2); fprintf (trace_file, "): %d = %d\n", DQUANT, DQ_tab[DQUANT]); } } else { tmp = getbits (1); if (tmp) { /* only one more additional bit was sent */ tmp = getbits (1); if (tmp) { /* second bit of quant is 1 */ DQUANT = change_of_quant_tab_11[quant]; } else { /* second bit of quant is 0 */ DQUANT = change_of_quant_tab_10[quant]; } quant += DQUANT; if (trace) { fprintf (trace_file, "DQUANT (1"); printbits (tmp, 1, 1); fprintf (trace_file, "): %d \n", DQUANT); } } else { /* five additional bits were sent as * DQUANT */ DQUANT = getbits (5); quant = DQUANT; if (trace) { fprintf (trace_file, "DQUANT ("); printbits (DQUANT, 5, 5); fprintf (trace_file, "): %d \n", DQUANT); } } } } if (quant > 31 || quant < 1) { if (!quiet) printf ("Quantizer out of range: clipping\n"); quant = mmax (1, mmin (31, quant)); /* could set fault-flag and resync here */ } } /* motion vectors */ if (Mode == MODE_INTER || Mode == MODE_INTER_Q ) { switch (true_B_prediction_type) { case B_FORWARD_PREDICTION: if (plus_type && long_vectors) { mvfx = getRVLC (); mvfy = getRVLC (); /* flush start code emulation bit */ if (mvfx == 1 && mvfy == 1) flushbits(1); } else { mvfx = getTMNMV (); mvfy = getTMNMV (); } pmvf0 = find_pmv (xpos, ypos, 0, 0); pmvf1 = find_pmv (xpos, ypos, 0, 1); if (plus_type && long_vectors) { mvfx += pmvf0; mvfy += pmvf1; } else { mvfx = motion_decode (mvfx, pmvf0); mvfy = motion_decode (mvfy, pmvf1); } if (trace) { fprintf (trace_file, "mvfx: %d\n", mvfx); fprintf (trace_file, "mvfy: %d\n", mvfy); } MV[0][0][ypos + 1][xpos + 1] = mvfx; MV[1][0][ypos + 1][xpos + 1] = mvfy; MV[0][5][ypos + 1][xpos + 1] = 0; MV[1][5][ypos + 1][xpos + 1] = 0; break; case B_BACKWARD_PREDICTION: if (plus_type && long_vectors) { mvbx = getRVLC (); mvby = getRVLC (); /* flush start code emulation bit */ if (mvbx == 1 && mvby == 1) flushbits(1); } else { mvbx = getTMNMV (); mvby = getTMNMV (); } pmvb0 = find_pmv (xpos, ypos, 5, 0); pmvb1 = find_pmv (xpos, ypos, 5, 1); if (plus_type && long_vectors) { mvbx += pmvb0; mvby += pmvb1; } else { mvbx = motion_decode (mvbx, pmvb0); mvby = motion_decode (mvby, pmvb1); } if (trace) { fprintf (trace_file, "mvbx: %d\n", mvbx); fprintf (trace_file, "mvby: %d\n", mvby); } MV[0][5][ypos + 1][xpos + 1] = mvbx; MV[1][5][ypos + 1][xpos + 1] = mvby; MV[0][0][ypos + 1][xpos + 1] = 0; MV[1][0][ypos + 1][xpos + 1] = 0; break; case B_BIDIRECTIONAL_PREDICTION: if (plus_type && long_vectors) { mvfx = getRVLC (); mvfy = getRVLC (); /* flush start code emulation bit */ if (mvfx == 1 && mvfy == 1) flushbits(1); } else { mvfx = getTMNMV (); mvfy = getTMNMV (); } pmvf0 = find_pmv (xpos, ypos, 0, 0); pmvf1 = find_pmv (xpos, ypos, 0, 1); if (plus_type && long_vectors) { mvfx += pmvf0; mvfy += pmvf1; } else { mvfx = motion_decode (mvfx, pmvf0); mvfy = motion_decode (mvfy, pmvf1); } if (trace) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -