📄 getpic.c
字号:
fprintf (trace_file, "mvfx: %d\n", mvfx); fprintf (trace_file, "mvfy: %d\n", mvfy); } 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][0][ypos + 1][xpos + 1] = mvfx; MV[1][0][ypos + 1][xpos + 1] = mvfy; MV[0][5][ypos + 1][xpos + 1] = mvbx; MV[1][5][ypos + 1][xpos + 1] = mvby; break; default: /* No MV data for other modes. */ MV[0][0][ypos + 1][xpos + 1] = 0; MV[1][0][ypos + 1][xpos + 1] = 0; MV[0][5][ypos + 1][xpos + 1] = 0; MV[1][5][ypos + 1][xpos + 1] = 0; break; } } if (fault) goto resync; } else { /* COD == 1 --> skipped MB */ if (MBA >= MBAmax) { /* all macroblocks decoded */ return; } flushbits (1); Mode = MODE_INTER; /* Reset CBP */ CBP = 0; coded_map[ypos + 1][xpos + 1] = 0; true_B_prediction_type = B_DIRECT_PREDICTION; /* reset motion vectors */ MV[0][0][ypos + 1][xpos + 1] = 0; MV[1][0][ypos + 1][xpos + 1] = 0; MV[0][5][ypos + 1][xpos + 1] = 0; MV[1][5][ypos + 1][xpos + 1] = 0; } /* Store mode and prediction type */ modemap[ypos + 1][xpos + 1] = Mode; predictionmap[ypos + 1][xpos + 1] = true_B_prediction_type; /* store defaults for advanced intra coding mode */ if (advanced_intra_coding) { for (i = 0; i < blk_cnt; i++) store_qcoeff[MBA * blk_cnt * 64 + i * 64] = 1024; } if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { MV[0][0][ypos + 1][xpos + 1] = MV[1][0][ypos + 1][xpos + 1] = 0; MV[0][5][ypos + 1][xpos + 1] = MV[1][5][ypos + 1][xpos + 1] = 0; }reconstruct_mb: /* pixel coordinates of top left corner of current macroblock */ /* one delayed because of OBMC */ if (xpos > 0) { bx = 16 * (xpos - 1); by = 16 * ypos; } else { bx = coded_picture_width - 16; by = 16 * (ypos - 1); } if (MBA > 0) { Mode = modemap[by / 16 + 1][bx / 16 + 1]; true_B_prediction_type = predictionmap[by / 16 + 1][bx / 16 + 1]; /* motion compensation for true B frame. */ if (Mode == MODE_INTER || Mode == MODE_INTER_Q) reconstruct_true_B (bx, by, true_B_prediction_type); /* copy or add block data into true B picture */ for (comp = 0; comp < blk_cnt; comp++) { /* inverse DCT */ if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { if (refidct) idctref (ld->block[comp]); else idct (ld->block[comp]); addblock (comp, bx, by, 0); } else if ((pCBP & (1 << (blk_cnt - 1 - comp)))) { /* No need to to do this for blocks with no coeffs */ if (refidct) idctref (ld->block[comp]); else idct (ld->block[comp]); addblock (comp, bx, by, 1); } } } /* end if (MBA > 0) */ if (!COD) { Mode = modemap[ypos + 1][xpos + 1]; true_B_prediction_type = predictionmap[ypos + 1][xpos + 1]; for (comp = 0; comp < blk_cnt; comp++) { clearblock (comp); if ((Mode == MODE_INTRA || Mode == MODE_INTRA_Q) && !(advanced_intra_coding)) { /* Intra (except in advanced intra coding mode) */ bp = ld->block[comp]; bp[0] = getbits (8); if (trace) { fprintf (trace_file, "DC[%d]: (", comp); printbits ((int) bp[0], 8, 8); fprintf (trace_file, "): %d\n", (int) bp[0]); } if (bp[0] == 128) if (!quiet) fprintf (stderr, "Illegal DC-coeff: 1000000\n"); if (bp[0] == 255) /* Spec. in H.26P, not in TMN4 */ bp[0] = 128; bp[0] *= 8; /* Iquant */ if ((CBP & (1 << (blk_cnt - 1 - comp)))) { getblock (comp, 0, 0, Mode); } } else { /* Inter (or Intra in advanced intra coding mode) */ if ((CBP & (1 << (blk_cnt - 1 - comp)))) { getblock (comp, 1, INTRA_AC_DC, Mode); } } if ((advanced_intra_coding) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) { Intra_AC_DC_Decode (store_qcoeff, INTRA_AC_DC, MBA, xpos, ypos, comp, newgob); memcpy ((void *) (store_qcoeff + MBA * blk_cnt * 64 + comp * 64), (void *) ld->block[comp], sizeof (short) * 64); } if (fault) goto resync; } } /* advance to next macroblock */ MBA++; pCBP = CBP; pCOD = COD; quant_map[ypos + 1][xpos + 1] = quant; fflush (stdout); if (MBA >= MBAmax && !last_done) { COD = 1; xpos = 0; ypos++; last_done = 1; goto reconstruct_mb; } }}/********************************************************************** * * Name: get_EI_EP_MBs * Description: decode MBs for one EI or EP picture * Input: frame number * Returns: * Side effects: * * Date: 971102 Author: mikeg@ee.ubc.ca * ***********************************************************************/ static void get_EI_EP_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, pmvf0, pmvf1; int gfid, gobheader_read; int last_done = 0, pCBP = 0, pCOD = 0; int DQ_tab[4] = {-1, -2, 1, 2}; short *bp; int ei_ep_cbp = 0, ei_ep_quant = 0, ei_ep_prediction_type; int CBPC = 0, CBPY = 0, tmp = 0; /* variables used in advanced intra coding mode */ int INTRA_AC_DC = 0; short *store_qcoeff; 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; modemap[0][i] = MODE_INTRA; predictionmap[0][i] = EI_EP_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; modemap[i][0] = MODE_INTRA; modemap[i][mb_width + 1] = MODE_INTRA; predictionmap[i][0] = EI_EP_INTRA_PREDICTION; predictionmap[i][mb_width + 1] = EI_EP_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); ei_ep_prediction_type = getMBTYPE (&ei_ep_cbp, &ei_ep_quant); if (fault) goto resync; if (B_EI_EP_STUFFING == ei_ep_prediction_type) { /* stuffing - read next COD without advancing MB count. */ goto read_cod; } if (EI_EP_INTRA_PREDICTION != ei_ep_prediction_type) { if (1 == ei_ep_quant) { Mode = MODE_INTER_Q; } else { Mode = MODE_INTER; } } else { if (1 == ei_ep_quant) { Mode = MODE_INTRA_Q; } else { Mode = MODE_INTRA; } } if (advanced_intra_coding && (EI_EP_INTRA_PREDICTION == ei_ep_prediction_type)) { /* get INTRA_AC_DC mode for annex I */ if (!showbits (1)) INTRA_AC_DC = getbits (1); else INTRA_AC_DC = getbits (2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -