diff options
Diffstat (limited to 'Src/h264dec/ldecod/src/mb_prediction.c')
-rw-r--r-- | Src/h264dec/ldecod/src/mb_prediction.c | 979 |
1 files changed, 979 insertions, 0 deletions
diff --git a/Src/h264dec/ldecod/src/mb_prediction.c b/Src/h264dec/ldecod/src/mb_prediction.c new file mode 100644 index 00000000..799236a8 --- /dev/null +++ b/Src/h264dec/ldecod/src/mb_prediction.c @@ -0,0 +1,979 @@ +/*! +************************************************************************************* +* \file mb_prediction.c +* +* \brief +* Macroblock prediction functions +* +* \author +* Main contributors (see contributors.h for copyright, address and affiliation details) +* - Alexis Michael Tourapis <alexismt@ieee.org> +************************************************************************************* +*/ + +#include "contributors.h" + +#include "block.h" +#include "global.h" +#include "mbuffer.h" +#include "elements.h" +#include "errorconcealment.h" +#include "macroblock.h" +#include "fmo.h" +#include "cabac.h" +#include "vlc.h" +#include "image.h" +#include "mb_access.h" +#include "biaridecod.h" +#include "transform8x8.h" +#include "transform.h" +#include "mc_prediction.h" +#include "quant.h" +#include "intra4x4_pred.h" +#include "intra8x8_pred.h" +#include "intra16x16_pred.h" +#include "mv_prediction.h" +#include "mb_prediction.h" +#include "optim.h" + + +int mb_pred_intra4x4(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + Slice *currSlice = currMB->p_Slice; + int yuv = dec_picture->chroma_format_idc - 1; + + if (currMB->is_lossless == FALSE) + { + const h264_short_block_t *blocks = currSlice->cof4[curr_plane]; + const h264_imgpel_macroblock_row_t *mb_pred=currSlice->mb_pred[curr_plane]; + h264_imgpel_macroblock_row_t *mb_rec = currSlice->mb_rec[curr_plane]; + int block_x = currMB->block_x; + int block_y = currMB->block_y; + if (intrapred(currMB, curr_plane, 0,0,block_x + 0,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[0], mb_pred, mb_rec, 0, 0); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 0, 0); + if (intrapred(currMB, curr_plane, 4,0,block_x + 1,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[1], mb_pred, mb_rec, 4, 0); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 4, 0); + if (intrapred(currMB, curr_plane, 0,4,block_x + 0,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[2], mb_pred, mb_rec, 0, 4); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 0, 4); + if (intrapred(currMB, curr_plane, 4,4,block_x + 1,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[3], mb_pred, mb_rec, 4, 4); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 4, 4); + if (intrapred(currMB, curr_plane, 8,0,block_x + 2,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[4], mb_pred, mb_rec, 8, 0); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 8, 0); + if (intrapred(currMB, curr_plane, 12,0,block_x + 3,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[5], mb_pred, mb_rec, 12, 0); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 12, 0); + if (intrapred(currMB, curr_plane, 8,4,block_x + 2,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[6], mb_pred, mb_rec, 8, 4); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 8, 4); + if (intrapred(currMB, curr_plane, 12,4,block_x + 3,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[7], mb_pred, mb_rec, 12, 4); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 12, 4); + if (intrapred(currMB, curr_plane, 0,8,block_x + 0,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[8], mb_pred, mb_rec, 0, 8); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 0, 8); + if (intrapred(currMB, curr_plane, 4,8,block_x + 1,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[9], mb_pred, mb_rec, 4, 8); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 4, 8); + if (intrapred(currMB, curr_plane, 0,12,block_x + 0,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[10], mb_pred, mb_rec, 0, 12); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 0, 12); + if (intrapred(currMB, curr_plane, 4,12,block_x + 1,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[11], mb_pred, mb_rec, 4, 12); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 4, 12); + if (intrapred(currMB, curr_plane, 8,8,block_x + 2,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[12], mb_pred, mb_rec, 8, 8); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 8, 8); + if (intrapred(currMB, curr_plane, 12,8,block_x + 3,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[13], mb_pred, mb_rec, 12, 8); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 12, 8); + if (intrapred(currMB, curr_plane, 8,12,block_x + 2,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[14], mb_pred, mb_rec, 8, 12); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 8, 12); + if (intrapred(currMB, curr_plane, 12,12,block_x + 3,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + opt_itrans4x4(blocks[15], mb_pred, mb_rec, 12, 12); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 12, 12); + // benski> prediction might reference other parts of the image reconstructed during this block, so can't just do a single 16x16 image copy + } + else + { // lossless + h264_imgpel_macroblock_row_t *mb_rec = currSlice->mb_rec[curr_plane]; + int block_x = currMB->block_x; + int block_y = currMB->block_y; + + if (intrapred(currMB, curr_plane, 0,0,block_x + 0,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 0, 0); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 0, 0); + if (intrapred(currMB, curr_plane, 4,0,block_x + 1,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 4, 0); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 4, 0); + if (intrapred(currMB, curr_plane, 0,4,block_x + 0,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 0, 4); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 0, 4); + if (intrapred(currMB, curr_plane, 4,4,block_x + 1,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 4, 4); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 4, 4); + if (intrapred(currMB, curr_plane, 8,0,block_x + 2,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 8, 0); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 8, 0); + if (intrapred(currMB, curr_plane, 12,0,block_x + 3,block_y + 0) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 12, 0); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 0)<<2, currSlice->mb_rec[curr_plane], 12, 0); + if (intrapred(currMB, curr_plane, 8,4,block_x + 2,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 8, 4); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 8, 4); + if (intrapred(currMB, curr_plane, 12,4,block_x + 3,block_y + 1) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 12, 4); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 1)<<2, currSlice->mb_rec[curr_plane], 12, 4); + if (intrapred(currMB, curr_plane, 0,8,block_x + 0,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 0, 8); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 0, 8); + if (intrapred(currMB, curr_plane, 4,8,block_x + 1,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 4, 8); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 4, 8); + if (intrapred(currMB, curr_plane, 0,12,block_x + 0,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 0, 12); + copy_image_data_4x4_stride(image, (block_x + 0)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 0, 12); + if (intrapred(currMB, curr_plane, 4,12,block_x + 1,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 4, 12); + copy_image_data_4x4_stride(image, (block_x + 1)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 4, 12); + if (intrapred(currMB, curr_plane, 8,8,block_x + 2,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 8, 8); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 8, 8); + if (intrapred(currMB, curr_plane, 12,8,block_x + 3,block_y + 2) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 12, 8); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 2)<<2, currSlice->mb_rec[curr_plane], 12, 8); + if (intrapred(currMB, curr_plane, 8,12,block_x + 2,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 8, 12); + copy_image_data_4x4_stride(image, (block_x + 2)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 8, 12); + if (intrapred(currMB, curr_plane, 12,12,block_x + 3,block_y + 3) == SEARCH_SYNC) return SEARCH_SYNC; + Inv_Residual_trans_4x4(currMB, curr_plane, 12, 12); + copy_image_data_4x4_stride(image, (block_x + 3)<<2, (block_y + 3)<<2, currSlice->mb_rec[curr_plane], 12, 12); + // benski> prediction might reference other parts of the image reconstructed during this block, so can't just do a single 16x16 image copy + } + + // chroma decoding ******************************************************* + if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) + { + intra_cr_decoding(currMB, yuv); + } + + return 1; +} + + +int mb_pred_intra16x16(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + int yuv = dec_picture->chroma_format_idc - 1; + + intrapred16x16(currMB, curr_plane, currMB->i16mode); + currMB->ipmode_DPCM = (char) currMB->i16mode; //For residual DPCM + // =============== 4x4 itrans ================ + // ------------------------------------------- + iMBtrans4x4(currMB, curr_plane, 0); + + // chroma decoding ******************************************************* + if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) + { + intra_cr_decoding(currMB, yuv); + } + return 1; +} + +int mb_pred_intra8x8(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + Slice *currSlice = currMB->p_Slice; + int yuv = dec_picture->chroma_format_idc - 1; + + if (currMB->is_lossless) + { + //PREDICTION + intrapred8x8(currMB, curr_plane, 0, 0); + Inv_Residual_trans_8x8(currMB, curr_plane, 0,0); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 0 ,currMB->pix_y + 0, currSlice->mb_rec[curr_plane], 0, 0); + + intrapred8x8(currMB, curr_plane, 8, 0); + Inv_Residual_trans_8x8(currMB, curr_plane, 8,0); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 8 ,currMB->pix_y + 0, currSlice->mb_rec[curr_plane], 8, 0); + + intrapred8x8(currMB, curr_plane, 0, 8); + Inv_Residual_trans_8x8(currMB, curr_plane, 0,8); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 0 ,currMB->pix_y + 8, currSlice->mb_rec[curr_plane], 0, 8); + + intrapred8x8(currMB, curr_plane, 8, 8); + Inv_Residual_trans_8x8 (currMB, curr_plane, 8,8); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 8 ,currMB->pix_y + 8, currSlice->mb_rec[curr_plane], 8, 8); + } + else + { + h264_imgpel_macroblock_row_t *mb_rec = currSlice->mb_rec[curr_plane]; + h264_imgpel_macroblock_row_t *mb_pred = currSlice->mb_pred[curr_plane]; + h264_short_8x8block_t *mb_rres8 = currSlice->mb_rres8[curr_plane]; + + //PREDICTION + intrapred8x8(currMB, curr_plane, 0, 0); + opt_itrans8x8(mb_rec, mb_pred, mb_rres8[0], 0); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 0 ,currMB->pix_y + 0, currSlice->mb_rec[curr_plane], 0, 0); + + intrapred8x8(currMB, curr_plane, 8, 0); + opt_itrans8x8(mb_rec, mb_pred, mb_rres8[1], 8); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 8 ,currMB->pix_y + 0, currSlice->mb_rec[curr_plane], 8, 0); + + intrapred8x8(currMB, curr_plane, 0, 8); + opt_itrans8x8(mb_rec+8, mb_pred+8, mb_rres8[2], 0); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 0 ,currMB->pix_y + 8, currSlice->mb_rec[curr_plane], 0, 8); + + intrapred8x8(currMB, curr_plane, 8, 8); + opt_itrans8x8(mb_rec+8, mb_pred+8, mb_rres8[3], 8); // use DCT transform and make 8x8 block m7 from prediction block mpr + copy_image_data_8x8_stride2(image, currMB->pix_x + 8 ,currMB->pix_y + 8, currSlice->mb_rec[curr_plane], 8, 8); + } + + // chroma decoding ******************************************************* + if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) + { + intra_cr_decoding(currMB, yuv); + } + return 1; +} + + +static void set_chroma_vector(Macroblock *currMB, int *list_offset) +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + + if (!currSlice->mb_aff_frame_flag) + { + if(p_Vid->structure == TOP_FIELD) + { + int k,l; + for (l = LIST_0; l <= (LIST_1); l++) + { + for(k = 0; k < p_Vid->listXsize[l]; k++) + { + if(p_Vid->structure != p_Vid->listX[l][k]->structure) + p_Vid->listX[l][k]->chroma_vector_adjustment = -2; + else + p_Vid->listX[l][k]->chroma_vector_adjustment= 0; + } + } + } + else if(p_Vid->structure == BOTTOM_FIELD) + { + int k,l; + for (l = LIST_0; l <= (LIST_1); l++) + { + for(k = 0; k < p_Vid->listXsize[l]; k++) + { + if (p_Vid->structure != p_Vid->listX[l][k]->structure) + p_Vid->listX[l][k]->chroma_vector_adjustment = 2; + else + p_Vid->listX[l][k]->chroma_vector_adjustment= 0; + } + } + } + else + { + int k,l; + for (l = LIST_0; l <= (LIST_1); l++) + { + for(k = 0; k < p_Vid->listXsize[l]; k++) + { + p_Vid->listX[l][k]->chroma_vector_adjustment= 0; + } + } + } + } + else + { + int mb_nr = (currMB->mbAddrX & 0x01); + int k,l; + + ////////////////////////// + // find out the correct list offsets + if (currMB->mb_field) + { + *list_offset = mb_nr ? 4 : 2; + + for (l = LIST_0 + *list_offset; l <= (LIST_1 + *list_offset); l++) + { + for(k = 0; k < p_Vid->listXsize[l]; k++) + { + if(mb_nr == 0 && p_Vid->listX[l][k]->structure == BOTTOM_FIELD) + p_Vid->listX[l][k]->chroma_vector_adjustment = -2; + else if(mb_nr == 1 && p_Vid->listX[l][k]->structure == TOP_FIELD) + p_Vid->listX[l][k]->chroma_vector_adjustment = 2; + else + p_Vid->listX[l][k]->chroma_vector_adjustment= 0; + } + } + } + else + { + for (l = LIST_0; l <= (LIST_1); l++) + { + for(k = 0; k < p_Vid->listXsize[l]; k++) + { + p_Vid->listX[l][k]->chroma_vector_adjustment= 0; + } + } + } + } + + p_Vid->max_mb_vmv_r = (p_Vid->structure != FRAME || (currSlice->mb_aff_frame_flag && currMB->mb_field)) ? p_Vid->max_vmv_r >> 1 : p_Vid->max_vmv_r; +} + +void mb_pred_skip(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + perform_mc16x16(currMB, curr_plane, dec_picture, LIST_0, list_offset, curr_mb_field); + + opt_copy_image_data_16x16_stride(image, currMB->pix_x, currMB->pix_y, currSlice->mb_pred[curr_plane]); + + if (dec_picture->chroma_format_idc == YUV420) + { + copy_image_data_8x8_stride(dec_picture->imgUV[0], currMB->pix_c_x, currMB->pix_c_y, currSlice->mb_pred[1]); + copy_image_data_8x8_stride(dec_picture->imgUV[1], currMB->pix_c_x, currMB->pix_c_y, currSlice->mb_pred[2]); + } + else if (dec_picture->chroma_format_idc == YUV422) + { + copy_image_data_stride(dec_picture->imgUV[0], currMB->pix_c_x, currMB->pix_c_y, currSlice->mb_pred[1], 8, 16); + copy_image_data_stride(dec_picture->imgUV[1], currMB->pix_c_x, currMB->pix_c_y, currSlice->mb_pred[2], 8, 16); + } +} + +void mb_pred_sp_skip(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + Slice *currSlice = currMB->p_Slice; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + perform_mc16x16(currMB, curr_plane, dec_picture, LIST_0, list_offset, curr_mb_field); + iTransform(currMB, curr_plane, 1); +} + +void mb_pred_p_inter8x8(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + int block8x8; // needed for ABT + int i=0, j=0,k; + + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + int smb = p_Vid->type == SP_SLICE && IS_INTER(currMB); + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + for (block8x8=0; block8x8<4; block8x8++) + { + int mv_mode = currMB->b8mode[block8x8]; + int pred_dir = currMB->b8pdir[block8x8]; + if (mv_mode == SMB8x8) + { + i = (decode_block_scan[block8x8*4] & 3); + j = block8x8 & ~1; + perform_mc8x8(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, curr_mb_field); + } + else if (mv_mode == SMB4x4) + { + int k_start = (block8x8 << 2); + int k_inc = (mv_mode == SMB8x4) ? 2 : 1; + int k_end = (mv_mode == SMB8x8) ? k_start + 1 : ((mv_mode == SMB4x4) ? k_start + 4 : k_start + k_inc + 1); + + int block_size_x = (mv_mode == SMB8x4) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + int block_size_y = (mv_mode == SMB4x8) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + + for (k = k_start; k < k_end; k += k_inc) + { + i = (decode_block_scan[k] & 3); + j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + } + else + { + int k_start = (block8x8 << 2); + int k_inc = (mv_mode == SMB8x4) ? 2 : 1; + int k_end = k_start + k_inc + 1; + + int block_size_x = (mv_mode == SMB8x4) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + int block_size_y = (mv_mode == SMB4x8) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + + for (k = k_start; k < k_end; k += k_inc) + { + i = (decode_block_scan[k] & 3); + j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + } + /* generic: + int k_start = (block8x8 << 2); + int k_inc = (mv_mode == SMB8x4) ? 2 : 1; + int k_end = (mv_mode == SMB8x8) ? k_start + 1 : ((mv_mode == SMB4x4) ? k_start + 4 : k_start + k_inc + 1); + + int block_size_x = ( mv_mode == SMB8x4 || mv_mode == SMB8x8 ) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + int block_size_y = ( mv_mode == SMB4x8 || mv_mode == SMB8x8 ) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + + for (k = k_start; k < k_end; k += k_inc) + { + i = (decode_block_scan[k] & 3); + j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + */ + } + + iTransform(currMB, curr_plane, smb); +} + +void mb_pred_p_inter16x16(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + int smb = (currMB->p_Vid->type == SP_SLICE); + Slice *currSlice = currMB->p_Slice; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + perform_mc16x16(currMB, curr_plane, dec_picture, currMB->b8pdir[0], list_offset, curr_mb_field); + iTransform(currMB, curr_plane, smb); +} + +void mb_pred_p_inter16x8(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + int smb = (currMB->p_Vid->type == SP_SLICE); + Slice *currSlice = currMB->p_Slice; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + perform_mc16x8(currMB, curr_plane, dec_picture, currMB->b8pdir[0], 0, 0, list_offset, curr_mb_field); + perform_mc16x8(currMB, curr_plane, dec_picture, currMB->b8pdir[2], 0, 2, list_offset, curr_mb_field); + iTransform(currMB, curr_plane, smb); +} + +void mb_pred_p_inter8x16(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + int smb = (currMB->p_Vid->type == SP_SLICE); + Slice *currSlice = currMB->p_Slice; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + perform_mc8x16(currMB, curr_plane, dec_picture, currMB->b8pdir[0], 0, 0, list_offset, curr_mb_field); + perform_mc8x16(currMB, curr_plane, dec_picture, currMB->b8pdir[1], 2, 0, list_offset, curr_mb_field); + iTransform(currMB, curr_plane, smb); +} + +void mb_pred_b_dtemporal(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + short ref_idx; + int refList; + + PicMotionParams *motion = &dec_picture->motion; + int k; + int block8x8; // needed for ABT + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + + MotionParams *colocated = &currSlice->p_colocated->frame; + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + if (currMB->mb_field) + { + if(currMB->mbAddrX & 0x01) + { + colocated = &currSlice->p_colocated->bottom; + } + else + { + colocated = &currSlice->p_colocated->top; + } + } + + for (block8x8=0; block8x8<4; block8x8++) + { + int pred_dir = currMB->b8pdir[block8x8]; + + int k_start = (block8x8 << 2); + int k_end = k_start; + + if (p_Vid->active_sps->direct_8x8_inference_flag) + { + k_end ++; + } + else + { + k_end += BLOCK_MULTIPLE; + } + + for (k = k_start; k < k_start + BLOCK_MULTIPLE; k ++) + { + + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + int i4 = currMB->block_x + i; + int j4 = currMB->block_y + j; + int j6 = currMB->block_y_aff + j; + assert (pred_dir<=2); + + refList = (colocated->motion[LIST_0][j6][i4].ref_idx== -1 ? LIST_1 : LIST_0); + ref_idx = colocated->motion[refList][j6][i4].ref_idx; + + if(ref_idx==-1) // co-located is intra mode + { + memset( &motion->motion[LIST_0][j4][i4].mv, 0, sizeof(MotionVector)); + memset( &motion->motion[LIST_1][j4][i4].mv, 0, sizeof(MotionVector)); + + motion->motion[LIST_0][j4][i4].ref_idx = 0; + motion->motion[LIST_1][j4][i4].ref_idx = 0; + } + else // co-located skip or inter mode + { + int mapped_idx=0; + int iref; + + for (iref=0;iref<imin(currSlice->num_ref_idx_l0_active,p_Vid->listXsize[LIST_0 + list_offset]);iref++) + { + if(p_Vid->structure==0 && curr_mb_field==0) + { + // If the current MB is a frame MB and the colocated is from a field picture, + // then the colocated->ref_pic_id may have been generated from the wrong value of + // frame_poc if it references it's complementary field, so test both POC values + if(p_Vid->listX[0][iref]->top_poc*2 == colocated->motion[refList][j6][i4].ref_pic_id || p_Vid->listX[0][iref]->bottom_poc*2 == colocated->motion[refList][j6][i4].ref_pic_id) + { + mapped_idx=iref; + break; + } + else //! invalid index. Default to zero even though this case should not happen + mapped_idx=INVALIDINDEX; + continue; + } + + if (dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_0 + list_offset][iref]==colocated->motion[refList][j6][i4].ref_pic_id) + { + mapped_idx=iref; + break; + } + else //! invalid index. Default to zero even though this case should not happen + { + mapped_idx=INVALIDINDEX; + } + } + if (INVALIDINDEX == mapped_idx) + { + error("temporal direct error: colocated block has ref that is unavailable",-1111); + } + else + { + int mv_scale = currSlice->mvscale[LIST_0 + list_offset][mapped_idx]; + + //! In such case, an array is needed for each different reference. + if (mv_scale == 9999 || p_Vid->listX[LIST_0+list_offset][mapped_idx]->is_long_term) + { + memcpy(&motion->motion[LIST_0][j4][i4].mv, &colocated->motion[refList][j6][i4].mv, sizeof(MotionVector)); + memset(&motion->motion[LIST_1][j4][i4].mv, 0, sizeof(MotionVector)); + } + else + { + motion->motion[LIST_0][j4][i4].mv[0]= (short) ((mv_scale * colocated->motion[refList][j6][i4].mv[0] + 128 ) >> 8); + motion->motion[LIST_0][j4][i4].mv[1]= (short) ((mv_scale * colocated->motion[refList][j6][i4].mv[1] + 128 ) >> 8); + + motion->motion[LIST_1][j4][i4].mv[0]= (short) (motion->motion[LIST_0][j4][i4].mv[0] - colocated->motion[refList][j6][i4].mv[0]); + motion->motion[LIST_1][j4][i4].mv[1]= (short) (motion->motion[LIST_0][j4][i4].mv[1] - colocated->motion[refList][j6][i4].mv[1]); + } + + motion->motion[LIST_0][j4][i4].ref_idx = (char) mapped_idx; //p_Vid->listX[1][0]->ref_idx[refList][j4][i4]; + motion->motion[LIST_1][j4][i4].ref_idx = 0; + } + } + // store reference picture ID determined by direct mode + motion->motion[LIST_0][j4][i4].ref_pic_id = dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_0 + list_offset][(short)motion->motion[LIST_0][j4][i4].ref_idx]; + motion->motion[LIST_1][j4][i4].ref_pic_id = dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_1 + list_offset][(short)motion->motion[LIST_1][j4][i4].ref_idx]; + } + for (k = k_start; k < k_end; k ++) + { + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + if (p_Vid->active_sps->direct_8x8_inference_flag) + perform_mc8x8(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, curr_mb_field); + else + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, 4, 4, curr_mb_field); + } + } + + if (currMB->cbp == 0) + { + opt_copy_image_data_16x16_stride(image, currMB->pix_x, currMB->pix_y, currSlice->mb_pred[curr_plane]); + + if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) + { + copy_image_data_stride(dec_picture->imgUV[0], currMB->pix_c_x, currMB->pix_c_y, currSlice->mb_pred[1], p_Vid->mb_size[IS_CHROMA][0], p_Vid->mb_size[IS_CHROMA][1]); + copy_image_data_stride(dec_picture->imgUV[1], currMB->pix_c_x, currMB->pix_c_y, currSlice->mb_pred[2], p_Vid->mb_size[IS_CHROMA][0], p_Vid->mb_size[IS_CHROMA][1]); + } + } + else + iTransform(currMB, curr_plane, 0); +} + + +void mb_pred_b_inter8x8(Macroblock *currMB, ColorPlane curr_plane, VideoImage *image, StorablePicture *dec_picture) +{ + short ref_idx; + int refList; + + char l0_rFrame = -1, l1_rFrame = -1; + PicMotionParams *motion = &dec_picture->motion; + short pmvl0[2]={0,0}, pmvl1[2]={0,0}; + int block_size_x, block_size_y; + int k; + int block8x8; // needed for ABT + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + int curr_mb_field = ((currSlice->mb_aff_frame_flag)&&(currMB->mb_field)); + + MotionParams *colocated = &currSlice->p_colocated->frame; + int list_offset = 0; + + set_chroma_vector(currMB, &list_offset); + + if (currMB->mb_field) + { + if(currMB->mbAddrX & 0x01) + { + colocated = &currSlice->p_colocated->bottom; + } + else + { + colocated = &currSlice->p_colocated->top; + } + } + + // prepare direct modes + if (currSlice->direct_spatial_mv_pred_flag && (!(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3]))) + prepare_direct_params(currMB, dec_picture, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame); + + for (block8x8=0; block8x8<4; block8x8++) + { + int mv_mode = currMB->b8mode[block8x8]; + int pred_dir = currMB->b8pdir[block8x8]; + + if ( mv_mode == SMB8x8) + { + int i = (decode_block_scan[block8x8*4] & 3); + int j = ((decode_block_scan[block8x8*4] >> 2) & 3); + perform_mc8x8(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, curr_mb_field); + } + else if ( mv_mode == SMB4x4) + { + int k_start = (block8x8 << 2); + + for (k = k_start; k < k_start + 4; k ++) + { + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, BLOCK_SIZE, BLOCK_SIZE, curr_mb_field); + } + } + else if ( mv_mode != BSKIP_DIRECT) + { + int k_start = (block8x8 << 2); + int k_inc = (mv_mode == SMB8x4) ? 2 : 1; + int k_end = (k_start + k_inc + 1); + + block_size_x = ( mv_mode == SMB8x4) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + block_size_y = ( mv_mode == SMB4x8) ? SMB_BLOCK_SIZE : BLOCK_SIZE; + + for (k = k_start; k < k_end; k += k_inc) + { + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + } + else + { + int k_start = (block8x8 << 2); + + // Prepare mvs (needed for deblocking and mv prediction + if (currSlice->direct_spatial_mv_pred_flag) + { + h264_ref_t *ref_pic_num_l0 = dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_0 + list_offset]; + h264_ref_t *ref_pic_num_l1 = dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_1 + list_offset]; + + for (k = k_start; k < k_start + BLOCK_MULTIPLE; k ++) + { + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + int i4 = currMB->block_x + i; + int j4 = currMB->block_y + j; + int j6 = currMB->block_y_aff + j; + + assert (pred_dir<=2); + //===== DIRECT PREDICTION ===== + + if (l0_rFrame >=0) + { + if (!l0_rFrame && ((!colocated->moving_block[j6][i4]) && (!p_Vid->listX[LIST_1 + list_offset][0]->is_long_term))) + { + motion->motion[LIST_0][j4][i4].mv[0] = 0; + motion->motion[LIST_0][j4][i4].mv[1] = 0; + motion->motion[LIST_0][j4][i4].ref_idx = 0; + } + else + { + motion->motion[LIST_0][j4][i4].mv[0] = pmvl0[0]; + motion->motion[LIST_0][j4][i4].mv[1] = pmvl0[1]; + motion->motion[LIST_0][j4][i4].ref_idx = l0_rFrame; + } + } + else + { + motion->motion[LIST_0][j4][i4].ref_idx = -1; + motion->motion[LIST_0][j4][i4].mv[0] = 0; + motion->motion[LIST_0][j4][i4].mv[1] = 0; + } + + if (l1_rFrame >=0) + { + if (l1_rFrame==0 && ((!colocated->moving_block[j6][i4]) && (!p_Vid->listX[LIST_1 + list_offset][0]->is_long_term))) + { + motion->motion[LIST_1][j4][i4].mv[0] = 0; + motion->motion[LIST_1][j4][i4].mv[1] = 0; + motion->motion[LIST_1][j4][i4].ref_idx = l1_rFrame; + } + else + { + motion->motion[LIST_1][j4][i4].mv[0] = pmvl1[0]; + motion->motion[LIST_1][j4][i4].mv[1] = pmvl1[1]; + motion->motion[LIST_1][j4][i4].ref_idx = l1_rFrame; + } + } + else + { + motion->motion[LIST_1][j4][i4].mv[0] = 0; + motion->motion[LIST_1][j4][i4].mv[1] = 0; + motion->motion[LIST_1][j4][i4].ref_idx = -1; + } + + if (l0_rFrame < 0 && l1_rFrame < 0) + { + motion->motion[LIST_0][j4][i4].ref_idx = 0; + motion->motion[LIST_1][j4][i4].ref_idx = 0; + } + + if (motion->motion[LIST_1][j4][i4].ref_idx==-1) + { + pred_dir = 0; + ref_idx = (motion->motion[LIST_0][j4][i4].ref_idx != -1) ? motion->motion[LIST_0][j4][i4].ref_idx : 0; + } + else if (motion->motion[LIST_0][j4][i4].ref_idx==-1) + { + pred_dir = 1; + ref_idx = (motion->motion[LIST_1][j4][i4].ref_idx != -1) ? motion->motion[LIST_1][j4][i4].ref_idx : 0; + } + else + pred_dir = 2; + + motion->motion[LIST_0][j4][i4].ref_pic_id = ref_pic_num_l0[(short)motion->motion[LIST_0][j4][i4].ref_idx]; + motion->motion[LIST_1][j4][i4].ref_pic_id = ref_pic_num_l1[(short)motion->motion[LIST_1][j4][i4].ref_idx]; + } + } + else + { + for (k = k_start; k < k_start + BLOCK_MULTIPLE; k ++) + { + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + int i4 = currMB->block_x + i; + int j4 = currMB->block_y + j; + int j6 = currMB->block_y_aff + j; + + assert (pred_dir<=2); + + refList = (colocated->motion[LIST_0][j6][i4].ref_idx== -1 ? LIST_1 : LIST_0); + ref_idx = colocated->motion[refList][j6][i4].ref_idx; + + if(ref_idx==-1) // co-located is intra mode + { + memset( &motion->motion[LIST_0][j4][i4].mv, 0, sizeof(MotionVector)); + memset( &motion->motion[LIST_1][j4][i4].mv, 0, sizeof(MotionVector)); + + motion->motion[LIST_0][j4][i4].ref_idx = 0; + motion->motion[LIST_1][j4][i4].ref_idx = 0; + } + else // co-located skip or inter mode + { + int mapped_idx=0; + int iref; + + for (iref=0;iref<imin(currSlice->num_ref_idx_l0_active,p_Vid->listXsize[LIST_0 + list_offset]);iref++) + { + if(p_Vid->structure==0 && curr_mb_field==0) + { + // If the current MB is a frame MB and the colocated is from a field picture, + // then the colocated->ref_pic_id may have been generated from the wrong value of + // frame_poc if it references it's complementary field, so test both POC values + if(p_Vid->listX[0][iref]->top_poc*2 == colocated->motion[refList][j6][i4].ref_pic_id || p_Vid->listX[0][iref]->bottom_poc*2 == colocated->motion[refList][j6][i4].ref_pic_id) + { + mapped_idx=iref; + break; + } + else //! invalid index. Default to zero even though this case should not happen + mapped_idx=INVALIDINDEX; + continue; + } + + if (dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_0 + list_offset][iref]==colocated->motion[refList][j6][i4].ref_pic_id) + { + mapped_idx=iref; + break; + } + else //! invalid index. Default to zero even though this case should not happen + { + mapped_idx=INVALIDINDEX; + } + } + if (INVALIDINDEX == mapped_idx) + { + error("temporal direct error: colocated block has ref that is unavailable",-1111); + } + else + { + int mv_scale = currSlice->mvscale[LIST_0 + list_offset][mapped_idx]; + + //! In such case, an array is needed for each different reference. + if (mv_scale == 9999 || p_Vid->listX[LIST_0+list_offset][mapped_idx]->is_long_term) + { + memcpy(&motion->motion[LIST_0][j4][i4].mv, &colocated->motion[refList][j6][i4].mv, sizeof(MotionVector)); + memset(&motion->motion[LIST_1][j4][i4].mv, 0, sizeof(MotionVector)); + } + else + { + motion->motion[LIST_0][j4][i4].mv[0]= (short) ((mv_scale * colocated->motion[refList][j6][i4].mv[0] + 128 ) >> 8); + motion->motion[LIST_0][j4][i4].mv[1]= (short) ((mv_scale * colocated->motion[refList][j6][i4].mv[1] + 128 ) >> 8); + + motion->motion[LIST_1][j4][i4].mv[0]= (short) (motion->motion[LIST_0][j4][i4].mv[0] - colocated->motion[refList][j6][i4].mv[0]); + motion->motion[LIST_1][j4][i4].mv[1]= (short) (motion->motion[LIST_0][j4][i4].mv[1] - colocated->motion[refList][j6][i4].mv[1]); + } + + motion->motion[LIST_0][j4][i4].ref_idx = (char) mapped_idx; //p_Vid->listX[1][0]->ref_idx[refList][j4][i4]; + motion->motion[LIST_1][j4][i4].ref_idx = 0; + } + } + // store reference picture ID determined by direct mode + motion->motion[LIST_0][j4][i4].ref_pic_id = dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_0 + list_offset][(short)motion->motion[LIST_0][j4][i4].ref_idx]; + motion->motion[LIST_1][j4][i4].ref_pic_id = dec_picture->ref_pic_num[p_Vid->current_slice_nr][LIST_1 + list_offset][(short)motion->motion[LIST_1][j4][i4].ref_idx]; + } + } + + if (p_Vid->active_sps->direct_8x8_inference_flag) + { + int i = (decode_block_scan[k_start] & 3); + int j = ((decode_block_scan[k_start] >> 2) & 3); + perform_mc8x8(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, curr_mb_field); + } + else + { + for (k = k_start; k < k_start+BLOCK_MULTIPLE; k ++) + { + int i = (decode_block_scan[k] & 3); + int j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(currMB, curr_plane, dec_picture, pred_dir, i, j, list_offset, BLOCK_SIZE, BLOCK_SIZE, curr_mb_field); + } + } + } + } + + iTransform(currMB, curr_plane, 0); +} + +/*! +************************************************************************ +* \brief +* Copy IPCM coefficients to decoded picture buffer and set parameters for this MB +* (for IPCM CABAC and IPCM CAVLC 28/11/2003) +* +* \author +* Dong Wang <Dong.Wang@bristol.ac.uk> +************************************************************************ +*/ +void set_chroma_qp(Macroblock* currMB); +static inline void update_qp(Macroblock *currMB, int qp) +{ + VideoParameters *p_Vid = currMB->p_Vid; + currMB->qp = qp; + currMB->qp_scaled[0] = qp + p_Vid->bitdepth_luma_qp_scale; + set_chroma_qp(currMB); + currMB->is_lossless = (Boolean) ((currMB->qp_scaled[0] == 0) && (p_Vid->lossless_qpprime_flag == 1)); +} + +void mb_pred_ipcm(Macroblock *currMB) +{ + int i, j, k; + Slice *currSlice = currMB->p_Slice; + VideoParameters *p_Vid = currMB->p_Vid; + StorablePicture *dec_picture = p_Vid->dec_picture; + + //Copy coefficients to decoded picture buffer + //IPCM coefficients are stored in currSlice->ipcm which is set in function read_IPCM_coeffs_from_NAL() + + for(i = 0; i < MB_BLOCK_SIZE; ++i) + { + for(j = 0;j < MB_BLOCK_SIZE ; ++j) + { + dec_picture->imgY->img[currMB->pix_y + i][currMB->pix_x + j] = (imgpel) currSlice->ipcm[0][i][j]; + } + } + + if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(p_Vid)) + { + for (k = 0; k < 2; ++k) + { + for(i = 0; i < p_Vid->mb_cr_size_y; ++i) + { + for(j = 0;j < p_Vid->mb_cr_size_x; ++j) + { + dec_picture->imgUV[k]->img[currMB->pix_c_y+i][currMB->pix_c_x + j] = (imgpel) currSlice->ipcm[k + 1][i][j]; + } + } + } + } + + // for deblocking filter + update_qp(currMB, 0); + + // for CAVLC: Set the nz_coeff to 16. + // These parameters are to be used in CAVLC decoding of neighbour blocks + memset(&p_Vid->nz_coeff[currMB->mbAddrX][0][0][0], 16, sizeof(h264_nz_coefficient)); + + // for CABAC decoding of MB skip flag + currMB->skip_flag = 0; + + //for deblocking filter CABAC + currMB->cbp_blk[0] = 0xFFFF; + + //For CABAC decoding of Dquant + currSlice->last_dquant = 0; +} + |