[xiph-commits] r9185 - in experimental/derf/theora-exp: include/theora lib

tterribe at motherfish-iii.xiph.org tterribe at motherfish-iii.xiph.org
Mon Apr 25 18:55:55 PDT 2005


Author: tterribe
Date: 2005-04-25 18:55:52 -0700 (Mon, 25 Apr 2005)
New Revision: 9185

Modified:
   experimental/derf/theora-exp/include/theora/theoraenc.h
   experimental/derf/theora-exp/lib/encint.h
   experimental/derf/theora-exp/lib/encode.c
Log:
Add VP3-compatibility mode to the encoder to produce video that can be
 losslessly transcoded back to VP3.


Modified: experimental/derf/theora-exp/include/theora/theoraenc.h
===================================================================
--- experimental/derf/theora-exp/include/theora/theoraenc.h	2005-04-25 21:33:07 UTC (rev 9184)
+++ experimental/derf/theora-exp/include/theora/theoraenc.h	2005-04-26 01:55:52 UTC (rev 9185)
@@ -82,6 +82,34 @@
  * \retval OC_EINVAL \a _buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
  * \retval OC_IMPL   Not supported by this implementation.*/
 #define OC_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
+/**Disables any encoder features that would prevent lossless transcoding back
+ *  to VP3.
+ * This primarily means disabling block-level QI values and not using 4MV mode
+ *  when any of the luma blocks in a macro block are not coded.
+ * It also includes using the VP3 quantization tables and Huffman codes; if you
+ *  set them explicitly after calling this function, the resulting stream will
+ *  not by VP3-compatible.
+ * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
+ *  material, or when using a picture region smaller than the full frame (e.g.
+ *  a non-multiple-of-16 width or height), then non-VP3 bitstream features will
+ *  still be disabled, but the stream will still not be VP3-compatible, as VP3
+ *  was not capable of encoding such formats.
+ * If you call this after encoding has already begun, then the quantization
+ *  tables and codebooks cannot be changed, but the frame-level features will
+ *  be enabled or disabled as requested.
+ *
+ * \param[in]  _buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
+ *                   or 0 to disable it (the default).
+ * \param[out] _buf <tt>int</tt>: 1 if all bitstream features required for
+ *                   VP3-compatibility could be set, and 0 otherwise.
+ *                  The latter will be returned if with pixel format is not
+ *                   4:2:0, the picture region is smaller than the full frame,
+ *                   or if encoding has begun, preventing the quantization
+ *                   tables and codebooks from being set.
+ * \retval OC_FAULT  \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
+#define OC_ENCCTL_SET_VP3_COMPATIBLE (10)
 /*@}*/
 
 

Modified: experimental/derf/theora-exp/lib/encint.h
===================================================================
--- experimental/derf/theora-exp/lib/encint.h	2005-04-25 21:33:07 UTC (rev 9184)
+++ experimental/derf/theora-exp/lib/encint.h	2005-04-26 01:55:52 UTC (rev 9185)
@@ -151,6 +151,8 @@
   theora_huff_code         huff_codes[OC_NHUFFMAN_TABLES][OC_NDCT_TOKENS];
   /*The scale factor for the current quality setting.*/
   float                    qscale;
+  /*Whether or not VP3-compatibility is enabled.*/
+  int                      vp3_compatible;
   /*The quantization parameters in use.*/
   theora_quant_info        qinfo;
   /*Pointers to the quantization tables in use.*/

Modified: experimental/derf/theora-exp/lib/encode.c
===================================================================
--- experimental/derf/theora-exp/lib/encode.c	2005-04-25 21:33:07 UTC (rev 9184)
+++ experimental/derf/theora-exp/lib/encode.c	2005-04-26 01:55:52 UTC (rev 9185)
@@ -660,6 +660,8 @@
       _enc->qis[fti][0]=qi0;
       _enc->nqis[fti]=1;
     }
+    /*If we're in VP3 compatibility mode, just use the first quantizer.*/
+    if(_enc->vp3_compatible)_enc->nqis[fti]=1;
   }
 }
 
@@ -2154,6 +2156,11 @@
       /*Finally, pick the mode with the cheapest estimated bit cost.*/
       mb->mode=0;
       for(modei=1;modei<OC_NMODES;modei++)if(bits[modei]<bits[mb->mode]){
+        /*Do not select 4MV mode when not all the luma blocks are coded when
+           we're in VP3 compatibility mode.*/
+        if(_enc->vp3_compatible&&modei==OC_MODE_INTER_MV_FOUR&&ncoded_luma<4){
+          continue;
+        }
         mb->mode=modei;
       }
 #if defined(OC_BITRATE_STATS)
