[xiph-commits] r14699 - branches/theora-thusnelda/lib/enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Thu Apr 10 19:47:37 PDT 2008
Author: xiphmont
Date: 2008-04-10 19:47:37 -0700 (Thu, 10 Apr 2008)
New Revision: 14699
Modified:
branches/theora-thusnelda/lib/enc/dct_encode.c
branches/theora-thusnelda/lib/enc/encode.c
branches/theora-thusnelda/lib/enc/mode.c
Log:
Move transform and quantization inline with the rest of the macroblock mode loop
Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c 2008-04-11 02:27:50 UTC (rev 14698)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c 2008-04-11 02:47:37 UTC (rev 14699)
@@ -432,142 +432,3 @@
}
}
-
-static int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
-
-static void BlockUpdateDifference (CP_INSTANCE * cpi,
- unsigned char *FiltPtr,
- ogg_int16_t *DctInputPtr,
- ogg_int32_t MvDivisor,
- int fi,
- ogg_uint32_t PixelsPerLine,
- int mode,
- mv_t mv) {
-
- ogg_int32_t MvShift;
- ogg_int32_t MvModMask;
- ogg_int32_t AbsRefOffset;
- ogg_int32_t AbsXOffset;
- ogg_int32_t AbsYOffset;
- ogg_int32_t MVOffset; /* Baseline motion vector offset */
- ogg_int32_t ReconPtr2Offset; /* Offset for second reconstruction in
- half pixel MC */
- unsigned char *ReconPtr1; /* DCT reconstructed image pointers */
- unsigned char *ReconPtr2; /* Pointer used in half pixel MC */
- int bi = cpi->frag_buffer_index[fi];
- unsigned char *thisrecon = &cpi->recon[bi];
-
- if ( ModeUsesMC[mode] ){
- switch(MvDivisor) {
- case 2:
- MvShift = 1;
- MvModMask = 1;
- break;
- case 4:
- MvShift = 2;
- MvModMask = 3;
- break;
- default:
- break;
- }
-
- /* Set up the baseline offset for the motion vector. */
- MVOffset = ((mv.y / MvDivisor) * PixelsPerLine) + (mv.x / MvDivisor);
-
- /* Work out the offset of the second reference position for 1/2
- pixel interpolation. For the U and V planes the MV specifies 1/4
- pixel accuracy. This is adjusted to 1/2 pixel as follows ( 0->0,
- 1/4->1/2, 1/2->1/2, 3/4->1/2 ). */
- ReconPtr2Offset = 0;
- AbsXOffset = mv.x % MvDivisor;
- AbsYOffset = mv.y % MvDivisor;
-
- if ( AbsXOffset ) {
- if ( mv.x > 0 )
- ReconPtr2Offset += 1;
- else
- ReconPtr2Offset -= 1;
- }
-
- if ( AbsYOffset ) {
- if ( mv.y > 0 )
- ReconPtr2Offset += PixelsPerLine;
- else
- ReconPtr2Offset -= PixelsPerLine;
- }
-
- if ( mode==CODE_GOLDEN_MV ) {
- ReconPtr1 = &cpi->golden[bi];
- } else {
- ReconPtr1 = &cpi->lastrecon[bi];
- }
-
- ReconPtr1 += MVOffset;
- ReconPtr2 = ReconPtr1 + ReconPtr2Offset;
-
- AbsRefOffset = abs((int)(ReconPtr1 - ReconPtr2));
-
- /* Is the MV offset exactly pixel alligned */
- if ( AbsRefOffset == 0 ){
- dsp_sub8x8(cpi->dsp, FiltPtr, ReconPtr1, DctInputPtr, PixelsPerLine);
- dsp_copy8x8 (cpi->dsp, ReconPtr1, thisrecon, PixelsPerLine);
- } else {
- /* Fractional pixel MVs. */
- /* Note that we only use two pixel values even for the diagonal */
- dsp_sub8x8avg2(cpi->dsp, FiltPtr, ReconPtr1, ReconPtr2, DctInputPtr, PixelsPerLine);
- dsp_copy8x8_half (cpi->dsp, ReconPtr1, ReconPtr2, thisrecon, PixelsPerLine);
- }
-
- } else {
- if ( ( mode==CODE_INTER_NO_MV ) ||
- ( mode==CODE_USING_GOLDEN ) ) {
- if ( mode==CODE_INTER_NO_MV ) {
- ReconPtr1 = &cpi->lastrecon[bi];
- } else {
- ReconPtr1 = &cpi->golden[bi];
- }
-
- dsp_sub8x8(cpi->dsp, FiltPtr, ReconPtr1, DctInputPtr,PixelsPerLine);
- dsp_copy8x8 (cpi->dsp, ReconPtr1, thisrecon, PixelsPerLine);
- } else if ( mode==CODE_INTRA ) {
- dsp_sub8x8_128(cpi->dsp, FiltPtr, DctInputPtr, PixelsPerLine);
- dsp_set8x8(cpi->dsp, 128, thisrecon, PixelsPerLine);
- }
- }
-}
-
-void TransformQuantizeBlock (CP_INSTANCE *cpi,
- coding_mode_t mode,
- int fi,
- mv_t mv){
-
- unsigned char *FiltPtr = &cpi->frame[cpi->frag_buffer_index[fi]];
- int qi = cpi->BaseQ; // temporary
- int inter = (mode != CODE_INTRA);
- int plane = (fi < cpi->frag_n[0] ? 0 :
- (fi-cpi->frag_n[0] < cpi->frag_n[1] ? 1 : 2));
- ogg_int32_t *q = cpi->iquant_tables[inter][plane][qi];
- ogg_int16_t DCTInput[64];
- ogg_int16_t DCTOutput[64];
- ogg_int32_t MvDivisor; /* Defines MV resolution (2 = 1/2
- pixel for Y or 4 = 1/4 for UV) */
- /* Set plane specific values */
- if (plane == 0){
- MvDivisor = 2; /* 1/2 pixel accuracy in Y */
- }else{
- MvDivisor = 4; /* UV planes at 1/2 resolution of Y */
- }
-
- /* produces the appropriate motion compensation block, applies it to
- the reconstruction buffer, and proces a difference block for
- forward DCT */
- BlockUpdateDifference(cpi, FiltPtr, DCTInput,
- MvDivisor, fi, cpi->stride[plane], mode, mv);
-
- dsp_fdct_short(cpi->dsp, DCTInput, DCTOutput);
-
- /* Quantize that transform data. */
- quantize (cpi, q, DCTOutput, cpi->frag_dct[fi].data);
- cpi->frag_dc[fi] = cpi->frag_dct[fi].data[0];
-
-}
Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c 2008-04-11 02:27:50 UTC (rev 14698)
+++ branches/theora-thusnelda/lib/enc/encode.c 2008-04-11 02:47:37 UTC (rev 14699)
@@ -153,55 +153,6 @@
}
}
-static ogg_uint32_t CodePlane ( CP_INSTANCE *cpi, int plane, int subsample){
- int B;
- unsigned char *cp = cpi->frag_coded;
- macroblock_t *mp = cpi->macro;
- macroblock_t *mp_end = cpi->macro+cpi->macro_total;
- int fi;
-
- switch(subsample){
- case 1:
- for ( ; mp<mp_end; mp++ ) {
-
- for ( B=0; B<4; B++) {
- fi = mp->Ryuv[plane][B];
- if ( cp[fi] )
- TransformQuantizeBlock( cpi, mp->mode, fi, mp->mv[B] );
- }
- }
- return 0;
- case 2:
- /* fill me in when we need to support 4:2:2 */
- return 1;
- case 4:
- for ( ; mp<mp_end; mp++ ) {
- int fi = mp->Hyuv[plane][0];
- if ( cp[fi] ) {
-
- if(mp->mode == CODE_INTER_FOURMV){
- mv_t mv;
-
- /* Calculate motion vector as the average of the Y plane ones. */
- /* Uncoded members are 0,0 and not special-cased */
- mv.x = mp->mv[0].x + mp->mv[1].x + mp->mv[2].x + mp->mv[3].x;
- mv.y = mp->mv[0].y + mp->mv[1].y + mp->mv[2].y + mp->mv[3].y;
-
- mv.x = ( mv.x >= 0 ? (mv.x + 2) / 4 : (mv.x - 2) / 4);
- mv.y = ( mv.y >= 0 ? (mv.y + 2) / 4 : (mv.y - 2) / 4);
-
- TransformQuantizeBlock( cpi, mp->mode, fi, mv );
- }else
- TransformQuantizeBlock( cpi, mp->mode, fi, mp->mv[0] );
-
- }
- }
- return 0;
- default:
- return 1;
- }
-}
-
static void ChooseTokenTables (CP_INSTANCE *cpi, int huff[4]) {
int i,plane;
int best;
@@ -399,12 +350,6 @@
dsp_save_fpu (cpi->dsp);
- /* Encode and tokenise the Y, U and V components */
- /* 4:2:0 for now */
- CodePlane(cpi, 0, 1);
- CodePlane(cpi, 1, 4);
- CodePlane(cpi, 2, 4);
-
PredictDC(cpi);
DPCMTokenize(cpi);
Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c 2008-04-11 02:27:50 UTC (rev 14698)
+++ branches/theora-thusnelda/lib/enc/mode.c 2008-04-11 02:47:37 UTC (rev 14699)
@@ -445,8 +445,6 @@
OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
}
-
-
static void MBSAD420(CP_INSTANCE *cpi, int mbi, mv_t last, mv_t last2,
int sad[8][3][4]){
unsigned char *cp = cpi->frag_coded;
@@ -496,12 +494,13 @@
ogg_int16_t *block){
int plane = fi>=cpi->frag_n[0]; /* sets plane to 'Y' or 'Chroma' */
- int qp = (plane?1:0);
+ int qp = (plane>0); /* 4:2:0 specific for now */
int bi = cpi->frag_buffer_index[fi];
unsigned char *frame_ptr = &cpi->frame[bi];
- unsigned char *recon = ((mode == CODE_USING_GOLDEN ||
+ unsigned char *lastrecon = ((mode == CODE_USING_GOLDEN ||
mode == CODE_GOLDEN_MV) ?
- cpi->golden : cpi->lastrecon);
+ cpi->golden : cpi->lastrecon)+bi;
+ unsigned char *thisrecon = cpi->recon+bi;
int stride = cpi->stride[plane];
switch(mode){
@@ -517,12 +516,14 @@
int mx2 = mvmap2[qp][mv.x+31];
int my2 = mvmap2[qp][mv.y+31];
- unsigned char *r1 = recon + bi+ my * stride + mx;
+ unsigned char *r1 = lastrecon + my * stride + mx;
if(mx2 || my2){
unsigned char *r2 = r1 + my2 * stride + mx2;
- dsp_sub8x8avg2(cpi->dsp, frame_ptr, r1, r2, block, stride);
+ dsp_copy8x8_half (cpi->dsp, r1, r2, thisrecon, stride);
+ dsp_sub8x8(cpi->dsp, frame_ptr, thisrecon, block, stride);
}else{
+ dsp_copy8x8 (cpi->dsp, r1, thisrecon, stride);
dsp_sub8x8(cpi->dsp, frame_ptr, r1, block, stride);
}
}
@@ -530,14 +531,110 @@
case CODE_USING_GOLDEN:
case CODE_INTER_NO_MV:
- dsp_sub8x8(cpi->dsp, frame_ptr, recon+bi, block, stride);
+ dsp_copy8x8 (cpi->dsp, lastrecon, thisrecon, stride);
+ dsp_sub8x8(cpi->dsp, frame_ptr, lastrecon, block, stride);
break;
case CODE_INTRA:
dsp_sub8x8_128(cpi->dsp, frame_ptr, block, stride);
+ dsp_set8x8(cpi->dsp, 128, thisrecon, stride);
break;
}
}
+static void TQB (CP_INSTANCE *cpi, int mode, int fi, ogg_int32_t *q, mv_t mv){
+ if ( cpi->frag_coded[fi] ) {
+ ogg_int16_t buffer[128];
+
+ /* motion comp */
+ mb_get_dct_input(cpi,mode,fi,mv,cpi->frag_dct[fi].data);
+
+ /* transform */
+ dsp_fdct_short(cpi->dsp, cpi->frag_dct[fi].data, buffer);
+
+ /* collect rho metrics */
+
+ /* quantize */
+ quantize (cpi, q, buffer, cpi->frag_dct[fi].data);
+ cpi->frag_dc[fi] = cpi->frag_dct[fi].data[0];
+ }
+}
+
+static void TQMB ( CP_INSTANCE *cpi, macroblock_t *mb, int qi){
+ int pf = cpi->info.pixelformat;
+ int mode = mb->mode;
+ int inter = (mode != CODE_INTRA);
+ ogg_int32_t *q = cpi->iquant_tables[inter][0][qi];
+ int i;
+
+ for(i=0;i<4;i++)
+ TQB(cpi,mode,mb->Ryuv[0][i],q,mb->mv[i]);
+
+ switch(pf){
+ case OC_PF_420:
+ if(mode == CODE_INTER_FOURMV){
+ mv_t mv;
+
+ mv.x = mb->mv[0].x + mb->mv[1].x + mb->mv[2].x + mb->mv[3].x;
+ mv.y = mb->mv[0].y + mb->mv[1].y + mb->mv[2].y + mb->mv[3].y;
+
+ mv.x = ( mv.x >= 0 ? (mv.x + 2) / 4 : (mv.x - 2) / 4);
+ mv.y = ( mv.y >= 0 ? (mv.y + 2) / 4 : (mv.y - 2) / 4);
+
+ q = cpi->iquant_tables[inter][1][qi];
+ TQB(cpi,mode,mb->Ryuv[1][0],q,mv);
+ q = cpi->iquant_tables[inter][2][qi];
+ TQB(cpi,mode,mb->Ryuv[2][0],q,mv);
+ }else{
+ q = cpi->iquant_tables[inter][1][qi];
+ TQB(cpi,mode,mb->Ryuv[1][0],q,mb->mv[0]);
+ q = cpi->iquant_tables[inter][2][qi];
+ TQB(cpi,mode,mb->Ryuv[2][0],q,mb->mv[0]);
+ }
+ break;
+
+ case OC_PF_422:
+ if(mode == CODE_INTER_FOURMV){
+ mv_t mvA;
+ mv_t mvB;
+
+ mvA.x = mb->mv[0].x + mb->mv[1].x;
+ mvA.y = mb->mv[0].y + mb->mv[1].y;
+ mvA.x = ( mvA.x >= 0 ? (mvA.x + 1) / 2 : (mvA.x - 1) / 2);
+ mvA.y = ( mvA.y >= 0 ? (mvA.y + 1) / 2 : (mvA.y - 1) / 2);
+ mvB.x = mb->mv[0].x + mb->mv[1].x;
+ mvB.y = mb->mv[0].y + mb->mv[1].y;
+ mvB.x = ( mvB.x >= 0 ? (mvB.x + 1) / 2 : (mvB.x - 1) / 2);
+ mvB.y = ( mvB.y >= 0 ? (mvB.y + 1) / 2 : (mvB.y - 1) / 2);
+
+ q = cpi->iquant_tables[inter][1][qi];
+ TQB(cpi,mode,mb->Ryuv[1][0],q,mvA);
+ TQB(cpi,mode,mb->Ryuv[1][1],q,mvB);
+
+ q = cpi->iquant_tables[inter][2][qi];
+ TQB(cpi,mode,mb->Ryuv[2][0],q,mvA);
+ TQB(cpi,mode,mb->Ryuv[2][1],q,mvB);
+
+ }else{
+ q = cpi->iquant_tables[inter][1][qi];
+ TQB(cpi,mode,mb->Ryuv[1][0],q,mb->mv[0]);
+ TQB(cpi,mode,mb->Ryuv[1][1],q,mb->mv[0]);
+ q = cpi->iquant_tables[inter][2][qi];
+ TQB(cpi,mode,mb->Ryuv[2][0],q,mb->mv[0]);
+ TQB(cpi,mode,mb->Ryuv[2][1],q,mb->mv[0]);
+ }
+ break;
+
+ case OC_PF_444:
+ q = cpi->iquant_tables[inter][1][qi];
+ for(i=0;i<4;i++)
+ TQB(cpi,mode,mb->Ryuv[1][i],q,mb->mv[i]);
+ q = cpi->iquant_tables[inter][2][qi];
+ for(i=0;i<4;i++)
+ TQB(cpi,mode,mb->Ryuv[2][i],q,mb->mv[i]);
+ break;
+ }
+}
+
int PickModes(CP_INSTANCE *cpi, int recode){
unsigned char qi = cpi->BaseQ; // temporary
superblock_t *sb = cpi->super[0];
@@ -702,12 +799,15 @@
}
}
#endif
+
+ /* Transform, quantize, collect rho metrics */
+ TQMB(cpi, mb, qi);
+
}
}
-
if(cpi->FrameType != KEY_FRAME){
-
+
if(interbits>intrabits) return 1; /* short circuit */
/* finish adding flagging overhead costs to inter bit counts */
More information about the commits
mailing list