21 |
* along with this program ; if not, write to the Free Software |
* along with this program ; if not, write to the Free Software |
22 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 |
* |
* |
24 |
* $Id: estimation_bvop.c,v 1.1.2.8 2003-12-18 02:02:08 Isibaar Exp $ |
* $Id: estimation_bvop.c,v 1.1.2.10 2003-12-18 13:26:48 Isibaar Exp $ |
25 |
* |
* |
26 |
****************************************************************************/ |
****************************************************************************/ |
27 |
|
|
39 |
#include "sad.h" |
#include "sad.h" |
40 |
#include "motion_inlines.h" |
#include "motion_inlines.h" |
41 |
|
|
|
|
|
42 |
static int32_t |
static int32_t |
43 |
ChromaSAD2(const int fx, const int fy, const int bx, const int by, |
ChromaSAD2(const int fx, const int fy, const int bx, const int by, |
44 |
SearchData * const data) |
SearchData * const data) |
711 |
{ |
{ |
712 |
int i, j; |
int i, j; |
713 |
int b_range[4], f_range[4]; |
int b_range[4], f_range[4]; |
714 |
|
int threshA = (MotionFlags & XVID_ME_FAST_MODEINTERPOLATE) ? 0 : 500; |
715 |
|
int threshB = (MotionFlags & XVID_ME_FAST_MODEINTERPOLATE) ? 0 : 300; |
716 |
|
|
717 |
Data->qpel_precision = 0; |
Data->qpel_precision = 0; |
718 |
*Data->iMinSAD = 4096*256; |
*Data->iMinSAD = 4096*256; |
781 |
|
|
782 |
/* qpel refinement */ |
/* qpel refinement */ |
783 |
if (Data->qpel) { |
if (Data->qpel) { |
784 |
if (*Data->iMinSAD > *best_sad + 500) return; |
if (*Data->iMinSAD > *best_sad + threshA) return; |
785 |
Data->qpel_precision = 1; |
Data->qpel_precision = 1; |
786 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, fcode, 2, 0); |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, fcode, 2, 0); |
787 |
|
|
790 |
Data->currentQMV[1].x = 2 * Data->currentMV[1].x; |
Data->currentQMV[1].x = 2 * Data->currentMV[1].x; |
791 |
Data->currentQMV[1].y = 2 * Data->currentMV[1].y; |
Data->currentQMV[1].y = 2 * Data->currentMV[1].y; |
792 |
SubpelRefine_dir(Data, CheckCandidateInt, 1); |
SubpelRefine_dir(Data, CheckCandidateInt, 1); |
793 |
if (*Data->iMinSAD > *best_sad + 300) return; |
if (*Data->iMinSAD > *best_sad + threshB) return; |
794 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, bcode, 2, 0); |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4, pParam->width, pParam->height, bcode, 2, 0); |
795 |
SubpelRefine_dir(Data, CheckCandidateInt, 2); |
SubpelRefine_dir(Data, CheckCandidateInt, 2); |
796 |
} |
} |
841 |
uint32_t skip_sad; |
uint32_t skip_sad; |
842 |
|
|
843 |
const MACROBLOCK * const b_mbs = b_reference->mbs; |
const MACROBLOCK * const b_mbs = b_reference->mbs; |
844 |
|
MACROBLOCK *const pMBs = frame->mbs; |
845 |
|
|
846 |
VECTOR f_predMV, b_predMV; |
VECTOR f_predMV, b_predMV; |
847 |
|
|
869 |
for (i = 0; i < pParam->mb_width; i++) { |
for (i = 0; i < pParam->mb_width; i++) { |
870 |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
871 |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
872 |
|
int interpol_search; |
873 |
|
int bf_search = 0; |
874 |
|
int bf_thresh1, bf_thresh2; |
875 |
|
|
876 |
/* special case, if collocated block is SKIPed in P-VOP: encoding is forward (0,0), cpb=0 without further ado */ |
/* special case, if collocated block is SKIPed in P-VOP: encoding is forward (0,0), cpb=0 without further ado */ |
877 |
if (b_reference->coding_type != S_VOP) |
if (b_reference->coding_type != S_VOP) |
878 |
if (b_mb->mode == MODE_NOT_CODED) { |
if (b_mb->mode == MODE_NOT_CODED) { |
879 |
pMB->mode = MODE_NOT_CODED; |
pMB->mode = MODE_NOT_CODED; |
880 |
pMB->mvs[0] = pMB->b_mvs[0] = zeroMV; |
pMB->mvs[0] = pMB->b_mvs[0] = zeroMV; |
881 |
|
pMB->sad16 = 0; |
882 |
continue; |
continue; |
883 |
} |
} |
884 |
|
|
901 |
&best_sad, |
&best_sad, |
902 |
&Data); |
&Data); |
903 |
|
|
904 |
if (pMB->mode == MODE_DIRECT_NONE_MV) continue; |
if (pMB->mode == MODE_DIRECT_NONE_MV) { |
905 |
|
pMB->sad16 = best_sad; |
906 |
|
continue; |
907 |
|
} |
908 |
|
|
909 |
|
if (frame->motion_flags & XVID_ME_BFRAME_EARLYSTOP) { |
910 |
|
|
911 |
|
if(i > 0 && j > 0 && i < pParam->mb_width) { |
912 |
|
bf_thresh1 = ((&pMBs[(i-1) + j * pParam->mb_width])->sad16 + |
913 |
|
(&pMBs[i + (j-1) * pParam->mb_width])->sad16 + |
914 |
|
(&pMBs[(i+1) + (j-1) * pParam->mb_width])->sad16) / 3; |
915 |
|
|
916 |
|
if (((&pMBs[(i-1) + j * pParam->mb_width])->mode != MODE_FORWARD) && |
917 |
|
((&pMBs[(i-1) + j * pParam->mb_width])->mode != MODE_BACKWARD) && |
918 |
|
((&pMBs[(i-1) + j * pParam->mb_width])->mode != MODE_INTERPOLATE)) |
919 |
|
bf_search++; |
920 |
|
|
921 |
|
if (((&pMBs[i + (j - 1) * pParam->mb_width])->mode != MODE_FORWARD) && |
922 |
|
((&pMBs[i + (j - 1) * pParam->mb_width])->mode != MODE_BACKWARD) && |
923 |
|
((&pMBs[i + (j - 1) * pParam->mb_width])->mode != MODE_INTERPOLATE)) |
924 |
|
bf_search++; |
925 |
|
|
926 |
|
if (((&pMBs[(i + 1) + (j - 1) * pParam->mb_width])->mode != MODE_FORWARD) && |
927 |
|
((&pMBs[(i + 1) + (j - 1) * pParam->mb_width])->mode != MODE_BACKWARD) && |
928 |
|
((&pMBs[(i + 1) + (j - 1) * pParam->mb_width])->mode != MODE_INTERPOLATE)) |
929 |
|
bf_search++; |
930 |
|
} |
931 |
|
|
932 |
|
if ((best_sad < bf_thresh1) && (bf_search == 3)) |
933 |
|
continue; |
934 |
|
} |
935 |
|
|
936 |
/* forward search */ |
/* forward search */ |
937 |
SearchBF(f_ref, f_refH->y, f_refV->y, f_refHV->y, |
SearchBF(f_ref, f_refH->y, f_refV->y, f_refHV->y, |
950 |
MODE_BACKWARD, &Data); |
MODE_BACKWARD, &Data); |
951 |
|
|
952 |
/* interpolate search comes last, because it uses data from forward and backward as prediction */ |
/* interpolate search comes last, because it uses data from forward and backward as prediction */ |
953 |
|
if (frame->motion_flags & XVID_ME_FAST_MODEINTERPOLATE) |
954 |
|
interpol_search = (best_sad > Data.iQuant * 3 * MAX_SAD00_FOR_SKIP * (Data.chroma ? 3:2)); |
955 |
|
else |
956 |
|
interpol_search = 1; |
957 |
|
|
958 |
|
if (interpol_search) { |
959 |
SearchInterpolate(f_ref, f_refH->y, f_refV->y, f_refHV->y, |
SearchInterpolate(f_ref, f_refH->y, f_refV->y, f_refHV->y, |
960 |
b_ref, b_refH->y, b_refV->y, b_refHV->y, |
b_ref, b_refH->y, b_refV->y, b_refHV->y, |
961 |
i, j, |
i, j, |
965 |
&f_predMV, &b_predMV, |
&f_predMV, &b_predMV, |
966 |
pMB, &best_sad, |
pMB, &best_sad, |
967 |
&Data); |
&Data); |
968 |
|
} |
969 |
|
|
970 |
/* final skip decision */ |
/* final skip decision */ |
971 |
if ( (skip_sad < Data.iQuant * MAX_SAD00_FOR_SKIP * (Data.chroma ? 3:2) ) |
if ( (skip_sad < Data.iQuant * MAX_SAD00_FOR_SKIP * (Data.chroma ? 3:2) ) |
976 |
switch (pMB->mode) { |
switch (pMB->mode) { |
977 |
case MODE_FORWARD: |
case MODE_FORWARD: |
978 |
f_predMV = Data.qpel ? pMB->qmvs[0] : pMB->mvs[0]; |
f_predMV = Data.qpel ? pMB->qmvs[0] : pMB->mvs[0]; |
979 |
|
pMB->sad16 = best_sad; |
980 |
break; |
break; |
981 |
case MODE_BACKWARD: |
case MODE_BACKWARD: |
982 |
b_predMV = Data.qpel ? pMB->b_qmvs[0] : pMB->b_mvs[0]; |
b_predMV = Data.qpel ? pMB->b_qmvs[0] : pMB->b_mvs[0]; |
983 |
|
pMB->sad16 = best_sad; |
984 |
break; |
break; |
985 |
case MODE_INTERPOLATE: |
case MODE_INTERPOLATE: |
986 |
f_predMV = Data.qpel ? pMB->qmvs[0] : pMB->mvs[0]; |
f_predMV = Data.qpel ? pMB->qmvs[0] : pMB->mvs[0]; |
987 |
b_predMV = Data.qpel ? pMB->b_qmvs[0] : pMB->b_mvs[0]; |
b_predMV = Data.qpel ? pMB->b_qmvs[0] : pMB->b_mvs[0]; |
988 |
|
pMB->sad16 = best_sad; |
989 |
break; |
break; |
990 |
default: |
default: |
991 |
|
pMB->sad16 = best_sad; |
992 |
break; |
break; |
993 |
} |
} |
994 |
} |
} |