[xiph-commits] r14650 - branches/theora-thusnelda/lib/enc

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Wed Apr 2 12:28:58 PDT 2008


Author: xiphmont
Date: 2008-04-02 12:28:57 -0700 (Wed, 02 Apr 2008)
New Revision: 14650

Modified:
   branches/theora-thusnelda/lib/enc/codec_internal.h
   branches/theora-thusnelda/lib/enc/encoder_toplevel.c
   branches/theora-thusnelda/lib/enc/frinit.c
   branches/theora-thusnelda/lib/enc/mcenc.c
   branches/theora-thusnelda/lib/enc/mode.c
Log:
re-inline ME with mode selection as part of the master encode loop.



Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h	2008-04-01 16:24:39 UTC (rev 14649)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h	2008-04-02 19:28:57 UTC (rev 14650)
@@ -325,9 +325,15 @@
 
 extern void EncodeData(CP_INSTANCE *cpi);
 
-extern void PickMVs(CP_INSTANCE *cpi);
+extern void oc_mcenc_start(CP_INSTANCE *cpi,
+			   mc_state *mcenc);
+extern void oc_mcenc_search(CP_INSTANCE *cpi, 
+			    mc_state *_mcenc,
+			    int _mbi,
+			    int _goldenp,
+			    mv_t *_bmvs);
 
-extern int PickModes(CP_INSTANCE *cpi);
+extern int PickModes(CP_INSTANCE *cpi, int recode);
 
 extern void InitFrameInfo(CP_INSTANCE *cpi);
 

Modified: branches/theora-thusnelda/lib/enc/encoder_toplevel.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_toplevel.c	2008-04-01 16:24:39 UTC (rev 14649)
+++ branches/theora-thusnelda/lib/enc/encoder_toplevel.c	2008-04-02 19:28:57 UTC (rev 14650)
@@ -41,11 +41,7 @@
   oggpackB_write(cpi->oggbuffer,0,1);
   
   WriteFrameHeader(cpi);
-  PickMVs(cpi);
-
-  for(i=0; i<cpi->macro_total; i++)
-    cpi->macro[i].mode = CODE_INTRA;
-  
+  PickModes(cpi,0);
   EncodeData(cpi);
   
   cpi->LastKeyFrame = 1;
@@ -64,8 +60,7 @@
   oggpackB_write(cpi->oggbuffer,0,1);
 
   WriteFrameHeader(cpi);
