754 |
pMB->mode = MODE_NOT_CODED; |
pMB->mode = MODE_NOT_CODED; |
755 |
pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; |
pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; |
756 |
pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; |
pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; |
|
|
|
757 |
pMB->qmvs[0].x = pMB->qmvs[1].x = pMB->qmvs[2].x = pMB->qmvs[3].x = 0; |
pMB->qmvs[0].x = pMB->qmvs[1].x = pMB->qmvs[2].x = pMB->qmvs[3].x = 0; |
758 |
pMB->qmvs[0].y = pMB->qmvs[1].y = pMB->qmvs[2].y = pMB->qmvs[3].y = 0; |
pMB->qmvs[0].y = pMB->qmvs[1].y = pMB->qmvs[2].y = pMB->qmvs[3].y = 0; |
759 |
|
|
822 |
pMB->quant = quant; |
pMB->quant = quant; |
823 |
} |
} |
824 |
|
|
825 |
//initial skip decision |
/* initial skip decision */ |
826 |
|
/* no early skip for GMC (global vector = skip vector is unknown!) */ |
827 |
|
|
828 |
|
if (current->coding_type == P_VOP) { /* no fast SKIP for S(GMC)-VOPs */ |
829 |
if (pMB->dquant == NO_CHANGE && sad00 < pMB->quant * INITIAL_SKIP_THRESH) |
if (pMB->dquant == NO_CHANGE && sad00 < pMB->quant * INITIAL_SKIP_THRESH) |
830 |
if (SkipDecisionP(pCurrent, pRef, x, y, pParam->edged_width, pMB->quant)) { |
if (SkipDecisionP(pCurrent, pRef, x, y, pParam->edged_width, pMB->quant)) { |
831 |
SkipMacroblockP(pMB, sad00); |
SkipMacroblockP(pMB, sad00); |
832 |
continue; |
continue; |
833 |
} |
} |
834 |
|
} |
835 |
|
|
836 |
SearchP(pRef->y, pRefH->y, pRefV->y, pRefHV->y, qimage, pCurrent, x, |
SearchP(pRef->y, pRefH->y, pRefV->y, pRefHV->y, qimage, pCurrent, x, |
837 |
y, current->motion_flags, pMB->quant, |
y, current->motion_flags, pMB->quant, |
839 |
current->global_flags & XVID_INTER4V, pMB); |
current->global_flags & XVID_INTER4V, pMB); |
840 |
|
|
841 |
/* final skip decision, a.k.a. "the vector you found, really that good?" */ |
/* final skip decision, a.k.a. "the vector you found, really that good?" */ |
842 |
if (pMB->dquant == NO_CHANGE && sad00 < pMB->quant * MAX_SAD00_FOR_SKIP |
if (current->coding_type == P_VOP) { |
843 |
|
if ( (pMB->dquant == NO_CHANGE) && (sad00 < pMB->quant * MAX_SAD00_FOR_SKIP) |
844 |
&& ((100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH) ) |
&& ((100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH) ) |
845 |
if (SkipDecisionP(pCurrent, pRef, x, y, pParam->edged_width, pMB->quant)) { |
if (SkipDecisionP(pCurrent, pRef, x, y, pParam->edged_width, pMB->quant)) { |
846 |
SkipMacroblockP(pMB, sad00); |
SkipMacroblockP(pMB, sad00); |
847 |
continue; |
continue; |
848 |
} |
} |
849 |
|
} |
850 |
|
|
851 |
/* finally, intra decision */ |
/* finally, intra decision */ |
852 |
|
|
876 |
} |
} |
877 |
} |
} |
878 |
free(qimage); |
free(qimage); |
879 |
|
|
880 |
|
if (current->coding_type == S_VOP) /* first GMC step only for S(GMC)-VOPs */ |
881 |
|
current->GMC_MV = GlobalMotionEst( pMBs, pParam, current->fcode ); |
882 |
|
else |
883 |
|
current->GMC_MV = zeroMV; |
884 |
|
|
885 |
return 0; |
return 0; |
886 |
} |
} |
887 |
|
|
1640 |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
MACROBLOCK * const pMB = frame->mbs + i + j * pParam->mb_width; |
1641 |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
1642 |
|
|
1643 |
/* special case, if collocated block is SKIPed: 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 */ |
1644 |
if (b_mb->mode == MODE_NOT_CODED) { |
if ( (b_mb->mode == MODE_NOT_CODED) ) { |
1645 |
pMB->mode = MODE_NOT_CODED; |
pMB->mode = MODE_NOT_CODED; |
1646 |
continue; |
continue; |
1647 |
} |
} |
2131 |
for (i = 1; (max > 32 << (i - 1)); i++); |
for (i = 1; (max > 32 << (i - 1)); i++); |
2132 |
return i; |
return i; |
2133 |
} |
} |
2134 |
|
|
2135 |
|
|
2136 |
|
/* Global Motion Estimation, (C) 2002 by sysKin */ |
2137 |
|
/* calculate global translation from local (halfpel) motion field */ |
2138 |
|
|
2139 |
|
static VECTOR |
2140 |
|
GlobalMotionEst(const MACROBLOCK * const pMBs, const MBParam * const pParam, const uint32_t iFcode) |
2141 |
|
{ |
2142 |
|
|
2143 |
|
int count, bestcount = 0; |
2144 |
|
int x, y; |
2145 |
|
VECTOR gmc; |
2146 |
|
int step, min_x, max_x, min_y, max_y; |
2147 |
|
uint32_t mx, my; |
2148 |
|
|
2149 |
|
min_x = min_y = -32<<iFcode; |
2150 |
|
max_x = max_y = 32<<iFcode; |
2151 |
|
|
2152 |
|
for (step = 32; step >= 2; step /= 2) { |
2153 |
|
bestcount = 0; |
2154 |
|
for (y = min_y; y <= max_y; y += step) |
2155 |
|
for (x = min_x ; x <= max_x; x += step) { |
2156 |
|
count = 0; |
2157 |
|
//for all macroblocks |
2158 |
|
for (my = 1; my < pParam->mb_height-1; my++) |
2159 |
|
for (mx = 1; mx < pParam->mb_width-1; mx++) { |
2160 |
|
const MACROBLOCK *pMB = &pMBs[mx + my * pParam->mb_width]; |
2161 |
|
VECTOR mv; |
2162 |
|
|
2163 |
|
if (pMB->mode == MODE_INTRA || pMB->mode == MODE_NOT_CODED) |
2164 |
|
continue; |
2165 |
|
|
2166 |
|
mv = pMB->mvs[0]; |
2167 |
|
if ( ABS(mv.x - x) <= step && ABS(mv.y - y) <= step ) /* GMC translation is always halfpel-res */ |
2168 |
|
count++; |
2169 |
|
} |
2170 |
|
if (count >= bestcount) { bestcount = count; gmc.x = x; gmc.y = y; } |
2171 |
|
} |
2172 |
|
min_x = gmc.x - step; |
2173 |
|
max_x = gmc.x + step; |
2174 |
|
min_y = gmc.y - step; |
2175 |
|
max_y = gmc.y + step; |
2176 |
|
|
2177 |
|
} |
2178 |
|
if (pParam->m_quarterpel) { |
2179 |
|
gmc.x *= 2; |
2180 |
|
gmc.y *= 2; /* we store the halfpel value as pseudo-qpel to make comparison easier */ |
2181 |
|
} |
2182 |
|
|
2183 |
|
if (bestcount < (pParam->mb_height-2)*(pParam->mb_width-2)/10) |
2184 |
|
gmc.x = gmc.y = 0; //no camara pan, no GMC |
2185 |
|
|
2186 |
|
return gmc; |
2187 |
|
} |