[xiph-cvs] cvs commit: theora/lib dct_decode.c encoder_internal.h toplevel.c

Ralph Giles giles at xiph.org
Mon Mar 8 18:02:57 PST 2004



giles       04/03/08 21:02:57

  Modified:    lib      dct_decode.c encoder_internal.h toplevel.c
  Log:
  Save the limit value table for the in-loop block filter in the setup
  header.
  
  THIS IS AN INCOMPATIBLE BITSTREAM CHANGE.
  
  This table, indexed by q, is used to compute the width of the triangle
  waveform in the PB_INSTANCE.FiltBoundingValue table. Since it's part of
  the encoder loop, we want to be able to tweak it and include it in the
  bitstream.
  
  As we understand it, the maximum useful value for an entry is 127, so we
  use 7 bits to store the unsigned values. This adds another 56 bytes to
  the header. Run length encoding them would help, but we don't believe
  it's worth the complexity while we have no general mechanism for this
  sort of data. A simple length,value pair scheme gets this below 30
  bytes for the current table; if we implement this for the q matricies
  we should do it here as well.

Revision  Changes    Path
1.10      +39 -9     theora/lib/dct_decode.c

Index: dct_decode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/dct_decode.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- dct_decode.c	3 Dec 2003 08:59:39 -0000	1.9
+++ dct_decode.c	9 Mar 2004 02:02:56 -0000	1.10
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-  last mod: $Id: dct_decode.c,v 1.9 2003/12/03 08:59:39 arc Exp $
+  last mod: $Id: dct_decode.c,v 1.10 2004/03/09 02:02:56 giles Exp $
 
  ********************************************************************/
 
@@ -27,7 +27,9 @@
 #define PL 1
 #define HIGHBITDUPPED(X) (((signed short) X)  >> 15)
 
-static const ogg_uint32_t LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {
+/* in-loop filter tables. one of these is used in dct_decode.c */
+
+static const unsigned char LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {
   30, 25, 20, 20, 15, 15, 14, 14,
   13, 13, 12, 12, 11, 11, 10, 10,
   9,  9,  8,  8,  7,  7,  7,  7,
@@ -38,7 +40,7 @@
   0,  0,  0,  0,  0,  0,  0,  0
 };
 
-static const ogg_uint32_t LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {
+static const unsigned char LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {
   30, 25, 20, 20, 15, 15, 14, 14,
   13, 13, 12, 12, 11, 11, 10, 10,
   9,  9,  8,  8,  7,  7,  7,  7,
@@ -67,10 +69,42 @@
   }
 }
 
+/* handle the in-loop filter limit value table */
+
+void WriteFilterTables(PB_INSTANCE *pbi, oggpack_buffer *opb){
+  int i;
+  for(i=0;i<Q_TABLE_SIZE;i++)
+    oggpackB_write(opb, pbi->LoopFilterLimits[i],7);
+}
+
+int ReadFilterTables(codec_setup_info *ci, oggpack_buffer *opb){
+  int i, bits;
+
+  for(i=0;i<Q_TABLE_SIZE;i++){
+    theora_read(opb,7,&bits);
+    ci->LoopFilterLimitValues[i]=bits;
+  }
+  if(bits<0)return OC_BADHEADER;
+
+  return 0;
+}
+
+/* copy in-loop filter limits from the bitstream header into our instance */
+void CopyFilterTables(PB_INSTANCE *pbi, codec_setup_info *ci){
+  memcpy(pbi->LoopFilterLimits, ci->LoopFilterLimitValues, Q_TABLE_SIZE);
+}
+
+/* initialize the filter limits from our static table */
+void InitFilterTables(PB_INSTANCE *pbi){
+  memcpy(pbi->LoopFilterLimits, LoopFilterLimitValuesV1, Q_TABLE_SIZE);
+}
+
 void SetupLoopFilter(PB_INSTANCE *pbi){
   ogg_int32_t FLimit;
 
-  FLimit = LoopFilterLimitValuesV2[pbi->FrameQIndex];
+  /* nb: this was using the V2 values rather than V1
+     we think is was a mistake; the results were not used */
+  FLimit = pbi->LoopFilterLimits[pbi->FrameQIndex];
   SetupBoundingValueArray_Generic(pbi, FLimit);
 }
 
@@ -719,14 +753,10 @@
     QIndex --;
   }
 
-  /* Encoder version specific clause */
-  FLimit = LoopFilterLimitValuesV1[QIndex];
-
+  FLimit = pbi->LoopFilterLimits[QIndex];
   if ( FLimit == 0 ) return;
-
   SetupBoundingValueArray_Generic(pbi, FLimit);
 
