📄 getpic.c
字号:
/* 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; /* if a gob with GN != 0 was present as the first gob * of a picture, decode the rest of the gob header */ if (gob) goto getgobhrd; for (;;) { if (MBA >= MBAmax) { /* all macroblocks decoded */ memcpy(anchorframemodemap,modemap,(sizeof(int)*(MBR+1)*(MBC+2)) ); return; } 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 (!(syntax_arith_coding && MBA < MBAmax)) { return; } } else if ((showbits (22) == PSC << 5)) { /* new picture */ /* conceal the last mb row */ if (concealment && MBA < MBAmax) { /* store the missing GOB number for error concealment */ number_of_mb_rows_missing = (MBAmax - MBA) / mb_width ; start_mb_row_missing = MBA / mb_width; decode_last_mb = 1; pypos = ypos; } else 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 end with MBs coded with no * bits. */ gob = (showbits (22) & 31); if (gob * mb_width != MBA) goto finish_gob; } gob = getheader () - 1; if (gob > mb_height) { if (!quiet) printf ("GN out of range\n"); return; } /* Get the remaining of the GOB header: this should be the complete gob header to facilitate the integration of the slice structure and the syntax of Annex N and the BCM. This will be changed when Slices are implemented */ /* if the first sync of a picture in not GN 0, start here */getgobhrd: getgobheader(); /* Get the reference picture for prediction corresponding to TRP in the GOB header. Only the reference GOB is needed, but it is simpler to get the whole reference picture. This should be changed to save time */ if (reference_picture_selection_mode) { if (-1 == (quality = get_reference_picture())) break; if (quality > 256) { fprintf(stderr,"completely out of sync -- waiting for I-frame\n"); stop_decoder = 1; break; } if ((mv_outside_frame) && (framenum > 0)) { make_edge_image (prev_I_P_frame[0], edgeframe[0], coded_picture_width, coded_picture_height, 32); make_edge_image (prev_I_P_frame[1], edgeframe[1], chrom_width, chrom_height, 16); make_edge_image (prev_I_P_frame[2], edgeframe[2], chrom_width, chrom_height, 16); } } /* if some data is loss due to (channel) errors, * decode the last (delayed) macroblock */ if (concealment && (gob * mb_width != MBA)) { /* if we are missing the last gob of the previous frame and * the first gob of the current frame, framenum should be * incremented */ /* store the missing GOB number for error concealment */ if (gob - MBA / mb_width < 0) { ++framenum; number_of_mb_rows_missing = (MBAmax - MBA) / mb_width ; }else number_of_mb_rows_missing = gob - MBA / mb_width ; start_mb_row_missing = MBA / mb_width; decode_last_mb = 1; pypos = ypos; } 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 */ } } } if (decode_last_mb) { if (!start_mb_row_missing) { /* the first gob is missing, we don't need to decode the last MB */ goto conceal_gob; } else { xpos = 0; ypos = ++pypos; COD = 1; goto reconstruct_mb; } } dont_reconstruct_next_mb = 0;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; }read_cod: if (syntax_arith_coding) { if (pict_type == PCT_INTER || pict_type == PCT_IPB) { COD_index = decode_a_symbol (cumf_COD); COD = codtab[COD_index]; if (trace) { fprintf (trace_file, "Arithmetic Decoding Debug \n"); fprintf (trace_file, "COD Index: %d COD: %d \n", COD_index, COD); } } else { COD = 0; /* COD not used in I-pictures, set to zero */ coded_map[ypos + 1][xpos + 1] = 1; } } else { if (PCT_INTER == pict_type || PCT_IPB == pict_type) { COD = showbits (1); if (trace) { fprintf (trace_file, "COD : %d \n", COD); } } else { COD = 0; /* Intra picture -> not skipped */ coded_map[ypos + 1][xpos + 1] = 1; } } if (!COD) { /* COD == 0 --> not skipped */ if (syntax_arith_coding) { if (pict_type == PCT_INTER || pict_type == PCT_IPB) { if (plus_type) { MCBPC_index = decode_a_symbol (cumf_MCBPC_4MVQ); MCBPC = mcbpctab_4mvq[MCBPC_index]; } else { MCBPC_index = decode_a_symbol (cumf_MCBPC_no4MVQ); MCBPC = mcbpctab[MCBPC_index]; } } else { MCBPC_index = decode_a_symbol (cumf_MCBPC_intra); MCBPC = mcbpc_intratab[MCBPC_index]; } if (trace) fprintf (trace_file, "MCBPC Index: %d MCBPC: %d \n", MCBPC_index, MCBPC); } else { if (PCT_INTER == pict_type || PCT_IPB == pict_type) { /* flush COD bit */ flushbits (1); } if (PCT_INTRA == pict_type) { MCBPC = getMCBPCintra (); } else { MCBPC = getMCBPC (); } } if (fault) goto resync; if (MCBPC == 255) { /* stuffing - read next COD without advancing MB count. */ goto read_cod; } else { /* normal MB data */ Mode = MCBPC & 7; if (advanced_intra_coding && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) { /* get INTRA_AC_DC mode for annex I */ if (syntax_arith_coding) { INTRA_AC_DC_index = decode_a_symbol (cumf_INTRA_AC_DC); INTRA_AC_DC = intra_ac_dctab[INTRA_AC_DC_index]; } else { /* using VLC */ 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); } /* MODB and CBPB */ if (pb_frame) { CBPB = 0; if (syntax_arith_coding) { if (pb_frame== PB_FRAMES) { MODB_index = decode_a_symbol (cumf_MODB_G); MODB = modb_tab_G[MODB_index]; } else { MODB_index = decode_a_symbol (cumf_MODB_M); MODB = modb_tab_M[MODB_index]; } } else MODB = getMODB (); if ( (MODB == PBMODE_CBPB_MVDB && pb_frame == PB_FRAMES) || (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_FRW_PRED || MODB == PBMODE_CBPB_BIDIR_PRED || MODB == PBMODE_CBPB_BCKW_PRED) ) ) { 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) fprintf (trace_file, "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) fprintf (trace_file, "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 */ coded_map[ypos + 1][xpos + 1] = 1; if (!syntax_arith_coding) CBPY = CBPY ^ 15; /* needed in huffman coding only */ } else if (!syntax_arith_coding && alternative_inter_VLC_mode && ((MCBPC >> 4) == 3)) CBPY = CBPY ^ 15; /* Annex S.3 change */ CBP = (CBPY << 2) | (MCBPC >> 4); if ((Mode == MODE_INTER4V || Mode == MODE_INTER4V_Q) && !use_4mv) { fault = 1; if (!quiet) { /* Could set fault-flag and resync */ printf ("8x8 vectors not allowed in normal prediction mode\n"); } if (trace) fprintf (trace_file, "8x8 vectors not allowed in normal prediction mode\n"); } if (Mode == MODE_INTER_Q || Mode == MODE_INTRA_Q || Mode == MODE_INTER4V_Q) { /* Read DQUANT if necessary */ if (syntax_arith_coding) { DQUANT_index = decode_a_symbol (cumf_DQUANT); DQUANT = dquanttab[DQUANT_index] - 2; quant += DQUANT; if (trace) fprintf (trace_file, "DQUANT Index: %d DQUANT %d \n", DQUANT_index, DQUANT); } else { 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -