summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/convolve_test.cc24
-rw-r--r--vp9/common/arm/neon/vp9_convolve8_neon.asm250
-rw-r--r--vp9/common/arm/neon/vp9_dc_only_idct_add_neon.asm69
-rw-r--r--vp9/common/vp9_blockd.h48
-rw-r--r--vp9/common/vp9_entropymode.c4
-rw-r--r--vp9/common/vp9_entropymv.c4
-rw-r--r--vp9/common/vp9_entropymv.h1
-rw-r--r--vp9/common/vp9_loopfilter.c6
-rw-r--r--vp9/common/vp9_loopfilter.h2
-rw-r--r--vp9/common/vp9_onyxc_int.h4
-rw-r--r--vp9/common/vp9_pred_common.h2
-rw-r--r--vp9/common/vp9_quant_common.c6
-rw-r--r--vp9/common/vp9_rtcd_defs.sh8
-rw-r--r--vp9/common/vp9_seg_common.c35
-rw-r--r--vp9/common/vp9_seg_common.h51
-rw-r--r--vp9/common/x86/vp9_asm_stubs.c1
-rw-r--r--vp9/common/x86/vp9_idct_intrin_sse2.c149
-rw-r--r--vp9/decoder/vp9_decodemv.c40
-rw-r--r--vp9/decoder/vp9_decodframe.c48
-rw-r--r--vp9/decoder/vp9_detokenize.c6
-rw-r--r--vp9/encoder/vp9_bitstream.c223
-rw-r--r--vp9/encoder/vp9_encodeframe.c79
-rw-r--r--vp9/encoder/vp9_onyx_if.c113
-rw-r--r--vp9/encoder/vp9_quantize.c2
-rw-r--r--vp9/encoder/vp9_ratectrl.c4
-rw-r--r--vp9/encoder/vp9_rdopt.c61
-rw-r--r--vp9/encoder/vp9_segmentation.c32
-rw-r--r--vp9/encoder/vp9_tokenize.c10
-rw-r--r--vp9/vp9_common.mk2
-rw-r--r--vp9/vp9_dx_iface.c29
-rw-r--r--vpx/internal/vpx_codec_internal.h9
31 files changed, 899 insertions, 423 deletions
diff --git a/test/convolve_test.cc b/test/convolve_test.cc
index 6e5002fe9..93d3b01c2 100644
--- a/test/convolve_test.cc
+++ b/test/convolve_test.cc
@@ -211,7 +211,7 @@ class ConvolveTest : public PARAMS(int, int, const ConvolveFunctions*) {
virtual void SetUp() {
UUT_ = GET_PARAM(2);
- /* Set up guard blocks for an inner block cetered in the outer block */
+ /* Set up guard blocks for an inner block centered in the outer block */
for (int i = 0; i < kOutputBufferSize; ++i) {
if (IsIndexInBorder(i))
output_[i] = 255;
@@ -546,4 +546,26 @@ INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest, ::testing::Values(
make_tuple(32, 64, &convolve8_ssse3),
make_tuple(64, 64, &convolve8_ssse3)));
#endif
+
+#if HAVE_NEON
+const ConvolveFunctions convolve8_neon(
+ vp9_convolve8_horiz_neon, vp9_convolve8_avg_horiz_c,
+ vp9_convolve8_vert_neon, vp9_convolve8_avg_vert_c,
+ vp9_convolve8_c, vp9_convolve8_avg_c);
+
+INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest, ::testing::Values(
+ make_tuple(4, 4, &convolve8_neon),
+ make_tuple(8, 4, &convolve8_neon),
+ make_tuple(4, 8, &convolve8_neon),
+ make_tuple(8, 8, &convolve8_neon),
+ make_tuple(16, 8, &convolve8_neon),
+ make_tuple(8, 16, &convolve8_neon),
+ make_tuple(16, 16, &convolve8_neon),
+ make_tuple(32, 16, &convolve8_neon),
+ make_tuple(16, 32, &convolve8_neon),
+ make_tuple(32, 32, &convolve8_neon),
+ make_tuple(64, 32, &convolve8_neon),
+ make_tuple(32, 64, &convolve8_neon),
+ make_tuple(64, 64, &convolve8_neon)));
+#endif
} // namespace
diff --git a/vp9/common/arm/neon/vp9_convolve8_neon.asm b/vp9/common/arm/neon/vp9_convolve8_neon.asm
new file mode 100644
index 000000000..842c73c90
--- /dev/null
+++ b/vp9/common/arm/neon/vp9_convolve8_neon.asm
@@ -0,0 +1,250 @@
+;
+; Copyright (c) 2013 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.
+;
+
+
+ ; These functions are only valid when:
+ ; x_step_q4 == 16
+ ; w%4 == 0
+ ; h%4 == 0
+ ; taps == 8
+ ; VP9_FILTER_WEIGHT == 128
+ ; VP9_FILTER_SHIFT == 7
+
+ EXPORT |vp9_convolve8_horiz_neon|
+ EXPORT |vp9_convolve8_vert_neon|
+ IMPORT |vp9_convolve8_horiz_c|
+ IMPORT |vp9_convolve8_vert_c|
+ ARM
+ REQUIRE8
+ PRESERVE8
+
+ AREA ||.text||, CODE, READONLY, ALIGN=2
+
+ ; Multiply and accumulate by q0
+ MACRO
+ MULTIPLY_BY_Q0 $dst, $src0, $src1, $src2, $src3, $src4, $src5, $src6, $src7
+ vmull.s16 $dst, $src0, d0[0]
+ vmlal.s16 $dst, $src1, d0[1]
+ vmlal.s16 $dst, $src2, d0[2]
+ vmlal.s16 $dst, $src3, d0[3]
+ vmlal.s16 $dst, $src4, d1[0]
+ vmlal.s16 $dst, $src5, d1[1]
+ vmlal.s16 $dst, $src6, d1[2]
+ vmlal.s16 $dst, $src7, d1[3]
+ MEND
+
+; r0 const uint8_t *src
+; r1 int src_stride
+; r2 uint8_t *dst
+; r3 int dst_stride
+; sp[]const int16_t *filter_x
+; sp[]int x_step_q4
+; sp[]const int16_t *filter_y ; unused
+; sp[]int y_step_q4 ; unused
+; sp[]int w
+; sp[]int h
+
+|vp9_convolve8_horiz_neon| PROC
+ push {r4-r10, lr}
+
+ sub r0, r0, #3 ; adjust for taps
+
+ ldr r4, [sp, #36] ; x_step_q4
+ ldr r5, [sp, #32] ; filter_x
+ cmp r4, #16
+ bne call_horiz_c_convolve ; x_step_q4 != 16
+
+ ldr r6, [sp, #48] ; w
+ ldr r7, [sp, #52] ; h
+
+ vld1.s16 {q0}, [r5] ; filter_x
+
+ add r8, r1, r1, lsl #1 ; src_stride * 3
+ add r8, r8, #4 ; src_stride * 3 + 4
+ rsb r8, r8, #0 ; reset for src
+
+ add r4, r3, r3, lsl #1 ; dst_stride * 3
+ sub r4, r4, #4 ; dst_stride * 3 - 4
+ rsb r4, r4, #0 ; reset for dst
+
+ sub r9, r1, #8 ; post increment for src load
+
+ rsb r1, r6, r1, lsl #2 ; reset src for outer loop
+ rsb r12, r6, r3, lsl #2 ; reset dst for outer loop
+
+ mov r10, r6 ; w loop counter
+
+loop_horiz
+ vld4.u8 {d24[0], d25[0], d26[0], d27[0]}, [r0]!
+ vld4.u8 {d24[4], d25[4], d26[4], d27[4]}, [r0]!
+ vld3.u8 {d28[0], d29[0], d30[0]}, [r0], r9
+
+ vld4.u8 {d24[1], d25[1], d26[1], d27[1]}, [r0]!
+ vld4.u8 {d24[5], d25[5], d26[5], d27[5]}, [r0]!
+ vld3.u8 {d28[1], d29[1], d30[1]}, [r0], r9
+
+ vld4.u8 {d24[2], d25[2], d26[2], d27[2]}, [r0]!
+ vld4.u8 {d24[6], d25[6], d26[6], d27[6]}, [r0]!
+ vld3.u8 {d28[2], d29[2], d30[2]}, [r0], r9
+
+ vld4.u8 {d24[3], d25[3], d26[3], d27[3]}, [r0]!
+ vld4.u8 {d24[7], d25[7], d26[7], d27[7]}, [r0]!
+ vld3.u8 {d28[3], d29[3], d30[3]}, [r0], r8
+
+ ; extract to s16
+ vmovl.u8 q8, d24
+ vmovl.u8 q9, d25
+ vmovl.u8 q10, d26
+ vmovl.u8 q11, d27
+ vtrn.32 d28, d29 ; only the first half is populated
+ vmovl.u8 q12, d28
+ vmovl.u8 q13, d30
+
+ ; src[] * filter_x
+ MULTIPLY_BY_Q0 q1, d16, d18, d20, d22, d17, d19, d21, d23
+ MULTIPLY_BY_Q0 q2, d18, d20, d22, d17, d19, d21, d23, d24
+ MULTIPLY_BY_Q0 q14, d20, d22, d17, d19, d21, d23, d24, d25
+ MULTIPLY_BY_Q0 q15, d22, d17, d19, d21, d23, d24, d25, d26
+
+ ; += 64 >> 7
+ vqrshrun.s32 d2, q1, #7
+ vqrshrun.s32 d3, q2, #7
+ vqrshrun.s32 d4, q14, #7
+ vqrshrun.s32 d5, q15, #7
+
+ ; saturate
+ vqshrn.u16 d2, q1, #0
+ vqshrn.u16 d3, q2, #0
+
+ ; transpose
+ vtrn.16 d2, d3
+ vtrn.32 d2, d3
+ vtrn.8 d2, d3
+
+ vst1.u32 {d2[0]}, [r2], r3
+ vst1.u32 {d3[0]}, [r2], r3
+ vst1.u32 {d2[1]}, [r2], r3
+ vst1.u32 {d3[1]}, [r2], r4
+
+ subs r6, r6, #4 ; w -= 4
+ bgt loop_horiz
+
+ ; outer loop
+ mov r6, r10 ; restore w counter
+ add r0, r0, r1 ; src += src_stride * 4 - w
+ add r2, r2, r12 ; dst += dst_stride * 4 - w
+ subs r7, r7, #4 ; h -= 4
+ bgt loop_horiz
+
+ pop {r4-r10, pc}
+
+call_horiz_c_convolve
+ pop {r4-r10, lr}
+ add r0, r0, #3 ; un-adjust for taps
+ b vp9_convolve8_horiz_c
+
+
+ ENDP
+
+|vp9_convolve8_vert_neon| PROC
+ push {r4-r10, lr}
+
+ ; adjust for taps
+ sub r0, r0, r1
+ sub r0, r0, r1, lsl #1
+
+ ldr r6, [sp, #44] ; y_step_q4
+ ldr r7, [sp, #40] ; filter_y
+ cmp r6, #16
+ bne call_vert_c_convolve ; y_step_q4 != 16
+
+ ldr r8, [sp, #48] ; w
+ ldr r9, [sp, #52] ; h
+
+ vld1.s16 {q0}, [r7] ; filter_y
+
+ mov r5, r1, lsl #1 ; src_stride * 2
+ add r5, r5, r1, lsl #3 ; src_stride * 10
+ sub r5, r5, #4 ; src_stride * 10 + 4
+ rsb r5, r5, #0 ; reset for src
+
+ add r6, r3, r3, lsl #1 ; dst_stride * 3
+ sub r6, r6, #4 ; dst_stride * 3 - 4
+ rsb r6, r6, #0 ; reset for dst
+
+ rsb r7, r8, r1, lsl #2 ; reset src for outer loop
+ rsb r12, r8, r3, lsl #2 ; reset dst for outer loop
+
+ mov r10, r8 ; w loop counter
+
+loop_vert
+ ; always process a 4x4 block at a time
+ vld1.u32 {d16[0]}, [r0], r1
+ vld1.u32 {d16[1]}, [r0], r1
+ vld1.u32 {d18[0]}, [r0], r1
+ vld1.u32 {d18[1]}, [r0], r1
+ vld1.u32 {d20[0]}, [r0], r1
+ vld1.u32 {d20[1]}, [r0], r1
+ vld1.u32 {d22[0]}, [r0], r1
+ vld1.u32 {d22[1]}, [r0], r1
+ vld1.u32 {d24[0]}, [r0], r1
+ vld1.u32 {d24[1]}, [r0], r1
+ vld1.u32 {d26[0]}, [r0], r5
+
+ ; extract to s16
+ vmovl.u8 q8, d16
+ vmovl.u8 q9, d18
+ vmovl.u8 q10, d20
+ vmovl.u8 q11, d22
+ vmovl.u8 q12, d24
+ vmovl.u8 q13, d26
+
+ ; src[] * filter_y
+ MULTIPLY_BY_Q0 q1, d16, d17, d18, d19, d20, d21, d22, d23
+ MULTIPLY_BY_Q0 q2, d17, d18, d19, d20, d21, d22, d23, d24
+ MULTIPLY_BY_Q0 q14, d18, d19, d20, d21, d22, d23, d24, d25
+ MULTIPLY_BY_Q0 q15, d19, d20, d21, d22, d23, d24, d25, d26
+
+ ; += 64 >> 7
+ vqrshrun.s32 d2, q1, #7
+ vqrshrun.s32 d3, q2, #7
+ vqrshrun.s32 d4, q14, #7
+ vqrshrun.s32 d5, q15, #7
+
+ ; saturate
+ vqshrn.u16 d2, q1, #0
+ vqshrn.u16 d3, q2, #0
+
+ vst1.u32 {d2[0]}, [r2], r3
+ vst1.u32 {d2[1]}, [r2], r3
+ vst1.u32 {d3[0]}, [r2], r3
+ vst1.u32 {d3[1]}, [r2], r6
+
+ subs r8, r8, #4 ; w -= 4
+ bgt loop_vert
+
+ ; outer loop
+ mov r8, r10 ; restore w counter
+ add r0, r0, r7 ; src += 4 * src_stride - w
+ add r2, r2, r12 ; dst += 4 * dst_stride - w
+ subs r9, r9, #4 ; h -= 4
+ bgt loop_vert
+
+ pop {r4-r10, pc}
+
+call_vert_c_convolve
+ pop {r4-r10, lr}
+ ; un-adjust for taps
+ add r0, r0, r1
+ add r0, r0, r1, lsl #1
+ b vp9_convolve8_vert_c
+
+ ENDP
+ END
diff --git a/vp9/common/arm/neon/vp9_dc_only_idct_add_neon.asm b/vp9/common/arm/neon/vp9_dc_only_idct_add_neon.asm
new file mode 100644
index 000000000..60a0d98c5
--- /dev/null
+++ b/vp9/common/arm/neon/vp9_dc_only_idct_add_neon.asm
@@ -0,0 +1,69 @@
+;
+; Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+;
+; Use of this source code is governed by a BSD-style license and patent
+; grant that can be found in the LICENSE file in the root of the source
+; tree. All contributing project authors may be found in the AUTHORS
+; file in the root of the source tree.
+;
+
+
+ EXPORT |vp9_dc_only_idct_add_neon|
+ ARM
+ REQUIRE8
+ PRESERVE8
+
+ AREA ||.text||, CODE, READONLY, ALIGN=2
+
+;void vp9_dc_only_idct_add_neon(int input_dc, uint8_t *pred_ptr,
+; uint8_t *dst_ptr, int pitch, int stride)
+;
+; r0 int input_dc
+; r1 uint8_t *pred_ptr
+; r2 uint8_t *dst_ptr
+; r3 int pitch
+; sp int stride
+
+|vp9_dc_only_idct_add_neon| PROC
+
+ ; generate cospi_16_64 = 11585
+ mov r12, #0x2d00
+ add r12, #0x41
+
+ ; dct_const_round_shift(input_dc * cospi_16_64)
+ mul r0, r0, r12 ; input_dc * cospi_16_64
+ add r0, r0, #0x2000 ; +(1 << ((DCT_CONST_BITS) - 1))
+ asr r0, r0, #14 ; >> DCT_CONST_BITS
+
+ ; dct_const_round_shift(out * cospi_16_64)
+ mul r0, r0, r12 ; out * cospi_16_64
+ add r0, r0, #0x2000 ; +(1 << ((DCT_CONST_BITS) - 1))
+ asr r0, r0, #14 ; >> DCT_CONST_BITS
+
+ ; ROUND_POWER_OF_TWO(out, 4)
+ add r0, r0, #8 ; + (1 <<((4) - 1))
+ asr r0, r0, #4 ; >> 4
+
+ vdup.16 q0, r0; ; duplicate a1
+ ldr r12, [sp] ; load stride
+
+ vld1.32 {d2[0]}, [r1], r3
+ vld1.32 {d2[1]}, [r1], r3
+ vld1.32 {d4[0]}, [r1], r3
+ vld1.32 {d4[1]}, [r1]
+
+ vaddw.u8 q1, q0, d2 ; a1 + pred_ptr[c]
+ vaddw.u8 q2, q0, d4
+
+ vqmovun.s16 d2, q1 ; clip_pixel
+ vqmovun.s16 d4, q2
+
+ vst1.32 {d2[0]}, [r2], r12
+ vst1.32 {d2[1]}, [r2], r12
+ vst1.32 {d4[0]}, [r2], r12
+ vst1.32 {d4[1]}, [r2]
+
+ bx lr
+ ENDP ; |vp9_dc_only_idct_add_neon|
+
+ END
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 385dcc1d1..e67250b0f 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -13,18 +13,19 @@
#define VP9_COMMON_VP9_BLOCKD_H_
#include "./vpx_config.h"
+
+#include "vpx_ports/mem.h"
#include "vpx_scale/yv12config.h"
+
+#include "vp9/common/vp9_common.h"
+#include "vp9/common/vp9_common_data.h"
#include "vp9/common/vp9_convolve.h"
+#include "vp9/common/vp9_enums.h"
#include "vp9/common/vp9_mv.h"
+#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_treecoder.h"
-#include "vpx_ports/mem.h"
-#include "vp9/common/vp9_common.h"
-#include "vp9/common/vp9_enums.h"
-#include "vp9/common/vp9_common_data.h"
#define BLOCK_SIZE_GROUPS 4
-#define MAX_MB_SEGMENTS 8
-#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1)
#define PREDICTION_PROBS 3
@@ -34,8 +35,6 @@
#define MAX_MODE_LF_DELTAS 2
/* Segment Feature Masks */
-#define SEGMENT_DELTADATA 0
-#define SEGMENT_ABSDATA 1
#define MAX_MV_REF_CANDIDATES 2
#define INTRA_INTER_CONTEXTS 4
@@ -94,15 +93,6 @@ static INLINE int is_inter_mode(MB_PREDICTION_MODE mode) {
// Segment level features.
typedef enum {
- SEG_LVL_ALT_Q = 0, // Use alternate Quantizer ....
- SEG_LVL_ALT_LF = 1, // Use alternate loop filter value...
- SEG_LVL_REF_FRAME = 2, // Optional Segment reference frame
- SEG_LVL_SKIP = 3, // Optional Segment (0,0) + skip mode
- SEG_LVL_MAX = 4 // Number of MB level features supported
-} SEG_LVL_FEATURES;
-
-// Segment level features.
-typedef enum {
TX_4X4 = 0, // 4x4 dct transform
TX_8X8 = 1, // 8x8 dct transform
TX_16X16 = 2, // 16x16 dct transform
@@ -253,32 +243,12 @@ typedef struct macroblockd {
int left_available;
int right_available;
+ struct segmentation seg;
+
// partition contexts
PARTITION_CONTEXT *above_seg_context;
PARTITION_CONTEXT *left_seg_context;
- /* 0 (disable) 1 (enable) segmentation */
- unsigned char segmentation_enabled;
-
- /* 0 (do not update) 1 (update) the macroblock segmentation map. */
- unsigned char update_mb_segmentation_map;
-
- /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */
- unsigned char update_mb_segmentation_data;
-
- /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */
- unsigned char mb_segment_abs_delta;
-
- /* 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 */
-
- // Probability Tree used to code Segment number
- vp9_prob mb_segment_tree_probs[MB_SEG_TREE_PROBS];
-
- // Segment features
- int16_t segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
- unsigned int segment_feature_mask[MAX_MB_SEGMENTS];
-
/* mode_based Loop filter adjustment */
unsigned char mode_ref_lf_delta_enabled;
unsigned char mode_ref_lf_delta_update;
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 1cdf1380d..0b5f2ea46 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -460,8 +460,8 @@ void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) {
// Reset the segment feature data to the default stats:
// Features disabled, 0, with delta coding (Default state).
int i;
- vp9_clearall_segfeatures(xd);
- xd->mb_segment_abs_delta = SEGMENT_DELTADATA;
+ vp9_clearall_segfeatures(&xd->seg);
+ xd->seg.abs_delta = SEGMENT_DELTADATA;
if (cm->last_frame_seg_map)
vpx_memset(cm->last_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols));
diff --git a/vp9/common/vp9_entropymv.c b/vp9/common/vp9_entropymv.c
index 50e8463f6..ed6af665e 100644
--- a/vp9/common/vp9_entropymv.c
+++ b/vp9/common/vp9_entropymv.c
@@ -56,7 +56,7 @@ const vp9_tree_index vp9_mv_fp_tree [2 * 4 - 2] = {
};
struct vp9_token vp9_mv_fp_encodings[4];
-const nmv_context vp9_default_nmv_context = {
+static const nmv_context default_nmv_context = {
{32, 64, 96},
{
{ /* vert component */
@@ -360,5 +360,5 @@ void vp9_entropy_mv_init() {
}
void vp9_init_mv_probs(VP9_COMMON *cm) {
- vpx_memcpy(&cm->fc.nmvc, &vp9_default_nmv_context, sizeof(nmv_context));
+ cm->fc.nmvc = default_nmv_context;
}
diff --git a/vp9/common/vp9_entropymv.h b/vp9/common/vp9_entropymv.h
index 15f9ada43..0df92d031 100644
--- a/vp9/common/vp9_entropymv.h
+++ b/vp9/common/vp9_entropymv.h
@@ -130,7 +130,6 @@ typedef struct {
void vp9_inc_mv(const MV *mv, const MV *ref, nmv_context_counts *mvctx,
int usehp);
-extern const nmv_context vp9_default_nmv_context;
void vp9_counts_process(nmv_context_counts *NMVcount, int usehp);
diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c
index 6dc622a96..37209a74b 100644
--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -92,9 +92,9 @@ void vp9_loop_filter_frame_init(VP9_COMMON *cm, MACROBLOCKD *xd,
int lvl_seg = default_filt_lvl, ref, mode, intra_lvl;
// Set the baseline filter values for each segment
- if (vp9_segfeature_active(xd, seg, SEG_LVL_ALT_LF)) {
- const int data = vp9_get_segdata(xd, seg, SEG_LVL_ALT_LF);
- lvl_seg = xd->mb_segment_abs_delta == SEGMENT_ABSDATA
+ if (vp9_segfeature_active(&xd->seg, seg, SEG_LVL_ALT_LF)) {
+ const int data = vp9_get_segdata(&xd->seg, seg, SEG_LVL_ALT_LF);
+ lvl_seg = xd->seg.abs_delta == SEGMENT_ABSDATA
? data
: clamp(default_filt_lvl + data, 0, MAX_LOOP_FILTER);
}
diff --git a/vp9/common/vp9_loopfilter.h b/vp9/common/vp9_loopfilter.h
index 2582979f5..52d3b2d63 100644
--- a/vp9/common/vp9_loopfilter.h
+++ b/vp9/common/vp9_loopfilter.h
@@ -13,7 +13,9 @@
#include "vpx_ports/mem.h"
#include "vpx_config.h"
+
#include "vp9/common/vp9_blockd.h"
+#include "vp9/common/vp9_seg_common.h"
#define MAX_LOOP_FILTER 63
#define MAX_SHARPNESS 7
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 7094e711d..b7025cac7 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -247,10 +247,6 @@ typedef struct VP9Common {
[VP9_INTRA_MODES - 1];
vp9_prob kf_uv_mode_prob[VP9_INTRA_MODES] [VP9_INTRA_MODES - 1];
- // Context probabilities when using predictive coding of segment id
- vp9_prob segment_pred_probs[PREDICTION_PROBS];
- unsigned char temporal_update;
-
// Context probabilities for reference frame prediction
int allow_comp_inter_inter;
MV_REFERENCE_FRAME comp_fixed_ref;
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h
index 3ec1ff780..21a7d809e 100644
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -32,7 +32,7 @@ static INLINE unsigned char vp9_get_pred_context_seg_id(const VP9_COMMON *cm,
static INLINE vp9_prob vp9_get_pred_prob_seg_id(const VP9_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = vp9_get_pred_context_seg_id(cm, xd);
- return cm->segment_pred_probs[pred_context];
+ return xd->seg.pred_probs[pred_context];
}
static INLINE unsigned char vp9_get_pred_flag_seg_id(
const MACROBLOCKD * const xd) {
diff --git a/vp9/common/vp9_quant_common.c b/vp9/common/vp9_quant_common.c
index 295c8e738..2b81c2e28 100644
--- a/vp9/common/vp9_quant_common.c
+++ b/vp9/common/vp9_quant_common.c
@@ -57,9 +57,9 @@ int16_t vp9_ac_quant(int qindex, int delta) {
int vp9_get_qindex(MACROBLOCKD *xd, int segment_id, int base_qindex) {
- if (vp9_segfeature_active(xd, segment_id, SEG_LVL_ALT_Q)) {
- const int data = vp9_get_segdata(xd, segment_id, SEG_LVL_ALT_Q);
- return xd->mb_segment_abs_delta == SEGMENT_ABSDATA ?
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_ALT_Q)) {
+ const int data = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_ALT_Q);
+ return xd->seg.abs_delta == SEGMENT_ABSDATA ?
data : // Abs value
clamp(base_qindex + data, 0, MAXQ); // Delta value
} else {
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index 56a2284b5..95cf3acb8 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -274,10 +274,10 @@ prototype void vp9_convolve8 "const uint8_t *src, ptrdiff_t src_stride, uint8_t
specialize vp9_convolve8 ssse3
prototype void vp9_convolve8_horiz "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int x_step_q4, const int16_t *filter_y, int y_step_q4, int w, int h"
-specialize vp9_convolve8_horiz ssse3
+specialize vp9_convolve8_horiz ssse3 neon
prototype void vp9_convolve8_vert "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int x_step_q4, const int16_t *filter_y, int y_step_q4, int w, int h"
-specialize vp9_convolve8_vert ssse3
+specialize vp9_convolve8_vert ssse3 neon
prototype void vp9_convolve8_avg "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int x_step_q4, const int16_t *filter_y, int y_step_q4, int w, int h"
specialize vp9_convolve8_avg ssse3
@@ -325,7 +325,7 @@ prototype void vp9_short_idct10_32x32_add "int16_t *input, uint8_t *dest, int de
specialize vp9_short_idct10_32x32_add
prototype void vp9_short_iht4x4_add "int16_t *input, uint8_t *dest, int dest_stride, int tx_type"
-specialize vp9_short_iht4x4_add
+specialize vp9_short_iht4x4_add sse2
prototype void vp9_short_iht8x8_add "int16_t *input, uint8_t *dest, int dest_stride, int tx_type"
specialize vp9_short_iht8x8_add
@@ -338,7 +338,7 @@ specialize vp9_idct4_1d sse2
# dct and add
prototype void vp9_dc_only_idct_add "int input_dc, uint8_t *pred_ptr, uint8_t *dst_ptr, int pitch, int stride"
-specialize vp9_dc_only_idct_add sse2
+specialize vp9_dc_only_idct_add sse2 neon
prototype void vp9_short_iwalsh4x4_1_add "int16_t *input, uint8_t *dest, int dest_stride"
specialize vp9_short_iwalsh4x4_1_add
diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c
index 9bf207251..9b13b5b5f 100644
--- a/vp9/common/vp9_seg_common.c
+++ b/vp9/common/vp9_seg_common.c
@@ -9,8 +9,11 @@
*/
#include <assert.h>
+
#include "vp9/common/vp9_blockd.h"
+#include "vp9/common/vp9_loopfilter.h"
#include "vp9/common/vp9_seg_common.h"
+#include "vp9/common/vp9_quant_common.h"
static const int seg_feature_data_signed[SEG_LVL_MAX] = { 1, 1, 0, 0 };
@@ -22,25 +25,25 @@ static const int seg_feature_data_max[SEG_LVL_MAX] = {
// the coding mechanism is still subject to change so these provide a
// convenient single point of change.
-int vp9_segfeature_active(const MACROBLOCKD *xd, int segment_id,
+int vp9_segfeature_active(const struct segmentation *seg, int segment_id,
SEG_LVL_FEATURES feature_id) {
- return xd->segmentation_enabled &&
- (xd->segment_feature_mask[segment_id] & (1 << feature_id));
+ return seg->enabled &&
+ (seg->feature_mask[segment_id] & (1 << feature_id));
}
-void vp9_clearall_segfeatures(MACROBLOCKD *xd) {
- vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
- vpx_memset(xd->segment_feature_mask, 0, sizeof(xd->segment_feature_mask));
+void vp9_clearall_segfeatures(struct segmentation *seg) {
+ vpx_memset(seg->feature_data, 0, sizeof(seg->feature_data));
+ vpx_memset(seg->feature_mask, 0, sizeof(seg->feature_mask));
}
-void vp9_enable_segfeature(MACROBLOCKD *xd, int segment_id,
+void vp9_enable_segfeature(struct segmentation *seg, int segment_id,
SEG_LVL_FEATURES feature_id) {
- xd->segment_feature_mask[segment_id] |= 1 << feature_id;
+ seg->feature_mask[segment_id] |= 1 << feature_id;
}
-void vp9_disable_segfeature(MACROBLOCKD *xd, int segment_id,
+void vp9_disable_segfeature(struct segmentation *seg, int segment_id,
SEG_LVL_FEATURES feature_id) {
- xd->segment_feature_mask[segment_id] &= ~(1 << feature_id);
+ seg->feature_mask[segment_id] &= ~(1 << feature_id);
}
int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id) {
@@ -51,12 +54,12 @@ int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id) {
return seg_feature_data_signed[feature_id];
}
-void vp9_clear_segdata(MACROBLOCKD *xd, int segment_id,
+void vp9_clear_segdata(struct segmentation *seg, int segment_id,
SEG_LVL_FEATURES feature_id) {
- xd->segment_feature_data[segment_id][feature_id] = 0;
+ seg->feature_data[segment_id][feature_id] = 0;
}
-void vp9_set_segdata(MACROBLOCKD *xd, int segment_id,
+void vp9_set_segdata(struct segmentation *seg, int segment_id,
SEG_LVL_FEATURES feature_id, int seg_data) {
assert(seg_data <= seg_feature_data_max[feature_id]);
if (seg_data < 0) {
@@ -64,12 +67,12 @@ void vp9_set_segdata(MACROBLOCKD *xd, int segment_id,
assert(-seg_data <= seg_feature_data_max[feature_id]);
}
- xd->segment_feature_data[segment_id][feature_id] = seg_data;
+ seg->feature_data[segment_id][feature_id] = seg_data;
}
-int vp9_get_segdata(const MACROBLOCKD *xd, int segment_id,
+int vp9_get_segdata(const struct segmentation *seg, int segment_id,
SEG_LVL_FEATURES feature_id) {
- return xd->segment_feature_data[segment_id][feature_id];
+ return seg->feature_data[segment_id][feature_id];
}
diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h
index 74ba03c3e..f072a518d 100644
--- a/vp9/common/vp9_seg_common.h
+++ b/vp9/common/vp9_seg_common.h
@@ -8,23 +8,54 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "vp9/common/vp9_onyxc_int.h"
-#include "vp9/common/vp9_blockd.h"
-
#ifndef VP9_COMMON_VP9_SEG_COMMON_H_
#define VP9_COMMON_VP9_SEG_COMMON_H_
-int vp9_segfeature_active(const MACROBLOCKD *xd,
+#include "vp9/common/vp9_treecoder.h"
+
+#define SEGMENT_DELTADATA 0
+#define SEGMENT_ABSDATA 1
+
+#define MAX_MB_SEGMENTS 8
+#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1)
+
+#define PREDICTION_PROBS 3
+
+// Segment level features.
+typedef enum {
+ SEG_LVL_ALT_Q = 0, // Use alternate Quantizer ....
+ SEG_LVL_ALT_LF = 1, // Use alternate loop filter value...
+ SEG_LVL_REF_FRAME = 2, // Optional Segment reference frame
+ SEG_LVL_SKIP = 3, // Optional Segment (0,0) + skip mode
+ SEG_LVL_MAX = 4 // Number of MB level features supported
+} SEG_LVL_FEATURES;
+
+
+struct segmentation {
+ uint8_t enabled;
+ uint8_t update_map;
+ uint8_t update_data;
+ uint8_t abs_delta;
+ uint8_t temporal_update;
+
+ vp9_prob tree_probs[MB_SEG_TREE_PROBS];
+ vp9_prob pred_probs[PREDICTION_PROBS];
+
+ int16_t feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
+ unsigned int feature_mask[MAX_MB_SEGMENTS];
+};
+
+int vp9_segfeature_active(const struct segmentation *seg,
int segment_id,
SEG_LVL_FEATURES feature_id);
-void vp9_clearall_segfeatures(MACROBLOCKD *xd);
+void vp9_clearall_segfeatures(struct segmentation *seg);
-void vp9_enable_segfeature(MACROBLOCKD *xd,
+void vp9_enable_segfeature(struct segmentation *seg,
int segment_id,
SEG_LVL_FEATURES feature_id);
-void vp9_disable_segfeature(MACROBLOCKD *xd,
+void vp9_disable_segfeature(struct segmentation *seg,
int segment_id,
SEG_LVL_FEATURES feature_id);
@@ -32,16 +63,16 @@ int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id);
int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id);
-void vp9_clear_segdata(MACROBLOCKD *xd,
+void vp9_clear_segdata(struct segmentation *seg,
int segment_id,
SEG_LVL_FEATURES feature_id);
-void vp9_set_segdata(MACROBLOCKD *xd,
+void vp9_set_segdata(struct segmentation *seg,
int segment_id,
SEG_LVL_FEATURES feature_id,
int seg_data);
-int vp9_get_segdata(const MACROBLOCKD *xd,
+int vp9_get_segdata(const struct segmentation *seg,
int segment_id,
SEG_LVL_FEATURES feature_id);
diff --git a/vp9/common/x86/vp9_asm_stubs.c b/vp9/common/x86/vp9_asm_stubs.c
index 98fc4dc83..3f1c19828 100644
--- a/vp9/common/x86/vp9_asm_stubs.c
+++ b/vp9/common/x86/vp9_asm_stubs.c
@@ -126,6 +126,7 @@ void vp9_convolve8_horiz_ssse3(const uint8_t *src, ptrdiff_t src_stride,
const int16_t *filter_x, int x_step_q4,
const int16_t *filter_y, int y_step_q4,
int w, int h) {
+ /* Ensure the filter can be compressed to int16_t. */
if (x_step_q4 == 16 && filter_x[3] != 128) {
while (w >= 16) {
vp9_filter_block1d16_h8_ssse3(src, src_stride,
diff --git a/vp9/common/x86/vp9_idct_intrin_sse2.c b/vp9/common/x86/vp9_idct_intrin_sse2.c
index 599dcff93..4495b15ed 100644
--- a/vp9/common/x86/vp9_idct_intrin_sse2.c
+++ b/vp9/common/x86/vp9_idct_intrin_sse2.c
@@ -241,6 +241,155 @@ void vp9_idct4_1d_sse2(int16_t *input, int16_t *output) {
_mm_storel_epi64((__m128i *)output, in);
}
+static INLINE void transpose_4x4(__m128i *res) {
+ const __m128i tr0_0 = _mm_unpacklo_epi16(res[0], res[1]);
+ const __m128i tr0_1 = _mm_unpacklo_epi16(res[2], res[3]);
+ res[0] = _mm_unpacklo_epi32(tr0_0, tr0_1);
+ res[2] = _mm_unpackhi_epi32(tr0_0, tr0_1);
+
+ res[1] = _mm_unpackhi_epi64(res[0], res[0]);
+ res[3] = _mm_unpackhi_epi64(res[2], res[2]);
+}
+
+void idct4_1d_sse2(__m128i *in) {
+ const __m128i k__cospi_p16_p16 = pair_set_epi16(cospi_16_64, cospi_16_64);
+ const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64);
+ const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64);
+ const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64);
+ const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING);
+ __m128i u[8], v[8];
+
+ transpose_4x4(in);
+ // stage 1
+ u[0] = _mm_unpacklo_epi16(in[0], in[2]);
+ u[1] = _mm_unpacklo_epi16(in[1], in[3]);
+ v[0] = _mm_madd_epi16(u[0], k__cospi_p16_p16);
+ v[1] = _mm_madd_epi16(u[0], k__cospi_p16_m16);
+ v[2] = _mm_madd_epi16(u[1], k__cospi_p24_m08);
+ v[3] = _mm_madd_epi16(u[1], k__cospi_p08_p24);
+
+ u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING);
+ u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING);
+ u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING);
+ u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING);
+
+ v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS);
+ v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS);
+ v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS);
+ v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS);
+
+ u[0] = _mm_packs_epi32(v[0], v[2]);
+ u[1] = _mm_packs_epi32(v[1], v[3]);
+ u[2] = _mm_unpackhi_epi64(u[0], u[0]);
+ u[3] = _mm_unpackhi_epi64(u[1], u[1]);
+
+ // stage 2
+ in[0] = _mm_add_epi16(u[0], u[3]);
+ in[1] = _mm_add_epi16(u[1], u[2]);
+ in[2] = _mm_sub_epi16(u[1], u[2]);
+ in[3] = _mm_sub_epi16(u[0], u[3]);
+}
+
+void iadst4_1d_sse2(__m128i *in) {
+ const __m128i k__sinpi_p01_p04 = pair_set_epi16(sinpi_1_9, sinpi_4_9);
+ const __m128i k__sinpi_p03_p02 = pair_set_epi16(sinpi_3_9, sinpi_2_9);
+ const __m128i k__sinpi_p02_m01 = pair_set_epi16(sinpi_2_9, -sinpi_1_9);
+ const __m128i k__sinpi_p03_m04 = pair_set_epi16(sinpi_3_9, -sinpi_4_9);
+ const __m128i k__sinpi_p03_p03 = _mm_set1_epi16(sinpi_3_9);
+ const __m128i kZero = _mm_set1_epi16(0);
+ const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING);
+ __m128i u[8], v[8], in7;
+
+ transpose_4x4(in);
+ in7 = _mm_add_epi16(in[0], in[3]);
+ in7 = _mm_sub_epi16(in7, in[2]);
+
+ u[0] = _mm_unpacklo_epi16(in[0], in[2]);
+ u[1] = _mm_unpacklo_epi16(in[1], in[3]);
+ u[2] = _mm_unpacklo_epi16(in7, kZero);
+ u[3] = _mm_unpacklo_epi16(in[1], kZero);
+
+ v[0] = _mm_madd_epi16(u[0], k__sinpi_p01_p04); // s0 + s3
+ v[1] = _mm_madd_epi16(u[1], k__sinpi_p03_p02); // s2 + s5
+ v[2] = _mm_madd_epi16(u[2], k__sinpi_p03_p03); // x2
+ v[3] = _mm_madd_epi16(u[0], k__sinpi_p02_m01); // s1 - s4
+ v[4] = _mm_madd_epi16(u[1], k__sinpi_p03_m04); // s2 - s6
+ v[5] = _mm_madd_epi16(u[3], k__sinpi_p03_p03); // s2
+
+ u[0] = _mm_add_epi32(v[0], v[1]);
+ u[1] = _mm_add_epi32(v[3], v[4]);
+ u[2] = v[2];
+ u[3] = _mm_add_epi32(u[0], u[1]);
+ u[4] = _mm_slli_epi32(v[5], 2);
+ u[5] = _mm_add_epi32(u[3], v[5]);
+ u[6] = _mm_sub_epi32(u[5], u[4]);
+
+ v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING);
+ v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING);
+ v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING);
+ v[3] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING);
+
+ u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS);
+ u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS);
+ u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS);
+ u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS);
+
+ in[0] = _mm_packs_epi32(u[0], u[2]);
+ in[1] = _mm_packs_epi32(u[1], u[3]);
+ in[2] = _mm_unpackhi_epi64(in[0], in[0]);
+ in[3] = _mm_unpackhi_epi64(in[1], in[1]);
+}
+
+void vp9_short_iht4x4_add_sse2(int16_t *input, uint8_t *dest, int stride,
+ int tx_type) {
+ __m128i in[4];
+ const __m128i zero = _mm_setzero_si128();
+ const __m128i eight = _mm_set1_epi16(8);
+
+ in[0] = _mm_loadl_epi64((__m128i *)input);
+ in[1] = _mm_loadl_epi64((__m128i *)(input + 4));
+ in[2] = _mm_loadl_epi64((__m128i *)(input + 8));
+ in[3] = _mm_loadl_epi64((__m128i *)(input + 12));
+
+ switch (tx_type) {
+ case 0: // DCT_DCT
+ idct4_1d_sse2(in);
+ idct4_1d_sse2(in);
+ break;
+ case 1: // ADST_DCT
+ idct4_1d_sse2(in);
+ iadst4_1d_sse2(in);
+ break;
+ case 2: // DCT_ADST
+ iadst4_1d_sse2(in);
+ idct4_1d_sse2(in);
+ break;
+ case 3: // ADST_ADST
+ iadst4_1d_sse2(in);
+ iadst4_1d_sse2(in);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ // Final round and shift
+ in[0] = _mm_add_epi16(in[0], eight);
+ in[1] = _mm_add_epi16(in[1], eight);
+ in[2] = _mm_add_epi16(in[2], eight);
+ in[3] = _mm_add_epi16(in[3], eight);
+
+ in[0] = _mm_srai_epi16(in[0], 4);
+ in[1] = _mm_srai_epi16(in[1], 4);
+ in[2] = _mm_srai_epi16(in[2], 4);
+ in[3] = _mm_srai_epi16(in[3], 4);
+
+ RECON_AND_STORE4X4(dest, in[0]);
+ RECON_AND_STORE4X4(dest, in[1]);
+ RECON_AND_STORE4X4(dest, in[2]);
+ RECON_AND_STORE4X4(dest, in[3]);
+}
+
#define TRANSPOSE_8X8(in0, in1, in2, in3, in4, in5, in6, in7, \
out0, out1, out2, out3, out4, out5, out6, out7) \
{ \
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 369505c2f..3fc62c365 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -44,8 +44,8 @@ static MB_PREDICTION_MODE read_inter_mode(vp9_reader *r, const vp9_prob *p) {
return (MB_PREDICTION_MODE)treed_read(r, vp9_sb_mv_ref_tree, p);
}
-static int read_segment_id(vp9_reader *r, MACROBLOCKD *xd) {
- return treed_read(r, vp9_segment_tree, xd->mb_segment_tree_probs);
+static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
+ return treed_read(r, vp9_segment_tree, seg->tree_probs);
}
static TX_SIZE read_selected_txfm_size(VP9_COMMON *cm, MACROBLOCKD *xd,
@@ -105,13 +105,13 @@ static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize,
static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
vp9_reader *r) {
- VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
+ struct segmentation *const seg = &xd->seg;
const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
- if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
- const int segment_id = read_segment_id(r, xd);
- set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
+ if (seg->enabled && seg->update_map) {
+ const int segment_id = read_segment_id(r, seg);
+ set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id);
return segment_id;
} else {
return 0;
@@ -121,7 +121,7 @@ static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
static uint8_t read_skip_coeff(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
- int skip_coeff = vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
+ int skip_coeff = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP);
if (!skip_coeff) {
const uint8_t ctx = vp9_get_pred_context_mbskip(cm, xd);
skip_coeff = vp9_read(r, vp9_get_pred_prob_mbskip(cm, xd));
@@ -290,8 +290,8 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
MACROBLOCKD *const xd = &pbi->mb;
FRAME_CONTEXT *const fc = &cm->fc;
- if (vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) {
- ref_frame[0] = vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME);
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
+ ref_frame[0] = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME);
ref_frame[1] = NONE;
} else {
const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
@@ -366,26 +366,28 @@ static int read_inter_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
+ struct segmentation *const seg = &xd->seg;
const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
int pred_segment_id;
int segment_id;
- if (!xd->segmentation_enabled)
+ if (!seg->enabled)
return 0; // Default for disabled segmentation
pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
- bsize, mi_row, mi_col);
- if (!xd->update_mb_segmentation_map)
+ bsize, mi_row, mi_col);
+ if (!seg->update_map)
return pred_segment_id;
- if (cm->temporal_update) {
+
+ if (seg->temporal_update) {
const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(cm, xd);
const int pred_flag = vp9_read(r, pred_prob);
vp9_set_pred_flag_seg_id(xd, bsize, pred_flag);
segment_id = pred_flag ? pred_segment_id
- : read_segment_id(r, xd);
+ : read_segment_id(r, seg);
} else {
- segment_id = read_segment_id(r, xd);
+ segment_id = read_segment_id(r, seg);
}
set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
return segment_id;
@@ -455,14 +457,14 @@ static MV_REFERENCE_FRAME read_reference_frame(VP9D_COMP *pbi, int segment_id,
MACROBLOCKD *const xd = &pbi->mb;
MV_REFERENCE_FRAME ref;
- if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) {
+ if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
const int ctx = vp9_get_pred_context_intra_inter(cm, xd);
ref = (MV_REFERENCE_FRAME)
vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
cm->fc.intra_inter_count[ctx][ref != INTRA_FRAME]++;
} else {
- ref = (MV_REFERENCE_FRAME)
- vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME;
+ ref = (MV_REFERENCE_FRAME) vp9_get_segdata(&xd->seg, segment_id,
+ SEG_LVL_REF_FRAME) != INTRA_FRAME;
}
return ref;
}
@@ -515,7 +517,7 @@ static void read_inter_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
mv_ref_p = cm->fc.inter_mode_probs[mbmi->mb_mode_context[ref0]];
- if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) {
+ if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
mbmi->mode = ZEROMV;
} else if (bsize >= BLOCK_SIZE_SB8X8) {
mbmi->mode = read_inter_mode(r, mv_ref_p);
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 37bdad29d..48be06946 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -174,7 +174,7 @@ static int decode_tokens(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
vp9_reset_sb_tokens_context(xd, bsize);
return -1;
} else {
- if (xd->segmentation_enabled)
+ if (xd->seg.enabled)
mb_init_dequantizer(&pbi->common, xd);
// TODO(dkovalev) if (!vp9_reader_has_error(r))
@@ -395,55 +395,53 @@ static void read_coef_probs(FRAME_CONTEXT *fc, TXFM_MODE txfm_mode,
read_coef_probs_common(fc, TX_32X32, r);
}
-static void setup_segmentation(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
+static void setup_segmentation(struct segmentation *seg,
+ struct vp9_read_bit_buffer *rb) {
int i, j;
- VP9_COMMON *const cm = &pbi->common;
- MACROBLOCKD *const xd = &pbi->mb;
-
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ seg->update_map = 0;
+ seg->update_data = 0;
- xd->segmentation_enabled = vp9_rb_read_bit(rb);
- if (!xd->segmentation_enabled)
+ seg->enabled = vp9_rb_read_bit(rb);
+ if (!seg->enabled)
return;
// Segmentation map update
- xd->update_mb_segmentation_map = vp9_rb_read_bit(rb);
- if (xd->update_mb_segmentation_map) {
+ seg->update_map = vp9_rb_read_bit(rb);
+ if (seg->update_map) {
for (i = 0; i < MB_SEG_TREE_PROBS; i++)
- xd->mb_segment_tree_probs[i] = vp9_rb_read_bit(rb) ?
- vp9_rb_read_literal(rb, 8) : MAX_PROB;
+ seg->tree_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8)
+ : MAX_PROB;
- cm->temporal_update = vp9_rb_read_bit(rb);
- if (cm->temporal_update) {
+ seg->temporal_update = vp9_rb_read_bit(rb);
+ if (seg->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++)
- cm->segment_pred_probs[i] = vp9_rb_read_bit(rb) ?
- vp9_rb_read_literal(rb, 8) : MAX_PROB;
+ seg->pred_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8)
+ : MAX_PROB;
} else {
for (i = 0; i < PREDICTION_PROBS; i++)
- cm->segment_pred_probs[i] = MAX_PROB;
+ seg->pred_probs[i] = MAX_PROB;
}
}
// Segmentation data update
- xd->update_mb_segmentation_data = vp9_rb_read_bit(rb);
- if (xd->update_mb_segmentation_data) {
- xd->mb_segment_abs_delta = vp9_rb_read_bit(rb);
+ seg->update_data = vp9_rb_read_bit(rb);
+ if (seg->update_data) {
+ seg->abs_delta = vp9_rb_read_bit(rb);
- vp9_clearall_segfeatures(xd);
+ vp9_clearall_segfeatures(seg);
for (i = 0; i < MAX_MB_SEGMENTS; i++) {
for (j = 0; j < SEG_LVL_MAX; j++) {
int data = 0;
const int feature_enabled = vp9_rb_read_bit(rb);
if (feature_enabled) {
- vp9_enable_segfeature(xd, i, j);
+ vp9_enable_segfeature(seg, i, j);
data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j));
if (vp9_is_segfeature_signed(j))
data = vp9_rb_read_bit(rb) ? -data : data;
}
- vp9_set_segdata(xd, i, j, data);
+ vp9_set_segdata(seg, i, j, data);
}
}
}
@@ -902,7 +900,7 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
setup_loopfilter(pbi, rb);
setup_quantization(pbi, rb);
- setup_segmentation(pbi, rb);
+ setup_segmentation(&pbi->mb.seg, rb);
setup_tile_info(cm, rb);
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index 76889c477..3a4fae065 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -278,8 +278,8 @@ SKIP_START:
return c;
}
-static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
- return vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
+static int get_eob(struct segmentation *seg, int segment_id, int eob_max) {
+ return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
}
struct decode_block_args {
@@ -300,7 +300,7 @@ static void decode_block(int plane, int block,
struct macroblockd_plane* pd = &xd->plane[plane];
const int segment_id = xd->mode_info_context->mbmi.segment_id;
const TX_SIZE ss_tx_size = ss_txfrm_size / 2;
- const int seg_eob = get_eob(xd, segment_id, 16 << ss_txfrm_size);
+ const int seg_eob = get_eob(&xd->seg, segment_id, 16 << ss_txfrm_size);
const int off = block >> ss_txfrm_size;
const int mod = bw - ss_tx_size - pd->subsampling_x;
const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size;
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 3a2990cf3..adeff102f 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -216,7 +216,7 @@ static void write_selected_txfm_size(const VP9_COMP *cpi, TX_SIZE tx_size,
static int write_skip_coeff(const VP9_COMP *cpi, int segment_id, MODE_INFO *m,
vp9_writer *w) {
const MACROBLOCKD *const xd = &cpi->mb.e_mbd;
- if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)) {
return 1;
} else {
const int skip_coeff = m->mbmi.mb_skip_coeff;
@@ -348,18 +348,18 @@ static void pack_mb_tokens(vp9_writer* const bc,
*tp = p;
}
-static void write_sb_mv_ref(vp9_writer *w, MB_PREDICTION_MODE m,
+static void write_sb_mv_ref(vp9_writer *w, MB_PREDICTION_MODE mode,
const vp9_prob *p) {
- assert(NEARESTMV <= m && m <= NEWMV);
+ assert(is_inter_mode(mode));
write_token(w, vp9_sb_mv_ref_tree, p,
- vp9_sb_mv_ref_encoding_array - NEARESTMV + m);
+ &vp9_sb_mv_ref_encoding_array[mode - NEARESTMV]);
}
-static void write_segment_id(vp9_writer *w, const MACROBLOCKD *xd,
+static void write_segment_id(vp9_writer *w, const struct segmentation *seg,
int segment_id) {
- if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
- treed_write(w, vp9_segment_tree, xd->mb_segment_tree_probs, segment_id, 3);
+ if (seg->enabled && seg->update_map)
+ treed_write(w, vp9_segment_tree, seg->tree_probs, segment_id, 3);
}
// This function encodes the reference frame
@@ -369,7 +369,7 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *mi = &xd->mode_info_context->mbmi;
const int segment_id = mi->segment_id;
- int seg_ref_active = vp9_segfeature_active(xd, segment_id,
+ int seg_ref_active = vp9_segfeature_active(&xd->seg, segment_id,
SEG_LVL_REF_FRAME);
// If segment level coding of this signal is disabled...
// or the segment allows multiple reference frame options
@@ -396,7 +396,7 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
}
} else {
assert(mi->ref_frame[1] <= INTRA_FRAME);
- assert(vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) ==
+ assert(vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME) ==
mi->ref_frame[0]);
}
@@ -410,6 +410,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
const nmv_context *nmvc = &pc->fc.nmvc;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
+ struct segmentation *seg = &xd->seg;
MB_MODE_INFO *const mi = &m->mbmi;
const MV_REFERENCE_FRAME rf = mi->ref_frame[0];
const MB_PREDICTION_MODE mode = mi->mode;
@@ -423,33 +424,27 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
active_section = 9;
#endif
- if (cpi->mb.e_mbd.update_mb_segmentation_map) {
- // Is temporal coding of the segment map enabled
- if (pc->temporal_update) {
+ if (seg->update_map) {
+ if (seg->temporal_update) {
unsigned char prediction_flag = vp9_get_pred_flag_seg_id(xd);
vp9_prob pred_prob = vp9_get_pred_prob_seg_id(pc, xd);
-
- // Code the segment id prediction flag for this mb
vp9_write(bc, prediction_flag, pred_prob);
-
- // If the mb segment id wasn't predicted code explicitly
if (!prediction_flag)
- write_segment_id(bc, xd, mi->segment_id);
+ write_segment_id(bc, seg, mi->segment_id);
} else {
- // Normal unpredicted coding
- write_segment_id(bc, xd, mi->segment_id);
+ write_segment_id(bc, seg, mi->segment_id);
}
}
skip_coeff = write_skip_coeff(cpi, segment_id, m, bc);
- if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME))
+ if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
vp9_write(bc, rf != INTRA_FRAME,
vp9_get_pred_prob_intra_inter(pc, xd));
if (mi->sb_type >= BLOCK_SIZE_SB8X8 && pc->txfm_mode == TX_MODE_SELECT &&
!(rf != INTRA_FRAME &&
- (skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
+ (skip_coeff || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) {
write_selected_txfm_size(cpi, mi->txfm_size, mi->sb_type, bc);
}
@@ -484,7 +479,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
#endif
// If segment skip is not enabled code the mode.
- if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
+ if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
if (mi->sb_type >= BLOCK_SIZE_SB8X8) {
write_sb_mv_ref(bc, mode, mv_ref_p);
vp9_accum_mv_refs(&cpi->common, mode, mi->mb_mode_context[rf]);
@@ -554,8 +549,8 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
const int mis = c->mode_info_stride;
const int segment_id = m->mbmi.segment_id;
- if (xd->update_mb_segmentation_map)
- write_segment_id(bc, xd, m->mbmi.segment_id);
+ if (xd->seg.update_map)
+ write_segment_id(bc, &xd->seg, m->mbmi.segment_id);
write_skip_coeff(cpi, segment_id, m, bc);
@@ -1002,23 +997,23 @@ static void encode_quantization(VP9_COMMON *cm,
static void encode_segmentation(VP9_COMP *cpi,
- struct vp9_write_bit_buffer *wb) {
+ struct vp9_write_bit_buffer *wb) {
int i, j;
- VP9_COMMON *const cm = &cpi->common;
- MACROBLOCKD *const xd = &cpi->mb.e_mbd;
- vp9_wb_write_bit(wb, xd->segmentation_enabled);
- if (!xd->segmentation_enabled)
+ struct segmentation *seg = &cpi->mb.e_mbd.seg;
+
+ vp9_wb_write_bit(wb, seg->enabled);
+ if (!seg->enabled)
return;
// Segmentation map
- vp9_wb_write_bit(wb, xd->update_mb_segmentation_map);
- if (xd->update_mb_segmentation_map) {
+ vp9_wb_write_bit(wb, seg->update_map);
+ if (seg->update_map) {
// Select the coding strategy (temporal or spatial)
vp9_choose_segmap_coding_method(cpi);
// Write out probabilities used to decode unpredicted macro-block segments
for (i = 0; i < MB_SEG_TREE_PROBS; i++) {
- const int prob = xd->mb_segment_tree_probs[i];
+ const int prob = seg->tree_probs[i];
const int update = prob != MAX_PROB;
vp9_wb_write_bit(wb, update);
if (update)
@@ -1026,10 +1021,10 @@ static void encode_segmentation(VP9_COMP *cpi,
}
// Write out the chosen coding method.
- vp9_wb_write_bit(wb, cm->temporal_update);
- if (cm->temporal_update) {
+ vp9_wb_write_bit(wb, seg->temporal_update);
+ if (seg->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++) {
- const int prob = cm->segment_pred_probs[i];
+ const int prob = seg->pred_probs[i];
const int update = prob != MAX_PROB;
vp9_wb_write_bit(wb, update);
if (update)
@@ -1039,16 +1034,16 @@ static void encode_segmentation(VP9_COMP *cpi,
}
// Segmentation data
- vp9_wb_write_bit(wb, xd->update_mb_segmentation_data);
- if (xd->update_mb_segmentation_data) {
- vp9_wb_write_bit(wb, xd->mb_segment_abs_delta);
+ vp9_wb_write_bit(wb, seg->update_data);
+ if (seg->update_data) {
+ vp9_wb_write_bit(wb, seg->abs_delta);
for (i = 0; i < MAX_MB_SEGMENTS; i++) {
for (j = 0; j < SEG_LVL_MAX; j++) {
- const int active = vp9_segfeature_active(xd, i, j);
+ const int active = vp9_segfeature_active(seg, i, j);
vp9_wb_write_bit(wb, active);
if (active) {
- const int data = vp9_get_segdata(xd, i, j);
+ const int data = vp9_get_segdata(seg, i, j);
const int data_max = vp9_seg_feature_data_max(j);
if (vp9_is_segfeature_signed(j)) {
@@ -1385,57 +1380,18 @@ static void write_uncompressed_header(VP9_COMP *cpi,
write_tile_info(cm, wb);
}
-void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
- int i, bytes_packed;
- VP9_COMMON *const pc = &cpi->common;
- vp9_writer header_bc;
+static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
+ VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+ FRAME_CONTEXT *const fc = &cm->fc;
+ vp9_writer header_bc;
- uint8_t *cx_data = dest;
- struct vp9_write_bit_buffer wb = {dest, 0};
- struct vp9_write_bit_buffer first_partition_size_wb;
-
- write_uncompressed_header(cpi, &wb);
- first_partition_size_wb = wb;
- vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size
-
- bytes_packed = vp9_rb_bytes_written(&wb);
- cx_data += bytes_packed;
-
- vp9_compute_update_table();
-
- vp9_start_encode(&header_bc, cx_data);
+ vp9_start_encode(&header_bc, data);
-#ifdef ENTROPY_STATS
- if (pc->frame_type == INTER_FRAME)
- active_section = 0;
+ if (xd->lossless)
+ cm->txfm_mode = ONLY_4X4;
else
- active_section = 7;
-#endif
-
- vp9_clear_system_state(); // __asm emms;
-
- vp9_copy(pc->fc.pre_coef_probs, pc->fc.coef_probs);
- vp9_copy(pc->fc.pre_y_mode_prob, pc->fc.y_mode_prob);
- vp9_copy(pc->fc.pre_uv_mode_prob, pc->fc.uv_mode_prob);
- vp9_copy(pc->fc.pre_partition_prob, pc->fc.partition_prob[INTER_FRAME]);
- pc->fc.pre_nmvc = pc->fc.nmvc;
- vp9_copy(pc->fc.pre_switchable_interp_prob, pc->fc.switchable_interp_prob);
- vp9_copy(pc->fc.pre_inter_mode_probs, pc->fc.inter_mode_probs);
- vp9_copy(pc->fc.pre_intra_inter_prob, pc->fc.intra_inter_prob);
- vp9_copy(pc->fc.pre_comp_inter_prob, pc->fc.comp_inter_prob);
- vp9_copy(pc->fc.pre_comp_ref_prob, pc->fc.comp_ref_prob);
- vp9_copy(pc->fc.pre_single_ref_prob, pc->fc.single_ref_prob);
- vp9_copy(pc->fc.pre_tx_probs_8x8p, pc->fc.tx_probs_8x8p);
- vp9_copy(pc->fc.pre_tx_probs_16x16p, pc->fc.tx_probs_16x16p);
- vp9_copy(pc->fc.pre_tx_probs_32x32p, pc->fc.tx_probs_32x32p);
- vp9_copy(pc->fc.pre_mbskip_probs, pc->fc.mbskip_probs);
-
- if (xd->lossless) {
- pc->txfm_mode = ONLY_4X4;
- } else {
encode_txfm_probs(cpi, &header_bc);
- }
update_coef_probs(cpi, &header_bc);
@@ -1445,80 +1401,123 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
vp9_update_skip_probs(cpi, &header_bc);
- if (pc->frame_type != KEY_FRAME) {
+ if (cm->frame_type != KEY_FRAME) {
+ int i;
#ifdef ENTROPY_STATS
active_section = 1;
#endif
- update_inter_mode_probs(pc, &header_bc);
- vp9_zero(cpi->common.fc.inter_mode_counts);
+ update_inter_mode_probs(cm, &header_bc);
+ vp9_zero(fc->inter_mode_counts);
- if (pc->mcomp_filter_type == SWITCHABLE)
+ if (cm->mcomp_filter_type == SWITCHABLE)
update_switchable_interp_probs(cpi, &header_bc);
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
- vp9_cond_prob_diff_update(&header_bc, &pc->fc.intra_inter_prob[i],
+ vp9_cond_prob_diff_update(&header_bc, &fc->intra_inter_prob[i],
VP9_MODE_UPDATE_PROB,
cpi->intra_inter_count[i]);
- if (pc->allow_comp_inter_inter) {
+ if (cm->allow_comp_inter_inter) {
const int comp_pred_mode = cpi->common.comp_pred_mode;
- const int use_compound_pred = (comp_pred_mode != SINGLE_PREDICTION_ONLY);
- const int use_hybrid_pred = (comp_pred_mode == HYBRID_PREDICTION);
+ const int use_compound_pred = comp_pred_mode != SINGLE_PREDICTION_ONLY;
+ const int use_hybrid_pred = comp_pred_mode == HYBRID_PREDICTION;
vp9_write_bit(&header_bc, use_compound_pred);
if (use_compound_pred) {
vp9_write_bit(&header_bc, use_hybrid_pred);
- if (use_hybrid_pred) {
+ if (use_hybrid_pred)
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
- vp9_cond_prob_diff_update(&header_bc, &pc->fc.comp_inter_prob[i],
+ vp9_cond_prob_diff_update(&header_bc, &fc->comp_inter_prob[i],
VP9_MODE_UPDATE_PROB,
cpi->comp_inter_count[i]);
- }
}
}
- if (pc->comp_pred_mode != COMP_PREDICTION_ONLY) {
+ if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) {
for (i = 0; i < REF_CONTEXTS; i++) {
- vp9_cond_prob_diff_update(&header_bc, &pc->fc.single_ref_prob[i][0],
+ vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
VP9_MODE_UPDATE_PROB,
cpi->single_ref_count[i][0]);
- vp9_cond_prob_diff_update(&header_bc, &pc->fc.single_ref_prob[i][1],
+ vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
VP9_MODE_UPDATE_PROB,
cpi->single_ref_count[i][1]);
}
}
- if (pc->comp_pred_mode != SINGLE_PREDICTION_ONLY) {
+ if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
for (i = 0; i < REF_CONTEXTS; i++)
- vp9_cond_prob_diff_update(&header_bc, &pc->fc.comp_ref_prob[i],
+ vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
VP9_MODE_UPDATE_PROB,
cpi->comp_ref_count[i]);
- }
update_mbintra_mode_probs(cpi, &header_bc);
for (i = 0; i < NUM_PARTITION_CONTEXTS; ++i) {
- vp9_prob Pnew[PARTITION_TYPES - 1];
+ vp9_prob pnew[PARTITION_TYPES - 1];
unsigned int bct[PARTITION_TYPES - 1][2];
update_mode(&header_bc, PARTITION_TYPES, vp9_partition_encodings,
- vp9_partition_tree, Pnew,
- pc->fc.partition_prob[pc->frame_type][i], bct,
+ vp9_partition_tree, pnew,
+ fc->partition_prob[cm->frame_type][i], bct,
(unsigned int *)cpi->partition_count[i]);
}
vp9_write_nmv_probs(cpi, xd->allow_high_precision_mv, &header_bc);
}
-
vp9_stop_encode(&header_bc);
+ assert(header_bc.pos <= 0xffff);
+ return header_bc.pos;
+}
- // first partition size
- assert(header_bc.pos <= 0xffff);
- vp9_wb_write_literal(&first_partition_size_wb, header_bc.pos, 16);
- *size = bytes_packed + header_bc.pos;
- *size += encode_tiles(cpi, cx_data + header_bc.pos);
+void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
+ FRAME_CONTEXT *const fc = &cpi->common.fc;
+ uint8_t *data = dest;
+ size_t first_part_size;
+ struct vp9_write_bit_buffer wb = {data, 0};
+ struct vp9_write_bit_buffer saved_wb;
+
+ write_uncompressed_header(cpi, &wb);
+ saved_wb = wb;
+ vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size
+
+ data += vp9_rb_bytes_written(&wb);
+
+ vp9_compute_update_table();
+
+#ifdef ENTROPY_STATS
+ if (pc->frame_type == INTER_FRAME)
+ active_section = 0;
+ else
+ active_section = 7;
+#endif
+
+ vp9_clear_system_state(); // __asm emms;
+
+ vp9_copy(fc->pre_coef_probs, fc->coef_probs);
+ vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob);
+ vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob);
+ vp9_copy(fc->pre_partition_prob, fc->partition_prob[INTER_FRAME]);
+ fc->pre_nmvc = fc->nmvc;
+ vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob);
+ vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs);
+ vp9_copy(fc->pre_intra_inter_prob, fc->intra_inter_prob);
+ vp9_copy(fc->pre_comp_inter_prob, fc->comp_inter_prob);
+ vp9_copy(fc->pre_comp_ref_prob, fc->comp_ref_prob);
+ vp9_copy(fc->pre_single_ref_prob, fc->single_ref_prob);
+ vp9_copy(fc->pre_tx_probs_8x8p, fc->tx_probs_8x8p);
+ vp9_copy(fc->pre_tx_probs_16x16p, fc->tx_probs_16x16p);
+ vp9_copy(fc->pre_tx_probs_32x32p, fc->tx_probs_32x32p);
+ vp9_copy(fc->pre_mbskip_probs, fc->mbskip_probs);
+
+ first_part_size = write_compressed_header(cpi, data);
+ data += first_part_size;
+ vp9_wb_write_literal(&saved_wb, first_part_size, 16);
+
+ data += encode_tiles(cpi, data);
+
+ *size = data - dest;
}
#ifdef ENTROPY_STATS
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index adaf667c6..a3e116bbf 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -360,7 +360,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
if (!output_enabled)
return;
- if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) {
+ if (!vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
for (i = 0; i < NB_TXFM_MODES; i++) {
cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i];
}
@@ -512,16 +512,16 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col,
x->rdmult = cpi->RDMULT;
/* segment ID */
- if (xd->segmentation_enabled) {
- uint8_t *map = xd->update_mb_segmentation_map ? cpi->segmentation_map
- : cm->last_frame_seg_map;
+ if (xd->seg.enabled) {
+ uint8_t *map = xd->seg.update_map ? cpi->segmentation_map
+ : cm->last_frame_seg_map;
mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
vp9_mb_init_quantizer(cpi, x);
- if (xd->segmentation_enabled && cpi->seg0_cnt > 0
- && !vp9_segfeature_active(xd, 0, SEG_LVL_REF_FRAME)
- && vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) {
+ if (xd->seg.enabled && cpi->seg0_cnt > 0
+ && !vp9_segfeature_active(&xd->seg, 0, SEG_LVL_REF_FRAME)
+ && vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) {
cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
} else {
const int y = mb_row & ~3;
@@ -541,11 +541,11 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col,
}
static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
- TOKENEXTRA **tp, int *totalrate, int64_t *totaldist,
+ int *totalrate, int64_t *totaldist,
BLOCK_SIZE_TYPE bsize, PICK_MODE_CONTEXT *ctx) {
- VP9_COMMON * const cm = &cpi->common;
- MACROBLOCK * const x = &cpi->mb;
- MACROBLOCKD * const xd = &x->e_mbd;
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
x->rd_search = 1;
@@ -558,14 +558,13 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
vp9_activity_masking(cpi, x);
- /* Find best coding mode & reconstruct the MB so it is available
- * as a predictor for MBs that follow in the SB */
- if (cm->frame_type == KEY_FRAME) {
+ // Find best coding mode & reconstruct the MB so it is available
+ // as a predictor for MBs that follow in the SB
+ if (cm->frame_type == KEY_FRAME)
vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx);
- } else {
+ else
vp9_rd_pick_inter_mode_sb(cpi, x, mi_row, mi_col, totalrate, totaldist,
bsize, ctx);
- }
}
static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
@@ -576,10 +575,8 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
MB_MODE_INFO * const mbmi = &mi->mbmi;
if (cm->frame_type != KEY_FRAME) {
- int segment_id, seg_ref_active;
-
- segment_id = mbmi->segment_id;
- seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);
+ const int seg_ref_active = vp9_segfeature_active(&xd->seg, mbmi->segment_id,
+ SEG_LVL_REF_FRAME);
if (!seg_ref_active)
cpi->intra_inter_count[vp9_get_pred_context_intra_inter(cm, xd)][mbmi
@@ -1232,7 +1229,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
mi_row + (ms >> 1) < cm->mi_rows &&
mi_col + (ms >> 1) < cm->mi_cols) {
*(get_sb_partitioning(x, bsize)) = bsize;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &none_rate, &none_dist, bsize,
+ pick_sb_modes(cpi, mi_row, mi_col, &none_rate, &none_dist, bsize,
get_block_context(x, bsize));
set_partition_seg_context(cm, xd, mi_row, mi_col);
@@ -1247,7 +1244,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
switch (partition) {
case PARTITION_NONE:
- pick_sb_modes(cpi, mi_row, mi_col, tp, &last_part_rate, &last_part_dist,
+ pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist,
bsize, get_block_context(x, bsize));
set_partition_seg_context(cm, xd, mi_row, mi_col);
pl = partition_plane_context(xd, bsize);
@@ -1255,7 +1252,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
break;
case PARTITION_HORZ:
*(get_sb_index(xd, subsize)) = 0;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &last_part_rate, &last_part_dist,
+ pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist,
subsize, get_block_context(x, subsize));
if (bsize >= BLOCK_SIZE_SB8X8 && mi_row + (mh >> 1) < cm->mi_rows) {
int rt = 0;
@@ -1263,7 +1260,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*(get_sb_index(xd, subsize)) = 1;
- pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, tp, &rt, &dt, subsize,
+ pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &rt, &dt, subsize,
get_block_context(x, subsize));
last_part_rate += rt;
last_part_dist += dt;
@@ -1274,7 +1271,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
break;
case PARTITION_VERT:
*(get_sb_index(xd, subsize)) = 0;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &last_part_rate, &last_part_dist,
+ pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist,
subsize, get_block_context(x, subsize));
if (bsize >= BLOCK_SIZE_SB8X8 && mi_col + (ms >> 1) < cm->mi_cols) {
int rt = 0;
@@ -1282,7 +1279,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*(get_sb_index(xd, subsize)) = 1;
- pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), tp, &rt, &dt, subsize,
+ pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &rt, &dt, subsize,
get_block_context(x, subsize));
last_part_rate += rt;
last_part_dist += dt;
@@ -1347,7 +1344,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
- pick_sb_modes(cpi, mi_row + y_idx, mi_col + x_idx, tp, &rt, &dt,
+ pick_sb_modes(cpi, mi_row + y_idx, mi_col + x_idx, &rt, &dt,
split_subsize, get_block_context(x, split_subsize));
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
@@ -1478,7 +1475,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
(mi_col + (ms >> 1) < cm->mi_cols)) {
int r;
int64_t d;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d, bsize,
+ pick_sb_modes(cpi, mi_row, mi_col, &r, &d, bsize,
get_block_context(x, bsize));
if (bsize >= BLOCK_SIZE_SB8X8) {
set_partition_seg_context(cm, xd, mi_row, mi_col);
@@ -1503,7 +1500,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
int64_t d2, d = 0;
subsize = get_subsize(bsize, PARTITION_HORZ);
*(get_sb_index(xd, subsize)) = 0;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
+ pick_sb_modes(cpi, mi_row, mi_col, &r2, &d2, subsize,
get_block_context(x, subsize));
if (mi_row + (ms >> 1) < cm->mi_rows) {
@@ -1511,7 +1508,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*(get_sb_index(xd, subsize)) = 1;
- pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, tp, &r, &d, subsize,
+ pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &r, &d, subsize,
get_block_context(x, subsize));
r2 += r;
d2 += d;
@@ -1535,7 +1532,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
int64_t d2;
subsize = get_subsize(bsize, PARTITION_VERT);
*(get_sb_index(xd, subsize)) = 0;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r2, &d2, subsize,
+ pick_sb_modes(cpi, mi_row, mi_col, &r2, &d2, subsize,
get_block_context(x, subsize));
if (mi_col + (ms >> 1) < cm->mi_cols) {
int r = 0;
@@ -1544,7 +1541,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*(get_sb_index(xd, subsize)) = 1;
- pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), tp, &r, &d, subsize,
+ pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &r, &d, subsize,
get_block_context(x, subsize));
r2 += r;
d2 += d;
@@ -1603,7 +1600,7 @@ static void rd_pick_reference_frame(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
if ((mi_row + (ms >> 1) < cm->mi_rows) &&
(mi_col + (ms >> 1) < cm->mi_cols)) {
cpi->set_ref_frame_mask = 1;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d, BLOCK_SIZE_SB64X64,
+ pick_sb_modes(cpi, mi_row, mi_col, &r, &d, BLOCK_SIZE_SB64X64,
get_block_context(x, BLOCK_SIZE_SB64X64));
set_partition_seg_context(cm, xd, mi_row, mi_col);
pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64);
@@ -1886,7 +1883,7 @@ static int check_dual_ref_flags(VP9_COMP *cpi) {
MACROBLOCKD *xd = &cpi->mb.e_mbd;
int ref_flags = cpi->ref_frame_flags;
- if (vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) {
+ if (vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) {
return 0;
} else {
return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG)
@@ -1933,9 +1930,8 @@ static void reset_skip_txfm_size_b(VP9_COMP *cpi, MODE_INFO *mi, int mis,
const int xmbs = MIN(bw, cm->mi_cols - mi_col);
xd->mode_info_context = mi;
- assert(
- vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP) ||
- get_skip_flag(mi, mis, ymbs, xmbs));
+ assert(vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP) ||
+ get_skip_flag(mi, mis, ymbs, xmbs));
set_txfm_flag(mi, mis, ymbs, xmbs, txfm_max);
}
}
@@ -2371,10 +2367,11 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
vp9_set_pred_flag_mbskip(xd, bsize, mi->mbmi.mb_skip_coeff);
if (output_enabled) {
- if (cm->txfm_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_SIZE_SB8X8
- && !(mbmi->ref_frame[0] != INTRA_FRAME
- && (mbmi->mb_skip_coeff
- || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
+ if (cm->txfm_mode == TX_MODE_SELECT &&
+ mbmi->sb_type >= BLOCK_SIZE_SB8X8 &&
+ !(mbmi->ref_frame[0] != INTRA_FRAME &&
+ (mbmi->mb_skip_coeff ||
+ vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)))) {
const int context = vp9_get_pred_context_tx_size(cm, xd);
if (bsize >= BLOCK_SIZE_SB32X32) {
cm->fc.tx_count_32x32p[context][mbmi->txfm_size]++;
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 67d0c4c76..486686ad7 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -219,13 +219,13 @@ static void setup_features(VP9_COMP *cpi) {
MACROBLOCKD *xd = &cpi->mb.e_mbd;
// Set up default state for MB feature flags
- xd->segmentation_enabled = 0;
+ xd->seg.enabled = 0;
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
- vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 0;
+ vpx_memset(xd->seg.tree_probs, 255, sizeof(xd->seg.tree_probs));
- vp9_clearall_segfeatures(xd);
+ vp9_clearall_segfeatures(&xd->seg);
xd->mode_ref_lf_delta_enabled = 0;
xd->mode_ref_lf_delta_update = 0;
@@ -305,26 +305,26 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
if (cm->frame_type == KEY_FRAME) {
// Clear down the global segmentation map
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 0;
cpi->static_mb_pct = 0;
// Disable segmentation
vp9_disable_segmentation((VP9_PTR)cpi);
// Clear down the segment features.
- vp9_clearall_segfeatures(xd);
+ vp9_clearall_segfeatures(&xd->seg);
} else if (cpi->refresh_alt_ref_frame) {
// If this is an alt ref frame
// Clear down the global segmentation map
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 0;
cpi->static_mb_pct = 0;
// Disable segmentation and individual segment features by default
vp9_disable_segmentation((VP9_PTR)cpi);
- vp9_clearall_segfeatures(xd);
+ vp9_clearall_segfeatures(&xd->seg);
// Scan frames from current to arf frame.
// This function re-enables segmentation if appropriate.
@@ -332,45 +332,45 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
// If segmentation was enabled set those features needed for the
// arf itself.
- if (xd->segmentation_enabled) {
- xd->update_mb_segmentation_map = 1;
- xd->update_mb_segmentation_data = 1;
+ if (xd->seg.enabled) {
+ xd->seg.update_map = 1;
+ xd->seg.update_data = 1;
qi_delta = compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 0.875));
- vp9_set_segdata(xd, 1, SEG_LVL_ALT_Q, (qi_delta - 2));
- vp9_set_segdata(xd, 1, SEG_LVL_ALT_LF, -2);
+ vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2));
+ vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_LF, -2);
- vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_Q);
- vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_LF);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_Q);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_LF);
// Where relevant assume segment data is delta data
- xd->mb_segment_abs_delta = SEGMENT_DELTADATA;
+ xd->seg.abs_delta = SEGMENT_DELTADATA;
}
- } else if (xd->segmentation_enabled) {
+ } else if (xd->seg.enabled) {
// All other frames if segmentation has been enabled
// First normal frame in a valid gf or alt ref group
if (cpi->common.frames_since_golden == 0) {
// Set up segment features for normal frames in an arf group
if (cpi->source_alt_ref_active) {
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 1;
- xd->mb_segment_abs_delta = SEGMENT_DELTADATA;
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 1;
+ xd->seg.abs_delta = SEGMENT_DELTADATA;
qi_delta = compute_qdelta(cpi, cpi->avg_q,
(cpi->avg_q * 1.125));
- vp9_set_segdata(xd, 1, SEG_LVL_ALT_Q, (qi_delta + 2));
- vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_Q);
+ vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2));
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_Q);
- vp9_set_segdata(xd, 1, SEG_LVL_ALT_LF, -2);
- vp9_enable_segfeature(xd, 1, SEG_LVL_ALT_LF);
+ vp9_set_segdata(&xd->seg, 1, SEG_LVL_ALT_LF, -2);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_ALT_LF);
// Segment coding disabled for compred testing
if (high_q || (cpi->static_mb_pct == 100)) {
- vp9_set_segdata(xd, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
- vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
- vp9_enable_segfeature(xd, 1, SEG_LVL_SKIP);
+ vp9_set_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_REF_FRAME);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_SKIP);
}
} else {
// Disable segmentation and clear down features if alt ref
@@ -380,10 +380,10 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 0;
- vp9_clearall_segfeatures(xd);
+ vp9_clearall_segfeatures(&xd->seg);
}
} else if (cpi->is_src_frame_alt_ref) {
// Special case where we are coding over the top of a previous
@@ -391,28 +391,28 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
// Segment coding disabled for compred testing
// Enable ref frame features for segment 0 as well
- vp9_enable_segfeature(xd, 0, SEG_LVL_REF_FRAME);
- vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
+ vp9_enable_segfeature(&xd->seg, 0, SEG_LVL_REF_FRAME);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_REF_FRAME);
// All mbs should use ALTREF_FRAME
- vp9_clear_segdata(xd, 0, SEG_LVL_REF_FRAME);
- vp9_set_segdata(xd, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
- vp9_clear_segdata(xd, 1, SEG_LVL_REF_FRAME);
- vp9_set_segdata(xd, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
+ vp9_clear_segdata(&xd->seg, 0, SEG_LVL_REF_FRAME);
+ vp9_set_segdata(&xd->seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
+ vp9_clear_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME);
+ vp9_set_segdata(&xd->seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
// Skip all MBs if high Q (0,0 mv and skip coeffs)
if (high_q) {
- vp9_enable_segfeature(xd, 0, SEG_LVL_SKIP);
- vp9_enable_segfeature(xd, 1, SEG_LVL_SKIP);
+ vp9_enable_segfeature(&xd->seg, 0, SEG_LVL_SKIP);
+ vp9_enable_segfeature(&xd->seg, 1, SEG_LVL_SKIP);
}
// Enable data udpate
- xd->update_mb_segmentation_data = 1;
+ xd->seg.update_data = 1;
} else {
// All other frames.
// No updates.. leave things as they are.
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 0;
}
}
}
@@ -2567,9 +2567,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
setup_features(cpi);
// If segmentation is enabled force a map update for key frames
- if (xd->segmentation_enabled) {
- xd->update_mb_segmentation_map = 1;
- xd->update_mb_segmentation_data = 1;
+ if (xd->seg.enabled) {
+ xd->seg.update_map = 1;
+ xd->seg.update_data = 1;
}
// The alternate reference frame cannot be active for a key frame
@@ -3100,9 +3100,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cpi->dummy_packing = 0;
vp9_pack_bitstream(cpi, dest, size);
- if (xd->update_mb_segmentation_map) {
+ if (xd->seg.update_map)
update_reference_segmentation_map(cpi);
- }
release_scaled_references(cpi);
update_reference_frames(cpi);
@@ -3408,8 +3407,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
// Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
- xd->update_mb_segmentation_map = 0;
- xd->update_mb_segmentation_data = 0;
+ xd->seg.update_map = 0;
+ xd->seg.update_data = 0;
xd->mode_ref_lf_delta_update = 0;
// keep track of the last coded dimensions
@@ -3521,8 +3520,8 @@ static int frame_is_reference(const VP9_COMP *cpi) {
cpi->refresh_alt_ref_frame ||
cm->refresh_frame_context ||
mb->mode_ref_lf_delta_update ||
- mb->update_mb_segmentation_map ||
- mb->update_mb_segmentation_data;
+ mb->seg.update_map ||
+ mb->seg.update_data;
}
#if CONFIG_MULTIPLE_ARF
@@ -3978,14 +3977,14 @@ int vp9_set_roimap(VP9_PTR comp, unsigned char *map, unsigned int rows,
// Enable the loop and quant changes in the feature mask
for (i = 0; i < MAX_MB_SEGMENTS; i++) {
if (delta_q[i])
- vp9_enable_segfeature(xd, i, SEG_LVL_ALT_Q);
+ vp9_enable_segfeature(&xd->seg, i, SEG_LVL_ALT_Q);
else
- vp9_disable_segfeature(xd, i, SEG_LVL_ALT_Q);
+ vp9_disable_segfeature(&xd->seg, i, SEG_LVL_ALT_Q);
if (delta_lf[i])
- vp9_enable_segfeature(xd, i, SEG_LVL_ALT_LF);
+ vp9_enable_segfeature(&xd->seg, i, SEG_LVL_ALT_LF);
else
- vp9_disable_segfeature(xd, i, SEG_LVL_ALT_LF);
+ vp9_disable_segfeature(&xd->seg, i, SEG_LVL_ALT_LF);
}
// Initialise the feature data structure
diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c
index 862923fd4..2d3d6bf9d 100644
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -365,7 +365,7 @@ void vp9_mb_init_quantizer(VP9_COMP *cpi, MACROBLOCK *x) {
x->e_mbd.plane[3].dequant = cpi->common.a_dequant[qindex];
#endif
- x->skip_block = vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
+ x->skip_block = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP);
/* save this macroblock QIndex for vp9_update_zbin_extra() */
x->e_mbd.q_index = qindex;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 93f8bb56d..733932821 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -127,7 +127,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
vp9_copy(cc->uv_mode_prob, cm->fc.uv_mode_prob);
vp9_copy(cc->partition_prob, cm->fc.partition_prob);
- vp9_copy(cc->segment_pred_probs, cm->segment_pred_probs);
+ vp9_copy(cc->segment_pred_probs, xd->seg.pred_probs);
vp9_copy(cc->intra_inter_prob, cm->fc.intra_inter_prob);
vp9_copy(cc->comp_inter_prob, cm->fc.comp_inter_prob);
@@ -167,7 +167,7 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob);
vp9_copy(cm->fc.partition_prob, cc->partition_prob);
- vp9_copy(cm->segment_pred_probs, cc->segment_pred_probs);
+ vp9_copy(xd->seg.pred_probs, cc->segment_pred_probs);
vp9_copy(cm->fc.intra_inter_prob, cc->intra_inter_prob);
vp9_copy(cm->fc.comp_inter_prob, cc->comp_inter_prob);
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index f42467969..03b35eb0f 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -644,7 +644,7 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
pt = combine_entropy_contexts(above_ec, left_ec);
nb = vp9_get_coef_neighbors_handle(scan);
- if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP))
seg_eob = 0;
/* sanity check to ensure that we do not have spurious non-zero q values */
@@ -769,20 +769,6 @@ static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x,
return cost;
}
-static int block_error(int16_t *coeff, int16_t *dqcoeff,
- int block_size, int shift) {
- int i;
- int64_t error = 0;
-
- for (i = 0; i < block_size; i++) {
- int this_diff = coeff[i] - dqcoeff[i];
- error += (unsigned)this_diff * this_diff;
- }
- error >>= shift;
-
- return error > INT_MAX ? INT_MAX : (int)error;
-}
-
static int block_error_sby(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
int shift, int64_t *sse) {
struct macroblockd_plane *p = &x->e_mbd.plane[0];
@@ -1556,19 +1542,19 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
return best_rd;
}
-static int cost_mv_ref(VP9_COMP *cpi,
- MB_PREDICTION_MODE m,
- const int mode_context) {
+static int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode,
+ int mode_context) {
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
- int segment_id = xd->mode_info_context->mbmi.segment_id;
+ const int segment_id = xd->mode_info_context->mbmi.segment_id;
- // Dont account for mode here if segment skip is enabled.
- if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
- assert(NEARESTMV <= m && m <= NEWMV);
- return x->inter_mode_cost[mode_context][m - NEARESTMV];
- } else
+ // Don't account for mode here if segment skip is enabled.
+ if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)) {
+ assert(is_inter_mode(mode));
+ return x->inter_mode_cost[mode_context][mode - NEARESTMV];
+ } else {
return 0;
+ }
}
void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) {
@@ -2172,7 +2158,7 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
vp9_prob *comp_mode_p) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
- int seg_ref_active = vp9_segfeature_active(xd, segment_id,
+ int seg_ref_active = vp9_segfeature_active(&xd->seg, segment_id,
SEG_LVL_REF_FRAME);
if (seg_ref_active) {
vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
@@ -3189,7 +3175,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// Do not allow compound prediction if the segment level reference
// frame feature is in use as in this case there can only be one reference.
if ((vp9_mode_order[mode_index].second_ref_frame > INTRA_FRAME) &&
- vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME))
+ vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME))
continue;
x->skip = 0;
@@ -3271,9 +3257,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1],
scale_factor);
- mode_excluded =
- mode_excluded ?
- mode_excluded : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
+ mode_excluded = mode_excluded
+ ? mode_excluded
+ : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
} else {
// mbmi->ref_frame[1] = vp9_mode_order[mode_index].ref_frame[1];
if (ref_frame != INTRA_FRAME) {
@@ -3293,18 +3279,20 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// If the segment reference frame feature is enabled....
// then do nothing if the current ref frame is not allowed..
- if (vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) &&
- vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME) &&
+ vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME) !=
+ (int)ref_frame) {
continue;
// If the segment skip feature is enabled....
// then do nothing if the current mode is not allowed..
- } else if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) &&
+ } else if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP) &&
(this_mode != ZEROMV && ref_frame != INTRA_FRAME)) {
continue;
// Disable this drop out case if the ref frame
// segment level feature is enabled for this segment. This is to
// prevent the possibility that we end up unable to pick any mode.
- } else if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME)) {
+ } else if (!vp9_segfeature_active(&xd->seg, segment_id,
+ SEG_LVL_REF_FRAME)) {
// Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
// unless ARNR filtering is enabled in which case we want
// an unfiltered alternative
@@ -3579,10 +3567,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// because there are no non zero coefficients and make any
// necessary adjustment for rate. Ignore if skip is coded at
// segment level as the cost wont have been added in.
- int mb_skip_allowed;
-
// Is Mb level skip allowed (i.e. not coded at segment level).
- mb_skip_allowed = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
+ const int mb_skip_allowed = !vp9_segfeature_active(&xd->seg, segment_id,
+ SEG_LVL_SKIP);
if (skippable && bsize >= BLOCK_SIZE_SB8X8) {
// Back out the coefficient coding costs
@@ -3881,7 +3868,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// This code forces Altref,0,0 and skip for the frame that overlays a
// an alrtef unless Altref is filtered. However, this is unsafe if
// segment level coding of ref frame is enabled for this segment.
- if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) &&
+ if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME) &&
cpi->is_src_frame_alt_ref &&
(cpi->oxcf.arnr_max_frames == 0) &&
(best_mbmode.mode != ZEROMV || best_mbmode.ref_frame[0] != ALTREF_FRAME)
diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c
index fb2b23dbe..6a22df86c 100644
--- a/vp9/encoder/vp9_segmentation.c
+++ b/vp9/encoder/vp9_segmentation.c
@@ -18,14 +18,14 @@
void vp9_enable_segmentation(VP9_PTR ptr) {
VP9_COMP *cpi = (VP9_COMP *)ptr;
- cpi->mb.e_mbd.segmentation_enabled = 1;
- cpi->mb.e_mbd.update_mb_segmentation_map = 1;
- cpi->mb.e_mbd.update_mb_segmentation_data = 1;
+ cpi->mb.e_mbd.seg.enabled = 1;
+ cpi->mb.e_mbd.seg.update_map = 1;
+ cpi->mb.e_mbd.seg.update_data = 1;
}
void vp9_disable_segmentation(VP9_PTR ptr) {
VP9_COMP *cpi = (VP9_COMP *)ptr;
- cpi->mb.e_mbd.segmentation_enabled = 0;
+ cpi->mb.e_mbd.seg.enabled = 0;
}
void vp9_set_segmentation_map(VP9_PTR ptr,
@@ -37,8 +37,8 @@ void vp9_set_segmentation_map(VP9_PTR ptr,
(cpi->common.mi_rows * cpi->common.mi_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;
+ cpi->mb.e_mbd.seg.update_map = 1;
+ cpi->mb.e_mbd.seg.update_data = 1;
}
void vp9_set_segment_data(VP9_PTR ptr,
@@ -46,10 +46,10 @@ void vp9_set_segment_data(VP9_PTR ptr,
unsigned char abs_delta) {
VP9_COMP *cpi = (VP9_COMP *)(ptr);
- cpi->mb.e_mbd.mb_segment_abs_delta = abs_delta;
+ cpi->mb.e_mbd.seg.abs_delta = abs_delta;
- vpx_memcpy(cpi->mb.e_mbd.segment_feature_data, feature_data,
- sizeof(cpi->mb.e_mbd.segment_feature_data));
+ vpx_memcpy(cpi->mb.e_mbd.seg.feature_data, feature_data,
+ sizeof(cpi->mb.e_mbd.seg.feature_data));
// TBD ?? Set the feature mask
// vpx_memcpy(cpi->mb.e_mbd.segment_feature_mask, 0,
@@ -232,8 +232,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// Set default state for the segment tree probabilities and the
// temporal coding probabilities
- vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
- vpx_memset(cm->segment_pred_probs, 255, sizeof(cm->segment_pred_probs));
+ vpx_memset(xd->seg.tree_probs, 255, sizeof(xd->seg.tree_probs));
+ vpx_memset(xd->seg.pred_probs, 255, sizeof(xd->seg.pred_probs));
vpx_memset(no_pred_segcounts, 0, sizeof(no_pred_segcounts));
vpx_memset(t_unpred_seg_counts, 0, sizeof(t_unpred_seg_counts));
@@ -283,11 +283,11 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// Now choose which coding method to use.
if (t_pred_cost < no_pred_cost) {
- cm->temporal_update = 1;
- vpx_memcpy(xd->mb_segment_tree_probs, t_pred_tree, sizeof(t_pred_tree));
- vpx_memcpy(cm->segment_pred_probs, t_nopred_prob, sizeof(t_nopred_prob));
+ xd->seg.temporal_update = 1;
+ vpx_memcpy(xd->seg.tree_probs, t_pred_tree, sizeof(t_pred_tree));
+ vpx_memcpy(xd->seg.pred_probs, t_nopred_prob, sizeof(t_nopred_prob));
} else {
- cm->temporal_update = 0;
- vpx_memcpy(xd->mb_segment_tree_probs, no_pred_tree, sizeof(no_pred_tree));
+ xd->seg.temporal_update = 0;
+ vpx_memcpy(xd->seg.tree_probs, no_pred_tree, sizeof(no_pred_tree));
}
}
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index c16bdff35..d526990df 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -180,7 +180,7 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE_TYPE bsize,
pt = combine_entropy_contexts(above_ec, left_ec);
nb = vp9_get_coef_neighbors_handle(scan);
- if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
+ if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP))
seg_eob = 0;
c = 0;
@@ -274,12 +274,10 @@ void vp9_tokenize_sb(VP9_COMP *cpi,
MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi;
TOKENEXTRA *t_backup = *t;
const int mb_skip_context = vp9_get_pred_context_mbskip(cm, xd);
- const int segment_id = mbmi->segment_id;
- const int skip_inc = !vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP);
+ const int skip_inc = !vp9_segfeature_active(&xd->seg, mbmi->segment_id,
+ SEG_LVL_SKIP);
const TX_SIZE txfm_size = mbmi->txfm_size;
- struct tokenize_b_args arg = {
- cpi, xd, t, txfm_size, dry_run
- };
+ struct tokenize_b_args arg = { cpi, xd, t, txfm_size, dry_run };
mbmi->mb_skip_coeff = vp9_sb_is_skippable(xd, bsize);
diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk
index ee744d541..2518ce148 100644
--- a/vp9/vp9_common.mk
+++ b/vp9/vp9_common.mk
@@ -88,6 +88,8 @@ endif
VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_idct_intrin_sse2.c
+VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_convolve8_neon$(ASM)
VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_loopfilter_neon$(ASM)
+VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_dc_only_idct_add_neon$(ASM)
$(eval $(call rtcd_h_template,vp9_rtcd,vp9/common/vp9_rtcd_defs.sh))
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index ea6946bd9..3bfb35813 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -212,26 +212,27 @@ static vpx_codec_err_t vp8_peek_si(const uint8_t *data,
vpx_codec_stream_info_t *si) {
vpx_codec_err_t res = VPX_CODEC_OK;
- if (data + data_sz <= data)
+ if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM;
+
+ if (data + data_sz <= data) {
res = VPX_CODEC_INVALID_PARAM;
- else {
- si->is_kf = 0;
+ } else {
+ const int frame_marker = (data[0] >> 6) & 0x3;
+ const int version = (data[0] >> 4) & 0x3;
+ if (frame_marker != 0x2) return VPX_CODEC_UNSUP_BITSTREAM;
+ if (version != 0) return VPX_CODEC_UNSUP_BITSTREAM;
- if (data_sz >= 8 && (data[0] & 0xD8) == 0x80) { /* I-Frame */
+ si->is_kf = !((data[0] >> 2) & 0x1);
+ if (si->is_kf) {
const uint8_t *c = data + 1;
- si->is_kf = 1;
if (c[0] != SYNC_CODE_0 || c[1] != SYNC_CODE_1 || c[2] != SYNC_CODE_2)
- res = VPX_CODEC_UNSUP_BITSTREAM;
-
- si->w = (c[3] << 8) | c[4];
- si->h = (c[5] << 8) | c[6];
+ return VPX_CODEC_UNSUP_BITSTREAM;
- // printf("w=%d, h=%d\n", si->w, si->h);
- if (!(si->h | si->w))
- res = VPX_CODEC_UNSUP_BITSTREAM;
- } else
- res = VPX_CODEC_UNSUP_BITSTREAM;
+ c += 3;
+ si->w = (((c[0] & 0xf) << 12) | (c[1] << 4) | ((c[2] >> 4) & 0xf)) + 1;
+ si->h = (((c[2] & 0xf) << 12) | (c[3] << 4) | ((c[4] >> 4) & 0xf)) + 1;
+ }
}
return res;
diff --git a/vpx/internal/vpx_codec_internal.h b/vpx/internal/vpx_codec_internal.h
index d7bcd4620..0b057de4c 100644
--- a/vpx/internal/vpx_codec_internal.h
+++ b/vpx/internal/vpx_codec_internal.h
@@ -94,9 +94,10 @@ typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)(vpx_codec_alg_priv_t *ctx);
/*!\brief parse stream info function pointer prototype
*
- * Performs high level parsing of the bitstream. This function is called by
- * the generic vpx_codec_parse_stream() wrapper function, so plugins implementing
- * this interface may trust the input parameters to be properly initialized.
+ * Performs high level parsing of the bitstream. This function is called by the
+ * generic vpx_codec_peek_stream_info() wrapper function, so plugins
+ * implementing this interface may trust the input parameters to be properly
+ * initialized.
*
* \param[in] data Pointer to a block of data to parse
* \param[in] data_sz Size of the data buffer
@@ -301,7 +302,7 @@ struct vpx_codec_iface {
vpx_codec_set_mmap_fn_t set_mmap; /**< \copydoc ::vpx_codec_set_mmap_fn_t */
struct vpx_codec_dec_iface {
vpx_codec_peek_si_fn_t peek_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */
- vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */
+ vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_get_si_fn_t */
vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */
vpx_codec_get_frame_fn_t get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */
} dec;