/*! * \param *dc The current DecodingContext. * \param mbAddr The current macroblock address. * \return 0 if macroblock decoding fail, 1 otherwise. * * This function extract one macroblock from the bitstream, handle intra/inter * prediction for its blocks. */ int macroblock_layer(DecodingContext_t *dc, const int mbAddr) { TRACE_INFO(MB, "<> " BLD_GREEN "macroblock_layer(" CLR_RESET "%i" BLD_GREEN ")\n" CLR_RESET, mbAddr); int retcode = FAILURE; // Macroblock allocation //////////////////////////////////////////////////////////////////////////// dc->mb_array[mbAddr] = (Macroblock_t*)calloc(1, sizeof(Macroblock_t)); if (dc->mb_array[mbAddr] == NULL) { TRACE_ERROR(MB, "Unable to alloc new macroblock!\n"); } else { // Set macroblock address dc->mb_array[mbAddr]->mbAddr = mbAddr; // Shortcuts pps_t *pps = dc->pps_array[dc->active_slice->pic_parameter_set_id]; sps_t *sps = dc->sps_array[pps->seq_parameter_set_id]; slice_t *slice = dc->active_slice; Macroblock_t *mb = dc->mb_array[mbAddr]; // Macroblock decoding //////////////////////////////////////////////////////////////////////// #if ENABLE_DEBUG mb->mbFileAddrStart = bitstream_get_absolute_bit_offset(dc->bitstr); #endif // ENABLE_DEBUG deriv_macroblockneighbours_availability(dc, mbAddr); MbPosition(mb, sps); if (pps->entropy_coding_mode_flag) mb->mb_type = read_ae(dc, SE_mb_type); else mb->mb_type = read_ue(dc->bitstr); mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0); mb->NumMbPart = NumMbPart(slice->slice_type, mb->mb_type); if (mb->mb_type == I_PCM) { #if ENABLE_IPCM TRACE_3(MB, "---- macroblock_layer - I PCM macroblock\n"); while (bitstream_check_alignment(dc->bitstr) == false) { if (read_bit(dc->bitstr) != 0) // pcm_alignment_zero_bit { TRACE_ERROR(MB, " Error while reading pcm_alignment_zero_bit: must be 0!\n"); return FAILURE; } } // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2 initCabacDecodingEngine(dc); int i = 0; for (i = 0; i < 256; i++) { mb->pcm_sample_luma[i] = (uint8_t)read_bits(dc->bitstr, sps->BitDepthY); } // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2 initCabacDecodingEngine(dc); for (i = 0; i < 2 * sps->MbWidthC * sps->MbHeightC; i++) { mb->pcm_sample_chroma[i] = (uint8_t)read_bits(dc->bitstr, sps->BitDepthC); } // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2 initCabacDecodingEngine(dc); #else // ENABLE_IPCM TRACE_ERROR(MB, "I_PCM decoding is currently disabled!\n"); return UNSUPPORTED; #endif // ENABLE_IPCM } else { #if ENABLE_INTER_PRED bool noSubMbPartSizeLessThan8x8Flag = true; if (mb->mb_type != I_NxN && mb->MbPartPredMode[0] != Intra_16x16 && mb->NumMbPart == 4) { TRACE_3(MB, "---- macroblock_layer - mb partition & related\n"); int mbPartIdx = 0; for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if (mb->sub_mb_type[mbPartIdx] != B_Direct_8x8) { if (NumSubMbPart(slice->slice_type, mb->sub_mb_type[mbPartIdx]) > 1) { noSubMbPartSizeLessThan8x8Flag = false; } } else if (sps->direct_8x8_inference_flag == false) { noSubMbPartSizeLessThan8x8Flag = false; } } // Read sub macroblock prediction mode sub_mb_pred(dc, mb->mb_type, mb->sub_mb_type); } else #endif // ENABLE_INTER_PRED { TRACE_3(MB, "---- macroblock_layer - transform_size_8x8_flag & prediction modes\n"); if (pps->transform_8x8_mode_flag == true && mb->mb_type == I_NxN) { if (pps->entropy_coding_mode_flag) mb->transform_size_8x8_flag = read_ae(dc, SE_transform_size_8x8_flag); else mb->transform_size_8x8_flag = read_bit(dc->bitstr); // Need to update MbPartPredMode in order to detect I_8x8 prediction mode mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0); } // Read macroblock prediction mode mb_pred(dc, mb); } if (mb->MbPartPredMode[0] != Intra_16x16) { TRACE_3(MB, "---- macroblock_layer - coded block pattern & transform_size_8x8_flag\n"); if (pps->entropy_coding_mode_flag) mb->coded_block_pattern = read_ae(dc, SE_coded_block_pattern); else mb->coded_block_pattern = read_me(dc->bitstr, sps->ChromaArrayType, dc->IdrPicFlag); mb->CodedBlockPatternLuma = mb->coded_block_pattern % 16; mb->CodedBlockPatternChroma = mb->coded_block_pattern / 16; #if ENABLE_INTER_PRED if (mb->CodedBlockPatternLuma > 0 && pps->transform_8x8_mode_flag == true && mb->mb_type != I_NxN && noSubMbPartSizeLessThan8x8Flag == true && (mb->mb_type != B_Direct_16x16 || sps->direct_8x8_inference_flag == true)) { if (pps->entropy_coding_mode_flag) mb->transform_size_8x8_flag = read_ae(dc, SE_transform_size_8x8_flag); else mb->transform_size_8x8_flag = read_bit(dc->bitstr); // Need to update MbPartPredMode in order to account for I_8x8 prediction mode if (transform_size_8x8_flag) mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0); } #endif // ENABLE_INTER_PRED } if (mb->CodedBlockPatternLuma > 0 || mb->CodedBlockPatternChroma > 0 || mb->MbPartPredMode[0] == Intra_16x16) { TRACE_3(MB, "---- macroblock_layer - quantization parameter & residual datas\n"); // Read QP delta if (pps->entropy_coding_mode_flag) mb->mb_qp_delta = read_ae(dc, SE_mb_qp_delta); else mb->mb_qp_delta = read_se(dc->bitstr); // Parse the residual coefficients //////////////////////////////////////////////////////////////// // Luma levels residual_luma(dc, 0, 15); // Chroma levels residual_chroma(dc, 0, 15); } else { TRACE_3(MB, "---- macroblock_layer - No residual datas to decode in this macroblock\n"); } // Compute luma Quantization Parameters if (mb->mb_qp_delta) mb->QPY = ((slice->QPYprev + mb->mb_qp_delta + 52 + sps->QpBdOffsetY*2) % (52 + sps->QpBdOffsetY)) - sps->QpBdOffsetY; else mb->QPY = slice->QPYprev; mb->QPprimeY = mb->QPY + sps->QpBdOffsetY; slice->QPYprev = mb->QPY; // Set Transform Bypass Mode if (sps->qpprime_y_zero_transform_bypass_flag == true && mb->QPprimeY == 0) mb->TransformBypassModeFlag = true; // Prediction process (include quantization and transformation stages) //////////////////////////////////////////////////////////////// if (dc->IdrPicFlag) { retcode = intra_prediction_process(dc, mb); } else { retcode = inter_prediction_process(dc, mb); } // Print macroblock(s) header and block data ? //////////////////////////////////////////////////////////////// #if ENABLE_DEBUG mb->mbFileAddrStop = bitstream_get_absolute_bit_offset(dc->bitstr) - 1; int frame_debug_range[2] = {-1, -1}; // Range of (idr) frame(s) to debug/analyse int mb_debug_range[2] = {-1, -1}; // Range of macroblock(s) to debug/analyse if (dc->idrCounter >= frame_debug_range[0] && dc->idrCounter <= frame_debug_range[1]) { if (mb->mbAddr >= mb_debug_range[0] && mb->mbAddr <= mb_debug_range[1]) { print_macroblock_layer(dc, mb); print_macroblock_pixel_residual(mb); print_macroblock_pixel_predicted(mb); print_macroblock_pixel_final(mb); } } #endif // ENABLE_DEBUG } TRACE_3(MB, "---- macroblock_layer - the end\n\n"); } return retcode; }
void macroblock_layer(const decoder_context *decoder, unsigned mb_id) { bitstream_reader *reader = (void *) &decoder->reader; const decoder_context_sps *sps = decoder->active_sps; const decoder_context_pps *pps = decoder->active_pps; macroblock *mb = &decoder->frames[0]->macroblocks[mb_id]; unsigned ChromaArrayType = ChromaArrayType(); unsigned CodedBlockPatternLuma = 0; unsigned CodedBlockPatternChroma = 0; unsigned noSubMbPartSizeLessThan8x8Flag = 1; unsigned MbWidthC, MbHeightC; unsigned mb_type; int32_t mb_qp_delta; int i; mb->transform_size_8x8_flag = 0; if (CABAC_MODE) { mb_type = bitstream_read_ae(reader); } else { mb_type = bitstream_read_ue(reader); } switch (decoder->sh.slice_type) { case I: SYNTAX_IPRINT("MacroBlock type %d = %s\n", mb_type, MB_TYPE_I(mb)); break; default: SYNTAX_ERR("MacroBlock slice_type unimplemented\n"); break; } mb->mb_type = mb_type; mb->slice_type = decoder->sh.slice_type; switch (decoder->active_sps->chroma_format_idc) { case YUV400: MbWidthC = 4; MbHeightC = 4; break; case YUV420: MbWidthC = 8; MbHeightC = 8; break; case YUV422: MbWidthC = 8; MbHeightC = 16; break; case YUV444: MbWidthC = 16; MbHeightC = 16; break; default: SYNTAX_ERR("Bad color format\n"); break; } if (mb->mb_type == I_PCM) { uint8_t align_bits = bitstream_read_rbsp_align(reader); // uint8_t luma_depth = decoder->sps.bit_depth_luma_minus8 + 8; // uint8_t chroma_depth = decoder->sps.bit_depth_chroma_minus8 + 8; SYNTAX_ERR("I_PCM unimplemented\n"); if (align_bits != 0) { SYNTAX_ERR("I_PCM align failure\n"); } for (i = 0; i < 16 * 16; i++) { // mb->luma_decoded[i] = // bitstream_read_u(reader, luma_depth); } for (i = 0; i < MbWidthC * MbHeightC; i++) { // mb->chromaU_decoded[i] = // bitstream_read_u(reader, chroma_depth); } for (i = 0; i < MbWidthC * MbHeightC; i++) { // mb->chromaV_decoded[i] = // bitstream_read_u(reader, chroma_depth); } return; } if (mb->mb_type != I_NxN && MbPartPredMode(mb, decoder->sh.slice_type) != Intra_16x16 && NumMbPart(mb) == 4) { SYNTAX_ERR("MbPartPredMode unimplemented\n"); } else { if (decoder->active_pps->transform_8x8_mode_flag && mb->mb_type == I_NxN) { mb->transform_size_8x8_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("transform_size_8x8_flag %u\n", mb->transform_size_8x8_flag); } macroblock_prediction(decoder, mb, mb_id); } if (MbPartPredMode(mb, decoder->sh.slice_type) != Intra_16x16) { unsigned codeNum = bitstream_read_ue(reader); unsigned coded_block_pattern = 0; if (ChromaArrayType == 1 || ChromaArrayType == 2) { if (codeNum > 47) { SYNTAX_ERR("Malformed codeNum %d\n", codeNum); } coded_block_pattern = coded_block_pattern_intra_1_2[codeNum]; } if (ChromaArrayType == 0 || ChromaArrayType == 3) { if (codeNum > 15) { SYNTAX_ERR("Malformed codeNum %d\n", codeNum); } coded_block_pattern = coded_block_pattern_intra_0_3[codeNum]; } CodedBlockPatternLuma = coded_block_pattern % 16; CodedBlockPatternChroma = coded_block_pattern / 16; // SYNTAX_IPRINT("coded_block_pattern = %u\n", coded_block_pattern); // SYNTAX_IPRINT("CodedBlockPatternLuma = %u\n", CodedBlockPatternLuma); // SYNTAX_IPRINT("CodedBlockPatternChroma = %u\n", CodedBlockPatternChroma); if (CodedBlockPatternLuma > 0 && decoder->active_pps->transform_8x8_mode_flag && mb->mb_type != I_NxN && noSubMbPartSizeLessThan8x8Flag && (/*mb->mb_type != B_Direct_16x16 ||*/ decoder->active_sps->direct_8x8_inference_flag)) { mb->transform_size_8x8_flag = bitstream_read_u(reader, 1); SYNTAX_IPRINT("transform_size_8x8_flag %u\n", mb->transform_size_8x8_flag); } } else { switch (mb->mb_type) { case 1 ... 4: break; case 5 ... 8: CodedBlockPatternChroma = 1; break; case 9 ... 12: CodedBlockPatternChroma = 2; break; case 13 ... 16: CodedBlockPatternLuma = 15; break; case 17 ... 20: CodedBlockPatternChroma = 1; CodedBlockPatternLuma = 15; break; case 21 ... 24: CodedBlockPatternChroma = 2; CodedBlockPatternLuma = 15; break; } } if (CodedBlockPatternLuma == 0 && CodedBlockPatternChroma == 0 && MbPartPredMode(mb, decoder->sh.slice_type) != Intra_16x16) { SYNTAX_IPRINT("MacroBlock is empty\n"); mb->mb_qp_delta = 0; mb->luma_DC.totalcoeff = 0; mb->chroma_U_DC.totalcoeff = 0; mb->chroma_V_DC.totalcoeff = 0; for (i = 0; i < 16; i++) { mb->luma_AC[i].totalcoeff = 0; if (i < 4) { mb->chroma_U_AC[i].totalcoeff = 0; mb->chroma_V_AC[i].totalcoeff = 0; } } return; } mb_qp_delta = bitstream_read_se(reader); if (mb_qp_delta > 26 || mb_qp_delta < -26) { SYNTAX_ERR("Malformed mb_qp_delta %d\n", mb_qp_delta); } mb->mb_qp_delta = mb_qp_delta; // SYNTAX_IPRINT("mb_qp_delta = %d\n", mb->mb_qp_delta); residual(decoder, mb, mb_id, 0, 15, CodedBlockPatternLuma, CodedBlockPatternChroma); }
/*! * \brief Read prediction informations for current macroblock. * \param *dc The current DecodingContext. * \param *mb The current macroblock. * * Intra prediction infos are a table containing prediction mode for each blocks. * Inter prediction infos are motion vectors. */ static void mb_pred(DecodingContext_t *dc, Macroblock_t *mb) { TRACE_INFO(MB, " > " BLD_GREEN "mb_pred()\n" CLR_RESET); if (mb->MbPartPredMode[0] == Intra_4x4 || mb->MbPartPredMode[0] == Intra_8x8 || mb->MbPartPredMode[0] == Intra_16x16) { if (mb->MbPartPredMode[0] == Intra_4x4) { // Read intra prediction mode for all 16 4x4 luma blocks unsigned int luma4x4BlkIdx = 0; for (luma4x4BlkIdx = 0; luma4x4BlkIdx < 16; luma4x4BlkIdx++) { if (dc->entropy_coding_mode_flag) mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = read_ae(dc, SE_prev_intraxxx_pred_mode_flag); else mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = read_bit(dc->bitstr); if (mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] == false) { if (dc->entropy_coding_mode_flag) mb->rem_intra4x4_pred_mode[luma4x4BlkIdx] = read_ae(dc, SE_rem_intraxxx_pred_mode); else mb->rem_intra4x4_pred_mode[luma4x4BlkIdx] = read_bits(dc->bitstr, 3); } } } else if (mb->MbPartPredMode[0] == Intra_8x8) { // Read intra prediction mode for all 4 8x8 luma blocks unsigned int luma8x8BlkIdx = 0; for (luma8x8BlkIdx = 0; luma8x8BlkIdx < 4; luma8x8BlkIdx++) { if (dc->entropy_coding_mode_flag) mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] = read_ae(dc, SE_prev_intraxxx_pred_mode_flag); else mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] = read_bit(dc->bitstr); if (mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] == false) { if (dc->entropy_coding_mode_flag) mb->rem_intra8x8_pred_mode[luma8x8BlkIdx] = read_ae(dc, SE_rem_intraxxx_pred_mode); else mb->rem_intra8x8_pred_mode[luma8x8BlkIdx] = read_bits(dc->bitstr, 3); } } } // Read intra prediction mode for chroma blocks if (dc->ChromaArrayType == 1 || dc->ChromaArrayType == 2) { if (dc->entropy_coding_mode_flag) mb->IntraChromaPredMode = read_ae(dc, SE_intra_chroma_pred_mode); else mb->IntraChromaPredMode = read_ue(dc->bitstr); } } else if (mb->MbPartPredMode[0] != Direct) { // ref_idx_l0 unsigned int mbPartIdx = 0; for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++) { if ((dc->active_slice->num_ref_idx_l0_active_minus1 > 0 || dc->active_slice->mb_field_decoding_flag != dc->active_slice->field_pic_flag) && MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L1) { if (dc->entropy_coding_mode_flag) mb->ref_idx_l0[mbPartIdx] = read_ae(dc, SE_ref_idx_lx); else mb->ref_idx_l0[mbPartIdx] = read_te(dc->bitstr, 0); } } // ref_idx_l1 for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++) { if ((dc->active_slice->num_ref_idx_l1_active_minus1 > 0 || dc->active_slice->mb_field_decoding_flag != dc->active_slice->field_pic_flag) && MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L0) { if (dc->entropy_coding_mode_flag) mb->ref_idx_l1[mbPartIdx] = read_ae(dc, SE_ref_idx_lx); else mb->ref_idx_l1[mbPartIdx] = read_te(dc->bitstr, 0); } } // mvd_l0 for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++) { if (MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L1) { if (dc->entropy_coding_mode_flag) { mb->mvd_l0[mbPartIdx][0][0] = read_ae(dc, SE_mvd_lx0); mb->mvd_l0[mbPartIdx][0][1] = read_ae(dc, SE_mvd_lx1); } else { mb->mvd_l0[mbPartIdx][0][0] = read_te(dc->bitstr, 0); mb->mvd_l0[mbPartIdx][0][1] = read_te(dc->bitstr, 0); } } } // mvd_l1 for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++) { if (MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L0) { if (dc->entropy_coding_mode_flag) { mb->mvd_l1[mbPartIdx][0][0] = read_ae(dc, SE_mvd_lx0); mb->mvd_l1[mbPartIdx][0][1] = read_ae(dc, SE_mvd_lx1); } else { mb->mvd_l1[mbPartIdx][0][0] = read_te(dc->bitstr, 0); mb->mvd_l1[mbPartIdx][0][1] = read_te(dc->bitstr, 0); } } } } }
void RBSP_decode(NALunit nal_unit) { static int nalBrojac=0; static int idr_frame_number=0; printf("Entering RBPS_decode #%d\n",nalBrojac++); initRawReader(nal_unit.rbsp_byte, nal_unit.NumBytesInRBSP); //TYPE 7 = Sequence parameter set TODO: Provjera postoji li veæ SPS //READ SPS if (nal_unit.nal_unit_type==NAL_UNIT_TYPE_SEI) { printf("RBSP_decode -> Not supported NAL unit type: SEI (type 6)\n"); } else if (nal_unit.nal_unit_type==NAL_UNIT_TYPE_SPS) { fill_sps(&nal_unit); init_h264_structures(); AllocateMemory(); } //TYPE 8 = Picture parameter set TODO: Provjera postoji li veæ PPS i SPS else if (nal_unit.nal_unit_type==NAL_UNIT_TYPE_PPS) { fill_pps(&nal_unit); } //IDR or NOT IDR slice data //////////////////////////////////////////////////////////////////// //Actual picture decoding takes place here //The main loop works macroblock by macroblock until the end of the slice //Macroblock skipping is implemented else if ((nal_unit.nal_unit_type==NAL_UNIT_TYPE_IDR) || (nal_unit.nal_unit_type==NAL_UNIT_TYPE_NOT_IDR)) { frameCount++; //Read slice header fill_shd(&nal_unit); printf("Working on frame #%d...\n", frameCount); int MbCount=shd.PicSizeInMbs; //Norm: firstMbAddr=first_mb_in_slice * ( 1 + MbaffFrameFlag ); int firstMbAddr = 0; CurrMbAddr = firstMbAddr; //Norm: moreDataFlag = 1 bool moreDataFlag = true; //Norm: prevMbSkipped = 0 int prevMbSkipped = 0; //Used later on int mb_skip_run; // Prediction samples formed by either intra or inter prediction. int predL[16][16], predCb[8][8], predCr[8][8]; QPy = shd.SliceQPy; while (moreDataFlag && CurrMbAddr<MbCount) { /*for (int i = 0; i < 4; i++) ChromaDCLevel[0][i] = ChromaDCLevel[1][i] = 0; for (int i = 0; i < 16; i++) LumaDCLevel[i] = 0;*/ if ((shd.slice_type%5)!=I_SLICE && (shd.slice_type%5)!=SI_SLICE) { //First decode various data at the beggining of each slice/frame //Norm: if( !entropy_coding_mode_flag ) ... this "if clause" is skipped. mb_skip_run=expGolomb_UD(); prevMbSkipped = (mb_skip_run > 0); for(int i=0; i<mb_skip_run; i++ ) { if (CurrMbAddr >= MbCount) { break; } mb_type = P_Skip; mb_type_array[CurrMbAddr]=P_Skip; // Inter prediction: DeriveMVs(); Decode(predL, predCr, predCb); // Norm: QpBdOffsetY == 0 in baseline QPy = (QPy + mb_qp_delta + 52) % 52; // Inverse transformation and decoded sample construction: transformDecodingP_Skip(predL, predCb, predCr, QPy); //Norm: CurrMbAddr = NextMbAddress( CurrMbAddr ) CurrMbAddr++; } if ((CurrMbAddr != firstMbAddr) || (mb_skip_run > 0)) { moreDataFlag = more_rbsp_data(); } } if(moreDataFlag) { // Norm: start macroblock_layer() mb_pos_array[CurrMbAddr]=(RBSP_current_bit+1)&7; mb_type = expGolomb_UD(); mb_type_array[CurrMbAddr]=mb_type; if ((mb_type > 31) || ((shd.slice_type == I_SLICE) && (mb_type > 24))) { printf("Fatal error: Unexpected mb_type value (%d)\n", mb_type); printf("Slice type: %d\n", shd.slice_type); printf("Frame #%d, CurrMbAddr = %d\n", frameCount, CurrMbAddr); system("pause"); writeToPPM("errorFrame"); // dump the current frame exit(1); } //Norm: if( mb_type != I_NxN && MbPartPredMode( mb_type, 0 ) != Intra_16x16 && NumMbPart( mb_type ) == 4 ) // I_NxN is an alias for Intra_4x4 and Intra_8x8 MbPartPredMode (mb_type in both cases equal to 0) // mb_type (positive integer value) is equal to "Name of mb_type" (i.e. I_NxN). These are often interchanged in the norm // Everything as described in norm page 119. table 7-11. //Specific inter prediction? // Norm: if (mb_type != I_NxN && MbPartPredMode(mb_type,0) != Intra_16x16 && NumMbPart(mb_type) == 4) if(MbPartPredMode(mb_type,0) != Intra_4x4 && MbPartPredMode( mb_type, 0 )!=Intra_16x16 && NumMbPart( mb_type )==4 ) { // Norm: start sub_mb_pred(mb_type) int mbPartIdx; for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { sub_mb_type[mbPartIdx]=expGolomb_UD(); } for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if ((shd.num_ref_idx_active_override_flag > 0) && (mb_type != P_8x8ref0) && (SubMbPredMode(sub_mb_type[mbPartIdx]) != Pred_L1)) { ref_idx_l0_array[CurrMbAddr][mbPartIdx] = expGolomb_TD(); } } // Norm: there are no B-frames in baseline, so the stream // does not contain ref_idx_l1 or mvd_l1 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { for (int subMbPartIdx = 0; subMbPartIdx < NumSubMbPart(sub_mb_type[mbPartIdx]); subMbPartIdx++) { mvd_l0[mbPartIdx][subMbPartIdx][0] = expGolomb_SD(); mvd_l0[mbPartIdx][subMbPartIdx][1] = expGolomb_SD(); } } // Norm: end sub_mb_pred(mb_type) } else { //Norm: This is section "mb_pred( mb_type )" if(MbPartPredMode(mb_type, 0) == Intra_4x4 /*|| MbPartPredMode(mb_type, 0) == Intra_8x8*/ || MbPartPredMode(mb_type, 0) == Intra_16x16 ) { if(MbPartPredMode(mb_type, 0) == Intra_4x4) { for(int luma4x4BlkIdx=0; luma4x4BlkIdx<16; luma4x4BlkIdx++) { prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = (bool)getRawBit(); if(prev_intra4x4_pred_mode_flag[luma4x4BlkIdx]==false) { rem_intra4x4_pred_mode[luma4x4BlkIdx]=getRawBits(3); } } } //Norm: //if( MbPartPredMode( mb_type, 0 ) = = Intra_8x8 ) //This if clause has been skipped, because "intra_8x8" is not supported in baseline. //Norm: //if( ChromaArrayType == 1 || ChromaArrayType == 2 ) //baseline defines "ChromaArrayType==1", so the if clause is skipped intra_chroma_pred_mode=expGolomb_UD(); if (intra_chroma_pred_mode > 3) { printf("Fatal error: Unexpected intra_chroma_pred_mode value (%d)\n", intra_chroma_pred_mode); printf("Frame #%d, CurrMbAddr = %d\n", frameCount, CurrMbAddr); system("pause"); writeToPPM("errorFrame"); // dump the current frame exit(1); } } else { int mbPartIdx; for (mbPartIdx = 0; mbPartIdx < NumMbPart(mb_type); mbPartIdx++) { if ((shd.num_ref_idx_l0_active_minus1 > 0) && (MbPartPredMode(mb_type, mbPartIdx) != Pred_L1)) { ref_idx_l0_array[CurrMbAddr][mbPartIdx] = expGolomb_TD(); } } // Norm: there are no B-frames in baseline, so the stream // does not contain ref_idx_l1 or mvd_l1 for (mbPartIdx = 0; mbPartIdx < NumMbPart(mb_type); ++mbPartIdx) { if (MbPartPredMode(mb_type, mbPartIdx) != Pred_L1) { mvd_l0[mbPartIdx][0][0] = expGolomb_SD(); mvd_l0[mbPartIdx][0][1] = expGolomb_SD(); } } } // Norm: end mb_pred(mb_type) } //If the next if clause does not execute, this is the final value of coded block patterns for this macroblock CodedBlockPatternLuma=-1; CodedBlockPatternChroma=-1; if(MbPartPredMode(mb_type,0)!=Intra_16x16) { int coded_block_pattern=expGolomb_UD(); if (coded_block_pattern > 47) { printf("Fatal error: Unexpected coded_block_pattern value (%d)\n", coded_block_pattern); printf("Frame #%d, CurrMbAddr = %d\n", frameCount, CurrMbAddr); system("pause"); writeToPPM("errorFrame"); // dump the current frame exit(1); } //This is not real coded_block_pattern, it's the coded "codeNum" value which is now being decoded: if(MbPartPredMode(mb_type,0)==Intra_4x4 /*|| MbPartPredMode(mb_type,0)==Intra_8x8*/ ) { coded_block_pattern=codeNum_to_coded_block_pattern_intra[coded_block_pattern]; } //Inter prediction else { coded_block_pattern=codeNum_to_coded_block_pattern_inter[coded_block_pattern]; } CodedBlockPatternLuma=coded_block_pattern & 15; CodedBlockPatternChroma=coded_block_pattern >> 4; //Norm: /* if( CodedBlockPatternLuma > 0 && transform_8x8_mode_flag && mb_type != I_NxN && noSubMbPartSizeLessThan8x8Flag && ( mb_type != B_Direct_16x16 || direct_8x8_inference_flag)) */ //This if clause is not implemented since transform_8x8_mode_flag is not supported } //DOES NOT EXIST IN THE NORM! else { if (shd.slice_type % 5 == I_SLICE) { CodedBlockPatternChroma=I_Macroblock_Modes[mb_type][5]; CodedBlockPatternLuma=I_Macroblock_Modes[mb_type][6]; } else { CodedBlockPatternChroma=P_and_SP_macroblock_modes[mb_type][5]; CodedBlockPatternLuma=P_and_SP_macroblock_modes[mb_type][6]; } } CodedBlockPatternLumaArray[CurrMbAddr] = CodedBlockPatternLuma; CodedBlockPatternChromaArray[CurrMbAddr] = CodedBlockPatternChroma; if(CodedBlockPatternLuma>0 || CodedBlockPatternChroma>0 || MbPartPredMode(mb_type,0)==Intra_16x16) { mb_qp_delta=expGolomb_SD(); if ((mb_qp_delta < -26) || (mb_qp_delta > 25)) { printf("Fatal error: Unexpected mb_qp_delta value (%d)\n", mb_qp_delta); printf("Frame #%d, CurrMbAddr = %d\n", frameCount, CurrMbAddr); system("pause"); writeToPPM("errorFrame"); // dump the current frame exit(1); } //Norm: decode residual data. //residual_block_cavlc( coeffLevel, startIdx, endIdx, maxNumCoeff ) residual(0, 15); } else { clear_residual_structures(); } // Norm: end macroblock_layer() //Data ready for rendering // Norm: QpBdOffsetY == 0 in baseline QPy = (QPy + mb_qp_delta + 52) % 52; if ((MbPartPredMode(mb_type , 0) == Intra_4x4) || (MbPartPredMode(mb_type , 0) == Intra_16x16)) { intraPrediction(predL, predCr, predCb); } else { DeriveMVs(); Decode(predL, predCr, predCb); } if (MbPartPredMode(mb_type, 0) == Intra_16x16) { transformDecodingIntra_16x16Luma(Intra16x16DCLevel, Intra16x16ACLevel, predL, QPy); } else if (MbPartPredMode(mb_type, 0) != Intra_4x4) // Intra { for(int luma4x4BlkIdx = 0; luma4x4BlkIdx < 16; luma4x4BlkIdx++) { transformDecoding4x4LumaResidual(LumaLevel, predL, luma4x4BlkIdx, QPy); } } transformDecodingChroma(ChromaDCLevel[0], ChromaACLevel[0], predCb, QPy, true); transformDecodingChroma(ChromaDCLevel[1], ChromaACLevel[1], predCr, QPy, false); moreDataFlag=more_rbsp_data(); ++CurrMbAddr; }