shithub: libvpx

Download patch

ref: 0952acb79af7319b64cc598712450f6766108a0d
parent: 1689564bb5c0f03bb2f35244bf40bcf58c9fec35
author: John Koleszar <jkoleszar@google.com>
date: Tue Jun 1 07:14:25 EDT 2010

setup experimental infrastructure

This patch creates some basic infrastructure for doing bitstream-
incompatible changes to the VP8 encoder. The key parts are:

 - --enable-experimental configure switch, to enable support for this
   incompatible bitstream. This switch is required to be set to enable
   any "experiments"

 - A list for "experiments" which translate into --enable-<experiment>
   options and CONFIG_<experiment> macros.

 - The high bit of the "Version" field is used to indicate that the
   bitstream was produced by an experimental encoder. The decoder will
   fail to decode an experimental bitstream without
   --enable-experimental.

 - A new "vp8x" encoder interface is created to set the experimental
   bit.

 - The vp8x encoder interface is made the default for ivfenc in
   experimental mode.

Change-Id: Idbdd5eae4cec5becf75bb4770837dcd256b2abef

--- a/configure
+++ b/configure
@@ -203,6 +203,8 @@
     pthread_h
     sys_mman_h
 "
+EXPERIMENT_LIST="
+"
 CONFIG_LIST="
     external_build
     install_docs
@@ -242,6 +244,9 @@
     static_msvcrt
     spatial_resampling
     realtime_only
+
+    experimental
+    ${EXPERIMENT_LIST}
 "
 CMDLINE_SELECT="
     extra_warnings
@@ -280,6 +285,7 @@
     mem_tracker
     spatial_resampling
     realtime_only
+    experimental
 "
 
 process_cmdline() {
@@ -287,6 +293,18 @@
         optval="${opt#*=}"
         case "$opt" in
         --disable-codecs) for c in ${CODECS}; do disable $c; done ;;
+        --enable-?*|--disable-?*)
+        eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
+        if echo "${EXPERIMENT_LIST}" | grep "^ *$option\$" >/dev/null; then
+            if enabled experimental; then
+                $action $option
+            else
+                log_echo "Ignoring $opt -- not in experimental mode."
+            fi
+        else
+            process_common_cmdline $opt
+        fi
+        ;;
         *) process_common_cmdline $opt
         ;;
         esac
--- a/ivfenc.c
+++ b/ivfenc.c
@@ -29,6 +29,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #endif
+#include "vpx_config.h"
 #include "vpx/vp8cx.h"
 #include "vpx_ports/mem_ops.h"
 #include "vpx_ports/vpx_timer.h"
@@ -42,6 +43,9 @@
     unsigned int             fourcc;
 } codecs[] =
 {
+#if CONFIG_EXPERIMENTAL && CONFIG_VP8_ENCODER
+    {"vp8x",  &vpx_codec_vp8x_cx_algo, 0x78385056},
+#endif
 #if CONFIG_VP8_ENCODER
     {"vp8",  &vpx_codec_vp8_cx_algo, 0x30385056},
 #endif
--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -174,8 +174,17 @@
 }
 void vp8_setup_version(VP8_COMMON *cm)
 {
-    switch (cm->version)
+    if (cm->version & 0x4)
     {
+        if (!CONFIG_EXPERIMENTAL)
+            vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+                               "Bitstream was created by an experimental "
+                               "encoder");        
+        cm->experimental = 1;
+    }
+    
+    switch (cm->version & 0x3)
+    {
     case 0:
         cm->no_lpf = 0;
         cm->simpler_lpf = 0;
@@ -199,13 +208,6 @@
         cm->simpler_lpf = 1;
         cm->use_bilinear_mc_filter = 1;
         cm->full_pixel = 1;
-        break;
-    default:
-        //4,5,6,7 are reserved for future use
-        cm->no_lpf = 0;
-        cm->simpler_lpf = 0;
-        cm->use_bilinear_mc_filter = 0;
-        cm->full_pixel = 0;
         break;
     }
 }
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -113,6 +113,7 @@
     int mode_info_stride;
 
     // prfile settings