@@ -2201,8 +2208,6 @@
           last_mv[0][1]=mbmv[1];
         }break;
         case OC_MODE_INTER_MV_FOUR:{
-          /*TODO: Handle the case when less than 4 luma blocks are being
-             coded.*/
           mvbitsa+=mb4mvbitsa;
           mvbitsb+=mb4mvbitsb;
           if(ncoded_luma>0){
@@ -2492,6 +2497,8 @@
   _enc->psych=oc_psych_alloc(_enc);
   /*Reset the packet-out state machine.*/
   _enc->packet_state=OC_PACKET_INFO_HDR;
+  /*Mark us as not VP3-compatible.*/
+  _enc->vp3_compatible=0;
   /*Set the Huffman codes and quantization parameters to the defaults.*/
   memcpy(_enc->huff_codes,OC_VP31_HUFF_CODES,sizeof(_enc->huff_codes));
   oc_enc_set_quant_params(_enc,NULL);
@@ -2545,28 +2552,55 @@
       return oc_enc_set_huffman_codes(_enc,(theora_huff_table *)_buf);
     }break;
     case OC_ENCCTL_SET_QUANT_PARAMS:{
-       if(_buf==NULL&&_buf_sz!=0||
-        _buf!=NULL&&_buf_sz!=sizeof(theora_quant_info)){
-         return OC_EINVAL;
-       }
-       return oc_enc_set_quant_params(_enc,(theora_quant_info *)_buf);
+      if(_buf==NULL&&_buf_sz!=0||
+       _buf!=NULL&&_buf_sz!=sizeof(theora_quant_info)){
+        return OC_EINVAL;
+      }
+      return oc_enc_set_quant_params(_enc,(theora_quant_info *)_buf);
     }break;
     case OC_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE:{
-       ogg_uint32_t keyframe_frequency_force;
-       if(_enc==NULL||_buf==NULL)return OC_FAULT;
-       if(_buf_sz!=sizeof(ogg_uint32_t))return OC_EINVAL;
-       keyframe_frequency_force=*(ogg_uint32_t *)_buf;
-       if(_enc->packet_state==OC_PACKET_INFO_HDR){
-         /*It's still early enough to enlarge keyframe_granule_shift.*/
-         _enc->state.info.keyframe_granule_shift=
-          OC_MAXI(_enc->state.info.keyframe_granule_shift,
-          OC_MINI(31,oc_ilog(keyframe_frequency_force-1)));
-       }
-       _enc->keyframe_frequency_force=OC_MINI(keyframe_frequency_force,
-        1U<<_enc->state.info.keyframe_granule_shift);
-       (*(ogg_uint32_t *)_buf)=_enc->keyframe_frequency_force;
-       return 0;
+      ogg_uint32_t keyframe_frequency_force;
+      if(_enc==NULL||_buf==NULL)return OC_FAULT;
+      if(_buf_sz!=sizeof(ogg_uint32_t))return OC_EINVAL;
+      keyframe_frequency_force=*(ogg_uint32_t *)_buf;
+      if(_enc->packet_state==OC_PACKET_INFO_HDR){
+        /*It's still early enough to enlarge keyframe_granule_shift.*/
+        _enc->state.info.keyframe_granule_shift=
+         OC_MAXI(_enc->state.info.keyframe_granule_shift,
+         OC_MINI(31,oc_ilog(keyframe_frequency_force-1)));
+      }
+      _enc->keyframe_frequency_force=OC_MINI(keyframe_frequency_force,
+       1U<<_enc->state.info.keyframe_granule_shift);
+      (*(ogg_uint32_t *)_buf)=_enc->keyframe_frequency_force;
+      return 0;
     }break;
+    case OC_ENCCTL_SET_VP3_COMPATIBLE:{
+      int vp3_compatible;
+      int ret;
+      if(_enc==NULL||_buf==NULL)return OC_FAULT;
+      if(_buf_sz!=sizeof(int))return OC_EINVAL;
+      vp3_compatible=*(int *)_buf;
+      _enc->vp3_compatible=vp3_compatible;
+      ret=oc_enc_set_huffman_codes(_enc,OC_VP31_HUFF_CODES);
+      if(ret<0)vp3_compatible=0;
+      ret=oc_enc_set_quant_params(_enc,&OC_VP31_QUANT_INFO);
+      if(ret<0)vp3_compatible=0;
+      if(_enc->state.info.pixel_fmt!=OC_PF_420||
+       _enc->state.info.pic_width<_enc->state.info.frame_width||
+       _enc->state.info.pic_height<_enc->state.info.frame_height||
+      /*If we have more than 4095 super blocks, VP3's RLE coding might
+         overflow.
+        We could overcome this by ensuring we flip the coded/not-coded flags on
+         at lease one super block in the frame, but we pick the simple solution
+         of just marking the stream incompatible instead.
+        It's unlikely the old VP3 codec would be able to decode streams at this
+         resolution in real time in the first place.*/
+       _enc->state.nsbs>4095){
+        vp3_compatible=0;
+      }
+      *((int *)_buf)=vp3_compatible;
+      return 0;
+    }break;
     default:return OC_IMPL;
   }
 }



More information about the commits mailing list