/*! *********************************************************************** * \brief * Calculate SSE 4x4 *********************************************************************** */ distblk distortion4x4SSE(short* diff, distblk min_dist) { int distortion = 0, k; for (k = 0; k < 16; k++) { distortion += iabs2(*diff++); } return (dist_scale((distblk) distortion)); }
/*! *********************************************************************** * \brief * Calculate SSE for 8x8 *********************************************************************** */ distblk distortion8x8SSE(short* diff, distblk min_dist) { distblk distortion = 0; int k; for (k = 0; k < 64; k++) { distortion += iabs2(*diff++); } return (dist_scale(distortion)); }
/*! *********************************************************************** * \brief * compute 16x16 SSE *********************************************************************** */ distblk compute_SSE16x16(imgpel **imgRef, imgpel **imgSrc, int xRef, int xSrc) { int i, j; imgpel *lineRef, *lineSrc; distblk distortion = 0; 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++ ); } return dist_scale(distortion); }
distblk compute_SSE_cr(imgpel **imgRef, imgpel **imgSrc, int xRef, int xSrc, int ySize, int xSize) { int i, j; imgpel *lineRef, *lineSrc; distblk distortion = 0; for (j = 0; j < ySize; j++) { lineRef = &imgRef[j][xRef]; lineSrc = &imgSrc[j][xSrc]; for (i = 0; i < xSize; i++) distortion += iabs2( *lineRef++ - *lineSrc++ ); } return dist_scale(distortion); }
/*! *********************************************************************** * \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 * SATD distortion for an 8x8 Intra block ************************************************************************************* */ distblk compute_satd8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost) { int i, j; short diff64[64]; short *diff = &diff64[0]; imgpel *cimg, *cmpr; for (j=0; j<8; j++) { cimg = &cur_img[j][pic_opix_x]; cmpr = &mpr8x8[j][0]; for (i=0; i<8; i++) { *diff++ = *cimg++ - *cmpr++; } } return (dist_scale(HadamardSAD8x8 (diff64))); }
/*! ************************************************************************************* * \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); }
miScalar worleynoise3d_val(miState *state,texture_worleynoise3d_t *param) { miScalar f1, f2, f3; miVector p1, p2, p3; // ways to get the current point: // state->tex_list[0]; // yields good results only in the x and y coordinate // state->point // usable for 3D, but problematic for getting a smooth 2D texture as x,y and z all have to be somehow incorporated in the 2D vector to use // state->tex // does not yield usable results / seems to be constant // // instead, we just take an u and v value explicitly; they would usually be provided by a 2D placement node. // note: getting current values must always be wrapped in mi_eval... calls! miVector pt; miScalar *m = mi_eval_transform(¶m->matrix); mi_point_transform(&pt,&state->point,m); point_distances3(state,param,&pt,&f1,&p1,&f2,&p2,&f3,&p3); miInteger dist_measure = *mi_eval_integer(¶m->distance_measure); miScalar scale = dist_scale(dist_measure) * (*mi_eval_scalar(¶m->scale)) * (*mi_eval_scalar(¶m->scaleX)); miBoolean jagged = *mi_eval_boolean(¶m->jagged_gap); miScalar s = 1.0; { miScalar gap_size = *mi_eval_scalar(¶m->gap_size); miVector ptX = pt; // jagged edges. useful for broken earth crusts if(jagged) { miVector seed = pt; mi_vector_mul(&seed,3 / scale); miScalar jaggingX = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2; ptX.x += jaggingX; seed.x += 1000; miScalar jaggingY = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2; ptX.y += jaggingY; seed.y += 1000; miScalar jaggingZ = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2; ptX.z += jaggingZ; } miScalar f1X, f2X, f3X; miVector p1X, p2X, p3X; point_distances3(state,param,&ptX,&f1X,&p1X,&f2X,&p2X,&f3X,&p3X); // based on code from "Advanced Renderman" // this leads to gaps of equal width, in contrast to just simple thresholding of f2 - f1. miScalar scaleFactor = (distance3(dist_measure, &p1X, &p2X) * scale) / (f1X + f2X); // FIXME: there may be some adjustment needed for distance measures that are not just dist_linear if(gap_size * scaleFactor > f2X - f1X) // on left side s = -1.0; } { f1 /= scale; f2 /= scale; f3 /= scale; } miScalar dist = 0.0; { miInteger dist_mode = *mi_eval_integer(¶m->distance_mode); switch(dist_mode) { case DIST_F1: dist = f1; break; case DIST_F2_M_F1: dist = f2 - f1; break; case DIST_F1_P_F2: dist = (2 * f1 + f2) / 3; break; case DIST_F3_M_F2_M_F1: dist = (2 * f3 - f2 - f1) / 2; break; case DIST_F1_P_F2_P_F3: dist = (0.5 * f1 + 0.33 * f2 + (1 - 0.5 - 0.33) * f3); break; default: ; } } return s * scaling_function(dist); }
/*! ************************************************************************ * \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 * Calculate SATD *********************************************************************** */ distblk distortion4x4SATD(short* diff, distblk min_dist) { distblk i64Ret = HadamardSAD4x4( diff ); return (dist_scale(i64Ret)); }
/*! ************************************************************************ * \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)); }