summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure23
-rw-r--r--vp8/common/alloccommon.c18
-rw-r--r--vp8/common/blockd.h12
-rw-r--r--vp8/common/entropy.c6
-rw-r--r--vp8/common/entropy.h4
-rw-r--r--vp8/common/generic/systemdependent.c10
-rw-r--r--vp8/common/idctllm.c33
-rw-r--r--vp8/common/maskingmv.c855
-rw-r--r--vp8/common/onyxc_int.h1
-rw-r--r--vp8/common/quant_common.c45
-rw-r--r--vp8/common/reconintra4x4.c16
-rw-r--r--vp8/common/x86/mask_sse3.asm484
-rw-r--r--vp8/decoder/decodemv.c50
-rw-r--r--vp8/decoder/decodframe.c12
-rw-r--r--vp8/decoder/detokenize.c24
-rw-r--r--vp8/decoder/generic/dsystemdependent.c9
-rw-r--r--vp8/decoder/onyxd_if.c9
-rw-r--r--vp8/decoder/onyxd_int.h8
-rw-r--r--vp8/encoder/bitstream.c98
-rw-r--r--vp8/encoder/dct.c28
-rw-r--r--vp8/encoder/encodeframe.c181
-rw-r--r--vp8/encoder/encodemb.c4
-rw-r--r--vp8/encoder/firstpass.c2
-rw-r--r--vp8/encoder/generic/csystemdependent.c8
-rw-r--r--vp8/encoder/onyx_if.c125
-rw-r--r--vp8/encoder/onyx_int.h4
-rw-r--r--vp8/encoder/psnr.c2
-rw-r--r--vp8/encoder/ratectrl.c49
-rw-r--r--vp8/encoder/rdopt.c81
-rw-r--r--vp8/vp8_common.mk5
-rw-r--r--vp8/vp8_cx_iface.c56
-rw-r--r--vpx/vp8cx.h10
-rw-r--r--vpxenc.c10
33 files changed, 2160 insertions, 122 deletions
diff --git a/configure b/configure
index 7596d1124..772cded33 100755
--- a/configure
+++ b/configure
@@ -214,6 +214,11 @@ HAVE_LIST="
sys_mman_h
unistd_h
"
+EXPERIMENT_LIST="
+ extend_qrange
+ segmentation
+ csm
+"
CONFIG_LIST="
external_build
install_docs
@@ -255,6 +260,9 @@ CONFIG_LIST="
small
postproc_visualizer
os_support
+
+ experimental
+ ${EXPERIMENT_LIST}
"
CMDLINE_SELECT="
extra_warnings
@@ -295,6 +303,7 @@ CMDLINE_SELECT="
shared
small
postproc_visualizer
+ experimental
"
process_cmdline() {
@@ -302,7 +311,19 @@ process_cmdline() {
optval="${opt#*=}"
case "$opt" in
--disable-codecs) for c in ${CODECS}; do disable $c; done ;;
- *) process_common_cmdline "$opt"
+ --enable-?*|--disable-?*)
+ eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
+ if echo "${EXPERIMENT_LIST}" | grep "^ *$option\$" >/dev/null; then
+ if enabled experimental; then
+ $action $option
+ else
+ log_echo "Ignoring $opt -- not in experimental mode."
+ fi
+ else
+ process_common_cmdline $opt
+ fi
+ ;;
+ *) process_common_cmdline $opt
;;
esac
done
diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c
index 376707ec6..869f6e20f 100644
--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -148,7 +148,16 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
}
void vp8_setup_version(VP8_COMMON *cm)
{
- switch (cm->version)
+ if (cm->version & 0x4)
+ {
+ if (!CONFIG_EXPERIMENTAL)
+ vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+ "Bitstream was created by an experimental "
+ "encoder");
+ cm->experimental = 1;
+ }
+
+ switch (cm->version & 0x3)
{
case 0:
cm->no_lpf = 0;
@@ -174,13 +183,6 @@ void vp8_setup_version(VP8_COMMON *cm)
cm->use_bilinear_mc_filter = 1;
cm->full_pixel = 1;
break;
- default:
- /*4,5,6,7 are reserved for future use*/
- cm->no_lpf = 0;
- cm->filter_type = NORMAL_LOOPFILTER;
- cm->use_bilinear_mc_filter = 0;
- cm->full_pixel = 0;
- break;
}
}
void vp8_create_common(VP8_COMMON *oci)
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index 84c52773c..48929a869 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -29,6 +29,7 @@ void vpx_log(const char *format, ...);
#define DCPREDCNTTHRESH 3
#define MB_FEATURE_TREE_PROBS 3
+
#define MAX_MB_SEGMENTS 4
#define MAX_REF_LF_DELTAS 4
@@ -157,6 +158,7 @@ typedef struct
MB_PREDICTION_MODE mode, uv_mode;
MV_REFERENCE_FRAME ref_frame;
int_mv mv;
+ unsigned char segment_flag;
unsigned char partitioning;
unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */
@@ -230,11 +232,15 @@ typedef struct
/* 0 (do not update) 1 (update) the macroblock segmentation feature data. */
unsigned char mb_segement_abs_delta;
+ unsigned char temporal_update;
/* Per frame flags that define which MB level features (such as quantizer or loop filter level) */
/* are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO */
- vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS]; /* Probability Tree used to code Segment number */
-
- signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; /* Segment parameters */
+#if CONFIG_SEGMENTATION
+ vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS + 3]; // Probability Tree used to code Segment number
+#else
+ vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
+#endif
+ signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; // Segment parameters
/* mode_based Loop filter adjustment */
unsigned char mode_ref_lf_delta_enabled;
diff --git a/vp8/common/entropy.c b/vp8/common/entropy.c
index fba7a07ff..14821e72d 100644
--- a/vp8/common/entropy.c
+++ b/vp8/common/entropy.c
@@ -76,7 +76,7 @@ static const Prob Pcat3[] = { 173, 148, 140};
static const Prob Pcat4[] = { 176, 155, 140, 135};
static const Prob Pcat5[] = { 180, 157, 141, 134, 130};
static const Prob Pcat6[] =
-{ 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129};
+{ 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129};
static vp8_tree_index cat1[2], cat2[4], cat3[6], cat4[8], cat5[10], cat6[22];
@@ -111,7 +111,7 @@ static void init_bit_trees()
init_bit_tree(cat3, 3);
init_bit_tree(cat4, 4);
init_bit_tree(cat5, 5);
- init_bit_tree(cat6, 11);
+ init_bit_tree(cat6, 13);
}
vp8_extra_bit_struct vp8_extra_bits[12] =
@@ -126,7 +126,7 @@ vp8_extra_bit_struct vp8_extra_bits[12] =
{ cat3, Pcat3, 3, 11},
{ cat4, Pcat4, 4, 19},
{ cat5, Pcat5, 5, 35},
- { cat6, Pcat6, 11, 67},
+ { cat6, Pcat6, 13, 67},
{ 0, 0, 0, 0}
};
#include "defaultcoefcounts.h"
diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h
index 66d282b61..3c25453a7 100644
--- a/vp8/common/entropy.h
+++ b/vp8/common/entropy.h
@@ -27,7 +27,7 @@
#define DCT_VAL_CATEGORY3 7 /* 11-18 Extra Bits 3+1 */
#define DCT_VAL_CATEGORY4 8 /* 19-34 Extra Bits 4+1 */
#define DCT_VAL_CATEGORY5 9 /* 35-66 Extra Bits 5+1 */
-#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 11+1 */
+#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 13+1 */
#define DCT_EOB_TOKEN 11 /* EOB Extra Bits 0+0 */
#define MAX_ENTROPY_TOKENS 12
@@ -50,7 +50,7 @@ extern vp8_extra_bit_struct vp8_extra_bits[12]; /* indexed by token value */
#define PROB_UPDATE_BASELINE_COST 7
#define MAX_PROB 255
-#define DCT_MAX_VALUE 2048
+#define DCT_MAX_VALUE 8192
/* Coefficients are predicted via a 3-dimensional probability table. */
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
index 133938097..d9d439cf8 100644
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -129,9 +129,19 @@ void vp8_machine_specific_config(VP8_COMMON *ctx)
vp8_arch_x86_common_init(ctx);
#endif
+
#if ARCH_ARM
vp8_arch_arm_common_init(ctx);
#endif
+#if CONFIG_EXTEND_QRANGE
+ rtcd->idct.idct1 = vp8_short_idct4x4llm_1_c;
+ rtcd->idct.idct16 = vp8_short_idct4x4llm_c;
+ rtcd->idct.idct1_scalar_add = vp8_dc_only_idct_add_c;
+ rtcd->idct.iwalsh1 = vp8_short_inv_walsh4x4_1_c;
+ rtcd->idct.iwalsh16 = vp8_short_inv_walsh4x4_c;
+
+#endif
+
#if CONFIG_MULTITHREAD
ctx->processor_core_count = get_cpu_count();
diff --git a/vp8/common/idctllm.c b/vp8/common/idctllm.c
index 196062df6..c65d35adc 100644
--- a/vp8/common/idctllm.c
+++ b/vp8/common/idctllm.c
@@ -22,6 +22,8 @@
* so
* x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1).
**************************************************************************/
+#include "vpx_ports/config.h"
+
static const int cospi8sqrt2minus1 = 20091;
static const int sinpi8sqrt2 = 35468;
static const int rounding = 0;
@@ -75,11 +77,19 @@ void vp8_short_idct4x4llm_c(short *input, short *output, int pitch)
d1 = temp1 + temp2;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a1 + d1 + 4) >> 3;
op[3] = (a1 - d1 + 4) >> 3;
op[1] = (b1 + c1 + 4) >> 3;
op[2] = (b1 - c1 + 4) >> 3;
+#else
+ op[0] = (a1 + d1 + 16) >> 5;
+ op[3] = (a1 - d1 + 16) >> 5;
+
+ op[1] = (b1 + c1 + 16) >> 5;
+ op[2] = (b1 - c1 + 16) >> 5;
+#endif
ip += shortpitch;
op += shortpitch;
@@ -92,8 +102,11 @@ void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch)
int a1;
short *op = output;
int shortpitch = pitch >> 1;
+#if !CONFIG_EXTEND_QRANGE
a1 = ((input[0] + 4) >> 3);
-
+#else
+ a1 = ((input[0] + 16) >> 5);
+#endif
for (i = 0; i < 4; i++)
{
op[0] = a1;
@@ -106,7 +119,11 @@ void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch)
void vp8_dc_only_idct_add_c(short input_dc, unsigned char *pred_ptr, unsigned char *dst_ptr, int pitch, int stride)
{
+#if !CONFIG_EXTEND_QRANGE
int a1 = ((input_dc + 4) >> 3);
+#else
+ int a1 = ((input_dc + 16) >> 5);
+#endif
int r, c;
for (r = 0; r < 4; r++)
@@ -168,11 +185,17 @@ void vp8_short_inv_walsh4x4_c(short *input, short *output)
c2 = a1 - b1;
d2 = d1 - c1;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a2 + 3) >> 3;
op[1] = (b2 + 3) >> 3;
op[2] = (c2 + 3) >> 3;
op[3] = (d2 + 3) >> 3;
-
+#else
+ op[0] = (a2 + 1) >> 2;
+ op[1] = (b2 + 1) >> 2;
+ op[2] = (c2 + 1) >> 2;
+ op[3] = (d2 + 1) >> 2;
+#endif
ip += 4;
op += 4;
}
@@ -184,7 +207,11 @@ void vp8_short_inv_walsh4x4_1_c(short *input, short *output)
int a1;
short *op = output;
- a1 = ((input[0] + 3) >> 3);
+#if !CONFIG_EXTEND_QRANGE
+ a1 = (input[0] + 3 )>> 3;
+#else
+ a1 = (input[0] + 1 )>> 2;
+#endif
for (i = 0; i < 4; i++)
{
diff --git a/vp8/common/maskingmv.c b/vp8/common/maskingmv.c
new file mode 100644
index 000000000..d01a18fc8
--- /dev/null
+++ b/vp8/common/maskingmv.c
@@ -0,0 +1,855 @@
+/*
+ ============================================================================
+ Name : maskingmv.c
+ Author : jimbankoski
+ Version :
+ Copyright : Your copyright notice
+ Description : Hello World in C, Ansi-style
+ ============================================================================
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+extern unsigned int vp8_sad16x16_sse3(
+ unsigned char *src_ptr,
+ int src_stride,
+ unsigned char *ref_ptr,
+ int ref_stride,
+ int max_err);
+
+extern void vp8_sad16x16x3_sse3(
+ unsigned char *src_ptr,
+ int src_stride,
+ unsigned char *ref_ptr,
+ int ref_stride,
+ int *results);
+
+extern int vp8_growmaskmb_sse3(
+ unsigned char *om,
+ unsigned char *nm);
+
+extern void vp8_makemask_sse3(
+ unsigned char *y,
+ unsigned char *u,
+ unsigned char *v,
+ unsigned char *ym,
+ int yp,
+ int uvp,
+ int ys,
+ int us,
+ int vs,
+ int yt,
+ int ut,
+ int vt);
+
+unsigned int vp8_sad16x16_unmasked_wmt(
+ unsigned char *src_ptr,
+ int src_stride,
+ unsigned char *ref_ptr,
+ int ref_stride,
+ unsigned char *mask);
+
+unsigned int vp8_sad16x16_masked_wmt(
+ unsigned char *src_ptr,
+ int src_stride,
+ unsigned char *ref_ptr,
+ int ref_stride,
+ unsigned char *mask);
+
+unsigned int vp8_masked_predictor_wmt(
+ unsigned char *masked,
+ unsigned char *unmasked,
+ int src_stride,
+ unsigned char *dst_ptr,
+ int dst_stride,
+ unsigned char *mask);
+unsigned int vp8_masked_predictor_uv_wmt(
+ unsigned char *masked,
+ unsigned char *unmasked,
+ int src_stride,
+ unsigned char *dst_ptr,
+ int dst_stride,
+ unsigned char *mask);
+unsigned int vp8_uv_from_y_mask(
+ unsigned char *ymask,
+ unsigned char *uvmask);
+int yp=16;
+unsigned char sxy[]=
+{
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90
+};
+
+unsigned char sts[]=
+{
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+};
+unsigned char str[]=
+{
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+};
+
+unsigned char y[]=
+{
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
+40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,
+60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,
+60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,
+60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,
+40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,
+40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
+40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
+40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40
+};
+int uvp=8;
+unsigned char u[]=
+{
+90,80,70,70,90,90,90,17,
+90,80,70,70,90,90,90,17,
+84,70,70,90,90,90,17,17,
+84,70,70,90,90,90,17,17,
+80,70,70,90,90,90,17,17,
+90,80,70,70,90,90,90,17,
+90,80,70,70,90,90,90,17,
+90,80,70,70,90,90,90,17
+};
+
+unsigned char v[]=
+{
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80
+};
+
+unsigned char ym[256];
+unsigned char uvm[64];
+typedef struct
+{
+ unsigned char y;
+ unsigned char yt;
+ unsigned char u;
+ unsigned char ut;
+ unsigned char v;
+ unsigned char vt;
+ unsigned char use;
+} COLOR_SEG_ELEMENT;
+
+/*
+COLOR_SEG_ELEMENT segmentation[]=
+{
+ { 60,4,80,17,80,10, 1},
+ { 40,4,15,10,80,10, 1},
+};
+*/
+
+COLOR_SEG_ELEMENT segmentation[]=
+{
+ { 79,44,92,44, 237,60, 1},
+};
+
+unsigned char pixel_mask(unsigned char y,unsigned char u,unsigned char v,
+ COLOR_SEG_ELEMENT sgm[],
+ int c)
+{
+ COLOR_SEG_ELEMENT *s=sgm;
+ unsigned char m =0;
+ int i;
+ for(i=0;i<c;i++,s++)
+ m |= ( abs(y-s->y)< s->yt &&
+ abs(u-s->u)< s->ut &&
+ abs(v-s->v)< s->vt ? 255 : 0 );
+
+ return m;
+}
+int neighbors[256][8];
+int makeneighbors(void)
+{
+ int i,j;
+ for(i=0;i<256;i++)
+ {
+ int r=(i>>4),c=(i&15);
+ int ni=0;
+ for(j=0;j<8;j++)
+ neighbors[i][j]=i;
+ for(j=0;j<256;j++)
+ {
+ int nr=(j>>4),nc=(j&15);
+ if(abs(nr-r)<2&&abs(nc-c)<2)
+ neighbors[i][ni++]=j;
+ }
+ }
+ return 0;
+}
+void grow_ymask(unsigned char *ym)
+{
+ unsigned char nym[256];
+ int i,j;
+
+ for(i=0;i<256;i++)
+ {
+ nym[i]=ym[i];
+ for(j=0;j<8;j++)
+ {
+ nym[i]|=ym[neighbors[i][j]];
+ }
+ }
+ for(i=0;i<256;i++)
+ ym[i]=nym[i];
+}
+void make_mb_mask(unsigned char *y, unsigned char *u, unsigned char *v,
+ unsigned char *ym, unsigned char *uvm,
+ int yp, int uvp,
+ COLOR_SEG_ELEMENT sgm[],
+ int count)
+{
+ int r,c;
+ unsigned char *oym = ym;
+
+ memset(ym,20,256);
+ for(r=0;r<8;r++,uvm+=8,u+=uvp,v+=uvp,y+=(yp+yp),ym+=32)
+ for(c=0;c<8;c++)
+ {
+ int y1=y[c<<1];
+ int u1=u[c];
+ int v1=v[c];
+ int m = pixel_mask(y1,u1,v1,sgm,count);
+ uvm[c] = m;
+ ym[c<<1] = uvm[c];// = pixel_mask(y[c<<1],u[c],v[c],sgm,count);
+ ym[(c<<1)+1] = pixel_mask(y[1+(c<<1)],u[c],v[c],sgm,count);
+ ym[(c<<1)+16] = pixel_mask(y[yp+(c<<1)],u[c],v[c],sgm,count);
+ ym[(c<<1)+17] = pixel_mask(y[1+yp+(c<<1)],u[c],v[c],sgm,count);
+ }
+ grow_ymask(oym);
+}
+
+int masked_sad(unsigned char *src, int p, unsigned char *dst, int dp,
+ unsigned char *ym )
+{
+ int i,j;
+ unsigned sad = 0;
+ for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16)
+ for(j=0;j<16;j++)
+ if(ym[j])
+ sad+= abs(src[j]-dst[j]);
+
+ return sad;
+}
+
+int compare_masks(unsigned char *sym, unsigned char *ym)
+{
+ int i,j;
+ unsigned sad = 0;
+ for(i=0;i<16;i++,sym += 16,ym+=16)
+ for(j=0;j<16;j++)
+ sad+= (sym[j]!=ym[j]?1:0);
+
+ return sad;
+}
+int unmasked_sad(unsigned char *src, int p, unsigned char *dst, int dp,
+ unsigned char *ym)
+{
+ int i,j;
+ unsigned sad = 0;
+ for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16)
+ for(j=0;j<16;j++)
+ if(!ym[j])
+ sad+= abs(src[j]-dst[j]);
+
+ return sad;
+}
+int masked_motion_search( unsigned char *y, unsigned char *u, unsigned char *v,
+ int yp, int uvp,
+ unsigned char *dy, unsigned char *du, unsigned char *dv,
+ int dyp, int duvp,
+ COLOR_SEG_ELEMENT sgm[],
+ int count,
+ int *mi,
+ int *mj,
+ int *ui,
+ int *uj,
+ int *wm)
+{
+ int i,j;
+
+ unsigned char ym[256];
+ unsigned char uvm[64];
+ unsigned char dym[256];
+ unsigned char duvm[64];
+ unsigned int e = 0 ;
+ int beste=256;
+ int bmi=-32,bmj=-32;
+ int bui=-32,buj=-32;
+ int beste1=256;
+ int bmi1=-32,bmj1=-32;
+ int bui1=-32,buj1=-32;
+ int obeste;
+
+ // first try finding best mask and then unmasked
+ beste = 0xffffffff;
+
+ // find best unmasked mv
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ unsigned char *duz = i/2*duvp + du;
+ unsigned char *dvz = i/2*duvp + dv;
+ for(j=-32;j<32;j++)
+ {
+ // 0,0 masked destination
+ make_mb_mask(dyz+j,duz+j/2, dvz+j/2, dym, duvm, dyp, duvp,sgm,count);
+
+ e = unmasked_sad(y, yp, dyz+j, dyp, dym );
+
+ if(e<beste)
+ {
+ bui=i;
+ buj=j;
+ beste=e;
+ }
+ }
+ }
+ //bui=0;buj=0;
+ // best mv masked destination
+ make_mb_mask(dy+bui*dyp+buj,du+bui/2*duvp+buj/2, dv+bui/2*duvp+buj/2,
+ dym, duvm, dyp, duvp,sgm,count);
+
+ obeste = beste;
+ beste = 0xffffffff;
+
+ // find best masked
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ for(j=-32;j<32;j++)
+ {
+ e = masked_sad(y, yp, dyz+j, dyp, dym );
+
+ if(e<beste)
+ {
+ bmi=i;
+ bmj=j;
+ beste=e;
+ }
+ }
+ }
+ beste1=beste+obeste;
+ bmi1=bmi;bmj1=bmj;
+ bui1=bui;buj1=buj;
+
+ beste = 0xffffffff;
+ // source mask
+ make_mb_mask(y,u, v, ym, uvm, yp, uvp,sgm,count);
+
+ // find best mask
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ unsigned char *duz = i/2*duvp + du;
+ unsigned char *dvz = i/2*duvp + dv;
+ for(j=-32;j<32;j++)
+ {
+ // 0,0 masked destination
+ make_mb_mask(dyz+j,duz+j/2, dvz+j/2, dym, duvm, dyp, duvp,sgm,count);
+
+ e = compare_masks(ym, dym);
+
+ if(e<beste)
+ {
+ bmi=i;
+ bmj=j;
+ beste=e;
+ }
+ }
+ }
+
+
+ // best mv masked destination
+ make_mb_mask(dy+bmi*dyp+bmj,du+bmi/2*duvp+bmj/2, dv+bmi/2*duvp+bmj/2,
+ dym, duvm, dyp, duvp,sgm,count);
+
+ obeste = masked_sad(y, yp, dy+bmi*dyp+bmj, dyp, dym );
+
+ beste = 0xffffffff;
+
+ // find best unmasked mv
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ for(j=-32;j<32;j++)
+ {
+ e = unmasked_sad(y, yp, dyz+j, dyp, dym );
+
+ if(e<beste)
+ {
+ bui=i;
+ buj=j;
+ beste=e;
+ }
+ }
+ }
+ beste += obeste;
+
+
+ if(beste<beste1)
+ {
+ *mi = bmi;
+ *mj = bmj;
+ *ui = bui;
+ *uj = buj;
+ *wm = 1;
+ }
+ else
+ {
+ *mi = bmi1;
+ *mj = bmj1;
+ *ui = bui1;
+ *uj = buj1;
+ *wm = 0;
+
+ }
+ return 0;
+}
+
+int predict(unsigned char *src, int p, unsigned char *dst, int dp,
+ unsigned char *ym, unsigned char *prd )
+{
+ int i,j;
+ for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16, prd+=16)
+ for(j=0;j<16;j++)
+ prd[j]=(ym[j] ? src[j]:dst[j]);
+ return 0;
+}
+
+int fast_masked_motion_search( unsigned char *y, unsigned char *u, unsigned char *v,
+ int yp, int uvp,
+ unsigned char *dy, unsigned char *du, unsigned char *dv,
+ int dyp, int duvp,
+ COLOR_SEG_ELEMENT sgm[],
+ int count,
+ int *mi,
+ int *mj,
+ int *ui,
+ int *uj,
+ int *wm)
+{
+ int i,j;
+
+ unsigned char ym[256];
+ unsigned char ym2[256];
+ unsigned char uvm[64];
+ unsigned char dym2[256];
+ unsigned char dym[256];
+ unsigned char duvm[64];
+ unsigned int e = 0 ;
+ int beste=256;
+ int bmi=-32,bmj=-32;
+ int bui=-32,buj=-32;
+ int beste1=256;
+ int bmi1=-32,bmj1=-32;
+ int bui1=-32,buj1=-32;
+ int obeste;
+
+ // first try finding best mask and then unmasked
+ beste = 0xffffffff;
+
+#if 0
+ for(i=0;i<16;i++)
+ {
+ unsigned char *dy = i*yp + y;
+ for(j=0;j<16;j++)
+ printf("%2x",dy[j]);
+ printf("\n");
+ }
+ printf("\n");
+
+ for(i=-32;i<48;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ for(j=-32;j<48;j++)
+ printf("%2x",dyz[j]);
+ printf("\n");
+ }
+#endif
+
+ // find best unmasked mv
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ unsigned char *duz = i/2*duvp + du;
+ unsigned char *dvz = i/2*duvp + dv;
+ for(j=-32;j<32;j++)
+ {
+ // 0,0 masked destination
+ vp8_makemask_sse3(dyz+j,duz+j/2, dvz+j/2, dym, dyp, duvp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+
+ vp8_growmaskmb_sse3(dym,dym2);
+
+ e = vp8_sad16x16_unmasked_wmt(y, yp, dyz+j, dyp, dym2 );
+
+ if(e<beste)
+ {
+ bui=i;
+ buj=j;
+ beste=e;
+ }
+ }
+ }
+ //bui=0;buj=0;
+ // best mv masked destination
+
+ vp8_makemask_sse3(dy+bui*dyp+buj,du+bui/2*duvp+buj/2, dv+bui/2*duvp+buj/2,
+ dym, dyp, duvp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+
+ vp8_growmaskmb_sse3(dym,dym2);
+
+ obeste = beste;
+ beste = 0xffffffff;
+
+ // find best masked
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ for(j=-32;j<32;j++)
+ {
+ e = vp8_sad16x16_masked_wmt(y, yp, dyz+j, dyp, dym2 );
+ if(e<beste)
+ {
+ bmi=i;
+ bmj=j;
+ beste=e;
+ }
+ }
+ }
+ beste1=beste+obeste;
+ bmi1=bmi;bmj1=bmj;
+ bui1=bui;buj1=buj;
+
+ // source mask
+ vp8_makemask_sse3(y,u, v,
+ ym, yp, uvp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+
+ vp8_growmaskmb_sse3(ym,ym2);
+
+ // find best mask
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ unsigned char *duz = i/2*duvp + du;
+ unsigned char *dvz = i/2*duvp + dv;
+ for(j=-32;j<32;j++)
+ {
+ // 0,0 masked destination
+ vp8_makemask_sse3(dyz+j,duz+j/2, dvz+j/2, dym, dyp, duvp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+
+ vp8_growmaskmb_sse3(dym,dym2);
+
+ e = compare_masks(ym2, dym2);
+
+ if(e<beste)
+ {
+ bmi=i;
+ bmj=j;
+ beste=e;
+ }
+ }
+ }
+
+ vp8_makemask_sse3(dy+bmi*dyp+bmj,du+bmi/2*duvp+bmj/2, dv+bmi/2*duvp+bmj/2,
+ dym, dyp, duvp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+
+ vp8_growmaskmb_sse3(dym,dym2);
+
+ obeste = vp8_sad16x16_masked_wmt(y, yp, dy+bmi*dyp+bmj, dyp, dym2 );
+
+ beste = 0xffffffff;
+
+ // find best unmasked mv
+ for(i=-32;i<32;i++)
+ {
+ unsigned char *dyz = i*dyp + dy;
+ for(j=-32;j<32;j++)
+ {
+ e = vp8_sad16x16_unmasked_wmt(y, yp, dyz+j, dyp, dym2 );
+
+ if(e<beste)
+ {
+ bui=i;
+ buj=j;
+ beste=e;
+ }
+ }
+ }
+ beste += obeste;
+
+ if(beste<beste1)
+ {
+ *mi = bmi;
+ *mj = bmj;
+ *ui = bui;
+ *uj = buj;
+ *wm = 1;
+ }
+ else
+ {
+ *mi = bmi1;
+ *mj = bmj1;
+ *ui = bui1;
+ *uj = buj1;
+ *wm = 0;
+ beste=beste1;
+
+ }
+ return beste;
+}
+
+int predict_all(unsigned char *ym, unsigned char *um, unsigned char *vm,
+ int ymp, int uvmp,
+ unsigned char *yp, unsigned char *up, unsigned char *vp,
+ int ypp, int uvpp,
+ COLOR_SEG_ELEMENT sgm[],
+ int count,
+ int mi,
+ int mj,
+ int ui,
+ int uj,
+ int wm)
+{
+ int i,j;
+ unsigned char dym[256];
+ unsigned char dym2[256];
+ unsigned char duvm[64];
+ unsigned char *yu=ym,*uu=um, *vu=vm;
+
+ unsigned char *dym3=dym2;
+
+ ym+=mi*ymp+mj;
+ um+=mi/2*uvmp+mj/2;
+ vm+=mi/2*uvmp+mj/2;
+
+ yu+=ui*ymp+uj;
+ uu+=ui/2*uvmp+uj/2;
+ vu+=ui/2*uvmp+uj/2;
+
+ // best mv masked destination
+ if(wm)
+ vp8_makemask_sse3(ym,um, vm, dym, ymp, uvmp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+ else
+ vp8_makemask_sse3(yu,uu, vu, dym, ymp, uvmp,
+ sgm[0].y,sgm[0].u,sgm[0].v,
+ sgm[0].yt,sgm[0].ut,sgm[0].vt);
+
+ vp8_growmaskmb_sse3(dym,dym2);
+ vp8_masked_predictor_wmt(ym,yu,ymp,yp,ypp,dym3);
+ vp8_uv_from_y_mask(dym3,duvm);
+ vp8_masked_predictor_uv_wmt(um,uu,uvmp,up,uvpp,duvm);
+ vp8_masked_predictor_uv_wmt(vm,vu,uvmp,vp,uvpp,duvm);
+
+ return 0;
+}
+
+unsigned char f0p[1280*720*3/2];
+unsigned char f1p[1280*720*3/2];
+unsigned char prd[1280*720*3/2];
+unsigned char msk[1280*720*3/2];
+
+
+int mainz(int argc, char *argv[]) {
+
+ FILE *f=fopen(argv[1],"rb");
+ FILE *g=fopen(argv[2],"wb");
+ int w=atoi(argv[3]),h=atoi(argv[4]);
+ int y_stride=w,uv_stride=w/2;
+ int r,c;
+ unsigned char *f0=f0p,*f1=f1p,*t;
+ unsigned char ym[256],uvm[64];
+ unsigned char ym2[256],uvm2[64];
+ unsigned char ym3[256],uvm3[64];
+ int a,b;
+
+ COLOR_SEG_ELEMENT last={ 20,20,20,20, 230,20, 1},best;
+#if 0
+ makeneighbors();
+ COLOR_SEG_ELEMENT segmentation[]=
+ {
+ { 60,4,80,17,80,10, 1},
+ { 40,4,15,10,80,10, 1},
+ };
+ make_mb_mask(y, u, v,ym2,uvm2,16,8,segmentation,1);
+
+ vp8_makemask_sse3(y,u,v,ym, (int) 16,(int) 8,
+ (int) segmentation[0].y,(int) segmentation[0].u,(int) segmentation[0].v,
+ segmentation[0].yt,segmentation[0].ut,segmentation[0].vt);
+
+ vp8_growmaskmb_sse3(ym,ym3);
+
+ a = vp8_sad16x16_masked_wmt(str,16,sts,16,ym3);
+ b = vp8_sad16x16_unmasked_wmt(str,16,sts,16,ym3);
+
+ vp8_masked_predictor_wmt(str,sts,16,ym,16,ym3);
+
+ vp8_uv_from_y_mask(ym3,uvm3);
+
+ return 4;
+#endif
+ makeneighbors();
+
+
+ memset(prd,128,w*h*3/2);
+
+ fread(f0,w*h*3/2,1,f);
+
+ while(!feof(f))
+ {
+ unsigned char *ys=f1,*yd=f0,*yp=prd;
+ unsigned char *us=f1+w*h,*ud=f0+w*h,*up=prd+w*h;
+ unsigned char *vs=f1+w*h*5/4,*vd=f0+w*h*5/4,*vp=prd+w*h*5/4;
+ fread(f1,w*h*3/2,1,f);
+
+ ys+=32*y_stride;yd+=32*y_stride;yp+=32*y_stride;
+ us+=16*uv_stride;ud+=16*uv_stride;up+=16*uv_stride;
+ vs+=16*uv_stride;vd+=16*uv_stride;vp+=16*uv_stride;
+ for(r=32;r<h-32;r+=16,
+ ys+=16*w,yd+=16*w,yp+=16*w,
+ us+=8*uv_stride,ud+=8*uv_stride,up+=8*uv_stride,
+ vs+=8*uv_stride,vd+=8*uv_stride,vp+=8*uv_stride)
+ {
+ for(c=32;c<w-32;c+=16)
+ {
+ int mi,mj,ui,uj,wm;
+ int bmi,bmj,bui,buj,bwm;
+ unsigned char ym[256];
+
+ if(vp8_sad16x16_sse3( ys+c,y_stride, yd+c,y_stride,0xffff) == 0)
+ bmi=bmj=bui=buj=bwm=0;
+ else
+ {
+ COLOR_SEG_ELEMENT cs[5];
+ int j;
+ unsigned int beste=0xfffffff;
+ unsigned int bestj=0;
+
+ // try color from last mb segmentation
+ cs[0] = last;
+
+ // try color segs from 4 pixels in mb recon as segmentation
+ cs[1].y = yd[c + y_stride + 1];cs[1].u = ud[c/2 + uv_stride];
+ cs[1].v = vd[c/2 + uv_stride];
+ cs[1].yt = cs[1].ut = cs[1].vt = 20;
+ cs[2].y = yd[c + w + 14];
+ cs[2].u = ud[c/2 + uv_stride+7];
+ cs[2].v = vd[c/2 + uv_stride+7];
+ cs[2].yt = cs[2].ut = cs[2].vt = 20;
+ cs[3].y = yd[c + w*14 + 1];
+ cs[3].u = ud[c/2 + uv_stride*7];
+ cs[3].v = vd[c/2 + uv_stride*7];
+ cs[3].yt = cs[3].ut = cs[3].vt = 20;
+ cs[4].y = yd[c + w*14 + 14];
+ cs[4].u = ud[c/2 + uv_stride*7+7];
+ cs[4].v = vd[c/2 + uv_stride*7+7];
+ cs[4].yt = cs[4].ut = cs[4].vt = 20;
+
+ for(j=0;j<5;j++)
+ {
+ int e;
+
+ e = fast_masked_motion_search(
+ ys+c, us+c/2, vs+c/2, y_stride, uv_stride,
+ yd+c, ud+c/2, vd+c/2, y_stride, uv_stride,
+ &cs[j], 1, &mi,&mj,&ui,&uj,&wm);
+
+ if(e<beste)
+ {
+ bmi=mi;bmj=mj;bui=ui;buj=uj,bwm=wm;
+ bestj=j;
+ beste=e;
+ }
+ }
+ best = cs[bestj];
+ //best = segmentation[0];
+ last = best;
+ }
+ predict_all(yd+c, ud+c/2, vd+c/2, w, uv_stride,
+ yp+c, up+c/2, vp+c/2, w, uv_stride,
+ &best, 1, bmi,bmj,bui,buj,bwm);
+
+ }
+ }
+ fwrite(prd,w*h*3/2,1,g);
+ t=f0;
+ f0=f1;
+ f1=t;
+
+ }
+ fclose(f);
+ fclose(g);
+ return;
+}
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index a381dfe87..7bbe5676c 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -119,6 +119,7 @@ typedef struct VP8Common
int mode_info_stride;
/* profile settings */
+ int experimental;
int mb_no_coeff_skip;
int no_lpf;
int use_bilinear_mc_filter;
diff --git a/vp8/common/quant_common.c b/vp8/common/quant_common.c
index e9833fe33..b8e6e2972 100644
--- a/vp8/common/quant_common.c
+++ b/vp8/common/quant_common.c
@@ -11,6 +11,8 @@
#include "quant_common.h"
+
+#if !CONFIG_EXTEND_QRANGE
static const int dc_qlookup[QINDEX_RANGE] =
{
4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17,
@@ -34,7 +36,32 @@ static const int ac_qlookup[QINDEX_RANGE] =
155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209,
213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284,
};
+#else
+
+static const int dc_qlookup[QINDEX_RANGE] =
+{
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36, 38, 40, 42,
+ 44, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88,
+ 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
+ 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 205, 210, 215, 220,
+ 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300,
+ 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460,
+ 472, 484, 496, 508, 520, 532, 544, 556, 572, 588, 608, 628, 648, 668, 692, 720,
+};
+static const int ac_qlookup[QINDEX_RANGE] =
+{
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 51,
+ 54, 57, 60, 63, 66, 69, 72, 76, 80, 84, 88, 92, 96, 100, 105, 110,
+ 115, 120, 125, 130, 135, 140, 146, 152, 158, 164, 170, 176, 182, 188, 194, 200,
+ 206, 212, 218, 224, 232, 240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320,
+ 330, 340, 350, 360, 370, 380, 392, 404, 416, 428, 440, 454, 468, 482, 496, 510,
+ 524, 540, 556, 572, 588, 604, 622, 640, 658, 676, 696, 716, 736, 756, 776, 796,
+ 820, 844, 868, 892, 916, 944, 972, 1000, 1032, 1064, 1096, 1128, 1168, 1208, 1252, 1300
+};
+#endif
int vp8_dc_quant(int QIndex, int Delta)
{
@@ -62,7 +89,11 @@ int vp8_dc2quant(int QIndex, int Delta)
else if (QIndex < 0)
QIndex = 0;
+#if !CONFIG_EXTEND_QRANGE
retval = dc_qlookup[ QIndex ] * 2;
+#else
+ retval = dc_qlookup[ QIndex ];
+#endif
return retval;
}
@@ -72,16 +103,13 @@ int vp8_dc_uv_quant(int QIndex, int Delta)
QIndex = QIndex + Delta;
- if (QIndex > 127)
- QIndex = 127;
+ if (QIndex > 117)
+ QIndex = 117;
else if (QIndex < 0)
QIndex = 0;
retval = dc_qlookup[ QIndex ];
- if (retval > 132)
- retval = 132;
-
return retval;
}
@@ -108,12 +136,13 @@ int vp8_ac2quant(int QIndex, int Delta)
QIndex = 127;
else if (QIndex < 0)
QIndex = 0;
-
+#if !CONFIG_EXTEND_QRANGE
retval = (ac_qlookup[ QIndex ] * 155) / 100;
-
if (retval < 8)
retval = 8;
-
+#else
+ retval = ac_qlookup[ QIndex ];
+#endif
return retval;
}
int vp8_ac_uv_quant(int QIndex, int Delta)
diff --git a/vp8/common/reconintra4x4.c b/vp8/common/reconintra4x4.c
index 18c514541..12e2e60c7 100644
--- a/vp8/common/reconintra4x4.c
+++ b/vp8/common/reconintra4x4.c
@@ -81,10 +81,10 @@ void vp8_intra4x4_predict(BLOCKD *x,
{
unsigned int ap[4];
- ap[0] = (top_left + 2 * Above[0] + Above[1] + 2) >> 2;
- ap[1] = (Above[0] + 2 * Above[1] + Above[2] + 2) >> 2;
- ap[2] = (Above[1] + 2 * Above[2] + Above[3] + 2) >> 2;
- ap[3] = (Above[2] + 2 * Above[3] + Above[4] + 2) >> 2;
+ ap[0] = Above[0];
+ ap[1] = Above[1];
+ ap[2] = Above[2];
+ ap[3] = Above[3];
for (r = 0; r < 4; r++)
{
@@ -105,10 +105,10 @@ void vp8_intra4x4_predict(BLOCKD *x,
{
unsigned int lp[4];
- lp[0] = (top_left + 2 * Left[0] + Left[1] + 2) >> 2;
- lp[1] = (Left[0] + 2 * Left[1] + Left[2] + 2) >> 2;
- lp[2] = (Left[1] + 2 * Left[2] + Left[3] + 2) >> 2;
- lp[3] = (Left[2] + 2 * Left[3] + Left[3] + 2) >> 2;
+ lp[0] = Left[0];
+ lp[1] = Left[1];
+ lp[2] = Left[2];
+ lp[3] = Left[3];
for (r = 0; r < 4; r++)
{
diff --git a/vp8/common/x86/mask_sse3.asm b/vp8/common/x86/mask_sse3.asm
new file mode 100644
index 000000000..0d90cfa86
--- /dev/null
+++ b/vp8/common/x86/mask_sse3.asm
@@ -0,0 +1,484 @@
+;
+; 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.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;void int vp8_makemask_sse3(
+; unsigned char *y,
+; unsigned char *u,
+; unsigned char *v,
+; unsigned char *ym,
+; unsigned char *uvm,
+; int yp,
+; int uvp,
+; int ys,
+; int us,
+; int vs,
+; int yt,
+; int ut,
+; int vt)
+global sym(vp8_makemask_sse3)
+sym(vp8_makemask_sse3):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 14
+ push rsi
+ push rdi
+ ; end prolog
+
+ mov rsi, arg(0) ;y
+ mov rdi, arg(1) ;u
+ mov rcx, arg(2) ;v
+ mov rax, arg(3) ;ym
+ movsxd rbx, dword arg(4) ;yp
+ movsxd rdx, dword arg(5) ;uvp
+
+ pxor xmm0,xmm0
+
+ ;make 16 copies of the center y value
+ movd xmm1, arg(6)
+ pshufb xmm1, xmm0
+
+ ; make 16 copies of the center u value
+ movd xmm2, arg(7)
+ pshufb xmm2, xmm0
+
+ ; make 16 copies of the center v value
+ movd xmm3, arg(8)
+ pshufb xmm3, xmm0
+ unpcklpd xmm2, xmm3
+
+ ;make 16 copies of the y tolerance
+ movd xmm3, arg(9)
+ pshufb xmm3, xmm0
+
+ ;make 16 copies of the u tolerance
+ movd xmm4, arg(10)
+ pshufb xmm4, xmm0
+
+ ;make 16 copies of the v tolerance
+ movd xmm5, arg(11)
+ pshufb xmm5, xmm0
+ unpckhpd xmm4, xmm5
+
+ mov r8,8
+
+NextPairOfRows:
+
+ ;grab the y source values
+ movdqu xmm0, [rsi]
+
+ ;compute abs difference between source and y target
+ movdqa xmm6, xmm1
+ movdqa xmm7, xmm0
+ psubusb xmm0, xmm1
+ psubusb xmm6, xmm7
+ por xmm0, xmm6
+
+ ;compute abs difference between
+ movdqa xmm6, xmm3
+ pcmpgtb xmm6, xmm0
+
+ ;grab the y source values
+ add rsi, rbx
+ movdqu xmm0, [rsi]
+
+ ;compute abs difference between source and y target
+ movdqa xmm11, xmm1
+ movdqa xmm7, xmm0
+ psubusb xmm0, xmm1
+ psubusb xmm11, xmm7
+ por xmm0, xmm11
+
+ ;compute abs difference between
+ movdqa xmm11, xmm3
+ pcmpgtb xmm11, xmm0
+
+
+ ;grab the u and v source values
+ movdqu xmm7, [rdi]
+ movdqu xmm8, [rcx]
+ unpcklpd xmm7, xmm8
+
+ ;compute abs difference between source and uv targets
+ movdqa xmm9, xmm2
+ movdqa xmm10, xmm7
+ psubusb xmm7, xmm2
+ psubusb xmm9, xmm10
+ por xmm7, xmm9
+
+ ;check whether the number is < tolerance
+ movdqa xmm0, xmm4
+ pcmpgtb xmm0, xmm7
+
+ ;double u and v masks
+ movdqa xmm8, xmm0
+ punpckhbw xmm0, xmm0
+ punpcklbw xmm8, xmm8
+
+ ;mask row 0 and output
+ pand xmm6, xmm8
+ pand xmm6, xmm0
+ movdqa [rax],xmm6
+
+ ;mask row 1 and output
+ pand xmm11, xmm8
+ pand xmm11, xmm0
+ movdqa [rax+16],xmm11
+
+
+ ; to the next row or set of rows
+ add rsi, rbx
+ add rdi, rdx
+ add rcx, rdx
+ add rax,32
+ dec r8
+ jnz NextPairOfRows
+
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+;GROW_HORIZ (register for result, source register or mem local)
+; takes source and shifts left and ors with source
+; then shifts right and ors with source
+%macro GROW_HORIZ 2
+ movdqa %1, %2
+ movdqa xmm14, %1
+ movdqa xmm15, %1
+ pslldq xmm14, 1
+ psrldq xmm15, 1
+ por %1,xmm14
+ por %1,xmm15
+%endmacro
+;GROW_VERT (result, center row, above row, below row)
+%macro GROW_VERT 4
+ movdqa %1,%2
+ por %1,%3
+ por %1,%4
+%endmacro
+
+;GROW_NEXTLINE (new line to grow, new source, line to write)
+%macro GROW_NEXTLINE 3
+ GROW_HORIZ %1, %2
+ GROW_VERT xmm3, xmm0, xmm1, xmm2
+ movdqa %3,xmm3
+%endmacro
+
+
+;void int vp8_growmaskmb_sse3(
+; unsigned char *om,
+; unsigned char *nm,
+global sym(vp8_growmaskmb_sse3)
+sym(vp8_growmaskmb_sse3):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 2
+ push rsi
+ push rdi
+ ; end prolog
+
+ mov rsi, arg(0) ;src
+ mov rdi, arg(1) ;rst
+
+ GROW_HORIZ xmm0, [rsi]
+ GROW_HORIZ xmm1, [rsi+16]
+ GROW_HORIZ xmm2, [rsi+32]
+
+ GROW_VERT xmm3, xmm0, xmm1, xmm2
+ por xmm0,xmm1
+ movdqa [rdi], xmm0
+ movdqa [rdi+16],xmm3
+
+ GROW_NEXTLINE xmm0,[rsi+48],[rdi+32]
+ GROW_NEXTLINE xmm1,[rsi+64],[rdi+48]
+ GROW_NEXTLINE xmm2,[rsi+80],[rdi+64]
+ GROW_NEXTLINE xmm0,[rsi+96],[rdi+80]
+ GROW_NEXTLINE xmm1,[rsi+112],[rdi+96]
+ GROW_NEXTLINE xmm2,[rsi+128],[rdi+112]
+ GROW_NEXTLINE xmm0,[rsi+144],[rdi+128]
+ GROW_NEXTLINE xmm1,[rsi+160],[rdi+144]
+ GROW_NEXTLINE xmm2,[rsi+176],[rdi+160]
+ GROW_NEXTLINE xmm0,[rsi+192],[rdi+176]
+ GROW_NEXTLINE xmm1,[rsi+208],[rdi+192]
+ GROW_NEXTLINE xmm2,[rsi+224],[rdi+208]
+ GROW_NEXTLINE xmm0,[rsi+240],[rdi+224]
+
+ por xmm0,xmm2
+ movdqa [rdi+240], xmm0
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+
+
+;unsigned int vp8_sad16x16_masked_wmt(
+; unsigned char *src_ptr,
+; int src_stride,
+; unsigned char *ref_ptr,
+; int ref_stride,
+; unsigned char *mask)
+global sym(vp8_sad16x16_masked_wmt)
+sym(vp8_sad16x16_masked_wmt):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 5
+ push rsi
+ push rdi
+ ; end prolog
+ mov rsi, arg(0) ;src_ptr
+ mov rdi, arg(2) ;ref_ptr
+
+ mov rbx, arg(4) ;mask
+ movsxd rax, dword ptr arg(1) ;src_stride
+ movsxd rdx, dword ptr arg(3) ;ref_stride
+
+ mov rcx, 16
+
+ pxor xmm3, xmm3
+
+NextSadRow:
+ movdqu xmm0, [rsi]
+ movdqu xmm1, [rdi]
+ movdqu xmm2, [rbx]
+ pand xmm0, xmm2
+ pand xmm1, xmm2
+
+ psadbw xmm0, xmm1
+ paddw xmm3, xmm0
+
+ add rsi, rax
+ add rdi, rdx
+ add rbx, 16
+
+ dec rcx
+ jnz NextSadRow
+
+ movdqa xmm4 , xmm3
+ psrldq xmm4, 8
+ paddw xmm3, xmm4
+ movq rax, xmm3
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+
+;unsigned int vp8_sad16x16_unmasked_wmt(
+; unsigned char *src_ptr,
+; int src_stride,
+; unsigned char *ref_ptr,
+; int ref_stride,
+; unsigned char *mask)
+global sym(vp8_sad16x16_unmasked_wmt)
+sym(vp8_sad16x16_unmasked_wmt):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 5
+ push rsi
+ push rdi
+ ; end prolog
+ mov rsi, arg(0) ;src_ptr
+ mov rdi, arg(2) ;ref_ptr
+
+ mov rbx, arg(4) ;mask
+ movsxd rax, dword ptr arg(1) ;src_stride
+ movsxd rdx, dword ptr arg(3) ;ref_stride
+
+ mov rcx, 16
+
+ pxor xmm3, xmm3
+
+next_vp8_sad16x16_unmasked_wmt:
+ movdqu xmm0, [rsi]
+ movdqu xmm1, [rdi]
+ movdqu xmm2, [rbx]
+ por xmm0, xmm2
+ por xmm1, xmm2
+
+ psadbw xmm0, xmm1
+ paddw xmm3, xmm0
+
+ add rsi, rax
+ add rdi, rdx
+ add rbx, 16
+
+ dec rcx
+ jnz next_vp8_sad16x16_unmasked_wmt
+
+ movdqa xmm4 , xmm3
+ psrldq xmm4, 8
+ paddw xmm3, xmm4
+ movq rax, xmm3
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+
+;unsigned int vp8_masked_predictor_wmt(
+; unsigned char *masked,
+; unsigned char *unmasked,
+; int src_stride,
+; unsigned char *dst_ptr,
+; int dst_stride,
+; unsigned char *mask)
+global sym(vp8_masked_predictor_wmt)
+sym(vp8_masked_predictor_wmt):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 6
+ push rsi
+ push rdi
+ ; end prolog
+ mov rsi, arg(0) ;src_ptr
+ mov rdi, arg(1) ;ref_ptr
+
+ mov rbx, arg(5) ;mask
+ movsxd rax, dword ptr arg(2) ;src_stride
+ mov r11, arg(3) ; destination
+ movsxd rdx, dword ptr arg(4) ;dst_stride
+
+ mov rcx, 16
+
+ pxor xmm3, xmm3
+
+next_vp8_masked_predictor_wmt:
+ movdqu xmm0, [rsi]
+ movdqu xmm1, [rdi]
+ movdqu xmm2, [rbx]
+
+ pand xmm0, xmm2
+ pandn xmm2, xmm1
+ por xmm0, xmm2
+ movdqu [r11], xmm0
+
+ add r11, rdx
+ add rsi, rax
+ add rdi, rdx
+ add rbx, 16
+
+ dec rcx
+ jnz next_vp8_masked_predictor_wmt
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+;unsigned int vp8_masked_predictor_uv_wmt(
+; unsigned char *masked,
+; unsigned char *unmasked,
+; int src_stride,
+; unsigned char *dst_ptr,
+; int dst_stride,
+; unsigned char *mask)
+global sym(vp8_masked_predictor_uv_wmt)
+sym(vp8_masked_predictor_uv_wmt):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 6
+ push rsi
+ push rdi
+ ; end prolog
+ mov rsi, arg(0) ;src_ptr
+ mov rdi, arg(1) ;ref_ptr
+
+ mov rbx, arg(5) ;mask
+ movsxd rax, dword ptr arg(2) ;src_stride
+ mov r11, arg(3) ; destination
+ movsxd rdx, dword ptr arg(4) ;dst_stride
+
+ mov rcx, 8
+
+ pxor xmm3, xmm3
+
+next_vp8_masked_predictor_uv_wmt:
+ movq xmm0, [rsi]
+ movq xmm1, [rdi]
+ movq xmm2, [rbx]
+
+ pand xmm0, xmm2
+ pandn xmm2, xmm1
+ por xmm0, xmm2
+ movq [r11], xmm0
+
+ add r11, rdx
+ add rsi, rax
+ add rdi, rax
+ add rbx, 8
+
+ dec rcx
+ jnz next_vp8_masked_predictor_uv_wmt
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+
+;unsigned int vp8_uv_from_y_mask(
+; unsigned char *ymask,
+; unsigned char *uvmask)
+global sym(vp8_uv_from_y_mask)
+sym(vp8_uv_from_y_mask):
+ push rbp
+ mov rbp, rsp
+ SHADOW_ARGS_TO_STACK 6
+ push rsi
+ push rdi
+ ; end prolog
+ mov rsi, arg(0) ;src_ptr
+ mov rdi, arg(1) ;dst_ptr
+
+
+ mov rcx, 8
+
+ pxor xmm3, xmm3
+
+next_p8_uv_from_y_mask:
+ movdqu xmm0, [rsi]
+ pshufb xmm0, [shuf1b] ;[GLOBAL(shuf1b)]
+ movq [rdi],xmm0
+ add rdi, 8
+ add rsi,32
+
+ dec rcx
+ jnz next_p8_uv_from_y_mask
+
+ ; begin epilog
+ pop rdi
+ pop rsi
+ UNSHADOW_ARGS
+ pop rbp
+ ret
+
+SECTION_RODATA
+align 16
+shuf1b:
+ db 0, 2, 4, 6, 8, 10, 12, 14, 0, 0, 0, 0, 0, 0, 0, 0
+
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 01d940233..485aba053 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -208,11 +208,13 @@ static const unsigned char mbsplit_fill_offset[4][16] = {
-
static void mb_mode_mv_init(VP8D_COMP *pbi)
{
vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc;
+#if CONFIG_SEGMENTATION
+ MACROBLOCKD *const xd = & pbi->mb;
+#endif
#if CONFIG_ERROR_CONCEALMENT
/* Default is that no macroblock is corrupt, therefore we initialize
@@ -253,6 +255,9 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
}
read_mvcontexts(bc, mvc);
+#if CONFIG_SEGMENTATION
+ xd->temporal_update = vp8_read_bit(bc);
+#endif
}
}
@@ -263,7 +268,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc;
const int mis = pbi->common.mode_info_stride;
-
+#if CONFIG_SEGMENTATION
+ MACROBLOCKD *const xd = & pbi->mb;
+ int sum;
+ int index = mb_row * pbi->common.mb_cols + mb_col;
+#endif
int_mv *const mv = & mbmi->mv;
int mb_to_left_edge;
int mb_to_right_edge;
@@ -274,7 +283,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_bottom_edge = pbi->mb.mb_to_bottom_edge;
mb_to_top_edge -= LEFT_TOP_MARGIN;
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
-
mbmi->need_to_clamp_mvs = 0;
/* Distance of Mb to the various image edges.
* These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
@@ -289,7 +297,41 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
/* If required read in new segmentation data for this MB */
if (pbi->mb.update_mb_segmentation_map)
- vp8_read_mb_features(bc, mbmi, &pbi->mb);
+ {
+#if CONFIG_SEGMENTATION
+ if (xd->temporal_update)
+ {
+ sum = 0;
+
+ if (mb_col != 0)
+ sum += (mi-1)->mbmi.segment_flag;
+ if (mb_row != 0)
+ sum += (mi-pbi->common.mb_cols)->mbmi.segment_flag;
+
+ if (vp8_read(bc, xd->mb_segment_tree_probs[3+sum]) == 0)
+ {
+ mbmi->segment_id = pbi->segmentation_map[index];
+ mbmi->segment_flag = 0;
+ }
+ else
+ {
+ vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
+ mbmi->segment_flag = 1;
+ pbi->segmentation_map[index] = mbmi->segment_id;
+ }
+
+ }
+ else
+ {
+ vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
+ pbi->segmentation_map[index] = mbmi->segment_id;
+ }
+ index++;
+#else
+ vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
+#endif
+ }
+
/* Read the macroblock coeff skip flag if this feature is in use, else default to 0 */
if (pbi->common.mb_no_coeff_skip)
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index a300bb5fd..4d02fdec4 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -652,7 +652,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
const unsigned char *data = (const unsigned char *)pbi->Source;
const unsigned char *data_end = data + pbi->source_sz;
ptrdiff_t first_partition_length_in_bytes;
-
int mb_row;
int i, j, k, l;
const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
@@ -787,7 +786,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
/* Is segmentation enabled */
xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc);
-
if (xd->segmentation_enabled)
{
/* Signal whether or not the segmentation map is being explicitly updated this frame. */
@@ -823,9 +821,12 @@ int vp8_decode_frame(VP8D_COMP *pbi)
{
/* Which macro block level features are enabled */
vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
-
+#if CONFIG_SEGMENTATION
/* Read the probs used to decode the segment id for each macro block. */
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
{
/* If not explicitly set value is defaulted to 255 by memset above */
if (vp8_read_bit(bc))
@@ -995,6 +996,11 @@ int vp8_decode_frame(VP8D_COMP *pbi)
vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG));
vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG));
+#if CONFIG_SEGMENTATION
+ // Create the encoder segmentation map and set all entries to 0
+ CHECK_MEM_ERROR(pbi->segmentation_map, vpx_calloc((pc->mb_rows * pc->mb_cols), 1));
+#endif
+
/* set up frame new frame for intra coded blocks */
#if CONFIG_MULTITHREAD
if (!(pbi->b_multithreaded_rd) || pc->multi_token_partition == ONE_PARTITION || !(pc->filter_level))
diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c
index c22e0f28c..2d050512a 100644
--- a/vp8/decoder/detokenize.c
+++ b/vp8/decoder/detokenize.c
@@ -44,23 +44,23 @@ typedef struct
{
INT16 min_val;
INT16 Length;
- UINT8 Probs[12];
+ UINT8 Probs[14];
} TOKENEXTRABITS;
*/
DECLARE_ALIGNED(16, static const TOKENEXTRABITS, vp8d_token_extra_bits2[MAX_ENTROPY_TOKENS]) =
{
- { 0, -1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ZERO_TOKEN */
- { 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ONE_TOKEN */
- { 2, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* TWO_TOKEN */
- { 3, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* THREE_TOKEN */
- { 4, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* FOUR_TOKEN */
- { 5, 0, { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY1 */
- { 7, 1, { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY2 */
- { 11, 2, { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY3 */
- { 19, 3, { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY4 */
- { 35, 4, { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY5 */
- { 67, 10, { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254, 0 } }, /* DCT_VAL_CATEGORY6 */
+ { 0, -1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ZERO_TOKEN */
+ { 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ONE_TOKEN */
+ { 2, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* TWO_TOKEN */
+ { 3, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* THREE_TOKEN */
+ { 4, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* FOUR_TOKEN */
+ { 5, 0, { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY1 */
+ { 7, 1, { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY2 */
+ { 11, 2, { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY3 */
+ { 19, 3, { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY4 */
+ { 35, 4, { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY5 */
+ { 67, 12, { 129, 130, 133, 140, 153, 177, 196, 230, 243, 249, 252, 254, 254, 0 } }, /* DCT_VAL_CATEGORY6 */
{ 0, -1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* EOB TOKEN */
};
diff --git a/vp8/decoder/generic/dsystemdependent.c b/vp8/decoder/generic/dsystemdependent.c
index 2406deaaf..f76653231 100644
--- a/vp8/decoder/generic/dsystemdependent.c
+++ b/vp8/decoder/generic/dsystemdependent.c
@@ -33,7 +33,16 @@ void vp8_dmachine_specific_config(VP8D_COMP *pbi)
vp8_arch_x86_decode_init(pbi);
#endif
+
#if ARCH_ARM
vp8_arch_arm_decode_init(pbi);
#endif
+
+#if CONFIG_EXTEND_QRANGE
+ pbi->dequant.idct_add = vp8_dequant_idct_add_c;
+ pbi->dequant.dc_idct_add = vp8_dequant_dc_idct_add_c;
+ pbi->dequant.dc_idct_add_y_block = vp8_dequant_dc_idct_add_y_block_c;
+ pbi->dequant.idct_add_y_block = vp8_dequant_idct_add_y_block_c;
+ pbi->dequant.idct_add_uv_block = vp8_dequant_idct_add_uv_block_c;
+#endif
}
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 5f81ee638..92d8580ef 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -56,7 +56,6 @@ void vp8dx_initialize()
}
}
-
VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
{
VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
@@ -114,13 +113,17 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
return (VP8D_PTR) pbi;
}
-
void vp8dx_remove_decompressor(VP8D_PTR ptr)
{
VP8D_COMP *pbi = (VP8D_COMP *) ptr;
if (!pbi)
return;
+#if CONFIG_SEGMENTATION
+ // Delete sementation map
+ if (pbi->segmentation_map != 0)
+ vpx_free(pbi->segmentation_map);
+#endif
#if CONFIG_MULTITHREAD
if (pbi->b_multithreaded_rd)
@@ -466,6 +469,8 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
}
+ vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
+
vp8_clear_system_state();
diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h
index be6ffe6be..591fa4f23 100644
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -44,9 +44,9 @@ typedef struct
typedef struct
{
- INT16 min_val;
- INT16 Length;
- UINT8 Probs[12];
+ INT16 min_val;
+ INT16 Length;
+ UINT8 Probs[14];
} TOKENEXTRABITS;
typedef struct
@@ -87,6 +87,7 @@ typedef struct VP8Decompressor
unsigned int partition_sizes[MAX_PARTITIONS];
unsigned int num_partitions;
+ unsigned char *segmentation_map;
#if CONFIG_MULTITHREAD
/* variable for threading */
@@ -95,7 +96,6 @@ typedef struct VP8Decompressor
int current_mb_col_main;
int decoding_thread_count;
int allocated_decoding_thread_count;
-
int mt_baseline_filter_level[MAX_MB_SEGMENTS];
int sync_range;
int *mt_current_mb_col; /* Each row remembers its already decoded column. */
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 134e84881..e3c4b5f99 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -23,7 +23,9 @@
#include "vpx_mem/vpx_mem.h"
#include "bitstream.h"
#include "vp8/common/defaultcoefcounts.h"
-
+#if CONFIG_SEGMENTATION
+static int segment_cost = 0;
+#endif
const int vp8cx_base_skip_false_prob[128] =
{
255, 255, 255, 255, 255, 255, 255, 255,
@@ -824,24 +826,39 @@ static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACRO
case 0:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
+#endif
break;
case 1:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 1, x->mb_segment_tree_probs[1]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[1]);
+#endif
break;
case 2:
vp8_write(w, 1, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[2]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[2]);
+#endif
break;
case 3:
vp8_write(w, 1, x->mb_segment_tree_probs[0]);
vp8_write(w, 1, x->mb_segment_tree_probs[2]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[2]);
+#endif
break;
// TRAP.. This should not happen
default:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
+#endif
break;
}
}
@@ -853,7 +870,13 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
VP8_COMMON *const pc = & cpi->common;
vp8_writer *const w = & cpi->bc;
const MV_CONTEXT *mvc = pc->fc.mvc;
-
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+#if CONFIG_SEGMENTATION
+ int left_id, above_id;
+ int i;
+ int sum;
+ int index = 0;
+#endif
const int *const rfct = cpi->count_mb_ref_frame_usage;
const int rf_intra = rfct[INTRA_FRAME];
const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
@@ -910,7 +933,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
update_mbintra_mode_probs(cpi);
vp8_write_mvprobs(cpi);
-
+#if CONFIG_SEGMENTATION
+ vp8_write_bit(w, (xd->temporal_update) ? 1:0);
+#endif
while (++mb_row < pc->mb_rows)
{
int mb_col = -1;
@@ -921,7 +946,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
const MV_REFERENCE_FRAME rf = mi->ref_frame;
const MB_PREDICTION_MODE mode = mi->mode;
- MACROBLOCKD *xd = &cpi->mb.e_mbd;
+ //MACROBLOCKD *xd = &cpi->mb.e_mbd;
// Distance of Mb to the various image edges.
// These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
@@ -929,13 +954,46 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
xd->mb_to_top_edge = -((mb_row * 16)) << 3;
xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
-
+ xd->up_available = (mb_row != 0);
+ xd->left_available = (mb_col != 0);
#ifdef ENTROPY_STATS
active_section = 9;
#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map)
+ {
+#if CONFIG_SEGMENTATION
+ if (xd->temporal_update)
+ {
+ sum = 0;
+ if (mb_col != 0)
+ sum += (m-1)->mbmi.segment_flag;
+ if (mb_row != 0)
+ sum += (m-pc->mb_cols)->mbmi.segment_flag;
+
+ if (m->mbmi.segment_flag == 0)
+ {
+ vp8_write(w,0,xd->mb_segment_tree_probs[3+sum]);
+ segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[3+sum]);
+ }
+ else
+ {
+ vp8_write(w,1,xd->mb_segment_tree_probs[3+sum]);
+ segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[3+sum]);
+ write_mb_features(w, mi, &cpi->mb.e_mbd);
+ cpi->segmentation_map[index] = mi->segment_id;
+ }
+ }
+ else
+ {
+ write_mb_features(w, mi, &cpi->mb.e_mbd);
+ cpi->segmentation_map[index] = mi->segment_id;
+ }
+ index++;
+#else
write_mb_features(w, mi, &cpi->mb.e_mbd);
+#endif
+ }
if (pc->mb_no_coeff_skip)
vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
@@ -1070,7 +1128,11 @@ static void write_kfmodes(VP8_COMP *cpi)
const VP8_COMMON *const c = & cpi->common;
/* const */
MODE_INFO *m = c->mi;
-
+#if CONFIG_SEGMENTATION
+ int left_id, above_id;
+ int i;
+ int index = 0;
+#endif
int mb_row = -1;
int prob_skip_false = 0;
@@ -1095,9 +1157,22 @@ static void write_kfmodes(VP8_COMP *cpi)
while (++mb_col < c->mb_cols)
{
const int ym = m->mbmi.mode;
-
+#if CONFIG_SEGMENTATION
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+ xd->up_available = (mb_row != 0);
+ xd->left_available = (mb_col != 0);
+#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map)
+ {
+#if CONFIG_SEGMENTATION
+
write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+ cpi->segmentation_map[index] = m->mbmi.segment_id;
+ index++;
+#else
+ write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+#endif
+ }
if (c->mb_no_coeff_skip)
vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
@@ -1597,6 +1672,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
else
vp8_start_encode(bc, cx_data);
+ xd->update_mb_segmentation_map = 1;
// Signal whether or not Segmentation is enabled
vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0);
@@ -1647,8 +1723,12 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
if (xd->update_mb_segmentation_map)
{
+ #if CONFIG_SEGMENTATION
// Write the probs used to decode the segment id for each macro block.
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
{
int Data = xd->mb_segment_tree_probs[i];
@@ -1826,7 +1906,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
active_section = 1;
#endif
}
-
+#if CONFIG_SEGMENTATION
+ //printf("%d\n",segment_cost);
+#endif
vp8_stop_encode(bc);
oh.first_partition_length_in_bytes = cpi->bc.pos;
diff --git a/vp8/encoder/dct.c b/vp8/encoder/dct.c
index b5a11ae34..69a882c89 100644
--- a/vp8/encoder/dct.c
+++ b/vp8/encoder/dct.c
@@ -10,7 +10,7 @@
#include <math.h>
-
+#include "vpx_ports/config.h"
void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
{
int i;
@@ -20,11 +20,17 @@ void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
for (i = 0; i < 4; i++)
{
+#if CONFIG_EXTEND_QRANGE
+ a1 = ((ip[0] + ip[3])<<5);
+ b1 = ((ip[1] + ip[2])<<5);
+ c1 = ((ip[1] - ip[2])<<5);
+ d1 = ((ip[0] - ip[3])<<5);
+#else
a1 = ((ip[0] + ip[3])<<3);
b1 = ((ip[1] + ip[2])<<3);
c1 = ((ip[1] - ip[2])<<3);
d1 = ((ip[0] - ip[3])<<3);
-
+#endif
op[0] = a1 + b1;
op[2] = a1 - b1;
@@ -72,12 +78,22 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
for (i = 0; i < 4; i++)
{
+#if !CONFIG_EXTEND_QRANGE
a1 = ((ip[0] + ip[2])<<2);
d1 = ((ip[1] + ip[3])<<2);
c1 = ((ip[1] - ip[3])<<2);
b1 = ((ip[0] - ip[2])<<2);
op[0] = a1 + d1 + (a1!=0);
+#else
+ a1 = ((ip[0] + ip[2]));
+ d1 = ((ip[1] + ip[3]));
+ c1 = ((ip[1] - ip[3]));
+ b1 = ((ip[0] - ip[2]));
+
+
+ op[0] = a1 + d1;
+#endif
op[1] = b1 + c1;
op[2] = b1 - c1;
op[3] = a1 - d1;
@@ -105,11 +121,17 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
c2 += c2<0;
d2 += d2<0;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a2+3) >> 3;
op[4] = (b2+3) >> 3;
op[8] = (c2+3) >> 3;
op[12]= (d2+3) >> 3;
-
+#else
+ op[0] = (a2+1) >> 2;
+ op[4] = (b2+1) >> 2;
+ op[8] = (c2+1) >> 2;
+ op[12]= (d2+1) >> 2;
+#endif
ip++;
op++;
}
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 0efb9f646..d7aed0a3a 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -30,6 +30,7 @@
#include "vp8/common/subpixel.h"
#include "vpx_ports/vpx_timer.h"
+
#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD(x) &cpi->common.rtcd.x
#define IF_RTCD(x) (x)
@@ -37,6 +38,13 @@
#define RTCD(x) NULL
#define IF_RTCD(x) NULL
#endif
+
+#if CONFIG_SEGMENTATION
+#define SEEK_SEGID 12
+#define SEEK_SAMEID 4
+#define SEEK_DIFFID 7
+#endif
+
extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
@@ -376,7 +384,10 @@ void encode_mb_row(VP8_COMP *cpi,
int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
int map_index = (mb_row * cpi->common.mb_cols);
-
+#if CONFIG_SEGMENTATION
+ int left_id, above_id;
+ int sum;
+#endif
#if CONFIG_MULTITHREAD
const int nsync = cpi->mt_sync_range;
const int rightmost_col = cm->mb_cols - 1;
@@ -387,7 +398,6 @@ void encode_mb_row(VP8_COMP *cpi,
else
last_row_current_mb_col = &rightmost_col;
#endif
-
// reset above block coeffs
xd->above_context = cm->above_context;
@@ -467,6 +477,7 @@ void encode_mb_row(VP8_COMP *cpi,
xd->mode_info_context->mbmi.segment_id = 0;
vp8cx_mb_init_quantizer(cpi, x);
+
}
else
xd->mode_info_context->mbmi.segment_id = 0; // Set to Segment 0 by default
@@ -534,6 +545,11 @@ void encode_mb_row(VP8_COMP *cpi,
// Increment the activity mask pointers.
x->mb_activity_ptr++;
+ if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
+ xd->mode_info_context->mbmi.segment_id = 0;
+ else
+ xd->mode_info_context->mbmi.segment_id = 1;
+
/* save the block info */
for (i = 0; i < 16; i++)
xd->mode_info_context->bmi[i] = xd->block[i].bmi;
@@ -546,9 +562,42 @@ void encode_mb_row(VP8_COMP *cpi,
recon_yoffset += 16;
recon_uvoffset += 8;
- // Keep track of segment useage
- segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+#if CONFIG_SEGMENTATION
+ //cpi->segmentation_map[mb_row * cm->mb_cols + mb_col] = xd->mbmi.segment_id;
+ if (cm->frame_type == KEY_FRAME)
+ {
+ segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+ }
+ else
+ {
+ sum = 0;
+ if (mb_col != 0)
+ sum += (xd->mode_info_context-1)->mbmi.segment_flag;
+ if (mb_row != 0)
+ sum += (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag;
+
+ if (xd->mode_info_context->mbmi.segment_id == cpi->segmentation_map[(mb_row*cm->mb_cols) + mb_col])
+ xd->mode_info_context->mbmi.segment_flag = 0;
+ else
+ xd->mode_info_context->mbmi.segment_flag = 1;
+ if (xd->mode_info_context->mbmi.segment_flag == 0)
+ {
+ segment_counts[SEEK_SAMEID + sum]++;
+ segment_counts[10]++;
+ }
+ else
+ {
+ segment_counts[SEEK_DIFFID + sum]++;
+ segment_counts[11]++;
+ //calculate individual segment ids
+ segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+ }
+ }
+ segment_counts[SEEK_SEGID + xd->mode_info_context->mbmi.segment_id] ++;
+#else
+ segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+#endif
// skip to next mb
xd->mode_info_context++;
x->partition_info++;
@@ -572,7 +621,6 @@ void encode_mb_row(VP8_COMP *cpi,
// this is to account for the border
xd->mode_info_context++;
x->partition_info++;
-
#if CONFIG_MULTITHREAD
if ((cpi->b_multi_threaded != 0) && (mb_row == cm->mb_rows - 1))
{
@@ -580,7 +628,6 @@ void encode_mb_row(VP8_COMP *cpi,
}
#endif
}
-
void init_encode_frame_mb_context(VP8_COMP *cpi)
{
MACROBLOCK *const x = & cpi->mb;
@@ -675,7 +722,13 @@ void vp8_encode_frame(VP8_COMP *cpi)
MACROBLOCKD *const xd = & x->e_mbd;
TOKENEXTRA *tp = cpi->tok;
+#if CONFIG_SEGMENTATION
+ int segment_counts[MAX_MB_SEGMENTS + SEEK_SEGID];
+ int prob[3];
+ int new_cost, original_cost;
+#else
int segment_counts[MAX_MB_SEGMENTS];
+#endif
int totalrate;
vpx_memset(segment_counts, 0, sizeof(segment_counts));
@@ -736,9 +789,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
vp8cx_frame_init_quantizer(cpi);
- vp8_initialize_rd_consts(cpi,
- vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
-
vp8cx_initialize_me_consts(cpi, cm->base_qindex);
if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
@@ -847,41 +897,126 @@ void vp8_encode_frame(VP8_COMP *cpi)
}
-
// Work out the segment probabilites if segmentation is enabled
if (xd->segmentation_enabled)
{
int tot_count;
- int i;
+ int i,j;
+ int count1,count2,count3,count4;
// Set to defaults
vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
+#if CONFIG_SEGMENTATION
+
+ tot_count = segment_counts[12] + segment_counts[13] + segment_counts[14] + segment_counts[15];
+ count1 = segment_counts[12] + segment_counts[13];
+ count2 = segment_counts[14] + segment_counts[15];
+
+ if (tot_count)
+ prob[0] = (count1 * 255) / tot_count;
+
+ if (count1 > 0)
+ prob[1] = (segment_counts[12] * 255) /count1;
+
+ if (count2 > 0)
+ prob[2] = (segment_counts[14] * 255) /count2;
+
+ if (cm->frame_type != KEY_FRAME)
+ {
+ tot_count = segment_counts[4] + segment_counts[7];
+ if (tot_count)
+ xd->mb_segment_tree_probs[3] = (segment_counts[4] * 255)/tot_count;
+
+ tot_count = segment_counts[5] + segment_counts[8];
+ if (tot_count)
+ xd->mb_segment_tree_probs[4] = (segment_counts[5] * 255)/tot_count;
+
+ tot_count = segment_counts[6] + segment_counts[9];
+ if (tot_count)
+ xd->mb_segment_tree_probs[5] = (segment_counts[6] * 255)/tot_count;
+ }
tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
+ count3 = segment_counts[0] + segment_counts[1];
+ count4 = segment_counts[2] + segment_counts[3];
if (tot_count)
+ xd->mb_segment_tree_probs[0] = (count3 * 255) / tot_count;
+
+ if (count3 > 0)
+ xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count3;
+
+ if (count4 > 0)
+ xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count4;
+
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
{
- xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;
+ if (xd->mb_segment_tree_probs[i] == 0)
+ xd->mb_segment_tree_probs[i] = 1;
+ }
- tot_count = segment_counts[0] + segment_counts[1];
+ original_cost = count1 * vp8_cost_zero(prob[0]) + count2 * vp8_cost_one(prob[0]);
- if (tot_count > 0)
- {
- xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
- }
+ if (count1 > 0)
+ original_cost += segment_counts[12] * vp8_cost_zero(prob[1]) + segment_counts[13] * vp8_cost_one(prob[1]);
+
+ if (count2 > 0)
+ original_cost += segment_counts[14] * vp8_cost_zero(prob[2]) + segment_counts[15] * vp8_cost_one(prob[2]) ;
- tot_count = segment_counts[2] + segment_counts[3];
+ new_cost = 0;
- if (tot_count > 0)
- xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
+ if (cm->frame_type != KEY_FRAME)
+ {
+ new_cost = segment_counts[4] * vp8_cost_zero(xd->mb_segment_tree_probs[3]) + segment_counts[7] * vp8_cost_one(xd->mb_segment_tree_probs[3]);
+
+ new_cost += segment_counts[5] * vp8_cost_zero(xd->mb_segment_tree_probs[4]) + segment_counts[8] * vp8_cost_one(xd->mb_segment_tree_probs[4]);
+
+ new_cost += segment_counts[6] * vp8_cost_zero(xd->mb_segment_tree_probs[5]) + segment_counts[9] * vp8_cost_one (xd->mb_segment_tree_probs[5]);
+ }
- // Zero probabilities not allowed
- for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
+ if (tot_count > 0)
+ new_cost += count3 * vp8_cost_zero(xd->mb_segment_tree_probs[0]) + count4 * vp8_cost_one(xd->mb_segment_tree_probs[0]);
+
+ if (count3 > 0)
+ new_cost += segment_counts[0] * vp8_cost_zero(xd->mb_segment_tree_probs[1]) + segment_counts[1] * vp8_cost_one(xd->mb_segment_tree_probs[1]);
+
+ if (count4 > 0)
+ new_cost += segment_counts[2] * vp8_cost_zero(xd->mb_segment_tree_probs[2]) + segment_counts[3] * vp8_cost_one(xd->mb_segment_tree_probs[2]) ;
+
+ if (new_cost < original_cost)
+ xd->temporal_update = 1;
+ else
+ {
+ xd->temporal_update = 0;
+ xd->mb_segment_tree_probs[0] = prob[0];
+ xd->mb_segment_tree_probs[1] = prob[1];
+ xd->mb_segment_tree_probs[2] = prob[2];
+ }
+#else
+ tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
+ count1 = segment_counts[0] + segment_counts[1];
+ count2 = segment_counts[2] + segment_counts[3];
+
+ if (tot_count)
+ xd->mb_segment_tree_probs[0] = (count1 * 255) / tot_count;
+
+ if (count1 > 0)
+ xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count1;
+
+ if (count2 > 0)
+ xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2;
+
+#endif
+ // Zero probabilities not allowed
+#if CONFIG_SEGMENTATION
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
+ for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
{
if (xd->mb_segment_tree_probs[i] == 0)
xd->mb_segment_tree_probs[i] = 1;
}
- }
}
// 256 rate units to the bit
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
index 3ed16b681..eb89bba0a 100644
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -214,7 +214,11 @@ struct vp8_token_state{
// TODO: experiments to find optimal multiple numbers
#define Y1_RD_MULT 4
#define UV_RD_MULT 2
+#if !CONFIG_EXTEND_QRANGE
#define Y2_RD_MULT 16
+#else
+#define Y2_RD_MULT 4
+#endif
static const int plane_rd_mult[4]=
{
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 4fc6a8a58..d3a874cfd 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -545,7 +545,7 @@ void vp8_first_pass(VP8_COMP *cpi)
//if ( 0 )
{
int flag[2] = {1, 1};
- vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
+ vp8_initialize_rd_consts(cpi, cm->base_qindex+cm->y1dc_delta_q);
vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
}
diff --git a/vp8/encoder/generic/csystemdependent.c b/vp8/encoder/generic/csystemdependent.c
index 536636fd1..1ec3a9894 100644
--- a/vp8/encoder/generic/csystemdependent.c
+++ b/vp8/encoder/generic/csystemdependent.c
@@ -110,4 +110,12 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi)
vp8_arch_arm_encoder_init(cpi);
#endif
+#if CONFIG_EXTEND_QRANGE
+ cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_c;
+ cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_c;
+ cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_c;
+ cpi->rtcd.fdct.fast8x4 = vp8_short_fdct8x4_c;
+ cpi->rtcd.fdct.walsh_short4x4 = vp8_short_walsh4x4_c;
+#endif
+
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 80f7ae67c..79c638a16 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -150,7 +150,7 @@ extern const int qrounding_factors[129];
extern const int qzbin_factors[129];
extern void vp8cx_init_quantizer(VP8_COMP *cpi);
extern const int vp8cx_base_skip_false_prob[128];
-
+#if !CONFIG_EXTEND_QRANGE
// Tables relating active max Q to active min Q
static const int kf_low_motion_minq[QINDEX_RANGE] =
{
@@ -218,7 +218,76 @@ static const int inter_minq[QINDEX_RANGE] =
71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85,
86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
};
+#else
+static const int kf_low_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
+ 9, 9, 9, 10,10,11,11,12,12,13,13,14,14,15,15,16,
+ 16,17,17,18,18,19,19,20,20,21,21,22,23,23,24,24,
+ 25,25,26,27,28,29,30,30,31,32,33,34,35,35,36,36,
+ 38,38,39,40,40,41,42,42,43,44,44,45,46,46,47,48,
+ 49,49,50,50,51,52,52,53,54,55,56,57,58,59,60,61,
+};
+static const int kf_high_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,
+ 11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,24,
+ 25,26,27,28,28,29,29,30,30,31,31,32,33,33,34,34,
+ 35,36,37,38,39,39,40,41,41,42,43,44,45,45,46,46,
+ 47,47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,
+ 55,55,56,56,57,58,59,60,61,62,63,64,65,67,69,70,
+};
+
+static const int gf_low_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,
+ 10,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,
+ 17,18,18,19,19,20,21,22,23,24,25,26,27,29,29,30,
+ 31,32,33,34,35,36,37,38,39,40,41,41,42,42,43,43,
+ 44,44,45,45,46,46,47,47,48,48,49,49,50,50,51,51,
+ 52,52,53,53,54,54,55,55,56,56,57,57,58,59,60,61,
+ 62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,
+};
+static const int gf_mid_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,10,
+ 10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,
+ 18,19,19,20,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,35,36,36,37,37,38,38,39,39,40,40,41,
+ 41,42,42,43,43,44,44,45,45,46,46,47,48,49,50,51,
+ 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,
+ 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,
+};
+static const int gf_high_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4,
+ 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9,10,10,
+ 11,11,12,12,13,14,15,16,17,18,18,19,19,20,20,21,
+ 22,23,24,25,26,26,27,28,29,30,31,32,33,34,35,36,
+ 37,38,39,39,40,40,40,41,41,41,42,42,43,43,44,44,
+ 44,45,45,45,46,46,47,47,47,48,48,48,49,49,49,50,
+ 50,50,51,51,52,53,54,54,55,56,57,57,58,59,60,61,
+ 62,63,64,66,68,69,72,74,77,80,82,85,87,89,91,93,
+};
+static const int inter_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
+ 8, 9,10,11,12,13,14,15,16,17,18,18,19,19,20,21,
+ 21,22,23,23,24,25,26,26,27,28,29,30,31,32,32,33,
+ 34,35,36,36,37,38,39,40,40,41,41,42,43,44,44,45,
+ 46,46,47,47,48,49,49,50,50,51,52,52,53,54,54,55,
+ 55,56,57,57,58,59,60,60,61,62,63,63,64,65,66,67,
+ 68,68,69,70,71,72,72,73,74,75,76,77,78,79,80,81,
+ 81,82,83,84,85,86,87,88,89,90,90,91,92,93,94,95,
+};
+#endif
void vp8_initialize()
{
static int init_done = 0;
@@ -339,7 +408,6 @@ static void set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_map)
// Copy in the new segmentation map
vpx_memcpy(cpi->segmentation_map, segmentation_map, (cpi->common.mb_rows * cpi->common.mb_cols));
-
// Signal that the map should be updated.
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
@@ -365,12 +433,10 @@ static void set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned ch
static void segmentation_test_function(VP8_PTR ptr)
{
VP8_COMP *cpi = (VP8_COMP *)(ptr);
-
unsigned char *seg_map;
signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
-
+ CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
// Create a temporary map for segmentation data.
- CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
// MB loop to set local segmentation map
/*for ( i = 0; i < cpi->common.mb_rows; i++ )
@@ -430,7 +496,7 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols;
// Create a temporary map for segmentation data.
- CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+ CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
cpi->cyclic_refresh_q = Q;
@@ -1860,7 +1926,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
CHECK_MEM_ERROR(cpi->lf_ref_frame, vpx_calloc((cpi->common.mb_rows+2) * (cpi->common.mb_cols+2), sizeof(int)));
// Create the encoder segmentation map and set all entries to 0
- CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+ CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
cpi->active_map_enabled = 0;
@@ -1896,13 +1962,12 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
cpi->cyclic_refresh_q = 32;
if (cpi->cyclic_refresh_mode_enabled)
- {
CHECK_MEM_ERROR(cpi->cyclic_refresh_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
- }
else
cpi->cyclic_refresh_map = (signed char *) NULL;
// Test function for segmentation
+
//segmentation_test_function((VP8_PTR) cpi);
#ifdef ENTROPY_STATS
@@ -2982,6 +3047,12 @@ static int decide_key_frame(VP8_COMP *cpi)
return code_key_frame;
}
+#if !CONFIG_EXTEND_QRANGE
+#define FIRSTPASS_QINDEX 26
+#else
+#define FIRSTPASS_QINDEX 49
+#endif
+
#if !(CONFIG_REALTIME_ONLY)
static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
@@ -3248,6 +3319,10 @@ static void encode_frame_to_data_rate
// Test code for segmentation of gf/arf (0,0)
//segmentation_test_function((VP8_PTR) cpi);
+#if CONFIG_SEGMENTATION
+ cpi->mb.e_mbd.segmentation_enabled = 1;
+ cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+#endif
#if CONFIG_REALTIME_ONLY
if(cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME)
@@ -3783,6 +3858,17 @@ static void encode_frame_to_data_rate
vp8_clear_system_state(); //__asm emms;
+#if 0
+ if (cpi->pass != 1)
+ {
+ FILE *f = fopen("q_used.stt", "a");
+ fprintf(f, "%4d, %4d, %8d\n", cpi->common.current_video_frame,
+ cpi->common.base_qindex, cpi->projected_frame_size);
+ fclose(f);
+ }
+#endif
+
+
// Test to see if the stats generated for this frame indicate that we should have coded a key frame
// (assuming that we didn't)!
if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME)
@@ -4462,10 +4548,15 @@ static void encode_frame_to_data_rate
fclose(recon_file);
}
#endif
-
+#if 0
// DEBUG
- //vp8_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show);
-
+ if(cm->current_video_frame>173 && cm->current_video_frame<178)
+ {
+ char filename[512];
+ sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame);
+ vp8_write_yuv_frame(filename, cm->frame_to_show);
+ }
+#endif
}
@@ -4943,7 +5034,15 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
cpi->summed_quality += frame_ssim2 * weight;
cpi->summed_weights += weight;
-
+#if 0
+ {
+ FILE *f = fopen("q_used.stt", "a");
+ fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
+ cpi->common.current_video_frame,y2, u2, v2,
+ frame_psnr2, frame_ssim2);
+ fclose(f);
+ }
+#endif
}
}
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index ce401fd19..846df6d51 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -196,7 +196,11 @@ typedef struct
typedef struct
{
MACROBLOCK mb;
+#if CONFIG_SEGMENTATION
+ int segment_counts[MAX_MB_SEGMENTS + 8];
+#else
int segment_counts[MAX_MB_SEGMENTS];
+#endif
int totalrate;
} MB_ROW_COMP;
diff --git a/vp8/encoder/psnr.c b/vp8/encoder/psnr.c
index 5119bb8aa..7ecf6d7cd 100644
--- a/vp8/encoder/psnr.c
+++ b/vp8/encoder/psnr.c
@@ -13,7 +13,7 @@
#include "math.h"
#include "vp8/common/systemdependent.h" /* for vp8_clear_system_state() */
-#define MAX_PSNR 60
+#define MAX_PSNR 100
double vp8_mse2psnr(double Samples, double Peak, double Mse)
{
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 54c394dfc..78b3b4715 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -48,6 +48,7 @@ extern int inter_b_modes[10];
// Work in progress recalibration of baseline rate tables based on
// the assumption that bits per mb is inversely proportional to the
// quantizer value.
+#if !CONFIG_EXTEND_QRANGE
const int vp8_bits_per_mb[2][QINDEX_RANGE] =
{
// Intra case 450000/Qintra
@@ -89,10 +90,54 @@ const int vp8_bits_per_mb[2][QINDEX_RANGE] =
11445, 11220, 11003, 10795, 10594, 10401, 10215, 10035,
}
};
+#else
+const int vp8_bits_per_mb[2][QINDEX_RANGE] =
+{
+ // (Updated DEC 2010) Baseline estimate of Bits Per MB at each Q:
+ // 4500000/Qintra
+ {
+ 4500000,3600000,3000000,2571428,2250000,2000000,1800000,1636363,
+ 1500000,1384615,1285714,1200000,1125000,1058823,1000000, 947368,
+ 900000, 818181, 750000, 692307, 642857, 600000, 562500, 529411,
+ 500000, 473684, 450000, 428571, 409090, 391304, 375000, 352941,
+ 333333, 315789, 300000, 285714, 272727, 260869, 250000, 236842,
+ 225000, 214285, 204545, 195652, 187500, 180000, 171428, 163636,
+ 156521, 150000, 144000, 138461, 133333, 128571, 123287, 118421,
+ 113924, 109756, 105882, 102272, 98901, 95744, 92783, 90000,
+ 87378, 84905, 82568, 80357, 77586, 75000, 72580, 70312,
+ 68181, 66176, 64285, 62500, 60810, 59210, 57692, 56250,
+ 54545, 52941, 51428, 50000, 48648, 47368, 45918, 44554,
+ 43269, 42056, 40909, 39647, 38461, 37344, 36290, 35294,
+ 34351, 33333, 32374, 31468, 30612, 29801, 28938, 28125,
+ 27355, 26627, 25862, 25139, 24456, 23809, 23195, 22613,
+ 21951, 21327, 20737, 20179, 19650, 19067, 18518, 18000,
+ 17441, 16917, 16423, 15957, 15410, 14900, 14376, 13846,
+ },
+ //2850000/Qinter
+ {
+ 2850000,2280000,1900000,1628571,1425000,1266666,1140000,1036363,
+ 950000, 876923, 814285, 760000, 712500, 670588, 633333, 600000,
+ 570000, 518181, 475000, 438461, 407142, 380000, 356250, 335294,
+ 316666, 300000, 285000, 271428, 259090, 247826, 237500, 223529,
+ 211111, 200000, 190000, 180952, 172727, 165217, 158333, 150000,
+ 142500, 135714, 129545, 123913, 118750, 114000, 108571, 103636,
+ 99130, 95000, 91200, 87692, 84444, 81428, 78082, 75000,
+ 72151, 69512, 67058, 64772, 62637, 60638, 58762, 57000,
+ 55339, 53773, 52293, 50892, 49137, 47500, 45967, 44531,
+ 43181, 41911, 40714, 39583, 38513, 37500, 36538, 35625,
+ 34545, 33529, 32571, 31666, 30810, 30000, 29081, 28217,
+ 27403, 26635, 25909, 25110, 24358, 23651, 22983, 22352,
+ 21755, 21111, 20503, 19930, 19387, 18874, 18327, 17812,
+ 17325, 16863, 16379, 15921, 15489, 15079, 14690, 14321,
+ 13902, 13507, 13133, 12780, 12445, 12076, 11728, 11400,
+ 11046, 10714, 10401, 10106, 9760, 9437, 9105, 8769,
+ }
+ };
+ #endif
static const int kf_boost_qadjustment[QINDEX_RANGE] =
-{
- 128, 129, 130, 131, 132, 133, 134, 135,
+ {
+ 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151,
152, 153, 154, 155, 156, 157, 158, 159,
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 355542e47..6efa077ab 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -155,6 +155,48 @@ static int rd_iifactor [ 32 ] = { 4, 4, 3, 2, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
+// 3* dc_qlookup[Q]*dc_qlookup[Q];
+#if !CONFIG_EXTEND_QRANGE
+static int rdmult_lut[QINDEX_RANGE]=
+{
+ 48,75,108,147,192,243,300,300,
+ 363,432,507,588,675,768,867,867,
+ 972,1083,1200,1200,1323,1323,1452,1452,
+ 1587,1587,1728,1875,1875,2028,2187,2352,
+ 2523,2700,2883,3072,3267,3468,3675,3888,
+ 4107,4107,4332,4563,4800,5043,5292,5547,
+ 5808,6075,6348,6348,6627,6912,7203,7500,
+ 7803,8112,8427,8748,9075,9408,9747,10092,
+ 10443,10800,11163,11532,11907,12288,12675,13068,
+ 13467,13872,14283,14700,15123,15552,15987,16428,
+ 16875,17328,17328,17787,18252,18723,19200,19683,
+ 20172,20667,21168,21675,22188,22707,23232,23763,
+ 24843,25947,27075,27648,28812,30000,30603,31212,
+ 32448,33708,34992,36300,37632,38988,40368,41772,
+ 44652,46128,47628,49152,50700,52272,53868,55488,
+ 57132,58800,61347,63075,65712,68403,71148,73947,
+};
+#else
+static int rdmult_lut[QINDEX_RANGE]=
+{
+ 3,5,7,9,12,15,19,23,
+ 27,32,37,42,48,54,61,68,
+ 75,83,91,99,108,117,127,137,
+ 147,169,192,217,243,271,300,331,
+ 363,397,450,507,567,631,698,768,
+ 842,919,999,1083,1170,1261,1355,1452,
+ 1587,1728,1875,2028,2187,2352,2523,2700,
+ 2883,3072,3267,3468,3675,3888,4107,4332,
+ 4563,4800,5043,5292,5547,5808,6075,6348,
+ 6627,6912,7203,7500,7880,8269,8667,9075,
+ 9492,9919,10355,10800,11255,11719,12192,12675,
+ 13167,13669,14180,14700,15230,15769,16317,16875,
+ 18019,19200,20419,21675,22969,24300,25669,27075,
+ 28519,30000,31519,33075,34669,36300,37969,39675,
+ 41772,43923,46128,48387,50700,53067,55488,57963,
+ 61347,64827,69312,73947,78732,83667,89787,97200,
+};
+#endif
/* values are now correlated to quantizer */
static int sad_per_bit16lut[QINDEX_RANGE] =
{
@@ -201,12 +243,16 @@ void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex)
cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex];
}
-void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
+
+
+
+
+void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
{
int q;
int i;
- double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0;
- double rdconst = 2.70;
+ int *thresh;
+ int threshmult;
vp8_clear_system_state(); //__asm emms;
@@ -214,7 +260,8 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
// for key frames, golden frames and arf frames.
// if (cpi->common.refresh_golden_frame ||
// cpi->common.refresh_alt_ref_frame)
- cpi->RDMULT = (int)(rdconst * (capped_q * capped_q));
+ QIndex=(QIndex<0)? 0 : ((QIndex>127)?127 : QIndex);
+ cpi->RDMULT = rdmult_lut[QIndex];
// Extend rate multiplier along side quantizer zbin increases
if (cpi->zbin_over_quant > 0)
@@ -225,8 +272,7 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
// Experimental code using the same basic equation as used for Q above
// The units of cpi->zbin_over_quant are 1/128 of Q bin size
oq_factor = 1.0 + ((double)0.0015625 * cpi->zbin_over_quant);
- modq = (int)((double)capped_q * oq_factor);
- cpi->RDMULT = (int)(rdconst * (modq * modq));
+ cpi->RDMULT = (int)((double)cpi->RDMULT * oq_factor * oq_factor);
}
if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME))
@@ -238,16 +284,31 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
(cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
}
+#if !CONFIG_EXTEND_QRANGE
+#else
+ if (cpi->RDMULT < 7)
+ cpi->RDMULT = 7;
+#endif
cpi->mb.errorperbit = (cpi->RDMULT / 110);
cpi->mb.errorperbit += (cpi->mb.errorperbit==0);
+#if CONFIG_EXTEND_QRANGE
+ if(cpi->mb.errorperbit<1)
+ cpi->mb.errorperbit=1;
+#endif
vp8_set_speed_features(cpi);
- q = (int)pow(Qvalue, 1.25);
+ q = (int)pow(vp8_dc_quant(QIndex,0), 1.25);
if (q < 8)
q = 8;
+
+
+#if CONFIG_EXTEND_QRANGE
+ cpi->RDMULT *= 16;
+#endif
+
if (cpi->RDMULT > 1000)
{
cpi->RDDIV = 1;
@@ -568,7 +629,12 @@ static void macro_block_yrd( MACROBLOCK *mb,
// Distortion
d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
+
+#if CONFIG_EXTEND_QRANGE
+ d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff)<<2;
+#else
d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
+#endif
*Distortion = (d >> 4);
@@ -988,6 +1054,7 @@ static unsigned int vp8_encode_inter_mb_segment(MACROBLOCK *x, int const *labels
}
+
static const unsigned int segmentation_to_sseshift[4] = {3, 3, 2, 0};
diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk
index f55c899db..91e1e6cf8 100644
--- a/vp8/vp8_common.mk
+++ b/vp8/vp8_common.mk
@@ -102,6 +102,11 @@ endif
# common (c)
VP8_COMMON_SRCS-$(ARCH_ARM) += common/asm_com_offsets.c
+ifeq ($(CONFIG_CSM),yes)
+VP8_COMMON_SRCS-yes += common/maskingmv.c
+VP8_COMMON_SRCS-$(HAVE_SSE3) += common/x86/mask_sse3.asm
+endif
+
VP8_COMMON_SRCS-$(ARCH_ARM) += common/arm/arm_systemdependent.c
VP8_COMMON_SRCS-$(ARCH_ARM) += common/arm/bilinearfilter_arm.c
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 5e1278a4c..800ec0b02 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -37,6 +37,7 @@ struct vp8_extracfg
unsigned int arnr_max_frames; /* alt_ref Noise Reduction Max Frame Count */
unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */
unsigned int arnr_type; /* alt_ref filter type */
+ unsigned int experimental;
vp8e_tuning tuning;
unsigned int cq_level; /* constrained quality level */
@@ -69,6 +70,7 @@ static const struct extraconfig_map extracfg_map[] =
0, /* arnr_max_frames */
3, /* arnr_strength */
3, /* arnr_type*/
+ 0, /* experimental mode */
0, /* tuning*/
10, /* cq_level */
}
@@ -246,7 +248,8 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
struct vp8_extracfg vp8_cfg)
{
oxcf->multi_threaded = cfg.g_threads;
- oxcf->Version = cfg.g_profile;
+ oxcf->Version = cfg.g_profile;
+ oxcf->Version |= vp8_cfg.experimental? 0x4 : 0;
oxcf->Width = cfg.g_w;
oxcf->Height = cfg.g_h;
@@ -477,7 +480,10 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
return res;
#undef MAP
}
-static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
+
+
+static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
+ int experimental)
{
vpx_codec_err_t res = VPX_DEC_OK;
struct vpx_codec_alg_priv *priv;
@@ -522,6 +528,7 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
priv->vp8_cfg = extracfg_map[i].cfg;
priv->vp8_cfg.pkt_list = &priv->pkt_list.head;
+ priv->vp8_cfg.experimental = experimental;
priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2;
@@ -557,6 +564,21 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
return res;
}
+
+static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
+{
+ return vp8e_common_init(ctx, 0);
+}
+
+
+#if CONFIG_EXPERIMENTAL
+static vpx_codec_err_t vp8e_exp_init(vpx_codec_ctx_t *ctx)
+{
+ return vp8e_common_init(ctx, 1);
+}
+#endif
+
+
static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx)
{
@@ -1171,6 +1193,36 @@ CODEC_INTERFACE(vpx_codec_vp8_cx) =
};
+#if CONFIG_EXPERIMENTAL
+vpx_codec_iface_t vpx_codec_vp8x_cx_algo =
+{
+ "VP8 Experimental Encoder" VERSION_STRING,
+ VPX_CODEC_INTERNAL_ABI_VERSION,
+ VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
+ /* vpx_codec_caps_t caps; */
+ vp8e_exp_init, /* vpx_codec_init_fn_t init; */
+ vp8e_destroy, /* vpx_codec_destroy_fn_t destroy; */
+ vp8e_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
+ NOT_IMPLEMENTED, /* vpx_codec_get_mmap_fn_t get_mmap; */
+ NOT_IMPLEMENTED, /* vpx_codec_set_mmap_fn_t set_mmap; */
+ {
+ NOT_IMPLEMENTED, /* vpx_codec_peek_si_fn_t peek_si; */
+ NOT_IMPLEMENTED, /* vpx_codec_get_si_fn_t get_si; */
+ NOT_IMPLEMENTED, /* vpx_codec_decode_fn_t decode; */
+ NOT_IMPLEMENTED, /* vpx_codec_frame_get_fn_t frame_get; */
+ },
+ {
+ vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */
+ vp8e_encode, /* vpx_codec_encode_fn_t encode; */
+ vp8e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */
+ vp8e_set_config,
+ NOT_IMPLEMENTED,
+ vp8e_get_preview,
+ } /* encoder functions */
+};
+#endif
+
+
/*
* BEGIN BACKWARDS COMPATIBILITY SHIM.
*/
diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h
index b6bd7fc5f..d5cf6c013 100644
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -35,6 +35,16 @@ extern vpx_codec_iface_t* vpx_codec_vp8_cx(void);
/*!@} - end algorithm interface member group*/
+#if CONFIG_EXPERIMENTAL
+/*!\brief Algorithm interface for VP8 experimental branch
+ *
+ * This interface provides the ability to encode using the "experimental"
+ * VP8 variant, which is bitstream incompatible with the default VP8 encoder.
+ */
+extern vpx_codec_iface_t vpx_codec_vp8x_cx_algo;
+#endif
+
+
/*
* Algorithm Flags
*/
diff --git a/vpxenc.c b/vpxenc.c
index 042f07b81..1683ff261 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -32,6 +32,7 @@
#include <fcntl.h>
#include <unistd.h>
#endif
+#include "vpx_config.h"
#include "vpx_version.h"
#include "vpx/vp8cx.h"
#include "vpx_ports/mem_ops.h"
@@ -76,6 +77,9 @@ static const struct codec_item
unsigned int fourcc;
} codecs[] =
{
+#if CONFIG_EXPERIMENTAL && CONFIG_VP8_ENCODER
+ {"vp8x", &vpx_codec_vp8x_cx_algo, 0x78385056},
+#endif
#if CONFIG_VP8_ENCODER
{"vp8", &vpx_codec_vp8_cx_algo, 0x30385056},
#endif
@@ -1660,7 +1664,11 @@ int main(int argc, const char **argv_)
/* Handle codec specific options */
#if CONFIG_VP8_ENCODER
- if (codec->iface == &vpx_codec_vp8_cx_algo)
+ if (codec->iface == &vpx_codec_vp8_cx_algo
+#if CONFIG_EXPERIMENTAL
+ || codec->iface == &vpx_codec_vp8x_cx_algo
+#endif
+ )
{
ctrl_args = vp8_args;
ctrl_args_map = vp8_arg_ctrl_map;