/*! * \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; }
/*! * \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); } } } } }
/*! * \param *dc The current DecodingContext. * \param mb_type The macroblock prediction type. * \param *sub_mb_type The sub macroblock prediction type. * * Find the sub macroblock prediction type (intra prediction mode or motion vectors exctraction). */ static void sub_mb_pred(DecodingContext_t *dc, const unsigned int mb_type, unsigned int *sub_mb_type) { TRACE_INFO(MB, " > " BLD_GREEN "sub_mb_pred()\n" CLR_RESET); // Shortcut Macroblock_t *mb = dc->mb_array[dc->CurrMbAddr]; slice_t *slice = dc->active_slice; // Read sub_mb_type int mbPartIdx = 0; for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if (dc->entropy_coding_mode_flag) sub_mb_type[mbPartIdx] = read_ae(dc, SE_sub_mb_type); else sub_mb_type[mbPartIdx] = read_ue(dc->bitstr); } // ref_idx_l0 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if ((slice->num_ref_idx_l0_active_minus1 > 0 || slice->mb_field_decoding_flag != slice->field_pic_flag) && mb_type != P_8x8ref0 && sub_mb_type[mbPartIdx] != B_Direct_8x8 && SubMbPredMode(slice->slice_type, sub_mb_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 < 4; mbPartIdx++) { if ((slice->num_ref_idx_l1_active_minus1 > 0 || slice->mb_field_decoding_flag != slice->field_pic_flag) && sub_mb_type[mbPartIdx] != B_Direct_8x8 && SubMbPredMode(slice->slice_type, sub_mb_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 < 4; mbPartIdx++) { if (sub_mb_type[mbPartIdx] != B_Direct_8x8 && SubMbPredMode(slice->slice_type, sub_mb_type[mbPartIdx]) != Pred_L1) { int subMbPartIdx = 0; for (subMbPartIdx = 0; subMbPartIdx < NumSubMbPart(slice->slice_type, sub_mb_type[mbPartIdx]); subMbPartIdx++) { if (dc->entropy_coding_mode_flag) { mb->mvd_l0[mbPartIdx][subMbPartIdx][0] = read_ae(dc, SE_mvd_lx0); mb->mvd_l0[mbPartIdx][subMbPartIdx][1] = read_ae(dc, SE_mvd_lx1); } else { mb->mvd_l0[mbPartIdx][subMbPartIdx][0] = read_se(dc->bitstr); mb->mvd_l0[mbPartIdx][subMbPartIdx][1] = read_se(dc->bitstr); } } } } // mvd_l1 for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if (sub_mb_type[mbPartIdx] != B_Direct_8x8 && SubMbPredMode(slice->slice_type, sub_mb_type[mbPartIdx]) != Pred_L0) { int subMbPartIdx = 0; for (subMbPartIdx = 0; subMbPartIdx < NumSubMbPart(slice->slice_type, sub_mb_type[mbPartIdx]); subMbPartIdx++) { if (dc->entropy_coding_mode_flag) { mb->mvd_l1[mbPartIdx][subMbPartIdx][0] = read_ae(dc, SE_mvd_lx0); mb->mvd_l1[mbPartIdx][subMbPartIdx][1] = read_ae(dc, SE_mvd_lx1); } else { mb->mvd_l1[mbPartIdx][subMbPartIdx][0] = read_se(dc->bitstr); mb->mvd_l1[mbPartIdx][subMbPartIdx][1] = read_se(dc->bitstr); } } } } }
/*! * \param *dc The current DecodingContext. * \param *slice The current Slice. * \return 0 if an error occurred while decoding slice datas, 1 otherwise. */ static int decodeSliceData(DecodingContext_t *dc, slice_t *slice) { TRACE_INFO(SLICE, "> " BLD_GREEN "decodeSliceData()\n" CLR_RESET); // Initialization int retcode = SUCCESS; dc->CurrMbAddr = 0; slice->moreDataFlag = true; slice->prevMbSkipped = false; // Shortcut pps_t *pps = dc->pps_array[slice->pic_parameter_set_id]; // Slice data decoding //////////////////////////////////////////////////////////////////////////// if (pps->entropy_coding_mode_flag) { // CABAC alignment while (bitstream_check_alignment(dc->bitstr) == false) { if (read_bit(dc->bitstr) == 0) // cabac_alignment_one_bit { TRACE_ERROR(SLICE, "cabac_alignment_one_bit must be 1\n"); return FAILURE; } } // CABAC initialization process initCabacContextVariables(dc); initCabacDecodingEngine(dc); } while ((retcode == SUCCESS) && (slice->moreDataFlag == true) && (dc->CurrMbAddr < dc->PicSizeInMbs)) { #if ENABLE_INTER_PRED // Only I frames are supported anyway if (slice->slice_type != 2 && slice->slice_type != 7 && slice->slice_type != 4 && slice->slice_type != 9) // Not I or SI slice { if (pps->entropy_coding_mode_flag) { slice->mb_skip_flag = read_ae(dc, SE_mb_skip_flag); slice->moreDataFlag = !slice->mb_skip_flag; } else { int i = 0; slice->mb_skip_run = read_ue(dc->bitstr); slice->prevMbSkipped = (slice->mb_skip_run > 0); for (i = 0; i < slice->mb_skip_run; i++) { dc->CurrMbAddr = NextMbAddress(dc, dc->CurrMbAddr); } if (slice->mb_skip_run > 0) { slice->moreDataFlag = h264_more_rbsp_data(dc->bitstr); } } } // If there is still some data in the slice if (slice->moreDataFlag) { #if ENABLE_MBAFF if (slice->MbaffFrameFlag == true && (dc->CurrMbAddr % 2 == 0 || (dc->CurrMbAddr % 2 == 1 && slice->prevMbSkipped == true))) { if (pps->entropy_coding_mode_flag) slice->mb_field_decoding_flag = read_ae(dc, SE_mb_field_decoding_flag); else slice->mb_field_decoding_flag = read_bit(dc->bitstr); TRACE_ERROR(DSLICE, ">>> UNSUPPORTED (interlaced mode)\n"); return UNSUPPORTED; } #endif /* ENABLE_MBAFF */ // Macroblock decoding retcode = macroblock_layer(dc, dc->CurrMbAddr); } #endif /* ENABLE_INTER_PRED */ // Macroblock decoding retcode = macroblock_layer(dc, dc->CurrMbAddr); // Check for end of slice if (pps->entropy_coding_mode_flag) { #if ENABLE_INTER_PRED // Only I frames are supported anyway if (slice->slice_type != 2 && slice->slice_type != 7 && slice->slice_type != 4 && slice->slice_type != 9) // Not I or SI slice { slice->prevMbSkipped = slice->mb_skip_flag; } #if ENABLE_MBAFF // MbaffFrameFlag is unsupported, so always "false" if (slice->MbaffFrameFlag == true && dc->CurrMbAddr % 2 == 0) { slice->moreDataFlag = true; } else #endif /* ENABLE_MBAFF */ #endif /* ENABLE_INTER_PRED */ { slice->end_of_slice_flag = read_ae(dc, SE_end_of_slice_flag); if (slice->end_of_slice_flag) { TRACE_INFO(SLICE, "end_of_slice_flag detected!\n"); slice->moreDataFlag = false; } } } else { slice->moreDataFlag = h264_more_rbsp_data(dc->bitstr); } // Get next macroblock address dc->CurrMbAddr = NextMbAddress(dc, dc->CurrMbAddr); } return retcode; }