/*! *********************************************************************** * \brief * Calculate SAD for 8x8 (with a threshold) *********************************************************************** */ distblk distortion8x8SADthres(short* diff, distblk min_cost) { int distortion = 0; int i, j; int imin_cost = dist_down(min_cost); for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { distortion += iabs(*diff++); } if (distortion > imin_cost) break; } return (dist_scale((distblk) distortion)); }
distblk compute_SSE16x16_thres(imgpel **imgRef, imgpel **imgSrc, int xRef, int xSrc, distblk min_cost) { int i, j; imgpel *lineRef, *lineSrc; distblk distortion = 0; int imin_cost = dist_down(min_cost); for (j = 0; j < MB_BLOCK_SIZE; j++) { lineRef = &imgRef[j][xRef]; lineSrc = &imgSrc[j][xSrc]; for (i = 0; i < MB_BLOCK_SIZE; i++) distortion += iabs2( *lineRef++ - *lineSrc++ ); if (distortion > imin_cost) return (min_cost); } return dist_scale(distortion); }
/*! ************************************************************************************* * \brief * SAD distortion for an 8x8 Intra block ************************************************************************************* */ distblk compute_sad8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost) { imgpel *cimg, *cmpr; int i32Cost = 0; int i, j; int imin_cost = dist_down(min_cost); for (j=0; j<8; j++) { cimg = &cur_img[j][pic_opix_x]; cmpr = &mpr8x8[j][0]; for (i=0; i<8; i++) { i32Cost += iabs(*cimg++ - *cmpr++); } if (i32Cost > imin_cost) { return min_cost; } } return dist_scale(i32Cost); }
/*! ************************************************************************************* * \brief * SSE distortion for an 8x8 Intra block ************************************************************************************* */ distblk compute_sse8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost) { int i, j; imgpel *cimg, *cmpr; int imin_cost = dist_down(min_cost); int distortion = 0; for (j=0; j<8; j++) { cimg = &cur_img[j][pic_opix_x]; cmpr = &mpr8x8[j][0]; for (i=0; i<8; i++) { distortion += iabs2(*cimg++ - *cmpr++); } if (distortion > imin_cost) { return min_cost; } } return dist_scale(distortion); }
/*! ************************************************************************ * \brief * JLT : SAD computation (on-the-fly) ************************************************************************ */ distblk computeSAD_otf(StorablePicture *ref1, MEBlock *mv_block, distblk min_mcost, MotionVector *cand) { int mcost = 0; int imin_cost = dist_down(min_mcost); int y,x; short blocksize_x = mv_block->blocksize_x; short blocksize_y = mv_block->blocksize_y; VideoParameters *p_Vid = mv_block->p_Vid; DecodedPictureBuffer *p_Dpb = p_Vid->p_Dpb_layer[p_Vid->dpb_layer_id]; #if (JM_MEM_DISTORTION) int *imgpel_abs = p_Vid->imgpel_abs; #endif imgpel *src_line, *ref_line ; imgpel data[MB_PIXELS]; // local allocation could be optimized by a global instanciation int tmp_line[ (MB_BLOCK_SIZE+5)*(MB_BLOCK_SIZE+5) ] ; src_line = mv_block->orig_pic[0]; ref_line = data ; // get block with interpolation on-the-fly p_Dpb->pf_get_block_luma( p_Vid, ref_line, tmp_line, cand->mv_x, cand->mv_y, blocksize_x, blocksize_y, ref1, 0 ) ; for (y=0; y<blocksize_y; y++) { for (x = 0; x < blocksize_x; x+=4) { #if (JM_MEM_DISTORTION) mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; #else mcost += iabs( *src_line++ - *ref_line++ ); mcost += iabs( *src_line++ - *ref_line++ ); mcost += iabs( *src_line++ - *ref_line++ ); mcost += iabs( *src_line++ - *ref_line++ ); #endif } if(mcost > imin_cost) return (dist_scale_f((distblk)mcost)); } if ( mv_block->ChromaMEEnable ) { // calculate chroma conribution to motion compensation error int blocksize_x_cr = mv_block->blocksize_cr_x; int blocksize_y_cr = mv_block->blocksize_cr_y; int k; int mcr_cost = 0; // chroma me cost for (k=0; k < 2; k++) { src_line = mv_block->orig_pic[k+1]; ref_line = data ; p_Dpb->pf_get_block_chroma[OTF_ME]( p_Vid, ref_line, tmp_line, cand->mv_x, cand->mv_y, blocksize_x_cr, blocksize_y_cr, ref1, k+1 ) ; mcr_cost = 0; for (y = 0; y < blocksize_y_cr; y++) { for (x = 0; x < blocksize_x_cr; x += 2) { #if (JM_MEM_DISTORTION) mcr_cost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcr_cost += imgpel_abs[ *src_line++ - *ref_line++ ]; #else mcr_cost += iabs( *src_line++ - *ref_line++ ); mcr_cost += iabs( *src_line++ - *ref_line++ ); #endif } } mcost += mv_block->ChromaMEWeight * mcr_cost; if(mcost >imin_cost) return (dist_scale_f((distblk)mcost)); } } CHECKOVERFLOW(mcost); return (dist_scale((distblk)mcost)); }
/*! ************************************************************************ * \brief * JLT : SADWP computation for weighted samples ( on-the-fly ) ************************************************************************ */ distblk computeSADWP_otf(StorablePicture *ref1, MEBlock *mv_block, distblk min_mcost, MotionVector *cand ) { int mcost = 0; int imin_cost = dist_down(min_mcost); int y, x; int weighted_pel; short blocksize_x = mv_block->blocksize_x; short blocksize_y = mv_block->blocksize_y; VideoParameters *p_Vid = mv_block->p_Vid; Slice *currSlice = mv_block->p_Slice; DecodedPictureBuffer *p_Dpb = p_Vid->p_Dpb_layer[p_Vid->dpb_layer_id]; int max_imgpel_value = p_Vid->max_imgpel_value; short weight = mv_block->weight_luma; short offset = mv_block->offset_luma; int wp_luma_round = currSlice->wp_luma_round; short luma_log_weight_denom = currSlice->luma_log_weight_denom; imgpel *src_line, *ref_line ; imgpel data[MB_PIXELS]; // local allocation could be optimized by a global instanciation int tmp_line[ (MB_BLOCK_SIZE+5)*(MB_BLOCK_SIZE+5) ] ; src_line = mv_block->orig_pic[0]; ref_line = data ; // get block with interpolation on-the-fly p_Dpb->pf_get_block_luma( p_Vid, ref_line, tmp_line, cand->mv_x, cand->mv_y, blocksize_x, blocksize_y, ref1, 0 ); for (y=0; y<blocksize_y; y++) { for (x = 0; x < blocksize_x; x+=4) { weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); } if(mcost > imin_cost) return (dist_scale_f((distblk)mcost)); } if ( mv_block->ChromaMEEnable ) { // calculate chroma conribution to motion compensation error int blocksize_x_cr = mv_block->blocksize_cr_x; int blocksize_y_cr = mv_block->blocksize_cr_y; int k; int mcr_cost = 0; int max_imgpel_value_uv = p_Vid->max_pel_value_comp[1]; int wp_chroma_round = currSlice->wp_chroma_round; short chroma_log_weight_denom = currSlice->chroma_log_weight_denom; for (k=0; k < 2; k++) { weight = mv_block->weight_cr[k]; offset = mv_block->offset_cr[k]; mcr_cost = 0; src_line = mv_block->orig_pic[k+1]; ref_line = data ; p_Dpb->pf_get_block_chroma[OTF_ME]( p_Vid, ref_line, tmp_line, cand->mv_x, cand->mv_y, blocksize_x_cr, blocksize_y_cr, ref1, k+1 ) ; for (y=0; y<blocksize_y_cr; y++) { for (x = 0; x < blocksize_x_cr; x+=2) { weighted_pel = iClip1( max_imgpel_value_uv, ((weight * *ref_line++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); mcr_cost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value_uv, ((weight * *ref_line++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); mcr_cost += iabs( *src_line++ - weighted_pel ); } } mcost += mv_block->ChromaMEWeight * mcr_cost; if(mcost >imin_cost) return (dist_scale_f((distblk)mcost)); } }
/*! ************************************************************************ * \brief * SAD computation for weighted samples ************************************************************************ */ distblk computeSADWP(StorablePicture *ref1, MEBlock *mv_block, distblk min_mcost, MotionVector *cand ) { int mcost = 0; int imin_cost = dist_down(min_mcost); int y, x; int weighted_pel; short blocksize_x = mv_block->blocksize_x; short blocksize_y = mv_block->blocksize_y; VideoParameters *p_Vid = mv_block->p_Vid; Slice *currSlice = mv_block->p_Slice; int pad_size_x = p_Vid->padded_size_x - blocksize_x; int max_imgpel_value = p_Vid->max_imgpel_value; short weight = mv_block->weight_luma; short offset = mv_block->offset_luma; int wp_luma_round = currSlice->wp_luma_round; short luma_log_weight_denom = currSlice->luma_log_weight_denom; imgpel *src_line = mv_block->orig_pic[0]; imgpel *ref_line = UMVLine4X (ref1, cand->mv_y, cand->mv_x); for (y=0; y<blocksize_y; y++) { for (x = 0; x < blocksize_x; x+=4) { weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value, ((weight * *ref_line++ + wp_luma_round) >> luma_log_weight_denom) + offset); mcost += iabs( *src_line++ - weighted_pel ); } if(mcost > imin_cost) return (dist_scale_f((distblk)mcost)); ref_line += pad_size_x; } if ( mv_block->ChromaMEEnable ) { // calculate chroma conribution to motion compensation error int blocksize_x_cr = mv_block->blocksize_cr_x; int blocksize_y_cr = mv_block->blocksize_cr_y; int cr_pad_size_x = p_Vid->cr_padded_size_x - blocksize_x_cr; int k; int mcr_cost = 0; int max_imgpel_value_uv = p_Vid->max_pel_value_comp[1]; int wp_chroma_round = currSlice->wp_chroma_round; short chroma_log_weight_denom = currSlice->chroma_log_weight_denom; for (k=0; k < 2; k++) { weight = mv_block->weight_cr[k]; offset = mv_block->offset_cr[k]; mcr_cost = 0; src_line = mv_block->orig_pic[k+1]; ref_line = UMVLine8X_chroma ( ref1, k+1, cand->mv_y, cand->mv_x); for (y=0; y<blocksize_y_cr; y++) { for (x = 0; x < blocksize_x_cr; x+=2) { weighted_pel = iClip1( max_imgpel_value_uv, ((weight * *ref_line++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); mcr_cost += iabs( *src_line++ - weighted_pel ); weighted_pel = iClip1( max_imgpel_value_uv, ((weight * *ref_line++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); mcr_cost += iabs( *src_line++ - weighted_pel ); } ref_line += cr_pad_size_x; } mcost += mv_block->ChromaMEWeight * mcr_cost; if(mcost >imin_cost) return (dist_scale_f((distblk)mcost)); } }
/*! ************************************************************************ * \brief * SAD computation ************************************************************************ */ distblk computeSAD(StorablePicture *ref1, MEBlock *mv_block, distblk min_mcost, MotionVector *cand) { int mcost = 0; int imin_cost = dist_down(min_mcost); int y,x; short blocksize_x = mv_block->blocksize_x; short blocksize_y = mv_block->blocksize_y; VideoParameters *p_Vid = mv_block->p_Vid; int pad_size_x = p_Vid->padded_size_x - blocksize_x; #if (JM_MEM_DISTORTION) int *imgpel_abs = p_Vid->imgpel_abs; #endif imgpel *src_line, *ref_line; src_line = mv_block->orig_pic[0]; ref_line = UMVLine4X (ref1, cand->mv_y, cand->mv_x); for (y=0; y<blocksize_y; y++) { for (x = 0; x < blocksize_x; x+=4) { #if (JM_MEM_DISTORTION) mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcost += imgpel_abs[ *src_line++ - *ref_line++ ]; #else mcost += iabs( *src_line++ - *ref_line++ ); mcost += iabs( *src_line++ - *ref_line++ ); mcost += iabs( *src_line++ - *ref_line++ ); mcost += iabs( *src_line++ - *ref_line++ ); #endif } if(mcost > imin_cost) return (dist_scale_f((distblk)mcost)); ref_line += pad_size_x; } if ( mv_block->ChromaMEEnable ) { // calculate chroma conribution to motion compensation error int blocksize_x_cr = mv_block->blocksize_cr_x; int blocksize_y_cr = mv_block->blocksize_cr_y; int cr_pad_size_x = p_Vid->cr_padded_size_x - blocksize_x_cr; int k; int mcr_cost = 0; // chroma me cost for (k=0; k < 2; k++) { src_line = mv_block->orig_pic[k+1]; ref_line = UMVLine8X_chroma ( ref1, k+1, cand->mv_y, cand->mv_x); mcr_cost = 0; for (y = 0; y < blocksize_y_cr; y++) { for (x = 0; x < blocksize_x_cr; x += 2) { #if (JM_MEM_DISTORTION) mcr_cost += imgpel_abs[ *src_line++ - *ref_line++ ]; mcr_cost += imgpel_abs[ *src_line++ - *ref_line++ ]; #else mcr_cost += iabs( *src_line++ - *ref_line++ ); mcr_cost += iabs( *src_line++ - *ref_line++ ); #endif } ref_line += cr_pad_size_x; } mcost += mv_block->ChromaMEWeight * mcr_cost; if(mcost >imin_cost) return (dist_scale_f((distblk)mcost)); } } CHECKOVERFLOW(mcost); return (dist_scale((distblk)mcost)); }