1615 |
const IMAGE * const f_refV, |
const IMAGE * const f_refV, |
1616 |
const IMAGE * const f_refHV, |
const IMAGE * const f_refHV, |
1617 |
// backward (future) reference |
// backward (future) reference |
1618 |
const MACROBLOCK * const b_mbs, |
const FRAMEINFO * const b_reference, |
1619 |
const IMAGE * const b_ref, |
const IMAGE * const b_ref, |
1620 |
const IMAGE * const b_refH, |
const IMAGE * const b_refH, |
1621 |
const IMAGE * const b_refV, |
const IMAGE * const b_refV, |
1625 |
int32_t best_sad, skip_sad; |
int32_t best_sad, skip_sad; |
1626 |
int f_count = 0, b_count = 0, i_count = 0, d_count = 0, n_count = 0; |
int f_count = 0, b_count = 0, i_count = 0, d_count = 0, n_count = 0; |
1627 |
static const VECTOR zeroMV={0,0}; |
static const VECTOR zeroMV={0,0}; |
1628 |
|
const MACROBLOCK * const b_mbs = b_reference->mbs; |
1629 |
|
|
1630 |
VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ |
VECTOR f_predMV, b_predMV; /* there is no prediction for direct mode*/ |
1631 |
|
|
1653 |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
const MACROBLOCK * const b_mb = b_mbs + i + j * pParam->mb_width; |
1654 |
|
|
1655 |
/* 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 */ |
1656 |
|
if (b_reference->coding_type != S_VOP) |
1657 |
if (b_mb->mode == MODE_NOT_CODED) { |
if (b_mb->mode == MODE_NOT_CODED) { |
1658 |
pMB->mode = MODE_NOT_CODED; |
pMB->mode = MODE_NOT_CODED; |
1659 |
continue; |
continue; |
1962 |
|
|
1963 |
int i = 255, mask; |
int i = 255, mask; |
1964 |
VECTOR pmv[3]; |
VECTOR pmv[3]; |
|
|
|
1965 |
*(Data->iMinSAD) = MV_MAX_ERROR; |
*(Data->iMinSAD) = MV_MAX_ERROR; |
1966 |
Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); |
|
1967 |
|
//median is only used as prediction. it doesn't have to be real |
1968 |
|
if (x == 1 && y == 1) Data->predMV.x = Data->predMV.y = 0; |
1969 |
|
else |
1970 |
|
if (x == 1) //left macroblock does not have any vector now |
1971 |
|
Data->predMV = (pMB - pParam->mb_width)->mvs[0]; // top instead of median |
1972 |
|
else if (y == 1) // top macroblock don't have it's vector |
1973 |
|
Data->predMV = (pMB - 1)->mvs[0]; // left instead of median |
1974 |
|
else Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); //else median |
1975 |
|
|
1976 |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16, |
1977 |
pParam->width, pParam->height, Data->iFcode, pParam->m_quarterpel); |
pParam->width, pParam->height, Data->iFcode, pParam->m_quarterpel); |
1978 |
|
|
1979 |
Data->Cur = pCur + (x + y * pParam->edged_width) * 16; |
Data->Cur = pCur + (x + y * pParam->edged_width) * 16; |
1980 |
Data->Ref = pRef + (x + y * pParam->edged_width) * 16; |
Data->Ref = pRef + (x + y * pParam->edged_width) * 16; |
1981 |
|
|
|
CheckCandidate = CheckCandidate16no4vI; |
|
|
|
|
1982 |
pmv[1].x = EVEN(pMB->mvs[0].x); |
pmv[1].x = EVEN(pMB->mvs[0].x); |
1983 |
pmv[1].y = EVEN(pMB->mvs[0].y); |
pmv[1].y = EVEN(pMB->mvs[0].y); |
1984 |
pmv[0].x = EVEN(Data->predMV.x); |
pmv[2].x = EVEN(Data->predMV.x); |
1985 |
pmv[0].y = EVEN(Data->predMV.y); |
pmv[2].y = EVEN(Data->predMV.y); |
1986 |
pmv[2].x = pmv[2].y = 0; |
pmv[0].x = pmv[0].y = 0; |
1987 |
|
|
1988 |
|
(*CheckCandidate)(0, 0, 255, &i, Data); |
1989 |
|
|
1990 |
|
//early skip for 0,0 |
1991 |
|
if (*Data->iMinSAD < MAX_SAD00_FOR_SKIP * 4) { |
1992 |
|
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0]; |
1993 |
|
pMB->mode = MODE_NOT_CODED; |
1994 |
|
return 0; |
1995 |
|
} |
1996 |
|
|
|
CheckCandidate16no4vI(pmv[0].x, pmv[0].y, 255, &i, Data); |
|
1997 |
if (!(mask = make_mask(pmv, 1))) |
if (!(mask = make_mask(pmv, 1))) |
1998 |
CheckCandidate16no4vI(pmv[1].x, pmv[1].y, mask, &i, Data); |
(*CheckCandidate)(pmv[1].x, pmv[1].y, mask, &i, Data); |
1999 |
if (!(mask = make_mask(pmv, 2))) |
if (!(mask = make_mask(pmv, 2))) |
2000 |
CheckCandidate16no4vI(0, 0, mask, &i, Data); |
(*CheckCandidate)(pmv[2].x, pmv[2].y, mask, &i, Data); |
2001 |
|
|
2002 |
|
if (*Data->iMinSAD > MAX_SAD00_FOR_SKIP * 4) // diamond only if needed |
2003 |
DiamondSearch(Data->currentMV->x, Data->currentMV->y, Data, i); |
DiamondSearch(Data->currentMV->x, Data->currentMV->y, Data, i); |
2004 |
|
|
2005 |
pMB->mvs[0] = *Data->currentMV; |
pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0]; |
2006 |
pMB->mode = MODE_INTER; |
pMB->mode = MODE_INTER; |
|
|
|
2007 |
return *(Data->iMinSAD); |
return *(Data->iMinSAD); |
2008 |
} |
} |
2009 |
|
|
2010 |
#define INTRA_THRESH 1350 |
#define INTRA_THRESH 1350 |
2011 |
#define INTER_THRESH 900 |
#define INTER_THRESH 900 |
2012 |
|
|
2013 |
|
|
2014 |
int |
int |
2015 |
MEanalysis( const IMAGE * const pRef, |
MEanalysis( const IMAGE * const pRef, |
2016 |
const IMAGE * const pCurrent, |
FRAMEINFO * const Current, |
2017 |
MBParam * const pParam, |
MBParam * const pParam, |
2018 |
MACROBLOCK * const pMBs, |
int maxIntra, //maximum number if non-I frames |
2019 |
const uint32_t iFcode) |
int intraCount, //number of non-I frames after last I frame; 0 if we force P/B frame |
2020 |
|
int bCount) // number if B frames in a row |
2021 |
{ |
{ |
2022 |
uint32_t x, y, intra = 0; |
uint32_t x, y, intra = 0; |
2023 |
int sSAD = 0; |
int sSAD = 0; |
2024 |
|
MACROBLOCK * const pMBs = Current->mbs; |
2025 |
|
const IMAGE * const pCurrent = &Current->image; |
2026 |
|
int IntraThresh = INTRA_THRESH, InterThresh = INTER_THRESH; |
2027 |
|
|
2028 |
VECTOR currentMV; |
VECTOR currentMV; |
2029 |
int32_t iMinSAD; |
int32_t iMinSAD; |
2031 |
Data.iEdgedWidth = pParam->edged_width; |
Data.iEdgedWidth = pParam->edged_width; |
2032 |
Data.currentMV = ¤tMV; |
Data.currentMV = ¤tMV; |
2033 |
Data.iMinSAD = &iMinSAD; |
Data.iMinSAD = &iMinSAD; |
2034 |
Data.iFcode = iFcode; |
Data.iFcode = Current->fcode; |
2035 |
|
CheckCandidate = CheckCandidate16no4vI; |
2036 |
|
|
2037 |
|
if (intraCount < 12) // we're right after an I frame |
2038 |
|
IntraThresh += 4 * (intraCount - 12) * (intraCount - 12); |
2039 |
|
else |
2040 |
|
if ( 5*(maxIntra - intraCount) < maxIntra) // we're close to maximum. 2 sec when max is 10 sec |
2041 |
|
IntraThresh -= (IntraThresh * (maxIntra - 5*(maxIntra - intraCount)))/maxIntra; |
2042 |
|
|
2043 |
|
|
2044 |
|
InterThresh += 300 * (1 - bCount); |
2045 |
|
if (InterThresh < 200) InterThresh = 200; |
2046 |
|
|
2047 |
if (sadInit) (*sadInit) (); |
if (sadInit) (*sadInit) (); |
2048 |
|
|
2054 |
sad = MEanalyzeMB(pRef->y, pCurrent->y, x, y, |
sad = MEanalyzeMB(pRef->y, pCurrent->y, x, y, |
2055 |
pParam, pMBs, pMB, &Data); |
pParam, pMBs, pMB, &Data); |
2056 |
|
|
2057 |
if (sad > INTRA_THRESH) { |
if (sad > IntraThresh) { |
2058 |
dev = dev16(pCurrent->y + (x + y * pParam->edged_width) * 16, |
dev = dev16(pCurrent->y + (x + y * pParam->edged_width) * 16, |
2059 |
pParam->edged_width); |
pParam->edged_width); |
2060 |
if (dev + INTRA_THRESH < sad) { intra++; pMB->mode = MODE_INTRA; } |
if (dev + IntraThresh < sad) { |
2061 |
if (intra > (pParam->mb_height-2)*(pParam->mb_width-2)/2) return 2; // I frame |
pMB->mode = MODE_INTRA; |
2062 |
|
if (++intra > (pParam->mb_height-2)*(pParam->mb_width-2)/2) return 2; // I frame |
2063 |
|
} |
2064 |
} |
} |
2065 |
sSAD += sad; |
sSAD += sad; |
2066 |
} |
} |
2067 |
} |
} |
2068 |
sSAD /= (pParam->mb_height-2)*(pParam->mb_width-2); |
sSAD /= (pParam->mb_height-2)*(pParam->mb_width-2); |
2069 |
if (sSAD > INTER_THRESH ) return 1; //P frame |
if (sSAD > InterThresh ) return 1; //P frame |
2070 |
emms(); |
emms(); |
2071 |
return 0; // B frame |
return 0; // B frame |
2072 |
|
|