Merge "Fix mingw build error" into experimental
diff --git a/configure b/configure
index 05e5384..af4e3fb 100755
--- a/configure
+++ b/configure
@@ -243,6 +243,7 @@
non420
alpha
balanced_coeftree
+ new_loopfilter
"
CONFIG_LIST="
external_build
diff --git a/test/borders_test.cc b/test/borders_test.cc
new file mode 100644
index 0000000..8cac4fd
--- /dev/null
+++ b/test/borders_test.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <climits>
+#include <vector>
+#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "test/codec_factory.h"
+#include "test/encode_test_driver.h"
+#include "test/i420_video_source.h"
+#include "test/util.h"
+
+namespace {
+
+class BordersTest : public ::libvpx_test::EncoderTest,
+ public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
+ protected:
+ BordersTest() : EncoderTest(GET_PARAM(0)) {}
+
+ virtual void SetUp() {
+ InitializeConfig();
+ SetMode(GET_PARAM(1));
+ }
+
+ virtual bool Continue() const {
+ return !HasFatalFailure() && !abort_;
+ }
+
+ virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
+ ::libvpx_test::Encoder *encoder) {
+ if ( video->frame() == 1) {
+ encoder->Control(VP8E_SET_CPUUSED, 5);
+ encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
+ encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
+ encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
+ encoder->Control(VP8E_SET_ARNR_TYPE, 3);
+ }
+ }
+
+ virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
+ if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
+ }
+ }
+};
+
+TEST_P(BordersTest, TestEncodeHighBitrate) {
+ // Validate that this non multiple of 64 wide clip encodes and decodes
+ // without a mismatch when passing in a very low max q. This pushes
+ // the encoder to producing lots of big partitions which will likely
+ // extend into the border and test the border condition.
+ cfg_.g_lag_in_frames = 25;
+ cfg_.rc_2pass_vbr_minsection_pct = 5;
+ cfg_.rc_2pass_vbr_minsection_pct = 2000;
+ cfg_.rc_target_bitrate = 2000;
+ cfg_.rc_max_quantizer = 10;
+
+ ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
+ 40);
+
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+}
+TEST_P(BordersTest, TestLowBitrate) {
+ // Validate that this clip encodes and decodes without a mismatch
+ // when passing in a very high min q. This pushes the encoder to producing
+ // lots of small partitions which might will test the other condition.
+
+ cfg_.g_lag_in_frames = 25;
+ cfg_.rc_2pass_vbr_minsection_pct = 5;
+ cfg_.rc_2pass_vbr_minsection_pct = 2000;
+ cfg_.rc_target_bitrate = 200;
+ cfg_.rc_min_quantizer = 40;
+
+ ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
+ 40);
+
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+}
+
+VP9_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
+ ::libvpx_test::kTwoPassGood));
+} // namespace
diff --git a/test/test-data.sha1 b/test/test-data.sha1
index c1b6a83..98cdda0 100644
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -1,4 +1,5 @@
d5dfb0151c9051f8c85999255645d7a23916d3c0 hantro_collage_w352h288.yuv
+b87815bf86020c592ccc7a846ba2e28ec8043902 hantro_odd.yuv
5184c46ddca8b1fadd16742e8500115bc8f749da vp80-00-comprehensive-001.ivf
65bf1bbbced81b97bd030f376d1b7f61a224793f vp80-00-comprehensive-002.ivf
906b4c1e99eb734504c504b3f1ad8052137ce672 vp80-00-comprehensive-003.ivf
@@ -120,4 +121,4 @@
41d70bb5fa45bc88da1604a0af466930b8dd77b5 vp80-05-sharpness-1438.ivf.md5
086c56378df81b6cee264d7540a7b8f2b405c7a4 vp80-05-sharpness-1439.ivf.md5
d32dc2c4165eb266ea4c23c14a45459b363def32 vp80-05-sharpness-1440.ivf.md5
-8c69dc3d8e563f56ffab5ad1e400d9e689dd23df vp80-05-sharpness-1443.ivf.md5
\ No newline at end of file
+8c69dc3d8e563f56ffab5ad1e400d9e689dd23df vp80-05-sharpness-1443.ivf.md5
diff --git a/test/test.mk b/test/test.mk
index 0d069d0..1e0b217 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -22,6 +22,7 @@
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc
+LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += resize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../md5_utils.h ../md5_utils.c
@@ -92,6 +93,7 @@
## TEST DATA
##
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv
+LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-002.ivf
diff --git a/test/vp9_boolcoder_test.cc b/test/vp9_boolcoder_test.cc
index 5d87ff6..42b2229 100644
--- a/test/vp9_boolcoder_test.cc
+++ b/test/vp9_boolcoder_test.cc
@@ -68,6 +68,9 @@
vp9_stop_encode(&bw);
+ // First bit should be zero
+ GTEST_ASSERT_EQ(bw_buffer[0] & 0x80, 0);
+
vp9_reader br;
vp9_reader_init(&br, bw_buffer, buffer_size);
bit_rnd.Reset(random_seed);
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 930d93f..aec7bff 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -5179,7 +5179,7 @@
if (cm->show_frame)
{
-
+ cpi->common.show_frame_mi = cpi->common.mi;
cpi->count ++;
if (cpi->b_calculate_psnr)
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index ef14e1a..4960963 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -10,41 +10,39 @@
#include "./vpx_config.h"
-#include "vp9/common/vp9_blockd.h"
#include "vpx_mem/vpx_mem.h"
-#include "vp9/common/vp9_onyxc_int.h"
-#include "vp9/common/vp9_findnearmv.h"
+#include "vp9/common/vp9_blockd.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_entropymv.h"
+#include "vp9/common/vp9_findnearmv.h"
+#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_systemdependent.h"
-
-void vp9_update_mode_info_border(VP9_COMMON *cpi, MODE_INFO *mi) {
- const int stride = cpi->mode_info_stride;
+void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) {
+ const int stride = cm->mode_info_stride;
int i;
// Clear down top border row
vpx_memset(mi, 0, sizeof(MODE_INFO) * stride);
// Clear left border column
- for (i = 1; i < cpi->mi_rows + 1; i++)
+ for (i = 1; i < cm->mi_rows + 1; i++)
vpx_memset(&mi[i * stride], 0, sizeof(MODE_INFO));
}
-void vp9_update_mode_info_in_image(VP9_COMMON *cpi, MODE_INFO *mi) {
+void vp9_update_mode_info_in_image(VP9_COMMON *cm, MODE_INFO *mi) {
int i, j;
- MODE_INFO *ptr;
// For each in image mode_info element set the in image flag to 1
- for (i = 0; i < cpi->mi_rows; i++) {
- ptr = mi;
- for (j = 0; j < cpi->mi_cols; j++) {
+ for (i = 0; i < cm->mi_rows; i++) {
+ MODE_INFO *ptr = mi;
+ for (j = 0; j < cm->mi_cols; j++) {
ptr->mbmi.mb_in_image = 1;
ptr++; // Next element in the row
}
// Step over border element at start of next row
- mi += cpi->mode_info_stride;
+ mi += cm->mode_info_stride;
}
}
@@ -69,23 +67,46 @@
oci->above_seg_context = 0;
}
+static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) {
+ cm->mb_cols = aligned_width >> 4;
+ cm->mb_rows = aligned_height >> 4;
+ cm->MBs = cm->mb_rows * cm->mb_cols;
+
+ cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
+ cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
+ cm->mode_info_stride = cm->mi_cols + 1;
+}
+
+static void setup_mi(VP9_COMMON *cm) {
+ cm->mi = cm->mip + cm->mode_info_stride + 1;
+ cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
+
+ vpx_memset(cm->mip, 0,
+ cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO));
+
+ vp9_update_mode_info_border(cm, cm->mip);
+ vp9_update_mode_info_in_image(cm, cm->mi);
+
+ vp9_update_mode_info_border(cm, cm->prev_mip);
+ vp9_update_mode_info_in_image(cm, cm->prev_mi);
+}
+
int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) {
int i, mi_cols;
// Our internal buffers are always multiples of 16
const int aligned_width = multiple16(width);
const int aligned_height = multiple16(height);
+ const int ss_x = oci->subsampling_x;
+ const int ss_y = oci->subsampling_y;
vp9_free_frame_buffers(oci);
for (i = 0; i < NUM_YV12_BUFFERS; i++) {
oci->fb_idx_ref_cnt[i] = 0;
- if (vp9_alloc_frame_buffer(&oci->yv12_fb[i], width, height,
- oci->subsampling_x, oci->subsampling_y,
- VP9BORDERINPIXELS) < 0) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
+ if (vp9_alloc_frame_buffer(&oci->yv12_fb[i], width, height, ss_x, ss_y,
+ VP9BORDERINPIXELS) < 0)
+ goto fail;
}
oci->new_fb_idx = NUM_YV12_BUFFERS - 1;
@@ -99,77 +120,56 @@
oci->fb_idx_ref_cnt[i] = 1;
}
- if (vp9_alloc_frame_buffer(&oci->temp_scale_frame, width, 16,
- oci->subsampling_x, oci->subsampling_y,
- VP9BORDERINPIXELS) < 0) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
+ if (vp9_alloc_frame_buffer(&oci->temp_scale_frame, width, 16, ss_x, ss_y,
+ VP9BORDERINPIXELS) < 0)
+ goto fail;
- if (vp9_alloc_frame_buffer(&oci->post_proc_buffer, width, height,
- oci->subsampling_x, oci->subsampling_y,
- VP9BORDERINPIXELS) < 0) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
+ if (vp9_alloc_frame_buffer(&oci->post_proc_buffer, width, height, ss_x, ss_y,
+ VP9BORDERINPIXELS) < 0)
+ goto fail;
- oci->mb_rows = aligned_height >> 4;
- oci->mi_rows = aligned_height >> LOG2_MI_SIZE;
- oci->mb_cols = aligned_width >> 4;
- oci->mi_cols = aligned_width >> LOG2_MI_SIZE;
- oci->MBs = oci->mb_rows * oci->mb_cols;
- oci->mode_info_stride = oci->mi_cols + 1;
+ set_mb_mi(oci, aligned_width, aligned_height);
+
+ // Allocation
oci->mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1),
sizeof(MODE_INFO));
-
- if (!oci->mip) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
-
- oci->mi = oci->mip + oci->mode_info_stride + 1;
-
- /* allocate memory for last frame MODE_INFO array */
+ if (!oci->mip)
+ goto fail;
oci->prev_mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1),
sizeof(MODE_INFO));
+ if (!oci->prev_mip)
+ goto fail;
- if (!oci->prev_mip) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
-
- oci->prev_mi = oci->prev_mip + oci->mode_info_stride + 1;
+ setup_mi(oci);
// FIXME(jkoleszar): allocate subsampled arrays for U/V once subsampling
// information is exposed at this level
mi_cols = mi_cols_aligned_to_sb(oci);
+
+ // 2 contexts per 'mi unit', so that we have one context per 4x4 txfm
+ // block where mi unit size is 8x8.
# if CONFIG_ALPHA
- // TODO(jkoleszar): Why is this * 2?
oci->above_context[0] = vpx_calloc(sizeof(ENTROPY_CONTEXT) * 8 * mi_cols, 1);
#else
oci->above_context[0] = vpx_calloc(sizeof(ENTROPY_CONTEXT) * 6 * mi_cols, 1);
#endif
- if (!oci->above_context[0]) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
+ if (!oci->above_context[0])
+ goto fail;
+
for (i = 1; i < MAX_MB_PLANE; i++)
oci->above_context[i] =
oci->above_context[0] + i * sizeof(ENTROPY_CONTEXT) * 2 * mi_cols;
- oci->above_seg_context =
- vpx_calloc(sizeof(PARTITION_CONTEXT) * mi_cols, 1);
-
- if (!oci->above_seg_context) {
- vp9_free_frame_buffers(oci);
- return 1;
- }
-
- vp9_update_mode_info_border(oci, oci->mip);
- vp9_update_mode_info_in_image(oci, oci->mi);
+ oci->above_seg_context = vpx_calloc(sizeof(PARTITION_CONTEXT) * mi_cols, 1);
+ if (!oci->above_seg_context)
+ goto fail;
return 0;
+
+ fail:
+ vp9_free_frame_buffers(oci);
+ return 1;
}
void vp9_setup_version(VP9_COMMON *cm) {
@@ -222,27 +222,10 @@
vp9_entropy_mv_init();
}
-
void vp9_update_frame_size(VP9_COMMON *cm) {
const int aligned_width = multiple16(cm->width);
const int aligned_height = multiple16(cm->height);
- cm->mb_rows = aligned_height >> 4;
- cm->mb_cols = aligned_width >> 4;
-
- cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
- cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
-
- cm->MBs = cm->mb_rows * cm->mb_cols;
- cm->mode_info_stride = cm->mi_cols + 1;
- cm->mi = cm->mip + cm->mode_info_stride + 1;
- cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
-
- memset(cm->mip, 0,
- cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO));
- vp9_update_mode_info_border(cm, cm->mip);
- vp9_update_mode_info_in_image(cm, cm->mi);
-
- vp9_update_mode_info_border(cm, cm->prev_mip);
- vp9_update_mode_info_in_image(cm, cm->prev_mi);
+ set_mb_mi(cm, aligned_width, aligned_height);
+ setup_mi(cm);
}
diff --git a/vp9/common/vp9_alloccommon.h b/vp9/common/vp9_alloccommon.h
index 814a760..fc79f63 100644
--- a/vp9/common/vp9_alloccommon.h
+++ b/vp9/common/vp9_alloccommon.h
@@ -14,6 +14,8 @@
#include "vp9/common/vp9_onyxc_int.h"
+void vp9_initialize_common();
+
void vp9_update_mode_info_border(VP9_COMMON *cpi, MODE_INFO *mi);
void vp9_update_mode_info_in_image(VP9_COMMON *cpi, MODE_INFO *mi);
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index bc3416e..4b06a61 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -21,24 +21,26 @@
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_enums.h"
+#define BLOCK_SIZE_GROUPS 4
#define MAX_MB_SEGMENTS 8
#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1)
-#define PREDICTION_PROBS 3
-#define DEFAULT_PRED_PROB_0 120
-#define DEFAULT_PRED_PROB_1 80
-#define DEFAULT_PRED_PROB_2 40
+#define PREDICTION_PROBS 3
#define MBSKIP_CONTEXTS 3
#define MAX_REF_LF_DELTAS 4
-#define MAX_MODE_LF_DELTAS 4
+#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
+#define COMP_INTER_CONTEXTS 5
+#define REF_CONTEXTS 5
+
typedef enum {
PLANE_TYPE_Y_WITH_DC,
PLANE_TYPE_UV,
@@ -55,7 +57,8 @@
typedef enum {
KEY_FRAME = 0,
- INTER_FRAME = 1
+ INTER_FRAME = 1,
+ NUM_FRAME_TYPES,
} FRAME_TYPE;
typedef enum {
@@ -115,10 +118,19 @@
#define VP9_INTRA_MODES (TM_PRED + 1)
-#define VP9_MVREFS (1 + NEWMV - NEARESTMV)
+#define VP9_INTER_MODES (1 + NEWMV - NEARESTMV)
#define WHT_UPSCALE_FACTOR 2
+#define TX_SIZE_PROBS 6 // (TX_SIZE_MAX_SB * (TX_SIZE_MAX_SB - 1) / 2)
+
+#if TX_SIZE_PROBS == 6
+#define get_tx_probs_offset(b) ((b) < BLOCK_SIZE_MB16X16 ? 0 : \
+ (b) < BLOCK_SIZE_SB32X32 ? 1 : 3)
+#else
+#define get_tx_probs_offset(b) 0
+#endif
+
/* For keyframes, intra block modes are predicted by the (already decoded)
modes for the Y blocks to the left and above us; for interframes, there
is a single probability table. */
@@ -198,7 +210,7 @@
typedef struct {
MB_PREDICTION_MODE mode, uv_mode;
- MV_REFERENCE_FRAME ref_frame, second_ref_frame;
+ MV_REFERENCE_FRAME ref_frame[2];
TX_SIZE txfm_size;
int_mv mv[2]; // for each reference frame used
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
@@ -213,7 +225,6 @@
// Flags used for prediction status of various bistream signals
unsigned char seg_id_predicted;
- unsigned char ref_predicted;
// Indicates if the mb is part of the image (1) vs border (0)
// This can be useful in determining whether the MB provides
@@ -328,9 +339,9 @@
signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS];
/* 0 = Intra, Last, GF, ARF */
signed char ref_lf_deltas[MAX_REF_LF_DELTAS];
- /* 0 = I4X4_PRED, ZERO_MV, MV, SPLIT */
+ /* 0 = ZERO_MV, MV */
signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
- /* 0 = I4X4_PRED, ZERO_MV, MV, SPLIT */
+ /* 0 = ZERO_MV, MV */
signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];
/* Distance of MB away from frame edges */
@@ -524,7 +535,7 @@
TX_TYPE tx_type;
MODE_INFO *mi = xd->mode_info_context;
MB_MODE_INFO *const mbmi = &mi->mbmi;
- if (xd->lossless || mbmi->ref_frame != INTRA_FRAME)
+ if (xd->lossless || mbmi->ref_frame[0] != INTRA_FRAME)
return DCT_DCT;
if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
tx_type = txfm_map(mi->bmi[ib].as_mode.first);
@@ -622,6 +633,7 @@
BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size,
void *arg);
+
static INLINE void foreach_transformed_block_in_plane(
const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane,
foreach_transformed_block_visitor visit, void *arg) {
@@ -630,14 +642,14 @@
// block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
// 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
// transform size varies per plane, look it up in a common way.
- const TX_SIZE tx_size = plane ? get_uv_tx_size(xd)
- : xd->mode_info_context->mbmi.txfm_size;
+ const TX_SIZE tx_size =
+ plane ? get_uv_tx_size(xd) : xd->mode_info_context->mbmi.txfm_size;
const int block_size_b = bw + bh;
const int txfrm_size_b = tx_size * 2;
// subsampled size of the block
- const int ss_sum = xd->plane[plane].subsampling_x +
- xd->plane[plane].subsampling_y;
+ const int ss_sum = xd->plane[plane].subsampling_x
+ + xd->plane[plane].subsampling_y;
const int ss_block_size = block_size_b - ss_sum;
const int step = 1 << txfrm_size_b;
@@ -646,8 +658,42 @@
assert(txfrm_size_b <= block_size_b);
assert(txfrm_size_b <= ss_block_size);
- for (i = 0; i < (1 << ss_block_size); i += step) {
- visit(plane, i, bsize, txfrm_size_b, arg);
+
+ // If mb_to_right_edge is < 0 we are in a situation in which
+ // the current block size extends into the UMV and we won't
+ // visit the sub blocks that are wholly within the UMV.
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
+ int r, c;
+ const int sw = bw - xd->plane[plane].subsampling_x;
+ const int sh = bh - xd->plane[plane].subsampling_y;
+ int max_blocks_wide = 1 << sw;
+ int max_blocks_high = 1 << sh;
+
+ // xd->mb_to_right_edge is in units of pixels * 8. This converts
+ // it to 4x4 block sizes.
+ if (xd->mb_to_right_edge < 0)
+ max_blocks_wide +=
+ + (xd->mb_to_right_edge >> (5 + xd->plane[plane].subsampling_x));
+
+ if (xd->mb_to_bottom_edge < 0)
+ max_blocks_high +=
+ + (xd->mb_to_bottom_edge >> (5 + xd->plane[plane].subsampling_y));
+
+ i = 0;
+ // Unlike the normal case - in here we have to keep track of the
+ // row and column of the blocks we use so that we know if we are in
+ // the unrestricted motion border..
+ for (r = 0; r < (1 << sh); r += (1 << tx_size)) {
+ for (c = 0; c < (1 << sw); c += (1 << tx_size)) {
+ if (r < max_blocks_high && c < max_blocks_wide)
+ visit(plane, i, bsize, txfrm_size_b, arg);
+ i += step;
+ }
+ }
+ } else {
+ for (i = 0; i < (1 << ss_block_size); i += step) {
+ visit(plane, i, bsize, txfrm_size_b, arg);
+ }
}
}
@@ -779,4 +825,89 @@
*x = (raster_mb & (tx_cols - 1)) << (txwl);
*y = raster_mb >> tx_cols_lg2 << (txwl);
}
+
+static void extend_for_intra(MACROBLOCKD* const xd, int plane, int block,
+ BLOCK_SIZE_TYPE bsize, int ss_txfrm_size) {
+ const int bw = plane_block_width(bsize, &xd->plane[plane]);
+ const int bh = plane_block_height(bsize, &xd->plane[plane]);
+ int x, y;
+ txfrm_block_to_raster_xy(xd, bsize, plane, block, ss_txfrm_size, &x, &y);
+ x = x * 4 - 1;
+ y = y * 4 - 1;
+ // Copy a pixel into the umv if we are in a situation where the block size
+ // extends into the UMV.
+ // TODO(JBB): Should be able to do the full extend in place so we don't have
+ // to do this multiple times.
+ if (xd->mb_to_right_edge < 0) {
+ int umv_border_start = bw
+ + (xd->mb_to_right_edge >> (3 + xd->plane[plane].subsampling_x));
+
+ if (x + bw > umv_border_start)
+ vpx_memset(
+ xd->plane[plane].dst.buf + y * xd->plane[plane].dst.stride
+ + umv_border_start,
+ *(xd->plane[plane].dst.buf + y * xd->plane[plane].dst.stride
+ + umv_border_start - 1),
+ bw);
+ }
+ if (xd->mb_to_bottom_edge < 0) {
+ int umv_border_start = bh
+ + (xd->mb_to_bottom_edge >> (3 + xd->plane[plane].subsampling_y));
+ int i;
+ uint8_t c = *(xd->plane[plane].dst.buf
+ + (umv_border_start - 1) * xd->plane[plane].dst.stride + x);
+
+ uint8_t *d = xd->plane[plane].dst.buf
+ + umv_border_start * xd->plane[plane].dst.stride + x;
+
+ if (y + bh > umv_border_start)
+ for (i = 0; i < bh; i++, d += xd->plane[plane].dst.stride)
+ *d = c;
+ }
+}
+static void set_contexts_on_border(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize,
+ int plane, int ss_tx_size, int eob, int aoff,
+ int loff, ENTROPY_CONTEXT *A,
+ ENTROPY_CONTEXT *L) {
+ const int bw = b_width_log2(bsize), bh = b_height_log2(bsize);
+ const int sw = bw - xd->plane[plane].subsampling_x;
+ const int sh = bh - xd->plane[plane].subsampling_y;
+ int mi_blocks_wide = 1 << sw;
+ int mi_blocks_high = 1 << sh;
+ int tx_size_in_blocks = (1 << ss_tx_size);
+ int above_contexts = tx_size_in_blocks;
+ int left_contexts = tx_size_in_blocks;
+ int pt;
+
+ // xd->mb_to_right_edge is in units of pixels * 8. This converts
+ // it to 4x4 block sizes.
+ if (xd->mb_to_right_edge < 0) {
+ mi_blocks_wide += (xd->mb_to_right_edge
+ >> (5 + xd->plane[plane].subsampling_x));
+ }
+
+ // this code attempts to avoid copying into contexts that are outside
+ // our border. Any blocks that do are set to 0...
+ if (above_contexts + aoff > mi_blocks_wide)
+ above_contexts = mi_blocks_wide - aoff;
+
+ if (xd->mb_to_bottom_edge < 0) {
+ mi_blocks_high += (xd->mb_to_bottom_edge
+ >> (5 + xd->plane[plane].subsampling_y));
+ }
+ if (left_contexts + loff > mi_blocks_high) {
+ left_contexts = mi_blocks_high - loff;
+ }
+
+ for (pt = 0; pt < above_contexts; pt++)
+ A[pt] = eob > 0;
+ for (pt = above_contexts; pt < (1 << ss_tx_size); pt++)
+ A[pt] = 0;
+ for (pt = 0; pt < left_contexts; pt++)
+ L[pt] = eob > 0;
+ for (pt = left_contexts; pt < (1 << ss_tx_size); pt++)
+ L[pt] = 0;
+}
+
+
#endif // VP9_COMMON_VP9_BLOCKD_H_
diff --git a/vp9/common/vp9_coefupdateprobs.h b/vp9/common/vp9_coefupdateprobs.h
index e862008..ce35634 100644
--- a/vp9/common/vp9_coefupdateprobs.h
+++ b/vp9/common/vp9_coefupdateprobs.h
@@ -14,6 +14,8 @@
/* Update probabilities for the nodes in the token entropy tree.
Generated file included by vp9_entropy.c */
+#define VP9_DEF_UPDATE_PROB 252
+
static const vp9_prob vp9_coef_update_prob[UNCONSTRAINED_NODES] = {
252, 252, 252,
};
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 0274b4d..bf57e7e 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -15,58 +15,87 @@
#include "vp9/common/vp9_alloccommon.h"
#include "vpx_mem/vpx_mem.h"
-static const unsigned int y_mode_cts[VP9_INTRA_MODES] = {
- /* DC V H D45 D135 D117 D153 D27 D63 TM */
- 98, 19, 15, 14, 14, 14, 14, 12, 12, 13,
+static const vp9_prob default_kf_uv_probs[VP9_INTRA_MODES]
+ [VP9_INTRA_MODES - 1] = {
+ { 149, 13, 48, 141, 174, 131, 54, 61, 109 } /* y = dc */,
+ { 120, 17, 119, 132, 103, 103, 54, 100, 130 } /* y = v */,
+ { 114, 16, 19, 177, 220, 145, 31, 33, 122 } /* y = h */,
+ { 119, 12, 43, 102, 133, 133, 77, 90, 102 } /* y = d45 */,
+ { 110, 10, 28, 144, 78, 158, 40, 49, 161 } /* y = d135 */,
+ { 114, 10, 46, 169, 50, 96, 48, 70, 150 } /* y = d117 */,
+ { 116, 10, 24, 125, 134, 168, 26, 27, 193 } /* y = d153 */,
+ { 121, 14, 26, 124, 175, 143, 36, 37, 79 } /* y = d27 */,
+ { 116, 13, 54, 100, 105, 122, 58, 126, 122 } /* y = d63 */,
+ { 98, 22, 60, 147, 159, 124, 45, 68, 128 } /* y = tm */
};
-static const unsigned int uv_mode_cts[VP9_INTRA_MODES][VP9_INTRA_MODES] = {
- /* DC V H D45 135 117 153 D27 D63 TM */
- { 200, 15, 15, 10, 10, 10, 10, 10, 10, 6}, /* DC */
- { 130, 75, 10, 10, 10, 10, 10, 10, 10, 6}, /* V */
- { 130, 10, 75, 10, 10, 10, 10, 10, 10, 6}, /* H */
- { 130, 15, 10, 75, 10, 10, 10, 10, 10, 6}, /* D45 */
- { 150, 15, 10, 10, 75, 10, 10, 10, 10, 6}, /* D135 */
- { 150, 15, 10, 10, 10, 75, 10, 10, 10, 6}, /* D117 */
- { 150, 15, 10, 10, 10, 10, 75, 10, 10, 6}, /* D153 */
- { 150, 15, 10, 10, 10, 10, 10, 75, 10, 6}, /* D27 */
- { 150, 15, 10, 10, 10, 10, 10, 10, 75, 6}, /* D63 */
- { 160, 30, 30, 10, 10, 10, 10, 10, 10, 16}, /* TM */
+static const vp9_prob default_if_y_probs[BLOCK_SIZE_GROUPS]
+ [VP9_INTRA_MODES - 1] = {
+ { 42, 31, 23, 150, 161, 193, 32, 53, 100 } /* block_size < 8x8 */,
+ { 132, 58, 30, 160, 209, 195, 52, 47, 76 } /* block_size < 16x16 */,
+ { 179, 85, 24, 168, 236, 198, 87, 45, 46 } /* block_size < 32x32 */,
+ { 221, 176, 63, 133, 233, 121, 125, 105, 34 } /* block_size >= 32x32 */
};
-static const unsigned int kf_uv_mode_cts[VP9_INTRA_MODES][VP9_INTRA_MODES] = {
- // DC V H D45 135 117 153 D27 D63 TM
- { 160, 24, 24, 20, 20, 20, 20, 20, 20, 8}, /* DC */
- { 102, 64, 30, 20, 20, 20, 20, 20, 20, 10}, /* V */
- { 102, 30, 64, 20, 20, 20, 20, 20, 20, 10}, /* H */
- { 102, 33, 20, 64, 20, 20, 20, 20, 20, 14}, /* D45 */
- { 102, 33, 20, 20, 64, 20, 20, 20, 20, 14}, /* D135 */
- { 122, 33, 20, 20, 20, 64, 20, 20, 20, 14}, /* D117 */
- { 102, 33, 20, 20, 20, 20, 64, 20, 20, 14}, /* D153 */
- { 102, 33, 20, 20, 20, 20, 20, 64, 20, 14}, /* D27 */
- { 102, 33, 20, 20, 20, 20, 20, 20, 64, 14}, /* D63 */
- { 132, 36, 30, 20, 20, 20, 20, 20, 20, 18}, /* TM */
+static const vp9_prob default_if_uv_probs[VP9_INTRA_MODES]
+ [VP9_INTRA_MODES - 1] = {
+ { 115, 7, 78, 180, 210, 127, 34, 57, 104 } /* y = dc */,
+ { 43, 9, 165, 140, 112, 93, 45, 125, 117 } /* y = v */,
+ { 68, 6, 25, 206, 241, 154, 16, 23, 102 } /* y = h */,
+ { 90, 5, 48, 117, 155, 134, 61, 88, 96 } /* y = d45 */,
+ { 77, 5, 43, 148, 100, 147, 37, 60, 146 } /* y = d135 */,
+ { 75, 5, 57, 167, 62, 91, 45, 76, 139 } /* y = d117 */,
+ { 86, 4, 34, 155, 185, 163, 22, 29, 160 } /* y = d153 */,
+ { 82, 5, 34, 155, 207, 144, 26, 38, 79 } /* y = d27 */,
+ { 69, 6, 65, 105, 104, 122, 48, 131, 116 } /* y = d63 */,
+ { 86, 16, 114, 177, 189, 108, 28, 72, 120 } /* y = tm */
};
-const vp9_prob vp9_partition_probs[NUM_PARTITION_CONTEXTS]
+const vp9_prob vp9_partition_probs[NUM_FRAME_TYPES][NUM_PARTITION_CONTEXTS]
[PARTITION_TYPES - 1] = {
- // FIXME(jingning,rbultje) put real probabilities here
- {202, 162, 107},
- {16, 2, 169},
- {3, 246, 19},
- {104, 90, 134},
- {202, 162, 107},
- {16, 2, 169},
- {3, 246, 19},
- {104, 90, 134},
- {202, 162, 107},
- {16, 2, 169},
- {3, 246, 19},
- {104, 90, 134},
- {183, 70, 109},
- {30, 14, 162},
- {67, 208, 22},
- {4, 17, 5},
+ { /* frame_type = keyframe */
+ /* 8x8 -> 4x4 */
+ { 164, 121, 109 } /* a/l both not split */,
+ { 69, 11, 129 } /* a split, l not split */,
+ { 52, 181, 37 } /* l split, a not split */,
+ { 66, 71, 93 } /* a/l both split */,
+ /* 16x16 -> 8x8 */
+ { 154, 48, 43 } /* a/l both not split */,
+ { 81, 11, 63 } /* a split, l not split */,
+ { 67, 65, 17 } /* l split, a not split */,
+ { 57, 18, 24 } /* a/l both split */,
+ /* 32x32 -> 16x16 */
+ { 156, 42, 35 } /* a/l both not split */,
+ { 74, 10, 40 } /* a split, l not split */,
+ { 59, 53, 10 } /* l split, a not split */,
+ { 28, 10, 9 } /* a/l both split */,
+ /* 64x64 -> 32x32 */
+ { 168, 32, 43 } /* a/l both not split */,
+ { 59, 13, 41 } /* a split, l not split */,
+ { 60, 25, 10 } /* l split, a not split */,
+ { 13, 5, 4 } /* a/l both split */
+ }, { /* frame_type = interframe */
+ /* 8x8 -> 4x4 */
+ { 192, 121, 151 } /* a/l both not split */,
+ { 134, 63, 162 } /* a split, l not split */,
+ { 136, 134, 127 } /* l split, a not split */,
+ { 101, 97, 131 } /* a/l both split */,
+ /* 16x16 -> 8x8 */
+ { 167, 67, 80 } /* a/l both not split */,
+ { 87, 36, 70 } /* a split, l not split */,
+ { 90, 61, 45 } /* l split, a not split */,
+ { 46, 31, 32 } /* a/l both split */,
+ /* 32x32 -> 16x16 */
+ { 167, 63, 75 } /* a/l both not split */,
+ { 67, 27, 61 } /* a split, l not split */,
+ { 56, 87, 31 } /* l split, a not split */,
+ { 15, 13, 11 } /* a/l both split */,
+ /* 64x64 -> 32x32 */
+ { 222, 45, 44 } /* a/l both not split */,
+ { 62, 17, 62 } /* a split, l not split */,
+ { 52, 65, 16 } /* l split, a not split */,
+ { 9, 7, 6 } /* a/l both split */
+ }
};
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
@@ -96,23 +125,85 @@
struct vp9_token vp9_intra_mode_encodings[VP9_INTRA_MODES];
-struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
+struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_INTER_MODES];
struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
+static const vp9_prob default_intra_inter_p[INTRA_INTER_CONTEXTS] = {
+ 6, 87, 165, 213
+};
+
+static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
+ 25, 66, 106, 142, 183
+};
+
+static const vp9_prob default_comp_ref_p[REF_CONTEXTS] = {
+ 36, 93, 136, 205, 236
+};
+
+static const vp9_prob default_single_ref_p[REF_CONTEXTS][2] = {
+ { 30, 17 },
+ { 80, 66 },
+ { 142, 129 },
+ { 192, 178 },
+ { 235, 248 },
+};
+
+void tx_counts_to_branch_counts(unsigned int *tx_count_32x32p,
+ unsigned int *tx_count_16x16p,
+ unsigned int *tx_count_8x8p,
+ unsigned int (*ct)[2]) {
+#if TX_SIZE_PROBS == 6
+ ct[0][0] = tx_count_8x8p[TX_4X4];
+ ct[0][1] = tx_count_8x8p[TX_8X8];
+ ct[1][0] = tx_count_16x16p[TX_4X4];
+ ct[1][1] = tx_count_16x16p[TX_8X8] + tx_count_16x16p[TX_16X16];
+ ct[2][0] = tx_count_16x16p[TX_8X8];
+ ct[2][1] = tx_count_16x16p[TX_16X16];
+ ct[3][0] = tx_count_32x32p[TX_4X4];
+ ct[3][1] = tx_count_32x32p[TX_8X8] + tx_count_32x32p[TX_16X16] +
+ tx_count_32x32p[TX_32X32];
+ ct[4][0] = tx_count_32x32p[TX_8X8];
+ ct[4][1] = tx_count_32x32p[TX_16X16] + tx_count_32x32p[TX_32X32];
+ ct[5][0] = tx_count_32x32p[TX_16X16];
+ ct[5][1] = tx_count_32x32p[TX_32X32];
+#else
+ ct[0][0] = tx_count_32x32p[TX_4X4] +
+ tx_count_16x16p[TX_4X4] +
+ tx_count_8x8p[TX_4X4];
+ ct[0][1] = tx_count_32x32p[TX_8X8] +
+ tx_count_32x32p[TX_16X16] +
+ tx_count_32x32p[TX_32X32] +
+ tx_count_16x16p[TX_8X8] +
+ tx_count_16x16p[TX_16X16] +
+ tx_count_8x8p[TX_8X8];
+ ct[1][0] = tx_count_32x32p[TX_8X8] +
+ tx_count_16x16p[TX_8X8];
+ ct[1][1] = tx_count_32x32p[TX_16X16] +
+ tx_count_32x32p[TX_32X32] +
+ tx_count_16x16p[TX_16X16];
+ ct[2][0] = tx_count_32x32p[TX_16X16];
+ ct[2][1] = tx_count_32x32p[TX_32X32];
+#endif
+}
+
+#if TX_SIZE_PROBS == 6
+const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS] = {
+ 96, 96, 96, 96, 96, 96
+};
+#else
+const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS] = {
+ 96, 96, 96
+};
+#endif
+
void vp9_init_mbmode_probs(VP9_COMMON *x) {
- unsigned int bct[VP9_INTRA_MODES][2]; // num Ymodes > num UV modes
- int i;
-
- vp9_tree_probs_from_distribution(vp9_intra_mode_tree, x->fc.y_mode_prob,
- bct, y_mode_cts, 0);
-
- for (i = 0; i < VP9_INTRA_MODES; i++) {
- vp9_tree_probs_from_distribution(vp9_intra_mode_tree, x->kf_uv_mode_prob[i],
- bct, kf_uv_mode_cts[i], 0);
- vp9_tree_probs_from_distribution(vp9_intra_mode_tree, x->fc.uv_mode_prob[i],
- bct, uv_mode_cts[i], 0);
- }
+ vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs,
+ sizeof(default_if_uv_probs));
+ vpx_memcpy(x->kf_uv_mode_prob, default_kf_uv_probs,
+ sizeof(default_kf_uv_probs));
+ vpx_memcpy(x->fc.y_mode_prob, default_if_y_probs,
+ sizeof(default_if_y_probs));
vpx_memcpy(x->fc.switchable_interp_prob, vp9_switchable_interp_prob,
sizeof(vp9_switchable_interp_prob));
@@ -120,9 +211,16 @@
vpx_memcpy(x->fc.partition_prob, vp9_partition_probs,
sizeof(vp9_partition_probs));
- x->ref_pred_probs[0] = DEFAULT_PRED_PROB_0;
- x->ref_pred_probs[1] = DEFAULT_PRED_PROB_1;
- x->ref_pred_probs[2] = DEFAULT_PRED_PROB_2;
+ vpx_memcpy(x->fc.intra_inter_prob, default_intra_inter_p,
+ sizeof(default_intra_inter_p));
+ vpx_memcpy(x->fc.comp_inter_prob, default_comp_inter_p,
+ sizeof(default_comp_inter_p));
+ vpx_memcpy(x->fc.comp_ref_prob, default_comp_ref_p,
+ sizeof(default_comp_ref_p));
+ vpx_memcpy(x->fc.single_ref_prob, default_single_ref_p,
+ sizeof(default_single_ref_p));
+ vpx_memcpy(x->fc.tx_probs, vp9_default_tx_probs,
+ sizeof(vp9_default_tx_probs));
}
#if VP9_SWITCHABLE_FILTERS == 3
@@ -169,29 +267,30 @@
}
void vp9_init_mode_contexts(VP9_COMMON *pc) {
- vpx_memset(pc->fc.mv_ref_ct, 0, sizeof(pc->fc.mv_ref_ct));
- vpx_memcpy(pc->fc.vp9_mode_contexts,
- vp9_default_mode_contexts,
- sizeof(vp9_default_mode_contexts));
+ vpx_memset(pc->fc.inter_mode_counts, 0, sizeof(pc->fc.inter_mode_counts));
+ vpx_memcpy(pc->fc.inter_mode_probs,
+ vp9_default_inter_mode_probs,
+ sizeof(vp9_default_inter_mode_probs));
}
void vp9_accum_mv_refs(VP9_COMMON *pc,
MB_PREDICTION_MODE m,
const int context) {
- unsigned int (*mv_ref_ct)[VP9_MVREFS - 1][2] = pc->fc.mv_ref_ct;
+ unsigned int (*inter_mode_counts)[VP9_INTER_MODES - 1][2] =
+ pc->fc.inter_mode_counts;
if (m == ZEROMV) {
- ++mv_ref_ct[context][0][0];
+ ++inter_mode_counts[context][0][0];
} else {
- ++mv_ref_ct[context][0][1];
+ ++inter_mode_counts[context][0][1];
if (m == NEARESTMV) {
- ++mv_ref_ct[context][1][0];
+ ++inter_mode_counts[context][1][0];
} else {
- ++mv_ref_ct[context][1][1];
+ ++inter_mode_counts[context][1][1];
if (m == NEARMV) {
- ++mv_ref_ct[context][2][0];
+ ++inter_mode_counts[context][2][0];
} else {
- ++mv_ref_ct[context][2][1];
+ ++inter_mode_counts[context][2][1];
}
}
}
@@ -201,25 +300,35 @@
#define MVREF_MAX_UPDATE_FACTOR 128
void vp9_adapt_mode_context(VP9_COMMON *pc) {
int i, j;
- unsigned int (*mv_ref_ct)[VP9_MVREFS - 1][2] = pc->fc.mv_ref_ct;
- int (*mode_context)[VP9_MVREFS - 1] = pc->fc.vp9_mode_contexts;
+ unsigned int (*inter_mode_counts)[VP9_INTER_MODES - 1][2] =
+ pc->fc.inter_mode_counts;
+ vp9_prob (*mode_context)[VP9_INTER_MODES - 1] = pc->fc.inter_mode_probs;
for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
- for (i = 0; i < VP9_MVREFS - 1; i++) {
- int count = mv_ref_ct[j][i][0] + mv_ref_ct[j][i][1], factor;
-
+ for (i = 0; i < VP9_INTER_MODES - 1; i++) {
+ int count = inter_mode_counts[j][i][0] + inter_mode_counts[j][i][1];
+ int factor;
count = count > MVREF_COUNT_SAT ? MVREF_COUNT_SAT : count;
factor = (MVREF_MAX_UPDATE_FACTOR * count / MVREF_COUNT_SAT);
- mode_context[j][i] = weighted_prob(pc->fc.vp9_mode_contexts[j][i],
- get_binary_prob(mv_ref_ct[j][i][0],
- mv_ref_ct[j][i][1]),
- factor);
+ mode_context[j][i] = weighted_prob(
+ pc->fc.pre_inter_mode_probs[j][i],
+ get_binary_prob(inter_mode_counts[j][i][0],
+ inter_mode_counts[j][i][1]),
+ factor);
}
}
}
#define MODE_COUNT_SAT 20
#define MODE_MAX_UPDATE_FACTOR 144
+static int update_mode_ct(int pre_prob, int prob,
+ unsigned int branch_ct[2]) {
+ int factor, count = branch_ct[0] + branch_ct[1];
+ count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
+ factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
+ return weighted_prob(pre_prob, prob, factor);
+}
+
static void update_mode_probs(int n_modes,
const vp9_tree_index *tree, unsigned int *cnt,
vp9_prob *pre_probs, vp9_prob *dst_probs,
@@ -227,21 +336,22 @@
#define MAX_PROBS 32
vp9_prob probs[MAX_PROBS];
unsigned int branch_ct[MAX_PROBS][2];
- int t, count, factor;
+ int t;
assert(n_modes - 1 < MAX_PROBS);
vp9_tree_probs_from_distribution(tree, probs, branch_ct, cnt, tok0_offset);
- for (t = 0; t < n_modes - 1; ++t) {
- count = branch_ct[t][0] + branch_ct[t][1];
- count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
- factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
- dst_probs[t] = weighted_prob(pre_probs[t], probs[t], factor);
- }
+ for (t = 0; t < n_modes - 1; ++t)
+ dst_probs[t] = update_mode_ct(pre_probs[t], probs[t], branch_ct[t]);
+}
+
+static int update_mode_ct2(int pre_prob, unsigned int branch_ct[2]) {
+ return update_mode_ct(pre_prob, get_binary_prob(branch_ct[0],
+ branch_ct[1]), branch_ct);
}
// #define MODE_COUNT_TESTING
void vp9_adapt_mode_probs(VP9_COMMON *cm) {
- int i;
+ int i, j;
FRAME_CONTEXT *fc = &cm->fc;
#ifdef MODE_COUNT_TESTING
int t;
@@ -277,9 +387,24 @@
printf("};\n");
#endif
- update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree,
- fc->y_mode_counts, fc->pre_y_mode_prob,
- fc->y_mode_prob, 0);
+ for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
+ fc->intra_inter_prob[i] = update_mode_ct2(fc->pre_intra_inter_prob[i],
+ fc->intra_inter_count[i]);
+ for (i = 0; i < COMP_INTER_CONTEXTS; i++)
+ fc->comp_inter_prob[i] = update_mode_ct2(fc->pre_comp_inter_prob[i],
+ fc->comp_inter_count[i]);
+ for (i = 0; i < REF_CONTEXTS; i++)
+ fc->comp_ref_prob[i] = update_mode_ct2(fc->pre_comp_ref_prob[i],
+ fc->comp_ref_count[i]);
+ for (i = 0; i < REF_CONTEXTS; i++)
+ for (j = 0; j < 2; j++)
+ fc->single_ref_prob[i][j] = update_mode_ct2(fc->pre_single_ref_prob[i][j],
+ fc->single_ref_count[i][j]);
+
+ for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
+ update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree,
+ fc->y_mode_counts[i], fc->pre_y_mode_prob[i],
+ fc->y_mode_prob[i], 0);
for (i = 0; i < VP9_INTRA_MODES; ++i)
update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree,
@@ -289,7 +414,30 @@
for (i = 0; i < NUM_PARTITION_CONTEXTS; i++)
update_mode_probs(PARTITION_TYPES, vp9_partition_tree,
fc->partition_counts[i], fc->pre_partition_prob[i],
- fc->partition_prob[i], 0);
+ fc->partition_prob[INTER_FRAME][i], 0);
+
+ if (cm->mcomp_filter_type == SWITCHABLE) {
+ for (i = 0; i <= VP9_SWITCHABLE_FILTERS; i++) {
+ update_mode_probs(VP9_SWITCHABLE_FILTERS, vp9_switchable_interp_tree,
+ fc->switchable_interp_count[i],
+ fc->pre_switchable_interp_prob[i],
+ fc->switchable_interp_prob[i], 0);
+ }
+ }
+ if (cm->txfm_mode == TX_MODE_SELECT) {
+ unsigned int branch_ct[TX_SIZE_PROBS][2];
+ tx_counts_to_branch_counts(cm->fc.tx_count_32x32p,
+ cm->fc.tx_count_16x16p,
+ cm->fc.tx_count_8x8p, branch_ct);
+ for (i = 0; i < TX_SIZE_PROBS; ++i) {
+ int factor;
+ int count = branch_ct[i][0] + branch_ct[i][1];
+ vp9_prob prob = get_binary_prob(branch_ct[i][0], branch_ct[i][1]);
+ count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
+ factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
+ cm->fc.tx_probs[i] = weighted_prob(cm->fc.pre_tx_probs[i], prob, factor);
+ }
+ }
}
static void set_default_lf_deltas(MACROBLOCKD *xd) {
@@ -301,10 +449,8 @@
xd->ref_lf_deltas[GOLDEN_FRAME] = -1;
xd->ref_lf_deltas[ALTREF_FRAME] = -1;
- xd->mode_lf_deltas[0] = 2; // I4X4_PRED
- xd->mode_lf_deltas[1] = -1; // Zero
- xd->mode_lf_deltas[2] = 1; // New mv
- xd->mode_lf_deltas[3] = 2; // Split mv
+ xd->mode_lf_deltas[0] = 0; // Zero
+ xd->mode_lf_deltas[1] = 0; // New mv
}
void vp9_setup_past_independence(VP9_COMMON *cm, MACROBLOCKD *xd) {
diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h
index b731560..ce13a4c 100644
--- a/vp9/common/vp9_entropymode.h
+++ b/vp9/common/vp9_entropymode.h
@@ -21,7 +21,7 @@
extern const vp9_prob vp9_kf_default_bmode_probs[VP9_INTRA_MODES]
[VP9_INTRA_MODES]
- [VP9_INTRA_MODES -1 ];
+ [VP9_INTRA_MODES - 1];
extern const vp9_tree_index vp9_intra_mode_tree[];
extern const vp9_tree_index vp9_sb_mv_ref_tree[];
@@ -30,11 +30,14 @@
/* Inter mode values do not start at zero */
-extern struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
+extern struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_INTER_MODES];
// probability models for partition information
extern const vp9_tree_index vp9_partition_tree[];
extern struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
+extern const vp9_prob vp9_partition_probs[NUM_FRAME_TYPES]
+ [NUM_PARTITION_CONTEXTS]
+ [PARTITION_TYPES - 1];
void vp9_entropy_mode_init(void);
@@ -72,4 +75,11 @@
extern const vp9_prob vp9_switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS - 1];
+extern const vp9_prob vp9_default_tx_probs[TX_SIZE_PROBS];
+
+extern void tx_counts_to_branch_counts(unsigned int *tx_count_32x32p,
+ unsigned int *tx_count_16x16p,
+ unsigned int *tx_count_8x8p,
+ unsigned int (*ct)[2]);
+
#endif // VP9_COMMON_VP9_ENTROPYMODE_H_
diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h
index 7fb0d89..e18d353 100644
--- a/vp9/common/vp9_enums.h
+++ b/vp9/common/vp9_enums.h
@@ -16,8 +16,6 @@
#define LOG2_MI_SIZE 3
#define MI_SIZE (1 << LOG2_MI_SIZE)
-#define MI_UV_SIZE (1 << (LOG2_MI_SIZE - 1))
-
#define MI_MASK ((64 >> LOG2_MI_SIZE) - 1)
typedef enum BLOCK_SIZE_TYPE {
diff --git a/vp9/common/vp9_findnearmv.c b/vp9/common/vp9_findnearmv.c
index 9df6ce1..d781711 100644
--- a/vp9/common/vp9_findnearmv.c
+++ b/vp9/common/vp9_findnearmv.c
@@ -25,9 +25,9 @@
}
vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, vp9_prob *p, int context) {
- p[0] = pc->fc.vp9_mode_contexts[context][0];
- p[1] = pc->fc.vp9_mode_contexts[context][1];
- p[2] = pc->fc.vp9_mode_contexts[context][2];
+ p[0] = pc->fc.inter_mode_probs[context][0];
+ p[1] = pc->fc.inter_mode_probs[context][1];
+ p[2] = pc->fc.inter_mode_probs[context][2];
return p;
}
@@ -59,7 +59,7 @@
vp9_find_mv_refs_idx(cm, xd, xd->mode_info_context,
xd->prev_mode_info_context,
- ref_idx ? mbmi->second_ref_frame : mbmi->ref_frame,
+ mbmi->ref_frame[ref_idx],
mv_list, cm->ref_frame_sign_bias, block_idx);
dst_list[1].as_int = 0;
diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h
index 456d6c8..91736fe 100644
--- a/vp9/common/vp9_findnearmv.h
+++ b/vp9/common/vp9_findnearmv.h
@@ -71,7 +71,7 @@
}
vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
- vp9_prob p[VP9_MVREFS - 1],
+ vp9_prob p[VP9_INTER_MODES - 1],
const int context);
void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *pc,
@@ -87,7 +87,7 @@
/* On L edge, get from MB to left of us */
--cur_mb;
- if (cur_mb->mbmi.ref_frame != INTRA_FRAME) {
+ if (cur_mb->mbmi.ref_frame[0] != INTRA_FRAME) {
return DC_PRED;
} else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
return ((cur_mb->bmi + 1 + b)->as_mode.first);
@@ -105,7 +105,7 @@
/* On top edge, get from MB above us */
cur_mb -= mi_stride;
- if (cur_mb->mbmi.ref_frame != INTRA_FRAME) {
+ if (cur_mb->mbmi.ref_frame[0] != INTRA_FRAME) {
return DC_PRED;
} else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
return ((cur_mb->bmi + 2 + b)->as_mode.first);
diff --git a/vp9/common/vp9_implicit_segmentation.c b/vp9/common/vp9_implicit_segmentation.c
index a72c1c7..2a1d35f 100644
--- a/vp9/common/vp9_implicit_segmentation.c
+++ b/vp9/common/vp9_implicit_segmentation.c
@@ -140,11 +140,11 @@
break;
case SEGMENT_MV:
n = mi[mb_index].mbmi.mv[0].as_int;
- if (mi[mb_index].mbmi.ref_frame == INTRA_FRAME)
+ if (mi[mb_index].mbmi.ref_frame[0] == INTRA_FRAME)
n = -9999999;
break;
case SEGMENT_REFFRAME:
- n = mi[mb_index].mbmi.ref_frame;
+ n = mi[mb_index].mbmi.ref_frame[0];
break;
case SEGMENT_SKIPPED:
n = mi[mb_index].mbmi.mb_skip_coeff;
diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c
index eb7d01c..0347630 100644
--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -11,25 +11,26 @@
#include "vpx_config.h"
#include "vp9/common/vp9_loopfilter.h"
#include "vp9/common/vp9_onyxc_int.h"
+#include "vp9/common/vp9_reconinter.h"
#include "vpx_mem/vpx_mem.h"
#include "vp9/common/vp9_seg_common.h"
static void lf_init_lut(loop_filter_info_n *lfi) {
- lfi->mode_lf_lut[DC_PRED] = 1;
- lfi->mode_lf_lut[D45_PRED] = 1;
- lfi->mode_lf_lut[D135_PRED] = 1;
- lfi->mode_lf_lut[D117_PRED] = 1;
- lfi->mode_lf_lut[D153_PRED] = 1;
- lfi->mode_lf_lut[D27_PRED] = 1;
- lfi->mode_lf_lut[D63_PRED] = 1;
- lfi->mode_lf_lut[V_PRED] = 1;
- lfi->mode_lf_lut[H_PRED] = 1;
- lfi->mode_lf_lut[TM_PRED] = 1;
- lfi->mode_lf_lut[ZEROMV] = 1;
- lfi->mode_lf_lut[NEARESTMV] = 2;
- lfi->mode_lf_lut[NEARMV] = 2;
- lfi->mode_lf_lut[NEWMV] = 2;
+ lfi->mode_lf_lut[DC_PRED] = 0;
+ lfi->mode_lf_lut[D45_PRED] = 0;
+ lfi->mode_lf_lut[D135_PRED] = 0;
+ lfi->mode_lf_lut[D117_PRED] = 0;
+ lfi->mode_lf_lut[D153_PRED] = 0;
+ lfi->mode_lf_lut[D27_PRED] = 0;
+ lfi->mode_lf_lut[D63_PRED] = 0;
+ lfi->mode_lf_lut[V_PRED] = 0;
+ lfi->mode_lf_lut[H_PRED] = 0;
+ lfi->mode_lf_lut[TM_PRED] = 0;
+ lfi->mode_lf_lut[ZEROMV] = 0;
+ lfi->mode_lf_lut[NEARESTMV] = 1;
+ lfi->mode_lf_lut[NEARMV] = 1;
+ lfi->mode_lf_lut[NEWMV] = 1;
}
void vp9_loop_filter_update_sharpness(loop_filter_info_n *lfi,
@@ -131,13 +132,7 @@
/* Apply delta for reference frame */
lvl_ref += xd->ref_lf_deltas[ref] << n_shift;
- /* Apply delta for Intra modes */
- mode = 0; /* I4X4_PRED */
- /* Only the split mode I4X4_PRED has a further special case */
- lvl_mode = lvl_ref + (xd->mode_lf_deltas[mode] << n_shift);
- lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63);
-
- mode = 1; /* all the rest of Intra modes */
+ mode = 0; /* all the rest of Intra modes */
lvl_mode = lvl_ref;
lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63);
@@ -149,7 +144,7 @@
lvl_ref += xd->ref_lf_deltas[ref] << n_shift;
/* Apply delta for Inter modes */
- for (mode = 1; mode < 4; mode++) {
+ for (mode = 0; mode < MAX_MODE_LF_DELTAS; mode++) {
lvl_mode = lvl_ref + (xd->mode_lf_deltas[mode] << n_shift);
lfi->lvl[seg][ref][mode] = clamp(lvl_mode, 0, 63);
}
@@ -157,6 +152,7 @@
}
}
+#if !CONFIG_NEW_LOOPFILTER
// Determine if we should skip inner-MB loop filtering within a MB
// The current condition is that the loop filtering is skipped only
// the MB uses a prediction size of 16x16 and either 16x16 transform
@@ -177,8 +173,8 @@
const MB_MODE_INFO *mbmi0 = &mip0->mbmi;
const MB_MODE_INFO *mbmi1 = &mip1->mbmi;
return mb_lf_skip(mbmi0) && mb_lf_skip(mbmi1) &&
- mbmi0->ref_frame != INTRA_FRAME &&
- mbmi1->ref_frame != INTRA_FRAME;
+ mbmi0->ref_frame[0] != INTRA_FRAME &&
+ mbmi1->ref_frame[0] != INTRA_FRAME;
}
static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
@@ -191,7 +187,7 @@
int mode = mi->mbmi.mode;
int mode_index = lfi_n->mode_lf_lut[mode];
int seg = mi->mbmi.segment_id;
- int ref_frame = mi->mbmi.ref_frame;
+ MV_REFERENCE_FRAME ref_frame = mi->mbmi.ref_frame[0];
int filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
if (filter_level) {
@@ -537,3 +533,235 @@
}
}
}
+
+#else
+static int build_lfi(const VP9_COMMON *cm, const MB_MODE_INFO *mbmi,
+ struct loop_filter_info *lfi) {
+ const loop_filter_info_n *lfi_n = &cm->lf_info;
+ int mode = mbmi->mode;
+ int mode_index = lfi_n->mode_lf_lut[mode];
+ int seg = mbmi->segment_id;
+ int ref_frame = mbmi->ref_frame[0];
+ int filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
+
+ if (filter_level) {
+ const int hev_index = filter_level >> 4;
+ lfi->mblim = lfi_n->mblim[filter_level];
+ lfi->blim = lfi_n->blim[filter_level];
+ lfi->lim = lfi_n->lim[filter_level];
+ lfi->hev_thr = lfi_n->hev_thr[hev_index];
+ return 1;
+ }
+ return 0;
+}
+
+static void filter_selectively_vert(uint8_t *s, int pitch,
+ unsigned int mask_16x16,
+ unsigned int mask_8x8,
+ unsigned int mask_4x4,
+ unsigned int mask_4x4_1,
+ const struct loop_filter_info *lfi) {
+ unsigned int mask;
+
+ for (mask = mask_16x16 | mask_8x8 | mask_4x4; mask; mask >>= 1) {
+ if (mask & 1) {
+ if (mask_16x16 & 1) {
+ vp9_mb_lpf_vertical_edge_w(s, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ assert(!(mask_8x8 & 1));
+ assert(!(mask_4x4 & 1));
+ assert(!(mask_4x4_1 & 1));
+ } else if (mask_8x8 & 1) {
+ vp9_mbloop_filter_vertical_edge(s, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ assert(!(mask_16x16 & 1));
+ assert(!(mask_4x4 & 1));
+ } else if (mask_4x4 & 1) {
+ vp9_loop_filter_vertical_edge(s, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ assert(!(mask_16x16 & 1));
+ assert(!(mask_8x8 & 1));
+ } else {
+ assert(0);
+ }
+
+ if (mask_4x4_1 & 1)
+ vp9_loop_filter_vertical_edge(s + 4, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ }
+ s += 8;
+ lfi++;
+ mask_16x16 >>= 1;
+ mask_8x8 >>= 1;
+ mask_4x4 >>= 1;
+ mask_4x4_1 >>= 1;
+ }
+}
+
+static void filter_selectively_horiz(uint8_t *s, int pitch,
+ unsigned int mask_16x16,
+ unsigned int mask_8x8,
+ unsigned int mask_4x4,
+ unsigned int mask_4x4_1,
+ int only_4x4_1,
+ const struct loop_filter_info *lfi) {
+ unsigned int mask;
+
+ for (mask = mask_16x16 | mask_8x8 | mask_4x4; mask; mask >>= 1) {
+ if (mask & 1) {
+ if (!only_4x4_1) {
+ if (mask_16x16 & 1) {
+ vp9_mb_lpf_horizontal_edge_w(s, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ assert(!(mask_8x8 & 1));
+ assert(!(mask_4x4 & 1));
+ assert(!(mask_4x4_1 & 1));
+ } else if (mask_8x8 & 1) {
+ vp9_mbloop_filter_horizontal_edge(s, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ assert(!(mask_16x16 & 1));
+ assert(!(mask_4x4 & 1));
+ } else if (mask_4x4 & 1) {
+ vp9_loop_filter_horizontal_edge(s, pitch, lfi->mblim, lfi->lim,
+ lfi->hev_thr, 1);
+ assert(!(mask_16x16 & 1));
+ assert(!(mask_8x8 & 1));
+ } else {
+ assert(0);
+ }
+ }
+
+ if (mask_4x4_1 & 1)
+ vp9_loop_filter_horizontal_edge(s + 4 * pitch, pitch, lfi->mblim,
+ lfi->lim, lfi->hev_thr, 1);
+ }
+ s += 8;
+ lfi++;
+ mask_16x16 >>= 1;
+ mask_8x8 >>= 1;
+ mask_4x4 >>= 1;
+ mask_4x4_1 >>= 1;
+ }
+}
+
+static void filter_block_plane(VP9_COMMON *cm, MACROBLOCKD *xd,
+ int plane, int mi_row, int mi_col) {
+ const int ss_x = xd->plane[plane].subsampling_x;
+ const int row_step = 1 << xd->plane[plane].subsampling_y;
+ const int col_step = 1 << xd->plane[plane].subsampling_x;
+ struct buf_2d * const dst = &xd->plane[plane].dst;
+ uint8_t* const dst0 = dst->buf;
+ MODE_INFO* const mi0 = xd->mode_info_context;
+ unsigned int mask_16x16[64 / MI_SIZE] = {0};
+ unsigned int mask_8x8[64 / MI_SIZE] = {0};
+ unsigned int mask_4x4[64 / MI_SIZE] = {0};
+ unsigned int mask_4x4_1[64 / MI_SIZE] = {0};
+ struct loop_filter_info lfi[64 / MI_SIZE][64 / MI_SIZE];
+ int r, c;
+
+ for (r = 0; r < 64 / MI_SIZE && mi_row + r < cm->mi_rows; r += row_step) {
+ unsigned int mask_16x16_c = 0;
+ unsigned int mask_8x8_c = 0;
+ unsigned int mask_4x4_c = 0;
+ unsigned int border_mask;
+
+ // Determine the vertical edges that need filtering
+ for (c = 0; c < 64 / MI_SIZE && mi_col + c < cm->mi_cols; c += col_step) {
+ const MODE_INFO const *mi = xd->mode_info_context;
+ const MODE_INFO const *mi_above = xd->mode_info_context -
+ cm->mode_info_stride;
+ const int skip_above =
+ (r + mi_row > 0) ? mi_above[c].mbmi.mb_skip_coeff : 0;
+ const int skip_left =
+ (c + mi_col > 0) ? mi[c - 1].mbmi.mb_skip_coeff : 0;
+ const int skip_this = mi[c].mbmi.mb_skip_coeff;
+ const int skip_this_c = skip_this && skip_left;
+ const int skip_this_r = skip_this && skip_above;
+ const TX_SIZE tx_size = plane ? get_uv_tx_size(xd) : mi[c].mbmi.txfm_size;
+
+ // Filter level can vary per MI
+ if (!build_lfi(cm, &mi[c].mbmi,
+ lfi[r] + (c >> xd->plane[plane].subsampling_x)))
+ continue;
+
+ // Build masks based on the transform size of each block
+ if (tx_size == TX_32X32) {
+ if (!skip_this_c && (c & 3) == 0)
+ mask_16x16_c |= 1 << (c >> ss_x);
+ if (!skip_this_r && (r & 3) == 0)
+ mask_16x16[r] |= 1 << (c >> ss_x);
+ } else if (tx_size == TX_16X16) {
+ if (!skip_this_c && (c & 1) == 0)
+ mask_16x16_c |= 1 << (c >> ss_x);
+ if (!skip_this_r && (r & 1) == 0)
+ mask_16x16[r] |= 1 << (c >> ss_x);
+ } else {
+ // force 8x8 filtering on 32x32 boundaries
+ if (!skip_this_c) {
+ if (tx_size == TX_8X8 || (c & 3) == 0)
+ mask_8x8_c |= 1 << (c >> ss_x);
+ else
+ mask_4x4_c |= 1 << (c >> ss_x);
+ }
+
+ if (!skip_this_r) {
+ if (tx_size == TX_8X8 || (r & 3) == 0)
+ mask_8x8[r] |= 1 << (c >> ss_x);
+ else
+ mask_4x4[r] |= 1 << (c >> ss_x);
+ }
+
+ if (!skip_this && tx_size < TX_8X8)
+ mask_4x4_1[r] |= 1 << (c >> ss_x);
+ }
+ }
+
+ // Disable filtering on the leftmost column
+ border_mask = ~(mi_col == 0);
+ filter_selectively_vert(dst->buf, dst->stride,
+ mask_16x16_c & border_mask,
+ mask_8x8_c & border_mask,
+ mask_4x4_c & border_mask,
+ mask_4x4_1[r], lfi[r]);
+ dst->buf += 8 * dst->stride;
+ xd->mode_info_context += cm->mode_info_stride * row_step;
+ }
+
+ // Now do horizontal pass
+ dst->buf = dst0;
+ xd->mode_info_context = mi0;
+ for (r = 0; r < 64 / MI_SIZE && mi_row + r < cm->mi_rows; r += row_step) {
+ filter_selectively_horiz(dst->buf, dst->stride,
+ mask_16x16[r],
+ mask_8x8[r],
+ mask_4x4[r],
+ mask_4x4_1[r], mi_row + r == 0, lfi[r]);
+ dst->buf += 8 * dst->stride;
+ xd->mode_info_context += cm->mode_info_stride * row_step;
+ }
+}
+
+void vp9_loop_filter_frame(VP9_COMMON *cm,
+ MACROBLOCKD *xd,
+ int frame_filter_level,
+ int y_only) {
+ int mi_row, mi_col;
+
+ // Initialize the loop filter for this frame.
+ vp9_loop_filter_frame_init(cm, xd, frame_filter_level);
+
+ for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 64 / MI_SIZE) {
+ MODE_INFO* const mi = cm->mi + mi_row * cm->mode_info_stride;
+
+ for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 64 / MI_SIZE) {
+ int plane;
+
+ setup_dst_planes(xd, cm->frame_to_show, mi_row, mi_col);
+ for (plane = 0; plane < (y_only ? 1 : MAX_MB_PLANE); plane++) {
+ xd->mode_info_context = mi + mi_col;
+ filter_block_plane(cm, xd, plane, mi_row, mi_col);
+ }
+ }
+ }
+}
+#endif
diff --git a/vp9/common/vp9_loopfilter_filters.c b/vp9/common/vp9_loopfilter_filters.c
index fc7fbc4..3f90304 100644
--- a/vp9/common/vp9_loopfilter_filters.c
+++ b/vp9/common/vp9_loopfilter_filters.c
@@ -206,6 +206,7 @@
}
}
+#if !CONFIG_NEW_LOOPFILTER
/* Vertical MB Filtering */
void vp9_loop_filter_mbv_c(uint8_t *y_ptr, uint8_t *u_ptr,
uint8_t *v_ptr, int y_stride, int uv_stride,
@@ -308,6 +309,7 @@
vp9_loop_filter_vertical_edge_c(v + 4, uv_stride,
lfi->blim, lfi->lim, lfi->hev_thr, 1);
}
+#endif
static INLINE void wide_mbfilter(int8_t mask, uint8_t hev,
uint8_t flat, uint8_t flat2,
@@ -412,6 +414,7 @@
}
}
+#if !CONFIG_NEW_LOOPFILTER
void vp9_lpf_mbv_w_c(uint8_t *y, uint8_t *u, uint8_t *v,
int y_stride, int uv_stride,
struct loop_filter_info *lfi) {
@@ -441,4 +444,4 @@
vp9_mbloop_filter_horizontal_edge_c(v, uv_stride,
lfi->mblim, lfi->lim, lfi->hev_thr, 1);
}
-
+#endif
diff --git a/vp9/common/vp9_modecont.c b/vp9/common/vp9_modecont.c
index 973bb06..bdb0049 100644
--- a/vp9/common/vp9_modecont.c
+++ b/vp9/common/vp9_modecont.c
@@ -11,7 +11,8 @@
#include "vp9/common/vp9_entropy.h"
-const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][VP9_MVREFS - 1] = {
+const vp9_prob vp9_default_inter_mode_probs[INTER_MODE_CONTEXTS]
+ [VP9_INTER_MODES - 1] = {
{2, 173, 34}, // 0 = both zero mv
{7, 145, 85}, // 1 = one zero mv + one a predicted mv
{7, 166, 63}, // 2 = two predicted mvs
diff --git a/vp9/common/vp9_modecont.h b/vp9/common/vp9_modecont.h
index a6c4893..1a3e993 100644
--- a/vp9/common/vp9_modecont.h
+++ b/vp9/common/vp9_modecont.h
@@ -13,6 +13,7 @@
#include "vp9/common/vp9_entropy.h"
-extern const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][VP9_MVREFS - 1];
+extern const int vp9_default_inter_mode_probs[INTER_MODE_CONTEXTS]
+ [VP9_INTER_MODES - 1];
#endif // VP9_COMMON_VP9_MODECONT_H_
diff --git a/vp9/common/vp9_modecontext.c b/vp9/common/vp9_modecontext.c
index 39d53f5..f50652a 100644
--- a/vp9/common/vp9_modecontext.c
+++ b/vp9/common/vp9_modecontext.c
@@ -13,116 +13,116 @@
const vp9_prob vp9_kf_default_bmode_probs[VP9_INTRA_MODES]
[VP9_INTRA_MODES]
- [VP9_INTRA_MODES-1] = {
- { // Above 0
- { 231, 9, 124, 138, 96, 200, 76, 42, 88, }, // left 0
- { 152, 11, 187, 112, 170, 139, 130, 91, 113, }, // left 1
- { 175, 10, 71, 182, 212, 191, 43, 39, 82, }, // left 2
- { 56, 23, 63, 38, 76, 60, 185, 206, 159, }, // left 3
- { 144, 52, 89, 192, 19, 236, 134, 93, 37, }, // left 4
- { 114, 22, 29, 133, 37, 18, 60, 156, 233, }, // left 5
- { 121, 16, 26, 124, 176, 50, 29, 20, 234, }, // left 6
- { 170, 19, 50, 91, 169, 216, 14, 16, 5, }, // left 7
- { 63, 14, 21, 68, 32, 29, 71, 224, 181, }, // left 8
- { 81, 93, 62, 65, 78, 171, 152, 103, 172, }, // left 9
- }, { // Above 1
- { 134, 2, 185, 147, 159, 152, 83, 33, 136, }, // left 0
- { 72, 9, 194, 141, 208, 108, 124, 73, 119, }, // left 1
- { 66, 1, 102, 183, 236, 151, 35, 8, 78, }, // left 2
- { 41, 30, 60, 26, 101, 148, 212, 206, 177, }, // left 3
- { 104, 91, 122, 184, 33, 243, 156, 73, 1, }, // left 4
- { 74, 23, 47, 119, 63, 60, 79, 135, 211, }, // left 5
- { 65, 12, 40, 134, 211, 79, 42, 37, 187, }, // left 6
- { 87, 26, 76, 97, 218, 183, 27, 7, 31, }, // left 7
- { 47, 24, 45, 53, 78, 89, 105, 215, 128, }, // left 8
- { 66, 89, 68, 91, 120, 113, 190, 105, 98, }, // left 9
- }, { // Above 2
- { 88, 1, 88, 166, 229, 115, 30, 23, 155, }, // left 0
- { 43, 5, 98, 198, 244, 158, 50, 14, 113, }, // left 1
- { 39, 1, 53, 208, 247, 208, 10, 11, 92, }, // left 2
- { 56, 42, 41, 102, 156, 110, 76, 61, 106, }, // left 3
- { 107, 79, 78, 158, 85, 255, 20, 64, 114, }, // left 4
- { 39, 15, 30, 174, 135, 66, 85, 28, 176, }, // left 5
- { 34, 5, 22, 137, 222, 64, 22, 5, 220, }, // left 6
- { 68, 7, 25, 135, 206, 192, 7, 14, 8, }, // left 7
- { 34, 45, 24, 78, 85, 55, 85, 120, 60, }, // left 8
- { 62, 54, 23, 142, 182, 177, 64, 57, 171, }, // left 9
- }, { // Above 3
- { 193, 15, 108, 82, 121, 192, 188, 119, 145, }, // left 0
- { 60, 15, 157, 65, 142, 61, 202, 203, 85, }, // left 1
- { 112, 17, 121, 128, 175, 128, 94, 85, 1, }, // left 2
- { 40, 25, 47, 12, 20, 64, 221, 194, 57, }, // left 3
- { 100, 74, 112, 85, 43, 255, 64, 142, 128, }, // left 4
- { 88, 24, 47, 91, 93, 73, 141, 171, 85, }, // left 5
- { 61, 9, 65, 75, 107, 146, 53, 100, 255, }, // left 6
- { 142, 8, 80, 105, 199, 255, 20, 43, 1, }, // left 7
- { 41, 17, 43, 22, 64, 43, 98, 246, 255, }, // left 8
- { 51, 37, 59, 56, 94, 64, 200, 154, 128, }, // left 9
- }, { // Above 4
- { 125, 10, 103, 129, 89, 209, 65, 22, 91, }, // left 0
- { 95, 25, 93, 146, 108, 208, 96, 34, 108, }, // left 1
- { 75, 17, 84, 185, 188, 199, 20, 1, 43, }, // left 2
- { 57, 91, 27, 83, 23, 205, 67, 75, 149, }, // left 3
- { 115, 70, 29, 237, 3, 247, 73, 51, 1, }, // left 4
- { 38, 67, 45, 73, 64, 85, 51, 96, 255, }, // left 5
- { 41, 25, 11, 142, 133, 128, 77, 73, 205, }, // left 6
- { 101, 26, 32, 124, 38, 247, 7, 7, 8, }, // left 7
- { 57, 91, 28, 128, 32, 73, 128, 128, 128, }, // left 8
- { 117, 127, 39, 164, 51, 230, 128, 183, 255, }, // left 9
- }, { // Above 5
- { 138, 5, 32, 135, 70, 29, 33, 115, 208, }, // left 0
- { 67, 9, 91, 111, 142, 38, 78, 87, 199, }, // left 1
- { 63, 7, 60, 172, 138, 60, 85, 64, 199, }, // left 2
- { 40, 25, 44, 87, 71, 79, 102, 183, 85, }, // left 3
- { 57, 110, 80, 140, 85, 255, 51, 128, 128, }, // left 4
- { 47, 12, 16, 167, 26, 23, 69, 135, 171, }, // left 5
- { 46, 14, 18, 102, 89, 15, 7, 67, 238, }, // left 6
- { 65, 8, 33, 123, 158, 51, 18, 79, 114, }, // left 7
- { 40, 16, 3, 91, 28, 32, 37, 207, 224, }, // left 8
- { 87, 66, 49, 98, 32, 146, 59, 51, 224, }, // left 9
- }, { // Above 6
- { 104, 1, 55, 88, 130, 39, 9, 17, 234, }, // left 0
- { 64, 15, 96, 103, 192, 37, 43, 15, 248, }, // left 1
- { 54, 2, 57, 135, 213, 70, 4, 22, 203, }, // left 2
- { 30, 38, 40, 64, 128, 43, 114, 141, 171, }, // left 3
- { 75, 43, 38, 181, 21, 233, 154, 128, 1, }, // left 4
- { 39, 1, 19, 126, 107, 12, 35, 40, 237, }, // left 5
- { 31, 6, 9, 77, 221, 1, 2, 4, 244, }, // left 6
- { 88, 20, 33, 90, 110, 192, 39, 23, 51, }, // left 7
- { 56, 21, 23, 119, 55, 70, 48, 177, 128, }, // left 8
- { 55, 44, 46, 120, 188, 1, 60, 98, 192, }, // left 9
- }, { // Above 7
- { 102, 1, 61, 95, 192, 205, 6, 9, 31, }, // left 0
- { 69, 12, 63, 104, 187, 166, 14, 5, 20, }, // left 1
- { 68, 1, 45, 136, 242, 154, 1, 7, 30, }, // left 2
- { 62, 69, 24, 92, 73, 205, 82, 90, 93, }, // left 3
- { 75, 31, 17, 215, 12, 246, 16, 17, 1, }, // left 4
- { 37, 18, 46, 128, 80, 93, 112, 1, 114, }, // left 5
- { 63, 9, 10, 125, 195, 85, 20, 11, 134, }, // left 6
- { 86, 6, 6, 54, 136, 224, 1, 1, 1, }, // left 7
- { 56, 24, 9, 110, 43, 77, 128, 96, 1, }, // left 8
- { 58, 60, 20, 59, 116, 171, 69, 28, 75, }, // left 9
- }, { // Above 8
- { 164, 10, 52, 70, 121, 74, 105, 168, 164, }, // left 0
- { 51, 20, 112, 95, 138, 85, 101, 166, 238, }, // left 1
- { 86, 9, 42, 122, 140, 77, 117, 39, 23, }, // left 2
- { 22, 18, 28, 30, 156, 146, 141, 247, 255, }, // left 3
- { 83, 98, 20, 128, 43, 205, 128, 85, 1, }, // left 4
- { 45, 32, 18, 92, 67, 18, 38, 238, 255, }, // left 5
- { 56, 7, 22, 104, 98, 32, 54, 85, 154, }, // left 6
- { 85, 13, 27, 120, 192, 128, 57, 73, 51, }, // left 7
- { 18, 7, 12, 29, 67, 37, 40, 240, 192, }, // left 8
- { 35, 40, 32, 55, 57, 37, 147, 165, 154, }, // left 9
- }, { // Above 9
- { 190, 31, 91, 133, 82, 229, 152, 59, 141, }, // left 0
- { 85, 47, 155, 116, 163, 213, 141, 85, 171, }, // left 1
- { 101, 8, 78, 184, 186, 142, 118, 37, 128, }, // left 2
- { 56, 40, 49, 37, 128, 183, 219, 149, 205, }, // left 3
- { 146, 92, 56, 184, 45, 229, 114, 102, 1, }, // left 4
- { 71, 45, 37, 107, 51, 32, 110, 224, 1, }, // left 5
- { 101, 26, 43, 111, 158, 102, 45, 91, 228, }, // left 6
- { 138, 17, 48, 117, 144, 255, 81, 20, 21, }, // left 7
- { 32, 33, 47, 64, 93, 73, 101, 179, 171, }, // left 8
- { 112, 125, 38, 113, 56, 213, 168, 154, 192, }, // left 9
- },
+ [VP9_INTRA_MODES - 1] = {
+ { /* above = dc */
+ { 165, 25, 57, 147, 137, 207, 70, 49, 89 } /* left = dc */,
+ { 107, 33, 127, 132, 131, 173, 86, 88, 105 } /* left = v */,
+ { 87, 25, 24, 193, 225, 213, 44, 33, 94 } /* left = h */,
+ { 82, 32, 42, 91, 116, 154, 134, 119, 110 } /* left = d45 */,
+ { 87, 41, 47, 164, 49, 219, 85, 72, 84 } /* left = d135 */,
+ { 83, 29, 29, 134, 55, 84, 58, 132, 185 } /* left = d117 */,
+ { 78, 22, 24, 134, 145, 161, 37, 32, 199 } /* left = d153 */,
+ { 103, 25, 33, 121, 156, 215, 34, 32, 29 } /* left = d27 */,
+ { 73, 28, 26, 91, 75, 116, 67, 169, 128 } /* left = d63 */,
+ { 62, 79, 46, 119, 142, 197, 97, 73, 133 } /* left = tm */
+ }, { /* above = v */
+ { 77, 19, 144, 147, 131, 159, 67, 75, 108 } /* left = dc */,
+ { 48, 30, 180, 135, 139, 124, 84, 125, 102 } /* left = v */,
+ { 47, 14, 76, 169, 216, 171, 48, 35, 77 } /* left = h */,
+ { 53, 39, 82, 93, 98, 165, 128, 156, 115 } /* left = d45 */,
+ { 59, 52, 88, 155, 54, 208, 95, 109, 23 } /* left = d135 */,
+ { 45, 30, 76, 136, 51, 95, 62, 154, 157 } /* left = d117 */,
+ { 45, 22, 60, 127, 136, 156, 45, 67, 157 } /* left = d153 */,
+ { 59, 30, 78, 107, 157, 181, 49, 39, 50 } /* left = d27 */,
+ { 45, 33, 70, 85, 76, 127, 76, 185, 89 } /* left = d63 */,
+ { 41, 69, 104, 113, 125, 154, 110, 123, 88 } /* left = tm */
+ }, { /* above = h */
+ { 85, 12, 38, 172, 219, 185, 40, 29, 118 } /* left = dc */,
+ { 52, 25, 78, 175, 211, 189, 56, 37, 108 } /* left = v */,
+ { 38, 11, 17, 207, 245, 224, 18, 13, 84 } /* left = h */,
+ { 63, 42, 25, 121, 162, 179, 63, 53, 90 } /* left = d45 */,
+ { 69, 59, 35, 146, 108, 245, 33, 56, 115 } /* left = d135 */,
+ { 45, 27, 30, 160, 118, 128, 75, 49, 147 } /* left = d117 */,
+ { 40, 17, 19, 147, 198, 169, 30, 14, 181 } /* left = d153 */,
+ { 56, 19, 15, 150, 207, 212, 17, 22, 28 } /* left = d27 */,
+ { 45, 50, 21, 97, 113, 135, 68, 89, 72 } /* left = d63 */,
+ { 41, 70, 19, 165, 199, 203, 54, 52, 121 } /* left = tm */
+ }, { /* above = d45 */
+ { 124, 25, 52, 122, 127, 200, 116, 88, 105 } /* left = dc */,
+ { 60, 31, 107, 103, 119, 136, 135, 150, 90 } /* left = v */,
+ { 70, 28, 37, 157, 203, 192, 73, 67, 21 } /* left = h */,
+ { 62, 33, 39, 54, 67, 159, 150, 114, 61 } /* left = d45 */,
+ { 69, 41, 46, 102, 64, 240, 68, 103, 111 } /* left = d135 */,
+ { 59, 27, 39, 121, 68, 132, 101, 139, 96 } /* left = d117 */,
+ { 55, 19, 33, 119, 109, 198, 61, 88, 224 } /* left = d153 */,
+ { 92, 16, 40, 107, 160, 242, 48, 62, 15 } /* left = d27 */,
+ { 57, 27, 36, 65, 95, 130, 94, 213, 222 } /* left = d63 */,
+ { 47, 47, 47, 101, 130, 154, 130, 105, 102 } /* left = tm */
+ }, { /* above = d135 */
+ { 80, 19, 42, 132, 81, 205, 51, 36, 99 } /* left = dc */,
+ { 60, 34, 67, 145, 76, 196, 72, 61, 112 } /* left = v */,
+ { 46, 25, 29, 172, 181, 208, 37, 11, 79 } /* left = h */,
+ { 59, 45, 20, 103, 42, 203, 57, 68, 107 } /* left = d45 */,
+ { 68, 41, 25, 190, 21, 226, 68, 65, 38 } /* left = d135 */,
+ { 42, 38, 34, 133, 48, 145, 57, 106, 237 } /* left = d117 */,
+ { 35, 20, 11, 139, 94, 197, 49, 50, 182 } /* left = d153 */,
+ { 64, 26, 24, 122, 73, 230, 27, 27, 39 } /* left = d27 */,
+ { 53, 49, 25, 118, 52, 147, 84, 104, 103 } /* left = d63 */,
+ { 62, 70, 35, 156, 90, 214, 95, 140, 211 } /* left = tm */
+ }, { /* above = d117 */
+ { 78, 14, 37, 152, 67, 100, 44, 103, 160 } /* left = dc */,
+ { 50, 20, 86, 139, 72, 98, 62, 111, 157 } /* left = v */,
+ { 42, 17, 33, 169, 153, 139, 62, 61, 136 } /* left = h */,
+ { 48, 21, 39, 123, 65, 143, 76, 131, 87 } /* left = d45 */,
+ { 47, 41, 44, 149, 49, 221, 51, 107, 122 } /* left = d135 */,
+ { 37, 18, 26, 177, 20, 66, 58, 131, 148 } /* left = d117 */,
+ { 39, 19, 26, 125, 77, 115, 22, 75, 192 } /* left = d153 */,
+ { 48, 13, 33, 125, 113, 132, 30, 77, 99 } /* left = d27 */,
+ { 45, 27, 15, 119, 42, 96, 45, 168, 164 } /* left = d63 */,
+ { 48, 52, 52, 129, 60, 158, 58, 89, 153 } /* left = tm */
+ }, { /* above = d153 */
+ { 82, 9, 31, 121, 146, 145, 23, 28, 194 } /* left = dc */,
+ { 57, 32, 78, 121, 148, 128, 50, 37, 217 } /* left = v */,
+ { 38, 12, 19, 158, 221, 172, 12, 22, 166 } /* left = h */,
+ { 49, 32, 24, 100, 125, 142, 72, 83, 132 } /* left = d45 */,
+ { 54, 36, 22, 172, 49, 225, 88, 72, 59 } /* left = d135 */,
+ { 43, 7, 23, 130, 95, 86, 44, 57, 206 } /* left = d117 */,
+ { 34, 13, 12, 90, 196, 91, 8, 10, 226 } /* left = d153 */,
+ { 55, 23, 17, 106, 127, 207, 32, 23, 92 } /* left = d27 */,
+ { 54, 28, 20, 121, 76, 151, 45, 110, 124 } /* left = d63 */,
+ { 41, 51, 31, 120, 192, 74, 45, 62, 163 } /* left = tm */
+ }, { /* above = d27 */
+ { 88, 10, 40, 120, 157, 211, 25, 27, 54 } /* left = dc */,
+ { 64, 31, 69, 121, 129, 184, 36, 29, 45 } /* left = v */,
+ { 51, 11, 22, 170, 232, 209, 11, 20, 64 } /* left = h */,
+ { 65, 43, 19, 102, 91, 208, 68, 78, 75 } /* left = d45 */,
+ { 64, 40, 23, 171, 47, 229, 45, 48, 19 } /* left = d135 */,
+ { 43, 27, 39, 136, 76, 149, 92, 13, 114 } /* left = d117 */,
+ { 53, 19, 14, 128, 148, 173, 31, 25, 133 } /* left = d153 */,
+ { 73, 19, 13, 97, 137, 218, 12, 12, 10 } /* left = d27 */,
+ { 57, 35, 15, 111, 68, 149, 90, 102, 16 } /* left = d63 */,
+ { 43, 63, 23, 107, 144, 200, 64, 47, 88 } /* left = tm */
+ }, { /* above = d63 */
+ { 95, 19, 44, 97, 120, 145, 81, 142, 115 } /* left = dc */,
+ { 46, 29, 93, 95, 106, 133, 83, 189, 177 } /* left = v */,
+ { 54, 19, 29, 136, 181, 157, 80, 67, 47 } /* left = h */,
+ { 44, 26, 34, 83, 125, 180, 116, 218, 206 } /* left = d45 */,
+ { 56, 41, 25, 118, 55, 192, 93, 121, 22 } /* left = d135 */,
+ { 44, 31, 30, 110, 67, 80, 56, 217, 225 } /* left = d117 */,
+ { 44, 14, 25, 101, 105, 136, 57, 83, 133 } /* left = d153 */,
+ { 62, 16, 28, 105, 157, 164, 67, 92, 58 } /* left = d27 */,
+ { 36, 18, 25, 57, 88, 113, 59, 210, 127 } /* left = d63 */,
+ { 36, 41, 44, 79, 104, 129, 100, 151, 105 } /* left = tm */
+ }, { /* above = tm */
+ { 90, 61, 68, 152, 141, 209, 79, 59, 93 } /* left = dc */,
+ { 49, 71, 127, 132, 129, 187, 89, 105, 113 } /* left = v */,
+ { 48, 29, 26, 190, 225, 190, 55, 32, 75 } /* left = h */,
+ { 58, 51, 46, 110, 134, 192, 124, 100, 113 } /* left = d45 */,
+ { 69, 60, 38, 156, 82, 214, 79, 89, 24 } /* left = d135 */,
+ { 48, 54, 50, 139, 71, 106, 77, 162, 18 } /* left = d117 */,
+ { 52, 34, 33, 137, 149, 184, 45, 67, 169 } /* left = d153 */,
+ { 67, 29, 32, 123, 176, 244, 47, 27, 31 } /* left = d27 */,
+ { 38, 43, 46, 93, 106, 140, 78, 143, 111 } /* left = d63 */,
+ { 55, 98, 50, 135, 140, 208, 95, 103, 95 } /* left = tm */
+ }
};
diff --git a/vp9/common/vp9_mvref_common.c b/vp9/common/vp9_mvref_common.c
index f79d1c0..0a829d2 100644
--- a/vp9/common/vp9_mvref_common.c
+++ b/vp9/common/vp9_mvref_common.c
@@ -11,27 +11,34 @@
#include "vp9/common/vp9_mvref_common.h"
#define MVREF_NEIGHBOURS 8
-
-static int b_mv_ref_search[MVREF_NEIGHBOURS][2] = {
- {0, -1}, {-1, 0}, {-1, -1}, {0, -2},
- {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}
+static int mv_ref_blocks[BLOCK_SIZE_TYPES][MVREF_NEIGHBOURS][2] = {
+ // SB4X4
+ {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}},
+ // SB4X8
+ {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}},
+ // SB8X4
+ {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}},
+ // SB8X8
+ {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}},
+ // SB8X16
+ {{-1, 0}, {0, -1}, {-1, 1}, {-1, -1}, {-2, 0}, {0, -2}, {-1, -2}, {-2, -1}},
+ // SB16X8
+ {{0, -1}, {-1, 0}, {1, -1}, {-1, -1}, {0, -2}, {-2, 0}, {-2, -1}, {-1, -2}},
+ // SB16X16
+ {{0, -1}, {-1, 0}, {1, -1}, {-1, 1}, {-1, -1}, {0, -3}, {-3, 0}, {-3, -3}},
+ // SB16X32
+ {{-1, 0}, {0, -1}, {-1, 2}, {-1, -1}, {1, -1}, {-3, 0}, {0, -3}, {-3, -3}},
+ // SB32X16
+ {{0, -1}, {-1, 0}, {2, -1}, {-1, -1}, {-1, 1}, {0, -3}, {-3, 0}, {-3, -3}},
+ // SB32X32
+ {{1, -1}, {-1, 1}, {2, -1}, {-1, 2}, {-1, -1}, {0, -3}, {-3, 0}, {-3, -3}},
+ // SB32X64
+ {{-1, 0}, {0, -1}, {-1, 4}, {2, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-1, 2}},
+ // SB64X32
+ {{0, -1}, {-1, 0}, {4, -1}, {-1, 2}, {-1, -1}, {0, -3}, {-3, 0}, {2, -1}},
+ // SB64X64
+ {{3, -1}, {-1, 3}, {4, -1}, {-1, 4}, {-1, -1}, {0, -1}, {-1, 0}, {6, -1}}
};
-
-static int mb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
- {0, -1}, {-1, 0}, {-1, -1}, {0, -3},
- {-3, 0}, {-1, -3}, {-3, -1}, {-3, -3}
-};
-
-static int sb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
- {0, -1}, {-1, 0}, {2, -1}, {-1, 2},
- {-1, -1}, {0, -3}, {-3, 0}, {-1, -3}
-};
-
-static int sb64_mv_ref_search[MVREF_NEIGHBOURS][2] = {
- {0, -1}, {-1, 0}, {2, -1}, {-1, 2},
- {4, -1}, {-1, 4}, {6, -1}, {-1, -1}
-};
-
// clamp_mv_ref
#define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units
@@ -42,17 +49,17 @@
xd->mb_to_bottom_edge + MV_BORDER);
}
-// Gets a candidate refenence motion vector from the given mode info
+// Gets a candidate reference motion vector from the given mode info
// structure if one exists that matches the given reference frame.
static int get_matching_candidate(const MODE_INFO *candidate_mi,
MV_REFERENCE_FRAME ref_frame,
int_mv *c_mv, int block_idx) {
- if (ref_frame == candidate_mi->mbmi.ref_frame) {
+ if (ref_frame == candidate_mi->mbmi.ref_frame[0]) {
if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[0].as_int;
else
c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
- } else if (ref_frame == candidate_mi->mbmi.second_ref_frame) {
+ } else if (ref_frame == candidate_mi->mbmi.ref_frame[1]) {
if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[1].as_int;
else
@@ -64,7 +71,7 @@
return 1;
}
-// Gets candidate refenence motion vector(s) from the given mode info
+// Gets candidate reference motion vector(s) from the given mode info
// structure if they exists and do NOT match the given reference frame.
static void get_non_matching_candidates(const MODE_INFO *candidate_mi,
MV_REFERENCE_FRAME ref_frame,
@@ -79,18 +86,18 @@
*c2_ref_frame = INTRA_FRAME;
// If first candidate not valid neither will be.
- if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) {
+ if (candidate_mi->mbmi.ref_frame[0] > INTRA_FRAME) {
// First candidate
- if (candidate_mi->mbmi.ref_frame != ref_frame) {
- *c_ref_frame = candidate_mi->mbmi.ref_frame;
+ if (candidate_mi->mbmi.ref_frame[0] != ref_frame) {
+ *c_ref_frame = candidate_mi->mbmi.ref_frame[0];
c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
}
// Second candidate
- if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
- (candidate_mi->mbmi.second_ref_frame != ref_frame) &&
+ if ((candidate_mi->mbmi.ref_frame[1] > INTRA_FRAME) &&
+ (candidate_mi->mbmi.ref_frame[1] != ref_frame) &&
(candidate_mi->mbmi.mv[1].as_int != candidate_mi->mbmi.mv[0].as_int)) {
- *c2_ref_frame = candidate_mi->mbmi.second_ref_frame;
+ *c2_ref_frame = candidate_mi->mbmi.ref_frame[1];
c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
}
}
@@ -154,25 +161,48 @@
vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
vpx_memset(candidate_scores, 0, sizeof(candidate_scores));
- if (mbmi->sb_type == BLOCK_SIZE_SB64X64) {
- mv_ref_search = sb64_mv_ref_search;
- } else if (mbmi->sb_type >= BLOCK_SIZE_SB32X32) {
- mv_ref_search = sb_mv_ref_search;
- } else if (mbmi->sb_type >= BLOCK_SIZE_MB16X16) {
- mv_ref_search = mb_mv_ref_search;
- } else {
- mv_ref_search = b_mv_ref_search;
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
+ int pixels_wide = 4 * b_width_log2(mbmi->sb_type);
+ int pixels_high = 4 * b_height_log2(mbmi->sb_type);
+ int pixels_square = 0;
+
+ if (xd->mb_to_right_edge < 0)
+ pixels_wide += (xd->mb_to_right_edge >> 3);
+
+ if (xd->mb_to_bottom_edge < 0)
+ pixels_high += (xd->mb_to_bottom_edge >> 3);
+
+ if ( pixels_wide < pixels_high )
+ pixels_square = pixels_wide;
+ else
+ pixels_square = pixels_high;
+
+ if (pixels_square == 64) {
+ mv_ref_search = mv_ref_blocks[BLOCK_SIZE_SB64X64];
+ } else if (pixels_square == 32) {
+ mv_ref_search = mv_ref_blocks[BLOCK_SIZE_SB32X32];
+ } else if (pixels_square == 16) {
+ mv_ref_search = mv_ref_blocks[BLOCK_SIZE_MB16X16];
+ } else {
+ mv_ref_search = mv_ref_blocks[BLOCK_SIZE_SB8X8];
+ if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
+ x_idx = block_idx & 1;
+ y_idx = block_idx >> 1;
+ }
+ }
+ }
+ else {
+ mv_ref_search = mv_ref_blocks[mbmi->sb_type];
if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
x_idx = block_idx & 1;
y_idx = block_idx >> 1;
- }
+ }
}
// We first scan for candidate vectors that match the current reference frame
// Look at nearest neigbours
for (i = 0; i < 2; ++i) {
const int mi_search_col = mi_col + mv_ref_search[i][0];
-
if ((mi_search_col >= cm->cur_tile_mi_col_start) &&
(mi_search_col < cm->cur_tile_mi_col_end) &&
((mv_ref_search[i][1] << 6) >= xd->mb_to_top_edge)) {
@@ -194,7 +224,7 @@
&refmv_count, c_refmv, 16);
}
split_count += (candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8 &&
- candidate_mi->mbmi.ref_frame != INTRA_FRAME);
+ candidate_mi->mbmi.ref_frame[0] != INTRA_FRAME);
// Count number of neihgbours coded intra and zeromv
intra_count += (candidate_mi->mbmi.mode < NEARESTMV);
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index cbe010a..dedda20 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -26,8 +26,6 @@
/* Create/destroy static data structures. */
-void vp9_initialize_common(void);
-
// Define the number of candidate reference buffers.
#define NUM_REF_FRAMES 8
#define NUM_REF_FRAMES_LG2 3
@@ -42,23 +40,22 @@
#define NUM_FRAME_CONTEXTS_LG2 2
#define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LG2)
-#define COMP_PRED_CONTEXTS 2
-
#define MAX_LAG_BUFFERS 25
typedef struct frame_contexts {
- vp9_prob y_mode_prob[VP9_INTRA_MODES - 1]; /* interframe intra mode probs */
+ vp9_prob y_mode_prob[BLOCK_SIZE_GROUPS][VP9_INTRA_MODES - 1];
vp9_prob uv_mode_prob[VP9_INTRA_MODES][VP9_INTRA_MODES - 1];
- vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
+ vp9_prob partition_prob[NUM_FRAME_TYPES][NUM_PARTITION_CONTEXTS]
+ [PARTITION_TYPES - 1];
nmv_context nmvc;
nmv_context pre_nmvc;
/* interframe intra mode probs */
- vp9_prob pre_y_mode_prob[VP9_INTRA_MODES - 1];
+ vp9_prob pre_y_mode_prob[BLOCK_SIZE_GROUPS][VP9_INTRA_MODES - 1];
vp9_prob pre_uv_mode_prob[VP9_INTRA_MODES][VP9_INTRA_MODES - 1];
vp9_prob pre_partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
/* interframe intra mode probs */
- unsigned int y_mode_counts[VP9_INTRA_MODES];
+ unsigned int y_mode_counts[BLOCK_SIZE_GROUPS][VP9_INTRA_MODES];
unsigned int uv_mode_counts[VP9_INTRA_MODES][VP9_INTRA_MODES];
unsigned int partition_counts[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
@@ -71,9 +68,32 @@
nmv_context_counts NMVcount;
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS - 1];
+ vp9_prob pre_switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
+ [VP9_SWITCHABLE_FILTERS - 1];
+ unsigned int switchable_interp_count[VP9_SWITCHABLE_FILTERS + 1]
+ [VP9_SWITCHABLE_FILTERS];
- int vp9_mode_contexts[INTER_MODE_CONTEXTS][VP9_MVREFS - 1];
- unsigned int mv_ref_ct[INTER_MODE_CONTEXTS][VP9_MVREFS - 1][2];
+ vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
+ vp9_prob pre_inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
+ unsigned int inter_mode_counts[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2];
+
+ vp9_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
+ vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS];
+ vp9_prob single_ref_prob[REF_CONTEXTS][2];
+ vp9_prob comp_ref_prob[REF_CONTEXTS];
+ vp9_prob pre_intra_inter_prob[INTRA_INTER_CONTEXTS];
+ vp9_prob pre_comp_inter_prob[COMP_INTER_CONTEXTS];
+ vp9_prob pre_single_ref_prob[REF_CONTEXTS][2];
+ vp9_prob pre_comp_ref_prob[REF_CONTEXTS];
+ unsigned int intra_inter_count[INTRA_INTER_CONTEXTS][2];
+ unsigned int comp_inter_count[COMP_INTER_CONTEXTS][2];
+ unsigned int single_ref_count[REF_CONTEXTS][2][2];
+ unsigned int comp_ref_count[REF_CONTEXTS][2];
+ vp9_prob tx_probs[TX_SIZE_PROBS];
+ vp9_prob pre_tx_probs[TX_SIZE_PROBS];
+ unsigned int tx_count_32x32p[TX_SIZE_MAX_SB];
+ unsigned int tx_count_16x16p[TX_SIZE_MAX_SB - 1];
+ unsigned int tx_count_8x8p[TX_SIZE_MAX_SB - 2];
} FRAME_CONTEXT;
typedef enum {
@@ -158,7 +178,6 @@
/* profile settings */
int experimental;
TXFM_MODE txfm_mode;
- COMPPREDMODE_TYPE comp_pred_mode;
int no_lpf;
int use_bilinear_mc_filter;
@@ -215,23 +234,15 @@
[VP9_INTRA_MODES - 1];
vp9_prob kf_uv_mode_prob[VP9_INTRA_MODES] [VP9_INTRA_MODES - 1];
- vp9_prob prob_intra_coded;
- vp9_prob prob_last_coded;
- vp9_prob prob_gf_coded;
-
// 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
- unsigned char ref_scores[MAX_REF_FRAMES];
- vp9_prob ref_pred_probs[PREDICTION_PROBS];
- vp9_prob mod_refprobs[MAX_REF_FRAMES][PREDICTION_PROBS];
-
- vp9_prob prob_comppred[COMP_PRED_CONTEXTS];
-
- // FIXME contextualize
- vp9_prob prob_tx[TX_SIZE_MAX_SB - 1];
+ int allow_comp_inter_inter;
+ MV_REFERENCE_FRAME comp_fixed_ref;
+ MV_REFERENCE_FRAME comp_var_ref[2];
+ COMPPREDMODE_TYPE comp_pred_mode;
vp9_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
@@ -243,9 +254,6 @@
int near_boffset[3];
int version;
-#ifdef PACKET_TESTING
- VP9_HEADER oh;
-#endif
double bitrate;
double framerate;
diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c
index 459e9d5..73c7278 100644
--- a/vp9/common/vp9_pred_common.c
+++ b/vp9/common/vp9_pred_common.c
@@ -26,6 +26,8 @@
const MODE_INFO *const mi = xd->mode_info_context;
const MODE_INFO *const above_mi = mi - cm->mode_info_stride;
const MODE_INFO *const left_mi = mi - 1;
+ const int left_in_image = xd->left_available && left_mi->mbmi.mb_in_image;
+ const int above_in_image = xd->up_available && above_mi->mbmi.mb_in_image;
// Note:
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
@@ -37,19 +39,6 @@
pred_context += left_mi->mbmi.seg_id_predicted;
break;
- case PRED_REF:
- pred_context = above_mi->mbmi.ref_predicted;
- if (xd->left_available)
- pred_context += left_mi->mbmi.ref_predicted;
- break;
-
- case PRED_COMP:
- if (mi->mbmi.ref_frame == LAST_FRAME)
- pred_context = 0;
- else
- pred_context = 1;
- break;
-
case PRED_MBSKIP:
pred_context = above_mi->mbmi.mb_skip_coeff;
if (xd->left_available)
@@ -58,14 +47,12 @@
case PRED_SWITCHABLE_INTERP: {
// left
- const int left_in_image = xd->left_available && left_mi->mbmi.mb_in_image;
const int left_mv_pred = is_inter_mode(left_mi->mbmi.mode);
const int left_interp = left_in_image && left_mv_pred ?
vp9_switchable_interp_map[left_mi->mbmi.interp_filter] :
VP9_SWITCHABLE_FILTERS;
// above
- const int above_in_image = xd->up_available && above_mi->mbmi.mb_in_image;
const int above_mv_pred = is_inter_mode(above_mi->mbmi.mode);
const int above_interp = above_in_image && above_mv_pred ?
vp9_switchable_interp_map[above_mi->mbmi.interp_filter] :
@@ -88,7 +75,281 @@
break;
}
+ case PRED_INTRA_INTER: {
+ if (above_in_image && left_in_image) { // both edges available
+ if (left_mi->mbmi.ref_frame[0] == INTRA_FRAME &&
+ above_mi->mbmi.ref_frame[0] == INTRA_FRAME) { // intra/intra (3)
+ pred_context = 3;
+ } else { // intra/inter (1) or inter/inter (0)
+ pred_context = left_mi->mbmi.ref_frame[0] == INTRA_FRAME ||
+ above_mi->mbmi.ref_frame[0] == INTRA_FRAME;
+ }
+ } else if (above_in_image || left_in_image) { // one edge available
+ const MODE_INFO *edge = above_in_image ? above_mi : left_mi;
+
+ // inter: 0, intra: 2
+ pred_context = 2 * (edge->mbmi.ref_frame[0] == INTRA_FRAME);
+ } else {
+ pred_context = 0;
+ }
+ assert(pred_context >= 0 && pred_context < INTRA_INTER_CONTEXTS);
+ break;
+ }
+
+ case PRED_COMP_INTER_INTER: {
+ if (above_in_image && left_in_image) { // both edges available
+ if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ // neither edge uses comp pred (0/1)
+ pred_context = ((above_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref) ^
+ (left_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref));
+ } else if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ // one of two edges uses comp pred (2/3)
+ pred_context = 2 +
+ (above_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref ||
+ above_mi->mbmi.ref_frame[0] == INTRA_FRAME);
+ } else if (left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ // one of two edges uses comp pred (2/3)
+ pred_context = 2 +
+ (left_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref ||
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME);
+ } else { // both edges use comp pred (4)
+ pred_context = 4;
+ }
+ } else if (above_in_image || left_in_image) { // one edge available
+ const MODE_INFO *edge = above_in_image ? above_mi : left_mi;
+
+ if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ // edge does not use comp pred (0/1)
+ pred_context = edge->mbmi.ref_frame[0] == cm->comp_fixed_ref;
+ } else { // edge uses comp pred (3)
+ pred_context = 3;
+ }
+ } else { // no edges available (1)
+ pred_context = 1;
+ }
+ assert(pred_context >= 0 && pred_context < COMP_INTER_CONTEXTS);
+ break;
+ }
+
+ case PRED_COMP_REF_P: {
+ const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
+ const int var_ref_idx = !fix_ref_idx;
+
+ if (above_in_image && left_in_image) { // both edges available
+ if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { // intra/intra (2)
+ pred_context = 2;
+ } else if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME ||
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { // intra/inter
+ const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == INTRA_FRAME ?
+ left_mi : above_mi;
+
+ if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { // single pred (1/3)
+ pred_context = 1 +
+ 2 * edge->mbmi.ref_frame[0] != cm->comp_var_ref[1];
+ } else { // comp pred (1/3)
+ pred_context = 1 +
+ 2 * edge->mbmi.ref_frame[var_ref_idx] != cm->comp_var_ref[1];
+ }
+ } else { // inter/inter
+ int l_sg = left_mi->mbmi.ref_frame[1] <= INTRA_FRAME;
+ int a_sg = above_mi->mbmi.ref_frame[1] <= INTRA_FRAME;
+ MV_REFERENCE_FRAME vrfa = a_sg ? above_mi->mbmi.ref_frame[0] :
+ above_mi->mbmi.ref_frame[var_ref_idx];
+ MV_REFERENCE_FRAME vrfl = l_sg ? left_mi->mbmi.ref_frame[0] :
+ left_mi->mbmi.ref_frame[var_ref_idx];
+
+ if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
+ pred_context = 0;
+ } else if (l_sg && a_sg) { // single/single
+ if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
+ (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0])) {
+ pred_context = 4;
+ } else if (vrfa == vrfl) {
+ pred_context = 3;
+ } else {
+ pred_context = 1;
+ }
+ } else if (l_sg || a_sg) { // single/comp
+ MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
+ MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
+
+ if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1]) {
+ pred_context = 1;
+ } else if (rfs == cm->comp_var_ref[1] &&
+ vrfc != cm->comp_var_ref[1]) {
+ pred_context = 2;
+ } else {
+ pred_context = 4;
+ }
+ } else if (vrfa == vrfl) { // comp/comp
+ pred_context = 4;
+ } else {
+ pred_context = 2;
+ }
+ }
+ } else if (above_in_image || left_in_image) { // one edge available
+ const MODE_INFO *edge = above_in_image ? above_mi : left_mi;
+
+ if (edge->mbmi.ref_frame[0] == INTRA_FRAME) {
+ pred_context = 2;
+ } else if (edge->mbmi.ref_frame[1] > INTRA_FRAME) {
+ pred_context =
+ 4 * edge->mbmi.ref_frame[var_ref_idx] != cm->comp_var_ref[1];
+ } else {
+ pred_context = 3 * edge->mbmi.ref_frame[0] != cm->comp_var_ref[1];
+ }
+ } else { // no edges available (2)
+ pred_context = 2;
+ }
+ assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
+ break;
+ }
+
+ case PRED_SINGLE_REF_P1: {
+ if (above_in_image && left_in_image) { // both edges available
+ if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME) {
+ pred_context = 2;
+ } else if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME ||
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME) {
+ const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == INTRA_FRAME ?
+ left_mi : above_mi;
+
+ if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ pred_context = 4 * (edge->mbmi.ref_frame[0] == LAST_FRAME);
+ } else {
+ pred_context = 1 + (edge->mbmi.ref_frame[0] == LAST_FRAME ||
+ edge->mbmi.ref_frame[1] == LAST_FRAME);
+ }
+ } else if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ pred_context = 2 * (above_mi->mbmi.ref_frame[0] == LAST_FRAME) +
+ 2 * (left_mi->mbmi.ref_frame[0] == LAST_FRAME);
+ } else if (above_mi->mbmi.ref_frame[1] > INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[1] > INTRA_FRAME) {
+ pred_context = 1 + (above_mi->mbmi.ref_frame[0] == LAST_FRAME ||
+ above_mi->mbmi.ref_frame[1] == LAST_FRAME ||
+ left_mi->mbmi.ref_frame[0] == LAST_FRAME ||
+ left_mi->mbmi.ref_frame[1] == LAST_FRAME);
+ } else {
+ MV_REFERENCE_FRAME rfs = above_mi->mbmi.ref_frame[1] <= INTRA_FRAME ?
+ above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0];
+ MV_REFERENCE_FRAME crf1 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ?
+ above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0];
+ MV_REFERENCE_FRAME crf2 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ?
+ above_mi->mbmi.ref_frame[1] : left_mi->mbmi.ref_frame[1];
+
+ if (rfs == LAST_FRAME) {
+ pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
+ } else {
+ pred_context = crf1 == LAST_FRAME || crf2 == LAST_FRAME;
+ }
+ }
+ } else if (above_in_image || left_in_image) { // one edge available
+ const MODE_INFO *edge = above_in_image ? above_mi : left_mi;
+
+ if (edge->mbmi.ref_frame[0] == INTRA_FRAME) {
+ pred_context = 2;
+ } else if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ pred_context = 4 * (edge->mbmi.ref_frame[0] == LAST_FRAME);
+ } else {
+ pred_context = 1 + (edge->mbmi.ref_frame[0] == LAST_FRAME ||
+ edge->mbmi.ref_frame[1] == LAST_FRAME);
+ }
+ } else { // no edges available (2)
+ pred_context = 2;
+ }
+ assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
+ break;
+ }
+
+ case PRED_SINGLE_REF_P2: {
+ if (above_in_image && left_in_image) { // both edges available
+ if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME) {
+ pred_context = 2;
+ } else if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME ||
+ left_mi->mbmi.ref_frame[0] == INTRA_FRAME) {
+ const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == INTRA_FRAME ?
+ left_mi : above_mi;
+
+ if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ if (edge->mbmi.ref_frame[0] == LAST_FRAME) {
+ pred_context = 3;
+ } else {
+ pred_context = 4 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME);
+ }
+ } else {
+ pred_context = 1 + 2 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME ||
+ edge->mbmi.ref_frame[1] == GOLDEN_FRAME);
+ }
+ } else if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ if (above_mi->mbmi.ref_frame[0] == LAST_FRAME &&
+ left_mi->mbmi.ref_frame[0] == LAST_FRAME) {
+ pred_context = 3;
+ } else if (above_mi->mbmi.ref_frame[0] == LAST_FRAME ||
+ left_mi->mbmi.ref_frame[0] == LAST_FRAME) {
+ const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == LAST_FRAME ?
+ left_mi : above_mi;
+
+ pred_context = 4 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME);
+ } else {
+ pred_context = 2 * (above_mi->mbmi.ref_frame[0] == GOLDEN_FRAME) +
+ 2 * (left_mi->mbmi.ref_frame[0] == GOLDEN_FRAME);
+ }
+ } else if (above_mi->mbmi.ref_frame[1] > INTRA_FRAME &&
+ left_mi->mbmi.ref_frame[1] > INTRA_FRAME) {
+ if (above_mi->mbmi.ref_frame[0] == left_mi->mbmi.ref_frame[0] &&
+ above_mi->mbmi.ref_frame[1] == left_mi->mbmi.ref_frame[1]) {
+ pred_context = 3 * (above_mi->mbmi.ref_frame[0] == GOLDEN_FRAME ||
+ above_mi->mbmi.ref_frame[1] == GOLDEN_FRAME ||
+ left_mi->mbmi.ref_frame[0] == GOLDEN_FRAME ||
+ left_mi->mbmi.ref_frame[1] == GOLDEN_FRAME);
+ } else {
+ pred_context = 2;
+ }
+ } else {
+ MV_REFERENCE_FRAME rfs = above_mi->mbmi.ref_frame[1] <= INTRA_FRAME ?
+ above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0];
+ MV_REFERENCE_FRAME crf1 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ?
+ above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0];
+ MV_REFERENCE_FRAME crf2 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ?
+ above_mi->mbmi.ref_frame[1] : left_mi->mbmi.ref_frame[1];
+
+ if (rfs == GOLDEN_FRAME) {
+ pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
+ } else if (rfs == ALTREF_FRAME) {
+ pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME;
+ } else {
+ pred_context =
+ 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
+ }
+ }
+ } else if (above_in_image || left_in_image) { // one edge available
+ const MODE_INFO *edge = above_in_image ? above_mi : left_mi;
+
+ if (edge->mbmi.ref_frame[0] == INTRA_FRAME ||
+ (edge->mbmi.ref_frame[0] == LAST_FRAME &&
+ edge->mbmi.ref_frame[1] <= INTRA_FRAME)) {
+ pred_context = 2;
+ } else if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) {
+ pred_context = 4 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME);
+ } else {
+ pred_context = 3 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME ||
+ edge->mbmi.ref_frame[1] == GOLDEN_FRAME);
+ }
+ } else { // no edges available (2)
+ pred_context = 2;
+ }
+ assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
+ break;
+ }
+
default:
+ assert(0);
pred_context = 0; // *** add error trap code.
break;
}
@@ -106,16 +367,20 @@
switch (pred_id) {
case PRED_SEG_ID:
return cm->segment_pred_probs[pred_context];
- case PRED_REF:
- return cm->ref_pred_probs[pred_context];
- case PRED_COMP:
- // In keeping with convention elsewhre the probability returned is
- // the probability of a "0" outcome which in this case means the
- // probability of comp pred off.
- return cm->prob_comppred[pred_context];
case PRED_MBSKIP:
return cm->mbskip_pred_probs[pred_context];
+ case PRED_INTRA_INTER:
+ return cm->fc.intra_inter_prob[pred_context];
+ case PRED_COMP_INTER_INTER:
+ return cm->fc.comp_inter_prob[pred_context];
+ case PRED_COMP_REF_P:
+ return cm->fc.comp_ref_prob[pred_context];
+ case PRED_SINGLE_REF_P1:
+ return cm->fc.single_ref_prob[pred_context][0];
+ case PRED_SINGLE_REF_P2:
+ return cm->fc.single_ref_prob[pred_context][1];
default:
+ assert(0);
return 128; // *** add error trap code.
}
}
@@ -128,20 +393,10 @@
const int pred_context = vp9_get_pred_context(cm, xd, pred_id);
switch (pred_id) {
- case PRED_SEG_ID:
- return &cm->segment_pred_probs[pred_context];
- case PRED_REF:
- return &cm->ref_pred_probs[pred_context];
- case PRED_COMP:
- // In keeping with convention elsewhre the probability returned is
- // the probability of a "0" outcome which in this case means the
- // probability of comp pred off.
- return &cm->prob_comppred[pred_context];
- case PRED_MBSKIP:
- return &cm->mbskip_pred_probs[pred_context];
case PRED_SWITCHABLE_INTERP:
return &cm->fc.switchable_interp_prob[pred_context][0];
default:
+ assert(0);
return NULL; // *** add error trap code.
}
}
@@ -153,11 +408,10 @@
switch (pred_id) {
case PRED_SEG_ID:
return xd->mode_info_context->mbmi.seg_id_predicted;
- case PRED_REF:
- return xd->mode_info_context->mbmi.ref_predicted;
case PRED_MBSKIP:
return xd->mode_info_context->mbmi.mb_skip_coeff;
default:
+ assert(0);
return 0; // *** add error trap code.
}
}
@@ -186,14 +440,6 @@
}
break;
- case PRED_REF:
- for (y = 0; y < y_mis; y++) {
- for (x = 0; x < x_mis; x++) {
- xd->mode_info_context[y * mis + x].mbmi.ref_predicted = pred_flag;
- }
- }
- break;
-
case PRED_MBSKIP:
for (y = 0; y < y_mis; y++) {
for (x = 0; x < x_mis; x++) {
@@ -203,6 +449,7 @@
break;
default:
+ assert(0);
// *** add error trap code.
break;
}
@@ -231,138 +478,3 @@
}
return segment_id;
}
-
-MV_REFERENCE_FRAME vp9_get_pred_ref(const VP9_COMMON *const cm,
- const MACROBLOCKD *const xd) {
- MODE_INFO *m = xd->mode_info_context;
-
- MV_REFERENCE_FRAME left;
- MV_REFERENCE_FRAME above;
- MV_REFERENCE_FRAME above_left;
- MV_REFERENCE_FRAME pred_ref = LAST_FRAME;
-
- int segment_id = xd->mode_info_context->mbmi.segment_id;
- int i;
-
- unsigned char frame_allowed[MAX_REF_FRAMES] = {1, 1, 1, 1};
- unsigned char ref_score[MAX_REF_FRAMES];
- unsigned char best_score = 0;
- unsigned char left_in_image;
- unsigned char above_in_image;
- unsigned char above_left_in_image;
-
- // Is segment coding ennabled
- int seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);
-
- // Special case treatment if segment coding is enabled.
- // Dont allow prediction of a reference frame that the segment
- // does not allow
- if (seg_ref_active) {
- for (i = 0; i < MAX_REF_FRAMES; i++) {
- frame_allowed[i] =
- vp9_check_segref(xd, segment_id, i);
-
- // Score set to 0 if ref frame not allowed
- ref_score[i] = cm->ref_scores[i] * frame_allowed[i];
- }
- } else
- vpx_memcpy(ref_score, cm->ref_scores, sizeof(ref_score));
-
- // Reference frames used by neighbours
- left = (m - 1)->mbmi.ref_frame;
- above = (m - cm->mode_info_stride)->mbmi.ref_frame;
- above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame;
-
- // Are neighbours in image
- left_in_image = (m - 1)->mbmi.mb_in_image && xd->left_available;
- above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
- above_left_in_image = (m - 1 - cm->mode_info_stride)->mbmi.mb_in_image &&
- xd->left_available;
-
- // Adjust scores for candidate reference frames based on neigbours
- if (frame_allowed[left] && left_in_image) {
- ref_score[left] += 16;
- if (above_left_in_image && (left == above_left))
- ref_score[left] += 4;
- }
- if (frame_allowed[above] && above_in_image) {
- ref_score[above] += 16;
- if (above_left_in_image && (above == above_left))
- ref_score[above] += 4;
- }
-
- // Now choose the candidate with the highest score
- for (i = 0; i < MAX_REF_FRAMES; i++) {
- if (ref_score[i] > best_score) {
- pred_ref = i;
- best_score = ref_score[i];
- }
- }
-
- return pred_ref;
-}
-
-// Functions to computes a set of modified reference frame probabilities
-// to use when the prediction of the reference frame value fails
-void vp9_calc_ref_probs(int *count, vp9_prob *probs) {
- int tot_count = count[0] + count[1] + count[2] + count[3];
- probs[0] = get_prob(count[0], tot_count);
-
- tot_count -= count[0];
- probs[1] = get_prob(count[1], tot_count);
-
- tot_count -= count[1];
- probs[2] = get_prob(count[2], tot_count);
-}
-
-// Computes a set of modified conditional probabilities for the reference frame
-// Values willbe set to 0 for reference frame options that are not possible
-// because wither they were predicted and prediction has failed or because
-// they are not allowed for a given segment.
-void vp9_compute_mod_refprobs(VP9_COMMON *const cm) {
- int norm_cnt[MAX_REF_FRAMES];
- const int intra_count = cm->prob_intra_coded;
- const int inter_count = (255 - intra_count);
- const int last_count = (inter_count * cm->prob_last_coded) / 255;
- const int gfarf_count = inter_count - last_count;
- const int gf_count = (gfarf_count * cm->prob_gf_coded) / 255;
- const int arf_count = gfarf_count - gf_count;
-
- // Work out modified reference frame probabilities to use where prediction
- // of the reference frame fails
- norm_cnt[0] = 0;
- norm_cnt[1] = last_count;
- norm_cnt[2] = gf_count;
- norm_cnt[3] = arf_count;
- vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[INTRA_FRAME]);
- cm->mod_refprobs[INTRA_FRAME][0] = 0; // This branch implicit
-
- norm_cnt[0] = intra_count;
- norm_cnt[1] = 0;
- norm_cnt[2] = gf_count;
- norm_cnt[3] = arf_count;
- vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[LAST_FRAME]);
- cm->mod_refprobs[LAST_FRAME][1] = 0; // This branch implicit
-
- norm_cnt[0] = intra_count;
- norm_cnt[1] = last_count;
- norm_cnt[2] = 0;
- norm_cnt[3] = arf_count;
- vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[GOLDEN_FRAME]);
- cm->mod_refprobs[GOLDEN_FRAME][2] = 0; // This branch implicit
-
- norm_cnt[0] = intra_count;
- norm_cnt[1] = last_count;
- norm_cnt[2] = gf_count;
- norm_cnt[3] = 0;
- vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[ALTREF_FRAME]);
- cm->mod_refprobs[ALTREF_FRAME][2] = 0; // This branch implicit
-
- // Score the reference frames based on overal frequency.
- // These scores contribute to the prediction choices.
- // Max score 17 min 1
- cm->ref_scores[INTRA_FRAME] = 1 + (intra_count * 16 / 255);
- cm->ref_scores[LAST_FRAME] = 1 + (last_count * 16 / 255);
- cm->ref_scores[GOLDEN_FRAME] = 1 + (gf_count * 16 / 255);
- cm->ref_scores[ALTREF_FRAME] = 1 + (arf_count * 16 / 255);
-}
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h
index afb0bfe..6d52997 100644
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -17,10 +17,13 @@
// Predicted items
typedef enum {
PRED_SEG_ID = 0, // Segment identifier
- PRED_REF = 1,
- PRED_COMP = 2,
- PRED_MBSKIP = 3,
- PRED_SWITCHABLE_INTERP = 4
+ PRED_MBSKIP = 1,
+ PRED_SWITCHABLE_INTERP = 2,
+ PRED_INTRA_INTER = 3,
+ PRED_COMP_INTER_INTER = 4,
+ PRED_SINGLE_REF_P1 = 5,
+ PRED_SINGLE_REF_P2 = 6,
+ PRED_COMP_REF_P = 7,
} PRED_ID;
unsigned char vp9_get_pred_context(const VP9_COMMON *const cm,
@@ -46,9 +49,4 @@
int vp9_get_pred_mi_segid(VP9_COMMON *cm, BLOCK_SIZE_TYPE sb_type,
int mi_row, int mi_col);
-MV_REFERENCE_FRAME vp9_get_pred_ref(const VP9_COMMON *const cm,
- const MACROBLOCKD *const xd);
-
-void vp9_compute_mod_refprobs(VP9_COMMON *const cm);
-
#endif // VP9_COMMON_VP9_PRED_COMMON_H_
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index 679cc7d..93faa8c 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -171,8 +171,8 @@
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
set_scale_factors(xd,
- mbmi->ref_frame - 1,
- mbmi->second_ref_frame - 1,
+ mbmi->ref_frame[0] - 1,
+ mbmi->ref_frame[1] - 1,
cm->active_ref_scale);
}
@@ -386,7 +386,7 @@
const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y;
const int bh = 4 << bhl, bw = 4 << bwl;
const int x = 4 * (block & ((1 << bwl) - 1)), y = 4 * (block >> bwl);
- const int use_second_ref = xd->mode_info_context->mbmi.second_ref_frame > 0;
+ const int use_second_ref = xd->mode_info_context->mbmi.ref_frame[1] > 0;
int which_mv;
assert(x < bw);
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index 4a4634b..85dfe51 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -204,6 +204,8 @@
// 129 G H .. S T T T T T
// ..
+ assert(bw == bh);
+
if (left_available) {
for (i = 0; i < bh; i++)
yleft_col[i] = src[i * src_stride - 1];
@@ -271,89 +273,22 @@
}
break;
case D45_PRED:
+ d45_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
+ break;
case D135_PRED:
+ d135_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
+ break;
case D117_PRED:
+ d117_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
+ break;
case D153_PRED:
+ d153_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
+ break;
case D27_PRED:
+ d27_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
+ break;
case D63_PRED:
- if (bw == bh) {
- switch (mode) {
- case D45_PRED:
- d45_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
- break;
- case D135_PRED:
- d135_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
- break;
- case D117_PRED:
- d117_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
- break;
- case D153_PRED:
- d153_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
- break;
- case D27_PRED:
- d27_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
- break;
- case D63_PRED:
- d63_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
- break;
- default:
- assert(0);
- }
- } else if (bw > bh) {
- uint8_t pred[64*64];
- vpx_memset(yleft_col + bh, yleft_col[bh - 1], bw - bh);
- switch (mode) {
- case D45_PRED:
- d45_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
- break;
- case D135_PRED:
- d135_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
- break;
- case D117_PRED:
- d117_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
- break;
- case D153_PRED:
- d153_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
- break;
- case D27_PRED:
- d27_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
- break;
- case D63_PRED:
- d63_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
- break;
- default:
- assert(0);
- }
- for (i = 0; i < bh; i++)
- vpx_memcpy(ypred_ptr + y_stride * i, pred + i * 64, bw);
- } else {
- uint8_t pred[64 * 64];
- vpx_memset(yabove_row + bw * 2, yabove_row[bw * 2 - 1], (bh - bw) * 2);
- switch (mode) {
- case D45_PRED:
- d45_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
- break;
- case D135_PRED:
- d135_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
- break;
- case D117_PRED:
- d117_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
- break;
- case D153_PRED:
- d153_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
- break;
- case D27_PRED:
- d27_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
- break;
- case D63_PRED:
- d63_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
- break;
- default:
- assert(0);
- }
- for (i = 0; i < bh; i++)
- vpx_memcpy(ypred_ptr + y_stride * i, pred + i * 64, bw);
- }
+ d63_predictor(ypred_ptr, y_stride, bw, bh, yabove_row, yleft_col);
break;
default:
break;
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index 7b834d7..0517e92 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -86,6 +86,25 @@
#
# Loopfilter
#
+if [ "$CONFIG_NEW_LOOPFILTER" = "yes" ]; then
+prototype void vp9_mb_lpf_vertical_edge_w "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, int count"
+specialize vp9_mb_lpf_vertical_edge_w
+
+prototype void vp9_mbloop_filter_vertical_edge "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, int count"
+specialize vp9_mbloop_filter_vertical_edge
+
+prototype void vp9_loop_filter_vertical_edge "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, int count"
+specialize vp9_loop_filter_vertical_edge
+
+prototype void vp9_mb_lpf_horizontal_edge_w "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, int count"
+specialize vp9_mb_lpf_horizontal_edge_w
+
+prototype void vp9_mbloop_filter_horizontal_edge "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, int count"
+specialize vp9_mbloop_filter_horizontal_edge
+
+prototype void vp9_loop_filter_horizontal_edge "uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, int count"
+specialize vp9_loop_filter_horizontal_edge
+else
prototype void vp9_loop_filter_mbv "uint8_t *y, uint8_t *u, uint8_t *v, int ystride, int uv_stride, struct loop_filter_info *lfi"
specialize vp9_loop_filter_mbv sse2
@@ -109,6 +128,7 @@
prototype void vp9_lpf_mbv_w "unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, int y_stride, int uv_stride, struct loop_filter_info *lfi"
specialize vp9_lpf_mbv_w sse2
+fi
#
# post proc
diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c
index 67dfeae..890dcce 100644
--- a/vp9/common/vp9_seg_common.c
+++ b/vp9/common/vp9_seg_common.c
@@ -13,7 +13,7 @@
#include "vp9/common/vp9_seg_common.h"
static const int seg_feature_data_signed[SEG_LVL_MAX] = { 1, 1, 0, 0 };
-static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ, 63, 15, 15 };
+static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ, 63, 15, 0 };
// These functions provide access to new segment level features.
// Eventually these function may be "optimized out" but for the moment,
diff --git a/vp9/decoder/vp9_dboolhuff.c b/vp9/decoder/vp9_dboolhuff.c
index 9921ea7..df77d65 100644
--- a/vp9/decoder/vp9_dboolhuff.c
+++ b/vp9/decoder/vp9_dboolhuff.c
@@ -14,6 +14,8 @@
#include "vp9/decoder/vp9_dboolhuff.h"
int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size) {
+ int marker_bit;
+
r->buffer_end = buffer + size;
r->buffer = buffer;
r->value = 0;
@@ -24,7 +26,8 @@
return 1;
vp9_reader_fill(r);
- return 0;
+ marker_bit = vp9_read_bit(r);
+ return marker_bit != 0;
}
void vp9_reader_fill(vp9_reader *r) {
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index efd852b..cb16ccd 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -20,6 +20,7 @@
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/decoder/vp9_decodemv.h"
+#include "vp9/decoder/vp9_decodframe.h"
#include "vp9/common/vp9_mvref_common.h"
#if CONFIG_DEBUG
#include <assert.h>
@@ -63,12 +64,20 @@
}
static TX_SIZE select_txfm_size(VP9_COMMON *cm, vp9_reader *r,
- int allow_16x16, int allow_32x32) {
- TX_SIZE txfm_size = vp9_read(r, cm->prob_tx[0]); // TX_4X4 or >TX_4X4
- if (txfm_size != TX_4X4 && allow_16x16) {
- txfm_size += vp9_read(r, cm->prob_tx[1]); // TX_8X8 or >TX_8X8
- if (txfm_size != TX_8X8 && allow_32x32)
- txfm_size += vp9_read(r, cm->prob_tx[2]); // TX_16X16 or >TX_16X16
+ BLOCK_SIZE_TYPE bsize) {
+ int tx_probs_offset = get_tx_probs_offset(bsize);
+ TX_SIZE txfm_size = vp9_read(r, cm->fc.tx_probs[tx_probs_offset]);
+ if (txfm_size != TX_4X4 && bsize >= BLOCK_SIZE_MB16X16) {
+ txfm_size += vp9_read(r, cm->fc.tx_probs[tx_probs_offset + 1]);
+ if (txfm_size != TX_8X8 && bsize >= BLOCK_SIZE_SB32X32)
+ txfm_size += vp9_read(r, cm->fc.tx_probs[tx_probs_offset + 2]);
+ }
+ if (bsize >= BLOCK_SIZE_SB32X32) {
+ cm->fc.tx_count_32x32p[txfm_size]++;
+ } else if (bsize >= BLOCK_SIZE_MB16X16) {
+ cm->fc.tx_count_16x16p[txfm_size]++;
+ } else {
+ cm->fc.tx_count_8x8p[txfm_size]++;
}
return txfm_size;
}
@@ -80,7 +89,6 @@
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
const int mis = cm->mode_info_stride;
- m->mbmi.ref_frame = INTRA_FRAME;
// Read segmentation map if it is being updated explicitly this frame
m->mbmi.segment_id = 0;
@@ -96,9 +104,7 @@
if (cm->txfm_mode == TX_MODE_SELECT &&
m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
- const int allow_16x16 = m->mbmi.sb_type >= BLOCK_SIZE_MB16X16;
- const int allow_32x32 = m->mbmi.sb_type >= BLOCK_SIZE_SB32X32;
- m->mbmi.txfm_size = select_txfm_size(cm, r, allow_16x16, allow_32x32);
+ m->mbmi.txfm_size = select_txfm_size(cm, r, m->mbmi.sb_type);
} else if (cm->txfm_mode >= ALLOW_32X32 &&
m->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
m->mbmi.txfm_size = TX_32X32;
@@ -113,7 +119,7 @@
}
// luma mode
- m->mbmi.ref_frame = INTRA_FRAME;
+ m->mbmi.ref_frame[0] = INTRA_FRAME;
if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
const MB_PREDICTION_MODE L = xd->left_available ?
@@ -231,17 +237,13 @@
}
// Read the referncence frame
-static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
- vp9_reader *r,
- int segment_id) {
- MV_REFERENCE_FRAME ref_frame;
+static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
+ int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
-
int seg_ref_count = 0;
const int seg_ref_active = vp9_segfeature_active(xd, segment_id,
SEG_LVL_REF_FRAME);
-
const int intra = vp9_check_segref(xd, segment_id, INTRA_FRAME);
const int last = vp9_check_segref(xd, segment_id, LAST_FRAME);
const int golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME);
@@ -255,79 +257,43 @@
// Segment reference frame features not available or allows for
// multiple reference frame options
if (!seg_ref_active || seg_ref_count > 1) {
- // Values used in prediction model coding
- MV_REFERENCE_FRAME pred_ref;
+ int is_comp;
+ int comp_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER);
- // Get the context probability the prediction flag
- vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
-
- // Read the prediction status flag
- unsigned char prediction_flag = vp9_read(r, pred_prob);
-
- // Store the prediction flag.
- vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
-
- // Get the predicted reference frame.
- pred_ref = vp9_get_pred_ref(cm, xd);
-
- // If correctly predicted then use the predicted value
- if (prediction_flag) {
- ref_frame = pred_ref;
+ if (cm->comp_pred_mode == HYBRID_PREDICTION) {
+ is_comp = vp9_read(r, cm->fc.comp_inter_prob[comp_ctx]);
+ cm->fc.comp_inter_count[comp_ctx][is_comp]++;
} else {
- // decode the explicitly coded value
- vp9_prob mod_refprobs[PREDICTION_PROBS];
- vpx_memcpy(mod_refprobs, cm->mod_refprobs[pred_ref],
- sizeof(mod_refprobs));
+ is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
+ }
- // If segment coding enabled blank out options that cant occur by
- // setting the branch probability to 0.
- if (seg_ref_active) {
- mod_refprobs[INTRA_FRAME] *= intra;
- mod_refprobs[LAST_FRAME] *= last;
- mod_refprobs[GOLDEN_FRAME] *= golden * altref;
- }
+ // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
+ if (is_comp) {
+ int b, fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
+ int ref_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_REF_P);
- // Default to INTRA_FRAME (value 0)
- ref_frame = INTRA_FRAME;
-
- // Do we need to decode the Intra/Inter branch
- if (mod_refprobs[0])
- ref_frame = vp9_read(r, mod_refprobs[0]);
- else
- ref_frame++;
-
- if (ref_frame) {
- // Do we need to decode the Last/Gf_Arf branch
- if (mod_refprobs[1])
- ref_frame += vp9_read(r, mod_refprobs[1]);
- else
- ref_frame++;
-
- if (ref_frame > 1) {
- // Do we need to decode the GF/Arf branch
- if (mod_refprobs[2]) {
- ref_frame += vp9_read(r, mod_refprobs[2]);
- } else {
- if (seg_ref_active)
- ref_frame = pred_ref == GOLDEN_FRAME || !golden ? ALTREF_FRAME
- : GOLDEN_FRAME;
- else
- ref_frame = pred_ref == GOLDEN_FRAME ? ALTREF_FRAME
- : GOLDEN_FRAME;
- }
- }
+ ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
+ b = vp9_read(r, cm->fc.comp_ref_prob[ref_ctx]);
+ cm->fc.comp_ref_count[ref_ctx][b]++;
+ ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
+ } else {
+ int ref1_ctx = vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P1);
+ ref_frame[1] = NONE;
+ if (vp9_read(r, cm->fc.single_ref_prob[ref1_ctx][0])) {
+ int ref2_ctx = vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P2);
+ int b2 = vp9_read(r, cm->fc.single_ref_prob[ref2_ctx][1]);
+ ref_frame[0] = b2 ? ALTREF_FRAME : GOLDEN_FRAME;
+ cm->fc.single_ref_count[ref1_ctx][0][1]++;
+ cm->fc.single_ref_count[ref2_ctx][1][b2]++;
+ } else {
+ ref_frame[0] = LAST_FRAME;
+ cm->fc.single_ref_count[ref1_ctx][0][0]++;
}
}
} else {
- // Segment reference frame features are enabled
- // The reference frame for the mb is considered as correclty predicted
- // if it is signaled at the segment level for the purposes of the
- // common prediction model
- vp9_set_pred_flag(xd, PRED_REF, 1);
- ref_frame = vp9_get_pred_ref(cm, xd);
+ ref_frame[0] = last ? LAST_FRAME : golden ? GOLDEN_FRAME : ALTREF_FRAME;
+ ref_frame[1] = NONE;
}
-
- return ref_frame;
}
static MB_PREDICTION_MODE read_sb_mv_ref(vp9_reader *r, const vp9_prob *p) {
@@ -344,12 +310,28 @@
};
#endif
-static void read_switchable_interp_probs(VP9D_COMP* const pbi, vp9_reader *r) {
- VP9_COMMON *const cm = &pbi->common;
+static void read_switchable_interp_probs(VP9_COMMON* const cm, vp9_reader *r) {
int i, j;
- for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j)
- for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i)
- cm->fc.switchable_interp_prob[j][i] = vp9_read_prob(r);
+ for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j)
+ for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
+ cm->fc.switchable_interp_prob[j][i] =
+ // vp9_read_prob(r);
+ vp9_read_prob_diff_update(r, cm->fc.switchable_interp_prob[j][i]);
+ }
+ }
+}
+
+static void read_inter_mode_probs(VP9_COMMON *const cm, vp9_reader *r) {
+ int i, j;
+ for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
+ for (j = 0; j < VP9_INTER_MODES - 1; ++j) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
+ // cm->fc.inter_mode_probs[i][j] = vp9_read_prob(r);
+ cm->fc.inter_mode_probs[i][j] =
+ vp9_read_prob_diff_update(r, cm->fc.inter_mode_probs[i][j]);
+ }
+ }
}
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
@@ -367,32 +349,62 @@
MACROBLOCKD *const xd = &pbi->mb;
int i, j;
+ read_inter_mode_probs(cm, r);
+
if (cm->mcomp_filter_type == SWITCHABLE)
- read_switchable_interp_probs(pbi, r);
+ read_switchable_interp_probs(cm, r);
- // Baseline probabilities for decoding reference frame
- cm->prob_intra_coded = vp9_read_prob(r);
- cm->prob_last_coded = vp9_read_prob(r);
- cm->prob_gf_coded = vp9_read_prob(r);
+ for (i = 0; i < INTRA_INTER_CONTEXTS; i++) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+ cm->fc.intra_inter_prob[i] =
+ vp9_read_prob_diff_update(r, cm->fc.intra_inter_prob[i]);
+ }
- // Computes a modified set of probabilities for use when reference
- // frame prediction fails.
- vp9_compute_mod_refprobs(cm);
+ if (cm->allow_comp_inter_inter) {
+ cm->comp_pred_mode = read_comp_pred_mode(r);
+ if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ for (i = 0; i < COMP_INTER_CONTEXTS; i++)
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+ cm->fc.comp_inter_prob[i] =
+ vp9_read_prob_diff_update(r, cm->fc.comp_inter_prob[i]);
+ } else {
+ cm->comp_pred_mode = SINGLE_PREDICTION_ONLY;
+ }
- cm->comp_pred_mode = read_comp_pred_mode(r);
- if (cm->comp_pred_mode == HYBRID_PREDICTION)
- for (i = 0; i < COMP_PRED_CONTEXTS; i++)
- cm->prob_comppred[i] = vp9_read_prob(r);
+ if (cm->comp_pred_mode != COMP_PREDICTION_ONLY)
+ for (i = 0; i < REF_CONTEXTS; i++) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+ cm->fc.single_ref_prob[i][0] =
+ vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][0]);
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+ cm->fc.single_ref_prob[i][1] =
+ vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][1]);
+ }
+
+ if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
+ for (i = 0; i < REF_CONTEXTS; i++)
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+ cm->fc.comp_ref_prob[i] =
+ vp9_read_prob_diff_update(r, cm->fc.comp_ref_prob[i]);
// VP9_INTRA_MODES
- if (vp9_read_bit(r))
- for (i = 0; i < VP9_INTRA_MODES - 1; ++i)
- cm->fc.y_mode_prob[i] = vp9_read_prob(r);
-
- for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j)
- if (vp9_read_bit(r))
- for (i = 0; i < PARTITION_TYPES - 1; ++i)
- cm->fc.partition_prob[j][i] = vp9_read_prob(r);
+ for (j = 0; j < BLOCK_SIZE_GROUPS; j++) {
+ for (i = 0; i < VP9_INTRA_MODES - 1; ++i) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
+ cm->fc.y_mode_prob[j][i] =
+ vp9_read_prob_diff_update(r, cm->fc.y_mode_prob[j][i]);
+ }
+ }
+ }
+ for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j) {
+ for (i = 0; i < PARTITION_TYPES - 1; ++i) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB)) {
+ cm->fc.partition_prob[INTER_FRAME][j][i] =
+ vp9_read_prob_diff_update(r,
+ cm->fc.partition_prob[INTER_FRAME][j][i]);
+ }
+ }
+ }
read_nmvprobs(r, nmvc, xd->allow_high_precision_mv);
}
@@ -474,6 +486,9 @@
const int index = treed_read(r, vp9_switchable_interp_tree,
vp9_get_pred_probs(&pbi->common, &pbi->mb,
PRED_SWITCHABLE_INTERP));
+ ++pbi->common.fc.switchable_interp_count
+ [vp9_get_pred_context(
+ &pbi->common, &pbi->mb, PRED_SWITCHABLE_INTERP)][index];
return vp9_switchable_interp[index];
}
@@ -495,7 +510,7 @@
mbmi->need_to_clamp_mvs = 0;
mbmi->need_to_clamp_secondmv = 0;
- mbmi->second_ref_frame = NONE;
+ mbmi->ref_frame[1] = NONE;
// Make sure the MACROBLOCKD mode info pointer is pointed at the
// correct entry for the current macroblock.
@@ -521,14 +536,14 @@
mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
// Read the reference frame
- mbmi->ref_frame = read_ref_frame(pbi, r, mbmi->segment_id);
+ mbmi->ref_frame[0] = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_INTRA_INTER));
+ cm->fc.intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)]
+ [mbmi->ref_frame[0] != INTRA_FRAME]++;
if (cm->txfm_mode == TX_MODE_SELECT &&
- (mbmi->mb_skip_coeff == 0 || mbmi->ref_frame == INTRA_FRAME) &&
+ (mbmi->mb_skip_coeff == 0 || mbmi->ref_frame[0] == INTRA_FRAME) &&
bsize >= BLOCK_SIZE_SB8X8) {
- const int allow_16x16 = bsize >= BLOCK_SIZE_MB16X16;
- const int allow_32x32 = bsize >= BLOCK_SIZE_SB32X32;
- mbmi->txfm_size = select_txfm_size(cm, r, allow_16x16, allow_32x32);
+ mbmi->txfm_size = select_txfm_size(cm, r, bsize);
} else if (bsize >= BLOCK_SIZE_SB32X32 &&
cm->txfm_mode >= ALLOW_32X32) {
mbmi->txfm_size = TX_32X32;
@@ -542,11 +557,12 @@
}
// If reference frame is an Inter frame
- if (mbmi->ref_frame) {
+ if (mbmi->ref_frame[0] != INTRA_FRAME) {
int_mv nearest, nearby, best_mv;
int_mv nearest_second, nearby_second, best_mv_second;
- vp9_prob mv_ref_p[VP9_MVREFS - 1];
- const MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame;
+ vp9_prob mv_ref_p[VP9_INTER_MODES - 1];
+
+ read_ref_frame(pbi, r, mbmi->segment_id, mbmi->ref_frame);
{
#ifdef DEC_DEBUG
@@ -554,25 +570,27 @@
printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
xd->mode_info_context->mbmi.mv[0].as_mv.col);
#endif
- vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context, ref_frame,
- mbmi->ref_mvs[ref_frame], cm->ref_frame_sign_bias);
+ vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
+ mbmi->ref_frame[0], mbmi->ref_mvs[mbmi->ref_frame[0]],
+ cm->ref_frame_sign_bias);
- vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[ref_frame]);
+ vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[mbmi->ref_frame[0]]);
// If the segment level skip mode enabled
if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) {
mbmi->mode = ZEROMV;
} else if (bsize >= BLOCK_SIZE_SB8X8) {
mbmi->mode = read_sb_mv_ref(r, mv_ref_p);
- vp9_accum_mv_refs(cm, mbmi->mode, mbmi->mb_mode_context[ref_frame]);
+ vp9_accum_mv_refs(cm, mbmi->mode,
+ mbmi->mb_mode_context[mbmi->ref_frame[0]]);
}
if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
vp9_find_best_ref_mvs(xd,
- mbmi->ref_mvs[ref_frame],
+ mbmi->ref_mvs[mbmi->ref_frame[0]],
&nearest, &nearby);
- best_mv.as_int = mbmi->ref_mvs[ref_frame][0].as_int;
+ best_mv.as_int = mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_int;
}
#ifdef DEC_DEBUG
@@ -587,33 +605,18 @@
? read_switchable_filter_type(pbi, r)
: cm->mcomp_filter_type;
- if (cm->comp_pred_mode == COMP_PREDICTION_ONLY ||
- (cm->comp_pred_mode == HYBRID_PREDICTION &&
- vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_COMP)))) {
- /* Since we have 3 reference frames, we can only have 3 unique
- * combinations of combinations of 2 different reference frames
- * (A-G, G-L or A-L). In the bitstream, we use this to simply
- * derive the second reference frame from the first reference
- * frame, by saying it's the next one in the enumerator, and
- * if that's > n_refs, then the second reference frame is the
- * first one in the enumerator. */
- mbmi->second_ref_frame = mbmi->ref_frame + 1;
- if (mbmi->second_ref_frame == 4)
- mbmi->second_ref_frame = 1;
- if (mbmi->second_ref_frame > 0) {
- const MV_REFERENCE_FRAME second_ref_frame = mbmi->second_ref_frame;
+ if (mbmi->ref_frame[1] > INTRA_FRAME) {
+ vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
+ mbmi->ref_frame[1],
+ mbmi->ref_mvs[mbmi->ref_frame[1]],
+ cm->ref_frame_sign_bias);
- vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
- second_ref_frame, mbmi->ref_mvs[second_ref_frame],
- cm->ref_frame_sign_bias);
-
- if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
- vp9_find_best_ref_mvs(xd,
- mbmi->ref_mvs[second_ref_frame],
- &nearest_second,
- &nearby_second);
- best_mv_second.as_int = mbmi->ref_mvs[second_ref_frame][0].as_int;
- }
+ if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
+ vp9_find_best_ref_mvs(xd,
+ mbmi->ref_mvs[mbmi->ref_frame[1]],
+ &nearest_second,
+ &nearby_second);
+ best_mv_second.as_int = mbmi->ref_mvs[mbmi->ref_frame[1]][0].as_int;
}
}
@@ -628,9 +631,10 @@
j = idy * 2 + idx;
blockmode = read_sb_mv_ref(r, mv_ref_p);
- vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref_frame]);
+ vp9_accum_mv_refs(cm, blockmode,
+ mbmi->mb_mode_context[mbmi->ref_frame[0]]);
if (blockmode == NEARESTMV || blockmode == NEARMV) {
- MV_REFERENCE_FRAME rf2 = mbmi->second_ref_frame;
+ MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0);
if (rf2 > 0) {
vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest_second,
@@ -643,7 +647,7 @@
decode_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
decode_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
@@ -653,7 +657,7 @@
break;
case NEARESTMV:
blockmv.as_int = nearest.as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
secondmv.as_int = nearest_second.as_int;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][0]++;
@@ -661,7 +665,7 @@
break;
case NEARMV:
blockmv.as_int = nearby.as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
secondmv.as_int = nearby_second.as_int;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][1]++;
@@ -669,7 +673,7 @@
break;
case ZEROMV:
blockmv.as_int = 0;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
secondmv.as_int = 0;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][2]++;
@@ -679,7 +683,7 @@
break;
}
mi->bmi[j].as_mv[0].as_int = blockmv.as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
mi->bmi[j].as_mv[1].as_int = secondmv.as_int;
for (i = 1; i < bh; ++i)
@@ -700,7 +704,7 @@
mb_to_right_edge,
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
assign_and_clamp_mv(mv1, &nearby_second, mb_to_left_edge,
mb_to_right_edge,
mb_to_top_edge,
@@ -713,7 +717,7 @@
mb_to_right_edge,
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
assign_and_clamp_mv(mv1, &nearest_second, mb_to_left_edge,
mb_to_right_edge,
mb_to_top_edge,
@@ -722,7 +726,7 @@
case ZEROMV:
mv0->as_int = 0;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
mv1->as_int = 0;
break;
@@ -735,7 +739,7 @@
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->second_ref_frame > 0) {
+ if (mbmi->ref_frame[1] > 0) {
decode_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
mbmi->need_to_clamp_secondmv = check_mv_bounds(mv1,
@@ -757,16 +761,19 @@
mv0->as_int = 0;
if (bsize >= BLOCK_SIZE_SB8X8) {
- mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob);
- cm->fc.y_mode_counts[mbmi->mode]++;
+ const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
+ const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+ const int bsl = MIN(bwl, bhl);
+ mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[MIN(3, bsl)]);
+ cm->fc.y_mode_counts[MIN(3, bsl)][mbmi->mode]++;
} else {
int idx, idy;
for (idy = 0; idy < 2; idy += bh) {
for (idx = 0; idx < 2; idx += bw) {
int ib = idy * 2 + idx, k;
- int m = read_intra_mode(r, cm->fc.y_mode_prob);
+ int m = read_intra_mode(r, cm->fc.y_mode_prob[0]);
mi->bmi[ib].as_mode.first = m;
- cm->fc.y_mode_counts[m]++;
+ cm->fc.y_mode_counts[0][m]++;
for (k = 1; k < bh; ++k)
mi->bmi[ib + k * 2].as_mode.first = m;
for (k = 1; k < bw; ++k)
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 5c03061..aacdad5 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -57,11 +57,16 @@
pc->txfm_mode = vp9_read_literal(r, 2);
if (pc->txfm_mode == ALLOW_32X32)
pc->txfm_mode += vp9_read_bit(r);
-
if (pc->txfm_mode == TX_MODE_SELECT) {
- pc->prob_tx[0] = vp9_read_prob(r);
- pc->prob_tx[1] = vp9_read_prob(r);
- pc->prob_tx[2] = vp9_read_prob(r);
+ int i;
+ for (i = 0; i < TX_SIZE_PROBS; ++i) {
+ if (vp9_read(r, VP9_DEF_UPDATE_PROB))
+ pc->fc.tx_probs[i] =
+ vp9_read_prob_diff_update(r, pc->fc.tx_probs[i]);
+ }
+ } else {
+ vpx_memcpy(pc->fc.tx_probs, vp9_default_tx_probs,
+ sizeof(vp9_default_tx_probs));
}
}
}
@@ -117,13 +122,8 @@
return word;
}
-static int decode_unsigned_max(vp9_reader *r, int max) {
- int data = 0, bit = 0, lmax = max;
-
- while (lmax) {
- data |= vp9_read_bit(r) << bit++;
- lmax >>= 1;
- }
+static int decode_unsigned_max(struct vp9_read_bit_buffer *rb, int max) {
+ const int data = vp9_rb_read_literal(rb, get_unsigned_bits(max));
return data > max ? max : data;
}
@@ -153,7 +153,7 @@
}
}
-static vp9_prob read_prob_diff_update(vp9_reader *r, int oldp) {
+vp9_prob vp9_read_prob_diff_update(vp9_reader *r, int oldp) {
int delp = decode_term_subexp(r, SUBEXP_PARAM, 255);
return (vp9_prob)inv_remap_prob(delp, oldp);
}
@@ -240,6 +240,7 @@
mode = plane == 0? xd->mode_info_context->mbmi.mode:
xd->mode_info_context->mbmi.uv_mode;
+
if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8 && plane == 0) {
assert(bsize == BLOCK_SIZE_SB8X8);
b_mode = xd->mode_info_context->bmi[raster_block].as_mode.first;
@@ -247,6 +248,10 @@
b_mode = mode;
}
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
+ extend_for_intra(xd, plane, block, bsize, ss_txfrm_size);
+ }
+
plane_b_size = b_width_log2(bsize) - xd->plane[plane].subsampling_x;
vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size,
b_mode, dst, xd->plane[plane].dst.stride);
@@ -281,7 +286,7 @@
vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
- assert(mbmi->ref_frame != INTRA_FRAME);
+ assert(mbmi->ref_frame[0] != INTRA_FRAME);
if (pbi->common.frame_type != KEY_FRAME)
vp9_setup_interp_filters(xd, mbmi->interp_filter, &pbi->common);
@@ -334,7 +339,7 @@
const int mis = pc->mode_info_stride;
assert(mbmi->sb_type == bsize);
- assert(mbmi->ref_frame != INTRA_FRAME);
+ assert(mbmi->ref_frame[0] != INTRA_FRAME);
if (pbi->common.frame_type != KEY_FRAME)
vp9_setup_interp_filters(xd, mbmi->interp_filter, pc);
@@ -401,22 +406,22 @@
MACROBLOCKD *const xd = &pbi->mb;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
- if (mbmi->ref_frame > INTRA_FRAME) {
+ if (mbmi->ref_frame[0] > INTRA_FRAME) {
// Select the appropriate reference frame for this MB
- const int fb_idx = cm->active_ref_idx[mbmi->ref_frame - 1];
+ const int fb_idx = cm->active_ref_idx[mbmi->ref_frame[0] - 1];
const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx];
- xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame - 1];
- xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame - 1];
+ xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1];
+ xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1];
setup_pre_planes(xd, cfg, NULL, mi_row, mi_col,
xd->scale_factor, xd->scale_factor_uv);
xd->corrupted |= cfg->corrupted;
- if (mbmi->second_ref_frame > INTRA_FRAME) {
+ if (mbmi->ref_frame[1] > INTRA_FRAME) {
// Select the appropriate reference frame for this MB
- const int second_fb_idx = cm->active_ref_idx[mbmi->second_ref_frame - 1];
+ const int second_fb_idx = cm->active_ref_idx[mbmi->ref_frame[1] - 1];
const YV12_BUFFER_CONFIG *second_cfg = &cm->yv12_fb[second_fb_idx];
- xd->scale_factor[1] = cm->active_ref_scale[mbmi->second_ref_frame - 1];
- xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->second_ref_frame - 1];
+ xd->scale_factor[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1];
+ xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1];
setup_pre_planes(xd, NULL, second_cfg, mi_row, mi_col,
xd->scale_factor, xd->scale_factor_uv);
xd->corrupted |= second_cfg->corrupted;
@@ -435,7 +440,7 @@
vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r);
set_refs(pbi, mi_row, mi_col);
- if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
+ if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
decode_sb_intra(pbi, xd, mi_row, mi_col, r, (bsize < BLOCK_SIZE_SB8X8) ?
BLOCK_SIZE_SB8X8 : bsize);
else if (bsize < BLOCK_SIZE_SB8X8)
@@ -469,7 +474,7 @@
xd->above_seg_context = pc->above_seg_context + mi_col;
pl = partition_plane_context(xd, bsize);
partition = treed_read(r, vp9_partition_tree,
- pc->fc.partition_prob[pl]);
+ pc->fc.partition_prob[pc->frame_type][pl]);
pc->fc.partition_counts[pl][partition]++;
}
@@ -530,25 +535,6 @@
"Failed to allocate bool decoder %d", 1);
}
-static void init_frame(VP9D_COMP *pbi) {
- VP9_COMMON *const pc = &pbi->common;
- MACROBLOCKD *const xd = &pbi->mb;
-
- if (pc->frame_type == KEY_FRAME) {
- vp9_setup_past_independence(pc, xd);
- // All buffers are implicitly updated on key frames.
- pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1;
- } else if (pc->error_resilient_mode) {
- vp9_setup_past_independence(pc, xd);
- }
-
- xd->mode_info_context = pc->mi;
- xd->prev_mode_info_context = pc->prev_mi;
- xd->frame_type = pc->frame_type;
- xd->mode_info_context->mbmi.mode = DC_PRED;
- xd->mode_info_stride = pc->mode_info_stride;
-}
-
static void read_coef_probs_common(FRAME_CONTEXT *fc, TX_SIZE tx_size,
vp9_reader *r) {
const int entropy_nodes_update = UNCONSTRAINED_NODES;
@@ -569,7 +555,7 @@
vp9_prob *const p = coef_probs[i][j][k][l] + m;
if (vp9_read(r, vp9_coef_update_prob[m])) {
- *p = read_prob_diff_update(r, *p);
+ *p = vp9_read_prob_diff_update(r, *p);
}
}
}
@@ -580,65 +566,68 @@
}
static void read_coef_probs(VP9D_COMP *pbi, vp9_reader *r) {
- const TXFM_MODE mode = pbi->common.txfm_mode;
+ const TXFM_MODE txfm_mode = pbi->common.txfm_mode;
FRAME_CONTEXT *const fc = &pbi->common.fc;
read_coef_probs_common(fc, TX_4X4, r);
- if (mode > ONLY_4X4)
+ if (txfm_mode > ONLY_4X4)
read_coef_probs_common(fc, TX_8X8, r);
- if (mode > ALLOW_8X8)
+ if (txfm_mode > ALLOW_8X8)
read_coef_probs_common(fc, TX_16X16, r);
- if (mode > ALLOW_16X16)
+ if (txfm_mode > ALLOW_16X16)
read_coef_probs_common(fc, TX_32X32, r);
}
-static void setup_segmentation(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_reader *r) {
+static void setup_segmentation(VP9D_COMP *pbi, 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;
- xd->segmentation_enabled = vp9_read_bit(r);
+ xd->segmentation_enabled = vp9_rb_read_bit(rb);
if (!xd->segmentation_enabled)
return;
// Segmentation map update
- xd->update_mb_segmentation_map = vp9_read_bit(r);
+ xd->update_mb_segmentation_map = vp9_rb_read_bit(rb);
if (xd->update_mb_segmentation_map) {
for (i = 0; i < MB_SEG_TREE_PROBS; i++)
- xd->mb_segment_tree_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
- : MAX_PROB;
+ xd->mb_segment_tree_probs[i] = vp9_rb_read_bit(rb) ?
+ vp9_rb_read_literal(rb, 8) : MAX_PROB;
- pc->temporal_update = vp9_read_bit(r);
- if (pc->temporal_update) {
+ cm->temporal_update = vp9_rb_read_bit(rb);
+ if (cm->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++)
- pc->segment_pred_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
- : MAX_PROB;
+ cm->segment_pred_probs[i] = vp9_rb_read_bit(rb) ?
+ vp9_rb_read_literal(rb, 8) : MAX_PROB;
} else {
for (i = 0; i < PREDICTION_PROBS; i++)
- pc->segment_pred_probs[i] = MAX_PROB;
+ cm->segment_pred_probs[i] = MAX_PROB;
}
}
// Segmentation data update
- xd->update_mb_segmentation_data = vp9_read_bit(r);
+ xd->update_mb_segmentation_data = vp9_rb_read_bit(rb);
if (xd->update_mb_segmentation_data) {
- xd->mb_segment_abs_delta = vp9_read_bit(r);
+ xd->mb_segment_abs_delta = vp9_rb_read_bit(rb);
vp9_clearall_segfeatures(xd);
for (i = 0; i < MAX_MB_SEGMENTS; i++) {
for (j = 0; j < SEG_LVL_MAX; j++) {
int data = 0;
- const int feature_enabled = vp9_read_bit(r);
+ const int feature_enabled = vp9_rb_read_bit(rb);
if (feature_enabled) {
vp9_enable_segfeature(xd, i, j);
- data = decode_unsigned_max(r, vp9_seg_feature_data_max(j));
+ data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j));
if (vp9_is_segfeature_signed(j))
- data = vp9_read_and_apply_sign(r, data);
+ data = vp9_rb_read_bit(rb) ? -data : data;
}
vp9_set_segdata(xd, i, j, data);
}
@@ -646,22 +635,6 @@
}
}
-static void setup_pred_probs(VP9_COMMON *pc, vp9_reader *r) {
- // Read common prediction model status flag probability updates for the
- // reference frame
- if (pc->frame_type == KEY_FRAME) {
- // Set the prediction probabilities to defaults
- pc->ref_pred_probs[0] = DEFAULT_PRED_PROB_0;
- pc->ref_pred_probs[1] = DEFAULT_PRED_PROB_1;
- pc->ref_pred_probs[2] = DEFAULT_PRED_PROB_2;
- } else {
- int i;
- for (i = 0; i < PREDICTION_PROBS; ++i)
- if (vp9_read_bit(r))
- pc->ref_pred_probs[i] = vp9_read_prob(r);
- }
-}
-
static void setup_loopfilter(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
@@ -706,19 +679,36 @@
}
static void setup_quantization(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
+ MACROBLOCKD *const xd = &pbi->mb;
VP9_COMMON *const cm = &pbi->common;
int update = 0;
+
cm->base_qindex = vp9_rb_read_literal(rb, QINDEX_BITS);
update |= read_delta_q(rb, &cm->y_dc_delta_q);
update |= read_delta_q(rb, &cm->uv_dc_delta_q);
update |= read_delta_q(rb, &cm->uv_ac_delta_q);
if (update)
vp9_init_dequantizer(cm);
+
+ xd->lossless = cm->base_qindex == 0 &&
+ cm->y_dc_delta_q == 0 &&
+ cm->uv_dc_delta_q == 0 &&
+ cm->uv_ac_delta_q == 0;
+ if (xd->lossless) {
+ xd->itxm_add = vp9_idct_add_lossless_c;
+ xd->itxm_add_y_block = vp9_idct_add_y_block_lossless_c;
+ xd->itxm_add_uv_block = vp9_idct_add_uv_block_lossless_c;
+ } else {
+ xd->itxm_add = vp9_idct_add;
+ xd->itxm_add_y_block = vp9_idct_add_y_block;
+ xd->itxm_add_uv_block = vp9_idct_add_uv_block;
+ }
}
-static INTERPOLATIONFILTERTYPE read_mcomp_filter_type(vp9_reader *r) {
- return vp9_read_bit(r) ? SWITCHABLE
- : vp9_read_literal(r, 2);
+static INTERPOLATIONFILTERTYPE read_interp_filter_type(
+ struct vp9_read_bit_buffer *rb) {
+ return vp9_rb_read_bit(rb) ? SWITCHABLE
+ : vp9_rb_read_literal(rb, 2);
}
static void read_frame_size(VP9_COMMON *cm,
@@ -757,8 +747,8 @@
if (vp9_alloc_frame_buffers(pc, width, height))
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate frame buffers");
- pbi->initial_width = width;
- pbi->initial_height = height;
+ pbi->initial_width = width;
+ pbi->initial_height = height;
} else {
if (width > pbi->initial_width)
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
@@ -776,22 +766,41 @@
vp9_update_frame_size(pc);
}
+
+ vp9_realloc_frame_buffer(&pc->yv12_fb[pc->new_fb_idx], pc->width, pc->height,
+ pc->subsampling_x, pc->subsampling_y,
+ VP9BORDERINPIXELS);
}
static void update_frame_context(FRAME_CONTEXT *fc) {
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);
+ vp9_copy(fc->pre_partition_prob, fc->partition_prob[1]);
+ 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_single_ref_prob, fc->single_ref_prob);
+ vp9_copy(fc->pre_comp_ref_prob, fc->comp_ref_prob);
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_tx_probs, fc->tx_probs);
vp9_zero(fc->coef_counts);
vp9_zero(fc->eob_branch_counts);
vp9_zero(fc->y_mode_counts);
vp9_zero(fc->uv_mode_counts);
vp9_zero(fc->NMVcount);
- vp9_zero(fc->mv_ref_ct);
+ vp9_zero(fc->inter_mode_counts);
vp9_zero(fc->partition_counts);
+ vp9_zero(fc->switchable_interp_count);
+ vp9_zero(fc->intra_inter_count);
+ vp9_zero(fc->comp_inter_count);
+ vp9_zero(fc->single_ref_count);
+ vp9_zero(fc->comp_ref_count);
+ vp9_zero(fc->tx_count_8x8p);
+ vp9_zero(fc->tx_count_16x16p);
+ vp9_zero(fc->tx_count_32x32p);
}
static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) {
@@ -809,27 +818,33 @@
}
}
-static void decode_tiles(VP9D_COMP *pbi,
- const uint8_t *data, int first_partition_size,
- vp9_reader *header_bc, vp9_reader *residual_bc) {
- VP9_COMMON *const pc = &pbi->common;
+static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
+ int delta_log2_tiles;
- const uint8_t *data_ptr = data + first_partition_size;
- int tile_row, tile_col, delta_log2_tiles;
-
- vp9_get_tile_n_bits(pc, &pc->log2_tile_columns, &delta_log2_tiles);
+ vp9_get_tile_n_bits(cm, &cm->log2_tile_columns, &delta_log2_tiles);
while (delta_log2_tiles--) {
- if (vp9_read_bit(header_bc)) {
- pc->log2_tile_columns++;
+ if (vp9_rb_read_bit(rb)) {
+ cm->log2_tile_columns++;
} else {
break;
}
}
- pc->log2_tile_rows = vp9_read_bit(header_bc);
- if (pc->log2_tile_rows)
- pc->log2_tile_rows += vp9_read_bit(header_bc);
- pc->tile_columns = 1 << pc->log2_tile_columns;
- pc->tile_rows = 1 << pc->log2_tile_rows;
+
+ cm->log2_tile_rows = vp9_rb_read_bit(rb);
+ if (cm->log2_tile_rows)
+ cm->log2_tile_rows += vp9_rb_read_bit(rb);
+
+ cm->tile_columns = 1 << cm->log2_tile_columns;
+ cm->tile_rows = 1 << cm->log2_tile_rows;
+}
+
+static void decode_tiles(VP9D_COMP *pbi,
+ const uint8_t *data, size_t first_partition_size,
+ vp9_reader *residual_bc) {
+ VP9_COMMON *const pc = &pbi->common;
+
+ const uint8_t *data_ptr = data + first_partition_size;
+ int tile_row, tile_col;
// Note: this memset assumes above_context[0], [1] and [2]
// are allocated as part of the same buffer.
@@ -901,39 +916,56 @@
vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
}
+#define RESERVED \
+ if (vp9_rb_read_bit(rb)) \
+ vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, \
+ "Reserved bit must be unset")
+
size_t read_uncompressed_header(VP9D_COMP *pbi,
struct vp9_read_bit_buffer *rb) {
VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
- int scaling_active;
+ int scaling_active, i;
cm->last_frame_type = cm->frame_type;
+ if (vp9_rb_read_literal(rb, 2) != 0x2)
+ vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+ "Invalid frame marker");
+
+ cm->version = vp9_rb_read_bit(rb);
+ RESERVED;
+
+ if (vp9_rb_read_bit(rb)) {
+ // show an existing frame directly
+ int frame_to_show = cm->ref_frame_map[vp9_rb_read_literal(rb, 3)];
+ ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->new_fb_idx, frame_to_show);
+ pbi->refresh_frame_flags = 0;
+ cm->filter_level = 0;
+ return 0;
+ }
cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb);
- cm->version = vp9_rb_read_literal(rb, 3);
cm->show_frame = vp9_rb_read_bit(rb);
scaling_active = vp9_rb_read_bit(rb);
- cm->subsampling_x = vp9_rb_read_bit(rb);
- cm->subsampling_y = vp9_rb_read_bit(rb);
if (cm->frame_type == KEY_FRAME) {
if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 ||
vp9_rb_read_literal(rb, 8) != SYNC_CODE_1 ||
vp9_rb_read_literal(rb, 8) != SYNC_CODE_2) {
- vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
- "Invalid frame sync code");
+ vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+ "Invalid frame sync code");
+ }
+ vp9_rb_read_literal(rb, 3); // colorspace
+ if (cm->version == 1) {
+ cm->subsampling_x = vp9_rb_read_bit(rb);
+ cm->subsampling_y = vp9_rb_read_bit(rb);
+ vp9_rb_read_bit(rb); // has extra plane
+ } else {
+ cm->subsampling_y = cm->subsampling_x = 1;
}
}
setup_frame_size(pbi, scaling_active, rb);
- if (!cm->show_frame) {
- cm->intra_only = vp9_rb_read_bit(rb);
- } else {
- cm->intra_only = 0;
- }
-
- cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
- cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
-
cm->error_resilient_mode = vp9_rb_read_bit(rb);
if (!cm->error_resilient_mode) {
cm->reset_frame_context = vp9_rb_read_bit(rb);
@@ -945,8 +977,64 @@
cm->frame_parallel_decoding_mode = 1;
}
+ if (cm->frame_type == KEY_FRAME) {
+ vp9_setup_past_independence(cm, xd);
+
+ pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1;
+
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
+ cm->active_ref_idx[i] = cm->new_fb_idx;
+ } else {
+ if (cm->error_resilient_mode)
+ vp9_setup_past_independence(cm, xd);
+
+ pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES);
+
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+ const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LG2);
+ cm->active_ref_idx[i] = cm->ref_frame_map[ref];
+ vp9_setup_scale_factors(cm, i);
+ }
+
+ // Read the sign bias for each reference frame buffer.
+ cm->allow_comp_inter_inter = 0;
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
+ cm->ref_frame_sign_bias[i + 1] = vp9_rb_read_bit(rb);
+ cm->allow_comp_inter_inter |= i > 0 &&
+ cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1];
+ }
+ if (cm->allow_comp_inter_inter) {
+ // which one is always-on in comp inter-inter?
+ if (cm->ref_frame_sign_bias[LAST_FRAME] ==
+ cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
+ cm->comp_fixed_ref = ALTREF_FRAME;
+ cm->comp_var_ref[0] = LAST_FRAME;
+ cm->comp_var_ref[1] = GOLDEN_FRAME;
+ } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
+ cm->ref_frame_sign_bias[ALTREF_FRAME]) {
+ cm->comp_fixed_ref = GOLDEN_FRAME;
+ cm->comp_var_ref[0] = LAST_FRAME;
+ cm->comp_var_ref[1] = ALTREF_FRAME;
+ } else {
+ cm->comp_fixed_ref = LAST_FRAME;
+ cm->comp_var_ref[0] = GOLDEN_FRAME;
+ cm->comp_var_ref[1] = ALTREF_FRAME;
+ }
+ }
+
+ xd->allow_high_precision_mv = vp9_rb_read_bit(rb);
+ cm->mcomp_filter_type = read_interp_filter_type(rb);
+ }
+
+ cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
+ cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
+ cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
+
setup_loopfilter(pbi, rb);
setup_quantization(pbi, rb);
+ setup_segmentation(pbi, rb);
+
+ setup_tile_info(cm, rb);
return vp9_rb_read_literal(rb, 16);
}
@@ -956,7 +1044,7 @@
vp9_reader header_bc, residual_bc;
VP9_COMMON *const pc = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
- YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
+
const uint8_t *data = pbi->source;
const uint8_t *data_end = pbi->source + pbi->source_sz;
@@ -964,7 +1052,13 @@
pc, error_handler };
const size_t first_partition_size = read_uncompressed_header(pbi, &rb);
const int keyframe = pc->frame_type == KEY_FRAME;
+ YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
+ if (!first_partition_size) {
+ // showing a frame directly
+ *p_data_end = data + 1;
+ return 0;
+ }
data += vp9_rb_bytes_read(&rb);
xd->corrupted = 0;
new_fb->corrupted = 0;
@@ -976,15 +1070,13 @@
vp9_setup_version(pc);
if (!read_is_valid(data, first_partition_size, data_end))
- vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
- "Truncated packet or corrupt partition 0 length");
+ vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+ "Truncated packet or corrupt partition 0 length");
- init_frame(pbi);
-
- // Reset the frame pointers to the current frame size
- vp9_realloc_frame_buffer(new_fb, pc->width, pc->height,
- pc->subsampling_x, pc->subsampling_y,
- VP9BORDERINPIXELS);
+ xd->mode_info_context = pc->mi;
+ xd->prev_mode_info_context = pc->prev_mi;
+ xd->frame_type = pc->frame_type;
+ xd->mode_info_stride = pc->mode_info_stride;
if (vp9_reader_init(&header_bc, data, first_partition_size))
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
@@ -992,67 +1084,15 @@
mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup
- xd->lossless = pc->base_qindex == 0 &&
- pc->y_dc_delta_q == 0 &&
- pc->uv_dc_delta_q == 0 &&
- pc->uv_ac_delta_q == 0;
- if (xd->lossless) {
- xd->itxm_add = vp9_idct_add_lossless_c;
- xd->itxm_add_y_block = vp9_idct_add_y_block_lossless_c;
- xd->itxm_add_uv_block = vp9_idct_add_uv_block_lossless_c;
- } else {
- xd->itxm_add = vp9_idct_add;
- xd->itxm_add_y_block = vp9_idct_add_y_block;
- xd->itxm_add_uv_block = vp9_idct_add_uv_block;
- }
-
- // Determine if the golden frame or ARF buffer should be updated and how.
- // For all non key frames the GF and ARF refresh flags and sign bias
- // flags must be set explicitly.
- if (keyframe) {
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
- pc->active_ref_idx[i] = pc->new_fb_idx;
- } else {
- // Should the GF or ARF be updated from the current frame
- pbi->refresh_frame_flags = vp9_read_literal(&header_bc, NUM_REF_FRAMES);
-
- // Select active reference frames and calculate scaling factors
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
- const int ref = vp9_read_literal(&header_bc, NUM_REF_FRAMES_LG2);
- pc->active_ref_idx[i] = pc->ref_frame_map[ref];
- vp9_setup_scale_factors(pc, i);
- }
-
- // Read the sign bias for each reference frame buffer.
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
- pc->ref_frame_sign_bias[i + 1] = vp9_read_bit(&header_bc);
-
- xd->allow_high_precision_mv = vp9_read_bit(&header_bc);
- pc->mcomp_filter_type = read_mcomp_filter_type(&header_bc);
-
- // To enable choice of different interpolation filters
+ if (!keyframe)
vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
- }
pc->fc = pc->frame_contexts[pc->frame_context_idx];
- setup_segmentation(pc, xd, &header_bc);
-
- setup_pred_probs(pc, &header_bc);
+ update_frame_context(&pc->fc);
setup_txfm_mode(pc, xd->lossless, &header_bc);
- // Read inter mode probability context updates
- if (!keyframe) {
- int i, j;
- for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
- for (j = 0; j < VP9_MVREFS - 1; ++j)
- if (vp9_read(&header_bc, 252))
- pc->fc.vp9_mode_contexts[i][j] = vp9_read_prob(&header_bc);
- }
-
- update_frame_context(&pc->fc);
-
read_coef_probs(pbi, &header_bc);
// Initialize xd pointers. Any reference should do for xd->pre, so use 0.
@@ -1075,7 +1115,7 @@
vp9_decode_mode_mvs_init(pbi, &header_bc);
- decode_tiles(pbi, data, first_partition_size, &header_bc, &residual_bc);
+ decode_tiles(pbi, data, first_partition_size, &residual_bc);
pc->last_width = pc->width;
pc->last_height = pc->height;
diff --git a/vp9/decoder/vp9_decodframe.h b/vp9/decoder/vp9_decodframe.h
index 00b6d67..66e951d 100644
--- a/vp9/decoder/vp9_decodframe.h
+++ b/vp9/decoder/vp9_decodframe.h
@@ -17,5 +17,6 @@
void vp9_init_dequantizer(struct VP9Common *pc);
int vp9_decode_frame(struct VP9Decompressor *cpi, const uint8_t **p_data_end);
+vp9_prob vp9_read_prob_diff_update(vp9_reader *r, int oldp);
#endif // VP9_DECODER_VP9_DECODFRAME_H_
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index b208072..d06c9b0 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -111,7 +111,7 @@
vp9_prob *prob;
vp9_coeff_count_model *coef_counts;
- const int ref = xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME;
+ const int ref = xd->mode_info_context->mbmi.ref_frame[0] != INTRA_FRAME;
TX_TYPE tx_type = DCT_DCT;
const int *scan, *nb;
uint8_t token_cache[1024];
@@ -288,18 +288,14 @@
if (c < seg_eob)
coef_counts[type][ref][band][pt][DCT_EOB_MODEL_TOKEN]++;
- for (pt = 0; pt < (1 << txfm_size); pt++) {
- A[pt] = L[pt] = c > 0;
- }
return c;
}
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
- return vp9_get_segdata(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
+ return vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
}
-
struct decode_block_args {
VP9D_COMP *pbi;
MACROBLOCKD *xd;
@@ -314,6 +310,7 @@
const int bw = b_width_log2(bsize);
// find the maximum eob for this transform size, adjusted by segment
+ MACROBLOCKD *xd = arg->xd;
const int segment_id = arg->xd->mode_info_context->mbmi.segment_id;
const TX_SIZE ss_tx_size = ss_txfrm_size / 2;
const int seg_eob = get_eob(arg->xd, segment_id, 16 << ss_txfrm_size);
@@ -322,14 +319,23 @@
const int mod = bw - ss_tx_size - arg->xd->plane[plane].subsampling_x;
const int aoff = (off & ((1 << mod) - 1)) << ss_tx_size;
const int loff = (off >> mod) << ss_tx_size;
-
+ int pt;
+ ENTROPY_CONTEXT *A = arg->xd->plane[plane].above_context + aoff;
+ ENTROPY_CONTEXT *L = arg->xd->plane[plane].left_context + loff;
const int eob = decode_coefs(arg->pbi, arg->xd, arg->r, block,
arg->xd->plane[plane].plane_type, seg_eob,
BLOCK_OFFSET(qcoeff_base, block, 16),
ss_tx_size, arg->xd->plane[plane].dequant,
- arg->xd->plane[plane].above_context + aoff,
- arg->xd->plane[plane].left_context + loff);
+ A,
+ L);
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
+ set_contexts_on_border(xd, bsize, plane, ss_tx_size, eob, aoff, loff, A, L);
+ } else {
+ for (pt = 0; pt < (1 << ss_tx_size); pt++) {
+ A[pt] = L[pt] = eob > 0;
+ }
+ }
arg->xd->plane[plane].eobs[block] = eob;
arg->eobtotal[0] += eob;
}
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 043ac6a..28e107b 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -53,11 +53,6 @@
static int update_bits[255];
-static INLINE void write_le16(uint8_t *p, int value) {
- p[0] = value;
- p[1] = value >> 8;
-}
-
static INLINE void write_le32(uint8_t *p, int value) {
p[0] = value;
p[1] = value >> 8;
@@ -65,14 +60,7 @@
p[3] = value >> 24;
}
-void vp9_encode_unsigned_max(vp9_writer *br, int data, int max) {
- assert(data <= max);
- while (max) {
- vp9_write_bit(br, data & 1);
- data >>= 1;
- max >>= 1;
- }
-}
+
int recenter_nonneg(int v, int m) {
if (v > (m << 1))
@@ -93,6 +81,11 @@
return cat;
}
+void vp9_encode_unsigned_max(struct vp9_write_bit_buffer *wb,
+ int data, int max) {
+ vp9_wb_write_literal(wb, data, get_unsigned_bits(max));
+}
+
void encode_uniform(vp9_writer *w, int v, int n) {
int l = get_unsigned_bits(n);
int m;
@@ -203,151 +196,6 @@
return update_bits[delp] * 256;
}
-static void update_mode(
- vp9_writer *w,
- int n,
- const struct vp9_token tok[/* n */],
- vp9_tree tree,
- vp9_prob Pnew [/* n-1 */],
- vp9_prob Pcur [/* n-1 */],
- unsigned int bct [/* n-1 */] [2],
- const unsigned int num_events[/* n */]
-) {
- unsigned int new_b = 0, old_b = 0;
- int i = 0;
-
- vp9_tree_probs_from_distribution(tree, Pnew, bct, num_events, 0);
- n--;
-
- do {
- new_b += cost_branch(bct[i], Pnew[i]);
- old_b += cost_branch(bct[i], Pcur[i]);
- } while (++i < n);
-
- if (new_b + (n << 8) < old_b) {
- int i = 0;
-
- vp9_write_bit(w, 1);
-
- do {
- const vp9_prob p = Pnew[i];
-
- vp9_write_literal(w, Pcur[i] = p ? p : 1, 8);
- } while (++i < n);
- } else
- vp9_write_bit(w, 0);
-}
-
-static void update_mbintra_mode_probs(VP9_COMP* const cpi,
- vp9_writer* const bc) {
- VP9_COMMON *const cm = &cpi->common;
-
- vp9_prob pnew[VP9_INTRA_MODES - 1];
- unsigned int bct[VP9_INTRA_MODES - 1][2];
-
- update_mode(bc, VP9_INTRA_MODES, vp9_intra_mode_encodings,
- vp9_intra_mode_tree, pnew,
- cm->fc.y_mode_prob, bct, (unsigned int *)cpi->y_mode_count);
-}
-
-void vp9_update_skip_probs(VP9_COMP *cpi) {
- VP9_COMMON *const pc = &cpi->common;
- int k;
-
- for (k = 0; k < MBSKIP_CONTEXTS; ++k)
- pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
- cpi->skip_true_count[k]);
-}
-
-static void update_switchable_interp_probs(VP9_COMP *cpi,
- vp9_writer* const bc) {
- VP9_COMMON *const pc = &cpi->common;
- unsigned int branch_ct[32][2];
- int i, j;
- for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) {
- vp9_tree_probs_from_distribution(
- vp9_switchable_interp_tree,
- pc->fc.switchable_interp_prob[j], branch_ct,
- cpi->switchable_interp_count[j], 0);
- for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
- if (pc->fc.switchable_interp_prob[j][i] < 1)
- pc->fc.switchable_interp_prob[j][i] = 1;
- vp9_write_prob(bc, pc->fc.switchable_interp_prob[j][i]);
- }
- }
-}
-
-// This function updates the reference frame prediction stats
-static void update_refpred_stats(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
- int i;
- vp9_prob new_pred_probs[PREDICTION_PROBS];
- int old_cost, new_cost;
-
- // Set the prediction probability structures to defaults
- if (cm->frame_type != KEY_FRAME) {
- // From the prediction counts set the probabilities for each context
- for (i = 0; i < PREDICTION_PROBS; i++) {
- const int c0 = cpi->ref_pred_count[i][0];
- const int c1 = cpi->ref_pred_count[i][1];
-
- new_pred_probs[i] = get_binary_prob(c0, c1);
-
- // Decide whether or not to update the reference frame probs.
- // Returned costs are in 1/256 bit units.
- old_cost = c0 * vp9_cost_zero(cm->ref_pred_probs[i]) +
- c1 * vp9_cost_one(cm->ref_pred_probs[i]);
-
- new_cost = c0 * vp9_cost_zero(new_pred_probs[i]) +
- c1 * vp9_cost_one(new_pred_probs[i]);
-
- // Cost saving must be >= 8 bits (2048 in these units)
- if ((old_cost - new_cost) >= 2048) {
- cpi->ref_pred_probs_update[i] = 1;
- cm->ref_pred_probs[i] = new_pred_probs[i];
- } else
- cpi->ref_pred_probs_update[i] = 0;
- }
- }
-}
-
-// This function is called to update the mode probability context used to encode
-// inter modes. It assumes the branch counts table has already been populated
-// prior to the actual packing of the bitstream (in rd stage or dummy pack)
-//
-// The branch counts table is re-populated during the actual pack stage and in
-// the decoder to facilitate backwards update of the context.
-static void update_inter_mode_probs(VP9_COMMON *cm,
- int mode_context[INTER_MODE_CONTEXTS][VP9_MVREFS - 1]) {
- int i, j;
- unsigned int (*mv_ref_ct)[VP9_MVREFS - 1][2] = cm->fc.mv_ref_ct;
-
- vpx_memcpy(mode_context, cm->fc.vp9_mode_contexts,
- sizeof(cm->fc.vp9_mode_contexts));
-
- for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
- for (j = 0; j < VP9_MVREFS - 1; j++) {
- int new_prob, old_cost, new_cost;
-
- // Work out cost of coding branches with the old and optimal probability
- old_cost = cost_branch256(mv_ref_ct[i][j], mode_context[i][j]);
- new_prob = get_binary_prob(mv_ref_ct[i][j][0], mv_ref_ct[i][j][1]);
- new_cost = cost_branch256(mv_ref_ct[i][j], new_prob);
-
- // If cost saving is >= 14 bits then update the mode probability.
- // This is the approximate net cost of updating one probability given
- // that the no update case ismuch more common than the update case.
- if (new_cost <= (old_cost - (14 << 8))) {
- mode_context[i][j] = new_prob;
- }
- }
- }
-}
-
-static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) {
- write_token(bc, vp9_intra_mode_tree, p, vp9_intra_mode_encodings + m);
-}
-
static int prob_update_savings(const unsigned int *ct,
const vp9_prob oldp, const vp9_prob newp,
const vp9_prob upd) {
@@ -424,6 +272,7 @@
vp9_prob newp;
int savings;
newp = get_binary_prob(ct[0], ct[1]);
+ assert(newp >= 1);
savings = prob_update_savings(ct, *oldp, newp, upd);
if (savings > 0) {
vp9_write(bc, 1, upd);
@@ -434,6 +283,107 @@
}
}
+static void vp9_cond_prob_diff_update(vp9_writer *bc, vp9_prob *oldp,
+ vp9_prob upd,
+ unsigned int *ct) {
+ vp9_prob newp;
+ int savings;
+ newp = get_binary_prob(ct[0], ct[1]);
+ assert(newp >= 1);
+ savings = prob_diff_update_savings_search(ct, *oldp, &newp, upd);
+ if (savings > 0) {
+ vp9_write(bc, 1, upd);
+ write_prob_diff_update(bc, newp, *oldp);
+ *oldp = newp;
+ } else {
+ vp9_write(bc, 0, upd);
+ }
+}
+
+static void update_mode(
+ vp9_writer *w,
+ int n,
+ const struct vp9_token tok[/* n */],
+ vp9_tree tree,
+ vp9_prob Pnew[/* n-1 */],
+ vp9_prob Pcur[/* n-1 */],
+ unsigned int bct[/* n-1 */] [2],
+ const unsigned int num_events[/* n */]
+) {
+ int i = 0;
+
+ vp9_tree_probs_from_distribution(tree, Pnew, bct, num_events, 0);
+ n--;
+
+ for (i = 0; i < n; ++i) {
+ vp9_cond_prob_diff_update(w, &Pcur[i], VP9_DEF_UPDATE_PROB, bct[i]);
+ }
+}
+
+static void update_mbintra_mode_probs(VP9_COMP* const cpi,
+ vp9_writer* const bc) {
+ VP9_COMMON *const cm = &cpi->common;
+ int j;
+ vp9_prob pnew[VP9_INTRA_MODES - 1];
+ unsigned int bct[VP9_INTRA_MODES - 1][2];
+
+ for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
+ update_mode(bc, VP9_INTRA_MODES, vp9_intra_mode_encodings,
+ vp9_intra_mode_tree, pnew,
+ cm->fc.y_mode_prob[j], bct,
+ (unsigned int *)cpi->y_mode_count[j]);
+}
+
+void vp9_update_skip_probs(VP9_COMP *cpi) {
+ VP9_COMMON *const pc = &cpi->common;
+ int k;
+
+ for (k = 0; k < MBSKIP_CONTEXTS; ++k)
+ pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
+ cpi->skip_true_count[k]);
+}
+
+static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) {
+ write_token(bc, vp9_intra_mode_tree, p, vp9_intra_mode_encodings + m);
+}
+
+static void update_switchable_interp_probs(VP9_COMMON *const pc,
+ vp9_writer* const bc) {
+ unsigned int branch_ct[VP9_SWITCHABLE_FILTERS + 1]
+ [VP9_SWITCHABLE_FILTERS - 1][2];
+ vp9_prob new_prob[VP9_SWITCHABLE_FILTERS + 1][VP9_SWITCHABLE_FILTERS - 1];
+ int i, j;
+ for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) {
+ vp9_tree_probs_from_distribution(
+ vp9_switchable_interp_tree,
+ new_prob[j], branch_ct[j],
+ pc->fc.switchable_interp_count[j], 0);
+ }
+ for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) {
+ for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
+ // vp9_cond_prob_update(bc, &pc->fc.switchable_interp_prob[j][i],
+ // VP9_DEF_UPDATE_PROB, branch_ct[j][i]);
+ vp9_cond_prob_diff_update(bc, &pc->fc.switchable_interp_prob[j][i],
+ VP9_DEF_UPDATE_PROB, branch_ct[j][i]);
+ }
+ }
+}
+
+static void update_inter_mode_probs(VP9_COMMON *pc, vp9_writer* const bc) {
+ int i, j;
+
+ for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
+ for (j = 0; j < VP9_INTER_MODES - 1; j++) {
+ vp9_cond_prob_diff_update(bc, &pc->fc.inter_mode_probs[i][j],
+ VP9_DEF_UPDATE_PROB,
+ pc->fc.inter_mode_counts[i][j]);
+ // vp9_cond_prob_update(
+ // bc, &pc->fc.inter_mode_probs[i][j],
+ // VP9_DEF_UPDATE_PROB, pc->fc.inter_mode_counts[i][j]);
+ }
+ }
+}
+
static void pack_mb_tokens(vp9_writer* const bc,
TOKENEXTRA **tp,
const TOKENEXTRA *const stop) {
@@ -525,16 +475,15 @@
}
// This function encodes the reference frame
-static void encode_ref_frame(vp9_writer *const bc,
- VP9_COMMON *const cm,
- MACROBLOCKD *xd,
- int segment_id,
- MV_REFERENCE_FRAME rf) {
- int seg_ref_active;
+static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
+ VP9_COMMON *const pc = &cpi->common;
+ MACROBLOCK *const x = &cpi->mb;
+ 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,
+ SEG_LVL_REF_FRAME);
int seg_ref_count = 0;
- seg_ref_active = vp9_segfeature_active(xd,
- segment_id,
- SEG_LVL_REF_FRAME);
if (seg_ref_active) {
seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) +
@@ -546,84 +495,35 @@
// If segment level coding of this signal is disabled...
// or the segment allows multiple reference frame options
if (!seg_ref_active || (seg_ref_count > 1)) {
- // Values used in prediction model coding
- unsigned char prediction_flag;
- vp9_prob pred_prob;
- MV_REFERENCE_FRAME pred_rf;
-
- // Get the context probability the prediction flag
- pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
-
- // Get the predicted value.
- pred_rf = vp9_get_pred_ref(cm, xd);
-
- // Did the chosen reference frame match its predicted value.
- prediction_flag =
- (xd->mode_info_context->mbmi.ref_frame == pred_rf);
-
- vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
- vp9_write(bc, prediction_flag, pred_prob);
-
- // If not predicted correctly then code value explicitly
- if (!prediction_flag) {
- vp9_prob mod_refprobs[PREDICTION_PROBS];
-
- vpx_memcpy(mod_refprobs,
- cm->mod_refprobs[pred_rf], sizeof(mod_refprobs));
-
- // If segment coding enabled blank out options that cant occur by
- // setting the branch probability to 0.
- if (seg_ref_active) {
- mod_refprobs[INTRA_FRAME] *=
- vp9_check_segref(xd, segment_id, INTRA_FRAME);
- mod_refprobs[LAST_FRAME] *=
- vp9_check_segref(xd, segment_id, LAST_FRAME);
- mod_refprobs[GOLDEN_FRAME] *=
- (vp9_check_segref(xd, segment_id, GOLDEN_FRAME) *
- vp9_check_segref(xd, segment_id, ALTREF_FRAME));
- }
-
- if (mod_refprobs[0]) {
- vp9_write(bc, (rf != INTRA_FRAME), mod_refprobs[0]);
- }
-
- // Inter coded
- if (rf != INTRA_FRAME) {
- if (mod_refprobs[1]) {
- vp9_write(bc, (rf != LAST_FRAME), mod_refprobs[1]);
- }
-
- if (rf != LAST_FRAME) {
- if (mod_refprobs[2]) {
- vp9_write(bc, (rf != GOLDEN_FRAME), mod_refprobs[2]);
- }
- }
- }
+ // does the feature use compound prediction or not
+ // (if not specified at the frame/segment level)
+ if (pc->comp_pred_mode == HYBRID_PREDICTION) {
+ vp9_write(bc, mi->ref_frame[1] > INTRA_FRAME,
+ vp9_get_pred_prob(pc, xd, PRED_COMP_INTER_INTER));
+ } else {
+ assert((mi->ref_frame[1] <= INTRA_FRAME) ==
+ (pc->comp_pred_mode == SINGLE_PREDICTION_ONLY));
}
+
+ if (mi->ref_frame[1] > INTRA_FRAME) {
+ vp9_write(bc, mi->ref_frame[0] == GOLDEN_FRAME,
+ vp9_get_pred_prob(pc, xd, PRED_COMP_REF_P));
+ } else {
+ vp9_write(bc, mi->ref_frame[0] != LAST_FRAME,
+ vp9_get_pred_prob(pc, xd, PRED_SINGLE_REF_P1));
+ if (mi->ref_frame[0] != LAST_FRAME)
+ vp9_write(bc, mi->ref_frame[0] != GOLDEN_FRAME,
+ vp9_get_pred_prob(pc, xd, PRED_SINGLE_REF_P2));
+ }
+ } else {
+ assert(mi->ref_frame[1] <= INTRA_FRAME);
+ assert(vp9_check_segref(xd, segment_id, mi->ref_frame[0]));
}
// if using the prediction mdoel we have nothing further to do because
// the reference frame is fully coded by the segment
}
-// Update the probabilities used to encode reference frame data
-static void update_ref_probs(VP9_COMP *const cpi) {
- VP9_COMMON *const cm = &cpi->common;
-
- 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];
-
- cm->prob_intra_coded = get_binary_prob(rf_intra, rf_inter);
- cm->prob_last_coded = get_prob(rfct[LAST_FRAME], rf_inter);
- cm->prob_gf_coded = get_binary_prob(rfct[GOLDEN_FRAME], rfct[ALTREF_FRAME]);
-
- // Compute a modified set of probabilities to use when prediction of the
- // reference frame fails
- vp9_compute_mod_refprobs(cm);
-}
-
static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
vp9_writer *bc, int mi_row, int mi_col) {
VP9_COMMON *const pc = &cpi->common;
@@ -631,7 +531,7 @@
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mi = &m->mbmi;
- const MV_REFERENCE_FRAME rf = mi->ref_frame;
+ const MV_REFERENCE_FRAME rf = mi->ref_frame[0];
const MB_PREDICTION_MODE mode = mi->mode;
const int segment_id = mi->segment_id;
int skip_coeff;
@@ -669,19 +569,18 @@
vp9_get_pred_prob(pc, xd, PRED_MBSKIP));
}
- // Encode the reference frame.
- encode_ref_frame(bc, pc, xd, segment_id, rf);
+ vp9_write(bc, rf != INTRA_FRAME, vp9_get_pred_prob(pc, xd, PRED_INTRA_INTER));
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)))) {
TX_SIZE sz = mi->txfm_size;
- // FIXME(rbultje) code ternary symbol once all experiments are merged
- vp9_write(bc, sz != TX_4X4, pc->prob_tx[0]);
+ int tx_probs_offset = get_tx_probs_offset(mi->sb_type);
+ vp9_write(bc, sz != TX_4X4, pc->fc.tx_probs[tx_probs_offset]);
if (mi->sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
- vp9_write(bc, sz != TX_8X8, pc->prob_tx[1]);
+ vp9_write(bc, sz != TX_8X8, pc->fc.tx_probs[tx_probs_offset + 1]);
if (mi->sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
- vp9_write(bc, sz != TX_16X16, pc->prob_tx[2]);
+ vp9_write(bc, sz != TX_16X16, pc->fc.tx_probs[tx_probs_offset + 2]);
}
}
@@ -691,20 +590,26 @@
#endif
if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
- write_intra_mode(bc, mode, pc->fc.y_mode_prob);
+ const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
+ const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+ const int bsl = MIN(bwl, bhl);
+ write_intra_mode(bc, mode, pc->fc.y_mode_prob[MIN(3, bsl)]);
} else {
int idx, idy;
int bw = 1 << b_width_log2(mi->sb_type);
int bh = 1 << b_height_log2(mi->sb_type);
for (idy = 0; idy < 2; idy += bh)
- for (idx = 0; idx < 2; idx += bw)
- write_intra_mode(bc, m->bmi[idy * 2 + idx].as_mode.first,
- pc->fc.y_mode_prob);
+ for (idx = 0; idx < 2; idx += bw) {
+ MB_PREDICTION_MODE bm = m->bmi[idy * 2 + idx].as_mode.first;
+ write_intra_mode(bc, bm, pc->fc.y_mode_prob[0]);
+ }
}
write_intra_mode(bc, mi->uv_mode,
pc->fc.uv_mode_prob[mode]);
} else {
- vp9_prob mv_ref_p[VP9_MVREFS - 1];
+ vp9_prob mv_ref_p[VP9_INTER_MODES - 1];
+
+ encode_ref_frame(cpi, bc);
vp9_mv_ref_probs(&cpi->common, mv_ref_p, mi->mb_mode_context[rf]);
@@ -730,13 +635,6 @@
assert(mi->interp_filter == cpi->common.mcomp_filter_type);
}
- // does the feature use compound prediction or not
- // (if not specified at the frame/segment level)
- if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
- vp9_write(bc, mi->second_ref_frame > INTRA_FRAME,
- vp9_get_pred_prob(pc, xd, PRED_COMP));
- }
-
if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
int j;
MB_PREDICTION_MODE blockmode;
@@ -758,7 +656,7 @@
vp9_encode_mv(bc, &blockmv.as_mv, &mi->best_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
- if (mi->second_ref_frame > 0)
+ if (mi->ref_frame[1] > INTRA_FRAME)
vp9_encode_mv(bc,
&cpi->mb.partition_info->bmi[j].second_mv.as_mv,
&mi->best_second_mv.as_mv,
@@ -778,7 +676,7 @@
&mi->mv[0].as_mv, &mi->best_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
- if (mi->second_ref_frame > 0)
+ if (mi->ref_frame[1] > INTRA_FRAME)
vp9_encode_mv(bc,
&mi->mv[1].as_mv, &mi->best_second_mv.as_mv,
nmvc, xd->allow_high_precision_mv);
@@ -808,12 +706,12 @@
if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8 && c->txfm_mode == TX_MODE_SELECT) {
TX_SIZE sz = m->mbmi.txfm_size;
- // FIXME(rbultje) code ternary symbol once all experiments are merged
- vp9_write(bc, sz != TX_4X4, c->prob_tx[0]);
+ int tx_probs_offset = get_tx_probs_offset(m->mbmi.sb_type);
+ vp9_write(bc, sz != TX_4X4, c->fc.tx_probs[tx_probs_offset]);
if (m->mbmi.sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
- vp9_write(bc, sz != TX_8X8, c->prob_tx[1]);
+ vp9_write(bc, sz != TX_8X8, c->fc.tx_probs[tx_probs_offset + 1]);
if (m->mbmi.sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
- vp9_write(bc, sz != TX_16X16, c->prob_tx[2]);
+ vp9_write(bc, sz != TX_16X16, c->fc.tx_probs[tx_probs_offset + 2]);
}
}
@@ -915,7 +813,8 @@
xd->above_seg_context = cm->above_seg_context + mi_col;
pl = partition_plane_context(xd, bsize);
// encode the partition information
- write_token(bc, vp9_partition_tree, cm->fc.partition_prob[pl],
+ write_token(bc, vp9_partition_tree,
+ cm->fc.partition_prob[cm->frame_type][pl],
vp9_partition_encodings + partition);
}
@@ -1165,6 +1064,8 @@
}
static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) {
+ const TXFM_MODE txfm_mode = cpi->common.txfm_mode;
+
vp9_clear_system_state();
// Build the cofficient contexts based on counts collected in encode loop
@@ -1172,37 +1073,15 @@
update_coef_probs_common(bc, cpi, TX_4X4);
- /* do not do this if not even allowed */
- if (cpi->common.txfm_mode != ONLY_4X4) {
+ // do not do this if not even allowed
+ if (txfm_mode > ONLY_4X4)
update_coef_probs_common(bc, cpi, TX_8X8);
- }
- if (cpi->common.txfm_mode > ALLOW_8X8) {
+ if (txfm_mode > ALLOW_8X8)
update_coef_probs_common(bc, cpi, TX_16X16);
- }
- if (cpi->common.txfm_mode > ALLOW_16X16) {
+ if (txfm_mode > ALLOW_16X16)
update_coef_probs_common(bc, cpi, TX_32X32);
- }
-}
-
-static void segment_reference_frames(VP9_COMP *cpi) {
- VP9_COMMON *oci = &cpi->common;
- MODE_INFO *mi = oci->mi;
- int ref[MAX_MB_SEGMENTS] = {0};
- int i, j;
- int mb_index = 0;
- MACROBLOCKD *const xd = &cpi->mb.e_mbd;
-
- for (i = 0; i < oci->mb_rows; i++) {
- for (j = 0; j < oci->mb_cols; j++, mb_index++)
- ref[mi[mb_index].mbmi.segment_id] |= (1 << mi[mb_index].mbmi.ref_frame);
- mb_index++;
- }
- for (i = 0; i < MAX_MB_SEGMENTS; i++) {
- vp9_enable_segfeature(xd, i, SEG_LVL_REF_FRAME);
- vp9_set_segdata(xd, i, SEG_LVL_REF_FRAME, ref[i]);
- }
}
static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd,
@@ -1275,73 +1154,62 @@
}
-static void encode_segmentation(VP9_COMP *cpi, vp9_writer *w) {
+static void encode_segmentation(VP9_COMP *cpi,
+ struct vp9_write_bit_buffer *wb) {
int i, j;
- VP9_COMMON *const pc = &cpi->common;
+ VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
- vp9_write_bit(w, xd->segmentation_enabled);
+ vp9_wb_write_bit(wb, xd->segmentation_enabled);
if (!xd->segmentation_enabled)
return;
// Segmentation map
- vp9_write_bit(w, xd->update_mb_segmentation_map);
+ vp9_wb_write_bit(wb, xd->update_mb_segmentation_map);
if (xd->update_mb_segmentation_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];
- if (prob != MAX_PROB) {
- vp9_write_bit(w, 1);
- vp9_write_prob(w, prob);
- } else {
- vp9_write_bit(w, 0);
- }
+ const int update = prob != MAX_PROB;
+ vp9_wb_write_bit(wb, update);
+ if (update)
+ vp9_wb_write_literal(wb, prob, 8);
}
// Write out the chosen coding method.
- vp9_write_bit(w, pc->temporal_update);
- if (pc->temporal_update) {
+ vp9_wb_write_bit(wb, cm->temporal_update);
+ if (cm->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++) {
- const int prob = pc->segment_pred_probs[i];
- if (prob != MAX_PROB) {
- vp9_write_bit(w, 1);
- vp9_write_prob(w, prob);
- } else {
- vp9_write_bit(w, 0);
- }
+ const int prob = cm->segment_pred_probs[i];
+ const int update = prob != MAX_PROB;
+ vp9_wb_write_bit(wb, update);
+ if (update)
+ vp9_wb_write_literal(wb, prob, 8);
}
}
}
// Segmentation data
- vp9_write_bit(w, xd->update_mb_segmentation_data);
- // segment_reference_frames(cpi);
+ vp9_wb_write_bit(wb, xd->update_mb_segmentation_data);
if (xd->update_mb_segmentation_data) {
- vp9_write_bit(w, xd->mb_segment_abs_delta);
+ vp9_wb_write_bit(wb, xd->mb_segment_abs_delta);
for (i = 0; i < MAX_MB_SEGMENTS; i++) {
for (j = 0; j < SEG_LVL_MAX; j++) {
- const int data = vp9_get_segdata(xd, i, j);
- const int data_max = vp9_seg_feature_data_max(j);
-
- if (vp9_segfeature_active(xd, i, j)) {
- vp9_write_bit(w, 1);
+ const int active = vp9_segfeature_active(xd, i, j);
+ vp9_wb_write_bit(wb, active);
+ if (active) {
+ const int data = vp9_get_segdata(xd, i, j);
+ const int data_max = vp9_seg_feature_data_max(j);
if (vp9_is_segfeature_signed(j)) {
- if (data < 0) {
- vp9_encode_unsigned_max(w, -data, data_max);
- vp9_write_bit(w, 1);
- } else {
- vp9_encode_unsigned_max(w, data, data_max);
- vp9_write_bit(w, 0);
- }
+ vp9_encode_unsigned_max(wb, abs(data), data_max);
+ vp9_wb_write_bit(wb, data < 0);
} else {
- vp9_encode_unsigned_max(w, data, data_max);
+ vp9_encode_unsigned_max(wb, data, data_max);
}
- } else {
- vp9_write_bit(w, 0);
}
}
}
@@ -1349,7 +1217,7 @@
}
-static void encode_txfm(VP9_COMP *cpi, vp9_writer *w) {
+static void encode_txfm_probs(VP9_COMP *cpi, vp9_writer *w) {
VP9_COMMON *const cm = &cpi->common;
// Mode
@@ -1359,38 +1227,72 @@
// Probabilities
if (cm->txfm_mode == TX_MODE_SELECT) {
- cm->prob_tx[0] = get_prob(cpi->txfm_count_32x32p[TX_4X4] +
- cpi->txfm_count_16x16p[TX_4X4] +
- cpi->txfm_count_8x8p[TX_4X4],
- cpi->txfm_count_32x32p[TX_4X4] +
- cpi->txfm_count_32x32p[TX_8X8] +
- cpi->txfm_count_32x32p[TX_16X16] +
- cpi->txfm_count_32x32p[TX_32X32] +
- cpi->txfm_count_16x16p[TX_4X4] +
- cpi->txfm_count_16x16p[TX_8X8] +
- cpi->txfm_count_16x16p[TX_16X16] +
- cpi->txfm_count_8x8p[TX_4X4] +
- cpi->txfm_count_8x8p[TX_8X8]);
- cm->prob_tx[1] = get_prob(cpi->txfm_count_32x32p[TX_8X8] +
- cpi->txfm_count_16x16p[TX_8X8],
- cpi->txfm_count_32x32p[TX_8X8] +
- cpi->txfm_count_32x32p[TX_16X16] +
- cpi->txfm_count_32x32p[TX_32X32] +
- cpi->txfm_count_16x16p[TX_8X8] +
- cpi->txfm_count_16x16p[TX_16X16]);
- cm->prob_tx[2] = get_prob(cpi->txfm_count_32x32p[TX_16X16],
- cpi->txfm_count_32x32p[TX_16X16] +
- cpi->txfm_count_32x32p[TX_32X32]);
- vp9_write_prob(w, cm->prob_tx[0]);
- vp9_write_prob(w, cm->prob_tx[1]);
- vp9_write_prob(w, cm->prob_tx[2]);
+ int i;
+ unsigned int ct[TX_SIZE_PROBS][2];
+ tx_counts_to_branch_counts(cm->fc.tx_count_32x32p,
+ cm->fc.tx_count_16x16p,
+ cm->fc.tx_count_8x8p, ct);
+
+ for (i = 0; i < TX_SIZE_PROBS; i++) {
+ vp9_cond_prob_diff_update(w, &cm->fc.tx_probs[i],
+ VP9_DEF_UPDATE_PROB, ct[i]);
+ }
} else {
- cm->prob_tx[0] = 128;
- cm->prob_tx[1] = 128;
- cm->prob_tx[2] = 128;
+ vpx_memcpy(cm->fc.tx_probs, vp9_default_tx_probs,
+ sizeof(vp9_default_tx_probs));
}
}
+static void write_interp_filter_type(INTERPOLATIONFILTERTYPE type,
+ struct vp9_write_bit_buffer *wb) {
+ vp9_wb_write_bit(wb, type == SWITCHABLE);
+ if (type != SWITCHABLE)
+ vp9_wb_write_literal(wb, type, 2);
+}
+
+static void fix_mcomp_filter_type(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+
+ if (cm->mcomp_filter_type == SWITCHABLE) {
+ // Check to see if only one of the filters is actually used
+ int count[VP9_SWITCHABLE_FILTERS];
+ int i, j, c = 0;
+ for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) {
+ count[i] = 0;
+ for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j)
+ count[i] += cm->fc.switchable_interp_count[j][i];
+ c += (count[i] > 0);
+ }
+ if (c == 1) {
+ // Only one filter is used. So set the filter at frame level
+ for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) {
+ if (count[i]) {
+ cm->mcomp_filter_type = vp9_switchable_interp[i];
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void write_tile_info(VP9_COMMON *cm, struct vp9_write_bit_buffer *wb) {
+ int min_log2_tiles, delta_log2_tiles, n_tile_bits, n;
+ vp9_get_tile_n_bits(cm, &min_log2_tiles, &delta_log2_tiles);
+ n_tile_bits = cm->log2_tile_columns - min_log2_tiles;
+ for (n = 0; n < delta_log2_tiles; n++) {
+ if (n_tile_bits--) {
+ vp9_wb_write_bit(wb, 1);
+ } else {
+ vp9_wb_write_bit(wb, 0);
+ break;
+ }
+ }
+
+ vp9_wb_write_bit(wb, cm->log2_tile_rows != 0);
+ if (cm->log2_tile_rows != 0)
+ vp9_wb_write_bit(wb, cm->log2_tile_rows != 1);
+}
+
void write_uncompressed_header(VP9_COMP *cpi,
struct vp9_write_bit_buffer *wb) {
VP9_COMMON *const cm = &cpi->common;
@@ -1399,17 +1301,37 @@
const int scaling_active = cm->width != cm->display_width ||
cm->height != cm->display_height;
+ // frame marker bits
+ vp9_wb_write_bit(wb, 1);
+ vp9_wb_write_bit(wb, 0);
+
+ // bitstream version.
+ // 00 - profile 0. 4:2:0 only
+ // 10 - profile 1. adds 4:4:4, 4:2:2, alpha
+ vp9_wb_write_bit(wb, cm->version);
+ vp9_wb_write_bit(wb, 0);
+
+ vp9_wb_write_bit(wb, 0);
vp9_wb_write_bit(wb, cm->frame_type);
- vp9_wb_write_literal(wb, cm->version, 3);
vp9_wb_write_bit(wb, cm->show_frame);
vp9_wb_write_bit(wb, scaling_active);
- vp9_wb_write_bit(wb, cm->subsampling_x);
- vp9_wb_write_bit(wb, cm->subsampling_y);
if (cm->frame_type == KEY_FRAME) {
vp9_wb_write_literal(wb, SYNC_CODE_0, 8);
vp9_wb_write_literal(wb, SYNC_CODE_1, 8);
vp9_wb_write_literal(wb, SYNC_CODE_2, 8);
+ // colorspaces
+ // 000 - Unknown
+ // 001 - BT.601
+ // 010 - BT.709
+ // 011 - xvYCC
+ // 1xx - Reserved
+ vp9_wb_write_literal(wb, 0, 3);
+ if (cm->version == 1) {
+ vp9_wb_write_bit(wb, cm->subsampling_x);
+ vp9_wb_write_bit(wb, cm->subsampling_y);
+ vp9_wb_write_bit(wb, 0); // has extra plane
+ }
}
if (scaling_active) {
@@ -1420,13 +1342,6 @@
vp9_wb_write_literal(wb, cm->width, 16);
vp9_wb_write_literal(wb, cm->height, 16);
- if (!cm->show_frame) {
- vp9_wb_write_bit(wb, cm->intra_only);
- }
-
- vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
- vp9_wb_write_bit(wb, cm->clr_type);
-
vp9_wb_write_bit(wb, cm->error_resilient_mode);
if (!cm->error_resilient_mode) {
vp9_wb_write_bit(wb, cm->reset_frame_context);
@@ -1434,8 +1349,71 @@
vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
}
+ // When there is a key frame all reference buffers are updated using the new key frame
+ if (cm->frame_type != KEY_FRAME) {
+ int refresh_mask, i;
+
+ // Should the GF or ARF be updated using the transmitted frame or buffer
+#if CONFIG_MULTIPLE_ARF
+ if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
+ !cpi->refresh_alt_ref_frame) {
+#else
+ if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+#endif
+ // Preserve the previously existing golden frame and update the frame in
+ // the alt ref slot instead. This is highly specific to the use of
+ // alt-ref as a forward reference, and this needs to be generalized as
+ // other uses are implemented (like RTC/temporal scaling)
+ //
+ // gld_fb_idx and alt_fb_idx need to be swapped for future frames, but
+ // that happens in vp9_onyx_if.c:update_reference_frames() so that it can
+ // be done outside of the recode loop.
+ refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
+ (cpi->refresh_golden_frame << cpi->alt_fb_idx);
+ } else {
+ int arf_idx = cpi->alt_fb_idx;
+#if CONFIG_MULTIPLE_ARF
+ // Determine which ARF buffer to use to encode this ARF frame.
+ if (cpi->multi_arf_enabled) {
+ int sn = cpi->sequence_number;
+ arf_idx = (cpi->frame_coding_order[sn] < 0) ?
+ cpi->arf_buffer_idx[sn + 1] :
+ cpi->arf_buffer_idx[sn];
+ }
+#endif
+ refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
+ (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
+ (cpi->refresh_alt_ref_frame << arf_idx);
+ }
+
+ vp9_wb_write_literal(wb, refresh_mask, NUM_REF_FRAMES);
+ vp9_wb_write_literal(wb, cpi->lst_fb_idx, NUM_REF_FRAMES_LG2);
+ vp9_wb_write_literal(wb, cpi->gld_fb_idx, NUM_REF_FRAMES_LG2);
+ vp9_wb_write_literal(wb, cpi->alt_fb_idx, NUM_REF_FRAMES_LG2);
+
+ // Indicate the sign bias for each reference frame buffer.
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
+ vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]);
+
+ // Signal whether to allow high MV precision
+ vp9_wb_write_bit(wb, xd->allow_high_precision_mv);
+
+ // Signal the type of subpel filter to use
+ fix_mcomp_filter_type(cpi);
+ write_interp_filter_type(cm->mcomp_filter_type, wb);
+ }
+
+ if (!cm->show_frame)
+ vp9_wb_write_bit(wb, cm->intra_only);
+
+ vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
+ vp9_wb_write_bit(wb, cm->clr_type);
+
encode_loopfilter(cm, xd, wb);
encode_quantization(cm, wb);
+ encode_segmentation(cpi, wb);
+
+ write_tile_info(cm, wb);
}
void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
@@ -1459,82 +1437,6 @@
vp9_start_encode(&header_bc, cx_data);
- // When there is a key frame all reference buffers are updated using the new key frame
- if (pc->frame_type != KEY_FRAME) {
- int refresh_mask;
-
- // Should the GF or ARF be updated using the transmitted frame or buffer
-#if CONFIG_MULTIPLE_ARF
- if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
- !cpi->refresh_alt_ref_frame) {
-#else
- if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
-#endif
- /* Preserve the previously existing golden frame and update the frame in
- * the alt ref slot instead. This is highly specific to the use of
- * alt-ref as a forward reference, and this needs to be generalized as
- * other uses are implemented (like RTC/temporal scaling)
- *
- * gld_fb_idx and alt_fb_idx need to be swapped for future frames, but
- * that happens in vp9_onyx_if.c:update_reference_frames() so that it can
- * be done outside of the recode loop.
- */
- refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
- (cpi->refresh_golden_frame << cpi->alt_fb_idx);
- } else {
- int arf_idx = cpi->alt_fb_idx;
-#if CONFIG_MULTIPLE_ARF
- // Determine which ARF buffer to use to encode this ARF frame.
- if (cpi->multi_arf_enabled) {
- int sn = cpi->sequence_number;
- arf_idx = (cpi->frame_coding_order[sn] < 0) ?
- cpi->arf_buffer_idx[sn + 1] :
- cpi->arf_buffer_idx[sn];
- }
-#endif
- refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
- (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
- (cpi->refresh_alt_ref_frame << arf_idx);
- }
-
- vp9_write_literal(&header_bc, refresh_mask, NUM_REF_FRAMES);
- vp9_write_literal(&header_bc, cpi->lst_fb_idx, NUM_REF_FRAMES_LG2);
- vp9_write_literal(&header_bc, cpi->gld_fb_idx, NUM_REF_FRAMES_LG2);
- vp9_write_literal(&header_bc, cpi->alt_fb_idx, NUM_REF_FRAMES_LG2);
-
- // Indicate the sign bias for each reference frame buffer.
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
- vp9_write_bit(&header_bc, pc->ref_frame_sign_bias[LAST_FRAME + i]);
- }
-
- // Signal whether to allow high MV precision
- vp9_write_bit(&header_bc, (xd->allow_high_precision_mv) ? 1 : 0);
- if (pc->mcomp_filter_type == SWITCHABLE) {
- /* Check to see if only one of the filters is actually used */
- int count[VP9_SWITCHABLE_FILTERS];
- int i, j, c = 0;
- for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) {
- count[i] = 0;
- for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j)
- count[i] += cpi->switchable_interp_count[j][i];
- c += (count[i] > 0);
- }
- if (c == 1) {
- /* Only one filter is used. So set the filter at frame level */
- for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) {
- if (count[i]) {
- pc->mcomp_filter_type = vp9_switchable_interp[i];
- break;
- }
- }
- }
- }
- // Signal the type of subpel filter to use
- vp9_write_bit(&header_bc, (pc->mcomp_filter_type == SWITCHABLE));
- if (pc->mcomp_filter_type != SWITCHABLE)
- vp9_write_literal(&header_bc, (pc->mcomp_filter_type), 2);
- }
-
#ifdef ENTROPY_STATS
if (pc->frame_type == INTER_FRAME)
active_section = 0;
@@ -1542,65 +1444,28 @@
active_section = 7;
#endif
- encode_segmentation(cpi, &header_bc);
-
- // Encode the common prediction model status flag probability updates for
- // the reference frame
- update_refpred_stats(cpi);
- if (pc->frame_type != KEY_FRAME) {
- for (i = 0; i < PREDICTION_PROBS; i++) {
- if (cpi->ref_pred_probs_update[i]) {
- vp9_write_bit(&header_bc, 1);
- vp9_write_prob(&header_bc, pc->ref_pred_probs[i]);
- } else {
- vp9_write_bit(&header_bc, 0);
- }
- }
- }
-
- if (xd->lossless)
- pc->txfm_mode = ONLY_4X4;
- else
- encode_txfm(cpi, &header_bc);
-
- // If appropriate update the inter mode probability context and code the
- // changes in the bitstream.
- if (pc->frame_type != KEY_FRAME) {
- int i, j;
- int new_context[INTER_MODE_CONTEXTS][VP9_MVREFS - 1];
- if (!cpi->dummy_packing) {
- update_inter_mode_probs(pc, new_context);
- } else {
- // In dummy pack assume context unchanged.
- vpx_memcpy(new_context, pc->fc.vp9_mode_contexts,
- sizeof(pc->fc.vp9_mode_contexts));
- }
-
- for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
- for (j = 0; j < VP9_MVREFS - 1; j++) {
- if (new_context[i][j] != pc->fc.vp9_mode_contexts[i][j]) {
- vp9_write(&header_bc, 1, 252);
- vp9_write_prob(&header_bc, new_context[i][j]);
-
- // Only update the persistent copy if this is the "real pack"
- if (!cpi->dummy_packing) {
- pc->fc.vp9_mode_contexts[i][j] = new_context[i][j];
- }
- } else {
- vp9_write(&header_bc, 0, 252);
- }
- }
- }
- }
-
vp9_clear_system_state(); // __asm emms;
- vp9_copy(cpi->common.fc.pre_coef_probs, cpi->common.fc.coef_probs);
- vp9_copy(cpi->common.fc.pre_y_mode_prob, cpi->common.fc.y_mode_prob);
- vp9_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob);
- vp9_copy(cpi->common.fc.pre_partition_prob, cpi->common.fc.partition_prob);
+ 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(cpi->common.fc.pre_partition_prob,
+ cpi->common.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);
cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
- vp9_zero(cpi->common.fc.mv_ref_ct);
+ vp9_copy(cpi->common.fc.pre_tx_probs, cpi->common.fc.tx_probs);
+
+ if (xd->lossless) {
+ pc->txfm_mode = ONLY_4X4;
+ } else {
+ encode_txfm_probs(cpi, &header_bc);
+ }
update_coef_probs(cpi, &header_bc);
@@ -1609,26 +1474,25 @@
#endif
vp9_update_skip_probs(cpi);
- for (i = 0; i < MBSKIP_CONTEXTS; ++i) {
+ for (i = 0; i < MBSKIP_CONTEXTS; ++i)
vp9_write_prob(&header_bc, pc->mbskip_pred_probs[i]);
- }
if (pc->frame_type != KEY_FRAME) {
- // Update the probabilities used to encode reference frame data
- update_ref_probs(cpi);
-
#ifdef ENTROPY_STATS
active_section = 1;
#endif
+ update_inter_mode_probs(pc, &header_bc);
+ vp9_zero(cpi->common.fc.inter_mode_counts);
+
if (pc->mcomp_filter_type == SWITCHABLE)
- update_switchable_interp_probs(cpi, &header_bc);
+ update_switchable_interp_probs(pc, &header_bc);
- vp9_write_prob(&header_bc, pc->prob_intra_coded);
- vp9_write_prob(&header_bc, pc->prob_last_coded);
- vp9_write_prob(&header_bc, pc->prob_gf_coded);
+ for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
+ vp9_cond_prob_diff_update(&header_bc, &pc->fc.intra_inter_prob[i],
+ VP9_DEF_UPDATE_PROB, cpi->intra_inter_count[i]);
- {
+ if (pc->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);
@@ -1637,45 +1501,46 @@
if (use_compound_pred) {
vp9_write_bit(&header_bc, use_hybrid_pred);
if (use_hybrid_pred) {
- for (i = 0; i < COMP_PRED_CONTEXTS; i++) {
- pc->prob_comppred[i] = get_binary_prob(cpi->single_pred_count[i],
- cpi->comp_pred_count[i]);
- vp9_write_prob(&header_bc, pc->prob_comppred[i]);
- }
+ for (i = 0; i < COMP_INTER_CONTEXTS; i++)
+ vp9_cond_prob_diff_update(&header_bc, &pc->fc.comp_inter_prob[i],
+ VP9_DEF_UPDATE_PROB,
+ cpi->comp_inter_count[i]);
}
}
}
+
+ if (pc->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_DEF_UPDATE_PROB,
+ cpi->single_ref_count[i][0]);
+ vp9_cond_prob_diff_update(&header_bc, &pc->fc.single_ref_prob[i][1],
+ VP9_DEF_UPDATE_PROB,
+ cpi->single_ref_count[i][1]);
+ }
+ }
+
+ if (pc->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_DEF_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];
unsigned int bct[PARTITION_TYPES - 1][2];
update_mode(&header_bc, PARTITION_TYPES, vp9_partition_encodings,
- vp9_partition_tree, Pnew, pc->fc.partition_prob[i], bct,
+ vp9_partition_tree, Pnew,
+ pc->fc.partition_prob[pc->frame_type][i], bct,
(unsigned int *)cpi->partition_count[i]);
}
vp9_write_nmv_probs(cpi, xd->allow_high_precision_mv, &header_bc);
}
- /* tiling */
- {
- int min_log2_tiles, delta_log2_tiles, n_tile_bits, n;
-
- vp9_get_tile_n_bits(pc, &min_log2_tiles, &delta_log2_tiles);
- n_tile_bits = pc->log2_tile_columns - min_log2_tiles;
- for (n = 0; n < delta_log2_tiles; n++) {
- if (n_tile_bits--) {
- vp9_write_bit(&header_bc, 1);
- } else {
- vp9_write_bit(&header_bc, 0);
- break;
- }
- }
- vp9_write_bit(&header_bc, pc->log2_tile_rows != 0);
- if (pc->log2_tile_rows != 0)
- vp9_write_bit(&header_bc, pc->log2_tile_rows != 1);
- }
vp9_stop_encode(&header_bc);
diff --git a/vp9/encoder/vp9_boolhuff.c b/vp9/encoder/vp9_boolhuff.c
index 86143ca..0f1aa59 100644
--- a/vp9/encoder/vp9_boolhuff.c
+++ b/vp9/encoder/vp9_boolhuff.c
@@ -47,6 +47,7 @@
br->count = -24;
br->buffer = source;
br->pos = 0;
+ vp9_write_bit(br, 0);
}
void vp9_stop_encode(vp9_writer *br) {
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index d1666df..8980306 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -330,7 +330,6 @@
BLOCK_SIZE_TYPE bsize,
int output_enabled) {
int i, x_idx, y;
- VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *mi = &ctx->mic;
@@ -345,7 +344,8 @@
#if CONFIG_DEBUG
assert(mb_mode < MB_MODE_COUNT);
assert(mb_mode_index < MAX_MODES);
- assert(mi->mbmi.ref_frame < MAX_REF_FRAMES);
+ assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES);
+ assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES);
#endif
assert(mi->mbmi.sb_type == bsize);
@@ -366,7 +366,7 @@
ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16];
}
- if (mbmi->ref_frame != INTRA_FRAME && mbmi->sb_type < BLOCK_SIZE_SB8X8) {
+ if (mbmi->ref_frame[0] != INTRA_FRAME && mbmi->sb_type < BLOCK_SIZE_SB8X8) {
*x->partition_info = ctx->partition_info;
mbmi->mv[0].as_int = x->partition_info->bmi[3].mv.as_int;
mbmi->mv[1].as_int = x->partition_info->bmi[3].second_mv.as_int;
@@ -376,29 +376,9 @@
if (!output_enabled)
return;
- {
- int segment_id = mbmi->segment_id, ref_pred_flag;
- if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
- for (i = 0; i < NB_TXFM_MODES; i++) {
- cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i];
- }
- }
-
- // Did the chosen reference frame match its predicted value.
- ref_pred_flag = ((xd->mode_info_context->mbmi.ref_frame ==
- vp9_get_pred_ref(cm, xd)));
- vp9_set_pred_flag(xd, PRED_REF, ref_pred_flag);
- if (!xd->segmentation_enabled ||
- !vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) ||
- vp9_check_segref(xd, segment_id, INTRA_FRAME) +
- vp9_check_segref(xd, segment_id, LAST_FRAME) +
- vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
- vp9_check_segref(xd, segment_id, ALTREF_FRAME) > 1) {
- // Get the prediction context and status
- int pred_context = vp9_get_pred_context(cm, xd, PRED_REF);
-
- // Count prediction success
- cpi->ref_pred_count[pred_context][ref_pred_flag]++;
+ if (!vp9_segfeature_active(xd, 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];
}
}
@@ -448,15 +428,16 @@
*/
// Note how often each mode chosen as best
cpi->mode_chosen_counts[mb_mode_index]++;
- if (mbmi->ref_frame != INTRA_FRAME &&
+ if (mbmi->ref_frame[0] != INTRA_FRAME &&
(mbmi->sb_type < BLOCK_SIZE_SB8X8 || mbmi->mode == NEWMV)) {
int_mv best_mv, best_second_mv;
- MV_REFERENCE_FRAME rf = mbmi->ref_frame;
+ const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0];
+ const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1];
best_mv.as_int = ctx->best_ref_mv.as_int;
best_second_mv.as_int = ctx->second_best_ref_mv.as_int;
if (mbmi->mode == NEWMV) {
- best_mv.as_int = mbmi->ref_mvs[rf][0].as_int;
- best_second_mv.as_int = mbmi->ref_mvs[mbmi->second_ref_frame][0].as_int;
+ best_mv.as_int = mbmi->ref_mvs[rf1][0].as_int;
+ best_second_mv.as_int = mbmi->ref_mvs[rf2][0].as_int;
}
mbmi->best_mv.as_int = best_mv.as_int;
mbmi->best_second_mv.as_int = best_second_mv.as_int;
@@ -467,12 +448,14 @@
int i, j;
for (j = 0; j < bh; ++j)
for (i = 0; i < bw; ++i)
- xd->mode_info_context[mis * j + i].mbmi = *mbmi;
+ if ((xd->mb_to_right_edge >> (3 + LOG2_MI_SIZE)) + bw > i &&
+ (xd->mb_to_bottom_edge >> (3 + LOG2_MI_SIZE)) + bh > j)
+ xd->mode_info_context[mis * j + i].mbmi = *mbmi;
}
if (cpi->common.mcomp_filter_type == SWITCHABLE &&
is_inter_mode(mbmi->mode)) {
- ++cpi->switchable_interp_count
+ ++cpi->common.fc.switchable_interp_count
[vp9_get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
[vp9_switchable_interp_map[mbmi->interp_filter]];
}
@@ -652,14 +635,8 @@
if (cm->frame_type != KEY_FRAME) {
int segment_id, seg_ref_active;
- if (mbmi->ref_frame) {
- int pred_context = vp9_get_pred_context(cm, xd, PRED_COMP);
-
- if (mbmi->second_ref_frame <= INTRA_FRAME)
- cpi->single_pred_count[pred_context]++;
- else
- cpi->comp_pred_count[pred_context]++;
- }
+ cpi->intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)]
+ [mbmi->ref_frame[0] > INTRA_FRAME]++;
// If we have just a single reference frame coded for a segment then
// exclude from the reference frame counts used to work out
@@ -669,15 +646,31 @@
segment_id = mbmi->segment_id;
seg_ref_active = vp9_segfeature_active(xd, segment_id,
SEG_LVL_REF_FRAME);
- if (!seg_ref_active ||
- ((vp9_check_segref(xd, segment_id, INTRA_FRAME) +
- vp9_check_segref(xd, segment_id, LAST_FRAME) +
- vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
- vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1)) {
- cpi->count_mb_ref_frame_usage[mbmi->ref_frame]++;
+ if (mbmi->ref_frame[0] > INTRA_FRAME &&
+ (!seg_ref_active ||
+ ((vp9_check_segref(xd, segment_id, INTRA_FRAME) +
+ vp9_check_segref(xd, segment_id, LAST_FRAME) +
+ vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
+ vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1))) {
+ if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ cpi->comp_inter_count[vp9_get_pred_context(cm, xd,
+ PRED_COMP_INTER_INTER)]
+ [mbmi->ref_frame[1] > INTRA_FRAME]++;
+
+ if (mbmi->ref_frame[1] > INTRA_FRAME) {
+ cpi->comp_ref_count[vp9_get_pred_context(cm, xd, PRED_COMP_REF_P)]
+ [mbmi->ref_frame[0] == GOLDEN_FRAME]++;
+ } else {
+ cpi->single_ref_count[vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P1)]
+ [0][mbmi->ref_frame[0] != LAST_FRAME]++;
+ if (mbmi->ref_frame[0] != LAST_FRAME)
+ cpi->single_ref_count[vp9_get_pred_context(cm, xd,
+ PRED_SINGLE_REF_P2)]
+ [1][mbmi->ref_frame[0] != GOLDEN_FRAME]++;
+ }
}
// Count of last ref frame 0,0 usage
- if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
+ if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame[0] == LAST_FRAME))
cpi->inter_zz_count++;
}
}
@@ -915,13 +908,16 @@
MODE_INFO *m, BLOCK_SIZE_TYPE bsize, int mis,
int mi_row, int mi_col) {
int row, col;
- int bsl = b_width_log2(bsize);
+ int bwl = b_width_log2(bsize);
+ int bhl = b_height_log2(bsize);
+ int bsl = (bwl > bhl ? bwl : bhl);
+
int bs = (1 << bsl) / 2; //
MODE_INFO *m2 = m + mi_row * mis + mi_col;
for (row = 0; row < bs; row++) {
for (col = 0; col < bs; col++) {
if (mi_row + row >= cm->mi_rows || mi_col + col >= cm->mi_cols)
- return;
+ continue;
m2[row*mis+col].mbmi.sb_type = bsize;
}
}
@@ -961,21 +957,6 @@
/ v->count;
}
-// Fills a 16x16 variance tree node by calling get var8x8 var..
-static void fill_16x16_variance(const unsigned char *s, int sp,
- const unsigned char *d, int dp, v16x16 *vt) {
- unsigned int sse;
- int sum;
- vp9_get_sse_sum_8x8(s, sp, d, dp, &sse, &sum);
- fill_variance(&vt->split[0].none, sse, sum, 64);
- vp9_get_sse_sum_8x8(s + 8, sp, d + 8, dp, &sse, &sum);
- fill_variance(&vt->split[1].none, sse, sum, 64);
- vp9_get_sse_sum_8x8(s + 8 * sp, sp, d + 8 * dp, dp, &sse, &sum);
- fill_variance(&vt->split[2].none, sse, sum, 64);
- vp9_get_sse_sum_8x8(s + 8 * sp + 8, sp, d + 8 + 8 * dp, dp, &sse, &sum);
- fill_variance(&vt->split[3].none, sse, sum, 64);
-}
-
// Combine 2 variance structures by summing the sum_error, sum_square_error,
// and counts and then calculating the new variance.
void sum_2_variances(var *r, var *a, var*b) {
@@ -1021,8 +1002,18 @@
int sp;
const unsigned char * d = xd->plane[0].pre->buf;
int dp = xd->plane[0].pre->stride;
+ int pixels_wide = 64, pixels_high = 64;
+
+ vpx_memset(&vt, 0, sizeof(vt));
set_offsets(cpi, mi_row, mi_col, BLOCK_SIZE_SB64X64);
+
+ if (xd->mb_to_right_edge < 0)
+ pixels_wide += (xd->mb_to_right_edge >> 3);
+
+ if (xd->mb_to_bottom_edge < 0)
+ pixels_high += (xd->mb_to_bottom_edge >> 3);
+
s = x->plane[0].src.buf;
sp = x->plane[0].src.stride;
@@ -1034,6 +1025,7 @@
d = vp9_64x64_zeros;
dp = 64;
// }
+
// Fill in the entire tree of 8x8 variances for splits.
for (i = 0; i < 4; i++) {
const int x32_idx = ((i & 1) << 5);
@@ -1041,8 +1033,28 @@
for (j = 0; j < 4; j++) {
const int x_idx = x32_idx + ((j & 1) << 4);
const int y_idx = y32_idx + ((j >> 1) << 4);
- fill_16x16_variance(s + y_idx * sp + x_idx, sp, d + y_idx * dp + x_idx,
- dp, &vt.split[i].split[j]);
+ const uint8_t *st = s + y_idx * sp + x_idx;
+ const uint8_t *dt = d + y_idx * dp + x_idx;
+ unsigned int sse = 0;
+ int sum = 0;
+ v16x16 *vst = &vt.split[i].split[j];
+ sse = sum = 0;
+ if (x_idx < pixels_wide && y_idx < pixels_high)
+ vp9_get_sse_sum_8x8(st, sp, dt, dp, &sse, &sum);
+ fill_variance(&vst->split[0].none, sse, sum, 64);
+ sse = sum = 0;
+ if (x_idx + 8 < pixels_wide && y_idx < pixels_high)
+ vp9_get_sse_sum_8x8(st + 8, sp, dt + 8, dp, &sse, &sum);
+ fill_variance(&vst->split[1].none, sse, sum, 64);
+ sse = sum = 0;
+ if (x_idx < pixels_wide && y_idx + 8 < pixels_high)
+ vp9_get_sse_sum_8x8(st + 8 * sp, sp, dt + 8 * dp, dp, &sse, &sum);
+ fill_variance(&vst->split[2].none, sse, sum, 64);
+ sse = sum = 0;
+ if (x_idx + 8 < pixels_wide && y_idx + 8 < pixels_high)
+ vp9_get_sse_sum_8x8(st + 8 * sp + 8, sp, dt + 8 + 8 * dp, dp, &sse,
+ &sum);
+ fill_variance(&vst->split[3].none, sse, sum, 64);
}
}
// Fill the rest of the variance tree by summing the split partition
@@ -1088,8 +1100,10 @@
MACROBLOCK * const x = &cpi->mb;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
const int mis = cm->mode_info_stride;
- int bwl, bhl;
+ int bwl = b_width_log2(m->mbmi.sb_type);
+ int bhl = b_height_log2(m->mbmi.sb_type);
int bsl = b_width_log2(bsize);
+ int bh = (1 << bhl);
int bs = (1 << bsl);
int bss = (1 << bsl)/4;
int i, pl;
@@ -1103,9 +1117,6 @@
return;
- bwl = b_width_log2(m->mbmi.sb_type);
- bhl = b_height_log2(m->mbmi.sb_type);
-
// parse the partition type
if ((bwl == bsl) && (bhl == bsl))
partition = PARTITION_NONE;
@@ -1144,7 +1155,7 @@
*(get_sb_index(xd, subsize)) = 0;
pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d, subsize,
get_block_context(x, subsize));
- if (mi_row + (bs >> 1) <= cm->mi_rows) {
+ if (mi_row + (bh >> 1) <= cm->mi_rows) {
int rt, dt;
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
@@ -1404,18 +1415,13 @@
for (mi_col = cm->cur_tile_mi_col_start;
mi_col < cm->cur_tile_mi_col_end; mi_col += 8) {
int dummy_rate, dummy_dist;
- // TODO(JBB): remove the border conditions for 64x64 blocks once its fixed
- // without this border check choose will fail on the border of every
- // non 64x64.
- if (cpi->speed < 5 ||
- mi_col + 8 > cm->cur_tile_mi_col_end ||
- mi_row + 8 > cm->cur_tile_mi_row_end) {
+ if (cpi->speed < 5) {
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist);
} else {
const int idx_str = cm->mode_info_stride * mi_row + mi_col;
MODE_INFO *m = cm->mi + idx_str;
- // set_partitioning(cpi, m, BLOCK_SIZE_SB8X8);
+ // set_partitioning(cpi, m, BLOCK_SIZE_SB64X64);
choose_partitioning(cpi, cm->mi, mi_row, mi_col);
rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist);
@@ -1430,7 +1436,6 @@
x->act_zbin_adj = 0;
cpi->seg0_idx = 0;
- vpx_memset(cpi->ref_pred_count, 0, sizeof(cpi->ref_pred_count));
xd->mode_info_stride = cm->mode_info_stride;
xd->frame_type = cm->frame_type;
@@ -1457,11 +1462,17 @@
xd->mode_info_context->mbmi.mode = DC_PRED;
xd->mode_info_context->mbmi.uv_mode = DC_PRED;
- vp9_zero(cpi->count_mb_ref_frame_usage)
vp9_zero(cpi->y_mode_count)
vp9_zero(cpi->y_uv_mode_count)
- vp9_zero(cpi->common.fc.mv_ref_ct)
+ vp9_zero(cm->fc.inter_mode_counts)
vp9_zero(cpi->partition_count);
+ vp9_zero(cpi->intra_inter_count);
+ vp9_zero(cpi->comp_inter_count);
+ vp9_zero(cpi->single_ref_count);
+ vp9_zero(cpi->comp_ref_count);
+ vp9_zero(cm->fc.tx_count_32x32p);
+ vp9_zero(cm->fc.tx_count_16x16p);
+ vp9_zero(cm->fc.tx_count_8x8p);
// Note: this memset assumes above_context[0], [1] and [2]
// are allocated as part of the same buffer.
@@ -1501,11 +1512,6 @@
// cpi->common.current_video_frame, cpi->common.show_frame,
// cm->frame_type);
- // Compute a modified set of reference frame probabilities to use when
- // prediction fails. These are based on the current general estimates for
- // this frame which may be updated with each iteration of the recode loop.
- vp9_compute_mod_refprobs(cm);
-
// debug output
#if DBG_PRNT_SEGMAP
{
@@ -1524,7 +1530,7 @@
cpi->skip_true_count[0] = cpi->skip_true_count[1] = cpi->skip_true_count[2] = 0;
cpi->skip_false_count[0] = cpi->skip_false_count[1] = cpi->skip_false_count[2] = 0;
- vp9_zero(cpi->switchable_interp_count);
+ vp9_zero(cm->fc.switchable_interp_count);
vp9_zero(cpi->best_switchable_interp_count);
xd->mode_info_context = cm->mi;
@@ -1557,11 +1563,6 @@
init_encode_frame_mb_context(cpi);
vpx_memset(cpi->rd_comp_pred_diff, 0, sizeof(cpi->rd_comp_pred_diff));
- vpx_memset(cpi->single_pred_count, 0, sizeof(cpi->single_pred_count));
- vpx_memset(cpi->comp_pred_count, 0, sizeof(cpi->comp_pred_count));
- vpx_memset(cpi->txfm_count_32x32p, 0, sizeof(cpi->txfm_count_32x32p));
- vpx_memset(cpi->txfm_count_16x16p, 0, sizeof(cpi->txfm_count_16x16p));
- vpx_memset(cpi->txfm_count_8x8p, 0, sizeof(cpi->txfm_count_8x8p));
vpx_memset(cpi->rd_tx_select_diff, 0, sizeof(cpi->rd_tx_select_diff));
vpx_memset(cpi->rd_tx_select_threshes, 0, sizeof(cpi->rd_tx_select_threshes));
@@ -1749,6 +1750,26 @@
}
void vp9_encode_frame(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+
+ // In the longer term the encoder should be generalized to match the
+ // decoder such that we allow compound where one of the 3 buffers has a
+ // differnt sign bias and that buffer is then the fixed ref. However, this
+ // requires further work in the rd loop. For now the only supported encoder
+ // side behaviour is where the ALT ref buffer has oppositie sign bias to
+ // the other two.
+ if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
+ cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
+ (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
+ cm->ref_frame_sign_bias[LAST_FRAME])) {
+ cm->allow_comp_inter_inter = 0;
+ } else {
+ cm->allow_comp_inter_inter = 1;
+ cm->comp_fixed_ref = ALTREF_FRAME;
+ cm->comp_var_ref[0] = LAST_FRAME;
+ cm->comp_var_ref[1] = GOLDEN_FRAME;
+ }
+
if (cpi->sf.RD) {
int i, frame_type, pred_type;
TXFM_MODE txfm_type;
@@ -1772,7 +1793,7 @@
frame_type = 2;
/* prediction (compound, single or hybrid) mode selection */
- if (frame_type == 3)
+ if (frame_type == 3 || !cm->allow_comp_inter_inter)
pred_type = SINGLE_PREDICTION_ONLY;
else if (cpi->rd_prediction_type_threshes[frame_type][1] >
cpi->rd_prediction_type_threshes[frame_type][0] &&
@@ -1826,11 +1847,6 @@
ALLOW_32X32 : TX_MODE_SELECT;
#endif
cpi->common.txfm_mode = txfm_type;
- if (txfm_type != TX_MODE_SELECT) {
- cpi->common.prob_tx[0] = 128;
- cpi->common.prob_tx[1] = 128;
- cpi->common.prob_tx[2] = 128;
- }
cpi->common.comp_pred_mode = pred_type;
encode_frame_internal(cpi);
@@ -1855,28 +1871,30 @@
int single_count_zero = 0;
int comp_count_zero = 0;
- for (i = 0; i < COMP_PRED_CONTEXTS; i++) {
- single_count_zero += cpi->single_pred_count[i];
- comp_count_zero += cpi->comp_pred_count[i];
+ for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
+ single_count_zero += cpi->comp_inter_count[i][0];
+ comp_count_zero += cpi->comp_inter_count[i][1];
}
if (comp_count_zero == 0) {
cpi->common.comp_pred_mode = SINGLE_PREDICTION_ONLY;
+ vp9_zero(cpi->comp_inter_count);
} else if (single_count_zero == 0) {
cpi->common.comp_pred_mode = COMP_PREDICTION_ONLY;
+ vp9_zero(cpi->comp_inter_count);
}
}
if (cpi->common.txfm_mode == TX_MODE_SELECT) {
- const int count4x4 = cpi->txfm_count_16x16p[TX_4X4] +
- cpi->txfm_count_32x32p[TX_4X4] +
- cpi->txfm_count_8x8p[TX_4X4];
- const int count8x8_lp = cpi->txfm_count_32x32p[TX_8X8] +
- cpi->txfm_count_16x16p[TX_8X8];
- const int count8x8_8x8p = cpi->txfm_count_8x8p[TX_8X8];
- const int count16x16_16x16p = cpi->txfm_count_16x16p[TX_16X16];
- const int count16x16_lp = cpi->txfm_count_32x32p[TX_16X16];
- const int count32x32 = cpi->txfm_count_32x32p[TX_32X32];
+ const int count4x4 = cm->fc.tx_count_16x16p[TX_4X4] +
+ cm->fc.tx_count_32x32p[TX_4X4] +
+ cm->fc.tx_count_8x8p[TX_4X4];
+ const int count8x8_lp = cm->fc.tx_count_32x32p[TX_8X8] +
+ cm->fc.tx_count_16x16p[TX_8X8];
+ const int count8x8_8x8p = cm->fc.tx_count_8x8p[TX_8X8];
+ const int count16x16_16x16p = cm->fc.tx_count_16x16p[TX_16X16];
+ const int count16x16_lp = cm->fc.tx_count_32x32p[TX_16X16];
+ const int count32x32 = cm->fc.tx_count_32x32p[TX_32X32];
if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
count32x32 == 0) {
@@ -1913,7 +1931,10 @@
++cpi->y_uv_mode_count[m][uvm];
if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
- ++cpi->y_mode_count[m];
+ const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
+ const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+ const int bsl = MIN(bwl, bhl);
+ ++cpi->y_mode_count[MIN(bsl, 3)][m];
} else {
int idx, idy;
int bw = 1 << b_width_log2(xd->mode_info_context->mbmi.sb_type);
@@ -1921,7 +1942,7 @@
for (idy = 0; idy < 2; idy += bh) {
for (idx = 0; idx < 2; idx += bw) {
int m = xd->mode_info_context->bmi[idy * 2 + idx].as_mode.first;
- ++cpi->y_mode_count[m];
+ ++cpi->y_mode_count[0][m];
}
}
}
@@ -1979,9 +2000,9 @@
// Increase zbin size to suppress noise
cpi->zbin_mode_boost = 0;
if (cpi->zbin_mode_boost_enabled) {
- if (mbmi->ref_frame != INTRA_FRAME) {
+ if (mbmi->ref_frame[0] != INTRA_FRAME) {
if (mbmi->mode == ZEROMV) {
- if (mbmi->ref_frame != LAST_FRAME)
+ if (mbmi->ref_frame[0] != LAST_FRAME)
cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
else
cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
@@ -1998,7 +2019,7 @@
vp9_update_zbin_extra(cpi, x);
}
- if (mbmi->ref_frame == INTRA_FRAME) {
+ if (mbmi->ref_frame[0] == INTRA_FRAME) {
vp9_encode_intra_block_y(cm, x, (bsize < BLOCK_SIZE_SB8X8) ?
BLOCK_SIZE_SB8X8 : bsize);
vp9_encode_intra_block_uv(cm, x, (bsize < BLOCK_SIZE_SB8X8) ?
@@ -2006,11 +2027,11 @@
if (output_enabled)
sum_intra_stats(cpi, x);
} else {
- int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame)];
+ int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[0])];
YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx];
YV12_BUFFER_CONFIG *second_ref_fb = NULL;
- if (mbmi->second_ref_frame > 0) {
- idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->second_ref_frame)];
+ if (mbmi->ref_frame[1] > 0) {
+ idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[1])];
second_ref_fb = &cm->yv12_fb[idx];
}
@@ -2024,7 +2045,7 @@
: bsize);
}
- if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
+ if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) {
vp9_tokenize_sb(cpi, xd, t, !output_enabled,
(bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize);
} else if (!x->skip) {
@@ -2054,20 +2075,20 @@
if (output_enabled) {
if (cm->txfm_mode == TX_MODE_SELECT &&
mbmi->sb_type >= BLOCK_SIZE_SB8X8 &&
- !(mbmi->ref_frame != INTRA_FRAME && (mbmi->mb_skip_coeff ||
+ !(mbmi->ref_frame[0] != INTRA_FRAME && (mbmi->mb_skip_coeff ||
vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
if (bsize >= BLOCK_SIZE_SB32X32) {
- cpi->txfm_count_32x32p[mbmi->txfm_size]++;
+ cm->fc.tx_count_32x32p[mbmi->txfm_size]++;
} else if (bsize >= BLOCK_SIZE_MB16X16) {
- cpi->txfm_count_16x16p[mbmi->txfm_size]++;
+ cm->fc.tx_count_16x16p[mbmi->txfm_size]++;
} else {
- cpi->txfm_count_8x8p[mbmi->txfm_size]++;
+ cm->fc.tx_count_8x8p[mbmi->txfm_size]++;
}
} else {
int x, y;
TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ? TX_32X32 : cm->txfm_mode;
// The new intra coding scheme requires no change of transform size
- if (mi->mbmi.ref_frame != INTRA_FRAME) {
+ if (mi->mbmi.ref_frame[0] != INTRA_FRAME) {
if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32)
sz = TX_16X16;
if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16)
diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c
index 57041a9..c78882a 100644
--- a/vp9/encoder/vp9_encodeintra.c
+++ b/vp9/encoder/vp9_encodeintra.c
@@ -20,7 +20,7 @@
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
(void) cpi;
mbmi->mode = DC_PRED;
- mbmi->ref_frame = INTRA_FRAME;
+ mbmi->ref_frame[0] = INTRA_FRAME;
if (use_16x16_pred) {
mbmi->txfm_size = TX_16X16;
vp9_encode_intra_block_y(&cpi->common, x, BLOCK_SIZE_MB16X16);
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 389c5d8..aa9cf8d 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -118,7 +118,7 @@
int plane, int block, BLOCK_SIZE_TYPE bsize,
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
TX_SIZE tx_size) {
- const int ref = mb->e_mbd.mode_info_context->mbmi.ref_frame != INTRA_FRAME;
+ const int ref = mb->e_mbd.mode_info_context->mbmi.ref_frame[0] != INTRA_FRAME;
MACROBLOCKD *const xd = &mb->e_mbd;
vp9_token_state tokens[1025][2];
unsigned best_index[1025][2];
@@ -179,7 +179,7 @@
/* Now set up a Viterbi trellis to evaluate alternative roundings. */
rdmult = mb->rdmult * err_mult;
- if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME)
+ if (mb->e_mbd.mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
rdmult = (rdmult * 9) >> 4;
rddiv = mb->rddiv;
memset(best_index, 0, sizeof(best_index));
@@ -615,10 +615,14 @@
TX_TYPE tx_type;
int mode, b_mode;
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
+ extend_for_intra(xd, plane, block, bsize, ss_txfrm_size);
+ }
+
mode = plane == 0? mbmi->mode: mbmi->uv_mode;
if (plane == 0 &&
mbmi->sb_type < BLOCK_SIZE_SB8X8 &&
- mbmi->ref_frame == INTRA_FRAME)
+ mbmi->ref_frame[0] == INTRA_FRAME)
b_mode = xd->mode_info_context->bmi[ib].as_mode.first;
else
b_mode = mode;
@@ -684,7 +688,6 @@
MACROBLOCKD* const xd = &x->e_mbd;
struct optimize_ctx ctx;
struct encode_b_args arg = {cm, x, &ctx};
-
foreach_transformed_block_uv(xd, bsize, encode_block_intra, &arg);
}
diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c
index 2b6dfba..a582d18 100644
--- a/vp9/encoder/vp9_encodemv.c
+++ b/vp9/encoder/vp9_encodemv.c
@@ -584,7 +584,7 @@
mv.col = (pi->bmi[i].mv.as_mv.col - best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount,
x->e_mbd.allow_high_precision_mv);
- if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) {
+ if (x->e_mbd.mode_info_context->mbmi.ref_frame[1] > INTRA_FRAME) {
mv.row = pi->bmi[i].second_mv.as_mv.row -
second_best_ref_mv->as_mv.row;
mv.col = pi->bmi[i].second_mv.as_mv.col -
@@ -600,7 +600,7 @@
mv.col = (mbmi->mv[0].as_mv.col - best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount,
x->e_mbd.allow_high_precision_mv);
- if (mbmi->second_ref_frame > 0) {
+ if (mbmi->ref_frame[1] > INTRA_FRAME) {
mv.row = (mbmi->mv[1].as_mv.row - second_best_ref_mv->as_mv.row);
mv.col = (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount,
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index b07e37d..001129d 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -523,7 +523,7 @@
xd->left_available = (mb_col != 0);
xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_MB16X16;
- xd->mode_info_context->mbmi.ref_frame = INTRA_FRAME;
+ xd->mode_info_context->mbmi.ref_frame[0] = INTRA_FRAME;
// do intra 16x16 prediction
this_error = vp9_encode_intra(cpi, x, use_dc_pred);
@@ -620,7 +620,8 @@
this_error = motion_error;
vp9_set_mbmode_and_mvs(x, NEWMV, &mv);
xd->mode_info_context->mbmi.txfm_size = TX_4X4;
- xd->mode_info_context->mbmi.ref_frame = LAST_FRAME;
+ xd->mode_info_context->mbmi.ref_frame[0] = LAST_FRAME;
+ xd->mode_info_context->mbmi.ref_frame[1] = NONE;
vp9_build_inter_predictors_sby(xd, mb_row << 1,
mb_col << 1,
BLOCK_SIZE_MB16X16);
diff --git a/vp9/encoder/vp9_modecosts.c b/vp9/encoder/vp9_modecosts.c
index 099a044..f2e4ce4 100644
--- a/vp9/encoder/vp9_modecosts.c
+++ b/vp9/encoder/vp9_modecosts.c
@@ -28,7 +28,7 @@
}
// TODO(rbultje) separate tables for superblock costing?
- vp9_cost_tokens(c->mb.mbmode_cost, x->fc.y_mode_prob,
+ vp9_cost_tokens(c->mb.mbmode_cost, x->fc.y_mode_prob[1],
vp9_intra_mode_tree);
vp9_cost_tokens(c->mb.intra_uv_mode_cost[1],
x->fc.uv_mode_prob[VP9_INTRA_MODES - 1], vp9_intra_mode_tree);
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index a5659d6..73220dc 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -466,8 +466,9 @@
void vp9_update_mode_context_stats(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
int i, j;
- unsigned int (*mv_ref_ct)[VP9_MVREFS - 1][2] = cm->fc.mv_ref_ct;
- int64_t (*mv_ref_stats)[VP9_MVREFS - 1][2] = cpi->mv_ref_stats;
+ unsigned int (*inter_mode_counts)[VP9_INTER_MODES - 1][2] =
+ cm->fc.inter_mode_counts;
+ int64_t (*mv_ref_stats)[VP9_INTER_MODES - 1][2] = cpi->mv_ref_stats;
FILE *f;
// Read the past stats counters
@@ -481,9 +482,9 @@
// Add in the values for this frame
for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
- for (j = 0; j < VP9_MVREFS - 1; j++) {
- mv_ref_stats[i][j][0] += (int64_t)mv_ref_ct[i][j][0];
- mv_ref_stats[i][j][1] += (int64_t)mv_ref_ct[i][j][1];
+ for (j = 0; j < VP9_INTER_MODES - 1; j++) {
+ mv_ref_stats[i][j][0] += (int64_t)inter_mode_counts[i][j][0];
+ mv_ref_stats[i][j][1] += (int64_t)inter_mode_counts[i][j][1];
}
}
@@ -498,13 +499,14 @@
int i, j;
fprintf(f, "#include \"vp9_entropy.h\"\n");
- fprintf(f,
- "const int vp9_mode_contexts[INTER_MODE_CONTEXTS][VP9_MVREFS - 1] =");
+ fprintf(
+ f,
+ "const int inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1] =");
fprintf(f, "{\n");
for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
fprintf(f, " {/* %d */ ", j);
fprintf(f, " ");
- for (i = 0; i < VP9_MVREFS - 1; i++) {
+ for (i = 0; i < VP9_INTER_MODES - 1; i++) {
int this_prob;
int64_t count = cpi->mv_ref_stats[j][i][0] + cpi->mv_ref_stats[j][i][1];
if (count)
@@ -573,10 +575,8 @@
cpi->mb.e_mbd.ref_lf_deltas[GOLDEN_FRAME] = -2;
cpi->mb.e_mbd.ref_lf_deltas[ALTREF_FRAME] = -2;
- cpi->mb.e_mbd.mode_lf_deltas[0] = 4; // I4X4_PRED
- cpi->mb.e_mbd.mode_lf_deltas[1] = -2; // Zero
- cpi->mb.e_mbd.mode_lf_deltas[2] = 2; // New mv
- cpi->mb.e_mbd.mode_lf_deltas[3] = 4; // Split mv
+ cpi->mb.e_mbd.mode_lf_deltas[0] = 0; // Zero
+ cpi->mb.e_mbd.mode_lf_deltas[1] = 0; // New mv
}
static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) {
@@ -621,25 +621,20 @@
sf->thresh_mult[THR_SPLITG ] += speed_multiplier * 2500;
sf->thresh_mult[THR_SPLITA ] += speed_multiplier * 2500;
- sf->thresh_mult[THR_COMP_ZEROLG ] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_ZEROLA ] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_ZEROGA ] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_NEARESTLG] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARESTLA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARESTGA] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_NEARLG ] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARLA ] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARGA ] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_NEWLG ] += speed_multiplier * 2000;
sf->thresh_mult[THR_COMP_NEWLA ] += speed_multiplier * 2000;
sf->thresh_mult[THR_COMP_NEWGA ] += speed_multiplier * 2000;
sf->thresh_mult[THR_COMP_SPLITLA ] += speed_multiplier * 4500;
sf->thresh_mult[THR_COMP_SPLITGA ] += speed_multiplier * 4500;
- sf->thresh_mult[THR_COMP_SPLITLG ] += speed_multiplier * 4500;
if (speed > 4) {
for (i = 0; i < MAX_MODES; ++i)
@@ -683,14 +678,6 @@
sf->thresh_mult[THR_SPLITA ] = INT_MAX;
}
- if ((cpi->ref_frame_flags & (VP9_LAST_FLAG | VP9_GOLD_FLAG)) !=
- (VP9_LAST_FLAG | VP9_GOLD_FLAG)) {
- sf->thresh_mult[THR_COMP_ZEROLG ] = INT_MAX;
- sf->thresh_mult[THR_COMP_NEARESTLG] = INT_MAX;
- sf->thresh_mult[THR_COMP_NEARLG ] = INT_MAX;
- sf->thresh_mult[THR_COMP_NEWLG ] = INT_MAX;
- sf->thresh_mult[THR_COMP_SPLITLG ] = INT_MAX;
- }
if ((cpi->ref_frame_flags & (VP9_LAST_FLAG | VP9_ALT_FLAG)) !=
(VP9_LAST_FLAG | VP9_ALT_FLAG)) {
sf->thresh_mult[THR_COMP_ZEROLA ] = INT_MAX;
@@ -734,18 +721,18 @@
sf->quarter_pixel_search = 1;
sf->half_pixel_search = 1;
sf->iterative_sub_pixel = 1;
- sf->no_skip_block4x4_search = 1;
sf->optimize_coefficients = !cpi->oxcf.lossless;
sf->first_step = 0;
sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
- sf->comp_inter_joint_search = 1;
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZE_AB4X4;
+ sf->adpative_rd_thresh = 0;
+
#if CONFIG_MULTIPLE_ARF
// Switch segmentation off.
sf->static_segmentation = 0;
#else
sf->static_segmentation = 0;
#endif
- sf->mb16_breakout = 0;
switch (mode) {
case 0: // best quality mode
@@ -757,14 +744,13 @@
// Switch segmentation off.
sf->static_segmentation = 0;
#else
- sf->static_segmentation = 0;
+ sf->static_segmentation = 0;
#endif
- sf->mb16_breakout = 0;
-
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
+ sf->adpative_rd_thresh = 1;
if (speed > 0) {
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->optimize_coefficients = 0;
- sf->no_skip_block4x4_search = 0;
- sf->comp_inter_joint_search = 0;
sf->first_step = 1;
}
break;
@@ -1310,20 +1296,6 @@
cpi->frames_till_gf_update_due = 0;
cpi->gf_overspend_bits = 0;
cpi->non_gf_bitrate_adjustment = 0;
- cm->prob_last_coded = 128;
- cm->prob_gf_coded = 128;
- cm->prob_intra_coded = 63;
- for (i = 0; i < COMP_PRED_CONTEXTS; i++)
- cm->prob_comppred[i] = 128;
- for (i = 0; i < TX_SIZE_MAX_SB - 1; i++)
- cm->prob_tx[i] = 128;
-
- // Prime the recent reference frame usage counters.
- // Hereafter they will be maintained as a sort of moving average
- cpi->recent_ref_frame_usage[INTRA_FRAME] = 1;
- cpi->recent_ref_frame_usage[LAST_FRAME] = 1;
- cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1;
- cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1;
// Set reference frame sign bias for ALTREF frame to 1 (for now)
cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1;
@@ -2082,22 +2054,6 @@
cpi->refresh_golden_frame = 0;
cpi->common.frames_since_golden = 0;
- // if ( cm->frame_type == KEY_FRAME )
- // {
- cpi->recent_ref_frame_usage[INTRA_FRAME] = 1;
- cpi->recent_ref_frame_usage[LAST_FRAME] = 1;
- cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1;
- cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1;
- // }
- // else
- // {
- // // Carry a portion of count over to beginning of next gf sequence
- // cpi->recent_ref_frame_usage[INTRA_FRAME] >>= 5;
- // cpi->recent_ref_frame_usage[LAST_FRAME] >>= 5;
- // cpi->recent_ref_frame_usage[GOLDEN_FRAME] >>= 5;
- // cpi->recent_ref_frame_usage[ALTREF_FRAME] >>= 5;
- // }
-
// ******** Fixed Q test code only ************
// If we are going to use the ALT reference for the next group of frames set a flag to say so.
if (cpi->oxcf.fixed_q >= 0 &&
@@ -2122,13 +2078,6 @@
cpi->common.frames_till_alt_ref_frame--;
cpi->common.frames_since_golden++;
-
- if (cpi->common.frames_since_golden > 1) {
- cpi->recent_ref_frame_usage[INTRA_FRAME] += cpi->count_mb_ref_frame_usage[INTRA_FRAME];
- cpi->recent_ref_frame_usage[LAST_FRAME] += cpi->count_mb_ref_frame_usage[LAST_FRAME];
- cpi->recent_ref_frame_usage[GOLDEN_FRAME] += cpi->count_mb_ref_frame_usage[GOLDEN_FRAME];
- cpi->recent_ref_frame_usage[ALTREF_FRAME] += cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
- }
}
}
@@ -3112,6 +3061,10 @@
vp9_copy(cpi->common.fc.y_mode_counts, cpi->y_mode_count);
vp9_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count);
vp9_copy(cpi->common.fc.partition_counts, cpi->partition_count);
+ vp9_copy(cm->fc.intra_inter_count, cpi->intra_inter_count);
+ vp9_copy(cm->fc.comp_inter_count, cpi->comp_inter_count);
+ vp9_copy(cm->fc.single_ref_count, cpi->single_ref_count);
+ vp9_copy(cm->fc.comp_ref_count, cpi->comp_ref_count);
cpi->common.fc.NMVcount = cpi->NMVcount;
if (!cpi->common.error_resilient_mode &&
!cpi->common.frame_parallel_decoding_mode) {
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index dece457..b8a60d2 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -47,7 +47,7 @@
#define KEY_FRAME_CONTEXT 5
-#define MAX_MODES 41
+#define MAX_MODES 36
#define MIN_THRESHMULT 32
#define MAX_THRESHMULT 512
@@ -65,29 +65,31 @@
int nmvcosts_hp[2][MV_VALS];
vp9_prob segment_pred_probs[PREDICTION_PROBS];
- unsigned char ref_pred_probs_update[PREDICTION_PROBS];
- vp9_prob ref_pred_probs[PREDICTION_PROBS];
- vp9_prob prob_comppred[COMP_PRED_CONTEXTS];
+ vp9_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
+ vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS];
+ vp9_prob single_ref_prob[REF_CONTEXTS][2];
+ vp9_prob comp_ref_prob[REF_CONTEXTS];
unsigned char *last_frame_seg_map_copy;
// 0 = Intra, Last, GF, ARF
signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS];
- // 0 = I4X4_PRED, ZERO_MV, MV, SPLIT
+ // 0 = ZERO_MV, MV
signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
vp9_coeff_probs_model coef_probs[TX_SIZE_MAX_SB][BLOCK_TYPES];
- vp9_prob y_mode_prob[VP9_INTRA_MODES - 1]; /* interframe intra mode probs */
+ vp9_prob y_mode_prob[4][VP9_INTRA_MODES - 1];
vp9_prob uv_mode_prob[VP9_INTRA_MODES][VP9_INTRA_MODES - 1];
- vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
+ vp9_prob partition_prob[2][NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS - 1];
- int mv_ref_ct[INTER_MODE_CONTEXTS][VP9_MVREFS - 1][2];
- int vp9_mode_contexts[INTER_MODE_CONTEXTS][VP9_MVREFS - 1];
+ int inter_mode_counts[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2];
+ vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
+ vp9_prob tx_probs[TX_SIZE_PROBS];
} CODING_CONTEXT;
typedef struct {
@@ -174,10 +176,6 @@
THR_B_PRED,
- THR_COMP_ZEROLG,
- THR_COMP_NEARESTLG,
- THR_COMP_NEARLG,
-
THR_COMP_ZEROLA,
THR_COMP_NEARESTLA,
THR_COMP_NEARLA,
@@ -186,11 +184,9 @@
THR_COMP_NEARESTGA,
THR_COMP_NEARGA,
- THR_COMP_NEWLG,
THR_COMP_NEWLA,
THR_COMP_NEWGA,
- THR_COMP_SPLITLG,
THR_COMP_SPLITLA,
THR_COMP_SPLITGA,
} THR_MODES;
@@ -213,11 +209,10 @@
int max_step_search_steps;
int first_step;
int optimize_coefficients;
- int no_skip_block4x4_search;
int search_best_filter;
- int mb16_breakout;
int static_segmentation;
- int comp_inter_joint_search;
+ int comp_inter_joint_search_thresh;
+ int adpative_rd_thresh;
} SPEED_FEATURES;
enum BlockSize {
@@ -320,16 +315,19 @@
unsigned int mode_chosen_counts[MAX_MODES];
int rd_thresh_mult[MAX_MODES];
- int rd_baseline_thresh[MAX_MODES];
- int rd_threshes[MAX_MODES];
+ int rd_baseline_thresh[BLOCK_SIZE_TYPES][MAX_MODES];
+ int rd_threshes[BLOCK_SIZE_TYPES][MAX_MODES];
+ int rd_thresh_freq_fact[BLOCK_SIZE_TYPES][MAX_MODES];
+
int64_t rd_comp_pred_diff[NB_PREDICTION_TYPES];
int rd_prediction_type_threshes[4][NB_PREDICTION_TYPES];
- int comp_pred_count[COMP_PRED_CONTEXTS];
- int single_pred_count[COMP_PRED_CONTEXTS];
+ unsigned int intra_inter_count[INTRA_INTER_CONTEXTS][2];
+ unsigned int comp_inter_count[COMP_INTER_CONTEXTS][2];
+ unsigned int single_ref_count[REF_CONTEXTS][2][2];
+ unsigned int comp_ref_count[REF_CONTEXTS][2];
+
// FIXME contextualize
- int txfm_count_32x32p[TX_SIZE_MAX_SB];
- int txfm_count_16x16p[TX_SIZE_MAX_SB - 1];
- int txfm_count_8x8p[TX_SIZE_MAX_SB - 2];
+
int64_t rd_tx_select_diff[NB_TXFM_MODES];
int rd_tx_select_threshes[4][NB_TXFM_MODES];
@@ -405,7 +403,7 @@
int cq_target_quality;
- int y_mode_count[VP9_INTRA_MODES];
+ int y_mode_count[4][VP9_INTRA_MODES];
int y_uv_mode_count[VP9_INTRA_MODES][VP9_INTRA_MODES];
unsigned int partition_count[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
@@ -432,7 +430,6 @@
int mbgraph_n_frames; // number of frames filled in the above
int static_mb_pct; // % forced skip mbs by segmentation
int seg0_progress, seg0_idx, seg0_cnt;
- int ref_pred_count[3][2];
int decimation_factor;
int decimation_count;
@@ -453,12 +450,8 @@
vp9_prob last_skip_false_probs[3][MBSKIP_CONTEXTS];
int last_skip_probs_q[3];
- int recent_ref_frame_usage[MAX_REF_FRAMES];
- int count_mb_ref_frame_usage[MAX_REF_FRAMES];
int ref_frame_flags;
- unsigned char ref_pred_probs_update[PREDICTION_PROBS];
-
SPEED_FEATURES sf;
int error_bins[1024];
@@ -597,7 +590,7 @@
#endif
#ifdef ENTROPY_STATS
- int64_t mv_ref_stats[INTER_MODE_CONTEXTS][VP9_MVREFS - 1][2];
+ int64_t mv_ref_stats[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2];
#endif
} VP9_COMP;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 748c3a8..60ca355 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -122,16 +122,18 @@
vp9_copy(cc->nmvcosts, cpi->mb.nmvcosts);
vp9_copy(cc->nmvcosts_hp, cpi->mb.nmvcosts_hp);
- vp9_copy(cc->vp9_mode_contexts, cm->fc.vp9_mode_contexts);
+ vp9_copy(cc->inter_mode_probs, cm->fc.inter_mode_probs);
vp9_copy(cc->y_mode_prob, cm->fc.y_mode_prob);
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->ref_pred_probs_update, cpi->ref_pred_probs_update);
- vp9_copy(cc->ref_pred_probs, cm->ref_pred_probs);
- vp9_copy(cc->prob_comppred, cm->prob_comppred);
+
+ vp9_copy(cc->intra_inter_prob, cm->fc.intra_inter_prob);
+ vp9_copy(cc->comp_inter_prob, cm->fc.comp_inter_prob);
+ vp9_copy(cc->single_ref_prob, cm->fc.single_ref_prob);
+ vp9_copy(cc->comp_ref_prob, cm->fc.comp_ref_prob);
vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy,
cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols));
@@ -141,6 +143,7 @@
vp9_copy(cc->coef_probs, cm->fc.coef_probs);
vp9_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob);
+ vp9_copy(cc->tx_probs, cm->fc.tx_probs);
}
void vp9_restore_coding_context(VP9_COMP *cpi) {
@@ -156,16 +159,18 @@
vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts);
vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp);
- vp9_copy(cm->fc.vp9_mode_contexts, cc->vp9_mode_contexts);
+ vp9_copy(cm->fc.inter_mode_probs, cc->inter_mode_probs);
vp9_copy(cm->fc.y_mode_prob, cc->y_mode_prob);
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(cpi->ref_pred_probs_update, cc->ref_pred_probs_update);
- vp9_copy(cm->ref_pred_probs, cc->ref_pred_probs);
- vp9_copy(cm->prob_comppred, cc->prob_comppred);
+
+ vp9_copy(cm->fc.intra_inter_prob, cc->intra_inter_prob);
+ vp9_copy(cm->fc.comp_inter_prob, cc->comp_inter_prob);
+ vp9_copy(cm->fc.single_ref_prob, cc->single_ref_prob);
+ vp9_copy(cm->fc.comp_ref_prob, cc->comp_ref_prob);
vpx_memcpy(cm->last_frame_seg_map,
cpi->coding_context.last_frame_seg_map_copy,
@@ -176,6 +181,7 @@
vp9_copy(cm->fc.coef_probs, cc->coef_probs);
vp9_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob);
+ vp9_copy(cm->fc.tx_probs, cc->tx_probs);
}
void vp9_setup_key_frame(VP9_COMP *cpi) {
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index aead60b..0fea2b9 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -90,27 +90,32 @@
{I4X4_PRED, INTRA_FRAME, NONE},
/* compound prediction modes */
- {ZEROMV, LAST_FRAME, GOLDEN_FRAME},
- {NEARESTMV, LAST_FRAME, GOLDEN_FRAME},
- {NEARMV, LAST_FRAME, GOLDEN_FRAME},
-
- {ZEROMV, ALTREF_FRAME, LAST_FRAME},
- {NEARESTMV, ALTREF_FRAME, LAST_FRAME},
- {NEARMV, ALTREF_FRAME, LAST_FRAME},
+ {ZEROMV, LAST_FRAME, ALTREF_FRAME},
+ {NEARESTMV, LAST_FRAME, ALTREF_FRAME},
+ {NEARMV, LAST_FRAME, ALTREF_FRAME},
{ZEROMV, GOLDEN_FRAME, ALTREF_FRAME},
{NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME},
{NEARMV, GOLDEN_FRAME, ALTREF_FRAME},
- {NEWMV, LAST_FRAME, GOLDEN_FRAME},
- {NEWMV, ALTREF_FRAME, LAST_FRAME },
+ {NEWMV, LAST_FRAME, ALTREF_FRAME},
{NEWMV, GOLDEN_FRAME, ALTREF_FRAME},
- {SPLITMV, LAST_FRAME, GOLDEN_FRAME},
- {SPLITMV, ALTREF_FRAME, LAST_FRAME },
+ {SPLITMV, LAST_FRAME, ALTREF_FRAME},
{SPLITMV, GOLDEN_FRAME, ALTREF_FRAME},
};
+// The baseline rd thresholds for breaking out of the rd loop for
+// certain modes are assumed to be based on 8x8 blocks.
+// This table is used to correct for blocks size.
+// The factors here are << 2 (2 = x0.5, 32 = x8 etc).
+static int rd_thresh_block_size_factor[BLOCK_SIZE_TYPES] =
+ {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32};
+
+#define BASE_RD_THRESH_FREQ_FACT 16
+#define MAX_RD_THRESH_FREQ_FACT 32
+#define MAX_RD_THRESH_FREQ_INC 1
+
static void fill_token_costs(vp9_coeff_count (*c)[BLOCK_TYPES],
vp9_coeff_count (*cnoskip)[BLOCK_TYPES],
vp9_coeff_probs_model (*p)[BLOCK_TYPES]) {
@@ -175,7 +180,7 @@
void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex) {
- int q, i;
+ int q, i, bsize;
vp9_clear_system_state(); // __asm emms;
@@ -207,24 +212,43 @@
cpi->RDDIV = 1;
cpi->RDMULT /= 100;
- for (i = 0; i < MAX_MODES; i++) {
- if (cpi->sf.thresh_mult[i] < INT_MAX) {
- cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100;
- } else {
- cpi->rd_threshes[i] = INT_MAX;
+ for (bsize = 0; bsize < BLOCK_SIZE_TYPES; ++bsize) {
+ for (i = 0; i < MAX_MODES; ++i) {
+ // Threshold here seem unecessarily harsh but fine given actual
+ // range of values used for cpi->sf.thresh_mult[]
+ int thresh_max = INT_MAX / (q * rd_thresh_block_size_factor[bsize]);
+
+ // *4 relates to the scaling of rd_thresh_block_size_factor[]
+ if ((int64_t)cpi->sf.thresh_mult[i] < thresh_max) {
+ cpi->rd_threshes[bsize][i] =
+ cpi->sf.thresh_mult[i] * q *
+ rd_thresh_block_size_factor[bsize] / (4 * 100);
+ } else {
+ cpi->rd_threshes[bsize][i] = INT_MAX;
+ }
+ cpi->rd_baseline_thresh[bsize][i] = cpi->rd_threshes[bsize][i];
+ cpi->rd_thresh_freq_fact[bsize][i] = BASE_RD_THRESH_FREQ_FACT;
}
- cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
}
} else {
cpi->RDDIV = 100;
- for (i = 0; i < MAX_MODES; i++) {
- if (cpi->sf.thresh_mult[i] < (INT_MAX / q)) {
- cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q;
- } else {
- cpi->rd_threshes[i] = INT_MAX;
+ for (bsize = 0; bsize < BLOCK_SIZE_TYPES; ++bsize) {
+ for (i = 0; i < MAX_MODES; i++) {
+ // Threshold here seem unecessarily harsh but fine given actual
+ // range of values used for cpi->sf.thresh_mult[]
+ int thresh_max = INT_MAX / (q * rd_thresh_block_size_factor[bsize]);
+
+ if (cpi->sf.thresh_mult[i] < thresh_max) {
+ cpi->rd_threshes[bsize][i] =
+ cpi->sf.thresh_mult[i] * q *
+ rd_thresh_block_size_factor[bsize] / 4;
+ } else {
+ cpi->rd_threshes[bsize][i] = INT_MAX;
+ }
+ cpi->rd_baseline_thresh[bsize][i] = cpi->rd_threshes[bsize][i];
+ cpi->rd_thresh_freq_fact[bsize][i] = BASE_RD_THRESH_FREQ_FACT;
}
- cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
}
}
@@ -234,7 +258,7 @@
for (i = 0; i < NUM_PARTITION_CONTEXTS; i++)
vp9_cost_tokens(cpi->mb.partition_cost[i],
- cpi->common.fc.partition_prob[i],
+ cpi->common.fc.partition_prob[cpi->common.frame_type][i],
vp9_partition_tree);
/*rough estimate for costing*/
@@ -276,7 +300,7 @@
const int eob = xd->plane[plane].eobs[block];
const int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[plane].qcoeff,
block, 16);
- const int ref = mbmi->ref_frame != INTRA_FRAME;
+ const int ref = mbmi->ref_frame[0] != INTRA_FRAME;
unsigned int (*token_costs)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] =
mb->token_costs[tx_size][type][ref];
ENTROPY_CONTEXT above_ec, left_ec;
@@ -396,6 +420,7 @@
int *d, int *distortion,
int *s, int *skip,
int64_t txfm_cache[NB_TXFM_MODES],
+ BLOCK_SIZE_TYPE bs,
TX_SIZE max_txfm_size) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -405,13 +430,15 @@
int n, m;
int s0, s1;
+ int tx_probs_offset = get_tx_probs_offset(bs);
+
for (n = TX_4X4; n <= max_txfm_size; n++) {
r[n][1] = r[n][0];
for (m = 0; m <= n - (n == max_txfm_size); m++) {
if (m == n)
- r[n][1] += vp9_cost_zero(cm->prob_tx[m]);
+ r[n][1] += vp9_cost_zero(cm->fc.tx_probs[tx_probs_offset + m]);
else
- r[n][1] += vp9_cost_one(cm->prob_tx[m]);
+ r[n][1] += vp9_cost_one(cm->fc.tx_probs[tx_probs_offset + m]);
}
}
@@ -505,33 +532,48 @@
return sum > INT_MAX ? INT_MAX : (int)sum;
}
-static int rdcost_plane(VP9_COMMON *const cm, MACROBLOCK *x,
- int plane, BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) {
- MACROBLOCKD *const xd = &x->e_mbd;
+struct rdcost_block_args {
+ VP9_COMMON *cm;
+ MACROBLOCK *x;
+ ENTROPY_CONTEXT t_above[16];
+ ENTROPY_CONTEXT t_left[16];
+ TX_SIZE tx_size;
+ int bw;
+ int bh;
+ int cost;
+};
+
+static void rdcost_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
+ int ss_txfrm_size, void *arg) {
+ struct rdcost_block_args* args = arg;
+ int x_idx, y_idx;
+ MACROBLOCKD * const xd = &args->x->e_mbd;
+
+ txfrm_block_to_raster_xy(xd, bsize, plane, block, args->tx_size * 2, &x_idx,
+ &y_idx);
+
+ args->cost += cost_coeffs(args->cm, args->x, plane, block,
+ xd->plane[plane].plane_type, args->t_above + x_idx,
+ args->t_left + y_idx, args->tx_size,
+ args->bw * args->bh);
+}
+
+static int rdcost_plane(VP9_COMMON * const cm, MACROBLOCK *x, int plane,
+ BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) {
+ MACROBLOCKD * const xd = &x->e_mbd;
const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x;
const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y;
const int bw = 1 << bwl, bh = 1 << bhl;
- ENTROPY_CONTEXT t_above[16], t_left[16];
- int block, cost;
+ struct rdcost_block_args args = { cm, x, { 0 }, { 0 }, tx_size, bw, bh, 0 };
- vpx_memcpy(&t_above, xd->plane[plane].above_context,
+ vpx_memcpy(&args.t_above, xd->plane[plane].above_context,
sizeof(ENTROPY_CONTEXT) * bw);
- vpx_memcpy(&t_left, xd->plane[plane].left_context,
+ vpx_memcpy(&args.t_left, xd->plane[plane].left_context,
sizeof(ENTROPY_CONTEXT) * bh);
- cost = 0;
- for (block = 0; block < bw * bh; block += 1 << (tx_size * 2)) {
- int x_idx, y_idx;
+ foreach_transformed_block_in_plane(xd, bsize, plane, rdcost_block, &args);
- txfrm_block_to_raster_xy(xd, bsize, plane, block, tx_size * 2,
- &x_idx, &y_idx);
-
- cost += cost_coeffs(cm, x, plane, block, xd->plane[plane].plane_type,
- t_above + x_idx, t_left + y_idx,
- tx_size, bw * bh);
- }
-
- return cost;
+ return args.cost;
}
static int rdcost_uv(VP9_COMMON *const cm, MACROBLOCK *x,
@@ -549,7 +591,11 @@
BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) {
MACROBLOCKD *const xd = &x->e_mbd;
xd->mode_info_context->mbmi.txfm_size = tx_size;
- vp9_xform_quant_sby(cm, x, bsize);
+
+ if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
+ vp9_encode_intra_block_y(cm, x, bsize);
+ else
+ vp9_xform_quant_sby(cm, x, bsize);
*distortion = block_error_sby(x, bsize, tx_size == TX_32X32 ? 0 : 2);
*rate = rdcost_plane(cm, x, 0, bsize, tx_size);
@@ -565,7 +611,10 @@
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
- vp9_subtract_sby(x, bs);
+ assert(bs == mbmi->sb_type);
+
+ if (mbmi->ref_frame[0] > INTRA_FRAME)
+ vp9_subtract_sby(x, bs);
if (cpi->speed > 4) {
if (bs >= BLOCK_SIZE_SB32X32) {
@@ -577,6 +626,7 @@
} else {
mbmi->txfm_size = TX_4X4;
}
+ vpx_memset(txfm_cache, 0, NB_TXFM_MODES * sizeof(int64_t));
super_block_yrd_for_txfm(cm, x, rate, distortion, skip, bs,
mbmi->txfm_size);
return;
@@ -592,7 +642,8 @@
super_block_yrd_for_txfm(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4], bs,
TX_4X4);
- choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, skip, txfm_cache,
+ choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
+ skip, txfm_cache, bs,
TX_32X32 - (bs < BLOCK_SIZE_SB32X32)
- (bs < BLOCK_SIZE_MB16X16));
}
@@ -821,6 +872,7 @@
int64_t local_txfm_cache[NB_TXFM_MODES];
MODE_INFO *const mic = xd->mode_info_context;
const int mis = xd->mode_info_stride;
+
if (cpi->common.frame_type == KEY_FRAME) {
const MB_PREDICTION_MODE A = above_block_mode(mic, 0, mis);
const MB_PREDICTION_MODE L = xd->left_available ?
@@ -829,7 +881,6 @@
bmode_costs = x->y_mode_costs[A][L];
}
x->e_mbd.mode_info_context->mbmi.mode = mode;
- vp9_build_intra_predictors_sby_s(&x->e_mbd, bsize);
super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
bsize, local_txfm_cache);
@@ -867,7 +918,10 @@
int *skippable, BLOCK_SIZE_TYPE bsize,
TX_SIZE uv_tx_size) {
MACROBLOCKD *const xd = &x->e_mbd;
- vp9_xform_quant_sbuv(cm, x, bsize);
+ if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
+ vp9_encode_intra_block_uv(cm, x, bsize);
+ else
+ vp9_xform_quant_sbuv(cm, x, bsize);
*distortion = block_error_sbuv(x, bsize, uv_tx_size == TX_32X32 ? 0 : 2);
*rate = rdcost_uv(cm, x, bsize, uv_tx_size);
@@ -880,7 +934,8 @@
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
- vp9_subtract_sbuv(x, bsize);
+ if (mbmi->ref_frame[0] > INTRA_FRAME)
+ vp9_subtract_sbuv(x, bsize);
if (mbmi->txfm_size >= TX_32X32 && bsize >= BLOCK_SIZE_SB64X64) {
super_block_uvrd_for_txfm(cm, x, rate, distortion, skippable, bsize,
@@ -909,8 +964,6 @@
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
x->e_mbd.mode_info_context->mbmi.uv_mode = mode;
- vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
-
super_block_uvrd(&cpi->common, x, &this_rate_tokenonly,
&this_distortion, &s, bsize);
this_rate = this_rate_tokenonly +
@@ -942,7 +995,7 @@
if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) {
VP9_COMMON *pc = &cpi->common;
- vp9_prob p [VP9_MVREFS - 1];
+ vp9_prob p[VP9_INTER_MODES - 1];
assert(NEARESTMV <= m && m <= NEWMV);
vp9_mv_ref_probs(pc, p, mode_context);
return cost_token(vp9_sb_mv_ref_tree, p,
@@ -981,31 +1034,31 @@
// is when we are on a new label (jbb May 08, 2007)
switch (m = this_mode) {
case NEWMV:
- this_mv->as_int = seg_mvs[mbmi->ref_frame].as_int;
+ this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
102, xd->allow_high_precision_mv);
- if (mbmi->second_ref_frame > 0) {
- this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame].as_int;
+ if (mbmi->ref_frame[1] > 0) {
+ this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
mvjcost, mvcost, 102,
xd->allow_high_precision_mv);
}
break;
case NEARESTMV:
- this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame].as_int;
- if (mbmi->second_ref_frame > 0)
+ this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
+ if (mbmi->ref_frame[1] > 0)
this_second_mv->as_int =
- frame_mv[NEARESTMV][mbmi->second_ref_frame].as_int;
+ frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
break;
case NEARMV:
- this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame].as_int;
- if (mbmi->second_ref_frame > 0)
+ this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
+ if (mbmi->ref_frame[1] > 0)
this_second_mv->as_int =
- frame_mv[NEARMV][mbmi->second_ref_frame].as_int;
+ frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
break;
case ZEROMV:
this_mv->as_int = 0;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
this_second_mv->as_int = 0;
break;
default:
@@ -1013,15 +1066,15 @@
}
cost = vp9_cost_mv_ref(cpi, this_mode,
- mbmi->mb_mode_context[mbmi->ref_frame]);
+ mbmi->mb_mode_context[mbmi->ref_frame[0]]);
mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
x->partition_info->bmi[i].mode = m;
x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int;
for (idy = 0; idy < bh; ++idy) {
for (idx = 0; idx < bw; ++idx) {
@@ -1083,7 +1136,7 @@
// TODO(debargha): Make this work properly with the
// implicit-compoundinter-weight experiment when implicit
// weighting for splitmv modes is turned on.
- if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
+ if (xd->mode_info_context->mbmi.ref_frame[1] > 0) {
uint8_t* const second_pre =
raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
xd->plane[0].pre[1].buf,
@@ -1201,7 +1254,7 @@
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
x->e_mbd.plane[0].pre[0].buf,
x->e_mbd.plane[0].pre[0].stride);
- if (mbmi->second_ref_frame)
+ if (mbmi->ref_frame[1])
x->e_mbd.plane[0].pre[1].buf =
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
x->e_mbd.plane[0].pre[1].buf,
@@ -1213,7 +1266,7 @@
MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi;
x->plane[0].src = orig_src;
x->e_mbd.plane[0].pre[0] = orig_pre[0];
- if (mbmi->second_ref_frame)
+ if (mbmi->ref_frame[1])
x->e_mbd.plane[0].pre[1] = orig_pre[1];
}
@@ -1273,16 +1326,16 @@
int bestlabelyrate = 0;
i = idy * 2 + idx;
- frame_mv[ZEROMV][mbmi->ref_frame].as_int = 0;
- frame_mv[ZEROMV][mbmi->second_ref_frame].as_int = 0;
+ frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0;
+ frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0;
vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd,
- &frame_mv[NEARESTMV][mbmi->ref_frame],
- &frame_mv[NEARMV][mbmi->ref_frame],
+ &frame_mv[NEARESTMV][mbmi->ref_frame[0]],
+ &frame_mv[NEARMV][mbmi->ref_frame[0]],
i, 0);
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd,
- &frame_mv[NEARESTMV][mbmi->second_ref_frame],
- &frame_mv[NEARMV][mbmi->second_ref_frame],
+ &frame_mv[NEARESTMV][mbmi->ref_frame[1]],
+ &frame_mv[NEARMV][mbmi->ref_frame[1]],
i, 1);
// search for the best motion vector on this segment
@@ -1300,7 +1353,7 @@
vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
// motion search for newmv (single predictor case only)
- if (mbmi->second_ref_frame <= 0 && this_mode == NEWMV) {
+ if (mbmi->ref_frame[1] <= 0 && this_mode == NEWMV) {
int step_param = 0;
int further_steps;
int thissme, bestsme = INT_MAX;
@@ -1367,26 +1420,26 @@
&distortion, &sse);
// safe motion search result for use in compound prediction
- seg_mvs[i][mbmi->ref_frame].as_int = mode_mv[NEWMV].as_int;
+ seg_mvs[i][mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int;
}
// restore src pointers
mi_buf_restore(x, orig_src, orig_pre);
- } else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) {
- if (seg_mvs[i][mbmi->second_ref_frame].as_int == INVALID_MV ||
- seg_mvs[i][mbmi->ref_frame ].as_int == INVALID_MV)
+ } else if (mbmi->ref_frame[1] > 0 && this_mode == NEWMV) {
+ if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
+ seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
continue;
// adjust src pointers
mi_buf_shift(x, i);
- if (cpi->compressor_speed == 0 && cpi->sf.comp_inter_joint_search) {
+ if (cpi->sf.comp_inter_joint_search_thresh < bsize) {
iterative_motion_search(cpi, x, bsize, frame_mv[this_mode],
scaled_ref_frame,
mi_row, mi_col, seg_mvs[i]);
- seg_mvs[i][mbmi->ref_frame].as_int =
- frame_mv[this_mode][mbmi->ref_frame].as_int;
- seg_mvs[i][mbmi->second_ref_frame].as_int =
- frame_mv[this_mode][mbmi->second_ref_frame].as_int;
+ seg_mvs[i][mbmi->ref_frame[0]].as_int =
+ frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
+ seg_mvs[i][mbmi->ref_frame[1]].as_int =
+ frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
}
// restore src pointers
mi_buf_restore(x, orig_src, orig_pre);
@@ -1404,7 +1457,7 @@
((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
continue;
}
- if (mbmi->second_ref_frame > 0 &&
+ if (mbmi->ref_frame[1] > 0 &&
mv_check_bounds(x, &second_mode_mv[this_mode]))
continue;
@@ -1460,7 +1513,7 @@
// store everything needed to come back to this!!
for (i = 0; i < 4; i++) {
bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
bsi->second_mvs[i].as_mv = x->partition_info->bmi[i].second_mv.as_mv;
bsi->modes[i] = x->partition_info->bmi[i].mode;
bsi->eobs[i] = best_eobs[i];
@@ -1498,7 +1551,7 @@
/* set it to the best */
for (i = 0; i < 4; i++) {
x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int = bsi.mvs[i].as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
x->e_mbd.mode_info_context->bmi[i].as_mv[1].as_int =
bsi.second_mvs[i].as_int;
x->e_mbd.plane[0].eobs[i] = bsi.eobs[i];
@@ -1510,14 +1563,14 @@
for (i = 0; i < x->partition_info->count; i++) {
x->partition_info->bmi[i].mode = bsi.modes[i];
x->partition_info->bmi[i].mv.as_mv = bsi.mvs[i].as_mv;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
x->partition_info->bmi[i].second_mv.as_mv = bsi.second_mvs[i].as_mv;
}
/*
* used to set mbmi->mv.as_int
*/
x->partition_info->bmi[3].mv.as_int = bsi.mvs[3].as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
x->partition_info->bmi[3].second_mv.as_int = bsi.second_mvs[3].as_int;
*returntotrate = bsi.r;
@@ -1574,77 +1627,15 @@
x->mv_best_ref_index[ref_frame] = best_index;
}
-extern void vp9_calc_ref_probs(int *count, vp9_prob *probs);
-static void estimate_curframe_refprobs(VP9_COMP *cpi,
- vp9_prob mod_refprobs[3],
- int pred_ref) {
- int norm_cnt[MAX_REF_FRAMES];
- const int *const rfct = cpi->count_mb_ref_frame_usage;
- int intra_count = rfct[INTRA_FRAME];
- int last_count = rfct[LAST_FRAME];
- int gf_count = rfct[GOLDEN_FRAME];
- int arf_count = rfct[ALTREF_FRAME];
-
- // Work out modified reference frame probabilities to use where prediction
- // of the reference frame fails
- if (pred_ref == INTRA_FRAME) {
- norm_cnt[0] = 0;
- norm_cnt[1] = last_count;
- norm_cnt[2] = gf_count;
- norm_cnt[3] = arf_count;
- vp9_calc_ref_probs(norm_cnt, mod_refprobs);
- mod_refprobs[0] = 0; // This branch implicit
- } else if (pred_ref == LAST_FRAME) {
- norm_cnt[0] = intra_count;
- norm_cnt[1] = 0;
- norm_cnt[2] = gf_count;
- norm_cnt[3] = arf_count;
- vp9_calc_ref_probs(norm_cnt, mod_refprobs);
- mod_refprobs[1] = 0; // This branch implicit
- } else if (pred_ref == GOLDEN_FRAME) {
- norm_cnt[0] = intra_count;
- norm_cnt[1] = last_count;
- norm_cnt[2] = 0;
- norm_cnt[3] = arf_count;
- vp9_calc_ref_probs(norm_cnt, mod_refprobs);
- mod_refprobs[2] = 0; // This branch implicit
- } else {
- norm_cnt[0] = intra_count;
- norm_cnt[1] = last_count;
- norm_cnt[2] = gf_count;
- norm_cnt[3] = 0;
- vp9_calc_ref_probs(norm_cnt, mod_refprobs);
- mod_refprobs[2] = 0; // This branch implicit
- }
-}
-
-static INLINE unsigned weighted_cost(vp9_prob *tab0, vp9_prob *tab1,
- int idx, int val, int weight) {
- unsigned cost0 = tab0[idx] ? vp9_cost_bit(tab0[idx], val) : 0;
- unsigned cost1 = tab1[idx] ? vp9_cost_bit(tab1[idx], val) : 0;
- // weight is 16-bit fixed point, so this basically calculates:
- // 0.5 + weight * cost1 + (1.0 - weight) * cost0
- return (0x8000 + weight * cost1 + (0x10000 - weight) * cost0) >> 16;
-}
-
static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
- unsigned int *ref_costs) {
- VP9_COMMON *cm = &cpi->common;
- MACROBLOCKD *xd = &cpi->mb.e_mbd;
- vp9_prob *mod_refprobs;
-
- unsigned int cost;
- int pred_ref;
- int pred_flag;
- int pred_ctx;
- int i;
-
- vp9_prob pred_prob, new_pred_prob;
- int seg_ref_active;
+ unsigned int *ref_costs_single,
+ unsigned int *ref_costs_comp,
+ 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,
+ SEG_LVL_REF_FRAME);
int seg_ref_count = 0;
- seg_ref_active = vp9_segfeature_active(xd,
- segment_id,
- SEG_LVL_REF_FRAME);
if (seg_ref_active) {
seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) +
@@ -1653,56 +1644,56 @@
vp9_check_segref(xd, segment_id, ALTREF_FRAME);
}
- // Get the predicted reference for this mb
- pred_ref = vp9_get_pred_ref(cm, xd);
+ if (seg_ref_active && seg_ref_count == 1) {
+ vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
+ vpx_memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
+ *comp_mode_p = 128;
+ } else {
+ vp9_prob intra_inter_p = vp9_get_pred_prob(cm, xd, PRED_INTRA_INTER);
+ vp9_prob comp_inter_p = 128;
- // Get the context probability for the prediction flag (based on last frame)
- pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
-
- // Predict probability for current frame based on stats so far
- pred_ctx = vp9_get_pred_context(cm, xd, PRED_REF);
- new_pred_prob = get_binary_prob(cpi->ref_pred_count[pred_ctx][0],
- cpi->ref_pred_count[pred_ctx][1]);
-
- // Get the set of probabilities to use if prediction fails
- mod_refprobs = cm->mod_refprobs[pred_ref];
-
- // For each possible selected reference frame work out a cost.
- for (i = 0; i < MAX_REF_FRAMES; i++) {
- if (seg_ref_active && seg_ref_count == 1) {
- cost = 0;
+ if (cm->comp_pred_mode == HYBRID_PREDICTION) {
+ comp_inter_p = vp9_get_pred_prob(cm, xd, PRED_COMP_INTER_INTER);
+ *comp_mode_p = comp_inter_p;
} else {
- pred_flag = (i == pred_ref);
-
- // Get the prediction for the current mb
- cost = weighted_cost(&pred_prob, &new_pred_prob, 0,
- pred_flag, cpi->seg0_progress);
- if (cost > 1024) cost = 768; // i.e. account for 4 bits max.
-
- // for incorrectly predicted cases
- if (!pred_flag) {
- vp9_prob curframe_mod_refprobs[3];
-
- if (cpi->seg0_progress) {
- estimate_curframe_refprobs(cpi, curframe_mod_refprobs, pred_ref);
- } else {
- vpx_memset(curframe_mod_refprobs, 0, sizeof(curframe_mod_refprobs));
- }
-
- cost += weighted_cost(mod_refprobs, curframe_mod_refprobs, 0,
- (i != INTRA_FRAME), cpi->seg0_progress);
- if (i != INTRA_FRAME) {
- cost += weighted_cost(mod_refprobs, curframe_mod_refprobs, 1,
- (i != LAST_FRAME), cpi->seg0_progress);
- if (i != LAST_FRAME) {
- cost += weighted_cost(mod_refprobs, curframe_mod_refprobs, 2,
- (i != GOLDEN_FRAME), cpi->seg0_progress);
- }
- }
- }
+ *comp_mode_p = 128;
}
- ref_costs[i] = cost;
+ ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0);
+
+ if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) {
+ vp9_prob ref_single_p1 = vp9_get_pred_prob(cm, xd, PRED_SINGLE_REF_P1);
+ vp9_prob ref_single_p2 = vp9_get_pred_prob(cm, xd, PRED_SINGLE_REF_P2);
+ unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
+
+ if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ base_cost += vp9_cost_bit(comp_inter_p, 0);
+
+ ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
+ ref_costs_single[ALTREF_FRAME] = base_cost;
+ ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0);
+ ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1);
+ ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1);
+ ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0);
+ ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1);
+ } else {
+ ref_costs_single[LAST_FRAME] = 512;
+ ref_costs_single[GOLDEN_FRAME] = 512;
+ ref_costs_single[ALTREF_FRAME] = 512;
+ }
+ if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) {
+ vp9_prob ref_comp_p = vp9_get_pred_prob(cm, xd, PRED_COMP_REF_P);
+ unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
+
+ if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ base_cost += vp9_cost_bit(comp_inter_p, 1);
+
+ ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0);
+ ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1);
+ } else {
+ ref_costs_comp[LAST_FRAME] = 512;
+ ref_costs_comp[GOLDEN_FRAME] = 512;
+ }
}
}
@@ -1906,8 +1897,8 @@
int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize);
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
- int refs[2] = { mbmi->ref_frame,
- (mbmi->second_ref_frame < 0 ? 0 : mbmi->second_ref_frame) };
+ int refs[2] = { mbmi->ref_frame[0],
+ (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
int_mv ref_mv[2];
const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]);
int ite;
@@ -2049,7 +2040,6 @@
BLOCK_SIZE_TYPE bsize,
int64_t txfm_cache[],
int *rate2, int *distortion, int *skippable,
- int *compmode_cost,
int *rate_y, int *distortion_y,
int *rate_uv, int *distortion_uv,
int *mode_excluded, int *disable_skip,
@@ -2066,12 +2056,12 @@
const enum BlockSize uv_block_size = get_plane_block_size(bsize,
&xd->plane[1]);
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
- const int is_comp_pred = (mbmi->second_ref_frame > 0);
+ const int is_comp_pred = (mbmi->ref_frame[1] > 0);
const int num_refs = is_comp_pred ? 2 : 1;
const int this_mode = mbmi->mode;
int i;
- int refs[2] = { mbmi->ref_frame,
- (mbmi->second_ref_frame < 0 ? 0 : mbmi->second_ref_frame) };
+ int refs[2] = { mbmi->ref_frame[0],
+ (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
int_mv cur_mv[2];
int_mv ref_mv[2];
int64_t this_rd = 0;
@@ -2091,7 +2081,7 @@
frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
- if (cpi->sf.comp_inter_joint_search)
+ if (cpi->sf.comp_inter_joint_search_thresh < bsize)
iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame,
mi_row, mi_col, single_newmv);
@@ -2210,10 +2200,8 @@
* are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
* words if you present them in that order, the second one is always known
* if the first is known */
- *compmode_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP),
- is_comp_pred);
*rate2 += vp9_cost_mv_ref(cpi, this_mode,
- mbmi->mb_mode_context[mbmi->ref_frame]);
+ mbmi->mb_mode_context[mbmi->ref_frame[0]]);
pred_exists = 0;
interpolating_intpel_seen = 0;
@@ -2404,8 +2392,10 @@
int64_t err4x4 = INT64_MAX;
int i;
+ vpx_memset(&txfm_cache,0,sizeof(txfm_cache));
ctx->skip = 0;
xd->mode_info_context->mbmi.mode = DC_PRED;
+ xd->mode_info_context->mbmi.ref_frame[0] = INTRA_FRAME;
err = rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
&dist_y, &y_skip, bsize, txfm_cache);
mode = xd->mode_info_context->mbmi.mode;
@@ -2458,7 +2448,7 @@
const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]);
MB_PREDICTION_MODE this_mode;
MB_PREDICTION_MODE best_mode = DC_PRED;
- MV_REFERENCE_FRAME ref_frame, second_ref = INTRA_FRAME;
+ MV_REFERENCE_FRAME ref_frame;
unsigned char segment_id = xd->mode_info_context->mbmi.segment_id;
int comp_pred, i;
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
@@ -2478,7 +2468,8 @@
MB_MODE_INFO best_mbmode;
int j;
int mode_index, best_mode_index = 0;
- unsigned int ref_costs[MAX_REF_FRAMES];
+ unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
+ vp9_prob comp_mode_p;
int64_t best_overall_rd = INT64_MAX;
INTERPOLATIONFILTERTYPE best_filter = SWITCHABLE;
INTERPOLATIONFILTERTYPE tmp_best_filter = SWITCHABLE;
@@ -2495,6 +2486,10 @@
int_mv seg_mvs[4][MAX_REF_FRAMES];
union b_mode_info best_bmodes[4];
PARTITION_INFO best_partition;
+ int bwsl = b_width_log2(bsize);
+ int bws = (1 << bwsl) / 4; // mode_info step for subsize
+ int bhsl = b_height_log2(bsize);
+ int bhs = (1 << bhsl) / 4; // mode_info step for subsize
for (i = 0; i < 4; i++) {
int j;
@@ -2507,7 +2502,8 @@
ctx->modes_with_high_error = 0;
xd->mode_info_context->mbmi.segment_id = segment_id;
- estimate_ref_frame_costs(cpi, segment_id, ref_costs);
+ estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
+ &comp_mode_p);
vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
vpx_memset(&single_newmv, 0, sizeof(single_newmv));
@@ -2560,6 +2556,7 @@
if (cpi->speed == 0
|| (cpi->speed > 0 && (ref_frame_mask & (1 << INTRA_FRAME)))) {
mbmi->mode = DC_PRED;
+ mbmi->ref_frame[0] = INTRA_FRAME;
for (i = 0; i <= (bsize < BLOCK_SIZE_MB16X16 ? TX_4X4 :
(bsize < BLOCK_SIZE_SB32X32 ? TX_8X8 :
(bsize < BLOCK_SIZE_SB64X64 ? TX_16X16 : TX_32X32)));
@@ -2577,7 +2574,6 @@
int mode_excluded = 0;
int64_t this_rd = INT64_MAX;
int disable_skip = 0;
- int other_cost = 0;
int compmode_cost = 0;
int rate2 = 0, rate_y = 0, rate_uv = 0;
int distortion2 = 0, distortion_y = 0, distortion_uv = 0;
@@ -2589,9 +2585,9 @@
txfm_cache[i] = INT64_MAX;
// Test best rd so far against threshold for trying this mode.
- if (bsize >= BLOCK_SIZE_SB8X8 &&
- (best_rd < cpi->rd_threshes[mode_index] ||
- cpi->rd_threshes[mode_index] == INT_MAX))
+ if ((best_rd < ((cpi->rd_threshes[bsize][mode_index] *
+ cpi->rd_thresh_freq_fact[bsize][mode_index]) >> 4)) ||
+ cpi->rd_threshes[bsize][mode_index] == INT_MAX)
continue;
x->skip = 0;
@@ -2612,39 +2608,39 @@
}
}
- mbmi->ref_frame = ref_frame;
- mbmi->second_ref_frame = vp9_mode_order[mode_index].second_ref_frame;
+ mbmi->ref_frame[0] = ref_frame;
+ mbmi->ref_frame[1] = vp9_mode_order[mode_index].second_ref_frame;
if (!(ref_frame == INTRA_FRAME
|| (cpi->ref_frame_flags & flag_list[ref_frame]))) {
continue;
}
- if (!(mbmi->second_ref_frame == NONE
- || (cpi->ref_frame_flags & flag_list[mbmi->second_ref_frame]))) {
+ if (!(mbmi->ref_frame[1] == NONE
+ || (cpi->ref_frame_flags & flag_list[mbmi->ref_frame[1]]))) {
continue;
}
// TODO(jingning, jkoleszar): scaling reference frame not supported for
// SPLITMV.
- if (mbmi->ref_frame > 0 &&
- (scale_factor[mbmi->ref_frame].x_num !=
- scale_factor[mbmi->ref_frame].x_den ||
- scale_factor[mbmi->ref_frame].y_num !=
- scale_factor[mbmi->ref_frame].y_den) &&
+ if (mbmi->ref_frame[0] > 0 &&
+ (scale_factor[mbmi->ref_frame[0]].x_num !=
+ scale_factor[mbmi->ref_frame[0]].x_den ||
+ scale_factor[mbmi->ref_frame[0]].y_num !=
+ scale_factor[mbmi->ref_frame[0]].y_den) &&
this_mode == SPLITMV)
continue;
- if (mbmi->second_ref_frame > 0 &&
- (scale_factor[mbmi->second_ref_frame].x_num !=
- scale_factor[mbmi->second_ref_frame].x_den ||
- scale_factor[mbmi->second_ref_frame].y_num !=
- scale_factor[mbmi->second_ref_frame].y_den) &&
+ if (mbmi->ref_frame[1] > 0 &&
+ (scale_factor[mbmi->ref_frame[1]].x_num !=
+ scale_factor[mbmi->ref_frame[1]].x_den ||
+ scale_factor[mbmi->ref_frame[1]].y_num !=
+ scale_factor[mbmi->ref_frame[1]].y_den) &&
this_mode == SPLITMV)
continue;
- set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame,
+ set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1],
scale_factor);
- comp_pred = mbmi->second_ref_frame > INTRA_FRAME;
+ comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
mbmi->mode = this_mode;
mbmi->uv_mode = DC_PRED;
@@ -2661,24 +2657,18 @@
continue;
if (comp_pred) {
- if (ref_frame == ALTREF_FRAME) {
- second_ref = LAST_FRAME;
- } else {
- second_ref = ref_frame + 1;
- }
- if (!(cpi->ref_frame_flags & flag_list[second_ref]))
+ if (!(cpi->ref_frame_flags & flag_list[mbmi->ref_frame[1]]))
continue;
- mbmi->second_ref_frame = second_ref;
- set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame,
+ 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;
} else {
- // mbmi->second_ref_frame = vp9_mode_order[mode_index].second_ref_frame;
+ // mbmi->ref_frame[1] = vp9_mode_order[mode_index].ref_frame[1];
if (ref_frame != INTRA_FRAME) {
- if (mbmi->second_ref_frame != INTRA_FRAME)
+ if (mbmi->ref_frame[1] != INTRA_FRAME)
mode_excluded =
mode_excluded ?
mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY;
@@ -2689,7 +2679,7 @@
for (i = 0; i < MAX_MB_PLANE; i++) {
xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
if (comp_pred)
- xd->plane[i].pre[1] = yv12_mb[second_ref][i];
+ xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
}
// If the segment reference frame feature is enabled....
@@ -2715,6 +2705,15 @@
}
}
}
+ // TODO(JBB): This is to make up for the fact that we don't have sad
+ // functions that work when the block size reads outside the umv. We
+ // should fix this either by making the motion search just work on
+ // a representative block in the boundary ( first ) and then implement a
+ // function that does sads when inside the border..
+ if (((mi_row + bhs) > cm->mi_rows || (mi_col + bws) > cm->mi_cols) &&
+ this_mode == NEWMV) {
+ continue;
+ }
if (this_mode == I4X4_PRED) {
int rate;
@@ -2736,7 +2735,6 @@
txfm_cache[i] = txfm_cache[ONLY_4X4];
} else if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
- vp9_build_intra_predictors_sby_s(xd, bsize);
super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
bsize, txfm_cache);
@@ -2758,7 +2756,7 @@
rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;
} else if (this_mode == SPLITMV) {
- const int is_comp_pred = mbmi->second_ref_frame > 0;
+ const int is_comp_pred = mbmi->ref_frame[1] > 0;
int rate, distortion;
int64_t this_rd_thresh;
int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
@@ -2766,17 +2764,18 @@
int tmp_best_distortion = INT_MAX, tmp_best_skippable = 0;
int switchable_filter_index;
int_mv *second_ref = is_comp_pred ?
- &mbmi->ref_mvs[mbmi->second_ref_frame][0] : NULL;
+ &mbmi->ref_mvs[mbmi->ref_frame[1]][0] : NULL;
union b_mode_info tmp_best_bmodes[16];
MB_MODE_INFO tmp_best_mbmode;
PARTITION_INFO tmp_best_partition;
int pred_exists = 0;
int uv_skippable;
- this_rd_thresh = (mbmi->ref_frame == LAST_FRAME) ?
- cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
- this_rd_thresh = (mbmi->ref_frame == GOLDEN_FRAME) ?
- cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
+ this_rd_thresh = (mbmi->ref_frame[0] == LAST_FRAME) ?
+ cpi->rd_threshes[bsize][THR_NEWMV] :
+ cpi->rd_threshes[bsize][THR_NEWA];
+ this_rd_thresh = (mbmi->ref_frame[0] == GOLDEN_FRAME) ?
+ cpi->rd_threshes[bsize][THR_NEWG] : this_rd_thresh;
xd->mode_info_context->mbmi.txfm_size = TX_4X4;
for (switchable_filter_index = 0;
@@ -2788,12 +2787,12 @@
vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
tmp_rd = rd_pick_best_mbsegmentation(cpi, x,
- &mbmi->ref_mvs[mbmi->ref_frame][0],
- second_ref, INT64_MAX,
- &rate, &rate_y, &distortion,
- &skippable,
- (int)this_rd_thresh, seg_mvs,
- mi_row, mi_col);
+ &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
+ second_ref, INT64_MAX,
+ &rate, &rate_y, &distortion,
+ &skippable,
+ (int)this_rd_thresh, seg_mvs,
+ mi_row, mi_col);
if (cpi->common.mcomp_filter_type == SWITCHABLE) {
const int rs = get_switchable_rate(cm, x);
tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0);
@@ -2826,12 +2825,12 @@
// Handles the special case when a filter that is not in the
// switchable list (bilinear, 6-tap) is indicated at the frame level
tmp_rd = rd_pick_best_mbsegmentation(cpi, x,
- &mbmi->ref_mvs[mbmi->ref_frame][0],
- second_ref, INT64_MAX,
- &rate, &rate_y, &distortion,
- &skippable,
- (int)this_rd_thresh, seg_mvs,
- mi_row, mi_col);
+ &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
+ second_ref, INT64_MAX,
+ &rate, &rate_y, &distortion,
+ &skippable,
+ (int)this_rd_thresh, seg_mvs,
+ mi_row, mi_col);
} else {
if (cpi->common.mcomp_filter_type == SWITCHABLE) {
int rs = get_switchable_rate(cm, x);
@@ -2876,24 +2875,24 @@
mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
}
- compmode_cost =
- vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), is_comp_pred);
+ compmode_cost = vp9_cost_bit(comp_mode_p, is_comp_pred);
} else {
YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
- int fb = get_ref_frame_idx(cpi, mbmi->ref_frame);
+ int fb = get_ref_frame_idx(cpi, mbmi->ref_frame[0]);
if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb])
scaled_ref_frame[0] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]];
if (comp_pred) {
- fb = get_ref_frame_idx(cpi, mbmi->second_ref_frame);
+ fb = get_ref_frame_idx(cpi, mbmi->ref_frame[1]);
if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb])
scaled_ref_frame[1] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]];
}
+ compmode_cost = vp9_cost_bit(comp_mode_p,
+ mbmi->ref_frame[1] > INTRA_FRAME);
this_rd = handle_inter_mode(cpi, x, bsize,
txfm_cache,
&rate2, &distortion2, &skippable,
- &compmode_cost,
&rate_y, &distortion_y,
&rate_uv, &distortion_uv,
&mode_excluded, &disable_skip,
@@ -2910,7 +2909,11 @@
// Estimate the reference frame signaling cost and add it
// to the rolling cost variable.
- rate2 += ref_costs[xd->mode_info_context->mbmi.ref_frame];
+ if (mbmi->ref_frame[1] > INTRA_FRAME) {
+ rate2 += ref_costs_comp[mbmi->ref_frame[0]];
+ } else {
+ rate2 += ref_costs_single[mbmi->ref_frame[0]];
+ }
if (!disable_skip) {
// Test for the condition where skip block will be activated
@@ -2938,7 +2941,6 @@
if (skip_prob) {
prob_skip_cost = vp9_cost_bit(skip_prob, 1);
rate2 += prob_skip_cost;
- other_cost += prob_skip_cost;
}
}
} else if (mb_skip_allowed) {
@@ -2946,7 +2948,6 @@
int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd,
PRED_MBSKIP), 0);
rate2 += prob_skip_cost;
- other_cost += prob_skip_cost;
}
// Calculate the final RD estimate for this mode.
@@ -2955,14 +2956,14 @@
#if 0
// Keep record of best intra distortion
- if ((xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
+ if ((xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) &&
(this_rd < best_intra_rd)) {
best_intra_rd = this_rd;
*returnintra = distortion2;
}
#endif
- if (!disable_skip && mbmi->ref_frame == INTRA_FRAME)
+ if (!disable_skip && mbmi->ref_frame[0] == INTRA_FRAME)
for (i = 0; i < NB_PREDICTION_TYPES; ++i)
best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
@@ -2978,9 +2979,9 @@
|| distortion2 < mode_distortions[this_mode]) {
mode_distortions[this_mode] = distortion2;
}
- if (frame_distortions[mbmi->ref_frame] == -1
- || distortion2 < frame_distortions[mbmi->ref_frame]) {
- frame_distortions[mbmi->ref_frame] = distortion2;
+ if (frame_distortions[mbmi->ref_frame[0]] == -1
+ || distortion2 < frame_distortions[mbmi->ref_frame[0]]) {
+ frame_distortions[mbmi->ref_frame[0]] = distortion2;
}
}
@@ -2995,7 +2996,6 @@
mbmi->mv[0].as_int = 0;
}
- other_cost += ref_costs[xd->mode_info_context->mbmi.ref_frame];
*returnrate = rate2;
*returndistortion = distortion2;
best_rd = this_rd;
@@ -3032,7 +3032,7 @@
}
/* keep record of best compound/single-only prediction */
- if (!disable_skip && mbmi->ref_frame != INTRA_FRAME) {
+ if (!disable_skip && mbmi->ref_frame[0] != INTRA_FRAME) {
int single_rd, hybrid_rd, single_rate, hybrid_rate;
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
@@ -3046,10 +3046,10 @@
single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
- if (mbmi->second_ref_frame <= INTRA_FRAME &&
+ if (mbmi->ref_frame[1] <= INTRA_FRAME &&
single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
- } else if (mbmi->second_ref_frame > INTRA_FRAME &&
+ } else if (mbmi->ref_frame[1] > INTRA_FRAME &&
single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
}
@@ -3110,14 +3110,34 @@
assert((cm->mcomp_filter_type == SWITCHABLE) ||
(cm->mcomp_filter_type == best_mbmode.interp_filter) ||
- (best_mbmode.ref_frame == INTRA_FRAME));
+ (best_mbmode.ref_frame[0] == INTRA_FRAME));
// Accumulate filter usage stats
// TODO(agrange): Use RD criteria to select interpolation filter mode.
if (is_inter_mode(best_mode))
++cpi->best_switchable_interp_count[vp9_switchable_interp_map[best_filter]];
- // TODO(rbultje) integrate with RD thresholding
+ // Updating rd_thresh_freq_fact[] here means that the differnt
+ // partition/block sizes are handled independently based on the best
+ // choice for the current partition. It may well be better to keep a scaled
+ // best rd so far value and update rd_thresh_freq_fact based on the mode/size
+ // combination that wins out.
+ if (cpi->sf.adpative_rd_thresh) {
+ for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
+ if (mode_index == best_mode_index) {
+ cpi->rd_thresh_freq_fact[bsize][mode_index] = BASE_RD_THRESH_FREQ_FACT;
+ } else {
+ cpi->rd_thresh_freq_fact[bsize][mode_index] += MAX_RD_THRESH_FREQ_INC;
+ if (cpi->rd_thresh_freq_fact[bsize][mode_index] >
+ (cpi->sf.adpative_rd_thresh * MAX_RD_THRESH_FREQ_FACT)) {
+ cpi->rd_thresh_freq_fact[bsize][mode_index] =
+ cpi->sf.adpative_rd_thresh * MAX_RD_THRESH_FREQ_FACT;
+ }
+ }
+ }
+ }
+
+ // TODO(rbultje) integrate with RD trd_thresh_freq_facthresholding
#if 0
// Reduce the activation RD thresholds for the best choice mode
if ((cpi->rd_baseline_thresh[best_mode_index] > 0) &&
@@ -3138,11 +3158,11 @@
if (!vp9_segfeature_active(xd, 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 != ALTREF_FRAME)
+ (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame[0] != ALTREF_FRAME)
&& bsize >= BLOCK_SIZE_SB8X8) {
mbmi->mode = ZEROMV;
- mbmi->ref_frame = ALTREF_FRAME;
- mbmi->second_ref_frame = NONE;
+ mbmi->ref_frame[0] = ALTREF_FRAME;
+ mbmi->ref_frame[1] = NONE;
mbmi->mv[0].as_int = 0;
mbmi->uv_mode = DC_PRED;
mbmi->mb_skip_coeff = 1;
@@ -3162,19 +3182,19 @@
// macroblock modes
*mbmi = best_mbmode;
- if (best_mbmode.ref_frame == INTRA_FRAME &&
+ if (best_mbmode.ref_frame[0] == INTRA_FRAME &&
best_mbmode.sb_type < BLOCK_SIZE_SB8X8) {
for (i = 0; i < 4; i++)
xd->mode_info_context->bmi[i].as_mode = best_bmodes[i].as_mode;
}
- if (best_mbmode.ref_frame != INTRA_FRAME &&
+ if (best_mbmode.ref_frame[0] != INTRA_FRAME &&
best_mbmode.sb_type < BLOCK_SIZE_SB8X8) {
for (i = 0; i < 4; i++)
xd->mode_info_context->bmi[i].as_mv[0].as_int =
best_bmodes[i].as_mv[0].as_int;
- if (mbmi->second_ref_frame > 0)
+ if (mbmi->ref_frame[1] > 0)
for (i = 0; i < 4; i++)
xd->mode_info_context->bmi[i].as_mv[1].as_int =
best_bmodes[i].as_mv[1].as_int;
@@ -3204,13 +3224,13 @@
}
end:
- set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame,
+ set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1],
scale_factor);
store_coding_context(x, ctx, best_mode_index,
&best_partition,
- &mbmi->ref_mvs[mbmi->ref_frame][0],
- &mbmi->ref_mvs[mbmi->second_ref_frame < 0 ? 0 :
- mbmi->second_ref_frame][0],
+ &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
+ &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
+ mbmi->ref_frame[1]][0],
best_pred_diff, best_txfm_diff);
return best_rd;
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index 3d8390b..cb05219 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -99,6 +99,7 @@
TX_SIZE tx_size;
int dry_run;
};
+
static void tokenize_b(int plane, int block, BLOCK_SIZE_TYPE bsize,
int ss_txfrm_size, void *arg) {
struct tokenize_b_args* const args = arg;
@@ -129,7 +130,7 @@
const int *scan, *nb;
vp9_coeff_count *counts;
vp9_coeff_probs_model *coef_probs;
- const int ref = mbmi->ref_frame != INTRA_FRAME;
+ const int ref = mbmi->ref_frame[0] != INTRA_FRAME;
ENTROPY_CONTEXT above_ec, left_ec;
uint8_t token_cache[1024];
TX_TYPE tx_type = DCT_DCT;
@@ -233,8 +234,12 @@
} while (c < eob && ++c < seg_eob);
*tp = t;
- for (pt = 0; pt < (1 << tx_size); pt++) {
- A[pt] = L[pt] = c > 0;
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) {
+ set_contexts_on_border(xd, bsize, plane, tx_size, c, aoff, loff, A, L);
+ } else {
+ for (pt = 0; pt < (1 << tx_size); pt++) {
+ A[pt] = L[pt] = c > 0;
+ }
}
}
diff --git a/vp9/encoder/vp9_write_bit_buffer.h b/vp9/encoder/vp9_write_bit_buffer.h
index 18cf403..98ad3f6 100644
--- a/vp9/encoder/vp9_write_bit_buffer.h
+++ b/vp9/encoder/vp9_write_bit_buffer.h
@@ -26,8 +26,12 @@
const int off = wb->bit_offset;
const int p = off / CHAR_BIT;
const int q = CHAR_BIT - 1 - off % CHAR_BIT;
- wb->bit_buffer[p] &= ~(1 << q);
- wb->bit_buffer[p] |= bit << q;
+ if (q == CHAR_BIT -1) {
+ wb->bit_buffer[p] = bit << q;
+ } else {
+ wb->bit_buffer[p] &= ~(1 << q);
+ wb->bit_buffer[p] |= bit << q;
+ }
wb->bit_offset = off + 1;
}
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index b5aa10d..32cd620 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -217,7 +217,7 @@
else {
si->is_kf = 0;
- if (data_sz >= 8 && !(data[0] & 0x80)) { /* I-Frame */
+ if (data_sz >= 8 && (data[0] & 0xD8) == 0x80) { /* I-Frame */
const uint8_t *c = data + 1;
si->is_kf = 1;