+    int experimental;
     int mb_no_coeff_skip;
     int no_lpf;
     int simpler_lpf;
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -35,7 +35,7 @@
     unsigned int                arnr_max_frames;    /* alt_ref Noise Reduction Max Frame Count */
     unsigned int                arnr_strength;    /* alt_ref Noise Reduction Strength */
     unsigned int                arnr_type;        /* alt_ref filter type */
-
+    unsigned int                experimental;
 };
 
 struct extraconfig_map
@@ -65,6 +65,7 @@
             0, /* arnr_max_frames */
             0, /* arnr_strength */
             0, /* arnr_type*/
+            0,                          /* experimental mode */
         }
     }
 };
@@ -232,7 +233,8 @@
                                        struct vp8_extracfg vp8_cfg)
 {
     oxcf->multi_threaded         = cfg.g_threads;
-    oxcf->Version               = cfg.g_profile;
+    oxcf->Version               = cfg.g_profile;    
+    oxcf->Version              |= vp8_cfg.experimental? 0x4 : 0;
 
     oxcf->Width                 = cfg.g_w;
     oxcf->Height                = cfg.g_h;
@@ -453,7 +455,10 @@
     return res;
 #undef MAP
 }
-static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
+
+
+static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
+                                        int              experimental)
 {
     vpx_codec_err_t        res = VPX_DEC_OK;
     struct vpx_codec_alg_priv *priv;
@@ -495,6 +500,7 @@
 
             priv->vp8_cfg = extracfg_map[i].cfg;
             priv->vp8_cfg.pkt_list = &priv->pkt_list.head;
+            priv->vp8_cfg.experimental = experimental;
 
             priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2;
 
@@ -523,6 +529,21 @@
     return res;
 }
 
+
+static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
+{
+    return vp8e_common_init(ctx, 0);
+}
+
+
+#if CONFIG_EXPERIMENTAL
+static vpx_codec_err_t vp8e_exp_init(vpx_codec_ctx_t *ctx)
+{
+    return vp8e_common_init(ctx, 1);
+}
+#endif
+
+
 static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx)
 {
 
@@ -1091,6 +1112,36 @@
         vp8e_get_preview,
     } /* encoder functions */
 };
+
+
+#if CONFIG_EXPERIMENTAL
+vpx_codec_iface_t vpx_codec_vp8x_cx_algo =
+{
+    "VP8 Experimental Encoder" VERSION_STRING,
+    VPX_CODEC_INTERNAL_ABI_VERSION,
+    VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
+    /* vpx_codec_caps_t          caps; */
+    vp8e_exp_init,      /* vpx_codec_init_fn_t       init; */
+    vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
+    vp8e_ctf_maps,      /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
+    NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
+    NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
+    {
+        NOT_IMPLEMENTED,    /* vpx_codec_peek_si_fn_t    peek_si; */
+        NOT_IMPLEMENTED,    /* vpx_codec_get_si_fn_t     get_si; */
+        NOT_IMPLEMENTED,    /* vpx_codec_decode_fn_t     decode; */
+        NOT_IMPLEMENTED,    /* vpx_codec_frame_get_fn_t  frame_get; */
+    },
+    {
+        vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
+        vp8e_encode,        /* vpx_codec_encode_fn_t      encode; */
+        vp8e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
+        vp8e_set_config,
+        NOT_IMPLEMENTED,
+        vp8e_get_preview,
+    } /* encoder functions */
+};
+#endif
 
 
 /*
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -31,6 +31,16 @@
 extern vpx_codec_iface_t vpx_codec_vp8_cx_algo;
 
 
+#if CONFIG_EXPERIMENTAL
+/*!\brief Algorithm interface for VP8 experimental branch
+ *
+ * This interface provides the ability to encode using the "experimental"
+ * VP8 variant, which is bitstream incompatible with the default VP8 encoder.
+ */
+extern vpx_codec_iface_t vpx_codec_vp8x_cx_algo;
+#endif
+
+
 /*
  * Algorithm Flags
  */