📄 encode.c
字号:
cpi->pb.CodedBlockIndex = 0; /* Set the inter/intra descision control variables. */ 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_save_fpu (cpi->dsp); /* Encode any fragments coded using DCT. */ coded_pixels += QuadCodeDisplayFragments (cpi); dsp_restore_fpu (cpi->dsp); 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -