171 |
const IMAGE *const pCurrent = ¤t->image; |
const IMAGE *const pCurrent = ¤t->image; |
172 |
const IMAGE *const pRef = &reference->image; |
const IMAGE *const pRef = &reference->image; |
173 |
|
|
174 |
const VECTOR zeroMV = { 0, 0 }; |
static const VECTOR zeroMV = { 0, 0 }; |
175 |
|
|
176 |
int32_t x, y; |
int32_t x, y; |
177 |
int32_t iIntra = 0; |
int32_t iIntra = 0; |
1046 |
return iMinSAD; |
return iMinSAD; |
1047 |
} |
} |
1048 |
|
|
1049 |
|
Halfpel8_RefineFuncPtr Halfpel8_Refine; |
1050 |
|
|
1051 |
int32_t |
int32_t |
1052 |
Halfpel16_Refine(const uint8_t * const pRef, |
Halfpel16_Refine(const uint8_t * const pRef, |
1472 |
} |
} |
1473 |
|
|
1474 |
int32_t |
int32_t |
1475 |
Halfpel8_Refine(const uint8_t * const pRef, |
Halfpel8_Refine_c(const uint8_t * const pRef, |
1476 |
const uint8_t * const pRefH, |
const uint8_t * const pRefH, |
1477 |
const uint8_t * const pRefV, |
const uint8_t * const pRefV, |
1478 |
const uint8_t * const pRefHV, |
const uint8_t * const pRefHV, |
2448 |
|
|
2449 |
iMinSAD = |
iMinSAD = |
2450 |
sad16(cur, |
sad16(cur, |
2451 |
get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, |
get_iref_mv(pRef, x, y, 16, currMV, |
2452 |
iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); |
iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); |
2453 |
iMinSAD += |
iMinSAD += |
2454 |
calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y, |
calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y, |
2643 |
void |
void |
2644 |
MotionEstimationBVOP(MBParam * const pParam, |
MotionEstimationBVOP(MBParam * const pParam, |
2645 |
FRAMEINFO * const frame, |
FRAMEINFO * const frame, |
2646 |
|
const int32_t time_bp, |
2647 |
|
const int32_t time_pp, |
2648 |
// forward (past) reference |
// forward (past) reference |
2649 |
const MACROBLOCK * const f_mbs, |
const MACROBLOCK * const f_mbs, |
2650 |
const IMAGE * const f_ref, |
const IMAGE * const f_ref, |
2658 |
const IMAGE * const b_refV, |
const IMAGE * const b_refV, |
2659 |
const IMAGE * const b_refHV) |
const IMAGE * const b_refHV) |
2660 |
{ |
{ |
2661 |
const uint32_t mb_width = pParam->mb_width; |
const int mb_width = pParam->mb_width; |
2662 |
const uint32_t mb_height = pParam->mb_height; |
const int mb_height = pParam->mb_height; |
2663 |
const int32_t edged_width = pParam->edged_width; |
const int edged_width = pParam->edged_width; |
2664 |
|
|
2665 |
uint32_t i, j; |
int i, j, k; |
2666 |
|
|
2667 |
int32_t f_sad16; |
static const VECTOR zeroMV={0,0}; |
2668 |
int32_t b_sad16; |
|
2669 |
int32_t i_sad16; |
int f_sad16; /* forward (as usual) search */ |
2670 |
int32_t d_sad16; |
int b_sad16; /* backward (only in b-frames) search */ |
2671 |
int32_t best_sad; |
int i_sad16; /* interpolated (both direction, b-frames only) */ |
2672 |
|
int d_sad16; /* direct mode (assume linear motion) */ |
2673 |
|
|
2674 |
|
int best_sad; |
2675 |
|
|
2676 |
VECTOR pmv_dontcare; |
VECTOR pmv_dontcare; |
2677 |
|
|
2678 |
|
int f_count=0; |
2679 |
|
int b_count=0; |
2680 |
|
int i_count=0; |
2681 |
|
int d_count=0; |
2682 |
|
int dnv_count=0; |
2683 |
|
int s_count=0; |
2684 |
|
const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp; |
2685 |
|
const int64_t TRD = (int32_t)time_pp; |
2686 |
|
|
2687 |
|
fprintf(stderr,"TRB = %lld TRD = %lld time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp); |
2688 |
// note: i==horizontal, j==vertical |
// note: i==horizontal, j==vertical |
2689 |
for (j = 0; j < mb_height; j++) { |
for (j = 0; j < mb_height; j++) { |
2690 |
for (i = 0; i < mb_width; i++) { |
for (i = 0; i < mb_width; i++) { |
2692 |
const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; |
const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width]; |
2693 |
const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; |
const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width]; |
2694 |
|
|
2695 |
|
VECTOR directMV; |
2696 |
|
VECTOR deltaMV=zeroMV; |
2697 |
|
|
2698 |
|
/* special case, if collocated block is SKIPed: encoding is forward(0,0) */ |
2699 |
|
|
2700 |
if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && |
if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 && |
2701 |
b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { |
b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) { |
2702 |
mb->mode = MODE_NOT_CODED; |
mb->mode = MODE_NOT_CODED; |
2706 |
mb->b_mvs[0].y = 0; |
mb->b_mvs[0].y = 0; |
2707 |
continue; |
continue; |
2708 |
} |
} |
|
/* force F_SAD16 |
|
|
f_sad16 = 100; |
|
|
b_sad16 = 65535; |
|
2709 |
|
|
2710 |
mb->mode = MODE_FORWARD; |
/* same method of scaling as in decoder.c, so we copy 1:1 from there */ |
2711 |
mb->mvs[0].x = 1; |
|
2712 |
mb->mvs[0].y = 1; |
for (k = 0; k < 4; k++) { |
2713 |
mb->b_mvs[0].x = 1; |
directMV = b_mb->mvs[k]; |
|
mb->b_mvs[0].y = 1; |
|
|
continue; |
|
|
^^ force F_SAD16 */ |
|
2714 |
|
|
2715 |
|
mb->mvs[k].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x); |
2716 |
|
mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0) |
2717 |
|
? ((TRB - TRD) * directMV.x) / TRD |
2718 |
|
: mb->mvs[k].x - directMV.x); |
2719 |
|
mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y); |
2720 |
|
mb->b_mvs[k].y = (int32_t) ((deltaMV.y == 0) |
2721 |
|
? ((TRB - TRD) * directMV.y) / TRD |
2722 |
|
: mb->mvs[k].y - directMV.y); |
2723 |
|
} |
2724 |
|
|
2725 |
|
d_sad16 = |
2726 |
|
sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
2727 |
|
get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
2728 |
|
i, j, 16, &mb->mvs[0], edged_width), |
2729 |
|
get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
2730 |
|
i, j, 16, &mb->b_mvs[0], edged_width), |
2731 |
|
edged_width); |
2732 |
|
|
2733 |
// forward search |
// forward search |
2734 |
f_sad16 = |
f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
|
SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y, |
|
2735 |
&frame->image, i, j, frame->motion_flags, |
&frame->image, i, j, frame->motion_flags, |
2736 |
frame->quant, frame->fcode, pParam, |
frame->quant, frame->fcode, pParam, |
2737 |
f_mbs, f_mbs, /* todo */ |
f_mbs, f_mbs, /* todo */ |
2738 |
&mb->mvs[0], &pmv_dontcare); // ignore pmv |
&mb->mvs[0], &pmv_dontcare); // ignore pmv (why?) |
2739 |
|
|
2740 |
|
|
2741 |
// backward search |
// backward search |
2742 |
b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
2745 |
b_mbs, b_mbs, /* todo */ |
b_mbs, b_mbs, /* todo */ |
2746 |
&mb->b_mvs[0], &pmv_dontcare); // ignore pmv |
&mb->b_mvs[0], &pmv_dontcare); // ignore pmv |
2747 |
|
|
|
// interpolate search (simple, but effective) |
|
|
i_sad16 = 65535; |
|
|
|
|
|
/* |
|
|
x/y range somewhat buggy |
|
2748 |
i_sad16 = |
i_sad16 = |
2749 |
sad16bi_c(frame->image.y + i * 16 + j * 16 * edged_width, |
sad16bi(frame->image.y + i * 16 + j * 16 * edged_width, |
2750 |
get_ref(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, |
2751 |
i, j, 16, mb->mvs[0].x, mb->mvs[0].y, |
i, j, 16, &mb->mvs[0], edged_width), |
2752 |
edged_width), get_ref(b_ref->y, b_refH->y, |
get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y, |
2753 |
b_refV->y, b_refHV->y, |
i, j, 16, -mb->b_mvs[0].x, -mb->b_mvs[0].y, edged_width), |
|
i, j, 16, |
|
|
mb->b_mvs[0].x, |
|
|
mb->b_mvs[0].x, |
|
|
edged_width), |
|
2754 |
edged_width); |
edged_width); |
|
*/ |
|
2755 |
|
|
2756 |
// TODO: direct search |
// TODO: direct search |
2757 |
// predictor + range of [-32,32] |
// predictor + range of [-32,32] |
|
d_sad16 = 65535; |
|
2758 |
|
|
2759 |
|
DEBUG2("f_MV: ",mb->mvs[0].x,mb->mvs[0].y); |
2760 |
|
DEBUG2("b_MV: ",mb->b_mvs[0].x,mb->b_mvs[0].y); |
2761 |
|
|
2762 |
|
/* fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, d_sad16 = %d\n", |
2763 |
|
f_sad16,b_sad16,i_sad16,d_sad16); |
2764 |
|
*/ |
2765 |
|
|
2766 |
|
// d_sad16 -= 50; |
2767 |
|
// d_sad16 = 65535; |
2768 |
|
// i_sad16 = 65535; |
2769 |
|
// b_sad16 = 65535; |
2770 |
|
|
2771 |
if (f_sad16 < b_sad16) { |
if (f_sad16 < b_sad16) { |
2772 |
best_sad = f_sad16; |
best_sad = f_sad16; |
2783 |
|
|
2784 |
if (d_sad16 < best_sad) { |
if (d_sad16 < best_sad) { |
2785 |
best_sad = d_sad16; |
best_sad = d_sad16; |
2786 |
mb->mode = MODE_DIRECT; |
mb->mode = MODE_DIRECT_NONE_MV; |
2787 |
|
} |
2788 |
|
|
2789 |
|
switch (mb->mode) |
2790 |
|
{ |
2791 |
|
case MODE_FORWARD: |
2792 |
|
f_count++; break; |
2793 |
|
case MODE_BACKWARD: |
2794 |
|
b_count++; break; |
2795 |
|
case MODE_INTERPOLATE: |
2796 |
|
i_count++; break; |
2797 |
|
case MODE_DIRECT: |
2798 |
|
d_count++; break; |
2799 |
|
case MODE_DIRECT_NONE_MV: |
2800 |
|
dnv_count++; break; |
2801 |
|
default: |
2802 |
|
s_count++; break; |
2803 |
} |
} |
2804 |
|
|
2805 |
} |
} |
2806 |
} |
} |
2807 |
|
|
2808 |
|
#ifdef _DEBUG_BFRAME_STAT |
2809 |
|
fprintf(stderr,"B-Stat: F: %04d B: %04d I: %04d D0: %04d D: %04d S: %04d\n", |
2810 |
|
f_count,b_count,i_count,dnv_count,d_count,s_count); |
2811 |
|
#endif |
2812 |
|
|
2813 |
} |
} |