📄 encode.c
字号:
QIndex = Q_TABLE_SIZE - 1;
while ( QIndex >= 0 ) {
if ( (QIndex == 0) ||
( cpi->pb.QThreshTable[QIndex] >= cpi->pb.ThisFrameQualityValue) )
break;
QIndex --;
}
/* Encode and tokenise the Y, U and V components */
coded_pixels = QuadCodeComponent(cpi, 0, cpi->pb.YSBRows, cpi->pb.YSBCols,
cpi->pb.info.width );
coded_pixels += QuadCodeComponent(cpi, cpi->pb.YSuperBlocks,
cpi->pb.UVSBRows,
cpi->pb.UVSBCols,
cpi->pb.info.width>>1 );
coded_pixels += QuadCodeComponent(cpi,
cpi->pb.YSuperBlocks+cpi->pb.UVSuperBlocks,
cpi->pb.UVSBRows, cpi->pb.UVSBCols,
cpi->pb.info.width>>1 );
/* for y,u,v */
for ( j = 0; j < 3 ; j++) {
/* pick which fragments based on Y, U, V */
switch(j){
case 0: /* y */
FromFragment = 0;
ToFragment = cpi->pb.YPlaneFragments;
FragsAcross = cpi->pb.HFragments;
FragsDown = cpi->pb.VFragments;
break;
case 1: /* u */
FromFragment = cpi->pb.YPlaneFragments;
ToFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments ;
FragsAcross = cpi->pb.HFragments >> 1;
FragsDown = cpi->pb.VFragments >> 1;
break;
/*case 2: v */
default:
FromFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments;
ToFragment = cpi->pb.YPlaneFragments + (2 * cpi->pb.UVPlaneFragments) ;
FragsAcross = cpi->pb.HFragments >> 1;
FragsDown = cpi->pb.VFragments >> 1;
break;
}
/* initialize our array of last used DC Components */
for(k=0;k<3;k++)Last[k]=0;
i=FromFragment;
/* do prediction on all of Y, U or V */
for ( m = 0 ; m < FragsDown ; m++) {
for ( n = 0 ; n < FragsAcross ; n++, i++) {
cpi->OriginalDC[i] = cpi->pb.QFragData[i][0];
/* only do 2 prediction if fragment coded and on non intra or
if all fragments are intra */
if( cpi->pb.display_fragments[i] ||
(GetFrameType(&cpi->pb) == KEY_FRAME) ) {
/* Type of Fragment */
WhichFrame = Mode2Frame[cpi->pb.FragCodingMethod[i]];
/* Check Borderline Cases */
WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);
fn[0]=i-1;
fn[1]=i-FragsAcross-1;
fn[2]=i-FragsAcross;
fn[3]=i-FragsAcross+1;
/* fragment valid for prediction use if coded and it comes
from same frame as the one we are predicting */
for(k=pcount=wpc=0; k<4; k++) {
int pflag;
pflag=1<<k;
if((bc_mask[WhichCase]&pflag) &&
cpi->pb.display_fragments[fn[k]] &&
(Mode2Frame[cpi->pb.FragCodingMethod[fn[k]]] == WhichFrame)){
v[pcount]=cpi->OriginalDC[fn[k]];
wpc|=pflag;
pcount++;
}
}
if(wpc==0) {
/* fall back to the last coded fragment */
cpi->pb.QFragData[i][0] -= Last[WhichFrame];
} else {
/* don't do divide if divisor is 1 or 0 */
PredictedDC = pc[wpc][0]*v[0];
for(k=1; k<pcount; k++){
PredictedDC += pc[wpc][k]*v[k];
}
/* if we need to do a shift */
if(pc[wpc][4] != 0 ) {
/* If negative add in the negative correction factor */
PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
/* Shift in lieu of a divide */
PredictedDC >>= pc[wpc][4];
}
/* check for outranging on the two predictors that can outrange */
if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){
if( abs(PredictedDC - v[2]) > 128) {
PredictedDC = v[2];
} else if( abs(PredictedDC - v[0]) > 128) {
PredictedDC = v[0];
} else if( abs(PredictedDC - v[1]) > 128) {
PredictedDC = v[1];
}
}
cpi->pb.QFragData[i][0] -= PredictedDC;
}
/* Save the last fragment coded for whatever frame we are
predicting from */
Last[WhichFrame] = cpi->OriginalDC[i];
}
}
}
}
/* Pack DC tokens and adjust the ones we couldn't predict 2d */
for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
/* Get the linear index for the current coded fragment. */
FragIndex = cpi->pb.CodedBlockList[i];
coded_pixels += DPCMTokenizeBlock ( cpi, FragIndex);
}
/* Bit pack the video data data */
PackCodedVideo(cpi);
/* End the bit packing run. */
/* EndAddBitsToBuffer(cpi); */
/* Reconstruct the reference frames */
ReconRefFrames(&cpi->pb);
UpdateFragQIndex(&cpi->pb);
/* Measure the inter reconstruction error for all the blocks that
were coded */
/* for use as part of the recovery monitoring process in subsequent frames. */
for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
cpi->LastCodedErrorScore[ cpi->pb.CodedBlockList[i] ] =
GetBlockReconErrorSlow( cpi, cpi->pb.CodedBlockList[i] );
}
/* Return total number of coded pixels */
return coded_pixels;
}
ogg_uint32_t EncodeData(CP_INSTANCE *cpi){
ogg_uint32_t coded_pixels = 0;
/* Zero the count of tokens so far this frame. */
cpi->TotTokenCount = 0;
/* Zero the mode and MV list indices. */
cpi->ModeListCount = 0;
/* Zero Decoder EOB run count */
cpi->pb.EOB_Run = 0;
dsp_static_save_fpu ();
/* Encode any fragments coded using DCT. */
coded_pixels += QuadCodeDisplayFragments (cpi);
dsp_static_restore_fpu ();
return coded_pixels;
}
ogg_uint32_t PickIntra( CP_INSTANCE *cpi,
ogg_uint32_t SBRows,
ogg_uint32_t SBCols){
ogg_int32_t FragIndex; /* Fragment number */
ogg_uint32_t MB, B; /* Macro-Block, Block indices */
ogg_uint32_t SBrow; /* Super-Block row number */
ogg_uint32_t SBcol; /* Super-Block row number */
ogg_uint32_t SB=0; /* Super-Block index, initialised to first of
this component */
ogg_uint32_t UVRow;
ogg_uint32_t UVColumn;
ogg_uint32_t UVFragOffset;
/* decide what block type and motion vectors to use on all of the frames */
for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
/* Check its four Macro-Blocks */
for ( MB=0; MB<4; MB++ ) {
/* There may be MB's lying out of frame which must be
ignored. For these MB's Top left block will have a negative
Fragment Index. */
if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
cpi->MBCodingMode = CODE_INTRA;
/* Now actually code the blocks. */
for ( B=0; B<4; B++ ) {
FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
}
/* Matching fragments in the U and V planes */
UVRow = (FragIndex / (cpi->pb.HFragments * 2));
UVColumn = (FragIndex % cpi->pb.HFragments) / 2;
UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;
cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments + UVFragOffset] =
cpi->MBCodingMode;
cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments +
cpi->pb.UVPlaneFragments + UVFragOffset] =
cpi->MBCodingMode;
}
}
/* Next Super-Block */
SB++;
}
}
return 0;
}
static void AddMotionVector(CP_INSTANCE *cpi,
MOTION_VECTOR *ThisMotionVector) {
cpi->MVList[cpi->MvListCount].x = ThisMotionVector->x;
cpi->MVList[cpi->MvListCount].y = ThisMotionVector->y;
cpi->MvListCount++;
}
static void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
ogg_int32_t FragIndex,
MOTION_VECTOR *ThisMotionVector){
/* Note the coding mode and vector for each block */
cpi->pb.FragMVect[FragIndex].x = ThisMotionVector->x;
cpi->pb.FragMVect[FragIndex].y = ThisMotionVector->y;
cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
}
static void SetMBMotionVectorsAndMode(CP_INSTANCE *cpi,
ogg_int32_t YFragIndex,
ogg_int32_t UFragIndex,
ogg_int32_t VFragIndex,
MOTION_VECTOR *ThisMotionVector){
SetFragMotionVectorAndMode(cpi, YFragIndex, ThisMotionVector);
SetFragMotionVectorAndMode(cpi, YFragIndex + 1, ThisMotionVector);
SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,
ThisMotionVector);
SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,
ThisMotionVector);
SetFragMotionVectorAndMode(cpi, UFragIndex, ThisMotionVector);
SetFragMotionVectorAndMode(cpi, VFragIndex, ThisMotionVector);
}
ogg_uint32_t PickModes(CP_INSTANCE *cpi,
ogg_uint32_t SBRows, ogg_uint32_t SBCols,
ogg_uint32_t PixelsPerLine,
ogg_uint32_t *InterError, ogg_uint32_t *IntraError) {
ogg_int32_t YFragIndex;
ogg_int32_t UFragIndex;
ogg_int32_t VFragIndex;
ogg_uint32_t MB, B; /* Macro-Block, Block indices */
ogg_uint32_t SBrow; /* Super-Block row number */
ogg_uint32_t SBcol; /* Super-Block row number */
ogg_uint32_t SB=0; /* Super-Block index, initialised to first
of this component */
ogg_uint32_t MBIntraError; /* Intra error for macro block */
ogg_uint32_t MBGFError; /* Golden frame macro block error */
ogg_uint32_t MBGF_MVError; /* Golden frame plus MV error */
ogg_uint32_t LastMBGF_MVError; /* Golden frame error with
last used GF motion
vector. */
ogg_uint32_t MBInterError; /* Inter no MV macro block error */
ogg_uint32_t MBLastInterError; /* Inter with last used MV */
ogg_uint32_t MBPriorLastInterError; /* Inter with prior last MV */
ogg_uint32_t MBInterMVError; /* Inter MV macro block error */
ogg_uint32_t MBInterMVExError; /* Inter MV (exhaustive
search) macro block error */
ogg_uint32_t MBInterFOURMVError; /* Inter MV error when using 4
motion vectors per macro
block */
ogg_uint32_t BestError; /* Best error so far. */
MOTION_VECTOR FourMVect[6]; /* storage for last used vectors (one
entry for each block in MB) */
MOTION_VECTOR LastInterMVect; /* storage for last used Inter frame
MB motion vector */
MOTION_VECTOR PriorLastInterMVect; /* storage for prior last used
Inter frame MB motion vector */
MOTION_VECTOR TmpMVect; /* Temporary MV storage */
MOTION_VECTOR LastGFMVect; /* storage for last used Golden
Frame MB motion vector */
MOTION_VECTOR InterMVect; /* storage for motion vector */
MOTION_VECTOR InterMVectEx; /* storage for motion vector result
from exhaustive search */
MOTION_VECTOR GFMVect; /* storage for motion vector */
MOTION_VECTOR ZeroVect;
ogg_uint32_t UVRow;
ogg_uint32_t UVColumn;
ogg_uint32_t UVFragOffset;
int MBCodedFlag;
unsigned char QIndex;
/* initialize error scores */
*InterError = 0;
*IntraError = 0;
/* clear down the default motion vector. */
cpi->MvListCount = 0;
FourMVect[0].x = 0;
FourMVect[0].y = 0;
FourMVect[1].x = 0;
FourMVect[1].y = 0;
FourMVect[2].x = 0;
FourMVect[2].y = 0;
FourMVect[3].x = 0;
FourMVect[3].y = 0;
FourMVect[4].x = 0;
FourMVect[4].y = 0;
FourMVect[5].x = 0;
FourMVect[5].y = 0;
LastInterMVect.x = 0;
LastInterMVect.y = 0;
PriorLastInterMVect.x = 0;
PriorLastInterMVect.y = 0;
LastGFMVect.x = 0;
LastGFMVect.y = 0;
InterMVect.x = 0;
InterMVect.y = 0;
GFMVect.x = 0;
GFMVect.y = 0;
ZeroVect.x = 0;
ZeroVect.y = 0;
QIndex = (unsigned char)cpi->pb.FrameQIndex;
/* change the quatization matrix to the one at best Q to compute the
new error score */
cpi->MinImprovementForNewMV = (MvThreshTable[QIndex] << 12);
cpi->InterTripOutThresh = (5000<<12);
cpi->MVChangeFactor = MVChangeFactorTable[QIndex]; /* 0.9 */
if ( cpi->pb.info.quick_p ) {
cpi->ExhaustiveSearchThresh = (1000<<12);
cpi->FourMVThreshold = (2500<<12);
} else {
cpi->ExhaustiveSearchThresh = (250<<12);
cpi->FourMVThreshold = (500<<12);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -