[xiph-commits] r15040 - in branches/theora-thusnelda: examples lib/enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Sun Jun 15 03:31:45 PDT 2008
Author: xiphmont
Date: 2008-06-15 03:31:44 -0700 (Sun, 15 Jun 2008)
New Revision: 15040
Modified:
branches/theora-thusnelda/examples/player_example.c
branches/theora-thusnelda/lib/enc/codec_internal.h
branches/theora-thusnelda/lib/enc/encode.c
branches/theora-thusnelda/lib/enc/encoder_lookup.h
branches/theora-thusnelda/lib/enc/encoder_toplevel.c
branches/theora-thusnelda/lib/enc/mcenc.c
branches/theora-thusnelda/lib/enc/mode.c
Log:
Get initial RD-based skip determination into SVN. Lambda currently
hardwired.
Modified: branches/theora-thusnelda/examples/player_example.c
===================================================================
--- branches/theora-thusnelda/examples/player_example.c 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/examples/player_example.c 2008-06-15 10:31:44 UTC (rev 15040)
@@ -591,11 +591,11 @@
theora_control(&td,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
pp_inc=0;
- {
+ /*{
int arg = 0xffff;
theora_control(&td,TH_DECCTL_SET_TELEMETRY_MBMODE,&arg,sizeof(arg));
theora_control(&td,TH_DECCTL_SET_TELEMETRY_MV,&arg,sizeof(arg));
- }
+ }*/
}else{
/* tear down the partial theora setup */
theora_info_clear(&ti);
Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h 2008-06-15 10:31:44 UTC (rev 15040)
@@ -129,6 +129,7 @@
coding_mode_t mode;
/* per-block final motion vectors */
+ /* raster order */
mv_t mv[4];
/* Motion vectors for a macro block for the current frame and the
@@ -270,6 +271,8 @@
/********************************************************************/
/* Setup */
int keyframe_granule_shift;
+ int skip_lambda;
+ int mv_lambda;
int BaseQ;
int GoldenFrameEnabled;
int InterPrediction;
@@ -325,13 +328,13 @@
extern void oc_mcenc_start(CP_INSTANCE *cpi,
mc_state *mcenc);
-extern int oc_mcenc_search(CP_INSTANCE *cpi,
- mc_state *_mcenc,
- int _mbi,
- int _goldenp,
- mv_t *_bmvs,
- int *best_err,
- int best_block_err[4]);
+extern void oc_mcenc_search(CP_INSTANCE *cpi,
+ mc_state *_mcenc,
+ int _mbi,
+ int _goldenp,
+ mv_t *_bmvs,
+ int *best_err,
+ int best_block_err[4]);
extern void oc_mcenc_refine1mv(CP_INSTANCE *cpi,
int _mbi,
Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/lib/enc/encode.c 2008-06-15 10:31:44 UTC (rev 15040)
@@ -335,8 +335,14 @@
if(mbp->mode==CODE_INTER_PLUS_MV || mbp->mode==CODE_GOLDEN_MV){
/* One MV for the macroblock */
- oggpackB_write( opb, MvPatternPtr[mbp->mv[0].x], MvBitsPtr[mbp->mv[0].x] );
- oggpackB_write( opb, MvPatternPtr[mbp->mv[0].y], MvBitsPtr[mbp->mv[0].y] );
+ for(B=0; B<4; B++ ){
+ if(mbp->coded & (1<<B)){
+ oggpackB_write( opb, MvPatternPtr[mbp->mv[B].x], MvBitsPtr[mbp->mv[B].x] );
+ oggpackB_write( opb, MvPatternPtr[mbp->mv[B].y], MvBitsPtr[mbp->mv[B].y] );
+ break;
+ }
+ }
+
}else if (mbp->mode == CODE_INTER_FOURMV){
/* MV for each codedblock */
for(B=0; B<4; B++ ){
Modified: branches/theora-thusnelda/lib/enc/encoder_lookup.h
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_lookup.h 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/lib/enc/encoder_lookup.h 2008-06-15 10:31:44 UTC (rev 15040)
@@ -158,3 +158,4 @@
2, /* CODE_GOLDEN_MV 6 => Encoded diff from included MV MB golden frame */
1 /* CODE_INTER_FOUR_MV 7 => Encoded diff from included 4 separate MV blocks */
};
+
Modified: branches/theora-thusnelda/lib/enc/encoder_toplevel.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_toplevel.c 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/lib/enc/encoder_toplevel.c 2008-06-15 10:31:44 UTC (rev 15040)
@@ -123,6 +123,10 @@
if(c->target_bitrate<0)c->target_bitrate=0;
cpi->BaseQ = c->quality;
+ /* temporary while the RD code is only partially complete */
+ cpi->skip_lambda=64;
+ cpi->mv_lambda=0;
+
/* Set encoder flags. */
/* if not AutoKeyframing cpi->ForceKeyFrameEvery = is frequency */
if(!c->keyframe_auto_p)
Modified: branches/theora-thusnelda/lib/enc/mcenc.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mcenc.c 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/lib/enc/mcenc.c 2008-06-15 10:31:44 UTC (rev 15040)
@@ -368,7 +368,7 @@
_frame: The frame to search, either OC_FRAME_PREV or OC_FRAME_GOLD.
_bmvs: Returns the individual block motion vectors. */
-int oc_mcenc_search(CP_INSTANCE *cpi,
+void oc_mcenc_search(CP_INSTANCE *cpi,
mc_state *_mcenc,
int _mbi,
int _goldenp,
@@ -385,7 +385,6 @@
mv_t best_block_vec[4];
mv_t cand;
int bi;
- int bflag=0;
macroblock_t *mb = &cpi->macro[_mbi];
/*Find some candidate motion vectors.*/
@@ -548,7 +547,6 @@
if(err<*best_err){
*best_err=err;
best_vec=cand;
- bflag=1;
}
for(bj=0;bj<4;bj++)
if(block_err[bj]<best_block_err[bj]){
@@ -570,14 +568,12 @@
mb->analysis_mv[0][_goldenp].x=best_vec.x<<1;;
mb->analysis_mv[0][_goldenp].y=best_vec.y<<1;;
- if(_bmvs && bflag){
+ if(_bmvs){
for(bi=0;bi<4;bi++){
_bmvs[bi].x=best_block_vec[bi].x<<1;
_bmvs[bi].y=best_block_vec[bi].y<<1;
}
}
-
- return bflag;
}
Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c 2008-06-14 15:43:28 UTC (rev 15039)
+++ branches/theora-thusnelda/lib/enc/mode.c 2008-06-15 10:31:44 UTC (rev 15040)
@@ -181,7 +181,6 @@
int ri;
int si;
- mb->mode = _mode;
chooser->mode_counts[_mode]++;
/* Re-order the scheme0 mode list if necessary. */
@@ -354,6 +353,28 @@
return cost + (oc_mode_cost(cpi,mode) << OC_BIT_SCALE);
}
+static int cost_inter_nomv(CP_INSTANCE *cpi, int qi, int mbi){
+ unsigned char *cp = cpi->frag_coded;
+ macroblock_t *mb = &cpi->macro[mbi];
+ int i,j;
+ int cost = 0;
+ for(i=0;i<3;i++){
+ for(j=0;j<4;j++){
+ int fi=mb->Ryuv[i][j];
+ if(cp[fi]){
+ int bi = cpi->frag_buffer_index[fi];
+ int stride = cpi->stride[i];
+ int sad = dsp_sad8x8 (cpi->dsp, cpi->frame+bi, cpi->lastrecon+bi, stride);
+
+ if(i)sad<<=2;
+ cost += BINMAP(mode_rate[qi][i][0],sad);
+
+ }
+ }
+ }
+ return cost + (oc_mode_cost(cpi,CODE_INTER_NO_MV) << OC_BIT_SCALE);
+}
+
static int cost_inter1mv(CP_INSTANCE *cpi, int qi, int mbi, int golden, int *bits0){
unsigned char *cp = cpi->frag_coded;
macroblock_t *mb = &cpi->macro[mbi];
@@ -419,28 +440,20 @@
cost += (oc_mode_cost(cpi,CODE_INTER_FOURMV) << OC_BIT_SCALE);
*bits0 = *bits1 = 0;
+
+ *bits0 += MvBits[mb->mv[0].x + MAX_MV_EXTENT] +
+ MvBits[mb->mv[0].y+MAX_MV_EXTENT];
+ *bits1 += 12;
+ *bits0 += MvBits[mb->mv[1].x+MAX_MV_EXTENT] +
+ MvBits[mb->mv[1].y+MAX_MV_EXTENT];
+ *bits1 += 12;
+ *bits0 += MvBits[mb->mv[2].x+MAX_MV_EXTENT] +
+ MvBits[mb->mv[2].y+MAX_MV_EXTENT];
+ *bits1 += 12;
+ *bits0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] +
+ MvBits[mb->mv[3].y+MAX_MV_EXTENT];
+ *bits1 += 12;
- if(mb->coded & 1){
- *bits0 += MvBits[mb->mv[0].x + MAX_MV_EXTENT] +
- MvBits[mb->mv[0].y+MAX_MV_EXTENT];
- *bits1 += 12;
- }
- if(mb->coded & 2){
- *bits0 += MvBits[mb->mv[1].x+MAX_MV_EXTENT] +
- MvBits[mb->mv[1].y+MAX_MV_EXTENT];
- *bits1 += 12;
- }
- if(mb->coded & 4){
- *bits0 += MvBits[mb->mv[2].x+MAX_MV_EXTENT] +
- MvBits[mb->mv[2].y+MAX_MV_EXTENT];
- *bits1 += 12;
- }
- if(mb->coded & 8){
- *bits0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] +
- MvBits[mb->mv[3].y+MAX_MV_EXTENT];
- *bits1 += 12;
- }
-
return cost + ((OC_MINI(cpi->MVBits_0 + *bits0, cpi->MVBits_1 + *bits1)-
OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
}
@@ -489,126 +502,192 @@
#include "quant_lookup.h"
-static void TQB (CP_INSTANCE *cpi, int mode, int fi, mv_t mv, int plane, ogg_int16_t re_q[2][3][64], long *rho_count){
- if ( cpi->frag_coded[fi] ) {
- int qi = cpi->BaseQ; /* temporary */;
- int inter = (mode != CODE_INTRA);
- ogg_int32_t *iq = cpi->iquant_tables[inter][plane][qi];
- ogg_int16_t buffer[64];
- ogg_int16_t *data = cpi->frag_dct[fi].data;
- int bi = cpi->frag_buffer_index[fi];
- int stride = cpi->stride[plane];
- int xqp = (plane && cpi->info.pixelformat != OC_PF_444);
- int yqp = (plane && cpi->info.pixelformat == OC_PF_420);
- unsigned char *frame_ptr = &cpi->frame[bi];
- unsigned char *lastrecon = ((mode == CODE_USING_GOLDEN ||
- mode == CODE_GOLDEN_MV) ?
- cpi->golden : cpi->lastrecon)+bi;
- unsigned char *thisrecon = cpi->recon+bi;
- int nonzero=63;
+#include <stdio.h>
- /* motion comp */
- 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:
+
+static int TQB (CP_INSTANCE *cpi, int mode, int fi, mv_t mv, int plane, ogg_int16_t re_q[2][3][64],
+ long *rho_count, int keyframe){
+
+ int qi = cpi->BaseQ; /* temporary */;
+ int inter = (mode != CODE_INTRA);
+ ogg_int32_t *iq = cpi->iquant_tables[inter][plane][qi];
+ ogg_int16_t buffer[64];
+ ogg_int16_t *data = cpi->frag_dct[fi].data;
+ int bi = cpi->frag_buffer_index[fi];
+ int stride = cpi->stride[plane];
+ int xqp = (plane && cpi->info.pixelformat != OC_PF_444);
+ int yqp = (plane && cpi->info.pixelformat == OC_PF_420);
+ unsigned char *frame_ptr = &cpi->frame[bi];
+ unsigned char *lastrecon = ((mode == CODE_USING_GOLDEN ||
+ mode == CODE_GOLDEN_MV) ?
+ cpi->golden : cpi->lastrecon)+bi;
+ unsigned char *thisrecon = cpi->recon+bi;
+ int nonzero=63;
+ ogg_int16_t *dequant = re_q[inter][plane];
+ int uncoded_ssd=0,coded_ssd=0,sad=0;
+
+ /* motion comp */
+ 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[xqp][mv.x+31];
+ int my = mvmap[yqp][mv.y+31];
+ int mx2 = mvmap2[xqp][mv.x+31];
+ int my2 = mvmap2[yqp][mv.y+31];
- {
- int mx = mvmap[xqp][mv.x+31];
- int my = mvmap[yqp][mv.y+31];
- int mx2 = mvmap2[xqp][mv.x+31];
- int my2 = mvmap2[yqp][mv.y+31];
-
- unsigned char *r1 = lastrecon + my * stride + mx;
-
- if(mx2 || my2){
- unsigned char *r2 = r1 + my2 * stride + mx2;
- dsp_copy8x8_half (cpi->dsp, r1, r2, thisrecon, stride);
- dsp_sub8x8(cpi->dsp, frame_ptr, thisrecon, data, stride);
- }else{
- dsp_copy8x8 (cpi->dsp, r1, thisrecon, stride);
- dsp_sub8x8(cpi->dsp, frame_ptr, r1, data, stride);
- }
+ unsigned char *r1 = lastrecon + my * stride + mx;
+
+ if(mx2 || my2){
+ unsigned char *r2 = r1 + my2 * stride + mx2;
+ dsp_copy8x8_half (cpi->dsp, r1, r2, thisrecon, stride);
+ dsp_sub8x8(cpi->dsp, frame_ptr, thisrecon, data, stride);
+ }else{
+ dsp_copy8x8 (cpi->dsp, r1, thisrecon, stride);
+ dsp_sub8x8(cpi->dsp, frame_ptr, r1, data, stride);
}
- break;
-
- case CODE_USING_GOLDEN:
- case CODE_INTER_NO_MV:
- dsp_copy8x8 (cpi->dsp, lastrecon, thisrecon, stride);
- dsp_sub8x8(cpi->dsp, frame_ptr, lastrecon, data, stride);
- break;
- case CODE_INTRA:
- dsp_sub8x8_128(cpi->dsp, frame_ptr, data, stride);
- dsp_set8x8(cpi->dsp, 128, thisrecon, stride);
- break;
}
+ break;
+
+ case CODE_USING_GOLDEN:
+ case CODE_INTER_NO_MV:
+ dsp_copy8x8 (cpi->dsp, lastrecon, thisrecon, stride);
+ dsp_sub8x8(cpi->dsp, frame_ptr, lastrecon, data, stride);
+ break;
+ case CODE_INTRA:
+ dsp_sub8x8_128(cpi->dsp, frame_ptr, data, stride);
+ dsp_set8x8(cpi->dsp, 128, thisrecon, stride);
+ break;
+ }
- /* transform */
- dsp_fdct_short(cpi->dsp, data, buffer);
+ if(!keyframe){
+ int i;
+ if(mode==CODE_INTER_NO_MV){
+ for(i=0;i<64;i++)
+ uncoded_ssd += data[i]*data[i];
+ }else{
+ dsp_sub8x8(cpi->dsp, frame_ptr, cpi->lastrecon+bi, buffer, stride);
+ for(i=0;i<64;i++)
+ uncoded_ssd += buffer[i]*buffer[i];
+ }
+
+ for(i=0;i<64;i++)
+ sad += abs(data[i]);
+
+ if(mode==CODE_INTRA){
+ sad >>=6;
+ }else{
+ if(plane)sad<<=2;
+ }
+ }
+
+ /* transform */
+ dsp_fdct_short(cpi->dsp, data, buffer);
+
+ /* collect rho metrics, quantize */
+ {
+ int i;
+ quant_tables *qq = &(cpi->quant_tables[inter][plane]);
- /* collect rho metrics, quantize */
- {
- /* modified rho-domain (track zero-runs as well) */
- /* ZXZ; splits one zero run into two zero runs and a nonzero; +2
- ZXN; adds one nonzero token; +1
- NXZ; adds one nonzero token; +1
- NXN; replaces a zero run with a nonzero; +0 */
- int i;
- quant_tables *qq = &(cpi->quant_tables[inter][plane]);
+ for(i=0;i<64;i++){
+ int ii = dezigzag_index[i];
+ int pos;
+ int val = abs(buffer[ii])<<1;
+ ogg_int16_t *qqq = (*qq)[i];
+ for(pos=64;pos>0;pos--)
+ if(val < qqq[pos-1])break;
+
+ /* rho-domain distribution */
+ rho_count[pos]++;
- for(i=0;i<64;i++){
- int ii = dezigzag_index[i];
- int pos;
- int val = abs(buffer[ii])<<1;
- ogg_int16_t *qqq = (*qq)[i];
- for(pos=64;pos>0;pos--)
- if(val < qqq[pos-1])break;
-
- /* rho-domain distribution */
- rho_count[pos]++;
-
- if(qi<pos){
- data[i] = 0;
- }else{
- int val = (((iq[ii]>>15)*buffer[ii]) + (1<<15) + (((iq[ii]&0x7fff)*buffer[ii])>>15)) >>16;
- data[i] = (val>511?511:(val<-511?-511:val));
- }
+ if(qi<pos){
+ data[i] = 0;
+ }else{
+ int val = (((iq[ii]>>15)*buffer[ii]) + (1<<15) + (((iq[ii]&0x7fff)*buffer[ii])>>15)) >>16;
+ data[i] = (val>511?511:(val<-511?-511:val));
}
}
+ }
+
+ cpi->frag_dc[fi] = data[0];
+
+ /* reconstruct */
+ while(!data[nonzero] && --nonzero);
+ switch(nonzero){
+ case 0:
+ IDct1( data, dequant, buffer );
+ break;
+ case 1: case 2:
+ dsp_IDct3(cpi->dsp, data, dequant, buffer );
+ break;
+ case 3:case 4:case 5:case 6:case 7:case 8: case 9:
+ dsp_IDct10(cpi->dsp, data, dequant, buffer );
+ break;
+ default:
+ dsp_IDctSlow(cpi->dsp, data, dequant, buffer );
+ }
+
+ dsp_recon8x8 (cpi->dsp, thisrecon, buffer, stride);
- cpi->frag_dc[fi] = data[0];
+ if(!keyframe){
+ int i;
+ int cost = BINMAP(mode_rate[qi][plane][mode==CODE_INTRA],sad);
+ if(cost<0)cost=0; /* some of the trained fits can return a negative cost for zero entropy */
- /* reconstruct */
- while(!data[nonzero] && --nonzero);
- switch(nonzero){
- case 0:
- IDct1( data, re_q[inter][plane], buffer );
- break;
- case 1: case 2:
- dsp_IDct3(cpi->dsp, data, re_q[inter][plane], buffer );
- break;
- case 3:case 4:case 5:case 6:case 7:case 8: case 9:
- dsp_IDct10(cpi->dsp, data, re_q[inter][plane], buffer );
- break;
- default:
- dsp_IDctSlow(cpi->dsp, data, re_q[inter][plane], buffer );
+ /* in retrospect, should we have skipped this block? */
+ /* we are free to apply any distortion measure we like as we have
+ the full original block and fully reconstructed block with
+ which to do so.*/
+ /* for now, straight up SSD */
+ dsp_sub8x8(cpi->dsp, frame_ptr, thisrecon, buffer, stride);
+ for(i=0;i<64;i++)
+ coded_ssd += buffer[i]*buffer[i];
+
+ if(plane){
+ coded_ssd*=4;
+ uncoded_ssd*=4;
}
- dsp_recon8x8 (cpi->dsp, thisrecon, buffer, stride);
+ if(uncoded_ssd <= coded_ssd+((cpi->skip_lambda*cost)>>(OC_BIT_SCALE))){
+ /* mark uncoded */
+ cpi->frag_coded[fi]=0;
+ /* replace reconstruction with a block copy */
+ dsp_copy8x8 (cpi->dsp, cpi->lastrecon+bi, thisrecon, stride);
+
+ return 0;
+ }
}
+
+
+ return 1;
}
-static void TQMB ( CP_INSTANCE *cpi, macroblock_t *mb, int qi, ogg_int16_t req[2][3][64], long *rc){
+static int TQMB ( CP_INSTANCE *cpi, macroblock_t *mb, int qi, ogg_int16_t req[2][3][64],
+ long *rc, int keyframe){
int pf = cpi->info.pixelformat;
int mode = mb->mode;
int i;
-
+ int coded=0;
+
for(i=0;i<4;i++)
- TQB(cpi,mode,mb->Ryuv[0][i],mb->mv[i],0,req,rc);
+ if(TQB(cpi,mode,mb->Ryuv[0][i],mb->mv[i],0,req,rc,keyframe))
+ coded++;
+ else{
+ if(mode == CODE_INTER_FOURMV)
+ mb->mv[i]=(mv_t){0,0};
+ }
+ if(coded==0){
+ mode = mb->mode = CODE_INTER_NO_MV; /* No luma blocks coded, mode is forced */
+ mb->coded = 0;
+ mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
+ }
+
switch(pf){
case OC_PF_420:
if(mode == CODE_INTER_FOURMV){
@@ -620,11 +699,11 @@
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);
- TQB(cpi,mode,mb->Ryuv[1][0],mv,1,req,rc);
- TQB(cpi,mode,mb->Ryuv[2][0],mv,2,req,rc);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][0],mv,1,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][0],mv,2,req,rc,keyframe);
}else{
- TQB(cpi,mode,mb->Ryuv[1][0],mb->mv[0],1,req,rc);
- TQB(cpi,mode,mb->Ryuv[2][0],mb->mv[0],2,req,rc);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][0],mb->mv[0],1,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][0],mb->mv[0],2,req,rc,keyframe);
}
break;
@@ -642,26 +721,29 @@
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);
- TQB(cpi,mode,mb->Ryuv[1][0],mvA,1,req,rc);
- TQB(cpi,mode,mb->Ryuv[1][1],mvB,1,req,rc);
- TQB(cpi,mode,mb->Ryuv[2][0],mvA,2,req,rc);
- TQB(cpi,mode,mb->Ryuv[2][1],mvB,2,req,rc);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][0],mvA,1,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][1],mvB,1,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][0],mvA,2,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][1],mvB,2,req,rc,keyframe);
}else{
- TQB(cpi,mode,mb->Ryuv[1][0],mb->mv[0],1,req,rc);
- TQB(cpi,mode,mb->Ryuv[1][1],mb->mv[0],1,req,rc);
- TQB(cpi,mode,mb->Ryuv[2][0],mb->mv[0],2,req,rc);
- TQB(cpi,mode,mb->Ryuv[2][1],mb->mv[0],2,req,rc);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][0],mb->mv[0],1,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][1],mb->mv[0],1,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][0],mb->mv[0],2,req,rc,keyframe);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][1],mb->mv[0],2,req,rc,keyframe);
}
break;
case OC_PF_444:
for(i=0;i<4;i++)
- TQB(cpi,mode,mb->Ryuv[1][i],mb->mv[i],1,req,rc);
+ coded+=TQB(cpi,mode,mb->Ryuv[1][i],mb->mv[i],1,req,rc,keyframe);
for(i=0;i<4;i++)
- TQB(cpi,mode,mb->Ryuv[2][i],mb->mv[i],2,req,rc);
+ coded+=TQB(cpi,mode,mb->Ryuv[2][i],mb->mv[i],2,req,rc,keyframe);
break;
}
+
+ return coded;
+
}
int PickModes(CP_INSTANCE *cpi, int recode){
@@ -698,6 +780,9 @@
for(; sb<sb_end; sb++){
for(j = 0; j<4; j++){ /* mode addressing is through Y plane, always 4 MB per SB */
int mbi = sb->m[j];
+
+ if(mbi >= cpi->macro_total) continue;
+
int cost[8] = {0,0,0,0, 0,0,0,0};
int mb_mv_bits_0;
int mb_gmv_bits_0;
@@ -707,7 +792,6 @@
int aerror;
int gerror;
int block_err[4];
- int flag4mv=0;
macroblock_t *mb = &cpi->macro[mbi];
@@ -718,17 +802,17 @@
memmove(mb->analysis_mv+1,mb->analysis_mv,2*sizeof(mb->analysis_mv[0]));
/* basic 1MV search always done for all macroblocks, coded or not, keyframe or not */
- flag4mv = oc_mcenc_search(cpi, &mcenc, mbi, 0, mb->mv, &aerror, block_err);
+ oc_mcenc_search(cpi, &mcenc, mbi, 0, mb->mv, &aerror, block_err);
/* replace the block MVs for not-coded blocks with (0,0).*/
- mb->coded = 0;
+ /*mb->coded = 0;
for ( bi=0; bi<4; bi++ ){
int fi = mb->Ryuv[0][bi];
if(!cp[fi])
mb->mv[bi]=(mv_t){0,0};
else
mb->coded |= (1<<bi);
- }
+ }*/
/* search golden frame */
oc_mcenc_search(cpi, &mcenc, mbi, 1, NULL, &gerror, NULL);
@@ -737,8 +821,11 @@
if(cpi->FrameType == KEY_FRAME){
mb->mode = CODE_INTRA;
+ /* Transform, quantize, collect rho metrics */
+ TQMB(cpi, mb, qi, req, rho_count, 1);
+
}else{
-
+
/**************************************************************
Find the block choice with the lowest estimated coding cost
@@ -750,17 +837,14 @@
/* block coding cost is estimated from correlated SAD metrics */
/* At this point, all blocks that are in frame are still marked coded */
- cost[CODE_INTER_NO_MV] = cost_inter(cpi, qi, mbi, (mv_t){0,0}, CODE_INTER_NO_MV);
+ cost[CODE_INTER_NO_MV] = cost_inter_nomv(cpi, qi, mbi);
cost[CODE_INTRA] = cost_intra(cpi, qi, mbi, &intrabits);
cost[CODE_INTER_PLUS_MV] = cost_inter1mv(cpi, qi, mbi, 0, &mb_mv_bits_0);
cost[CODE_INTER_LAST_MV] = cost_inter(cpi, qi, mbi, last_mv, CODE_INTER_LAST_MV);
cost[CODE_INTER_PRIOR_LAST] = cost_inter(cpi, qi, mbi, prior_mv, CODE_INTER_PRIOR_LAST);
cost[CODE_USING_GOLDEN] = cost_inter(cpi, qi, mbi, (mv_t){0,0},CODE_USING_GOLDEN);
cost[CODE_GOLDEN_MV] = cost_inter1mv(cpi, qi, mbi, 1, &mb_gmv_bits_0);
- if(flag4mv)
- cost[CODE_INTER_FOURMV] = cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1);
- else
- cost[CODE_INTER_FOURMV] = 99999999;
+ cost[CODE_INTER_FOURMV] = cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1);
/* train this too... because the bit cost of an MV should be
considered in the context of LAST_MV and PRIOR_LAST. */
@@ -769,7 +853,7 @@
/* the explicit MV modes (2,6,7) have not yet gone through
halfpel refinement. We choose the explicit mv mode that's
already furthest ahead on bits and refine only that one */
- if(flag4mv && cost[CODE_INTER_FOURMV]<cost[CODE_INTER_PLUS_MV] && cost[CODE_INTER_FOURMV]<cost[CODE_GOLDEN_MV]){
+ if(cost[CODE_INTER_FOURMV]<cost[CODE_INTER_PLUS_MV] && cost[CODE_INTER_FOURMV]<cost[CODE_GOLDEN_MV]){
oc_mcenc_refine4mv(cpi, mbi, block_err);
cost[CODE_INTER_FOURMV] = cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1);
}else if (cost[CODE_GOLDEN_MV]<cost[CODE_INTER_PLUS_MV]){
@@ -786,7 +870,7 @@
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;
@@ -794,22 +878,17 @@
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];
+ 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;
@@ -820,9 +899,56 @@
mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
break;
}
- oc_mode_set(cpi,mb,mode);
+ mb->mode = mode;
- interbits += cost[mb->mode];
+ /* Transform, quantize, collect rho metrics */
+ if(!TQMB(cpi, mb, qi, req, rho_count, 0)){
+
+ /* ended up not coding the macroblock at all */
+ mb->coded = 0;
+ mb->mode = CODE_INTER_NO_MV;
+
+ }else{
+
+ /* still coding the MB */
+
+ /* replace the block MVs for not-coded blocks with (0,0).*/
+ mb->coded = 0;
+ for ( bi=0; bi<4; bi++ ){
+ int fi = mb->Ryuv[0][bi];
+ if(cp[fi])
+ mb->coded |= (1<<bi);
+ }
+
+ switch(mb->mode){
+ case CODE_INTER_PLUS_MV:
+ prior_mv = last_mv;
+ last_mv = mb->analysis_mv[0][0];
+ break;
+ case CODE_INTER_PRIOR_LAST:
+ {
+ mv_t temp = prior_mv;
+ prior_mv = last_mv;
+ last_mv = temp;
+ }
+ break;
+ case CODE_INTER_FOURMV:
+ prior_mv = last_mv;
+ if(mb->coded & 0x8)
+ last_mv = mb->mv[3];
+ else if(mb->coded & 0x4)
+ last_mv = mb->mv[2];
+ else if(mb->coded & 0x2)
+ last_mv = mb->mv[1];
+ else
+ last_mv = mb->mv[0];
+ break;
+ }
+
+ oc_mode_set(cpi,mb,mb->mode);
+
+ interbits += cost[mb->mode];
+ }
}
#ifdef COLLECT_METRICS
@@ -836,10 +962,6 @@
}
}
#endif
-
- /* Transform, quantize, collect rho metrics */
- TQMB(cpi, mb, qi, req, rho_count);
-
}
}
More information about the commits
mailing list