2868 |
int b_sad16; /* backward (only in b-frames) search */ |
int b_sad16; /* backward (only in b-frames) search */ |
2869 |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
2870 |
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 */ |
|
2871 |
|
|
2872 |
int best_sad; |
int best_sad; |
2873 |
|
|
2874 |
VECTOR f_predMV, b_predMV; /* there is no direct prediction */ |
VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ |
2875 |
VECTOR pmv_dontcare; |
VECTOR pmv_dontcare; |
2876 |
|
|
2877 |
int f_count=0; |
int f_count=0; |
2878 |
int b_count=0; |
int b_count=0; |
2879 |
int i_count=0; |
int i_count=0; |
2880 |
int d_count=0; |
int d_count=0; |
|
int dnv_count=0; |
|
2881 |
int s_count=0; |
int s_count=0; |
2882 |
|
|
2883 |
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
2884 |
const int64_t TRD = (int32_t)time_pp; |
const int64_t TRD = (int32_t)time_pp; |
2885 |
|
|
2895 |
const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; |
const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; |
2896 |
const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; |
const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; |
2897 |
|
|
2898 |
VECTOR directMV; |
mb->deltamv=zeroMV; |
|
VECTOR deltaMV=zeroMV; |
|
2899 |
|
|
2900 |
/* special case, if collocated block is SKIPed: encoding is forward(0,0) */ |
/* special case, if collocated block is SKIPed: encoding is forward(0,0) */ |
2901 |
|
|
2911 |
} |
} |
2912 |
#endif |
#endif |
2913 |
|
|
2914 |
dnv_sad16 = DIRECT_PENALTY; |
d_sad16 = DIRECT_PENALTY; |
2915 |
|
|
2916 |
if (b_mb->mode == MODE_INTER4V) |
if (b_mb->mode == MODE_INTER4V) |
2917 |
{ |
{ |
2919 |
/* 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 */ |
2920 |
for (k = 0; k < 4; k++) { |
for (k = 0; k < 4; k++) { |
2921 |
|
|
2922 |
directMV = b_mb->mvs[k]; |
mb->directmv[k] = b_mb->mvs[k]; |
2923 |
|
|
2924 |
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); |
2925 |
mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0) |
mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) |
2926 |
? ((TRB - TRD) * directMV.x) / TRD |
? ((TRB - TRD) * mb->directmv[k].x) / TRD |
2927 |
: mb->mvs[k].x - directMV.x); |
: mb->mvs[k].x - mb->directmv[k].x); |
2928 |
mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); |
|
2929 |
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); |
2930 |
? ((TRB - TRD) * directMV.y) / TRD |
mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) |
2931 |
: mb->mvs[k].y - directMV.y); |
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
2932 |
|
: mb->mvs[k].y - mb->directmv[k].y); |
2933 |
|
|
2934 |
dnv_sad16 += |
d_sad16 += |
2935 |
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, |
2936 |
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, |
2937 |
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), |
2942 |
} |
} |
2943 |
else |
else |
2944 |
{ |
{ |
2945 |
directMV = b_mb->mvs[0]; |
mb->directmv[3] = mb->directmv[2] = mb->directmv[1] = |
2946 |
|
mb->directmv[0] = b_mb->mvs[0]; |
2947 |
|
|
2948 |
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); |
2949 |
mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0) |
mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) |
2950 |
? ((TRB - TRD) * directMV.x) / TRD |
? ((TRB - TRD) * mb->directmv[0].x) / TRD |
2951 |
: mb->mvs[0].x - directMV.x); |
: mb->mvs[0].x - mb->directmv[0].x); |
2952 |
mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); |
|
2953 |
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); |
2954 |
? ((TRB - TRD) * directMV.y) / TRD |
mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) |
2955 |
: mb->mvs[0].y - directMV.y); |
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
2956 |
|
: mb->mvs[0].y - mb->directmv[0].y); |
2957 |
|
|
2958 |
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, |
|
2959 |
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, |
2960 |
i, j, 16, &mb->mvs[0], edged_width), |
i, j, 16, &mb->mvs[0], edged_width), |
2961 |
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, |
2962 |
i, j, 16, &mb->b_mvs[0], edged_width), |
i, j, 16, &mb->b_mvs[0], edged_width), |
2963 |
edged_width); |
edged_width); |
2964 |
|
|
|
|
|
2965 |
} |
} |
2966 |
|
d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant); |
2967 |
|
|
2968 |
// forward search |
// forward search |
2969 |
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, |
2970 |
&frame->image, i, j, |
&frame->image, i, j, |
2971 |
mb->mvs[0].x, mb->mvs[0].y, /* start point f_directMV */ |
mb->mvs[0].x, mb->mvs[0].y, /* start point f_directMV */ |
2972 |
f_predMV.x, f_predMV.y, /* center is f-prediction */ |
f_predMV.x, f_predMV.y, /* center is f-prediction */ |
2973 |
frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)), |
frame->motion_flags, |
2974 |
frame->quant, frame->fcode, pParam, |
frame->quant, frame->fcode, pParam, |
2975 |
f_mbs, f_mbs, |
f_mbs, f_mbs, |
2976 |
&mb->mvs[0], &pmv_dontcare); |
&mb->mvs[0], &pmv_dontcare); |
2981 |
&frame->image, i, j, |
&frame->image, i, j, |
2982 |
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 */ |
2983 |
b_predMV.x, b_predMV.y, /* center is b-prediction */ |
b_predMV.x, b_predMV.y, /* center is b-prediction */ |
2984 |
frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)), |
frame->motion_flags, |
2985 |
frame->quant, frame->bcode, pParam, |
frame->quant, frame->bcode, pParam, |
2986 |
b_mbs, b_mbs, |
b_mbs, b_mbs, |
2987 |
&mb->b_mvs[0], &pmv_dontcare); |
&mb->b_mvs[0], &pmv_dontcare); |
2995 |
edged_width); |
edged_width); |
2996 |
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, |
2997 |
frame->fcode, frame->quant); |
frame->fcode, frame->quant); |
2998 |
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, |
2999 |
frame->bcode, frame->quant); |
frame->bcode, frame->quant); |
3000 |
|
|
3001 |
// TODO: direct search |
// TODO: direct search |
3002 |
// predictor + delta vector in range [-32,32] (fcode=1) |
// predictor + delta vector in range [-32,32] (fcode=1) |
3003 |
|
|
3004 |
// i_sad16 = 65535; |
i_sad16 = 65535; |
3005 |
// f_sad16 = 65535; |
f_sad16 = 65535; |
3006 |
// b_sad16 = 65535; |
b_sad16 = 65535; |
3007 |
|
// d_sad16 = 65535; |
3008 |
|
|
3009 |
if (f_sad16 < b_sad16) { |
if (f_sad16 < b_sad16) { |
3010 |
best_sad = f_sad16; |
best_sad = f_sad16; |
3019 |
mb->mode = MODE_INTERPOLATE; |
mb->mode = MODE_INTERPOLATE; |
3020 |
} |
} |
3021 |
|
|
3022 |
if (dnv_sad16 < best_sad) { |
if (d_sad16 < best_sad) { |
3023 |
|
|
3024 |
if (dnv_sad16 > DIRECT_UPPERLIMIT) |
if (b_mb->mode == MODE_INTER4V) |
3025 |
{ |
{ |
|
/* 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 |
|
|
|
|
|
*/ |
|
|
|
|
|
directMV = b_mb->mvs[0]; |
|
|
|
|
|
mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); |
|
|
mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0) |
|
|
? ((TRB - TRD) * directMV.x) / TRD |
|
|
: 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); |
|
|
|
|
|
dnv_sad16 = |
|
|
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); |
|
3026 |
|
|
3027 |
if (dnv_sad16 < best_sad) |
/* same method of scaling as in decoder.c, so we copy from there */ |
3028 |
{ |
for (k = 0; k < 4; k++) { |
|
best_sad = dnv_sad16; |
|
|
mb->mode = MODE_INTERPOLATE; |
|
3029 |
|
|
3030 |
/* fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, dnv_sad16 = %d\n", |
mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x); |
3031 |
f_sad16,b_sad16,i_sad16,dnv_sad16); |
mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0) |
3032 |
*/ } |
? ((TRB - TRD) * mb->directmv[k].x) / TRD |
3033 |
|
: mb->mvs[k].x - mb->directmv[k].x); |
3034 |
|
|
3035 |
|
mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y); |
3036 |
|
mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0) |
3037 |
|
? ((TRB - TRD) * mb->directmv[k].y) / TRD |
3038 |
|
: mb->mvs[k].y - mb->directmv[k].y); |
3039 |
|
} |
3040 |
} |
} |
3041 |
else |
else |
3042 |
{ |
{ |
3043 |
best_sad = dnv_sad16; |
mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x); |
3044 |
mb->mode = MODE_DIRECT_NONE_MV; |
|
3045 |
|
mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0) |
3046 |
|
? ((TRB - TRD) * mb->directmv[0].x) / TRD |
3047 |
|
: mb->mvs[0].x - mb->directmv[0].x); |
3048 |
|
|
3049 |
|
mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y); |
3050 |
|
|
3051 |
|
mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0) |
3052 |
|
? ((TRB - TRD) * mb->directmv[0].y) / TRD |
3053 |
|
: mb->mvs[0].y - mb->directmv[0].y); |
3054 |
|
|
3055 |
|
mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0]; |
3056 |
|
mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0]; |
3057 |
} |
} |
3058 |
|
|
3059 |
|
best_sad = d_sad16; |
3060 |
|
mb->mode = MODE_DIRECT; |
3061 |
|
mb->mode = MODE_INTERPOLATE; // direct mode still broken :-( |
3062 |
} |
} |
3063 |
|
|
3064 |
switch (mb->mode) |
switch (mb->mode) |
3078 |
b_predMV = mb->b_mvs[0]; |
b_predMV = mb->b_mvs[0]; |
3079 |
break; |
break; |
3080 |
case MODE_DIRECT: |
case MODE_DIRECT: |
3081 |
d_count++; break; |
d_count++; |
3082 |
case MODE_DIRECT_NONE_MV: |
break; |
|
dnv_count++; break; |
|
3083 |
default: |
default: |
3084 |
s_count++; break; |
s_count++; // ??? |
3085 |
|
break; |
3086 |
} |
} |
3087 |
|
|
3088 |
} |
} |
3089 |
} |
} |
3090 |
|
|
3091 |
#ifdef _DEBUG_BFRAME_STAT |
#ifdef _DEBUG_BFRAME_STAT |
3092 |
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", |
3093 |
f_count,b_count,i_count,dnv_count,d_count,s_count); |
f_count,b_count,i_count,d_count,s_count); |
3094 |
#endif |
#endif |
3095 |
|
|
3096 |
} |
} |