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; |
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; |
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 |
|
|
2049 |
for (y = 1; y < pParam->mb_height-1; y++) { |
for (y = 1; y < pParam->mb_height-1; y++) { |
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 |
|
|