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
diff --git a/configure b/configure
index d7d041c..8fa56fe 100755
--- 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
diff --git a/ivfenc.c b/ivfenc.c
index 4dc7082..1600e03 100644
--- 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
diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c
index 6384fac..12d83aa 100644
--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -174,7 +174,16 @@
}
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;
@@ -200,13 +209,6 @@
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;
}
}
void vp8_create_common(VP8_COMMON *oci)
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index 39eab24..94632da 100644
--- 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;
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 16ad678..32c5f3b 100644
--- 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)
{
@@ -1093,6 +1114,36 @@
};
+#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
+
+
/*
* BEGIN BACKWARDS COMPATIBILITY SHIM.
*/
diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h
index 0773edc..6a8cf65 100644
--- 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
*/