/*The function used to fill in the chroma plane motion vectors for a macro block when 4 different motion vectors are specified in the luma plane. This version is for use with chroma decimated in the X and Y directions (4:2:0). _cbmvs: The chroma block-level motion vectors to fill in. _lbmvs: The luma block-level motion vectors.*/ static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){ int dx; int dy; dx=OC_MV_X(_lbmvs[0])+OC_MV_X(_lbmvs[1]) +OC_MV_X(_lbmvs[2])+OC_MV_X(_lbmvs[3]); dy=OC_MV_Y(_lbmvs[0])+OC_MV_Y(_lbmvs[1]) +OC_MV_Y(_lbmvs[2])+OC_MV_Y(_lbmvs[3]); _cbmvs[0]=OC_MV(OC_DIV_ROUND_POW2(dx,2,2),OC_DIV_ROUND_POW2(dy,2,2)); }
static void oc_mcenc_find_candidates_a(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, oc_mv _accum,int _mbi,int _frame){ oc_mb_enc_info *embs; int accum_x; int accum_y; int a[3][2]; int ncandidates; unsigned nmbi; int i; embs=_enc->mb_info; /*Skip a position to store the median predictor in.*/ ncandidates=1; if(embs[_mbi].ncneighbors>0){ /*Fill in the first part of set A: the vectors from adjacent blocks.*/ for(i=0;i<embs[_mbi].ncneighbors;i++){ nmbi=embs[_mbi].cneighbors[i]; _mcenc->candidates[ncandidates][0]= OC_MV_X(embs[nmbi].analysis_mv[0][_frame]); _mcenc->candidates[ncandidates][1]= OC_MV_Y(embs[nmbi].analysis_mv[0][_frame]); ncandidates++; } } accum_x=OC_MV_X(_accum); accum_y=OC_MV_Y(_accum); /*Add a few additional vectors to set A: the vectors used in the previous frames and the (0,0) vector.*/ _mcenc->candidates[ncandidates][0]=accum_x; _mcenc->candidates[ncandidates][1]=accum_y; ncandidates++; _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, OC_MV_X(embs[_mbi].analysis_mv[1][_frame])+accum_x,31); _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])+accum_y,31); ncandidates++; _mcenc->candidates[ncandidates][0]=0; _mcenc->candidates[ncandidates][1]=0; ncandidates++; /*Use the first three vectors of set A to find our best predictor: their median.*/ memcpy(a,_mcenc->candidates+1,sizeof(a)); OC_SORT2I(a[0][0],a[1][0]); OC_SORT2I(a[0][1],a[1][1]); OC_SORT2I(a[1][0],a[2][0]); OC_SORT2I(a[1][1],a[2][1]); OC_SORT2I(a[0][0],a[1][0]); OC_SORT2I(a[0][1],a[1][1]); _mcenc->candidates[0][0]=a[1][0]; _mcenc->candidates[0][1]=a[1][1]; _mcenc->setb0=ncandidates; }
static void oc_mcenc_find_candidates_b(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, oc_mv _accum,int _mbi,int _frame){ oc_mb_enc_info *embs; int accum_x; int accum_y; int ncandidates; embs=_enc->mb_info; accum_x=OC_MV_X(_accum); accum_y=OC_MV_Y(_accum); /*Fill in set B: accelerated predictors for this and adjacent macro blocks.*/ ncandidates=_mcenc->setb0; /*Use only the current block. Using more did not appear to be helpful with the current selection logic due to escaping the local search too quickly.*/ _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, 2*OC_MV_X(embs[_mbi].analysis_mv[1][_frame]) -OC_MV_X(embs[_mbi].analysis_mv[2][_frame])+accum_x,31); _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, 2*OC_MV_Y(embs[_mbi].analysis_mv[1][_frame]) -OC_MV_Y(embs[_mbi].analysis_mv[2][_frame])+accum_y,31); ncandidates++; _mcenc->ncandidates=ncandidates; }
static void oc_mcenc_find_candidates(oc_enc_ctx *_enc,oc_mcenc_ctx *_mcenc, oc_mv _accum,int _mbi,int _frame){ oc_mb_enc_info *embs; int accum_x; int accum_y; int a[3][2]; int ncandidates; unsigned nmbi; int i; embs=_enc->mb_info; /*Skip a position to store the median predictor in.*/ ncandidates=1; if(embs[_mbi].ncneighbors>0){ /*Fill in the first part of set A: the vectors from adjacent blocks.*/ for(i=0;i<embs[_mbi].ncneighbors;i++){ nmbi=embs[_mbi].cneighbors[i]; _mcenc->candidates[ncandidates][0]= OC_MV_X(embs[nmbi].analysis_mv[0][_frame]); _mcenc->candidates[ncandidates][1]= OC_MV_Y(embs[nmbi].analysis_mv[0][_frame]); ncandidates++; } } accum_x=OC_MV_X(_accum); accum_y=OC_MV_Y(_accum); /*Add a few additional vectors to set A: the vectors used in the previous frames and the (0,0) vector.*/ _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31,accum_x,31); _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31,accum_y,31); ncandidates++; _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, OC_MV_X(embs[_mbi].analysis_mv[1][_frame])+accum_x,31); _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, OC_MV_Y(embs[_mbi].analysis_mv[1][_frame])+accum_y,31); ncandidates++; _mcenc->candidates[ncandidates][0]=0; _mcenc->candidates[ncandidates][1]=0; ncandidates++; /*Use the first three vectors of set A to find our best predictor: their median.*/ memcpy(a,_mcenc->candidates+1,sizeof(a)); OC_SORT2I(a[0][0],a[1][0]); OC_SORT2I(a[0][1],a[1][1]); OC_SORT2I(a[1][0],a[2][0]); OC_SORT2I(a[1][1],a[2][1]); OC_SORT2I(a[0][0],a[1][0]); OC_SORT2I(a[0][1],a[1][1]); _mcenc->candidates[0][0]=a[1][0]; _mcenc->candidates[0][1]=a[1][1]; /*Fill in set B: accelerated predictors for this and adjacent macro blocks.*/ _mcenc->setb0=ncandidates; /*The first time through the loop use the current macro block.*/ nmbi=_mbi; for(i=0;;i++){ _mcenc->candidates[ncandidates][0]=OC_CLAMPI(-31, 2*OC_MV_X(embs[_mbi].analysis_mv[1][_frame]) -OC_MV_X(embs[_mbi].analysis_mv[2][_frame])+accum_x,31); _mcenc->candidates[ncandidates][1]=OC_CLAMPI(-31, 2*OC_MV_Y(embs[_mbi].analysis_mv[1][_frame]) -OC_MV_Y(embs[_mbi].analysis_mv[2][_frame])+accum_y,31); ncandidates++; if(i>=embs[_mbi].npneighbors)break; nmbi=embs[_mbi].pneighbors[i]; } /*Truncate to full-pel positions.*/ for(i=0;i<ncandidates;i++){ _mcenc->candidates[i][0]=OC_DIV2(_mcenc->candidates[i][0]); _mcenc->candidates[i][1]=OC_DIV2(_mcenc->candidates[i][1]); } _mcenc->ncandidates=ncandidates; }