[xiph-commits] r14584 - branches/theora-thusnelda/lib/enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Thu Mar 13 01:20:15 PDT 2008
Author: xiphmont
Date: 2008-03-13 01:20:14 -0700 (Thu, 13 Mar 2008)
New Revision: 14584
Modified:
branches/theora-thusnelda/lib/enc/dct_encode.c
branches/theora-thusnelda/lib/enc/encode.c
branches/theora-thusnelda/lib/enc/encoder_lookup.h
branches/theora-thusnelda/lib/enc/mode.c
Log:
Committing thought-in-progress to work on at home. DOES NOT BUILD. Don't try this one, Maik :-)
Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c 2008-03-12 23:21:07 UTC (rev 14583)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c 2008-03-13 08:20:14 UTC (rev 14584)
@@ -557,10 +557,117 @@
}
#endif
+void mb_background(CP_INSTANCE *cpi,
+ coding_mode_t mode,
+ int fi,
+ mv_t mv,
+ ogg_int16_t *block){
+
+ int mv_div = (plane?4:2);
+ unsigned char *frame_ptr = &cpi->frame[cpi->frag_buffer_index[fi]];
+ int stride = cpi->stride[plane];
+
+ if ( ModeUsesMC[mode] ){
+
+ 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){
+ mv_t mv,
+ int key){
unsigned char *FiltPtr = &cpi->frame[cpi->frag_buffer_index[fi]];
int qi = cpi->BaseQ; // temporary
@@ -570,8 +677,9 @@
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) */
+ 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 */
Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c 2008-03-12 23:21:07 UTC (rev 14583)
+++ branches/theora-thusnelda/lib/enc/encode.c 2008-03-13 08:20:14 UTC (rev 14584)
@@ -203,6 +203,68 @@
}
}
+static ogg_uint32_t CodeMBPlane ( CP_INSTANCE *cpi, macroblock_t *mp, int plane, int subsample, int key){
+ int B;
+ unsigned char *cp = cpi->frag_coded;
+ int fi;
+ int *yuv = mp->yuv[plane];
+
+ switch(subsample){
+ case 1:
+ {
+ int coded=0;
+
+ for ( B=0; B<4; B++) {
+ fi = yuv[B];
+ if (cp[fi])
+ cp[fi] = TransformQuantizeBlock( cpi, mp->mode, fi, mp->mv[B],key );
+ if(cp[fi]) coded=1;
+ }
+
+ return coded;
+ }
+ case 2:
+ /* fill me in when we need to support 4:2:2 */
+ return 1;
+ case 4:
+ fi = yuv[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);
+
+ cp[fi] = TransformQuantizeBlock( cpi, mp->mode, fi, mv, key);
+ }else
+ cp[fi] = TransformQuantizeBlock( cpi, mp->mode, fi, mp->mv[0], key);
+
+ }
+ if(cp[fi]) return 1;
+ }
+ return 0;
+}
+
+static ogg_uint32_t CodeMB420 ( CP_INSTANCE *cpi, macroblock_t *mp, int key){
+ int coded = 0;
+ if(CodeMBPlane(cpi,mp,0,1,key)){
+ coded = CodeMBPlane(cpi,mp,1,4,key);
+ coded |= CodeMBPlane(cpi,mp,2,4,key);
+ }
+
+ if(!coded){
+
+
+ }
+
+}
+
static void ChooseTokenTables (CP_INSTANCE *cpi, int huff[4]) {
int i,plane;
int best;
Modified: branches/theora-thusnelda/lib/enc/encoder_lookup.h
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_lookup.h 2008-03-12 23:21:07 UTC (rev 14583)
+++ branches/theora-thusnelda/lib/enc/encoder_lookup.h 2008-03-13 08:20:14 UTC (rev 14584)
@@ -17,6 +17,28 @@
#include "codec_internal.h"
+static signed char mvmap[2][63] = {
+ { -15,-15,-14, -14,-13,-13,-12, -12,-11,-11,-10, -10, -9, -9, -8,
+ -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0,
+ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 },
+ { -7, -7, -7, -7, -6, -6, -6, -6, -5, -5, -5, -5, -4, -4, -4,
+ -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7 }
+};
+
+static signed char mvmap2[2][63] = {
+ { -1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1,
+ 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
+ { -1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1,
+ 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1,
+ 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
+ 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }
+};
+
static const ogg_uint32_t MvPattern[(MAX_MV_EXTENT * 2) + 1] = {
0x000000ff, 0x000000fd, 0x000000fb, 0x000000f9,
0x000000f7, 0x000000f5, 0x000000f3, 0x000000f1,
Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c 2008-03-12 23:21:07 UTC (rev 14583)
+++ branches/theora-thusnelda/lib/enc/mode.c 2008-03-13 08:20:14 UTC (rev 14584)
@@ -173,7 +173,7 @@
_mode: The mode that was chosen.*/
-static void oc_mode_set( CP_INSTANCE *cpi,
+static void oc_mode_count( CP_INSTANCE *cpi,
macroblock_t *mb,
int _mode){
@@ -181,7 +181,6 @@
int ri;
int si;
- mb->mode = _mode;
chooser->mode_counts[_mode]++;
/* Re-order the scheme0 mode list if necessary. */
@@ -283,28 +282,6 @@
return cost;
}
-static signed char mvmap[2][63] = {
- { -15,-15,-14, -14,-13,-13,-12, -12,-11,-11,-10, -10, -9, -9, -8,
- -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0,
- 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
- 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 },
- { -7, -7, -7, -7, -6, -6, -6, -6, -5, -5, -5, -5, -4, -4, -4,
- -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
- 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7 }
-};
-
-static signed char mvmap2[2][63] = {
- { -1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1,
- 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1, 0,-1,
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
- { -1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1,
- 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1, 0,-1,-1,-1,
- 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
- 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }
-};
-
#define AV(a) ((r[a]+(int)r2[a])>>1)
static int BInterSAD(CP_INSTANCE *cpi, int fi, int plane, int goldenp, mv_t mv, int qp){
@@ -426,6 +403,55 @@
return cost;
}
+void mb_get_dct_input(CP_INSTANCE *cpi,
+ coding_mode_t mode,
+ int fi,
+ mv_t mv,
+ ogg_int16_t *block){
+
+ int qp = (plane?1:0);
+ int bi = cpi->frag_buffer_index[fi];
+ unsigned char *frame_ptr = &cpi->frame[bi];
+ unsigned char *recon = ((mode == CODE_USING_GOLDEN ||
+ mode == CODE_GOLDEN_MV) ?
+ cpi->golden : cpi->lastrecon);
+ int stride = cpi->stride[plane];
+
+ switch(mode){
+ case CODE_INTER_PLUS_MV:
+ case CODE_INTER_LAST_MV:
+ case CODE_INTER_PRIOR_LAST:
+ case CODE_GOLDEN_MV:
+ case CODE_INTER_FOURMV:
+
+ {
+ int mx = mvmap[qp][mv.x+31];
+ int my = mvmap[qp][mv.y+31];
+ int mx2 = mvmap2[qp][mv.x+31];
+ int my2 = mvmap2[qp][mv.y+31];
+
+ unsigned char *r = recon + bi+ my * stride + mx;
+ int j;
+
+ if(mx2 || my2){
+ unsigned char *r2 = r + my2 * stride + mx2;
+ dsp_sub8x8avg2(cpi->dsp, frame_ptr, r1, r2, block, stride);
+ }else{
+ dsp_sub8x8(cpi->dsp, frame_ptr, r1, block, stride);
+ }
+ }
+ break;
+
+ case CODE_USING_GOLDEN:
+ case CODE_INTER_NO_MV:
+ dsp_sub8x8(cpi->dsp, frame_ptr, recon[bi], block, stride);
+ break;
+ case CODE_INTRA:
+ dsp_sub8x8_128(cpi->dsp, frame_ptr, block, stride);
+ break;
+ }
+}
+
int PickModes(CP_INSTANCE *cpi){
unsigned char qi = cpi->BaseQ; // temporary
superblock_t *sb = cpi->super[0];
@@ -449,145 +475,182 @@
macroblock_t *mb = &cpi->macro[mbi];
if(cpi->FrameType == KEY_FRAME){
- mb->mode = CODE_INTRA;
- continue;
- }
+ mb->mode = mode = CODE_INTRA;
+ }else{
- /**************************************************************
- Find the block choice with the lowest estimated coding cost
+ /**************************************************************
+ Find the block choice with the lowest estimated coding cost
- NOTE THAT if U or V is coded but no Y from a macro block then
- the mode will be CODE_INTER_NO_MV as this is the default
- state to which the mode data structure is initialised in
- encoder and decoder at the start of each frame. */
+ NOTE THAT if U or V is coded but no Y from a macro block then
+ the mode must be CODE_INTER_NO_MV */
- /* block coding cost is estimated from correlated SAD metrics */
+ /* block coding cost is estimated from correlated SAD metrics */
- cost[CODE_INTER_NO_MV] = MBInterCost420(cpi,qi,mbi,(mv_t){0,0},0);
-
- /* 'should this have been a keyframe in retrospect' tracking;
- includes none of the rest of the inter-style labelling and
- flagging overhead, but must count 'uncoded' frags within the
- frame */
- intrabits += MBIntraCost420(cpi,qi,mbi,1);
-
- if(mb->coded == 0){
-
- oc_mode_set(cpi,mb,CODE_INTER_NO_MV);
- mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
-
- }else{
- int mb_mv_bits_0;
- int mb_gmv_bits_0;
- int mb_4mv_bits_0;
- int mb_4mv_bits_1;
- int mode;
-
- cost[CODE_INTRA] = MBIntraCost420(cpi,qi,mbi,0);
- cost[CODE_INTER_PLUS_MV] = MBInterCost420(cpi,qi,mbi,mb->analysis_mv[0][0],0);
- cost[CODE_INTER_LAST_MV] = MBInterCost420(cpi,qi,mbi,last_mv,0);
- cost[CODE_INTER_PRIOR_LAST] = MBInterCost420(cpi,qi,mbi,prior_mv,0);
- cost[CODE_USING_GOLDEN] = MBInterCost420(cpi,qi,mbi,(mv_t){0,0},1);
- cost[CODE_GOLDEN_MV] = MBInterCost420(cpi,qi,mbi,mb->analysis_mv[0][1],1);
- cost[CODE_INTER_FOURMV] = MBInter4Cost420(cpi,qi,mbi,mb->mv,0);
+ cost[CODE_INTER_NO_MV] = MBInterCost420(cpi,qi,mbi,(mv_t){0,0},0);
- /* add estimated labelling cost for each mode */
- for(i = 0; i < 8; i++)
- cost[i] += oc_mode_cost(cpi,i) << OC_BIT_SCALE;
+ /* 'should this have been a keyframe in retrospect' tracking;
+ includes none of the rest of the inter-style labelling and
+ flagging overhead, but must count 'uncoded' frags within the
+ frame */
+ intrabits += MBIntraCost420(cpi,qi,mbi,1);
- /* Add the motion vector bits for each mode that requires them.*/
- mb_mv_bits_0 = MvBits[mb->analysis_mv[0][0].x + MAX_MV_EXTENT] +
- MvBits[mb->analysis_mv[0][0].y + MAX_MV_EXTENT];
- mb_gmv_bits_0 = MvBits[mb->analysis_mv[0][1].x+MAX_MV_EXTENT] +
- MvBits[mb->analysis_mv[0][1].y+MAX_MV_EXTENT];
- mb_4mv_bits_0 = mb_4mv_bits_1 = 0;
- if(mb->coded & 1){
- mb_4mv_bits_0 += MvBits[mb->mv[0].x + MAX_MV_EXTENT] +
- MvBits[mb->mv[0].y+MAX_MV_EXTENT];
- mb_4mv_bits_1 += 12;
+ if(mb->coded == 0){
+
+ mode = CODE_INTER_NO_MV;
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
+
+ }else{
+ int mb_mv_bits_0;
+ int mb_gmv_bits_0;
+ int mb_4mv_bits_0;
+ int mb_4mv_bits_1;
+ int mode;
+
+ cost[CODE_INTRA] = MBIntraCost420(cpi,qi,mbi,0);
+ cost[CODE_INTER_PLUS_MV] = MBInterCost420(cpi,qi,mbi,mb->analysis_mv[0][0],0);
+ cost[CODE_INTER_LAST_MV] = MBInterCost420(cpi,qi,mbi,last_mv,0);
+ cost[CODE_INTER_PRIOR_LAST] = MBInterCost420(cpi,qi,mbi,prior_mv,0);
+ cost[CODE_USING_GOLDEN] = MBInterCost420(cpi,qi,mbi,(mv_t){0,0},1);
+ cost[CODE_GOLDEN_MV] = MBInterCost420(cpi,qi,mbi,mb->analysis_mv[0][1],1);
+ cost[CODE_INTER_FOURMV] = MBInter4Cost420(cpi,qi,mbi,mb->mv,0);
+
+ /* add estimated labelling cost for each mode */
+ for(i = 0; i < 8; i++)
+ cost[i] += oc_mode_cost(cpi,i) << OC_BIT_SCALE;
+
+ /* Add the motion vector bits for each mode that requires them.*/
+ mb_mv_bits_0 = MvBits[mb->analysis_mv[0][0].x + MAX_MV_EXTENT] +
+ MvBits[mb->analysis_mv[0][0].y + MAX_MV_EXTENT];
+ mb_gmv_bits_0 = MvBits[mb->analysis_mv[0][1].x+MAX_MV_EXTENT] +
+ MvBits[mb->analysis_mv[0][1].y+MAX_MV_EXTENT];
+ mb_4mv_bits_0 = mb_4mv_bits_1 = 0;
+ if(mb->coded & 1){
+ mb_4mv_bits_0 += MvBits[mb->mv[0].x + MAX_MV_EXTENT] +
+ MvBits[mb->mv[0].y+MAX_MV_EXTENT];
+ mb_4mv_bits_1 += 12;
+ }
+ if(mb->coded & 2){
+ mb_4mv_bits_0 += MvBits[mb->mv[1].x+MAX_MV_EXTENT] +
+ MvBits[mb->mv[1].y+MAX_MV_EXTENT];
+ mb_4mv_bits_1 += 12;
+ }
+ if(mb->coded & 4){
+ mb_4mv_bits_0 += MvBits[mb->mv[2].x+MAX_MV_EXTENT] +
+ MvBits[mb->mv[2].y+MAX_MV_EXTENT];
+ mb_4mv_bits_1 += 12;
+ }
+ if(mb->coded & 8){
+ mb_4mv_bits_0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] +
+ MvBits[mb->mv[3].y+MAX_MV_EXTENT];
+ mb_4mv_bits_1 += 12;
+ }
+
+ /* We use the same opportunity cost method of estimating the
+ cost of coding the motion vectors with the two different
+ schemes as we do for estimating the cost of the mode
+ labels. However, because there are only two schemes and
+ they're both pretty simple, this can just be done inline.*/
+ cost[CODE_INTER_PLUS_MV] +=
+ ((OC_MINI(cpi->MVBits_0 + mb_mv_bits_0, cpi->MVBits_1+12)-
+ OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+ cost[CODE_GOLDEN_MV] +=
+ ((OC_MINI(cpi->MVBits_0 + mb_gmv_bits_0, cpi->MVBits_1+12)-
+ OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+ cost[CODE_INTER_FOURMV] +=
+ ((OC_MINI(cpi->MVBits_0 + mb_4mv_bits_0, cpi->MVBits_1 + mb_4mv_bits_1)-
+ OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+
+ /* train this too... because the bit cost of an MV should be
+ considered in the context of LAST_MV and PRIOR_LAST. */
+ cost[CODE_INTER_PLUS_MV] -= 384;
+
+ /* Finally, pick the mode with the cheapest estimated bit cost.*/
+ mode=0;
+ for(i=1;i<8;i++)
+ if(cost[i]<cost[mode])
+ mode=i;
+
+ /* add back such that inter/intra counting are relatively correct */
+ cost[CODE_INTER_PLUS_MV] += 384;
+
+ /* set MVs and mode */
+ switch(mode){
+ case CODE_INTER_PLUS_MV:
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][0];
+ break;
+ case CODE_INTER_LAST_MV:
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = last_mv;
+ break;
+ case CODE_INTER_PRIOR_LAST:
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = prior_mv;
+ break;
+ case CODE_INTER_FOURMV:
+ break;
+ case CODE_GOLDEN_MV:
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][1];
+ break;
+ default:
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
+ break;
+ }
+ mb->mode = mode;
}
- if(mb->coded & 2){
- mb_4mv_bits_0 += MvBits[mb->mv[1].x+MAX_MV_EXTENT] +
- MvBits[mb->mv[1].y+MAX_MV_EXTENT];
- mb_4mv_bits_1 += 12;
- }
- if(mb->coded & 4){
- mb_4mv_bits_0 += MvBits[mb->mv[2].x+MAX_MV_EXTENT] +
- MvBits[mb->mv[2].y+MAX_MV_EXTENT];
- mb_4mv_bits_1 += 12;
- }
- if(mb->coded & 8){
- mb_4mv_bits_0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] +
- MvBits[mb->mv[3].y+MAX_MV_EXTENT];
- mb_4mv_bits_1 += 12;
- }
-
- /* We use the same opportunity cost method of estimating the
- cost of coding the motion vectors with the two different
- schemes as we do for estimating the cost of the mode
- labels. However, because there are only two schemes and
- they're both pretty simple, this can just be done inline.*/
- cost[CODE_INTER_PLUS_MV] +=
- ((OC_MINI(cpi->MVBits_0 + mb_mv_bits_0, cpi->MVBits_1+12)-
- OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
- cost[CODE_GOLDEN_MV] +=
- ((OC_MINI(cpi->MVBits_0 + mb_gmv_bits_0, cpi->MVBits_1+12)-
- OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
- cost[CODE_INTER_FOURMV] +=
- ((OC_MINI(cpi->MVBits_0 + mb_4mv_bits_0, cpi->MVBits_1 + mb_4mv_bits_1)-
- OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+ }
- /* train this too... because the bit cost of an MV should be
- considered in the context of LAST_MV and PRIOR_LAST. */
- cost[CODE_INTER_PLUS_MV] -= 384;
+ if(mb->coded){
+ ogg_int16_t background[64];
+ ogg_int16_t dct_input[64];
+ ogg_int16_t dct_output[64];
+ /* Code the macroblock now, as the quantize R/D step could
+ potentially decide that we didn't really want to code the
+ block after all, and in that case we want to be able to
+ back out. */
+ /* Get DCT input */
+ mb_get_dct_input(cpi, mode, fi, mv, block);
+ /* Quantize */
+
+ /* Code */
+
+ /* Reconsider coding this MB */
+
+ /* update reconstructed frame */
+
+ /* Update MVs and bit tracking metrics */
-
- /* Finally, pick the mode with the cheapest estimated bit cost.*/
- mode=0;
- for(i=1;i<8;i++)
- if(cost[i]<cost[mode])
- mode=i;
-
- /* add back such that inter/intra counting are relatively correct */
- cost[CODE_INTER_PLUS_MV] += 384;
-
- switch(mode){
- case CODE_INTER_PLUS_MV:
- cpi->MVBits_0 += mb_mv_bits_0;
- cpi->MVBits_1 += 12;
- prior_mv = last_mv;
- last_mv = mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][0];
- break;
- case CODE_INTER_LAST_MV:
- mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = last_mv;
- break;
- case CODE_INTER_PRIOR_LAST:
- mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = prior_mv;
- prior_mv = last_mv;
- last_mv = mb->mv[0];
- break;
- case CODE_INTER_FOURMV:
- cpi->MVBits_0 += mb_4mv_bits_0;
- cpi->MVBits_1 += mb_4mv_bits_1;
- prior_mv = last_mv;
- last_mv = mb->mv[3]; /* if coded, it is still used forced to 0,0 according to spec */
- break;
- case CODE_GOLDEN_MV:
- cpi->MVBits_0 += mb_gmv_bits_0;
- cpi->MVBits_1 += 12;
- mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][1];
- break;
- default:
- mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
- break;
- }
- oc_mode_set(cpi,mb,mode);
+ switch(mode){
+ case CODE_INTER_PLUS_MV:
+ cpi->MVBits_0 += mb_mv_bits_0;
+ cpi->MVBits_1 += 12;
+ prior_mv = last_mv;
+ last_mv = mb->analysis_mv[0][0];
+ break;
+ case CODE_INTER_LAST_MV:
+ break;
+ case CODE_INTER_PRIOR_LAST:
+ prior_mv = last_mv;
+ last_mv = mb->mv[0];
+ break;
+ case CODE_INTER_FOURMV:
+ cpi->MVBits_0 += mb_4mv_bits_0;
+ cpi->MVBits_1 += mb_4mv_bits_1;
+ prior_mv = last_mv;
+ last_mv = mb->mv[3]; /* if coded, it is still used forced to 0,0 according to spec */
+ /* XXXX Spec doc is wrong, should use last-coded Y block vector! */
+ break;
+ case CODE_GOLDEN_MV:
+ cpi->MVBits_0 += mb_gmv_bits_0;
+ cpi->MVBits_1 += 12;
+ break;
+ default:
+ break;
}
+ oc_mode_count(cpi,mb,mode);
+ }
- interbits += cost[mb->mode];
-
- }
+ interbits += cost[mb->mode];
+
}
+
if(cpi->FrameType != KEY_FRAME){
More information about the commits
mailing list