458 |
/* Do a diamond search around given starting point, return SAD of best */ |
/* Do a diamond search around given starting point, return SAD of best */ |
459 |
|
|
460 |
int32_t iDirection = 0; |
int32_t iDirection = 0; |
461 |
|
int32_t iDirectionBackup; |
462 |
int32_t iSAD; |
int32_t iSAD; |
463 |
VECTOR backupMV; |
VECTOR backupMV; |
464 |
|
|
472 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); |
473 |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); |
CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); |
474 |
|
|
475 |
if (iDirection) |
if (iDirection) { |
476 |
while (!iFound) { |
while (!iFound) { |
477 |
iFound = 1; |
iFound = 1; |
478 |
backupMV = *currMV; |
backupMV = *currMV; |
479 |
|
iDirectionBackup = iDirection; |
480 |
|
|
481 |
if (iDirection != 2) |
if (iDirectionBackup != 2) |
482 |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
483 |
backupMV.y, 1); |
backupMV.y, 1); |
484 |
if (iDirection != 1) |
if (iDirectionBackup != 1) |
485 |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
486 |
backupMV.y, 2); |
backupMV.y, 2); |
487 |
if (iDirection != 4) |
if (iDirectionBackup != 4) |
488 |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, |
489 |
backupMV.y - iDiamondSize, 3); |
backupMV.y - iDiamondSize, 3); |
490 |
if (iDirection != 3) |
if (iDirectionBackup != 3) |
491 |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, |
CHECK_MV16_CANDIDATE_FOUND(backupMV.x, |
492 |
backupMV.y + iDiamondSize, 4); |
backupMV.y + iDiamondSize, 4); |
493 |
|
} |
494 |
} else { |
} else { |
495 |
currMV->x = start_x; |
currMV->x = start_x; |
496 |
currMV->y = start_y; |
currMV->y = start_y; |
1616 |
/* Do a diamond search around given starting point, return SAD of best */ |
/* Do a diamond search around given starting point, return SAD of best */ |
1617 |
|
|
1618 |
int32_t iDirection = 0; |
int32_t iDirection = 0; |
1619 |
|
int32_t iDirectionBackup; |
1620 |
int32_t iSAD; |
int32_t iSAD; |
1621 |
VECTOR backupMV; |
VECTOR backupMV; |
1622 |
|
|
1630 |
CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); |
CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3); |
1631 |
CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); |
CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4); |
1632 |
|
|
1633 |
if (iDirection) |
if (iDirection) { |
1634 |
while (!iFound) { |
while (!iFound) { |
1635 |
iFound = 1; |
iFound = 1; |
1636 |
backupMV = *currMV; // since iDirection!=0, this is well defined! |
backupMV = *currMV; // since iDirection!=0, this is well defined! |
1637 |
|
iDirectionBackup = iDirection; |
1638 |
|
|
1639 |
if (iDirection != 2) |
if (iDirectionBackup != 2) |
1640 |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, |
1641 |
backupMV.y, 1); |
backupMV.y, 1); |
1642 |
if (iDirection != 1) |
if (iDirectionBackup != 1) |
1643 |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, |
1644 |
backupMV.y, 2); |
backupMV.y, 2); |
1645 |
if (iDirection != 4) |
if (iDirectionBackup != 4) |
1646 |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, |
1647 |
backupMV.y - iDiamondSize, 3); |
backupMV.y - iDiamondSize, 3); |
1648 |
if (iDirection != 3) |
if (iDirectionBackup != 3) |
1649 |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, |
CHECK_MV8_CANDIDATE_FOUND(backupMV.x, |
1650 |
backupMV.y + iDiamondSize, 4); |
backupMV.y + iDiamondSize, 4); |
1651 |
|
} |
1652 |
} else { |
} else { |
1653 |
currMV->x = start_x; |
currMV->x = start_x; |
1654 |
currMV->y = start_y; |
currMV->y = start_y; |
2874 |
int b_sad16; /* backward (only in b-frames) search */ |
int b_sad16; /* backward (only in b-frames) search */ |
2875 |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
2876 |
int d_sad16; /* direct mode (assume linear motion) */ |
int d_sad16; /* direct mode (assume linear motion) */ |
|
int dnv_sad16; /* direct mode (assume linear motion) without correction vector */ |
|
2877 |
|
|
2878 |
int best_sad; |
int best_sad; |
2879 |
|
|
2880 |
VECTOR f_predMV, b_predMV; /* there is no direct prediction */ |
VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ |
2881 |
VECTOR pmv_dontcare; |
VECTOR pmv_dontcare; |
2882 |
|
|
2883 |
int f_count=0; |
int f_count=0; |
2884 |
int b_count=0; |
int b_count=0; |
2885 |
int i_count=0; |
int i_count=0; |
2886 |
int d_count=0; |
int d_count=0; |
|
int dnv_count=0; |
|
2887 |
int s_count=0; |
int s_count=0; |
2888 |
|
|
2889 |
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
2890 |
const int64_t TRD = (int32_t)time_pp; |
const int64_t TRD = (int32_t)time_pp; |
2891 |
|
|
2901 |
const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; |
const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; |
2902 |
const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; |
const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; |
2903 |
|
|
2904 |
VECTOR directMV; |
mb->deltamv=zeroMV; |
|
VECTOR deltaMV=zeroMV; |
|
2905 |
|
|
2906 |
/* special case, if collocated block is SKIPed: encoding is forward(0,0) */ |
/* special case, if collocated block is SKIPed: encoding is forward(0,0) */ |
2907 |
|
|
2908 |
|
#ifndef _DISABLE_SKIP |
2909 |
if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && |
if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && |
2910 |
b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { |
b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { |
2911 |
mb->mode = MODE_NOT_CODED; |
mb->mode = MODE_NOT_CODED; |
2915 |
mb->b_mvs[0].y = 0; |
mb->b_mvs[0].y = 0; |
2916 |
continue; |
continue; |
2917 |
} |
} |
2918 |
|
#endif |
2919 |
|
|
2920 |
dnv_sad16 = DIRECT_PENALTY; |
d_sad16 = DIRECT_PENALTY; |
2921 |
|
|
2922 |
if (b_mb->mode == MODE_INTER4V) |
if (b_mb->mode == MODE_INTER4V) |
2923 |
{ |
{ |
2925 |
/* same method of scaling as in decoder.c, so we copy from there */ |
/* same method of scaling as in decoder.c, so we copy from there */ |
2926 |
for (k = 0; k < 4; k++) { |
for (k = 0; k < 4; k++) { |
2927 |
|
|
2928 |
directMV = b_mb->mvs[k]; |
mb->directmv[k] = b_mb->mvs[k]; |
2929 |
|
|
2930 |
mb->mvs[k].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); |
mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); |
2931 |
mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0) |
mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) |
2932 |
? ((TRB - TRD) * directMV.x) / TRD |
? ((TRB - TRD) * mb->directmv[k].x) / TRD |
2933 |
: mb->mvs[k].x - directMV.x); |
: mb->mvs[k].x - mb->directmv[k].x); |
2934 |
mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); |
|
2935 |
mb->b_mvs[k].y = (int32_t) ((deltaMV.y == 0) |
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
2936 |
? ((TRB - TRD) * directMV.y) / TRD |
mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) |
2937 |
: mb->mvs[k].y - directMV.y); |
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
2938 |
|
: mb->mvs[k].y - mb->directmv[k].y); |
2939 |
|
|
2940 |
dnv_sad16 += |
d_sad16 += |
2941 |
sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width, |
sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width, |
2942 |
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
2943 |
2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width), |
2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width), |
2948 |
} |
} |
2949 |
else |
else |
2950 |
{ |
{ |
2951 |
directMV = b_mb->mvs[0]; |
mb->directmv[3] = mb->directmv[2] = mb->directmv[1] = |
2952 |
|
mb->directmv[0] = b_mb->mvs[0]; |
2953 |
|
|
2954 |
mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); |
mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); |
2955 |
mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0) |
mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) |
2956 |
? ((TRB - TRD) * directMV.x) / TRD |
? ((TRB - TRD) * mb->directmv[0].x) / TRD |
2957 |
: mb->mvs[0].x - directMV.x); |
: mb->mvs[0].x - mb->directmv[0].x); |
2958 |
mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); |
|
2959 |
mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0) |
mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); |
2960 |
? ((TRB - TRD) * directMV.y) / TRD |
mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) |
2961 |
: mb->mvs[0].y - directMV.y); |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
2962 |
|
: mb->mvs[0].y - mb->directmv[0].y); |
2963 |
|
|
2964 |
dnv_sad16 = DIRECT_PENALTY + |
d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
|
sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
|
2965 |
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
2966 |
i, j, 16, &mb->mvs[0], edged_width), |
i, j, 16, &mb->mvs[0], edged_width), |
2967 |
get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
2968 |
i, j, 16, &mb->b_mvs[0], edged_width), |
i, j, 16, &mb->b_mvs[0], edged_width), |
2969 |
edged_width); |
edged_width); |
2970 |
|
|
|
|
|
2971 |
} |
} |
2972 |
|
d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant); |
2973 |
|
|
2974 |
// forward search |
// forward search |
2975 |
f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
2976 |
&frame->image, i, j, |
&frame->image, i, j, |
2977 |
mb->mvs[0].x, mb->mvs[0].y, /* start point f_directMV */ |
mb->mvs[0].x, mb->mvs[0].y, /* start point f_directMV */ |
2978 |
f_predMV.x, f_predMV.y, /* center is f-prediction */ |
f_predMV.x, f_predMV.y, /* center is f-prediction */ |
2979 |
frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)), |
frame->motion_flags, |
2980 |
frame->quant, frame->fcode, pParam, |
frame->quant, frame->fcode, pParam, |
2981 |
f_mbs, f_mbs, |
f_mbs, f_mbs, |
2982 |
&mb->mvs[0], &pmv_dontcare); |
&mb->mvs[0], &pmv_dontcare); |
2987 |
&frame->image, i, j, |
&frame->image, i, j, |
2988 |
mb->b_mvs[0].x, mb->b_mvs[0].y, /* start point b_directMV */ |
mb->b_mvs[0].x, mb->b_mvs[0].y, /* start point b_directMV */ |
2989 |
b_predMV.x, b_predMV.y, /* center is b-prediction */ |
b_predMV.x, b_predMV.y, /* center is b-prediction */ |
2990 |
frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)), |
frame->motion_flags, |
2991 |
frame->quant, frame->bcode, pParam, |
frame->quant, frame->bcode, pParam, |
2992 |
b_mbs, b_mbs, |
b_mbs, b_mbs, |
2993 |
&mb->b_mvs[0], &pmv_dontcare); |
&mb->b_mvs[0], &pmv_dontcare); |
3001 |
edged_width); |
edged_width); |
3002 |
i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y, |
i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y, |
3003 |
frame->fcode, frame->quant); |
frame->fcode, frame->quant); |
3004 |
i_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y, |
i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y, |
3005 |
frame->bcode, frame->quant); |
frame->bcode, frame->quant); |
3006 |
|
|
3007 |
// TODO: direct search |
// TODO: direct search |
3008 |
// predictor + delta vector in range [-32,32] (fcode=1) |
// predictor + delta vector in range [-32,32] (fcode=1) |
3009 |
|
|
3010 |
// i_sad16 = 65535; |
i_sad16 = 65535; |
3011 |
// f_sad16 = 65535; |
f_sad16 = 65535; |
3012 |
// b_sad16 = 65535; |
b_sad16 = 65535; |
3013 |
|
// d_sad16 = 65535; |
3014 |
|
|
3015 |
if (f_sad16 < b_sad16) { |
if (f_sad16 < b_sad16) { |
3016 |
best_sad = f_sad16; |
best_sad = f_sad16; |
3025 |
mb->mode = MODE_INTERPOLATE; |
mb->mode = MODE_INTERPOLATE; |
3026 |
} |
} |
3027 |
|
|
3028 |
if (dnv_sad16 < best_sad) { |
if (d_sad16 < best_sad) { |
3029 |
|
|
3030 |
if (dnv_sad16 > DIRECT_UPPERLIMIT) |
if (b_mb->mode == MODE_INTER4V) |
3031 |
{ |
{ |
|
/* if SAD value is too large, try same vector with MODE_INTERPOLATE |
|
|
instead (interpolate has residue encoding, direct mode without MV |
|
|
doesn't) |
|
|
|
|
|
This has to be replaced later by "real" direct mode, including delta |
|
|
vector and (if needed) residue encoding |
|
3032 |
|
|
3033 |
*/ |
/* same method of scaling as in decoder.c, so we copy from there */ |
3034 |
|
for (k = 0; k < 4; k++) { |
3035 |
|
|
3036 |
directMV = b_mb->mvs[0]; |
mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); |
3037 |
|
mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) |
3038 |
|
? ((TRB - TRD) * mb->directmv[k].x) / TRD |
3039 |
|
: mb->mvs[k].x - mb->directmv[k].x); |
3040 |
|
|
3041 |
|
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
3042 |
|
mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) |
3043 |
|
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
3044 |
|
: mb->mvs[k].y - mb->directmv[k].y); |
3045 |
|
} |
3046 |
|
} |
3047 |
|
else |
3048 |
|
{ |
3049 |
|
mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); |
3050 |
|
|
3051 |
mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); |
mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) |
3052 |
mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0) |
? ((TRB - TRD) * mb->directmv[0].x) / TRD |
3053 |
? ((TRB - TRD) * directMV.x) / TRD |
: mb->mvs[0].x - mb->directmv[0].x); |
|
: mb->mvs[0].x - directMV.x); |
|
|
mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); |
|
|
mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0) |
|
|
? ((TRB - TRD) * directMV.y) / TRD |
|
|
: mb->mvs[0].y - directMV.y); |
|
3054 |
|
|
3055 |
dnv_sad16 = |
mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); |
|
sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
|
|
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
|
|
i, j, 16, &mb->mvs[0], edged_width), |
|
|
get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
|
|
i, j, 16, &mb->b_mvs[0], edged_width), |
|
|
edged_width); |
|
|
dnv_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y, |
|
|
frame->fcode, frame->quant); |
|
|
dnv_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y, |
|
|
frame->bcode, frame->quant); |
|
3056 |
|
|
3057 |
if (dnv_sad16 < best_sad) |
mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) |
3058 |
{ |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
3059 |
best_sad = dnv_sad16; |
: mb->mvs[0].y - mb->directmv[0].y); |
|
mb->mode = MODE_INTERPOLATE; |
|
3060 |
|
|
3061 |
/* fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, dnv_sad16 = %d\n", |
mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0]; |
3062 |
f_sad16,b_sad16,i_sad16,dnv_sad16); |
mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0]; |
|
*/ } |
|
|
} |
|
|
else |
|
|
{ |
|
|
best_sad = dnv_sad16; |
|
|
mb->mode = MODE_DIRECT_NONE_MV; |
|
3063 |
} |
} |
3064 |
|
|
3065 |
|
best_sad = d_sad16; |
3066 |
|
mb->mode = MODE_DIRECT; |
3067 |
|
mb->mode = MODE_INTERPOLATE; // direct mode still broken :-( |
3068 |
} |
} |
3069 |
|
|
3070 |
switch (mb->mode) |
switch (mb->mode) |
3084 |
b_predMV = mb->b_mvs[0]; |
b_predMV = mb->b_mvs[0]; |
3085 |
break; |
break; |
3086 |
case MODE_DIRECT: |
case MODE_DIRECT: |
3087 |
d_count++; break; |
d_count++; |
3088 |
case MODE_DIRECT_NONE_MV: |
break; |
|
dnv_count++; break; |
|
3089 |
default: |
default: |
3090 |
s_count++; break; |
s_count++; // ??? |
3091 |
|
break; |
3092 |
} |
} |
3093 |
|
|
3094 |
} |
} |
3095 |
} |
} |
3096 |
|
|
3097 |
#ifdef _DEBUG_BFRAME_STAT |
#ifdef _DEBUG_BFRAME_STAT |
3098 |
fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D0: %04d D: %04d S: %04d\n", |
fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D: %04d S: %04d\n", |
3099 |
f_count,b_count,i_count,dnv_count,d_count,s_count); |
f_count,b_count,i_count,d_count,s_count); |
3100 |
#endif |
#endif |
3101 |
|
|
3102 |
} |
} |