-  PickMVs(cpi);
-  if(PickModes( cpi )){
+  if(PickModes( cpi,0 )){
     /* mode analysis thinks this should have been a keyframe; start over and code as a keyframe instead */
 
     oggpackB_reset(cpi->oggbuffer);
@@ -81,10 +76,7 @@
     
     WriteFrameHeader(cpi);
 
-    /* don't repeat MV or mode selection.  Set to intra */
-    for(i=0; i<cpi->macro_total; i++)
-      cpi->macro[i].mode = CODE_INTRA;
-  
+    PickModes(cpi,1);
     EncodeData(cpi);
     
     cpi->LastKeyFrame = 1;

Modified: branches/theora-thusnelda/lib/enc/frinit.c
===================================================================
--- branches/theora-thusnelda/lib/enc/frinit.c	2008-04-01 16:24:39 UTC (rev 14649)
+++ branches/theora-thusnelda/lib/enc/frinit.c	2008-04-02 19:28:57 UTC (rev 14650)
@@ -295,15 +295,52 @@
 	int macroindex = row*cpi->macro_h + col;
 	int count=0;
 
-	/* cneighbors are of four possible already-filled-in neighbors from the eight-neighbor square */
-	if(col)
-	  cpi->macro[macroindex].cneighbors[count++]=macroindex-1;
-	if(col && row)
-	  cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h-1;
-	if(row)
-	  cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h;
-	if(row && col+1<cpi->macro_h)
-	  cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h+1;
+	/* cneighbors are of four possible already-filled-in neighbors
+	   from the eight-neighbor square for doing ME. The
+	   macroblocks are scanned in Hilbert order and the corner
+	   cases here are annoying, so we precompute. */
+	if(row&1){
+	  if(col&1){
+	    /* 2 */
+	    cpi->macro[macroindex].cneighbors[count++]=macroindex-1;
+	    cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h-1;
+	  }else{
+	    /* 1 */
+	    if(col){
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-1;
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h-1;
+	    }
+	    cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h;
+	  }
+	}else{
+	  if(col&1){
+	    /* 3; Could have up to six, fill in at most 4 */
+	    if(row && col+1<cpi->macro_h)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h+1;
+	    if(row)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h;
+	    if(col && row)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h-1;
+	    if(col)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-1;
+	    if(col && row+1<cpi->macro_v && count<4)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex+cpi->macro_h-1;
+	    if(row+1<cpi->macro_v && count<4)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex+cpi->macro_h;
+	  }else{
+	    /* 0; Could have up to five, fill in at most 4 */
+	    if(row && col+1<cpi->macro_h)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h+1;
+	    if(row)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h;
+	    if(col && row)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-cpi->macro_h-1;
+	    if(col)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex-1;
+	    if(col && row+1<cpi->macro_v && count<4)
+	      cpi->macro[macroindex].cneighbors[count++]=macroindex+cpi->macro_h-1;
+	  }
+	}
 	cpi->macro[macroindex].ncneighbors=count;
 
 	/* pneighbors are of the four possible direct neighbors (plus pattern), not the same as cneighbors */

Modified: branches/theora-thusnelda/lib/enc/mcenc.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mcenc.c	2008-04-01 16:24:39 UTC (rev 14649)
+++ branches/theora-thusnelda/lib/enc/mcenc.c	2008-04-02 19:28:57 UTC (rev 14650)
@@ -588,7 +588,7 @@
 }
 
 
-static void oc_mcenc_start(CP_INSTANCE *cpi,
+void oc_mcenc_start(CP_INSTANCE *cpi,
                     mc_state *mcenc){
 
   ogg_int64_t  nframes;
@@ -604,44 +604,3 @@
   mcenc->mvapw2[OC_FRAME_GOLD]=(ogg_int32_t)(nframes!=2?(nframes<<16)/(nframes-2):0);
 
 }
-
-void PickMVs(CP_INSTANCE *cpi){
-  
-  unsigned char *cp = cpi->frag_coded;
-  mc_state mcenc;
-  int mbi, bi;
-
-  oc_mcenc_start(cpi, &mcenc); 
-
-  for(mbi = 0; mbi<cpi->macro_total; mbi++){
-    macroblock_t *mb     = &cpi->macro[mbi];
-
-    /*Move the motion vector predictors back a frame */
-    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 */
-    oc_mcenc_search(cpi, &mcenc, mbi, 0, mb->mv);
-
-    /* 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->mv[bi]=(mv_t){0,0};
-      else
-	mb->coded |= (1<<bi);
-    }
-
-    if(mb->coded==0){
-      /* Don't bother to do a MV search against the golden frame.
-	 Just re-use the last vector, which should match well since the
-	 contents of the MB haven't changed much.*/
-      mb->analysis_mv[0][1]=mb->analysis_mv[1][1];
-      continue;
-    }
-
-    /* search golden frame */
-    oc_mcenc_search(cpi, &mcenc, mbi, 1, NULL);
-  }
-}
-

Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c	2008-04-01 16:24:39 UTC (rev 14649)
+++ branches/theora-thusnelda/lib/enc/mode.c	2008-04-02 19:28:57 UTC (rev 14650)
@@ -413,23 +413,27 @@
   }
 }
 
-int PickModes(CP_INSTANCE *cpi){
+int PickModes(CP_INSTANCE *cpi, int recode){
   unsigned char qi = cpi->BaseQ; // temporary
   superblock_t *sb = cpi->super[0];
   superblock_t *sb_end = sb + cpi->super_n[0];
   int i,j;
   ogg_uint32_t interbits = 0;
   ogg_uint32_t intrabits = 0;
-
+  mc_state mcenc;
   mv_t last_mv = {0,0};
   mv_t prior_mv = {0,0};
+  unsigned char *cp = cpi->frag_coded;
 
   oc_mode_scheme_chooser_init(cpi);
 
   cpi->MVBits_0 = 0;
   cpi->MVBits_1 = 0;
  
-  /* Choose modes; must be done in Hilbert order */
+  if(!recode)
+    oc_mcenc_start(cpi, &mcenc); 
+  
+  /* Choose mvs, modes; must be done in Hilbert order */
   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];
@@ -439,10 +443,34 @@
       int mb_gmv_bits_0;
       int mb_4mv_bits_0;
       int mb_4mv_bits_1;
-      int mode;
+      int mode,bi;
 
       macroblock_t *mb = &cpi->macro[mbi];
 
+      if(!recode){
+	/* Motion estimation */
+
+	/* Move the motion vector predictors back a frame */
+	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 */
+	oc_mcenc_search(cpi, &mcenc, mbi, 0, mb->mv);
+	
+	/* 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->mv[bi]=(mv_t){0,0};
+	  else
+	    mb->coded |= (1<<bi);
+	}
+	
+	/* search golden frame */
+	oc_mcenc_search(cpi, &mcenc, mbi, 1, NULL);
+	
+      }
+
       if(cpi->FrameType == KEY_FRAME){
 	mb->mode = CODE_INTRA;
 	continue;



More information about the commits mailing list