-
   for ( j = 0; j < 3 ; j++){
     switch(j) {
     case 0: /* y */

<p><p>1.21      +8 -2      theora/lib/encoder_internal.h

Index: encoder_internal.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_internal.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- encoder_internal.h	8 Mar 2004 06:44:27 -0000	1.20
+++ encoder_internal.h	9 Mar 2004 02:02:56 -0000	1.21
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-  last mod: $Id: encoder_internal.h,v 1.20 2004/03/08 06:44:27 giles Exp $
+  last mod: $Id: encoder_internal.h,v 1.21 2004/03/09 02:02:56 giles Exp $
 
  ********************************************************************/
 
@@ -260,6 +260,8 @@
   Q_LIST_ENTRY Inter_coeffs[64];
 
   HUFF_ENTRY *HuffRoot[NUM_HUFF_TABLES];
+
+  unsigned char LoopFilterLimitValues[Q_TABLE_SIZE];
 } codec_setup_info;
 
 typedef struct PB_INSTANCE {
@@ -430,6 +432,7 @@
   ogg_int16_t   *TmpDataBuffer;
 
   /* Loop filter bounding values */
+  unsigned char  LoopFilterLimits[Q_TABLE_SIZE];
   ogg_int32_t    FiltBoundingValue[512];
 
   /* Dequantiser and rounding tables */
@@ -474,7 +477,6 @@
 
   unsigned char *DataOutputInPtr;
 
-
 } PB_INSTANCE;
 
 typedef struct CP_INSTANCE {
@@ -741,6 +743,10 @@
                               oggpack_buffer *opb);
 extern void InitHuffmanTrees(PB_INSTANCE *pbi, const codec_setup_info *ci);
 extern void ClearHuffmanTrees(HUFF_ENTRY *HuffRoot[NUM_HUFF_TABLES]);
+extern void WriteFilterTables(PB_INSTANCE *pbi, oggpack_buffer *opb);
+extern int  ReadFilterTables(codec_setup_info *ci, oggpack_buffer *opb);
+extern void CopyFilterTables(PB_INSTANCE *pbi, codec_setup_info *ci);
+extern void InitFilterTables(PB_INSTANCE *pbi);
 extern void QuadDecodeDisplayFragments ( PB_INSTANCE *pbi );
 extern void PackAndWriteDFArray( CP_INSTANCE *cpi );
 extern void UpdateFragQIndex(PB_INSTANCE *pbi);

<p><p>1.37      +12 -4     theora/lib/toplevel.c

Index: toplevel.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/toplevel.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- toplevel.c	5 Mar 2004 17:44:28 -0000	1.36
+++ toplevel.c	9 Mar 2004 02:02:56 -0000	1.37
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-  last mod: $Id: toplevel.c,v 1.36 2004/03/05 17:44:28 giles Exp $
+  last mod: $Id: toplevel.c,v 1.37 2004/03/09 02:02:56 giles Exp $
 
  ********************************************************************/
 
@@ -880,6 +880,7 @@
   cpi->ScanConfig.VideoFrameWidth = cpi->pb.info.width;
 
   InitFrameDetails(&cpi->pb);
+  InitFilterTables(&cpi->pb);
   EInitFragmentInfo(cpi);
   EInitFrameInfo(cpi);
 
@@ -1187,6 +1188,7 @@
 
   WriteQTables(&cpi->pb,cpi->oggbuffer);
   WriteHuffmanTrees(cpi->pb.HuffRoot_VP3x,cpi->oggbuffer);
+  WriteFilterTables(&cpi->pb,cpi->oggbuffer);
 
 #ifndef LIBOGG2
   op->packet=oggpackB_get_buffer(cpi->oggbuffer);
@@ -1341,13 +1343,18 @@
 
 static int _theora_unpack_tables(theora_info *c, oggpack_buffer *opb){
   codec_setup_info *ci;
-  int               ret;
+  int ret;
 
   ci=(codec_setup_info *)c->codec_setup;
 
   ret=ReadQTables(ci, opb);
   if(ret)return ret;
-  return ReadHuffmanTrees(ci, opb);
+  ret=ReadHuffmanTrees(ci, opb);
+  if(ret)return ret;
+  ret=ReadFilterTables(ci, opb);
+  if(ret)return ret;
+
+  return ret;
 }
 
 int theora_decode_header(theora_info *ci, theora_comment *cc, ogg_packet *op){
@@ -1458,8 +1465,9 @@
   /* Clear down the YUVtoRGB conversion skipped list. */
   memset(pbi->skipped_display_fragments, 0, pbi->UnitFragments );
 
-  /* Initialise version specific quantiser values */
+  /* Initialise version specific quantiser and in-loop filter values */
   CopyQTables(pbi, ci);
+  CopyFilterTables(pbi, ci);
 
   /* Huffman setup */
   InitHuffmanTrees(pbi, ci);

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list