[xiph-commits] r14408 - branches/theora-thusnelda/lib/enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Wed Jan 16 02:27:17 PST 2008
Author: xiphmont
Date: 2008-01-16 02:27:16 -0800 (Wed, 16 Jan 2008)
New Revision: 14408
Modified:
branches/theora-thusnelda/lib/enc/codec_internal.h
branches/theora-thusnelda/lib/enc/encode.c
branches/theora-thusnelda/lib/enc/encoder_toplevel.c
branches/theora-thusnelda/lib/enc/mcenc.c
branches/theora-thusnelda/lib/enc/mode.c
branches/theora-thusnelda/lib/enc/mode_select.h
Log:
Minor bugfixes and rearrangement toward DCT SAD/bitrate metric
collection
Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h 2008-01-16 09:49:35 UTC (rev 14407)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h 2008-01-16 10:27:16 UTC (rev 14408)
@@ -316,22 +316,14 @@
extern void EncodeData(CP_INSTANCE *cpi);
+extern void PickMVs(CP_INSTANCE *cpi);
+
extern int PickModes(CP_INSTANCE *cpi);
extern void InitFrameInfo(CP_INSTANCE *cpi);
extern void ClearFrameInfo (CP_INSTANCE *cpi);
-extern void oc_mode_unset(CP_INSTANCE *cpi,
- macroblock_t *mb);
-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);
-
#endif /* ENCODER_INTERNAL_H */
Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c 2008-01-16 09:49:35 UTC (rev 14407)
+++ branches/theora-thusnelda/lib/enc/encode.c 2008-01-16 10:27:16 UTC (rev 14408)
@@ -203,14 +203,13 @@
}
}
-static void EncodeDcTokenList (CP_INSTANCE *cpi) {
+static void ChooseTokenTables (CP_INSTANCE *cpi, int huff[4]) {
int i,plane;
int best;
- int huff[2];
- oggpack_buffer *opb=cpi->oggbuffer;
-
- /* Work out which table options are best for DC */
+
for(plane = 0; plane<2; plane++){
+
+ /* Work out which table options are best for DC */
best = cpi->dc_bits[plane][0];
huff[plane] = DC_HUFF_OFFSET;
for ( i = 1; i < DC_HUFF_CHOICES; i++ ) {
@@ -219,77 +218,70 @@
huff[plane] = i + DC_HUFF_OFFSET;
}
}
- oggpackB_write( opb, huff[plane] - DC_HUFF_OFFSET, DC_HUFF_CHOICE_BITS );
- }
- /* Encode the token list */
- for ( i = 0; i < cpi->dct_token_count[0]; i++){
- int token = cpi->dct_token[0][i];
- int eb = cpi->dct_token_eb[0][i];
- int plane = (i >= cpi->dct_token_ycount[0]);
-
- oggpackB_write( opb, cpi->HuffCodeArray_VP3x[huff[plane]][token],
- cpi->HuffCodeLengthArray_VP3x[huff[plane]][token] );
-
- if ( cpi->ExtraBitLengths_VP3x[token] > 0 )
- oggpackB_write( opb, eb, cpi->ExtraBitLengths_VP3x[token] );
+ /* Work out which table options are best for AC */
+ best = cpi->ac_bits[plane][0];
+ huff[plane+2] = AC_HUFF_OFFSET;
+ for ( i = 1; i < AC_HUFF_CHOICES; i++ ) {
+ if ( cpi->ac_bits[plane][i] < best ){
+ best = cpi->ac_bits[plane][i];
+ huff[plane+2] = i + AC_HUFF_OFFSET;
+ }
+ }
}
}
-static void EncodeAcGroup(CP_INSTANCE *cpi, int group, int huff_offset, int *huffchoice){
+static void EncodeTokenGroup(CP_INSTANCE *cpi,
+ int group,
+ int huffY,
+ int huffC){
+
int i;
oggpack_buffer *opb=cpi->oggbuffer;
- int c = 0;
int y = cpi->dct_token_ycount[group];
-
- for(i=0; i<cpi->dct_token_count[group]; i++){
- int token = cpi->dct_token[group][i];
- int eb = cpi->dct_token_eb[group][i];
- int plane = (c >= y);
+ unsigned char *token = cpi->dct_token[group];
+ ogg_uint16_t *eb = cpi->dct_token_eb[group];
+
+ for(i=0; i<y; i++){
+ oggpackB_write( opb, cpi->HuffCodeArray_VP3x[huffY][token[i]],
+ cpi->HuffCodeLengthArray_VP3x[huffY][token[i]] );
+ if (cpi->ExtraBitLengths_VP3x[token[i]] > 0)
+ oggpackB_write( opb, eb[i], cpi->ExtraBitLengths_VP3x[token[i]] );
+ }
- int hi = huff_offset + huffchoice[plane];
-
- oggpackB_write( opb, cpi->HuffCodeArray_VP3x[hi][token],
- cpi->HuffCodeLengthArray_VP3x[hi][token] );
-
- if (cpi->ExtraBitLengths_VP3x[token] > 0)
- oggpackB_write( opb, eb,cpi->ExtraBitLengths_VP3x[token] );
-
- c++;
+ for(; i<cpi->dct_token_count[group]; i++){
+ oggpackB_write( opb, cpi->HuffCodeArray_VP3x[huffC][token[i]],
+ cpi->HuffCodeLengthArray_VP3x[huffC][token[i]] );
+ if (cpi->ExtraBitLengths_VP3x[token[i]] > 0)
+ oggpackB_write( opb, eb[i], cpi->ExtraBitLengths_VP3x[token[i]] );
}
}
-static void EncodeAcTokenList (CP_INSTANCE *cpi) {
- int i,plane;
- int best;
- int huff[2];
+static void EncodeTokenList (CP_INSTANCE *cpi, int huff[4]) {
+ int i;
oggpack_buffer *opb=cpi->oggbuffer;
- /* Work out which table options are best for AC */
- for(plane = 0; plane<2; plane++){
- best = cpi->ac_bits[plane][0];
- huff[plane] = AC_HUFF_OFFSET;
- for ( i = 1; i < AC_HUFF_CHOICES; i++ ) {
- if ( cpi->ac_bits[plane][i] < best ){
- best = cpi->ac_bits[plane][i];
- huff[plane] = i + AC_HUFF_OFFSET;
- }
- }
- oggpackB_write( opb, huff[plane] - AC_HUFF_OFFSET, AC_HUFF_CHOICE_BITS );
- }
-
- /* encode dct tokens, group 1 through group 63 in the four AC ranges */
+ /* DC tokens aren't special, they just come first */
+ oggpackB_write( opb, huff[0] - DC_HUFF_OFFSET, DC_HUFF_CHOICE_BITS );
+ oggpackB_write( opb, huff[1] - DC_HUFF_OFFSET, DC_HUFF_CHOICE_BITS );
+
+ EncodeTokenGroup(cpi, 0, huff[0], huff[1]);
+
+ /* AC tokens */
+ oggpackB_write( opb, huff[2] - AC_HUFF_OFFSET, AC_HUFF_CHOICE_BITS );
+ oggpackB_write( opb, huff[3] - AC_HUFF_OFFSET, AC_HUFF_CHOICE_BITS );
+
for(i=1;i<=AC_TABLE_2_THRESH;i++)
- EncodeAcGroup(cpi, i, 0, huff);
+ EncodeTokenGroup(cpi, i, huff[2], huff[3]);
for(;i<=AC_TABLE_3_THRESH;i++)
- EncodeAcGroup(cpi, i, AC_HUFF_CHOICES, huff);
+ EncodeTokenGroup(cpi, i, huff[2]+AC_HUFF_CHOICES, huff[3]+AC_HUFF_CHOICES);
for(;i<=AC_TABLE_4_THRESH;i++)
- EncodeAcGroup(cpi, i, AC_HUFF_CHOICES*2, huff);
+ EncodeTokenGroup(cpi, i, huff[2]+AC_HUFF_CHOICES*2, huff[3]+AC_HUFF_CHOICES*2);
for(;i<BLOCK_SIZE;i++)
- EncodeAcGroup(cpi, i, AC_HUFF_CHOICES*3, huff);
+ EncodeTokenGroup(cpi, i, huff[2]+AC_HUFF_CHOICES*3, huff[3]+AC_HUFF_CHOICES*3);
}
@@ -392,6 +384,7 @@
}
void EncodeData(CP_INSTANCE *cpi){
+ int tokenhuff[4];
dsp_save_fpu (cpi->dsp);
@@ -410,8 +403,8 @@
PackMotionVectors (cpi);
}
- EncodeDcTokenList(cpi);
- EncodeAcTokenList(cpi);
+ ChooseTokenTables(cpi, tokenhuff);
+ EncodeTokenList(cpi, tokenhuff);
ReconRefFrames(cpi);
Modified: branches/theora-thusnelda/lib/enc/encoder_toplevel.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_toplevel.c 2008-01-16 09:49:35 UTC (rev 14407)
+++ branches/theora-thusnelda/lib/enc/encoder_toplevel.c 2008-01-16 10:27:16 UTC (rev 14408)
@@ -31,6 +31,7 @@
oggpackB_reset(cpi->oggbuffer);
cpi->FrameType = KEY_FRAME;
+ cpi->LastKeyFrame = 0;
/* code all blocks */
for(j=0;j<cpi->frag_total;j++)
@@ -39,14 +40,13 @@
/* mark as video frame */
oggpackB_write(cpi->oggbuffer,0,1);
- /* Write out the frame header information including size. */
WriteFrameHeader(cpi);
-
- /* still need to go through mode selection to do MV/mode analysis that
- will be used by subsequent inter frames. Mode will be special-forced to INTRA for each MB. */
+ PickMVs(cpi);
+ /* still need to go through mode selection to do MV/mode analysis
+ that will be used by subsequent inter frames. Mode will be
+ special-forced to INTRA for each MB. */
PickModes(cpi);
- /* Encode the data. */
EncodeData(cpi);
cpi->LastKeyFrame = 1;
@@ -64,20 +64,15 @@
/* mark as video frame */
oggpackB_write(cpi->oggbuffer,0,1);
- /* Write out the frame header information including size. */
WriteFrameHeader(cpi);
-
- /* Select modes and motion vectors for each of the blocks */
+ PickMVs(cpi);
if(PickModes( cpi )){
/* mode analysis thinks this should have been a keyframe; start over and code as a keyframe instead */
CompressKeyFrame(cpi); /* Code a key frame */
return 0;
}
- /* Increment the frames since last key frame count */
cpi->LastKeyFrame++;
-
- /* Encode the data. */
EncodeData(cpi);
return 0;
Modified: branches/theora-thusnelda/lib/enc/mcenc.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mcenc.c 2008-01-16 09:49:35 UTC (rev 14407)
+++ branches/theora-thusnelda/lib/enc/mcenc.c 2008-01-16 10:27:16 UTC (rev 14408)
@@ -617,7 +617,7 @@
}
-void oc_mcenc_start(CP_INSTANCE *cpi,
+static void oc_mcenc_start(CP_INSTANCE *cpi,
mc_state *mcenc){
ogg_int64_t nframes;
@@ -633,3 +633,44 @@
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->yuv[0][bi];
+ if(!cp[fi])
+ mb->mv[fi]=(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-01-16 09:49:35 UTC (rev 14407)
+++ branches/theora-thusnelda/lib/enc/mode.c 2008-01-16 10:27:16 UTC (rev 14408)
@@ -419,52 +419,16 @@
}
int PickModes(CP_INSTANCE *cpi){
-
unsigned char qi = cpi->BaseQ; // temporary
superblock_t *sb = cpi->super[0];
superblock_t *sb_end = sb + cpi->super_n[0];
- unsigned char *cp = cpi->frag_coded;
- mc_state mcenc;
- int mbi, bi, i;
+ int mbi, i;
ogg_uint32_t interbits = 0;
ogg_uint32_t intrabits = 0;
mv_t last_mv = {0,0};
mv_t prior_mv = {0,0};
- 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->yuv[0][bi];
- if(!cp[fi])
- mb->mv[fi]=(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);
- }
-
oc_mode_scheme_chooser_init(cpi);
cpi->MVBits_0 = 0;
cpi->MVBits_1 = 0;
Modified: branches/theora-thusnelda/lib/enc/mode_select.h
===================================================================
--- branches/theora-thusnelda/lib/enc/mode_select.h 2008-01-16 09:49:35 UTC (rev 14407)
+++ branches/theora-thusnelda/lib/enc/mode_select.h 2008-01-16 10:27:16 UTC (rev 14408)
@@ -1,4 +1,4 @@
-/********************************************************************
+ /********************************************************************
* *
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
More information about the commits
mailing list