Merge "multi-res: force Key frame sychronization"
diff --git a/.mailmap b/.mailmap
index 41932e0..ba1279b 100644
--- a/.mailmap
+++ b/.mailmap
@@ -5,3 +5,4 @@
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
Alpha Lam <hclam@google.com> <hclam@chromium.org>
+Deb Mukherjee <debargha@google.com>
diff --git a/AUTHORS b/AUTHORS
index 62636c4..0937d5d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -31,9 +31,11 @@
Joshua Bleecher Snyder <josh@treelinelabs.com>
Justin Clift <justin@salasaga.org>
Justin Lebar <justin.lebar@gmail.com>
+KO Myung-Hun <komh@chollian.net>
Lou Quillio <louquillio@google.com>
Luca Barbato <lu_zero@gentoo.org>
Makoto Kato <makoto.kt@gmail.com>
+Marco Paniconi <marpan@google.com>
Martin Ettl <ettl.martin78@googlemail.com>
Michael Kohler <michaelkohler@live.com>
Mike Hommey <mhommey@mozilla.com>
@@ -43,6 +45,7 @@
Paul Wilkins <paulwilkins@google.com>
Pavol Rusnak <stick@gk2.sk>
Philip Jägenstedt <philipj@opera.com>
+Priit Laes <plaes@plaes.org>
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
Rafaël Carré <funman@videolan.org>
Ralph Giles <giles@xiph.org>
@@ -50,6 +53,7 @@
Scott LaVarnway <slavarnway@google.com>
Stefan Holmer <holmer@google.com>
Taekhyun Kim <takim@nvidia.com>
+Takanori MATSUURA <t.matsuu@gmail.com>
Tero Rintaluoma <teror@google.com>
Thijs Vermeir <thijsvermeir@gmail.com>
Timothy B. Terriberry <tterribe@xiph.org>
diff --git a/CHANGELOG b/CHANGELOG
index 0b4112e..dcb9f73 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,94 @@
-NOTE FOR NEXT RELEASE: PLEASE DOCUMENT API CHANGE TO NOISE SENSITIVITY FEATURE
-AND WARN PEOPLE THAT FOR NOW IT'S EITHER ON OR OFF
+2012-05-09 v1.1.0 "Eider"
+ This introduces a number of enhancements, mostly focused on real-time
+ encoding. In addition, it fixes a decoder bug (first introduced in
+ Duclair) so all users of that release are encouraged to upgrade.
+
+ - Upgrading:
+ This release is ABI and API compatible with Duclair (v1.0.0). Users
+ of older releases should refer to the Upgrading notes in this
+ document for that release.
+
+ This release introduces a new temporal denoiser, controlled by the
+ VP8E_SET_NOISE_SENSITIVITY control. The temporal denoiser does not
+ currently take a strength parameter, so the control is effectively
+ a boolean - zero (off) or non-zero (on). For compatibility with
+ existing applications, the values accepted are the same as those
+ for the spatial denoiser (0-6). The temporal denoiser is enabled
+ by default, and the older spatial denoiser may be restored by
+ configuring with --disable-temporal-denoising. The temporal denoiser
+ is more computationally intensive than the spatial one.
+
+ This release removes support for a legacy, decode only API that was
+ supported, but deprecated, at the initial release of libvpx
+ (v0.9.0). This is not expected to have any impact. If you are
+ impacted, you can apply a reversion to commit 2bf8fb58 locally.
+ Please update to the latest libvpx API if you are affected.
+
+ - Enhancements:
+ Adds a motion compensated temporal denoiser to the encoder, which
+ gives higher quality than the older spatial denoiser. (See above
+ for notes on upgrading).
+
+ In addition, support for new compilers and platforms were added,
+ including:
+ improved support for XCode
+ Android x86 NDK build
+ OS/2 support
+ SunCC support
+
+ Changing resolution with vpx_codec_enc_config_set() is now
+ supported. Previously, reinitializing the codec was required to
+ change the input resolution.
+
+ The vpxenc application has initial support for producing multiple
+ encodes from the same input in one call. Resizing is not yet
+ supported, but varying other codec parameters is. Use -- to
+ delineate output streams. Options persist from one stream to the
+ next.
+
+ Also, the vpxenc application will now use a keyframe interval of
+ 5 seconds by default. Use the --kf-max-dist option to override.
+
+ - Speed:
+ Decoder performance improved 2.5% versus Duclair. Encoder speed is
+ consistent with Duclair for most material. Two pass encoding of
+ slideshow-like material will see significant improvements.
+
+ Large realtime encoding speed gains at a small quality expense are
+ possible by configuring the on-the-fly bitpacking experiment with
+ --enable-onthefly-bitpacking. Realtime encoder can be up to 13%
+ faster (ARM) depending on the number of threads and bitrate
+ settings. This technique sees constant gain over the 5-16 speed
+ range. For VC style input the loss seen is up to 0.2dB. See commit
+ 52cf4dca for further details.
+
+ - Quality:
+ On the whole, quality is consistent with the Duclair release. Some
+ tweaks:
+
+ Reduced blockiness in easy sections by applying a penalty to
+ intra modes.
+
+ Improved quality of static sections (like slideshows) with
+ two pass encoding.
+
+ Improved keyframe sizing with multiple temporal layers
+
+ - Bug Fixes:
+ Corrected alt-ref contribution to frame rate for visible updates
+ to the alt-ref buffer. This affected applications making manual
+ usage of the frame reference flags, or temporal layers.
+
+ Additional constraints were added to disable multi-frame quality
+ enhancement (MFQE) in sections of the frame where there is motion.
+ (#392)
+
+ Fixed corruption issues when vpx_codec_enc_config_set() was called
+ with spatial resampling enabled.
+
+ Fixed a decoder error introduced in Duclair where the segmentation
+ map was not being reinitialized on keyframes (#378)
+
2012-01-27 v1.0.0 "Duclair"
Our fourth named release, focused on performance and features related to
diff --git a/build/make/configure.sh b/build/make/configure.sh
index 4ffef01..068ccdc 100755
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -549,7 +549,7 @@
process_common_toolchain() {
if [ -z "$toolchain" ]; then
- gcctarget="$(gcc -dumpmachine 2> /dev/null)"
+ gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
# detect tgt_isa
case "$gcctarget" in
@@ -588,6 +588,10 @@
tgt_isa=x86_64
tgt_os=darwin11
;;
+ *darwin12*)
+ tgt_isa=x86_64
+ tgt_os=darwin12
+ ;;
*mingw32*|*cygwin*)
[ -z "$tgt_isa" ] && tgt_isa=x86
tgt_os=win32
@@ -679,6 +683,10 @@
add_cflags "-mmacosx-version-min=10.7"
add_ldflags "-mmacosx-version-min=10.7"
;;
+ *-darwin12-*)
+ add_cflags "-mmacosx-version-min=10.8"
+ add_ldflags "-mmacosx-version-min=10.8"
+ ;;
esac
# Handle Solaris variants. Solaris 10 needs -lposix4
@@ -813,7 +821,8 @@
darwin*)
if [ -z "${sdk_path}" ]; then
- SDK_PATH=/Developer/Platforms/iPhoneOS.platform/Developer
+ SDK_PATH=`xcode-select -print-path 2> /dev/null`
+ SDK_PATH=${SDK_PATH}/Platforms/iPhoneOS.platform/Developer
else
SDK_PATH=${sdk_path}
fi
@@ -835,7 +844,7 @@
add_ldflags -arch_only ${tgt_isa}
if [ -z "${alt_libc}" ]; then
- alt_libc=${SDK_PATH}/SDKs/iPhoneOS5.0.sdk
+ alt_libc=${SDK_PATH}/SDKs/iPhoneOS5.1.sdk
fi
add_cflags "-isysroot ${alt_libc}"
@@ -958,7 +967,7 @@
esac
;;
gcc*)
- add_cflags -m${bits}
+ add_cflags -m${bits}
add_ldflags -m${bits}
link_with_cc=gcc
tune_cflags="-march="
diff --git a/configure b/configure
index 3fbc67e..2b1328d 100755
--- a/configure
+++ b/configure
@@ -109,6 +109,8 @@
all_platforms="${all_platforms} x86-darwin9-gcc"
all_platforms="${all_platforms} x86-darwin9-icc"
all_platforms="${all_platforms} x86-darwin10-gcc"
+all_platforms="${all_platforms} x86-darwin11-gcc"
+all_platforms="${all_platforms} x86-darwin12-gcc"
all_platforms="${all_platforms} x86-linux-gcc"
all_platforms="${all_platforms} x86-linux-icc"
all_platforms="${all_platforms} x86-os2-gcc"
@@ -120,6 +122,7 @@
all_platforms="${all_platforms} x86_64-darwin9-gcc"
all_platforms="${all_platforms} x86_64-darwin10-gcc"
all_platforms="${all_platforms} x86_64-darwin11-gcc"
+all_platforms="${all_platforms} x86_64-darwin12-gcc"
all_platforms="${all_platforms} x86_64-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc"
all_platforms="${all_platforms} x86_64-solaris-gcc"
@@ -128,6 +131,9 @@
all_platforms="${all_platforms} x86_64-win64-vs9"
all_platforms="${all_platforms} universal-darwin8-gcc"
all_platforms="${all_platforms} universal-darwin9-gcc"
+all_platforms="${all_platforms} universal-darwin10-gcc"
+all_platforms="${all_platforms} universal-darwin11-gcc"
+all_platforms="${all_platforms} universal-darwin12-gcc"
all_platforms="${all_platforms} generic-gnu"
# all_targets is a list of all targets that can be configured
@@ -493,11 +499,20 @@
case $toolchain in
universal-darwin*)
local darwin_ver=${tgt_os##darwin}
- fat_bin_archs="$fat_bin_archs ppc32-${tgt_os}-gcc"
- # Intel
- fat_bin_archs="$fat_bin_archs x86-${tgt_os}-${tgt_cc}"
- if [ $darwin_ver -gt 8 ]; then
+ # Snow Leopard (10.6/darwin10) dropped support for PPC
+ # Include PPC support for all prior versions
+ if [ $darwin_ver -lt 10 ]; then
+ fat_bin_archs="$fat_bin_archs ppc32-${tgt_os}-gcc"
+ fi
+
+ # Tiger (10.4/darwin8) brought support for x86
+ if [ $darwin_ver -ge 8 ]; then
+ fat_bin_archs="$fat_bin_archs x86-${tgt_os}-${tgt_cc}"
+ fi
+
+ # Leopard (10.5/darwin9) brought 64 bit support
+ if [ $darwin_ver -ge 9 ]; then
fat_bin_archs="$fat_bin_archs x86_64-${tgt_os}-${tgt_cc}"
fi
;;
@@ -513,6 +528,10 @@
check_add_cflags -Wpointer-arith
check_add_cflags -Wtype-limits
check_add_cflags -Wcast-qual
+ check_add_cflags -Wimplicit-function-declaration
+ check_add_cflags -Wuninitialized
+ check_add_cflags -Wunused-variable
+ check_add_cflags -Wunused-but-set-variable
enabled extra_warnings || check_add_cflags -Wno-unused-function
fi
diff --git a/docs.mk b/docs.mk
index 98332a2..cfe57ed 100644
--- a/docs.mk
+++ b/docs.mk
@@ -21,9 +21,6 @@
usage_dx.dox \
# Other doxy files sourced in Markdown
-TXT_DOX-$(CONFIG_VP8) += vp8_api1_migration.dox
-vp8_api1_migration.dox.DESC = VP8 API 1.x Migration
-
TXT_DOX = $(call enabled,TXT_DOX)
%.dox: %.txt
diff --git a/libs.mk b/libs.mk
index 0b14613..f241d07 100644
--- a/libs.mk
+++ b/libs.mk
@@ -35,9 +35,9 @@
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8cx.mk
CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS))
CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_CX_EXPORTS))
- CODEC_SRCS-yes += $(VP8_PREFIX)vp8cx.mk vpx/vp8.h vpx/vp8cx.h vpx/vp8e.h
+ CODEC_SRCS-yes += $(VP8_PREFIX)vp8cx.mk vpx/vp8.h vpx/vp8cx.h
CODEC_SRCS-$(ARCH_ARM) += $(VP8_PREFIX)vp8cx_arm.mk
- INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8e.h include/vpx/vp8cx.h
+ INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
CODEC_DOC_SECTIONS += vp8 vp8_encoder
@@ -116,7 +116,6 @@
INSTALL-LIBS-yes += include/vpx/vpx_codec_impl_top.h
INSTALL-LIBS-yes += include/vpx/vpx_codec_impl_bottom.h
INSTALL-LIBS-$(CONFIG_DECODERS) += include/vpx/vpx_decoder.h
-INSTALL-LIBS-$(CONFIG_DECODERS) += include/vpx/vpx_decoder_compat.h
INSTALL-LIBS-$(CONFIG_ENCODERS) += include/vpx/vpx_encoder.h
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
ifeq ($(CONFIG_MSVS),yes)
@@ -235,7 +234,7 @@
$(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@
$(qexec)echo 'prefix=$(PREFIX)' >> $@
$(qexec)echo 'exec_prefix=$${prefix}' >> $@
- $(qexec)echo 'libdir=$${prefix}/lib' >> $@
+ $(qexec)echo 'libdir=$${prefix}/$(LIBSUBDIR)' >> $@
$(qexec)echo 'includedir=$${prefix}/include' >> $@
$(qexec)echo '' >> $@
$(qexec)echo 'Name: vpx' >> $@
diff --git a/third_party/libyuv/source/scale.c b/third_party/libyuv/source/scale.c
index 930a7ae..c142a17 100644
--- a/third_party/libyuv/source/scale.c
+++ b/third_party/libyuv/source/scale.c
@@ -60,7 +60,7 @@
#if defined(__ARM_NEON__) && !defined(YUV_DISABLE_ASM)
#define HAS_SCALEROWDOWN2_NEON
-void ScaleRowDown2_NEON(const uint8* src_ptr, int /* src_stride */,
+void ScaleRowDown2_NEON(const uint8* src_ptr, int src_stride,
uint8* dst, int dst_width) {
asm volatile (
"1: \n"
@@ -102,7 +102,7 @@
}
#define HAS_SCALEROWDOWN4_NEON
-static void ScaleRowDown4_NEON(const uint8* src_ptr, int /* src_stride */,
+static void ScaleRowDown4_NEON(const uint8* src_ptr, int src_stride,
uint8* dst_ptr, int dst_width) {
asm volatile (
"1: \n"
@@ -160,7 +160,7 @@
// Down scale from 4 to 3 pixels. Use the neon multilane read/write
// to load up the every 4th pixel into a 4 different registers.
// Point samples 32 pixels to 24 pixels.
-static void ScaleRowDown34_NEON(const uint8* src_ptr, int /* src_stride */,
+static void ScaleRowDown34_NEON(const uint8* src_ptr, int src_stride,
uint8* dst_ptr, int dst_width) {
asm volatile (
"1: \n"
@@ -284,7 +284,7 @@
65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18 };
// 32 -> 12
-static void ScaleRowDown38_NEON(const uint8* src_ptr, int,
+static void ScaleRowDown38_NEON(const uint8* src_ptr, int src_stride,
uint8* dst_ptr, int dst_width) {
asm volatile (
"vld1.u8 {q3}, [%3] \n"
diff --git a/tools/ftfy.sh b/tools/ftfy.sh
index 95fd397..c5cfdea 100755
--- a/tools/ftfy.sh
+++ b/tools/ftfy.sh
@@ -34,7 +34,7 @@
--align-pointer=name \
--indent-preprocessor --convert-tabs --indent-labels \
--suffix=none --quiet "$@"
- sed -i 's/[[:space:]]\{1,\},/,/g' "$@"
+ sed -i "" 's/[[:space:]]\{1,\},/,/g' "$@"
}
diff --git a/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm b/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm
index d753ad1..e7a3ed1 100644
--- a/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm
+++ b/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm
@@ -9,6 +9,11 @@
;
+bilinear_taps_coeff
+ DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+;-----------------
+
EXPORT |vp8_sub_pixel_variance16x16_neon_func|
ARM
REQUIRE8
@@ -27,7 +32,7 @@
|vp8_sub_pixel_variance16x16_neon_func| PROC
push {r4-r6, lr}
- ldr r12, _BilinearTaps_coeff_
+ adr r12, bilinear_taps_coeff
ldr r4, [sp, #16] ;load *dst_ptr from stack
ldr r5, [sp, #20] ;load dst_pixels_per_line from stack
ldr r6, [sp, #24] ;load *sse from stack
@@ -415,11 +420,4 @@
ENDP
-;-----------------
-
-_BilinearTaps_coeff_
- DCD bilinear_taps_coeff
-bilinear_taps_coeff
- DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
-
END
diff --git a/vp8/common/arm/neon/vp8_subpixelvariance8x8_neon.asm b/vp8/common/arm/neon/vp8_subpixelvariance8x8_neon.asm
index cc7ae52..f6b6847 100644
--- a/vp8/common/arm/neon/vp8_subpixelvariance8x8_neon.asm
+++ b/vp8/common/arm/neon/vp8_subpixelvariance8x8_neon.asm
@@ -27,7 +27,7 @@
|vp8_sub_pixel_variance8x8_neon| PROC
push {r4-r5, lr}
- ldr r12, _BilinearTaps_coeff_
+ adr r12, bilinear_taps_coeff
ldr r4, [sp, #12] ;load *dst_ptr from stack
ldr r5, [sp, #16] ;load dst_pixels_per_line from stack
ldr lr, [sp, #20] ;load *sse from stack
@@ -216,8 +216,6 @@
;-----------------
-_BilinearTaps_coeff_
- DCD bilinear_taps_coeff
bilinear_taps_coeff
DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
diff --git a/vp8/common/arm/variance_arm.c b/vp8/common/arm/variance_arm.c
index 41d5eb3..891d767 100644
--- a/vp8/common/arm/variance_arm.c
+++ b/vp8/common/arm/variance_arm.c
@@ -97,6 +97,17 @@
#if HAVE_NEON
+extern unsigned int vp8_sub_pixel_variance16x16_neon_func
+(
+ const unsigned char *src_ptr,
+ int src_pixels_per_line,
+ int xoffset,
+ int yoffset,
+ const unsigned char *dst_ptr,
+ int dst_pixels_per_line,
+ unsigned int *sse
+);
+
unsigned int vp8_sub_pixel_variance16x16_neon
(
const unsigned char *src_ptr,
diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
index 0f7f00c..091e4c7 100644
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -169,4 +169,3 @@
vpx_memcpy(p, vp8_bmode_prob, sizeof(vp8_bmode_prob));
}
-
diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h
index aa5c600..3a2fa84 100644
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -73,7 +73,6 @@
extern const vp8_prob vp8_kf_uv_mode_prob[VP8_UV_MODES-1];
extern const vp8_prob vp8_kf_ymode_prob[VP8_YMODES-1];
-
void vp8_init_mbmode_probs(VP8_COMMON *x);
void vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]);
void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1]);
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
index 39660ab..2a30166 100644
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -82,6 +82,58 @@
}
#endif
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+static void once(void (*func)(void))
+{
+ static pthread_once_t lock = PTHREAD_ONCE_INIT;
+ pthread_once(&lock, func);
+}
+
+
+#elif defined(_WIN32)
+static void once(void (*func)(void))
+{
+ /* Using a static initializer here rather than InitializeCriticalSection()
+ * since there's no race-free context in which to execute it. Protecting
+ * it with an atomic op like InterlockedCompareExchangePointer introduces
+ * an x86 dependency, and InitOnceExecuteOnce requires Vista.
+ */
+ static CRITICAL_SECTION lock = {(void *)-1, -1, 0, 0, 0, 0};
+ static int done;
+
+ EnterCriticalSection(&lock);
+
+ if (!done)
+ {
+ func();
+ done = 1;
+ }
+
+ LeaveCriticalSection(&lock);
+}
+
+
+#else
+/* No-op version that performs no synchronization. vpx_rtcd() is idempotent,
+ * so as long as your platform provides atomic loads/stores of pointers
+ * no synchronization is strictly necessary.
+ */
+
+static void once(void (*func)(void))
+{
+ static int done;
+
+ if(!done)
+ {
+ func();
+ done = 1;
+ }
+}
+#endif
+
+
void vp8_machine_specific_config(VP8_COMMON *ctx)
{
#if CONFIG_MULTITHREAD
@@ -94,5 +146,5 @@
ctx->cpu_caps = x86_simd_caps();
#endif
- vpx_rtcd();
+ once(vpx_rtcd);
}
diff --git a/vp8/common/mbpitch.c b/vp8/common/mbpitch.c
index 32025fa..32e1b66 100644
--- a/vp8/common/mbpitch.c
+++ b/vp8/common/mbpitch.c
@@ -11,45 +11,6 @@
#include "blockd.h"
-typedef enum
-{
- PRED = 0,
- DEST = 1
-} BLOCKSET;
-
-static void setup_macroblock(MACROBLOCKD *x, BLOCKSET bs)
-{
- int block;
-
- unsigned char **y, **u, **v;
-
- if (bs == DEST)
- {
- y = &x->dst.y_buffer;
- u = &x->dst.u_buffer;
- v = &x->dst.v_buffer;
- }
- else
- {
- y = &x->pre.y_buffer;
- u = &x->pre.u_buffer;
- v = &x->pre.v_buffer;
- }
-
- for (block = 0; block < 16; block++) /* y blocks */
- {
- x->block[block].offset =
- (block >> 2) * 4 * x->dst.y_stride + (block & 3) * 4;
- }
-
- for (block = 16; block < 20; block++) /* U and V blocks */
- {
- x->block[block+4].offset =
- x->block[block].offset =
- ((block - 16) >> 1) * 4 * x->dst.uv_stride + (block & 1) * 4;
- }
-}
-
void vp8_setup_block_dptrs(MACROBLOCKD *x)
{
int r, c;
@@ -90,8 +51,18 @@
void vp8_build_block_doffsets(MACROBLOCKD *x)
{
+ int block;
- /* handle the destination pitch features */
- setup_macroblock(x, DEST);
- setup_macroblock(x, PRED);
+ for (block = 0; block < 16; block++) /* y blocks */
+ {
+ x->block[block].offset =
+ (block >> 2) * 4 * x->dst.y_stride + (block & 3) * 4;
+ }
+
+ for (block = 16; block < 20; block++) /* U and V blocks */
+ {
+ x->block[block+4].offset =
+ x->block[block].offset =
+ ((block - 16) >> 1) * 4 * x->dst.uv_stride + (block & 1) * 4;
+ }
}
diff --git a/vp8/common/mfqe.c b/vp8/common/mfqe.c
index 1c5eadf..ca67e91 100644
--- a/vp8/common/mfqe.c
+++ b/vp8/common/mfqe.c
@@ -118,7 +118,7 @@
#define USE_SSD
static void multiframe_quality_enhance_block
(
- int blksize, /* Currently only values supported are 16, 8, 4 */
+ int blksize, /* Currently only values supported are 16, 8 */
int qcurr,
int qprev,
unsigned char *y,
@@ -140,9 +140,7 @@
int uvblksize = blksize >> 1;
int qdiff = qcurr - qprev;
- int i, j;
- unsigned char *yp;
- unsigned char *ydp;
+ int i;
unsigned char *up;
unsigned char *udp;
unsigned char *vp;
@@ -167,7 +165,7 @@
vsad = (vp8_sad8x8(v, uv_stride, vd, uvd_stride, INT_MAX)+32)>>6;
#endif
}
- else if (blksize == 8)
+ else /* if (blksize == 8) */
{
actd = (vp8_variance8x8(yd, yd_stride, VP8_ZEROS, 0, &sse)+32)>>6;
act = (vp8_variance8x8(y, y_stride, VP8_ZEROS, 0, &sse)+32)>>6;
diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h
index 500dff0..2c8188a 100644
--- a/vp8/common/onyx.h
+++ b/vp8/common/onyx.h
@@ -106,7 +106,7 @@
int Width; // width of data passed to the compressor
int Height; // height of data passed to the compressor
struct vpx_rational timebase;
- int target_bandwidth; // bandwidth to be used in kilobits per second
+ unsigned int target_bandwidth; // bandwidth to be used in kilobits per second
int noise_sensitivity; // parameter used for applying pre processing blur: recommendation 0
int Sharpness; // parameter used for sharpening output: recommendation 0:
@@ -207,10 +207,10 @@
// Temporal scaling parameters
unsigned int number_of_layers;
- unsigned int target_bitrate[MAX_PERIODICITY];
- unsigned int rate_decimator[MAX_PERIODICITY];
+ unsigned int target_bitrate[VPX_TS_MAX_PERIODICITY];
+ unsigned int rate_decimator[VPX_TS_MAX_PERIODICITY];
unsigned int periodicity;
- unsigned int layer_id[MAX_PERIODICITY];
+ unsigned int layer_id[VPX_TS_MAX_PERIODICITY];
#if CONFIG_MULTI_RES_ENCODING
/* Number of total resolutions encoded */
diff --git a/vp8/common/rtcd_defs.sh b/vp8/common/rtcd_defs.sh
index 69bd7b6..76f8d5a 100644
--- a/vp8/common/rtcd_defs.sh
+++ b/vp8/common/rtcd_defs.sh
@@ -129,6 +129,7 @@
prototype void vp8_build_intra_predictors_mbuv_s "struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride"
specialize vp8_build_intra_predictors_mbuv_s sse2 ssse3
+prototype void vp8_intra4x4_predict_d "unsigned char *above, unsigned char *left, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left"
prototype void vp8_intra4x4_predict "unsigned char *src, int src_stride, int b_mode, unsigned char *dst, int dst_stride"
specialize vp8_intra4x4_predict media
vp8_intra4x4_predict_media=vp8_intra4x4_predict_armv6
@@ -500,6 +501,12 @@
prototype void vp8_yv12_copy_partial_frame "struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc"
specialize vp8_yv12_copy_partial_frame neon
+#
+# Denoiser filter
+#
+prototype void vp8_denoiser_filter "struct yv12_buffer_config* mc_running_avg, struct yv12_buffer_config* running_avg, struct macroblock* signal, unsigned int motion_magnitude2, int y_offset, int uv_offset"
+specialize vp8_denoiser_filter sse2
+
# End of encoder only functions
fi
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index d11933e..48824ce 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -53,7 +53,7 @@
}
}
-void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd)
+void vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd)
{
int i;
int QIndex;
@@ -117,7 +117,7 @@
mode = xd->mode_info_context->mbmi.mode;
if (xd->segmentation_enabled)
- mb_init_dequantizer(pbi, xd);
+ vp8_mb_init_dequantizer(pbi, xd);
#if CONFIG_ERROR_CONCEALMENT
@@ -507,7 +507,7 @@
{
VP8_COMMON* pc = &pbi->common;
const unsigned char *partition_size_ptr = token_part_sizes + i * 3;
- unsigned int partition_size;
+ unsigned int partition_size = 0;
ptrdiff_t bytes_left = fragment_end - fragment_start;
/* Calculate the length of this partition. The last partition
* size is implicit. If the partition size can't be read, then
@@ -549,8 +549,8 @@
{
vp8_reader *bool_decoder = &pbi->bc2;
unsigned int partition_idx;
- int fragment_idx;
- int num_token_partitions;
+ unsigned int fragment_idx;
+ unsigned int num_token_partitions;
const unsigned char *first_fragment_end = pbi->fragments[0] +
pbi->fragment_sizes[0];
@@ -997,7 +997,7 @@
vp8cx_init_de_quantizer(pbi);
/* MB level dequantizer setup */
- mb_init_dequantizer(pbi, &pbi->mb);
+ vp8_mb_init_dequantizer(pbi, &pbi->mb);
}
/* Determine if the golden frame or ARF buffer should be updated and how.
@@ -1157,7 +1157,7 @@
#if CONFIG_MULTITHREAD
if (pbi->b_multithreaded_rd && pc->multi_token_partition != ONE_PARTITION)
{
- int i;
+ unsigned int i;
vp8mt_decode_mb_rows(pbi, xd);
vp8_yv12_extend_frame_borders(&pc->yv12_fb[pc->new_fb_idx]); /*cm->frame_to_show);*/
for (i = 0; i < pbi->decoding_thread_count; ++i)
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 8d9cca3..50d609d 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -303,7 +303,7 @@
if (pbi->num_fragments == 0)
{
/* New frame, reset fragment pointers and sizes */
- vpx_memset(pbi->fragments, 0, sizeof(pbi->fragments));
+ vpx_memset((void*)pbi->fragments, 0, sizeof(pbi->fragments));
vpx_memset(pbi->fragment_sizes, 0, sizeof(pbi->fragment_sizes));
}
if (pbi->input_fragments && !(source == NULL && size == 0))
diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h
index f2b9c60..8a5b8d5 100644
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -61,7 +61,7 @@
volatile int b_multithreaded_rd;
int max_threads;
int current_mb_col_main;
- int decoding_thread_count;
+ unsigned int decoding_thread_count;
int allocated_decoding_thread_count;
int mt_baseline_filter_level[MAX_MB_SEGMENTS];
diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c
index 25dc6fe..a51ca64 100644
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -28,7 +28,7 @@
#include "error_concealment.h"
#endif
-extern void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
+extern void vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
{
@@ -106,7 +106,7 @@
mode = xd->mode_info_context->mbmi.mode;
if (xd->segmentation_enabled)
- mb_init_dequantizer(pbi, xd);
+ vp8_mb_init_dequantizer(pbi, xd);
#if CONFIG_ERROR_CONCEALMENT
@@ -654,7 +654,7 @@
void vp8_decoder_create_threads(VP8D_COMP *pbi)
{
int core_count = 0;
- int ithread;
+ unsigned int ithread;
pbi->b_multithreaded_rd = 0;
pbi->allocated_decoding_thread_count = 0;
@@ -870,7 +870,8 @@
void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
{
VP8_COMMON *pc = &pbi->common;
- int i;
+ unsigned int i;
+ int j;
int filter_level = pc->filter_level;
@@ -881,19 +882,19 @@
vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
- for (i=1; i<pc->mb_rows; i++)
+ for (j=1; j<pc->mb_rows; j++)
{
- vpx_memset(pbi->mt_yabove_row[i] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
- vpx_memset(pbi->mt_uabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
- vpx_memset(pbi->mt_vabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
+ vpx_memset(pbi->mt_yabove_row[j] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
+ vpx_memset(pbi->mt_uabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
+ vpx_memset(pbi->mt_vabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
}
/* Set left_col to 129 initially */
- for (i=0; i<pc->mb_rows; i++)
+ for (j=0; j<pc->mb_rows; j++)
{
- vpx_memset(pbi->mt_yleft_col[i], (unsigned char)129, 16);
- vpx_memset(pbi->mt_uleft_col[i], (unsigned char)129, 8);
- vpx_memset(pbi->mt_vleft_col[i], (unsigned char)129, 8);
+ vpx_memset(pbi->mt_yleft_col[j], (unsigned char)129, 16);
+ vpx_memset(pbi->mt_uleft_col[j], (unsigned char)129, 8);
+ vpx_memset(pbi->mt_vleft_col[j], (unsigned char)129, 8);
}
/* Initialize the loop filter for this frame. */
diff --git a/vp8/encoder/arm/neon/fastquantizeb_neon.asm b/vp8/encoder/arm/neon/fastquantizeb_neon.asm
index c970cb7..1430588 100644
--- a/vp8/encoder/arm/neon/fastquantizeb_neon.asm
+++ b/vp8/encoder/arm/neon/fastquantizeb_neon.asm
@@ -98,7 +98,7 @@
vmul.s16 q2, q6, q4 ; x * Dequant
vmul.s16 q3, q7, q5
- ldr r0, _inv_zig_zag_ ; load ptr of inverse zigzag table
+ adr r0, inv_zig_zag ; load ptr of inverse zigzag table
vceq.s16 q8, q8 ; set q8 to all 1
@@ -181,7 +181,7 @@
vadd.s16 q12, q14 ; x + Round
vadd.s16 q13, q15
- ldr r0, _inv_zig_zag_ ; load ptr of inverse zigzag table
+ adr r0, inv_zig_zag ; load ptr of inverse zigzag table
vqdmulh.s16 q12, q8 ; y = ((Round+abs(z)) * Quant) >> 16
vqdmulh.s16 q13, q9
@@ -247,9 +247,6 @@
ENDP
; default inverse zigzag table is defined in vp8/common/entropy.c
-_inv_zig_zag_
- DCD inv_zig_zag
-
ALIGN 16 ; enable use of @128 bit aligned loads
inv_zig_zag
DCW 0x0001, 0x0002, 0x0006, 0x0007
diff --git a/vp8/encoder/arm/neon/picklpf_arm.c b/vp8/encoder/arm/neon/picklpf_arm.c
index 6610d2d..ec8071e 100644
--- a/vp8/encoder/arm/neon/picklpf_arm.c
+++ b/vp8/encoder/arm/neon/picklpf_arm.c
@@ -22,11 +22,9 @@
unsigned char *src_y, *dst_y;
int yheight;
int ystride;
- int border;
int yoffset;
int linestocopy;
- border = src_ybc->border;
yheight = src_ybc->y_height;
ystride = src_ybc->y_stride;
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 6ff40b1..d7cd5a9 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -521,12 +521,11 @@
const MV_CONTEXT *mvc = pc->fc.mvc;
- MODE_INFO *m = pc->mi, *ms;
+ MODE_INFO *m = pc->mi;
const int mis = pc->mode_info_stride;
int mb_row = -1;
int prob_skip_false = 0;
- ms = pc->mi - 1;
cpi->mb.partition_info = cpi->mb.pi;
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index 1be1021..4ecbf1f 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -108,7 +108,7 @@
int skip;
- int encode_breakout;
+ unsigned int encode_breakout;
//char * gf_active_ptr;
signed char *gf_active_ptr;
diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c
index d487065..45d54ee 100644
--- a/vp8/encoder/denoising.c
+++ b/vp8/encoder/denoising.c
@@ -15,160 +15,238 @@
#include "vpx_mem/vpx_mem.h"
#include "vpx_rtcd.h"
-const unsigned int NOISE_MOTION_THRESHOLD = 20*20;
-const unsigned int NOISE_DIFF2_THRESHOLD = 75;
+
+static const unsigned int NOISE_MOTION_THRESHOLD = 20 * 20;
// SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming var(noise) ~= 100.
-const unsigned int SSE_DIFF_THRESHOLD = 16*16*20;
-const unsigned int SSE_THRESHOLD = 16*16*40;
+static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20;
+static const unsigned int SSE_THRESHOLD = 16 * 16 * 40;
-static uint8_t blend(uint8_t state, uint8_t sample, uint8_t factor_q8)
-{
- return (uint8_t)(
- (((uint16_t)factor_q8 * ((uint16_t)state) + // Q8
- (uint16_t)(256 - factor_q8) * ((uint16_t)sample)) + 128) // Q8
- >> 8);
-}
-static unsigned int denoiser_motion_compensate(YV12_BUFFER_CONFIG* src,
- YV12_BUFFER_CONFIG* dst,
- MACROBLOCK* x,
- unsigned int best_sse,
- unsigned int zero_mv_sse,
- int recon_yoffset,
- int recon_uvoffset)
+static unsigned int denoiser_motion_compensate(YV12_BUFFER_CONFIG *src,
+ YV12_BUFFER_CONFIG *dst,
+ MACROBLOCK *x,
+ unsigned int best_sse,
+ unsigned int zero_mv_sse,
+ int recon_yoffset,
+ int recon_uvoffset)
{
- MACROBLOCKD filter_xd = x->e_mbd;
- int mv_col;
- int mv_row;
- int sse_diff = zero_mv_sse - best_sse;
- // Compensate the running average.
- filter_xd.pre.y_buffer = src->y_buffer + recon_yoffset;
- filter_xd.pre.u_buffer = src->u_buffer + recon_uvoffset;
- filter_xd.pre.v_buffer = src->v_buffer + recon_uvoffset;
- // Write the compensated running average to the destination buffer.
- filter_xd.dst.y_buffer = dst->y_buffer + recon_yoffset;
- filter_xd.dst.u_buffer = dst->u_buffer + recon_uvoffset;
- filter_xd.dst.v_buffer = dst->v_buffer + recon_uvoffset;
- // Use the best MV for the compensation.
- filter_xd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
- filter_xd.mode_info_context->mbmi.mode = filter_xd.best_sse_inter_mode;
- filter_xd.mode_info_context->mbmi.mv = filter_xd.best_sse_mv;
- filter_xd.mode_info_context->mbmi.need_to_clamp_mvs =
- filter_xd.need_to_clamp_best_mvs;
- mv_col = filter_xd.best_sse_mv.as_mv.col;
- mv_row = filter_xd.best_sse_mv.as_mv.row;
- if (filter_xd.mode_info_context->mbmi.mode <= B_PRED ||
- (mv_row*mv_row + mv_col*mv_col <= NOISE_MOTION_THRESHOLD &&
- sse_diff < SSE_DIFF_THRESHOLD))
- {
- // Handle intra blocks as referring to last frame with zero motion and
- // let the absolute pixel difference affect the filter factor.
- // Also consider small amount of motion as being random walk due to noise,
- // if it doesn't mean that we get a much bigger error.
- // Note that any changes to the mode info only affects the denoising.
+ MACROBLOCKD filter_xd = x->e_mbd;
+ int mv_col;
+ int mv_row;
+ int sse_diff = zero_mv_sse - best_sse;
+ // Compensate the running average.
+ filter_xd.pre.y_buffer = src->y_buffer + recon_yoffset;
+ filter_xd.pre.u_buffer = src->u_buffer + recon_uvoffset;
+ filter_xd.pre.v_buffer = src->v_buffer + recon_uvoffset;
+ // Write the compensated running average to the destination buffer.
+ filter_xd.dst.y_buffer = dst->y_buffer + recon_yoffset;
+ filter_xd.dst.u_buffer = dst->u_buffer + recon_uvoffset;
+ filter_xd.dst.v_buffer = dst->v_buffer + recon_uvoffset;
+ // Use the best MV for the compensation.
filter_xd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
- filter_xd.mode_info_context->mbmi.mode = ZEROMV;
- filter_xd.mode_info_context->mbmi.mv.as_int = 0;
- x->e_mbd.best_sse_inter_mode = ZEROMV;
- x->e_mbd.best_sse_mv.as_int = 0;
- best_sse = zero_mv_sse;
- }
- if (!x->skip)
- {
- vp8_build_inter_predictors_mb(&filter_xd);
- }
- else
- {
- vp8_build_inter16x16_predictors_mb(&filter_xd,
- filter_xd.dst.y_buffer,
- filter_xd.dst.u_buffer,
- filter_xd.dst.v_buffer,
- filter_xd.dst.y_stride,
- filter_xd.dst.uv_stride);
- }
- return best_sse;
-}
+ filter_xd.mode_info_context->mbmi.mode = filter_xd.best_sse_inter_mode;
+ filter_xd.mode_info_context->mbmi.mv = filter_xd.best_sse_mv;
+ filter_xd.mode_info_context->mbmi.need_to_clamp_mvs =
+ filter_xd.need_to_clamp_best_mvs;
+ mv_col = filter_xd.best_sse_mv.as_mv.col;
+ mv_row = filter_xd.best_sse_mv.as_mv.row;
-static void denoiser_filter(YV12_BUFFER_CONFIG* mc_running_avg,
- YV12_BUFFER_CONFIG* running_avg,
- MACROBLOCK* signal,
- unsigned int motion_magnitude2,
- int y_offset,
- int uv_offset)
-{
- unsigned char* sig = signal->thismb;
- int sig_stride = 16;
- unsigned char* mc_running_avg_y = mc_running_avg->y_buffer + y_offset;
- int mc_avg_y_stride = mc_running_avg->y_stride;
- unsigned char* running_avg_y = running_avg->y_buffer + y_offset;
- int avg_y_stride = running_avg->y_stride;
- int r, c;
- for (r = 0; r < 16; r++)
- {
- for (c = 0; c < 16; c++)
+ if (filter_xd.mode_info_context->mbmi.mode <= B_PRED ||
+ (mv_row *mv_row + mv_col *mv_col <= NOISE_MOTION_THRESHOLD &&
+ sse_diff < SSE_DIFF_THRESHOLD))
{
- int diff;
- int absdiff = 0;
- unsigned int filter_coefficient;
- absdiff = sig[c] - mc_running_avg_y[c];
- absdiff = absdiff > 0 ? absdiff : -absdiff;
- assert(absdiff >= 0 && absdiff < 256);
- filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3));
- // Allow some additional filtering of static blocks, or blocks with very
- // small motion vectors.
- filter_coefficient += filter_coefficient / (3 + (motion_magnitude2 >> 3));
- filter_coefficient = filter_coefficient > 255 ? 255 : filter_coefficient;
-
- running_avg_y[c] = blend(mc_running_avg_y[c], sig[c], filter_coefficient);
- diff = sig[c] - running_avg_y[c];
-
- if (diff * diff < NOISE_DIFF2_THRESHOLD)
- {
- // Replace with mean to suppress the noise.
- sig[c] = running_avg_y[c];
- }
- else
- {
- // Replace the filter state with the signal since the change in this
- // pixel isn't classified as noise.
- running_avg_y[c] = sig[c];
- }
+ // Handle intra blocks as referring to last frame with zero motion and
+ // let the absolute pixel difference affect the filter factor.
+ // Also consider small amount of motion as being random walk due to
+ // noise, if it doesn't mean that we get a much bigger error.
+ // Note that any changes to the mode info only affects the denoising.
+ filter_xd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
+ filter_xd.mode_info_context->mbmi.mode = ZEROMV;
+ filter_xd.mode_info_context->mbmi.mv.as_int = 0;
+ x->e_mbd.best_sse_inter_mode = ZEROMV;
+ x->e_mbd.best_sse_mv.as_int = 0;
+ best_sse = zero_mv_sse;
}
- sig += sig_stride;
- mc_running_avg_y += mc_avg_y_stride;
- running_avg_y += avg_y_stride;
- }
+
+ if (!x->skip)
+ {
+ vp8_build_inter_predictors_mb(&filter_xd);
+ }
+ else
+ {
+ vp8_build_inter16x16_predictors_mb(&filter_xd,
+ filter_xd.dst.y_buffer,
+ filter_xd.dst.u_buffer,
+ filter_xd.dst.v_buffer,
+ filter_xd.dst.y_stride,
+ filter_xd.dst.uv_stride);
+ }
+
+ return best_sse;
}
+// The filtering coefficients used for denoizing are adjusted for static
+// blocks, or blocks with very small motion vectors. This is done through
+// the motion magnitude parameter.
+//
+// There are currently 2048 possible mapping from absolute difference to
+// filter coefficient depending on the motion magnitude. Each mapping is
+// in a LUT table. All these tables are staticly allocated but they are only
+// filled on their first use.
+//
+// Each entry is a pair of 16b values, the coefficient and its complement
+// to 256. Each of these value should only be 8b but they are 16b wide to
+// avoid slow partial register manipulations.
+enum {num_motion_magnitude_adjustments = 2048};
+
+static union coeff_pair filter_coeff_LUT[num_motion_magnitude_adjustments][256];
+static uint8_t filter_coeff_LUT_initialized[num_motion_magnitude_adjustments] =
+ { 0 };
+
+
+union coeff_pair *vp8_get_filter_coeff_LUT(unsigned int motion_magnitude)
+{
+ union coeff_pair *LUT;
+ unsigned int motion_magnitude_adjustment = motion_magnitude >> 3;
+
+ if (motion_magnitude_adjustment >= num_motion_magnitude_adjustments)
+ {
+ motion_magnitude_adjustment = num_motion_magnitude_adjustments - 1;
+ }
+
+ LUT = filter_coeff_LUT[motion_magnitude_adjustment];
+
+ if (!filter_coeff_LUT_initialized[motion_magnitude_adjustment])
+ {
+ int absdiff;
+
+ for (absdiff = 0; absdiff < 256; ++absdiff)
+ {
+ unsigned int filter_coefficient;
+ filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3));
+ filter_coefficient += filter_coefficient /
+ (3 + motion_magnitude_adjustment);
+
+ if (filter_coefficient > 255)
+ {
+ filter_coefficient = 255;
+ }
+
+ LUT[absdiff].as_short[0] = filter_coefficient ;
+ LUT[absdiff].as_short[1] = 256 - filter_coefficient;
+ }
+
+ filter_coeff_LUT_initialized[motion_magnitude_adjustment] = 1;
+ }
+
+ return LUT;
+}
+
+
+
+void vp8_denoiser_filter_c(YV12_BUFFER_CONFIG *mc_running_avg,
+ YV12_BUFFER_CONFIG *running_avg, MACROBLOCK *signal,
+ unsigned int motion_magnitude, int y_offset,
+ int uv_offset)
+{
+ unsigned char *sig = signal->thismb;
+ int sig_stride = 16;
+ unsigned char *mc_running_avg_y = mc_running_avg->y_buffer + y_offset;
+ int mc_avg_y_stride = mc_running_avg->y_stride;
+ unsigned char *running_avg_y = running_avg->y_buffer + y_offset;
+ int avg_y_stride = running_avg->y_stride;
+ const union coeff_pair *LUT = vp8_get_filter_coeff_LUT(motion_magnitude);
+ int r, c;
+
+ for (r = 0; r < 16; ++r)
+ {
+ // Calculate absolute differences
+ unsigned char abs_diff[16];
+
+ union coeff_pair filter_coefficient[16];
+
+ for (c = 0; c < 16; ++c)
+ {
+ int absdiff = sig[c] - mc_running_avg_y[c];
+ absdiff = absdiff > 0 ? absdiff : -absdiff;
+ abs_diff[c] = absdiff;
+ }
+
+ // Use LUT to get filter coefficients (two 16b value; f and 256-f)
+ for (c = 0; c < 16; ++c)
+ {
+ filter_coefficient[c] = LUT[abs_diff[c]];
+ }
+
+ // Filtering...
+ for (c = 0; c < 16; ++c)
+ {
+ const uint16_t state = (uint16_t)(mc_running_avg_y[c]);
+ const uint16_t sample = (uint16_t)(sig[c]);
+
+ running_avg_y[c] = (filter_coefficient[c].as_short[0] * state +
+ filter_coefficient[c].as_short[1] * sample + 128) >> 8;
+ }
+
+ // Depending on the magnitude of the difference between the signal and
+ // filtered version, either replace the signal by the filtered one or
+ // update the filter state with the signal when the change in a pixel
+ // isn't classified as noise.
+ for (c = 0; c < 16; ++c)
+ {
+ const int diff = sig[c] - running_avg_y[c];
+
+ if (diff * diff < NOISE_DIFF2_THRESHOLD)
+ {
+ sig[c] = running_avg_y[c];
+ }
+ else
+ {
+ running_avg_y[c] = sig[c];
+ }
+ }
+
+ // Update pointers for next iteration.
+ sig += sig_stride;
+ mc_running_avg_y += mc_avg_y_stride;
+ running_avg_y += avg_y_stride;
+ }
+}
+
+
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height)
{
- assert(denoiser);
- denoiser->yv12_running_avg.flags = 0;
- if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg), width,
- height, VP8BORDERINPIXELS) < 0)
- {
- vp8_denoiser_free(denoiser);
- return 1;
- }
- denoiser->yv12_mc_running_avg.flags = 0;
- if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_mc_running_avg), width,
- height, VP8BORDERINPIXELS) < 0)
- {
- vp8_denoiser_free(denoiser);
- return 1;
- }
- vpx_memset(denoiser->yv12_running_avg.buffer_alloc, 0,
- denoiser->yv12_running_avg.frame_size);
- vpx_memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0,
- denoiser->yv12_mc_running_avg.frame_size);
- return 0;
+ assert(denoiser);
+ denoiser->yv12_running_avg.flags = 0;
+
+ if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg), width,
+ height, VP8BORDERINPIXELS) < 0)
+ {
+ vp8_denoiser_free(denoiser);
+ return 1;
+ }
+
+ denoiser->yv12_mc_running_avg.flags = 0;
+
+ if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_mc_running_avg), width,
+ height, VP8BORDERINPIXELS) < 0)
+ {
+ vp8_denoiser_free(denoiser);
+ return 1;
+ }
+
+ vpx_memset(denoiser->yv12_running_avg.buffer_alloc, 0,
+ denoiser->yv12_running_avg.frame_size);
+ vpx_memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0,
+ denoiser->yv12_mc_running_avg.frame_size);
+ return 0;
}
void vp8_denoiser_free(VP8_DENOISER *denoiser)
{
- assert(denoiser);
- vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg);
- vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_mc_running_avg);
+ assert(denoiser);
+ vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg);
+ vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_mc_running_avg);
}
void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
@@ -176,37 +254,37 @@
unsigned int best_sse,
unsigned int zero_mv_sse,
int recon_yoffset,
- int recon_uvoffset) {
- int mv_row;
- int mv_col;
- unsigned int motion_magnitude2;
- // Motion compensate the running average.
- best_sse = denoiser_motion_compensate(&denoiser->yv12_running_avg,
- &denoiser->yv12_mc_running_avg,
- x,
- best_sse,
- zero_mv_sse,
- recon_yoffset,
- recon_uvoffset);
+ int recon_uvoffset)
+{
+ int mv_row;
+ int mv_col;
+ unsigned int motion_magnitude2;
+ // Motion compensate the running average.
+ best_sse = denoiser_motion_compensate(&denoiser->yv12_running_avg,
+ &denoiser->yv12_mc_running_avg,
+ x,
+ best_sse,
+ zero_mv_sse,
+ recon_yoffset,
+ recon_uvoffset);
- mv_row = x->e_mbd.best_sse_mv.as_mv.row;
- mv_col = x->e_mbd.best_sse_mv.as_mv.col;
- motion_magnitude2 = mv_row*mv_row + mv_col*mv_col;
- if (best_sse > SSE_THRESHOLD ||
- motion_magnitude2 > 8 * NOISE_MOTION_THRESHOLD)
- {
- // No filtering of this block since it differs too much from the predictor,
- // or the motion vector magnitude is considered too big.
- vp8_copy_mem16x16(x->thismb, 16,
- denoiser->yv12_running_avg.y_buffer + recon_yoffset,
- denoiser->yv12_running_avg.y_stride);
- return;
- }
- // Filter.
- denoiser_filter(&denoiser->yv12_mc_running_avg,
- &denoiser->yv12_running_avg,
- x,
- motion_magnitude2,
- recon_yoffset,
- recon_uvoffset);
+ mv_row = x->e_mbd.best_sse_mv.as_mv.row;
+ mv_col = x->e_mbd.best_sse_mv.as_mv.col;
+ motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
+
+ if (best_sse > SSE_THRESHOLD ||
+ motion_magnitude2 > 8 * NOISE_MOTION_THRESHOLD)
+ {
+ // No filtering of this block since it differs too much from the
+ // predictor, or the motion vector magnitude is considered too big.
+ vp8_copy_mem16x16(x->thismb, 16,
+ denoiser->yv12_running_avg.y_buffer + recon_yoffset,
+ denoiser->yv12_running_avg.y_stride);
+ return;
+ }
+
+ // Filter.
+ vp8_denoiser_filter(&denoiser->yv12_mc_running_avg,
+ &denoiser->yv12_running_avg, x, motion_magnitude2,
+ recon_yoffset, recon_uvoffset);
}
diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h
index 343531b..0a54e71 100644
--- a/vp8/encoder/denoising.h
+++ b/vp8/encoder/denoising.h
@@ -13,6 +13,8 @@
#include "block.h"
+#define NOISE_DIFF2_THRESHOLD (75)
+
typedef struct vp8_denoiser
{
YV12_BUFFER_CONFIG yv12_running_avg;
@@ -30,4 +32,12 @@
int recon_yoffset,
int recon_uvoffset);
+union coeff_pair
+{
+ uint32_t as_int;
+ uint16_t as_short[2];
+};
+
+union coeff_pair *vp8_get_filter_coeff_LUT(unsigned int motion_magnitude);
+
#endif // VP8_ENCODER_DENOISING_H_
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 5c607d9..f0ffaea 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -31,6 +31,7 @@
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
#include "bitstream.h"
#endif
+#include "encodeframe.h"
extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
extern void vp8_calc_ref_frame_costs(int *ref_frame_cost,
@@ -46,13 +47,6 @@
MB_ROW_COMP *mbr_ei,
int mb_row,
int count);
-void vp8_build_block_offsets(MACROBLOCK *x);
-void vp8_setup_block_ptrs(MACROBLOCK *x);
-int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
- int recon_yoffset, int recon_uvoffset,
- int mb_row, int mb_col);
-int vp8cx_encode_intra_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
- TOKENEXTRA **t);
static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x );
#ifdef MODE_STATS
@@ -596,7 +590,7 @@
x->partition_info++;
}
-void init_encode_frame_mb_context(VP8_COMP *cpi)
+static void init_encode_frame_mb_context(VP8_COMP *cpi)
{
MACROBLOCK *const x = & cpi->mb;
VP8_COMMON *const cm = & cpi->common;
diff --git a/vp8/encoder/encodeframe.h b/vp8/encoder/encodeframe.h
new file mode 100644
index 0000000..4dd6ba0
--- /dev/null
+++ b/vp8/encoder/encodeframe.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef ENCODEFRAME_H
+#define ENCODEFRAME_H
+extern void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x);
+
+extern void vp8_build_block_offsets(MACROBLOCK *x);
+
+extern void vp8_setup_block_ptrs(MACROBLOCK *x);
+
+extern void vp8_encode_frame(VP8_COMP *cpi);
+
+extern int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
+ TOKENEXTRA **t,
+ int recon_yoffset, int recon_uvoffset,
+ int mb_row, int mb_col);
+
+extern int vp8cx_encode_intra_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
+ TOKENEXTRA **t);
+#endif
diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c
index 8bfbcc6..57d5783 100644
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -12,8 +12,8 @@
#include "vp8/common/threading.h"
#include "vp8/common/common.h"
#include "vp8/common/extend.h"
-
#include "bitstream.h"
+#include "encodeframe.h"
#if CONFIG_MULTITHREAD
@@ -24,8 +24,6 @@
extern int vp8cx_encode_intra_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
TOKENEXTRA **t);
extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip);
-extern void vp8_build_block_offsets(MACROBLOCK *x);
-extern void vp8_setup_block_ptrs(MACROBLOCK *x);
extern void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index a9c30e4..8de1a6a 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -28,11 +28,10 @@
#include "rdopt.h"
#include "vp8/common/quant_common.h"
#include "encodemv.h"
+#include "encodeframe.h"
//#define OUTPUT_FPF 1
-extern void vp8_build_block_offsets(MACROBLOCK *x);
-extern void vp8_setup_block_ptrs(MACROBLOCK *x);
extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);
extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
extern void vp8_alloc_compressor_data(VP8_COMP *cpi);
@@ -869,7 +868,7 @@
//
-double bitcost( double prob )
+static double bitcost( double prob )
{
return -(log( prob ) / log( 2.0 ));
}
@@ -2313,12 +2312,9 @@
FIRSTPASS_STATS this_frame = {0};
FIRSTPASS_STATS this_frame_copy;
- double this_frame_error;
double this_frame_intra_error;
double this_frame_coded_error;
- FIRSTPASS_STATS *start_pos;
-
int overhead_bits;
if (!cpi->twopass.stats_in)
@@ -2331,12 +2327,9 @@
if (EOF == input_stats(cpi, &this_frame))
return;
- this_frame_error = this_frame.ssim_weighted_pred_err;
this_frame_intra_error = this_frame.intra_error;
this_frame_coded_error = this_frame.coded_error;
- start_pos = cpi->twopass.stats_in;
-
// keyframe and section processing !
if (cpi->twopass.frames_to_key == 0)
{
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 536ae63..372d5aa 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -36,6 +36,7 @@
#if CONFIG_MULTI_RES_ENCODING
#include "mr_dissim.h"
#endif
+#include "encodeframe.h"
#include <math.h>
#include <stdio.h>
@@ -1016,8 +1017,10 @@
static void alloc_raw_frame_buffers(VP8_COMP *cpi)
{
+#if VP8_TEMPORAL_ALT_REF
int width = (cpi->oxcf.Width + 15) & ~15;
int height = (cpi->oxcf.Height + 15) & ~15;
+#endif
cpi->lookahead = vp8_lookahead_init(cpi->oxcf.Width, cpi->oxcf.Height,
cpi->oxcf.lag_in_frames);
@@ -1336,7 +1339,7 @@
#endif
}
-void update_layer_contexts (VP8_COMP *cpi)
+static void update_layer_contexts (VP8_COMP *cpi)
{
VP8_CONFIG *oxcf = &cpi->oxcf;
@@ -1398,12 +1401,24 @@
if (!oxcf)
return;
+#if CONFIG_MULTITHREAD
+ /* wait for the last picture loopfilter thread done */
+ if (cpi->b_lpf_running)
+ {
+ sem_wait(&cpi->h_event_end_lpf);
+ cpi->b_lpf_running = 0;
+ }
+#endif
+
if (cm->version != oxcf->Version)
{
cm->version = oxcf->Version;
vp8_setup_version(cm);
}
+ last_w = cpi->oxcf.Width;
+ last_h = cpi->oxcf.Height;
+
cpi->oxcf = *oxcf;
switch (cpi->oxcf.Mode)
@@ -1598,14 +1613,14 @@
cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
- last_w = cm->Width;
- last_h = cm->Height;
-
cm->Width = cpi->oxcf.Width;
cm->Height = cpi->oxcf.Height;
- cm->horiz_scale = cpi->horiz_scale;
- cm->vert_scale = cpi->vert_scale;
+ /* TODO(jkoleszar): if an internal spatial resampling is active,
+ * and we downsize the input image, maybe we should clear the
+ * internal scale immediately rather than waiting for it to
+ * correct.
+ */
// VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
if (cpi->oxcf.Sharpness > 7)
@@ -1626,7 +1641,7 @@
cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
}
- if (last_w != cm->Width || last_h != cm->Height)
+ if (last_w != cpi->oxcf.Width || last_h != cpi->oxcf.Height)
cpi->force_next_frame_intra = 1;
if (((cm->Width + 15) & 0xfffffff0) !=
@@ -3009,7 +3024,7 @@
return force_recode;
}
-void update_reference_frames(VP8_COMMON *cm)
+static void update_reference_frames(VP8_COMMON *cm)
{
YV12_BUFFER_CONFIG *yv12_fb = cm->yv12_fb;
@@ -3158,20 +3173,21 @@
int Loop = 0;
int loop_count;
- int this_q;
- int last_zbin_oq;
+ VP8_COMMON *cm = &cpi->common;
+ int active_worst_qchanged = 0;
+
+#if !(CONFIG_REALTIME_ONLY)
int q_low;
int q_high;
int zbin_oq_high;
int zbin_oq_low = 0;
int top_index;
int bottom_index;
- VP8_COMMON *cm = &cpi->common;
- int active_worst_qchanged = 0;
-
int overshoot_seen = 0;
int undershoot_seen = 0;
+#endif
+
int drop_mark = cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100;
int drop_mark75 = drop_mark * 2 / 3;
int drop_mark50 = drop_mark / 4;
@@ -3181,6 +3197,15 @@
// Clear down mmx registers to allow floating point in what follows
vp8_clear_system_state();
+#if CONFIG_MULTITHREAD
+ /* wait for the last picture loopfilter thread done */
+ if (cpi->b_lpf_running)
+ {
+ sem_wait(&cpi->h_event_end_lpf);
+ cpi->b_lpf_running = 0;
+ }
+#endif
+
// Test code for segmentation of gf/arf (0,0)
//segmentation_test_function( cpi);
@@ -3333,7 +3358,6 @@
{
cpi->decimation_factor = 1;
}
-
//vpx_log("Encoder: Decimation Factor: %d \n",cpi->decimation_factor);
}
@@ -3575,7 +3599,8 @@
// Determine initial Q to try
Q = vp8_regulate_q(cpi, cpi->this_frame_target);
- last_zbin_oq = cpi->zbin_over_quant;
+
+#if !(CONFIG_REALTIME_ONLY)
// Set highest allowed value for Zbin over quant
if (cm->frame_type == KEY_FRAME)
@@ -3587,6 +3612,7 @@
}
else
zbin_oq_high = ZBIN_OQ_MAX;
+#endif
// Setup background Q adjustment for error resilient mode.
// For multi-layer encodes only enable this for the base layer.
@@ -3595,18 +3621,20 @@
vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit);
+#if !(CONFIG_REALTIME_ONLY)
// Limit Q range for the adaptive loop.
bottom_index = cpi->active_best_quality;
top_index = cpi->active_worst_quality;
q_low = cpi->active_best_quality;
q_high = cpi->active_worst_quality;
+#endif
vp8_save_coding_context(cpi);
loop_count = 0;
-
scale_and_extend_source(cpi->un_scaled_source, cpi);
+
#if !(CONFIG_REALTIME_ONLY) && CONFIG_POSTPROC && !(CONFIG_TEMPORAL_DENOISING)
if (cpi->oxcf.noise_sensitivity > 0)
@@ -3670,7 +3698,6 @@
*/
vp8_set_quantizer(cpi, Q);
- this_q = Q;
// setup skip prob for costing in mode/mv decision
if (cpi->common.mb_no_coeff_skip)
@@ -3746,14 +3773,7 @@
vp8_setup_key_frame(cpi);
}
-#if CONFIG_MULTITHREAD
- /* wait for the last picture loopfilter thread done */
- if (cpi->b_lpf_running)
- {
- sem_wait(&cpi->h_event_end_lpf);
- cpi->b_lpf_running = 0;
- }
-#endif
+
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
{
@@ -3800,9 +3820,10 @@
if (cpi->compressor_speed == 2)
{
/* we don't do re-encoding in realtime mode
- * if key frame is decided than we force it on next frame */
+ * if key frame is decided then we force it on next frame */
cpi->force_next_frame_intra = key_frame_decision;
}
+#if !(CONFIG_REALTIME_ONLY)
else if (key_frame_decision)
{
// Reset all our sizing numbers and recode
@@ -3840,6 +3861,7 @@
continue;
}
+#endif
}
vp8_clear_system_state();
@@ -3859,10 +3881,12 @@
while ((cpi->active_worst_quality < cpi->worst_quality) && (over_size_percent > 0))
{
cpi->active_worst_quality++;
- top_index = cpi->active_worst_quality;
+
over_size_percent = (int)(over_size_percent * 0.96); // Assume 1 qstep = about 4% on frame size.
}
-
+#if !(CONFIG_REALTIME_ONLY)
+ top_index = cpi->active_worst_quality;
+#endif
// If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
active_worst_qchanged = 1;
}
@@ -4021,9 +4045,7 @@
// Clamp cpi->zbin_over_quant
cpi->zbin_over_quant = (cpi->zbin_over_quant < zbin_oq_low) ? zbin_oq_low : (cpi->zbin_over_quant > zbin_oq_high) ? zbin_oq_high : cpi->zbin_over_quant;
- //Loop = (Q != last_q) || (last_zbin_oq != cpi->zbin_over_quant);
Loop = Q != last_q;
- last_zbin_oq = cpi->zbin_over_quant;
}
else
#endif
@@ -4808,7 +4830,7 @@
}
// adjust frame rates based on timestamps given
- if (!cm->refresh_alt_ref_frame || (cpi->oxcf.number_of_layers > 1))
+ if (cm->show_frame)
{
int64_t this_duration;
int step = 0;
@@ -4855,7 +4877,7 @@
if (cpi->oxcf.number_of_layers > 1)
{
- int i;
+ unsigned int i;
// Update frame rates for each layer
for (i=0; i<cpi->oxcf.number_of_layers; i++)
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index f4b67e6..cf70231 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -57,8 +57,6 @@
#define VP8_TEMPORAL_ALT_REF 1
#endif
-#define MAX_PERIODICITY 16
-
#define MAX(x,y) (((x)>(y))?(x):(y))
#define MIN(x,y) (((x)<(y))?(x):(y))
@@ -485,8 +483,6 @@
int goldfreq;
int auto_worst_q;
int cpu_used;
- int horiz_scale;
- int vert_scale;
int pass;
@@ -672,21 +668,21 @@
// Coding layer state variables
unsigned int current_layer;
- LAYER_CONTEXT layer_context[MAX_LAYERS];
+ LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS];
- int64_t frames_in_layer[MAX_LAYERS];
- int64_t bytes_in_layer[MAX_LAYERS];
- double sum_psnr[MAX_LAYERS];
- double sum_psnr_p[MAX_LAYERS];
- double total_error2[MAX_LAYERS];
- double total_error2_p[MAX_LAYERS];
- double sum_ssim[MAX_LAYERS];
- double sum_weights[MAX_LAYERS];
+ int64_t frames_in_layer[VPX_TS_MAX_LAYERS];
+ int64_t bytes_in_layer[VPX_TS_MAX_LAYERS];
+ double sum_psnr[VPX_TS_MAX_LAYERS];
+ double sum_psnr_p[VPX_TS_MAX_LAYERS];
+ double total_error2[VPX_TS_MAX_LAYERS];
+ double total_error2_p[VPX_TS_MAX_LAYERS];
+ double sum_ssim[VPX_TS_MAX_LAYERS];
+ double sum_weights[VPX_TS_MAX_LAYERS];
- double total_ssimg_y_in_layer[MAX_LAYERS];
- double total_ssimg_u_in_layer[MAX_LAYERS];
- double total_ssimg_v_in_layer[MAX_LAYERS];
- double total_ssimg_all_in_layer[MAX_LAYERS];
+ double total_ssimg_y_in_layer[VPX_TS_MAX_LAYERS];
+ double total_ssimg_u_in_layer[VPX_TS_MAX_LAYERS];
+ double total_ssimg_v_in_layer[VPX_TS_MAX_LAYERS];
+ double total_ssimg_all_in_layer[VPX_TS_MAX_LAYERS];
#if CONFIG_MULTI_RES_ENCODING
/* Number of MBs per row at lower-resolution level */
@@ -708,12 +704,8 @@
void control_data_rate(VP8_COMP *cpi);
-void vp8_encode_frame(VP8_COMP *cpi);
-
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char *dest_end, unsigned long *size);
-void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x);
-
int rd_cost_intra_mb(MACROBLOCKD *x);
void vp8_tokenize_mb(VP8_COMP *, MACROBLOCKD *, TOKENEXTRA **);
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
index 45acb0b..4de84fd 100644
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -458,7 +458,7 @@
if (sse < x->encode_breakout)
{
// Check u and v to make sure skip is ok
- int sse2 = 0;
+ unsigned int sse2 = 0;
sse2 = VP8_UVSSE(x);
diff --git a/vp8/encoder/picklpf.c b/vp8/encoder/picklpf.c
index d09dfc8..21af45a 100644
--- a/vp8/encoder/picklpf.c
+++ b/vp8/encoder/picklpf.c
@@ -28,11 +28,9 @@
unsigned char *src_y, *dst_y;
int yheight;
int ystride;
- int border;
int yoffset;
int linestocopy;
- border = src_ybc->border;
yheight = src_ybc->y_height;
ystride = src_ybc->y_stride;
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 967a752..04fd2d0 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -350,7 +350,7 @@
{
// boost defaults to half second
int kf_boost;
- int target;
+ unsigned int target;
// Clear down mmx registers to allow floating point in what follows
vp8_clear_system_state(); //__asm emms;
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 167192d..1a2eb11 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1769,7 +1769,7 @@
{
unsigned int sse;
unsigned int var;
- int threshold = (xd->block[0].dequant[1]
+ unsigned int threshold = (xd->block[0].dequant[1]
* xd->block[0].dequant[1] >>4);
if(threshold < x->encode_breakout)
@@ -1788,7 +1788,7 @@
(sse /2 > var && sse-var < 64))
{
// Check u and v to make sure skip is ok
- int sse2= VP8_UVSSE(x);
+ unsigned int sse2 = VP8_UVSSE(x);
if (sse2 * 2 < threshold)
{
x->skip = 1;
diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c
index cfe9122..b391d5a 100644
--- a/vp8/encoder/temporal_filter.c
+++ b/vp8/encoder/temporal_filter.c
@@ -146,7 +146,6 @@
{
MACROBLOCK *x = &cpi->mb;
int step_param;
- int further_steps;
int sadpb = x->sadperbit16;
int bestsme = INT_MAX;
@@ -179,15 +178,11 @@
// Further step/diamond searches as necessary
if (cpi->Speed < 8)
{
- step_param = cpi->sf.first_step +
- (cpi->Speed > 5);
- further_steps =
- (cpi->sf.max_step_search_steps - 1)-step_param;
+ step_param = cpi->sf.first_step + (cpi->Speed > 5);
}
else
{
step_param = cpi->sf.first_step + 2;
- further_steps = 0;
}
/*cpi->sf.search_method == HEX*/
diff --git a/vp8/encoder/x86/denoising_sse2.c b/vp8/encoder/x86/denoising_sse2.c
new file mode 100644
index 0000000..9bf9382
--- /dev/null
+++ b/vp8/encoder/x86/denoising_sse2.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "vp8/encoder/denoising.h"
+
+#include "vp8/common/reconinter.h"
+#include "vpx/vpx_integer.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_rtcd.h"
+
+#include <emmintrin.h>
+
+void vp8_denoiser_filter_sse2(YV12_BUFFER_CONFIG *mc_running_avg,
+ YV12_BUFFER_CONFIG *running_avg,
+ MACROBLOCK *signal, unsigned int motion_magnitude,
+ int y_offset, int uv_offset)
+{
+ unsigned char *sig = signal->thismb;
+ int sig_stride = 16;
+ unsigned char *mc_running_avg_y = mc_running_avg->y_buffer + y_offset;
+ int mc_avg_y_stride = mc_running_avg->y_stride;
+ unsigned char *running_avg_y = running_avg->y_buffer + y_offset;
+ int avg_y_stride = running_avg->y_stride;
+ const union coeff_pair *LUT = vp8_get_filter_coeff_LUT(motion_magnitude);
+ int r, c;
+
+ for (r = 0; r < 16; ++r)
+ {
+ __m128i filter_coefficient_00, filter_coefficient_04;
+ __m128i filter_coefficient_08, filter_coefficient_12;
+ __m128i v_sig0, v_sig1;
+ __m128i v_mc_running_avg_y0, v_mc_running_avg_y1;
+ __m128i state0, state1, state2, state3;
+ __m128i res0, res1, res2, res3;
+ __m128i v_running_avg_y;
+ __m128i diff0, diff1, diff0sq, diff1sq, diff_sq;
+ const __m128i kNOISE_DIFF2_THRESHOLD =
+ _mm_set1_epi8(NOISE_DIFF2_THRESHOLD);
+ __m128i take_running, p0, p1, p2;
+ const __m128i k_zero = _mm_set1_epi16(0);
+ const __m128i k_128 = _mm_set1_epi32(128);
+
+ // Calculate absolute differences
+ DECLARE_ALIGNED_ARRAY(16,unsigned char,abs_diff,16);
+ DECLARE_ALIGNED_ARRAY(16,uint32_t,filter_coefficient,16);
+ __m128i v_sig = _mm_loadu_si128((__m128i *)(&sig[0]));
+ __m128i v_mc_running_avg_y = _mm_loadu_si128(
+ (__m128i *)(&mc_running_avg_y[0]));
+ __m128i a_minus_b = _mm_subs_epu8(v_sig, v_mc_running_avg_y);
+ __m128i b_minus_a = _mm_subs_epu8(v_mc_running_avg_y, v_sig);
+ __m128i v_abs_diff = _mm_adds_epu8(a_minus_b, b_minus_a);
+ _mm_store_si128((__m128i *)(&abs_diff[0]), v_abs_diff);
+
+ // Use LUT to get filter coefficients (two 16b value; f and 256-f)
+ for (c = 0; c < 16; ++c)
+ {
+ filter_coefficient[c] = LUT[abs_diff[c]].as_int;
+ }
+
+ // Filtering...
+ // load filter coefficients (two 16b value; f and 256-f)
+ filter_coefficient_00 = _mm_load_si128(
+ (__m128i *)(&filter_coefficient[ 0]));
+ filter_coefficient_04 = _mm_load_si128(
+ (__m128i *)(&filter_coefficient[ 4]));
+ filter_coefficient_08 = _mm_load_si128(
+ (__m128i *)(&filter_coefficient[ 8]));
+ filter_coefficient_12 = _mm_load_si128(
+ (__m128i *)(&filter_coefficient[12]));
+
+ // expand sig from 8b to 16b
+ v_sig0 = _mm_unpacklo_epi8(v_sig, k_zero);
+ v_sig1 = _mm_unpackhi_epi8(v_sig, k_zero);
+ // expand mc_running_avg_y from 8b to 16b
+ v_mc_running_avg_y0 = _mm_unpacklo_epi8(v_mc_running_avg_y, k_zero);
+ v_mc_running_avg_y1 = _mm_unpackhi_epi8(v_mc_running_avg_y, k_zero);
+ // interleave sig and mc_running_avg_y for upcoming multiply-add
+ state0 = _mm_unpacklo_epi16(v_mc_running_avg_y0, v_sig0);
+ state1 = _mm_unpackhi_epi16(v_mc_running_avg_y0, v_sig0);
+ state2 = _mm_unpacklo_epi16(v_mc_running_avg_y1, v_sig1);
+ state3 = _mm_unpackhi_epi16(v_mc_running_avg_y1, v_sig1);
+ // blend values
+ res0 = _mm_madd_epi16(filter_coefficient_00, state0);
+ res1 = _mm_madd_epi16(filter_coefficient_04, state1);
+ res2 = _mm_madd_epi16(filter_coefficient_08, state2);
+ res3 = _mm_madd_epi16(filter_coefficient_12, state3);
+ res0 = _mm_add_epi32(res0, k_128);
+ res1 = _mm_add_epi32(res1, k_128);
+ res2 = _mm_add_epi32(res2, k_128);
+ res3 = _mm_add_epi32(res3, k_128);
+ res0 = _mm_srai_epi32(res0, 8);
+ res1 = _mm_srai_epi32(res1, 8);
+ res2 = _mm_srai_epi32(res2, 8);
+ res3 = _mm_srai_epi32(res3, 8);
+ // combine the 32b results into a single 8b vector
+ res0 = _mm_packs_epi32(res0, res1);
+ res2 = _mm_packs_epi32(res2, res3);
+ v_running_avg_y = _mm_packus_epi16(res0, res2);
+
+ // Depending on the magnitude of the difference between the signal and
+ // filtered version, either replace the signal by the filtered one or
+ // update the filter state with the signal when the change in a pixel
+ // isn't classified as noise.
+ diff0 = _mm_sub_epi16(v_sig0, res0);
+ diff1 = _mm_sub_epi16(v_sig1, res2);
+ diff0sq = _mm_mullo_epi16(diff0, diff0);
+ diff1sq = _mm_mullo_epi16(diff1, diff1);
+ diff_sq = _mm_packus_epi16(diff0sq, diff1sq);
+ take_running = _mm_cmplt_epi8(diff_sq, kNOISE_DIFF2_THRESHOLD);
+ p0 = _mm_and_si128(take_running, v_running_avg_y);
+ p1 = _mm_andnot_si128(take_running, v_sig);
+ p2 = _mm_or_si128(p0, p1);
+ _mm_storeu_si128((__m128i *)(&running_avg_y[0]), p2);
+ _mm_storeu_si128((__m128i *)(&sig[0]), p2);
+
+ // Update pointers for next iteration.
+ sig += sig_stride;
+ mc_running_avg_y += mc_avg_y_stride;
+ running_avg_y += avg_y_stride;
+ }
+}
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 04d4d86..22d39b7 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -13,17 +13,12 @@
#include "vpx/internal/vpx_codec_internal.h"
#include "vpx_version.h"
#include "vp8/encoder/onyx_int.h"
-#include "vpx/vp8e.h"
+#include "vpx/vp8cx.h"
#include "vp8/encoder/firstpass.h"
#include "vp8/common/onyx.h"
#include <stdlib.h>
#include <string.h>
-/* This value is a sentinel for determining whether the user has set a mode
- * directly through the deprecated VP8E_SET_ENCODING_MODE control.
- */
-#define NO_MODE_SET 255
-
struct vp8_extracfg
{
struct vpx_codec_pkt_list *pkt_list;
@@ -94,7 +89,6 @@
unsigned int next_frame_flag;
vp8_postproc_cfg_t preview_ppcfg;
vpx_codec_pkt_list_decl(64) pkt_list; // changed to accomendate the maximum number of lagged frames allowed
- int deprecated_mode;
unsigned int fixed_kf_cntr;
};
@@ -183,19 +177,16 @@
RANGE_CHECK_BOOL(vp8_cfg, enable_auto_alt_ref);
RANGE_CHECK(vp8_cfg, cpu_used, -16, 16);
-#if CONFIG_TEMPORAL_DENOISING
- RANGE_CHECK(vp8_cfg, noise_sensitivity, 0, 1);
-#endif
#if !(CONFIG_REALTIME_ONLY)
RANGE_CHECK(vp8_cfg, encoding_mode, VP8_BEST_QUALITY_ENCODING, VP8_REAL_TIME_ENCODING);
-#if !(CONFIG_TEMPORAL_DENOISING)
- RANGE_CHECK_HI(vp8_cfg, noise_sensitivity, 6);
-#endif
#else
RANGE_CHECK(vp8_cfg, encoding_mode, VP8_REAL_TIME_ENCODING, VP8_REAL_TIME_ENCODING);
-#if !(CONFIG_TEMPORAL_DENOISING)
- RANGE_CHECK(vp8_cfg, noise_sensitivity, 0, 0);
#endif
+
+#if CONFIG_REALTIME_ONLY && !CONFIG_TEMPORAL_DENOISING
+ RANGE_CHECK(vp8_cfg, noise_sensitivity, 0, 0);
+#else
+ RANGE_CHECK_HI(vp8_cfg, noise_sensitivity, 6);
#endif
RANGE_CHECK(vp8_cfg, token_partitions, VP8_ONE_TOKENPARTITION, VP8_EIGHT_TOKENPARTITION);
@@ -236,7 +227,7 @@
if (cfg->ts_number_layers > 1)
{
- int i;
+ unsigned int i;
RANGE_CHECK_HI(cfg, ts_periodicity, 16);
for (i=1; i<cfg->ts_number_layers; i++)
@@ -516,7 +507,6 @@
switch (ctrl_id)
{
- MAP(VP8E_SET_ENCODING_MODE, ctx->deprecated_mode);
MAP(VP8E_SET_CPUUSED, xcfg.cpu_used);
MAP(VP8E_SET_ENABLEAUTOALTREF, xcfg.enable_auto_alt_ref);
MAP(VP8E_SET_NOISE_SENSITIVITY, xcfg.noise_sensitivity);
@@ -576,7 +566,7 @@
static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx,
vpx_codec_priv_enc_mr_cfg_t *mr_cfg)
{
- vpx_codec_err_t res = VPX_DEC_OK;
+ vpx_codec_err_t res = VPX_CODEC_OK;
struct vpx_codec_alg_priv *priv;
vpx_codec_enc_cfg_t *cfg;
unsigned int i;
@@ -631,8 +621,6 @@
return VPX_CODEC_MEM_ERROR;
}
- priv->deprecated_mode = NO_MODE_SET;
-
res = validate_config(priv, &priv->cfg, &priv->vp8_cfg, 0);
if (!res)
@@ -727,19 +715,6 @@
new_qc = MODE_REALTIME;
#endif
- switch (ctx->deprecated_mode)
- {
- case VP8_BEST_QUALITY_ENCODING:
- new_qc = MODE_BESTQUALITY;
- break;
- case VP8_GOOD_QUALITY_ENCODING:
- new_qc = MODE_GOODQUALITY;
- break;
- case VP8_REAL_TIME_ENCODING:
- new_qc = MODE_REALTIME;
- break;
- }
-
if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
new_qc = MODE_FIRSTPASS;
else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
@@ -767,6 +742,9 @@
if (!ctx->cfg.rc_target_bitrate)
return res;
+ if (!ctx->cfg.rc_target_bitrate)
+ return res;
+
if (img)
res = validate_img(ctx, img);
@@ -1216,7 +1194,6 @@
{VP8E_SET_ROI_MAP, vp8e_set_roi_map},
{VP8E_SET_ACTIVEMAP, vp8e_set_activemap},
{VP8E_SET_SCALEMODE, vp8e_set_scalemode},
- {VP8E_SET_ENCODING_MODE, set_param},
{VP8E_SET_CPUUSED, set_param},
{VP8E_SET_NOISE_SENSITIVITY, set_param},
{VP8E_SET_ENABLEAUTOALTREF, set_param},
@@ -1327,88 +1304,3 @@
vp8e_mr_alloc_mem,
} /* encoder functions */
};
-
-
-/*
- * BEGIN BACKWARDS COMPATIBILITY SHIM.
- */
-#define FORCE_KEY 2
-static vpx_codec_err_t api1_control(vpx_codec_alg_priv_t *ctx,
- int ctrl_id,
- va_list args)
-{
- vpx_codec_ctrl_fn_map_t *entry;
-
- switch (ctrl_id)
- {
- case VP8E_SET_FLUSHFLAG:
- /* VP8 sample code did VP8E_SET_FLUSHFLAG followed by
- * vpx_codec_get_cx_data() rather than vpx_codec_encode().
- */
- return vp8e_encode(ctx, NULL, 0, 0, 0, 0);
- case VP8E_SET_FRAMETYPE:
- ctx->base.enc.tbd |= FORCE_KEY;
- return VPX_CODEC_OK;
- }
-
- for (entry = vp8e_ctf_maps; entry && entry->fn; entry++)
- {
- if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
- {
- return entry->fn(ctx, ctrl_id, args);
- }
- }
-
- return VPX_CODEC_ERROR;
-}
-
-
-static vpx_codec_ctrl_fn_map_t api1_ctrl_maps[] =
-{
- {0, api1_control},
- { -1, NULL}
-};
-
-
-static vpx_codec_err_t api1_encode(vpx_codec_alg_priv_t *ctx,
- const vpx_image_t *img,
- vpx_codec_pts_t pts,
- unsigned long duration,
- vpx_enc_frame_flags_t flags,
- unsigned long deadline)
-{
- int force = ctx->base.enc.tbd;
-
- ctx->base.enc.tbd = 0;
- return vp8e_encode
- (ctx,
- img,
- pts,
- duration,
- flags | ((force & FORCE_KEY) ? VPX_EFLAG_FORCE_KF : 0),
- deadline);
-}
-
-
-vpx_codec_iface_t vpx_enc_vp8_algo =
-{
- "WebM Project VP8 Encoder (Deprecated API)" VERSION_STRING,
- VPX_CODEC_INTERNAL_ABI_VERSION,
- VPX_CODEC_CAP_ENCODER,
- /* vpx_codec_caps_t caps; */
- vp8e_init, /* vpx_codec_init_fn_t init; */
- vp8e_destroy, /* vpx_codec_destroy_fn_t destroy; */
- api1_ctrl_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}, /* decoder functions */
- {
- vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */
- api1_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,
- vp8e_mr_alloc_mem,
- } /* encoder functions */
-};
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index 33c1aff..37773db 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -785,33 +785,3 @@
NOT_IMPLEMENTED
}
};
-
-/*
- * BEGIN BACKWARDS COMPATIBILITY SHIM.
- */
-vpx_codec_iface_t vpx_codec_vp8_algo =
-{
- "WebM Project VP8 Decoder (Deprecated API)" VERSION_STRING,
- VPX_CODEC_INTERNAL_ABI_VERSION,
- VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT,
- /* vpx_codec_caps_t caps; */
- vp8_init, /* vpx_codec_init_fn_t init; */
- vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */
- vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
- vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t get_mmap; */
- vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t set_mmap; */
- {
- vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */
- vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */
- vp8_decode, /* vpx_codec_decode_fn_t decode; */
- vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */
- },
- { /* encoder functions */
- NOT_IMPLEMENTED,
- NOT_IMPLEMENTED,
- NOT_IMPLEMENTED,
- NOT_IMPLEMENTED,
- NOT_IMPLEMENTED,
- NOT_IMPLEMENTED
- }
-};
diff --git a/vp8/vp8cx.mk b/vp8/vp8cx.mk
index e2557eb..28deaf2 100644
--- a/vp8/vp8cx.mk
+++ b/vp8/vp8cx.mk
@@ -39,6 +39,7 @@
VP8_CX_SRCS-yes += encoder/boolhuff.c
VP8_CX_SRCS-yes += encoder/dct.c
VP8_CX_SRCS-yes += encoder/encodeframe.c
+VP8_CX_SRCS-yes += encoder/encodeframe.h
VP8_CX_SRCS-yes += encoder/encodeintra.c
VP8_CX_SRCS-yes += encoder/encodemb.c
VP8_CX_SRCS-yes += encoder/encodemv.c
@@ -100,6 +101,14 @@
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/dct_sse2.asm
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/fwalsh_sse2.asm
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/quantize_sse2.asm
+
+ifeq ($(CONFIG_TEMPORAL_DENOISING),yes)
+VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/denoising_sse2.c
+ifeq ($(HAVE_SSE2),yes)
+vp8/encoder/x86/denoising_sse2.c.o: CFLAGS += -msse2
+endif
+endif
+
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/subtract_sse2.asm
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/temporal_filter_apply_sse2.asm
VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp8_enc_stubs_sse2.c
diff --git a/vp8_api1_migration.txt b/vp8_api1_migration.txt
deleted file mode 100644
index 47b7981..0000000
--- a/vp8_api1_migration.txt
+++ /dev/null
@@ -1,198 +0,0 @@
-Version 2.x of this library has deprecated or removed a number of interfaces to
-the VP8 codec. Where possible, the old interfaces have been left in place in a
-deprecated state, and will generate compiler warnings when they are referenced.
-All users are encouraged to update their code to the new interfaces as soon as
-possible. To assist in this effort, the `VPX_CODEC_DISABLE_COMPAT` symbol can
-be #defined to 1 prior to including vpx headers. This will disable the
-backwards compatability workarounds and ensure that you are using only the
-latest API.
-
-The *TWO-PASS STATISTICS* sections detail the one section of code which is not
-backwards compatable and will require code changes.
-
-
-HEADER FILES
-============
-The following header files were renamed:
-
- vp8.h -> vp8dx.h
- vp8e.h -> vp8cx.h
-
-
-INTERFACE SYMBOLS
-=================
-The following interface symbols were renamed:
-
- vpx_codec_vp8_algo -> vpx_codec_vp8_dx_algo
- vpx_enc_vp8_algo -> vpx_codec_vp8_cx_algo
-
-
-TWO-PASS STATISTICS
-===================
-Two-pass statistics are handled significantly differently. The version 1 API
-stored statistics in a file, and the application passed the name of that file
-in the `vpx_codec_enc_cfg` structure. In this version, statistics are returned
-though the application though the `vpx_codec_get_cx_data()` interface. The
-application must concatenate these packets into a contiguous buffer and then
-pass that buffer to the encoder through the `vpx_codec_enc_cfg` structure on
-the second pass initialization. The application may choose to keep these packets
-in memory or write them to disk. Statistics packets are approximately 112 bytes
-per frame. See the example code for more detailed examples.
-
-
-ENCODER CONTROLS
-================
-
-Renames
--------
-The following controls are duplicated between the encoder and the decoder, but
-the encoder unnecessarily introduced unique identifiers for them. These
-identifiers were removed in favor of the ones used by the decoder:
-
- VP8E_SET_REFERENCE -> VP8_SET_REFERENCE
- VP8E_COPY_REFERENCE -> VP8_COPY_REFERENCE
- VP8E_SET_PREVIEWPP -> VP8_SET_POSTPROC
-
-
-VP8E_SET_FRAMETYPE
-------------------
-This control was removed in favor of the `flags` parameter to
-`vpx_codec_encode()`. Existing code such as:
-
-~~~
- vpx_codec_control(&encoder, VP8E_SET_FRAMETYPE, KEY_FRAME);
- ...
- vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
-~~~
-
-becomes:
-
-~~~
- vpx_codec_encode(&encoder, img, pts, 1, VPX_EFLAG_FORCE_KF,
- VPX_DL_REALTIME);
-~~~
-
-
-
-VP8E_SET_FLUSHFLAG
-------------------
-Flush is handled by passing `NULL` to the `img` parameter of
-`vpx_codec_encode()`. You must do this at least once, regardless of your encoder
-configuration. i.e. it's not specific to g_lag_in_frames. This control was
-removed.
-
-~~~
- while(...) {
- ...
- vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
- while( (pkt = vpx_codec_get_cx_data(&encoder, &iter)) ) {
- ...
- }
- }
- vpx_codec_control(&encoder, VP8E_SET_FLUSHFLAG, 1);
- while( (pkt = vpx_codec_get_cx_data(&encoder, &iter)) ) {
- ...
- }
- vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
-~~~
-
-becomes
-
-~~~
- while(new_image && ...) {
- ...
- vpx_codec_encode(&encoder, new_image?img:NULL, pts, 1, 0, 0);
- while( (pkt = vpx_codec_get_cx_data(&encoder, &iter)) ) {
- ...
- }
- }
-~~~
-
-
-
-VP8E_SET_ENCODING_MODE
-----------------------
-This control was removed in favor of the `deadline` parameter to
-`vpx_codec_encode()`. There are three macros that can be used to get the
-equivalent behavior: VPX_DL_REALTIME, VPX_DL_GOOD_QUALITY,
-VPX_DL_BEST_QUALITY. Existing code such as:
-
-~~~
- vpx_codec_control(&encoder, VP8E_SET_ENCODING_MODE, VP8_REAL_TIME_ENCODING);
- ...
- vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
-~~~
-
-becomes:
-
-~~~
- vpx_codec_encode(&encoder, img, pts, 1, 0, VPX_DL_REALTIME);
-~~~
-
-
-VP8E_UPD_ENTROPY
-------------------
-This control was deprecated in favor of the `flags` parameter to
-`vpx_codec_encode()`. Existing code such as:
-
-~~~
- vpx_codec_control(&encoder, VP8E_UPD_ENTROPY, 0);
-~~~
-
-becomes:
-
-~~~
- vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_NO_UPD_ENTROPY,
- VPX_DL_REALTIME);
-~~~
-
-
-VP8E_UPD_REFERENCE
-------------------
-This control was deprecated in favor of the `flags` parameter to
-`vpx_codec_encode()`. A set bit on the VP8E_UPD_REFERENCE bitfield is
-analogous to setting the VP8_EFLAG_FORCE_* flag. A cleared bit is analogous
-to setting the VP8_EFLAG_NO_UPD_* flag. If neither the FORCE or NO_UPD bit
-is set, the encoder will make its decision automatically, as usual. Setting
-both bits will result in an error being returned. Existing code such as:
-
-~~~
- vpx_codec_control(&encoder, VP8E_UPD_REFERENCE,
- VP8_LAST_FRAME | VP8_GOLD_FRAME);
- vpx_codec_control(&encoder, VP8E_UPD_REFERENCE, 0);
- ...
- vpx_codec_encode(&encoder, img, pts, 1, 0, VPX_DL_REALTIME);
-~~~
-
-becomes:
-
-~~~
- vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_FORCE_GF,
- VPX_DL_REALTIME);
- vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_NO_UPD_LAST
- | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF,
- VPX_DL_REALTIME);
-~~~
-
-
-VP8E_USE_REFERENCE
-------------------
-This control was deprecated in favor of the `flags` parameter to
-`vpx_codec_encode()`. A cleared bit on the VP8E_USE_REFERENCE bitfield is
-analogous to setting the VP8_EFLAG_NO_REF* flag. A set bit indicates that
-the encoder will make its decision automatically, as usual.
-Existing code such as:
-
-~~~
- vpx_codec_control(&encoder, VP8E_USE_REFERENCE,
- VP8_ALTR_FRAME | VP8_GOLD_FRAME);
- ...
- vpx_codec_encode(&encoder, img, pts, 1, 0, VPX_DL_REALTIME);
-~~~
-
-becomes
-
-~~~
- vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_NO_REF_LAST,
- VPX_DL_REALTIME);
-~~~
diff --git a/vp8_scalable_patterns.c b/vp8_scalable_patterns.c
index 50cc03a..aa931e2 100644
--- a/vp8_scalable_patterns.c
+++ b/vp8_scalable_patterns.c
@@ -117,7 +117,7 @@
static int mode_to_num_layers[9] = {2, 2, 3, 3, 3, 3, 5, 2, 3};
int main(int argc, char **argv) {
- FILE *infile, *outfile[MAX_LAYERS];
+ FILE *infile, *outfile[VPX_TS_MAX_LAYERS];
vpx_codec_ctx_t codec;
vpx_codec_enc_cfg_t cfg;
int frame_cnt = 0;
@@ -133,8 +133,8 @@
int frame_duration = 1; // 1 timebase tick per frame
int layering_mode = 0;
- int frames_in_layer[MAX_LAYERS] = {0};
- int layer_flags[MAX_PERIODICITY] = {0};
+ int frames_in_layer[VPX_TS_MAX_LAYERS] = {0};
+ int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
int flag_periodicity;
int max_intra_size_pct;
@@ -156,7 +156,7 @@
if (argc != 8+mode_to_num_layers[layering_mode])
die ("Invalid number of arguments");
- if (!vpx_img_alloc (&raw, VPX_IMG_FMT_I420, width, height, 1))
+ if (!vpx_img_alloc (&raw, VPX_IMG_FMT_I420, width, height, 32))
die ("Failed to allocate image", width, height);
printf("Using %s\n",vpx_codec_iface_name(interface));
@@ -438,6 +438,7 @@
}
case 8:
+ default:
{
// 3-layers
int ids[4] = {0,2,1,2};
@@ -469,8 +470,6 @@
VP8_EFLAG_NO_UPD_ENTROPY;
break;
}
- default:
- break;
}
// Open input file
@@ -494,7 +493,6 @@
// Cap CPU & first I-frame size
vpx_codec_control (&codec, VP8E_SET_CPUUSED, -6);
vpx_codec_control (&codec, VP8E_SET_STATIC_THRESHOLD, 800);
- vpx_codec_control (&codec, VP8E_SET_NOISE_SENSITIVITY, 2);
max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5)
* ((double) cfg.g_timebase.den / cfg.g_timebase.num)
diff --git a/vpx/src/vpx_decoder_compat.c b/vpx/src/vpx_decoder_compat.c
deleted file mode 100644
index 4fe00ce..0000000
--- a/vpx/src/vpx_decoder_compat.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-
-/*!\file
- * \brief Provides the high level interface to wrap decoder algorithms.
- *
- */
-#include <stdlib.h>
-#include <string.h>
-#include "vpx/vpx_decoder.h"
-#include "vpx/internal/vpx_codec_internal.h"
-
-#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
-
-const char *vpx_dec_iface_name(vpx_dec_iface_t *iface)
-{
- return vpx_codec_iface_name((vpx_codec_iface_t *)iface);
-}
-
-const char *vpx_dec_err_to_string(vpx_dec_err_t err)
-{
- return vpx_codec_err_to_string(err);
-}
-
-const char *vpx_dec_error(vpx_dec_ctx_t *ctx)
-{
- return vpx_codec_error((vpx_codec_ctx_t *)ctx);
-}
-
-const char *vpx_dec_error_detail(vpx_dec_ctx_t *ctx)
-{
- return vpx_codec_error_detail((vpx_codec_ctx_t *)ctx);
-}
-
-
-vpx_dec_err_t vpx_dec_init_ver(vpx_dec_ctx_t *ctx,
- vpx_dec_iface_t *iface,
- int ver)
-{
- return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
- (vpx_codec_iface_t *)iface,
- NULL,
- 0,
- ver);
-}
-
-
-vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx)
-{
- return vpx_codec_destroy((vpx_codec_ctx_t *)ctx);
-}
-
-
-vpx_dec_caps_t vpx_dec_get_caps(vpx_dec_iface_t *iface)
-{
- return vpx_codec_get_caps((vpx_codec_iface_t *)iface);
-}
-
-
-vpx_dec_err_t vpx_dec_peek_stream_info(vpx_dec_iface_t *iface,
- const uint8_t *data,
- unsigned int data_sz,
- vpx_dec_stream_info_t *si)
-{
- return vpx_codec_peek_stream_info((vpx_codec_iface_t *)iface, data, data_sz,
- (vpx_codec_stream_info_t *)si);
-}
-
-
-vpx_dec_err_t vpx_dec_get_stream_info(vpx_dec_ctx_t *ctx,
- vpx_dec_stream_info_t *si)
-{
- return vpx_codec_get_stream_info((vpx_codec_ctx_t *)ctx,
- (vpx_codec_stream_info_t *)si);
-}
-
-
-vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t *ctx,
- int ctrl_id,
- void *data)
-{
- return vpx_codec_control_((vpx_codec_ctx_t *)ctx, ctrl_id, data);
-}
-
-
-vpx_dec_err_t vpx_dec_decode(vpx_dec_ctx_t *ctx,
- uint8_t *data,
- unsigned int data_sz,
- void *user_priv,
- int rel_pts)
-{
- (void)rel_pts;
- return vpx_codec_decode((vpx_codec_ctx_t *)ctx, data, data_sz, user_priv,
- 0);
-}
-
-vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t *ctx,
- vpx_dec_iter_t *iter)
-{
- return vpx_codec_get_frame((vpx_codec_ctx_t *)ctx, iter);
-}
-
-
-vpx_dec_err_t vpx_dec_register_put_frame_cb(vpx_dec_ctx_t *ctx,
- vpx_dec_put_frame_cb_fn_t cb,
- void *user_priv)
-{
- return vpx_codec_register_put_frame_cb((vpx_codec_ctx_t *)ctx, cb,
- user_priv);
-}
-
-
-vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t *ctx,
- vpx_dec_put_slice_cb_fn_t cb,
- void *user_priv)
-{
- return vpx_codec_register_put_slice_cb((vpx_codec_ctx_t *)ctx, cb,
- user_priv);
-}
-
-
-vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t *ctx,
- vpx_dec_iface_t *iface,
- int ver)
-{
- return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
- (vpx_codec_iface_t *)iface,
- NULL,
- VPX_CODEC_USE_XMA,
- ver);
-}
-
-vpx_dec_err_t vpx_dec_get_mem_map(vpx_dec_ctx_t *ctx_,
- vpx_dec_mmap_t *mmap,
- const vpx_dec_stream_info_t *si,
- vpx_dec_iter_t *iter)
-{
- vpx_codec_ctx_t *ctx = (vpx_codec_ctx_t *)ctx_;
- vpx_dec_err_t res = VPX_DEC_OK;
-
- if (!ctx || !mmap || !si || !iter || !ctx->iface)
- res = VPX_DEC_INVALID_PARAM;
- else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
- res = VPX_DEC_ERROR;
- else
- {
- if (!ctx->config.dec)
- {
- ctx->config.dec = malloc(sizeof(vpx_codec_dec_cfg_t));
- ctx->config.dec->w = si->w;
- ctx->config.dec->h = si->h;
- }
-
- res = ctx->iface->get_mmap(ctx, mmap, iter);
- }
-
- return SAVE_STATUS(ctx, res);
-}
-
-
-vpx_dec_err_t vpx_dec_set_mem_map(vpx_dec_ctx_t *ctx_,
- vpx_dec_mmap_t *mmap,
- unsigned int num_maps)
-{
- vpx_codec_ctx_t *ctx = (vpx_codec_ctx_t *)ctx_;
- vpx_dec_err_t res = VPX_DEC_MEM_ERROR;
-
- if (!ctx || !mmap || !ctx->iface)
- res = VPX_DEC_INVALID_PARAM;
- else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
- res = VPX_DEC_ERROR;
- else
- {
- void *save = (ctx->priv) ? NULL : ctx->config.dec;
- unsigned int i;
-
- for (i = 0; i < num_maps; i++, mmap++)
- {
- if (!mmap->base)
- break;
-
- /* Everything look ok, set the mmap in the decoder */
- res = ctx->iface->set_mmap(ctx, mmap);
-
- if (res)
- break;
- }
-
- if (save) free(save);
- }
-
- return SAVE_STATUS(ctx, res);
-}
diff --git a/vpx/vp8.h b/vpx/vp8.h
index 393b161..2952203 100644
--- a/vpx/vp8.h
+++ b/vpx/vp8.h
@@ -119,13 +119,5 @@
/*! @} - end defgroup vp8 */
-#if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT
-/* The following definitions are provided for backward compatibility with
- * the VP8 1.0.x SDK. USE IN PRODUCTION CODE IS NOT RECOMMENDED.
- */
-
-DECLSPEC_DEPRECATED extern vpx_codec_iface_t vpx_codec_vp8_algo DEPRECATED;
-#endif
-
#include "vpx_codec_impl_bottom.h"
#endif
diff --git a/vpx/vp8e.h b/vpx/vp8e.h
deleted file mode 100644
index ca907c9..0000000
--- a/vpx/vp8e.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-
-/* This file contains backwards compatibility stubs for applications using
- * the VP8 version 1.0 API.
- */
-#ifndef VP8E_H
-#define VP8E_H
-#include "vpx_codec_impl_top.h"
-
-#if defined(VPX_CODEC_DISABLE_COMPAT) && VPX_CODEC_DISABLE_COMPAT
-#error "Backwards compatibility disabled: don't include vp8e.h"
-#endif
-
-#include "vp8cx.h"
-DECLSPEC_DEPRECATED extern vpx_codec_iface_t vpx_enc_vp8_algo DEPRECATED;
-
-
-enum
-{
- VP8E_SET_REFERENCE = VP8_SET_REFERENCE,
- VP8E_COPY_REFERENCE = VP8_COPY_REFERENCE,
- VP8E_SET_PREVIEWPP = VP8_SET_POSTPROC,
- VP8E_SET_FLUSHFLAG = 4,
- VP8E_SET_FRAMETYPE = 10,
- VP8E_SET_ENCODING_MODE = 12
-};
-
-#define NORMAL_FRAME (0)
-#define KEY_FRAME (1)
-
-/* Change VP8E to VP8 to get the undeprecated version of these (defined in
- * vp8.h)
- */
-VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_REFERENCE, vpx_ref_frame_t *)
-VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_COPY_REFERENCE, vpx_ref_frame_t *)
-VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_PREVIEWPP, vp8_postproc_cfg_t *)
-
-
-/* Flush is done by calling vpx_codec_encode with a NULL input image. */
-VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_FLUSHFLAG, int)
-
-
-/* Frame type is set with a flag to vpx_codec_control. See VPX_EFLAG_FORCE_KF
- */
-VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_FRAMETYPE, int)
-
-
-/* This control has been deprecated in favor of the duration parameter to
- * vpx_codec_encode(). Use the #VPX_DL_REALTIME, #VPX_DL_GOOD_QUALITY,
- * #VPX_DL_BEST_QUALITY constants to that parameter instead.
- */
-VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_ENCODING_MODE, vp8e_encoding_mode)
-#include "vpx_codec_impl_bottom.h"
-#endif
diff --git a/vpx/vpx_codec.mk b/vpx/vpx_codec.mk
index f2500ba..427fd0f 100644
--- a/vpx/vpx_codec.mk
+++ b/vpx/vpx_codec.mk
@@ -12,9 +12,7 @@
API_EXPORTS += exports
API_SRCS-yes += src/vpx_decoder.c
-API_SRCS-yes += src/vpx_decoder_compat.c
API_SRCS-yes += vpx_decoder.h
-API_SRCS-yes += vpx_decoder_compat.h
API_SRCS-yes += src/vpx_encoder.c
API_SRCS-yes += vpx_encoder.h
API_SRCS-yes += internal/vpx_codec_internal.h
diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h
index 6b03ede..7992cc4 100644
--- a/vpx/vpx_decoder.h
+++ b/vpx/vpx_decoder.h
@@ -327,7 +327,3 @@
#ifdef __cplusplus
}
#endif
-
-#if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT
-#include "vpx_decoder_compat.h"
-#endif
diff --git a/vpx/vpx_decoder_compat.h b/vpx/vpx_decoder_compat.h
deleted file mode 100644
index 8adc1b9..0000000
--- a/vpx/vpx_decoder_compat.h
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-
-/*!\defgroup decoder Common Decoder Algorithm Interface
- * This abstraction allows applications using this decoder to easily support
- * multiple video formats with minimal code duplication. This section describes
- * the interface common to all codecs.
- * @{
- */
-
-/*!\file
- * \brief Provides a compatibility layer between version 1 and 2 of this API.
- *
- * This interface has been deprecated. Only existing code should make use
- * of this interface, and therefore, it is only thinly documented. Existing
- * code should be ported to the vpx_codec_* API.
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef VPX_DECODER_COMPAT_H
-#define VPX_DECODER_COMPAT_H
-
- /*!\brief Decoder algorithm return codes */
- typedef enum {
- /*!\brief Operation completed without error */
- VPX_DEC_OK = VPX_CODEC_OK,
-
- /*!\brief Unspecified error */
- VPX_DEC_ERROR = VPX_CODEC_ERROR,
-
- /*!\brief Memory operation failed */
- VPX_DEC_MEM_ERROR = VPX_CODEC_MEM_ERROR,
-
- /*!\brief ABI version mismatch */
- VPX_DEC_ABI_MISMATCH = VPX_CODEC_ABI_MISMATCH,
-
- /*!\brief The given bitstream is not supported.
- *
- * The bitstream was unable to be parsed at the highest level. The decoder
- * is unable to proceed. This error \ref SHOULD be treated as fatal to the
- * stream. */
- VPX_DEC_UNSUP_BITSTREAM = VPX_CODEC_UNSUP_BITSTREAM,
-
- /*!\brief Encoded bitstream uses an unsupported feature
- *
- * The decoder does not implement a feature required by the encoder. This
- * return code should only be used for features that prevent future
- * pictures from being properly decoded. This error \ref MAY be treated as
- * fatal to the stream or \ref MAY be treated as fatal to the current GOP.
- */
- VPX_DEC_UNSUP_FEATURE = VPX_CODEC_UNSUP_FEATURE,
-
- /*!\brief The coded data for this stream is corrupt or incomplete
- *
- * There was a problem decoding the current frame. This return code
- * should only be used for failures that prevent future pictures from
- * being properly decoded. This error \ref MAY be treated as fatal to the
- * stream or \ref MAY be treated as fatal to the current GOP. If decoding
- * is continued for the current GOP, artifacts may be present.
- */
- VPX_DEC_CORRUPT_FRAME = VPX_CODEC_CORRUPT_FRAME,
-
- /*!\brief An application-supplied parameter is not valid.
- *
- */
- VPX_DEC_INVALID_PARAM = VPX_CODEC_INVALID_PARAM,
-
- /*!\brief An iterator reached the end of list.
- *
- */
- VPX_DEC_LIST_END = VPX_CODEC_LIST_END
-
- }
- vpx_dec_err_t;
-
- /*! \brief Decoder capabilities bitfield
- *
- * Each decoder advertises the capabilities it supports as part of its
- * ::vpx_dec_iface_t interface structure. Capabilities are extra interfaces
- * or functionality, and are not required to be supported by a decoder.
- *
- * The available flags are specified by VPX_DEC_CAP_* defines.
- */
- typedef int vpx_dec_caps_t;
-#define VPX_DEC_CAP_PUT_SLICE 0x0001 /**< Will issue put_slice callbacks */
-#define VPX_DEC_CAP_PUT_FRAME 0x0002 /**< Will issue put_frame callbacks */
-#define VPX_DEC_CAP_XMA 0x0004 /**< Supports eXternal Memory Allocation */
-
- /*!\brief Stream properties
- *
- * This structure is used to query or set properties of the decoded
- * stream. Algorithms may extend this structure with data specific
- * to their bitstream by setting the sz member appropriately.
- */
-#if 1
- typedef vpx_codec_stream_info_t vpx_dec_stream_info_t;
-#else
- typedef struct
- {
- unsigned int sz; /**< Size of this structure */
- unsigned int w; /**< Width (or 0 for unknown/default) */
- unsigned int h; /**< Height (or 0 for unknown/default) */
- unsigned int is_kf; /**< Current frame is a keyframe */
- } vpx_dec_stream_info_t;
-#endif
-
-
- /*!\brief Decoder interface structure.
- *
- * Contains function pointers and other data private to the decoder
- * implementation. This structure is opaque to the application.
- */
- typedef const struct vpx_codec_iface vpx_dec_iface_t;
- typedef struct vpx_codec_priv vpx_dec_priv_t;
-
- /*!\brief Iterator
- *
- * Opaque storage used for iterating over lists.
- */
- typedef vpx_codec_iter_t vpx_dec_iter_t;
-
- /*!\brief Decoder context structure
- *
- * All decoders \ref MUST support this context structure fully. In general,
- * this data should be considered private to the decoder algorithm, and
- * not be manipulated or examined by the calling application. Applications
- * may reference the 'name' member to get a printable description of the
- * algorithm.
- */
-#if 1
- typedef vpx_codec_ctx_t vpx_dec_ctx_t;
-#else
- typedef struct
- {
- const char *name; /**< Printable interface name */
- vpx_dec_iface_t *iface; /**< Interface pointers */
- vpx_dec_err_t err; /**< Last returned error */
- vpx_dec_priv_t *priv; /**< Algorithm private storage */
- } vpx_dec_ctx_t;
-#endif
-
-
- /*!\brief Return the build configuration
- *
- * Returns a printable string containing an encoded version of the build
- * configuration. This may be useful to vpx support.
- *
- */
- const char *vpx_dec_build_config(void) DEPRECATED;
-
- /*!\brief Return the name for a given interface
- *
- * Returns a human readable string for name of the given decoder interface.
- *
- * \param[in] iface Interface pointer
- *
- */
- const char *vpx_dec_iface_name(vpx_dec_iface_t *iface) DEPRECATED;
-
-
- /*!\brief Convert error number to printable string
- *
- * Returns a human readable string for the last error returned by the
- * algorithm. The returned error will be one line and will not contain
- * any newline characters.
- *
- *
- * \param[in] err Error number.
- *
- */
- const char *vpx_dec_err_to_string(vpx_dec_err_t err) DEPRECATED;
-
-
- /*!\brief Retrieve error synopsis for decoder context
- *
- * Returns a human readable string for the last error returned by the
- * algorithm. The returned error will be one line and will not contain
- * any newline characters.
- *
- *
- * \param[in] ctx Pointer to this instance's context.
- *
- */
- const char *vpx_dec_error(vpx_dec_ctx_t *ctx) DEPRECATED;
-
-
- /*!\brief Retrieve detailed error information for decoder context
- *
- * Returns a human readable string providing detailed information about
- * the last error.
- *
- * \param[in] ctx Pointer to this instance's context.
- *
- * \retval NULL
- * No detailed information is available.
- */
- const char *vpx_dec_error_detail(vpx_dec_ctx_t *ctx) DEPRECATED;
-
-
- /* REQUIRED FUNCTIONS
- *
- * The following functions are required to be implemented for all decoders.
- * They represent the base case functionality expected of all decoders.
- */
-
-
- /*!\brief Initialize a decoder instance
- *
- * Initializes a decoder context using the given interface. Applications
- * should call the vpx_dec_init convenience macro instead of this
- * function directly, to ensure that the ABI version number parameter
- * is properly initialized.
- *
- * \param[in] ctx Pointer to this instance's context.
- * \param[in] iface Pointer to the algorithm interface to use.
- * \param[in] ver ABI version number. Must be set to
- * VPX_DECODER_ABI_VERSION
- * \retval #VPX_DEC_OK
- * The decoder algorithm initialized.
- * \retval #VPX_DEC_MEM_ERROR
- * Memory allocation failed.
- */
- vpx_dec_err_t vpx_dec_init_ver(vpx_dec_ctx_t *ctx,
- vpx_dec_iface_t *iface,
- int ver) DEPRECATED;
-#define vpx_dec_init(ctx, iface) \
- vpx_dec_init_ver(ctx, iface, VPX_DECODER_ABI_VERSION)
-
-
- /*!\brief Destroy a decoder instance
- *
- * Destroys a decoder context, freeing any associated memory buffers.
- *
- * \param[in] ctx Pointer to this instance's context
- *
- * \retval #VPX_DEC_OK
- * The decoder algorithm initialized.
- * \retval #VPX_DEC_MEM_ERROR
- * Memory allocation failed.
- */
- vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx) DEPRECATED;
-
-
- /*!\brief Get the capabilities of an algorithm.
- *
- * Retrieves the capabilities bitfield from the algorithm's interface.
- *
- * \param[in] iface Pointer to the algorithm interface
- *
- */
- vpx_dec_caps_t vpx_dec_get_caps(vpx_dec_iface_t *iface) DEPRECATED;
-
-
- /*!\brief Parse stream info from a buffer
- *
- * Performs high level parsing of the bitstream. Construction of a decoder
- * context is not necessary. Can be used to determine if the bitstream is
- * of the proper format, and to extract information from the stream.
- *
- * \param[in] iface Pointer to the algorithm interface
- * \param[in] data Pointer to a block of data to parse
- * \param[in] data_sz Size of the data buffer
- * \param[in,out] si Pointer to stream info to update. The size member
- * \ref MUST be properly initialized, but \ref MAY be
- * clobbered by the algorithm. This parameter \ref MAY
- * be NULL.
- *
- * \retval #VPX_DEC_OK
- * Bitstream is parsable and stream information updated
- */
- vpx_dec_err_t vpx_dec_peek_stream_info(vpx_dec_iface_t *iface,
- const uint8_t *data,
- unsigned int data_sz,
- vpx_dec_stream_info_t *si) DEPRECATED;
-
-
- /*!\brief Return information about the current stream.
- *
- * Returns information about the stream that has been parsed during decoding.
- *
- * \param[in] ctx Pointer to this instance's context
- * \param[in,out] si Pointer to stream info to update. The size member
- * \ref MUST be properly initialized, but \ref MAY be
- * clobbered by the algorithm. This parameter \ref MAY
- * be NULL.
- *
- * \retval #VPX_DEC_OK
- * Bitstream is parsable and stream information updated
- */
- vpx_dec_err_t vpx_dec_get_stream_info(vpx_dec_ctx_t *ctx,
- vpx_dec_stream_info_t *si) DEPRECATED;
-
-
- /*!\brief Control algorithm
- *
- * This function is used to exchange algorithm specific data with the decoder
- * instance. This can be used to implement features specific to a particular
- * algorithm.
- *
- * This wrapper function dispatches the request to the helper function
- * associated with the given ctrl_id. It tries to call this function
- * transparently, but will return #VPX_DEC_ERROR if the request could not
- * be dispatched.
- *
- * \param[in] ctx Pointer to this instance's context
- * \param[in] ctrl_id Algorithm specific control identifier
- * \param[in,out] data Data to exchange with algorithm instance.
- *
- * \retval #VPX_DEC_OK
- * The control request was processed.
- * \retval #VPX_DEC_ERROR
- * The control request was not processed.
- * \retval #VPX_DEC_INVALID_PARAM
- * The data was not valid.
- */
- vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t *ctx,
- int ctrl_id,
- void *data) DEPRECATED;
-
- /*!\brief Decode data
- *
- * Processes a buffer of coded data. If the processing results in a new
- * decoded frame becoming available, #VPX_DEC_CB_PUT_SLICE and
- * #VPX_DEC_CB_PUT_FRAME events may be generated, as appropriate. Encoded data
- * \ref MUST be passed in DTS (decode time stamp) order. Frames produced will
- * always be in PTS (presentation time stamp) order.
- *
- * \param[in] ctx Pointer to this instance's context
- * \param[in] data Pointer to this block of new coded data. If
- * NULL, a VPX_DEC_CB_PUT_FRAME event is posted
- * for the previously decoded frame.
- * \param[in] data_sz Size of the coded data, in bytes.
- * \param[in] user_priv Application specific data to associate with
- * this frame.
- * \param[in] rel_pts PTS relative to the previous frame, in us. If
- * unknown or unavailable, set to zero.
- *
- * \return Returns #VPX_DEC_OK if the coded data was processed completely
- * and future pictures can be decoded without error. Otherwise,
- * see the descriptions of the other error codes in ::vpx_dec_err_t
- * for recoverability capabilities.
- */
- vpx_dec_err_t vpx_dec_decode(vpx_dec_ctx_t *ctx,
- uint8_t *data,
- unsigned int data_sz,
- void *user_priv,
- int rel_pts) DEPRECATED;
-
-
- /*!\brief Decoded frames iterator
- *
- * Iterates over a list of the frames available for display. The iterator
- * storage should be initialized to NULL to start the iteration. Iteration is
- * complete when this function returns NULL.
- *
- * The list of available frames becomes valid upon completion of the
- * vpx_dec_decode call, and remains valid until the next call to vpx_dec_decode.
- *
- * \param[in] ctx Pointer to this instance's context
- * \param[in out] iter Iterator storage, initialized to NULL
- *
- * \return Returns a pointer to an image, if one is ready for display. Frames
- * produced will always be in PTS (presentation time stamp) order.
- */
- vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t *ctx,
- vpx_dec_iter_t *iter) DEPRECATED;
-
-
- /*!\defgroup cap_put_frame Frame-Based Decoding Functions
- *
- * The following functions are required to be implemented for all decoders
- * that advertise the VPX_DEC_CAP_PUT_FRAME capability. Calling these functions
- * for codecs that don't advertise this capability will result in an error
- * code being returned, usually VPX_DEC_ERROR
- * @{
- */
-
- /*!\brief put frame callback prototype
- *
- * This callback is invoked by the decoder to notify the application of
- * the availability of decoded image data.
- */
- typedef void (*vpx_dec_put_frame_cb_fn_t)(void *user_priv,
- const vpx_image_t *img);
-
-
- /*!\brief Register for notification of frame completion.
- *
- * Registers a given function to be called when a decoded frame is
- * available.
- *
- * \param[in] ctx Pointer to this instance's context
- * \param[in] cb Pointer to the callback function
- * \param[in] user_priv User's private data
- *
- * \retval #VPX_DEC_OK
- * Callback successfully registered.
- * \retval #VPX_DEC_ERROR
- * Decoder context not initialized, or algorithm not capable of
- * posting slice completion.
- */
- vpx_dec_err_t vpx_dec_register_put_frame_cb(vpx_dec_ctx_t *ctx,
- vpx_dec_put_frame_cb_fn_t cb,
- void *user_priv) DEPRECATED;
-
-
- /*!@} - end defgroup cap_put_frame */
-
- /*!\defgroup cap_put_slice Slice-Based Decoding Functions
- *
- * The following functions are required to be implemented for all decoders
- * that advertise the VPX_DEC_CAP_PUT_SLICE capability. Calling these functions
- * for codecs that don't advertise this capability will result in an error
- * code being returned, usually VPX_DEC_ERROR
- * @{
- */
-
- /*!\brief put slice callback prototype
- *
- * This callback is invoked by the decoder to notify the application of
- * the availability of partially decoded image data. The
- */
- typedef void (*vpx_dec_put_slice_cb_fn_t)(void *user_priv,
- const vpx_image_t *img,
- const vpx_image_rect_t *valid,
- const vpx_image_rect_t *update);
-
-
- /*!\brief Register for notification of slice completion.
- *
- * Registers a given function to be called when a decoded slice is
- * available.
- *
- * \param[in] ctx Pointer to this instance's context
- * \param[in] cb Pointer to the callback function
- * \param[in] user_priv User's private data
- *
- * \retval #VPX_DEC_OK
- * Callback successfully registered.
- * \retval #VPX_DEC_ERROR
- * Decoder context not initialized, or algorithm not capable of
- * posting slice completion.
- */
- vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t *ctx,
- vpx_dec_put_slice_cb_fn_t cb,
- void *user_priv) DEPRECATED;
-
-
- /*!@} - end defgroup cap_put_slice*/
-
- /*!\defgroup cap_xma External Memory Allocation Functions
- *
- * The following functions are required to be implemented for all decoders
- * that advertise the VPX_DEC_CAP_XMA capability. Calling these functions
- * for codecs that don't advertise this capability will result in an error
- * code being returned, usually VPX_DEC_ERROR
- * @{
- */
-
- /*!\brief Memory Map Entry
- *
- * This structure is used to contain the properties of a memory segment. It
- * is populated by the decoder in the request phase, and by the calling
- * application once the requested allocation has been performed.
- */
-#if 1
-#define VPX_DEC_MEM_ZERO 0x1 /**< Segment must be zeroed by allocation */
-#define VPX_DEC_MEM_WRONLY 0x2 /**< Segment need not be readable */
-#define VPX_DEC_MEM_FAST 0x4 /**< Place in fast memory, if available */
- typedef struct vpx_codec_mmap vpx_dec_mmap_t;
-#else
- typedef struct vpx_dec_mmap
- {
- /*
- * The following members are set by the codec when requesting a segment
- */
- unsigned int id; /**< identifier for the segment's contents */
- unsigned long sz; /**< size of the segment, in bytes */
- unsigned int align; /**< required alignment of the segment, in bytes */
- unsigned int flags; /**< bitfield containing segment properties */
-#define VPX_DEC_MEM_ZERO 0x1 /**< Segment must be zeroed by allocation */
-#define VPX_DEC_MEM_WRONLY 0x2 /**< Segment need not be readable */
-#define VPX_DEC_MEM_FAST 0x4 /**< Place in fast memory, if available */
-
- /* The following members are to be filled in by the allocation function */
- void *base; /**< pointer to the allocated segment */
- void (*dtor)(struct vpx_dec_mmap *map); /**< destructor to call */
- void *priv; /**< allocator private storage */
- } vpx_dec_mmap_t;
-#endif
-
- /*!\brief Initialize a decoder instance in external allocation mode
- *
- * Initializes a decoder context using the given interface. Applications
- * should call the vpx_dec_xma_init convenience macro instead of this
- * function directly, to ensure that the ABI version number parameter
- * is properly initialized.
- *
- * \param[in] ctx Pointer to this instance's context.
- * \param[in] iface Pointer to the algorithm interface to use.
- * \param[in] ver ABI version number. Must be set to
- * VPX_DECODER_ABI_VERSION
- * \retval #VPX_DEC_OK
- * The decoder algorithm initialized.
- * \retval #VPX_DEC_ERROR
- * Decoder does not support XMA mode.
- */
- vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t *ctx,
- vpx_dec_iface_t *iface,
- int ver) DEPRECATED;
-#define vpx_dec_xma_init(ctx, iface) \
- vpx_dec_xma_init_ver(ctx, iface, VPX_DECODER_ABI_VERSION)
-
-
- /*!\brief Iterate over the list of segments to allocate.
- *
- * Iterates over a list of the segments to allocate. The iterator storage
- * should be initialized to NULL to start the iteration. Iteration is complete
- * when this function returns VPX_DEC_LIST_END. The amount of memory needed to
- * allocate is dependent upon the size of the encoded stream. This means that
- * the stream info structure must be known at allocation time. It can be
- * populated with the vpx_dec_peek_stream_info() function. In cases where the
- * stream to be decoded is not available at allocation time, a fixed size must
- * be requested. The decoder will not be able to decode streams larger than
- * the size used at allocation time.
- *
- * \param[in] ctx Pointer to this instance's context.
- * \param[out] mmap Pointer to the memory map entry to populate.
- * \param[in] si Pointer to the stream info.
- * \param[in out] iter Iterator storage, initialized to NULL
- *
- * \retval #VPX_DEC_OK
- * The memory map entry was populated.
- * \retval #VPX_DEC_ERROR
- * Decoder does not support XMA mode.
- * \retval #VPX_DEC_MEM_ERROR
- * Unable to determine segment size from stream info.
- */
- vpx_dec_err_t vpx_dec_get_mem_map(vpx_dec_ctx_t *ctx,
- vpx_dec_mmap_t *mmap,
- const vpx_dec_stream_info_t *si,
- vpx_dec_iter_t *iter) DEPRECATED;
-
-
- /*!\brief Identify allocated segments to decoder instance
- *
- * Stores a list of allocated segments in the decoder. Segments \ref MUST be
- * passed in the order they are read from vpx_dec_get_mem_map(), but may be
- * passed in groups of any size. Segments \ref MUST be set only once. The
- * allocation function \ref MUST ensure that the vpx_dec_mmap_t::base member
- * is non-NULL. If the segment requires cleanup handling (e.g., calling free()
- * or close()) then the vpx_dec_mmap_t::dtor member \ref MUST be populated.
- *
- * \param[in] ctx Pointer to this instance's context.
- * \param[in] mmaps Pointer to the first memory map entry in the list.
- * \param[in] num_maps Number of entries being set at this time
- *
- * \retval #VPX_DEC_OK
- * The segment was stored in the decoder context.
- * \retval #VPX_DEC_ERROR
- * Decoder does not support XMA mode.
- * \retval #VPX_DEC_MEM_ERROR
- * Segment base address was not set, or segment was already stored.
-
- */
- vpx_dec_err_t vpx_dec_set_mem_map(vpx_dec_ctx_t *ctx,
- vpx_dec_mmap_t *mmaps,
- unsigned int num_maps) DEPRECATED;
-
- /*!@} - end defgroup cap_xma*/
- /*!@} - end defgroup decoder*/
-
-
-#endif
-#ifdef __cplusplus
-}
-#endif
diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h
index 885ca22..239036e 100644
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -32,8 +32,19 @@
#define VPX_ENCODER_H
#include "vpx_codec.h"
-#define MAX_PERIODICITY 16
-#define MAX_LAYERS 5
+/*! Temporal Scalability: Maximum length of the sequence defining frame
+ * layer membership
+ */
+#define VPX_TS_MAX_PERIODICITY 16
+
+/*! Temporal Scalability: Maximum number of coding layers */
+#define VPX_TS_MAX_LAYERS 5
+
+/*!\deprecated Use #VPX_TS_MAX_PERIODICITY instead. */
+#define MAX_PERIODICITY VPX_TS_MAX_PERIODICITY
+
+/*!\deprecated Use #VPX_TS_MAX_LAYERS instead. */
+#define MAX_LAYERS VPX_TS_MAX_LAYERS
/*!\brief Current ABI version number
*
@@ -608,14 +619,14 @@
*
* These values specify the target coding bitrate for each coding layer.
*/
- unsigned int ts_target_bitrate[MAX_LAYERS];
+ unsigned int ts_target_bitrate[VPX_TS_MAX_LAYERS];
/*!\brief Frame rate decimation factor for each layer
*
* These values specify the frame rate decimation factors to apply
* to each layer.
*/
- unsigned int ts_rate_decimator[MAX_LAYERS];
+ unsigned int ts_rate_decimator[VPX_TS_MAX_LAYERS];
/*!\brief Length of the sequence defining frame layer membership
*
@@ -633,7 +644,7 @@
* and odd numbered frames to a second layer (1) with ts_periodicity=8,
* then ts_layer_id = (0,1,0,1,0,1,0,1).
*/
- unsigned int ts_layer_id[MAX_PERIODICITY];
+ unsigned int ts_layer_id[VPX_TS_MAX_PERIODICITY];
} vpx_codec_enc_cfg_t; /**< alias for struct vpx_codec_enc_cfg */
diff --git a/vpx_ports/mem.h b/vpx_ports/mem.h
index 9ec34fe..29e507f 100644
--- a/vpx_ports/mem.h
+++ b/vpx_ports/mem.h
@@ -14,7 +14,7 @@
#include "vpx_config.h"
#include "vpx/vpx_integer.h"
-#if defined(__GNUC__) && __GNUC__
+#if (defined(__GNUC__) && __GNUC__) || defined(__SUNPRO_C)
#define DECLARE_ALIGNED(n,typ,val) typ val __attribute__ ((aligned (n)))
#elif defined(_MSC_VER)
#define DECLARE_ALIGNED(n,typ,val) __declspec(align(n)) typ val
diff --git a/vpx_ports/x86.h b/vpx_ports/x86.h
index 1f3d5eb..1341c7f 100644
--- a/vpx_ports/x86.h
+++ b/vpx_ports/x86.h
@@ -50,6 +50,26 @@
: "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
: "a" (func));
#endif
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#if ARCH_X86_64
+#define cpuid(func,ax,bx,cx,dx)\
+ asm volatile (\
+ "xchg %rsi, %rbx \n\t" \
+ "cpuid \n\t" \
+ "movl %ebx, %edi \n\t" \
+ "xchg %rsi, %rbx \n\t" \
+ : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
+ : "a" (func));
+#else
+#define cpuid(func,ax,bx,cx,dx)\
+ asm volatile (\
+ "pushl %ebx \n\t" \
+ "cpuid \n\t" \
+ "movl %ebx, %edi \n\t" \
+ "popl %ebx \n\t" \
+ : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
+ : "a" (func));
+#endif
#else
#if ARCH_X86_64
void __cpuid(int CPUInfo[4], int info_type);
@@ -136,6 +156,10 @@
unsigned int tsc;
__asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
return tsc;
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+ unsigned int tsc;
+ asm volatile("rdtsc\n\t":"=a"(tsc):);
+ return tsc;
#else
#if ARCH_X86_64
return __rdtsc();
@@ -149,6 +173,9 @@
#if defined(__GNUC__) && __GNUC__
#define x86_pause_hint()\
__asm__ __volatile__ ("pause \n\t")
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#define x86_pause_hint()\
+ asm volatile ("pause \n\t")
#else
#if ARCH_X86_64
#define x86_pause_hint()\
@@ -172,6 +199,19 @@
__asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):);
return mode;
}
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+static void
+x87_set_control_word(unsigned short mode)
+{
+ asm volatile("fldcw %0" : : "m"(*&mode));
+}
+static unsigned short
+x87_get_control_word(void)
+{
+ unsigned short mode;
+ asm volatile("fstcw %0\n\t":"=m"(*&mode):);
+ return mode;
+}
#elif ARCH_X86_64
/* No fldcw intrinsics on Windows x64, punt to external asm */
extern void vpx_winx64_fldcw(unsigned short mode);
diff --git a/vpxenc.c b/vpxenc.c
index 11d80de..b9aa8e1 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -1517,6 +1517,7 @@
int arg_ctrls[ARG_CTRL_CNT_MAX][2];
int arg_ctrl_cnt;
int write_webm;
+ int have_kf_max_dist;
};
@@ -1542,6 +1543,23 @@
};
+void validate_positive_rational(const char *msg,
+ struct vpx_rational *rat)
+{
+ if (rat->den < 0)
+ {
+ rat->num *= -1;
+ rat->den *= -1;
+ }
+
+ if (rat->num < 0)
+ die("Error: %s must be positive\n", msg);
+
+ if (!rat->den)
+ die("Error: %s has zero denominator\n", msg);
+}
+
+
static void parse_global_config(struct global_config *global, char **argv)
{
char **argi, **argj;
@@ -1610,6 +1628,7 @@
else if (arg_match(&arg, &framerate, argi))
{
global->framerate = arg_parse_rational(&arg);
+ validate_positive_rational(arg.name, &global->framerate);
global->have_framerate = 1;
}
else if (arg_match(&arg,&out_part, argi))
@@ -1807,7 +1826,10 @@
else if (arg_match(&arg, &stereo_mode, argi))
config->stereo_fmt = arg_parse_enum_or_int(&arg);
else if (arg_match(&arg, &timebase, argi))
+ {
config->cfg.g_timebase = arg_parse_rational(&arg);
+ validate_positive_rational(arg.name, &config->cfg.g_timebase);
+ }
else if (arg_match(&arg, &error_resilient, argi))
config->cfg.g_error_resilient = arg_parse_uint(&arg);
else if (arg_match(&arg, &lag_in_frames, argi))
@@ -1862,7 +1884,10 @@
else if (arg_match(&arg, &kf_min_dist, argi))
config->cfg.kf_min_dist = arg_parse_uint(&arg);
else if (arg_match(&arg, &kf_max_dist, argi))
+ {
config->cfg.kf_max_dist = arg_parse_uint(&arg);
+ config->have_kf_max_dist = 1;
+ }
else if (arg_match(&arg, &kf_disabled, argi))
config->cfg.kf_mode = VPX_KF_DISABLED;
else
@@ -1965,6 +1990,21 @@
}
+static void set_default_kf_interval(struct stream_state *stream,
+ struct global_config *global)
+{
+ /* Use a max keyframe interval of 5 seconds, if none was
+ * specified on the command line.
+ */
+ if (!stream->config.have_kf_max_dist)
+ {
+ double framerate = (double)global->framerate.num/global->framerate.den;
+ if (framerate > 0.0)
+ stream->config.cfg.kf_max_dist = 5.0*framerate;
+ }
+}
+
+
static void show_stream_config(struct stream_state *stream,
struct global_config *global,
struct input_state *input)
@@ -2381,6 +2421,8 @@
if (!global.have_framerate)
global.framerate = input.framerate;
+ FOREACH_STREAM(set_default_kf_interval(stream, &global));
+
/* Show configuration */
if (global.verbose && pass == 0)
FOREACH_STREAM(show_stream_config(stream, &global, &input));
@@ -2395,7 +2437,7 @@
vpx_img_alloc(&raw,
input.use_i420 ? VPX_IMG_FMT_I420
: VPX_IMG_FMT_YV12,
- input.w, input.h, 1);
+ input.w, input.h, 32);
FOREACH_STREAM(init_rate_histogram(&stream->rate_hist,
&stream->config.cfg,