[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