summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/common/arm/neon/vp9_iht8x8_add_neon.asm2
-rw-r--r--vp9/common/generic/vp9_systemdependent.c19
-rw-r--r--vp9/common/vp9_alloccommon.c2
-rw-r--r--vp9/common/vp9_onyx.h2
-rw-r--r--vp9/common/vp9_reconintra.c14
-rw-r--r--vp9/common/vp9_systemdependent.h3
-rw-r--r--vp9/decoder/vp9_decodeframe.c7
-rw-r--r--vp9/encoder/vp9_bitstream.c10
-rw-r--r--vp9/encoder/vp9_encodeframe.c181
-rw-r--r--vp9/encoder/vp9_encodemb.c90
-rw-r--r--vp9/encoder/vp9_encodemb.h2
-rw-r--r--vp9/encoder/vp9_encodemv.c32
-rw-r--r--vp9/encoder/vp9_encodemv.h13
-rw-r--r--vp9/encoder/vp9_firstpass.c2
-rw-r--r--vp9/encoder/vp9_onyx_if.c52
-rw-r--r--vp9/encoder/vp9_onyx_int.h39
-rw-r--r--vp9/encoder/vp9_pickmode.c56
-rw-r--r--vp9/encoder/vp9_psnr.c29
-rw-r--r--vp9/encoder/vp9_psnr.h25
-rw-r--r--vp9/encoder/vp9_ratectrl.c36
-rw-r--r--vp9/encoder/vp9_rdopt.c316
-rw-r--r--vp9/encoder/vp9_rdopt.h8
-rw-r--r--vp9/encoder/vp9_resize.c4
-rw-r--r--vp9/encoder/vp9_temporal_filter.c1
-rw-r--r--vp9/encoder/vp9_tokenize.c4
-rw-r--r--vp9/encoder/vp9_tokenize.h2
-rw-r--r--vp9/vp9_common.mk1
-rw-r--r--vp9/vp9_cx_iface.c8
-rw-r--r--vp9/vp9cx.mk2
29 files changed, 472 insertions, 490 deletions
diff --git a/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm b/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm
index 93d3af301..b41f5661b 100644
--- a/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm
+++ b/vp9/common/arm/neon/vp9_iht8x8_add_neon.asm
@@ -576,6 +576,7 @@
vld1.s16 {q14,q15}, [r0]!
push {r0-r10}
+ vpush {d8-d15}
; transpose the input data
TRANSPOSE8X8
@@ -636,6 +637,7 @@ iadst_iadst
IADST8X8_1D
end_vp9_iht8x8_64_add_neon
+ vpop {d8-d15}
pop {r0-r10}
; ROUND_POWER_OF_TWO(temp_out[j], 5)
diff --git a/vp9/common/generic/vp9_systemdependent.c b/vp9/common/generic/vp9_systemdependent.c
deleted file mode 100644
index 536febb65..000000000
--- a/vp9/common/generic/vp9_systemdependent.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-
-#include "./vpx_config.h"
-#include "./vp9_rtcd.h"
-#include "vp9/common/vp9_onyxc_int.h"
-
-void vp9_machine_specific_config(VP9_COMMON *cm) {
- (void)cm;
- vp9_rtcd();
-}
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index 6f771992b..ff4b7c1f9 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -201,7 +201,7 @@ int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) {
}
void vp9_create_common(VP9_COMMON *cm) {
- vp9_machine_specific_config(cm);
+ vp9_rtcd();
}
void vp9_remove_common(VP9_COMMON *cm) {
diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h
index ab27ca523..222086886 100644
--- a/vp9/common/vp9_onyx.h
+++ b/vp9/common/vp9_onyx.h
@@ -149,6 +149,8 @@ extern "C" {
// Spatial and temporal scalability.
int ss_number_layers; // Number of spatial layers.
int ts_number_layers; // Number of temporal layers.
+ // Bitrate allocation for spatial layers.
+ int ss_target_bitrate[VPX_SS_MAX_LAYERS];
// Bitrate allocation (CBR mode) and framerate factor, for temporal layers.
int ts_target_bitrate[VPX_TS_MAX_LAYERS];
int ts_rate_decimator[VPX_TS_MAX_LAYERS];
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index 96ba3e464..71a41a9de 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -382,34 +382,34 @@ static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
/* slower path if the block needs border extension */
if (x0 + 2 * bs <= frame_width) {
if (right_available && bs == 4) {
- vpx_memcpy(above_row - 1, above_ref - 1, 2 * bs + 1);
+ vpx_memcpy(above_row, above_ref, 2 * bs);
} else {
- vpx_memcpy(above_row - 1, above_ref - 1, bs + 1);
+ vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 + bs <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
- vpx_memcpy(above_row - 1, above_ref - 1, r + 1);
+ vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
- vpx_memcpy(above_row - 1, above_ref - 1, bs + 1);
+ vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
- vpx_memcpy(above_row - 1, above_ref - 1, r + 1);
+ vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
- vpx_memcpy(above_row - 1, above_ref - 1, r + 1);
+ vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
}
- above_row[-1] = left_available ? above_ref[-1] : 129;
}
+ above_row[-1] = left_available ? above_ref[-1] : 129;
} else {
/* faster path if the block does not need extension */
if (bs == 4 && right_available && left_available) {
diff --git a/vp9/common/vp9_systemdependent.h b/vp9/common/vp9_systemdependent.h
index 7455abce3..72edbca55 100644
--- a/vp9/common/vp9_systemdependent.h
+++ b/vp9/common/vp9_systemdependent.h
@@ -76,9 +76,6 @@ static INLINE int get_msb(unsigned int n) {
}
#endif
-struct VP9Common;
-void vp9_machine_specific_config(struct VP9Common *cm);
-
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 80340b51a..e52b3f759 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -15,6 +15,7 @@
#include "./vpx_scale_rtcd.h"
#include "vpx_mem/vpx_mem.h"
+#include "vpx_ports/mem_ops.h"
#include "vpx_scale/vpx_scale.h"
#include "vp9/common/vp9_alloccommon.h"
@@ -39,10 +40,6 @@
#include "vp9/decoder/vp9_reader.h"
#include "vp9/decoder/vp9_thread.h"
-static int read_be32(const uint8_t *p) {
- return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-}
-
static int is_compound_reference_allowed(const VP9_COMMON *cm) {
int i;
for (i = 1; i < REFS_PER_FRAME; ++i)
@@ -837,7 +834,7 @@ static size_t get_tile(const uint8_t *const data_end,
vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt tile length");
- size = read_be32(*data);
+ size = mem_get_be32(*data);
*data += 4;
if (size > (size_t)(data_end - *data))
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 31ec069d0..34d1da7bd 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -14,6 +14,7 @@
#include "vpx/vpx_encoder.h"
#include "vpx_mem/vpx_mem.h"
+#include "vpx_ports/mem_ops.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_entropymv.h"
@@ -61,13 +62,6 @@ static void write_inter_mode(vp9_writer *w, MB_PREDICTION_MODE mode,
&inter_mode_encodings[INTER_OFFSET(mode)]);
}
-static INLINE void write_be32(uint8_t *p, int value) {
- p[0] = value >> 24;
- p[1] = value >> 16;
- p[2] = value >> 8;
- p[3] = value;
-}
-
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));
@@ -1007,7 +1001,7 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) {
vp9_stop_encode(&residual_bc);
if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) {
// size of this tile
- write_be32(data_ptr + total_size, residual_bc.pos);
+ mem_put_be32(data_ptr + total_size, residual_bc.pos);
total_size += 4;
}
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index f529c9336..84b7cef55 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -94,7 +94,8 @@ static const uint8_t VP9_VAR_OFFS[64] = {
128, 128, 128, 128, 128, 128, 128, 128
};
-static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x,
+static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi,
+ MACROBLOCK *x,
BLOCK_SIZE bs) {
unsigned int var, sse;
var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
@@ -102,6 +103,52 @@ static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x,
return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}
+static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi,
+ MACROBLOCK *x,
+ int mi_row,
+ int mi_col,
+ BLOCK_SIZE bs) {
+ const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
+ int offset = (mi_row * MI_SIZE) * yv12->y_stride + (mi_col * MI_SIZE);
+ unsigned int var, sse;
+ var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf,
+ x->plane[0].src.stride,
+ yv12->y_buffer + offset,
+ yv12->y_stride,
+ &sse);
+ return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
+}
+
+static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi,
+ int mi_row,
+ int mi_col) {
+ unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
+ mi_row, mi_col,
+ BLOCK_64X64);
+ if (var < 8)
+ return BLOCK_64X64;
+ else if (var < 128)
+ return BLOCK_32X32;
+ else if (var < 2048)
+ return BLOCK_16X16;
+ else
+ return BLOCK_8X8;
+}
+
+static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi,
+ int mi_row,
+ int mi_col) {
+ unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
+ mi_row, mi_col,
+ BLOCK_64X64);
+ if (var < 4)
+ return BLOCK_64X64;
+ else if (var < 10)
+ return BLOCK_32X32;
+ else
+ return BLOCK_16X16;
+}
+
// Original activity measure from Tim T's code.
static unsigned int tt_activity_measure(MACROBLOCK *x) {
unsigned int sse;
@@ -492,10 +539,10 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
if (!frame_is_intra_only(cm)) {
if (is_inter_block(mbmi)) {
if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) {
- int_mv best_mv[2];
+ MV best_mv[2];
for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
- best_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
- vp9_update_mv_count(cpi, x, best_mv);
+ best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
+ vp9_update_mv_count(cm, xd, best_mv);
}
if (cm->interp_filter == SWITCHABLE) {
@@ -994,7 +1041,7 @@ static void set_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
int index = block_row * mis + block_col;
// Find a partition size that fits
- bsize = find_partition_size(cpi->sf.always_this_block_size,
+ bsize = find_partition_size(bsize,
(row8x8_remaining - block_row),
(col8x8_remaining - block_col), &bh, &bw);
mi_8x8[index] = mi_upper_left + index;
@@ -1074,10 +1121,10 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
if (!frame_is_intra_only(cm)) {
if (is_inter_block(mbmi)) {
if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) {
- int_mv best_mv[2];
+ MV best_mv[2];
for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
- best_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
- vp9_update_mv_count(cpi, x, best_mv);
+ best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
+ vp9_update_mv_count(cm, xd, best_mv);
}
if (cm->interp_filter == SWITCHABLE) {
@@ -1179,7 +1226,7 @@ static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
subsize);
*get_sb_index(x, subsize) = 3;
encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
- subsize);
+ subsize);
break;
default:
assert("Invalid partition type.");
@@ -1212,10 +1259,13 @@ static void rd_use_partition(VP9_COMP *cpi,
PARTITION_CONTEXT sl[8], sa[8];
int last_part_rate = INT_MAX;
int64_t last_part_dist = INT64_MAX;
+ int64_t last_part_rd = INT64_MAX;
int none_rate = INT_MAX;
int64_t none_dist = INT64_MAX;
+ int64_t none_rd = INT64_MAX;
int chosen_rate = INT_MAX;
int64_t chosen_dist = INT64_MAX;
+ int64_t chosen_rd = INT64_MAX;
BLOCK_SIZE sub_subsize = BLOCK_4X4;
int splits_below = 0;
BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
@@ -1244,7 +1294,8 @@ static void rd_use_partition(VP9_COMP *cpi,
x->mb_energy = vp9_block_energy(cpi, x, bsize);
}
- if (cpi->sf.adjust_partitioning_from_last_frame) {
+ if (cpi->sf.partition_search_type == SEARCH_PARTITION &&
+ cpi->sf.adjust_partitioning_from_last_frame) {
// Check if any of the sub blocks are further split.
if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
@@ -1270,7 +1321,11 @@ static void rd_use_partition(VP9_COMP *cpi,
pl = partition_plane_context(cpi->above_seg_context,
cpi->left_seg_context,
mi_row, mi_col, bsize);
- none_rate += x->partition_cost[pl][PARTITION_NONE];
+
+ if (none_rate < INT_MAX) {
+ none_rate += x->partition_cost[pl][PARTITION_NONE];
+ none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist);
+ }
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
mi_8x8[0]->mbmi.sb_type = bs_type;
@@ -1365,10 +1420,13 @@ static void rd_use_partition(VP9_COMP *cpi,
pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
mi_row, mi_col, bsize);
- if (last_part_rate < INT_MAX)
+ if (last_part_rate < INT_MAX) {
last_part_rate += x->partition_cost[pl][partition];
+ last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist);
+ }
if (cpi->sf.adjust_partitioning_from_last_frame
+ && cpi->sf.partition_search_type == SEARCH_PARTITION
&& partition != PARTITION_SPLIT && bsize > BLOCK_8X8
&& (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows)
&& (mi_col + ms < cm->mi_cols || mi_col + (ms >> 1) == cm->mi_cols)) {
@@ -1424,21 +1482,21 @@ static void rd_use_partition(VP9_COMP *cpi,
mi_row, mi_col, bsize);
if (chosen_rate < INT_MAX) {
chosen_rate += x->partition_cost[pl][PARTITION_SPLIT];
+ chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist);
}
}
// If last_part is better set the partitioning to that...
- if (RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist)
- < RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist)) {
+ if (last_part_rd < chosen_rd) {
mi_8x8[0]->mbmi.sb_type = bsize;
if (bsize >= BLOCK_8X8)
*(get_sb_partitioning(x, bsize)) = subsize;
chosen_rate = last_part_rate;
chosen_dist = last_part_dist;
+ chosen_rd = last_part_rd;
}
// If none was better set the partitioning to that...
- if (RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist)
- > RDCOST(x->rdmult, x->rddiv, none_rate, none_dist)) {
+ if (none_rd < chosen_rd) {
if (bsize >= BLOCK_8X8)
*(get_sb_partitioning(x, bsize)) = bsize;
chosen_rate = none_rate;
@@ -1914,8 +1972,8 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
}
}
-static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
- int mi_row, TOKENEXTRA **tp) {
+static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
+ int mi_row, TOKENEXTRA **tp) {
VP9_COMMON *const cm = &cpi->common;
int mi_col;
@@ -1946,19 +2004,32 @@ static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
vp9_zero(cpi->mb.pred_mv);
- if (cpi->sf.use_lastframe_partitioning ||
- cpi->sf.use_one_partition_size_always ) {
+ if ((cpi->sf.partition_search_type == SEARCH_PARTITION &&
+ cpi->sf.use_lastframe_partitioning) ||
+ cpi->sf.partition_search_type == FIXED_PARTITION ||
+ cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
const int idx_str = cm->mode_info_stride * mi_row + mi_col;
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
cpi->mb.source_variance = UINT_MAX;
- if (cpi->sf.use_one_partition_size_always) {
+ if (cpi->sf.partition_search_type == FIXED_PARTITION) {
set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
cpi->sf.always_this_block_size);
rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
&dummy_rate, &dummy_dist, 1);
+ } else if (cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION ||
+ cpi->sf.partition_search_type == VAR_BASED_PARTITION) {
+ // TODO(debargha): Implement VAR_BASED_PARTITION as a separate case.
+ // Currently both VAR_BASED_FIXED_PARTITION/VAR_BASED_PARTITION
+ // map to the same thing.
+ BLOCK_SIZE bsize;
+ set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
+ bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
+ set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
+ rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
+ &dummy_rate, &dummy_dist, 1);
} else {
if ((cm->current_video_frame
% cpi->sf.last_partitioning_redo_frequency) == 0
@@ -2252,12 +2323,9 @@ static INLINE int get_block_col(int b32i, int b16i, int b8i) {
return ((b32i & 1) << 2) + ((b16i & 1) << 1) + (b8i & 1);
}
-static void rtc_use_partition(VP9_COMP *cpi,
- const TileInfo *const tile,
- MODE_INFO **mi_8x8,
- TOKENEXTRA **tp, int mi_row, int mi_col,
- BLOCK_SIZE bsize, int *rate, int64_t *dist,
- int do_recon) {
+static void nonrd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
+ TOKENEXTRA **tp, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, int *rate, int64_t *dist) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
@@ -2270,23 +2338,22 @@ static void rtc_use_partition(VP9_COMP *cpi,
int rows = MIN(MI_BLOCK_SIZE, tile->mi_row_end - mi_row);
int cols = MIN(MI_BLOCK_SIZE, tile->mi_col_end - mi_col);
- int mi_8x8_width = num_8x8_blocks_wide_lookup[bsize];
- int mi_8x8_hight = num_8x8_blocks_high_lookup[bsize];
+ int bw = num_8x8_blocks_wide_lookup[bsize];
+ int bh = num_8x8_blocks_high_lookup[bsize];
- int brate;
- int64_t bdist;
+ int brate = 0;
+ int64_t bdist = 0;
*rate = 0;
*dist = 0;
// find prediction mode for each 8x8 block
- for (br = 0; br < rows; br += mi_8x8_hight) {
- for (bc = 0; bc < cols; bc += mi_8x8_width) {
+ for (br = 0; br < rows; br += bh) {
+ for (bc = 0; bc < cols; bc += bw) {
int row = mi_row + br;
int col = mi_col + bc;
- int bh = 0, bw = 0;
+
BLOCK_SIZE bs = find_partition_size(bsize, rows - br, cols - bc,
&bh, &bw);
-
set_offsets(cpi, tile, row, col, bs);
if (cm->frame_type != KEY_FRAME)
@@ -2298,20 +2365,20 @@ static void rtc_use_partition(VP9_COMP *cpi,
*dist += bdist;
for (j = 0; j < bh; ++j)
- for (i = 0; i < bw; ++i)
+ for (i = 0; i < bw; ++i) {
xd->mi_8x8[j * mis + i] = xd->mi_8x8[0];
+ }
}
}
- encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, BLOCK_64X64);
-
*rate = chosen_rate;
*dist = chosen_dist;
+
+ encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, BLOCK_64X64);
}
-static void encode_rtc_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
- int mi_row, TOKENEXTRA **tp) {
- VP9_COMMON * const cm = &cpi->common;
+static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
+ int mi_row, TOKENEXTRA **tp) {
int mi_col;
// Initialize the left context for the new SB row
@@ -2324,13 +2391,25 @@ static void encode_rtc_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
int dummy_rate;
int64_t dummy_dist;
- const int idx_str = cm->mode_info_stride * mi_row + mi_col;
- MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
cpi->mb.source_variance = UINT_MAX;
- rtc_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
- cpi->sf.always_this_block_size,
- &dummy_rate, &dummy_dist, 1);
+ if (cpi->sf.partition_search_type == FIXED_PARTITION) {
+ nonrd_use_partition(cpi, tile, tp, mi_row, mi_col,
+ cpi->sf.always_this_block_size,
+ &dummy_rate, &dummy_dist);
+ } else if (cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION ||
+ cpi->sf.partition_search_type == VAR_BASED_PARTITION) {
+ // TODO(debargha): Implement VAR_BASED_PARTITION as a separate case.
+ // Currently both VAR_BASED_FIXED_PARTITION/VAR_BASED_PARTITION
+ // map to the same thing.
+ BLOCK_SIZE bsize = get_nonrd_var_based_fixed_partition(cpi,
+ mi_row,
+ mi_col);
+ nonrd_use_partition(cpi, tile, tp, mi_row, mi_col,
+ bsize, &dummy_rate, &dummy_dist);
+ } else {
+ assert(0);
+ }
}
}
// end RTC play code
@@ -2386,7 +2465,7 @@ static void encode_frame_internal(VP9_COMP *cpi) {
set_prev_mi(cm);
- if (cpi->sf.use_pick_mode) {
+ if (cpi->sf.use_nonrd_pick_mode) {
// Initialize internal buffer pointers for rtc coding, where non-RD
// mode decision is used and hence no buffer pointer swap needed.
int i;
@@ -2422,10 +2501,10 @@ static void encode_frame_internal(VP9_COMP *cpi) {
vp9_tile_init(&tile, cm, tile_row, tile_col);
for (mi_row = tile.mi_row_start;
mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) {
- if (cpi->sf.use_pick_mode)
- encode_rtc_sb_row(cpi, &tile, mi_row, &tp);
+ if (cpi->sf.use_nonrd_pick_mode)
+ encode_nonrd_sb_row(cpi, &tile, mi_row, &tp);
else
- encode_sb_row(cpi, &tile, mi_row, &tp);
+ encode_rd_sb_row(cpi, &tile, mi_row, &tp);
}
cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old);
assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols));
@@ -2688,7 +2767,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 &&
(cpi->oxcf.aq_mode != COMPLEXITY_AQ) &&
- !cpi->sf.use_pick_mode;
+ !cpi->sf.use_nonrd_pick_mode;
x->skip_optimize = ctx->is_coded;
ctx->is_coded = 1;
x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 8cb2843bd..13eabe05d 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -105,10 +105,9 @@ static int trellis_get_coeff_context(const int16_t *scan,
return pt;
}
-static void optimize_b(MACROBLOCK *mb,
- int plane, int block, BLOCK_SIZE plane_bsize,
- ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
- TX_SIZE tx_size) {
+static void optimize_b(int plane, int block, BLOCK_SIZE plane_bsize,
+ TX_SIZE tx_size, MACROBLOCK *mb,
+ struct optimize_ctx *ctx) {
MACROBLOCKD *const xd = &mb->e_mbd;
struct macroblock_plane *p = &mb->plane[plane];
struct macroblockd_plane *pd = &xd->plane[plane];
@@ -134,6 +133,11 @@ static void optimize_b(MACROBLOCK *mb,
const scan_order *so = get_scan(xd, tx_size, type, block);
const int16_t *scan = so->scan;
const int16_t *nb = so->neighbors;
+ ENTROPY_CONTEXT *a, *l;
+ int tx_x, tx_y;
+ txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &tx_x, &tx_y);
+ a = &ctx->ta[plane][tx_x];
+ l = &ctx->tl[plane][tx_y];
assert((!type && !plane) || (type && plane));
assert(eob <= default_eob);
@@ -307,29 +311,6 @@ static void optimize_b(MACROBLOCK *mb,
*a = *l = (final_eob > 0);
}
-void vp9_optimize_b(int plane, int block, BLOCK_SIZE plane_bsize,
- TX_SIZE tx_size, MACROBLOCK *mb, struct optimize_ctx *ctx) {
- int x, y;
- txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
- optimize_b(mb, plane, block, plane_bsize,
- &ctx->ta[plane][x], &ctx->tl[plane][y], tx_size);
-}
-
-static void optimize_init_b(int plane, BLOCK_SIZE bsize,
- struct encode_b_args *args) {
- const MACROBLOCKD *xd = &args->x->e_mbd;
- const struct macroblockd_plane* const pd = &xd->plane[plane];
- const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
- const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
- const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
- const MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
- const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi) : mbmi->tx_size;
-
- vp9_get_entropy_contexts(tx_size, args->ctx->ta[plane], args->ctx->tl[plane],
- pd->above_context, pd->left_context,
- num_4x4_w, num_4x4_h);
-}
-
static INLINE void fdct32x32(int rd_transform,
const int16_t *src, int16_t *dst, int src_stride) {
if (rd_transform)
@@ -341,22 +322,21 @@ static INLINE void fdct32x32(int rd_transform,
void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
MACROBLOCKD *const xd = &x->e_mbd;
- struct macroblock_plane *const p = &x->plane[plane];
- struct macroblockd_plane *const pd = &xd->plane[plane];
- int16_t *coeff = BLOCK_OFFSET(p->coeff, block);
- int16_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
- int16_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
- const scan_order *scan_order;
- uint16_t *eob = &p->eobs[block];
+ const struct macroblock_plane *const p = &x->plane[plane];
+ const struct macroblockd_plane *const pd = &xd->plane[plane];
+ const scan_order *const scan_order = &vp9_default_scan_orders[tx_size];
+ int16_t *const coeff = BLOCK_OFFSET(p->coeff, block);
+ int16_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
+ int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
+ uint16_t *const eob = &p->eobs[block];
const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
int i, j;
- int16_t *src_diff;
+ const int16_t *src_diff;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
switch (tx_size) {
case TX_32X32:
- scan_order = &vp9_default_scan_orders[TX_32X32];
fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
@@ -364,7 +344,6 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
scan_order->iscan);
break;
case TX_16X16:
- scan_order = &vp9_default_scan_orders[TX_16X16];
vp9_fdct16x16(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
@@ -372,7 +351,6 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
- scan_order = &vp9_default_scan_orders[TX_8X8];
vp9_fdct8x8(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
@@ -380,7 +358,6 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
- scan_order = &vp9_default_scan_orders[TX_4X4];
x->fwd_txm4x4(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
@@ -419,7 +396,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
- vp9_optimize_b(plane, block, plane_bsize, tx_size, x, ctx);
+ optimize_b(plane, block, plane_bsize, tx_size, x, ctx);
} else {
ctx->ta[plane][i] = p->eobs[block] > 0;
ctx->tl[plane][j] = p->eobs[block] > 0;
@@ -453,8 +430,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
}
static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
- struct encode_b_args *const args = arg;
- MACROBLOCK *const x = args->x;
+ MACROBLOCK *const x = (MACROBLOCK *)arg;
MACROBLOCKD *const xd = &x->e_mbd;
struct macroblock_plane *const p = &x->plane[plane];
struct macroblockd_plane *const pd = &xd->plane[plane];
@@ -466,24 +442,14 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
- if (p->eobs[block] == 0)
- return;
-
- xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
+ if (p->eobs[block] > 0)
+ xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
}
-void vp9_encode_sby(MACROBLOCK *x, BLOCK_SIZE bsize) {
- MACROBLOCKD *const xd = &x->e_mbd;
- struct optimize_ctx ctx;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
- struct encode_b_args arg = {x, &ctx, &mbmi->skip};
-
+void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize) {
vp9_subtract_plane(x, bsize, 0);
- if (x->optimize)
- optimize_init_b(0, bsize, &arg);
-
- vp9_foreach_transformed_block_in_plane(xd, bsize, 0, encode_block_pass1,
- &arg);
+ vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
+ encode_block_pass1, x);
}
void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize) {
@@ -497,8 +463,12 @@ void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize) {
if (!x->skip_recode)
vp9_subtract_plane(x, bsize, plane);
- if (x->optimize && (!x->skip_recode || !x->skip_optimize))
- optimize_init_b(plane, bsize, &arg);
+ if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
+ const struct macroblockd_plane* const pd = &xd->plane[plane];
+ const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi) : mbmi->tx_size;
+ vp9_get_entropy_contexts(bsize, tx_size, pd,
+ ctx.ta[plane], ctx.tl[plane]);
+ }
vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
&arg);
@@ -533,7 +503,7 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
// if (x->optimize)
- // vp9_optimize_b(plane, block, plane_bsize, tx_size, x, args->ctx);
+ // optimize_b(plane, block, plane_bsize, tx_size, x, args->ctx);
switch (tx_size) {
case TX_32X32:
diff --git a/vp9/encoder/vp9_encodemb.h b/vp9/encoder/vp9_encodemb.h
index a61f776a4..dcf6e8759 100644
--- a/vp9/encoder/vp9_encodemb.h
+++ b/vp9/encoder/vp9_encodemb.h
@@ -21,7 +21,7 @@ extern "C" {
#endif
void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize);
-void vp9_encode_sby(MACROBLOCK *x, BLOCK_SIZE bsize);
+void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize);
void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c
index af710a8f4..507969951 100644
--- a/vp9/encoder/vp9_encodemv.c
+++ b/vp9/encoder/vp9_encodemv.c
@@ -224,35 +224,29 @@ void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w,
}
}
-void vp9_build_nmv_cost_table(int *mvjoint,
- int *mvcost[2],
- const nmv_context* const mvctx,
- int usehp,
- int mvc_flag_v,
- int mvc_flag_h) {
- vp9_clear_system_state();
- vp9_cost_tokens(mvjoint, mvctx->joints, vp9_mv_joint_tree);
- if (mvc_flag_v)
- build_nmv_component_cost_table(mvcost[0], &mvctx->comps[0], usehp);
- if (mvc_flag_h)
- build_nmv_component_cost_table(mvcost[1], &mvctx->comps[1], usehp);
+void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
+ const nmv_context* ctx, int usehp) {
+ vp9_cost_tokens(mvjoint, ctx->joints, vp9_mv_joint_tree);
+ build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], usehp);
+ build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp);
}
-static void inc_mvs(int_mv mv[2], int_mv ref[2], int is_compound,
+static void inc_mvs(const int_mv mv[2], const MV ref[2], int is_compound,
nmv_context_counts *counts) {
int i;
for (i = 0; i < 1 + is_compound; ++i) {
- const MV diff = { mv[i].as_mv.row - ref[i].as_mv.row,
- mv[i].as_mv.col - ref[i].as_mv.col };
+ const MV diff = { mv[i].as_mv.row - ref[i].row,
+ mv[i].as_mv.col - ref[i].col };
vp9_inc_mv(&diff, counts);
}
}
-void vp9_update_mv_count(VP9_COMP *cpi, MACROBLOCK *x, int_mv best_ref_mv[2]) {
- MODE_INFO *mi = x->e_mbd.mi_8x8[0];
- MB_MODE_INFO *const mbmi = &mi->mbmi;
+void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd,
+ const MV best_ref_mv[2]) {
+ const MODE_INFO *mi = xd->mi_8x8[0];
+ const MB_MODE_INFO *const mbmi = &mi->mbmi;
const int is_compound = has_second_ref(mbmi);
- nmv_context_counts *counts = &cpi->common.counts.mv;
+ nmv_context_counts *counts = &cm->counts.mv;
if (mbmi->sb_type < BLOCK_8X8) {
const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type];
diff --git a/vp9/encoder/vp9_encodemv.h b/vp9/encoder/vp9_encodemv.h
index f0463bbd3..f16b2c17c 100644
--- a/vp9/encoder/vp9_encodemv.h
+++ b/vp9/encoder/vp9_encodemv.h
@@ -25,14 +25,11 @@ void vp9_write_nmv_probs(VP9_COMMON *cm, int usehp, vp9_writer *w);
void vp9_encode_mv(VP9_COMP *cpi, vp9_writer* w, const MV* mv, const MV* ref,
const nmv_context* mvctx, int usehp);
-void vp9_build_nmv_cost_table(int *mvjoint,
- int *mvcost[2],
- const nmv_context* const mvctx,
- int usehp,
- int mvc_flag_v,
- int mvc_flag_h);
-
-void vp9_update_mv_count(VP9_COMP *cpi, MACROBLOCK *x, int_mv best_ref_mv[2]);
+void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
+ const nmv_context* mvctx, int usehp);
+
+void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd,
+ const MV best_ref_mv[2]);
#ifdef __cplusplus
} // extern "C"
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index ddb901dd1..32ed96999 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -675,7 +675,7 @@ void vp9_first_pass(VP9_COMP *cpi) {
xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME;
xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE;
vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
- vp9_encode_sby(x, bsize);
+ vp9_encode_sby_pass1(x, bsize);
sum_mvr += mv.as_mv.row;
sum_mvr_abs += abs(mv.as_mv.row);
sum_mvc += mv.as_mv.col;
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 8f3d82570..95ebb0c6d 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -14,6 +14,8 @@
#include "./vpx_config.h"
#include "./vpx_scale_rtcd.h"
+#include "vpx/internal/vpx_psnr.h"
+#include "vpx_ports/vpx_timer.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_filter.h"
@@ -30,7 +32,6 @@
#include "vp9/encoder/vp9_mbgraph.h"
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_picklpf.h"
-#include "vp9/encoder/vp9_psnr.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
@@ -38,8 +39,6 @@
#include "vp9/encoder/vp9_vaq.h"
#include "vp9/encoder/vp9_resize.h"
-#include "vpx_ports/vpx_timer.h"
-
void vp9_entropy_mode_init();
void vp9_coef_tree_initialize();
@@ -491,18 +490,6 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi) {
sf->thresh_mult[THR_D207_PRED] += 2500;
sf->thresh_mult[THR_D63_PRED] += 2500;
- // disable using golden frame modes if golden frames are not being used
- if (cpi->rc.frames_till_gf_update_due == INT_MAX) {
- sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
- sf->thresh_mult[THR_ZEROG ] = INT_MAX;
- sf->thresh_mult[THR_NEARG ] = INT_MAX;
- sf->thresh_mult[THR_NEWG ] = INT_MAX;
- sf->thresh_mult[THR_COMP_ZEROGA ] = INT_MAX;
- sf->thresh_mult[THR_COMP_NEARESTGA] = INT_MAX;
- sf->thresh_mult[THR_COMP_NEARGA ] = INT_MAX;
- sf->thresh_mult[THR_COMP_NEWGA ] = INT_MAX;
- }
-
/* disable frame modes if flags not set */
if (!(cpi->ref_frame_flags & VP9_LAST_FLAG)) {
sf->thresh_mult[THR_NEWMV ] = INT_MAX;
@@ -717,7 +704,7 @@ static void set_good_speed_feature(VP9_COMMON *cm,
}
if (speed >= 5) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
- sf->use_one_partition_size_always = 1;
+ sf->partition_search_type = FIXED_PARTITION;
sf->always_this_block_size = BLOCK_16X16;
sf->tx_size_search_method = frame_is_intra_only(cm) ?
USE_FULL_RD : USE_LARGESTALL;
@@ -852,6 +839,9 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
sf->adaptive_rd_thresh = 5;
sf->auto_min_max_partition_size = frame_is_intra_only(cm) ?
RELAXED_NEIGHBORING_MIN_MAX : STRICT_NEIGHBORING_MIN_MAX;
+ sf->adjust_partitioning_from_last_frame =
+ cm->last_frame_type == KEY_FRAME || (0 ==
+ (cm->current_video_frame + 1) % sf->last_partitioning_redo_frequency);
sf->subpel_force_stop = 1;
for (i = 0; i < TX_SIZES; i++) {
sf->intra_y_mode_mask[i] = INTRA_DC_H_V;
@@ -859,16 +849,14 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
}
sf->frame_parameter_update = 0;
sf->encode_breakout_thresh = 1000;
-
sf->search_method = FAST_HEX;
}
if (speed >= 6) {
- sf->use_one_partition_size_always = 1;
- sf->always_this_block_size = BLOCK_32X32;
+ sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
}
if (speed >= 7) {
- sf->always_this_block_size = BLOCK_16X16;
- sf->use_pick_mode = 1;
+ sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
+ sf->use_nonrd_pick_mode = 1;
}
}
@@ -906,7 +894,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->adaptive_motion_search = 0;
sf->adaptive_pred_interp_filter = 0;
sf->reference_masking = 0;
- sf->use_one_partition_size_always = 0;
+ sf->partition_search_type = SEARCH_PARTITION;
sf->less_rectangular_check = 0;
sf->use_square_partition_only = 0;
sf->auto_min_max_partition_size = NOT_IN_USE;
@@ -928,7 +916,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_fast_lpf_pick = 0;
sf->use_fast_coef_updates = 0;
sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set
- sf->use_pick_mode = 0;
+ sf->use_nonrd_pick_mode = 0;
sf->encode_breakout_thresh = 0;
switch (cpi->oxcf.mode) {
@@ -2043,11 +2031,11 @@ void vp9_remove_compressor(VP9_PTR *ptr) {
if (cpi->b_calculate_psnr) {
const double total_psnr =
- vp9_mse2psnr((double)cpi->total_samples, 255.0,
- (double)cpi->total_sq_error);
+ vpx_sse_to_psnr((double)cpi->total_samples, 255.0,
+ (double)cpi->total_sq_error);
const double totalp_psnr =
- vp9_mse2psnr((double)cpi->totalp_samples, 255.0,
- (double)cpi->totalp_sq_error);
+ vpx_sse_to_psnr((double)cpi->totalp_samples, 255.0,
+ (double)cpi->totalp_sq_error);
const double total_ssim = 100 * pow(cpi->summed_quality /
cpi->summed_weights, 8.0);
const double totalp_ssim = 100 * pow(cpi->summedp_quality /
@@ -2228,7 +2216,7 @@ static void calc_psnr(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b,
w, h);
psnr->sse[1 + i] = sse;
psnr->samples[1 + i] = samples;
- psnr->psnr[1 + i] = vp9_mse2psnr(samples, 255.0, (double) sse);
+ psnr->psnr[1 + i] = vpx_sse_to_psnr(samples, 255.0, (double)sse);
total_sse += sse;
total_samples += samples;
@@ -2236,7 +2224,8 @@ static void calc_psnr(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b,
psnr->sse[0] = total_sse;
psnr->samples[0] = total_samples;
- psnr->psnr[0] = vp9_mse2psnr((double)total_samples, 255.0, (double)total_sse);
+ psnr->psnr[0] = vpx_sse_to_psnr((double)total_samples, 255.0,
+ (double)total_sse);
}
static void generate_psnr_packet(VP9_COMP *cpi) {
@@ -2903,7 +2892,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
vp9_save_coding_context(cpi);
cpi->dummy_packing = 1;
- if (!cpi->sf.use_pick_mode)
+ if (!cpi->sf.use_nonrd_pick_mode)
vp9_pack_bitstream(cpi, dest, size);
rc->projected_frame_size = (int)(*size) << 3;
@@ -3072,6 +3061,9 @@ static void get_ref_frame_flags(VP9_COMP *cpi) {
if (cpi->gold_is_last)
cpi->ref_frame_flags &= ~VP9_GOLD_FLAG;
+ if (cpi->rc.frames_till_gf_update_due == INT_MAX)
+ cpi->ref_frame_flags &= ~VP9_GOLD_FLAG;
+
if (cpi->alt_is_last)
cpi->ref_frame_flags &= ~VP9_ALT_FLAG;
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 7bcceedb8..fd2356591 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -218,6 +218,22 @@ typedef enum {
ENCODE_BREAKOUT_LIMITED = 2
} ENCODE_BREAKOUT_TYPE;
+typedef enum {
+ // Search partitions using RD/NONRD criterion
+ SEARCH_PARTITION = 0,
+
+ // Always use a fixed size partition
+ FIXED_PARTITION = 1,
+
+ // Use a fixed size partition in every 64X64 SB, where the size is
+ // determined based on source variance
+ VAR_BASED_FIXED_PARTITION = 2,
+
+ // Use an arbitrary partitioning scheme based on source variance within
+ // a 64X64 SB
+ VAR_BASED_PARTITION
+} PARTITION_SEARCH_TYPE;
+
typedef struct {
// Frame level coding parameter update
int frame_parameter_update;
@@ -304,16 +320,6 @@ typedef struct {
// TODO(JBB): remove this as its no longer used.
- // If set partition size will always be always_this_block_size.
- int use_one_partition_size_always;
-
- // Skip rectangular partition test when partition type none gives better
- // rd than partition type split.
- int less_rectangular_check;
-
- // Disable testing non square partitions. (eg 16x32)
- int use_square_partition_only;
-
// After looking at the first set of modes (set by index here), skip
// checking modes for reference frames that don't match the reference frame
// of the best so far.
@@ -322,9 +328,18 @@ typedef struct {
// TODO(JBB): Remove this.
int reference_masking;
- // Used in conjunction with use_one_partition_size_always.
+ PARTITION_SEARCH_TYPE partition_search_type;
+
+ // Used if partition_search_type = FIXED_SIZE_PARTITION
BLOCK_SIZE always_this_block_size;
+ // Skip rectangular partition test when partition type none gives better
+ // rd than partition type split.
+ int less_rectangular_check;
+
+ // Disable testing non square partitions. (eg 16x32)
+ int use_square_partition_only;
+
// Sets min and max partition sizes for this 64x64 region based on the
// same 64x64 in last encoded frame, and the left and above neighbor.
AUTO_MIN_MAX_MODE auto_min_max_partition_size;
@@ -396,7 +411,7 @@ typedef struct {
int use_fast_coef_updates; // 0: 2-loop, 1: 1-loop, 2: 1-loop reduced
// This flag controls the use of non-RD mode decision.
- int use_pick_mode;
+ int use_nonrd_pick_mode;
// This variable sets the encode_breakout threshold. Currently, it is only
// enabled in real time mode.
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 383d92751..87f20fa1c 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -98,8 +98,15 @@ static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
mvp_full.col >>= 3;
mvp_full.row >>= 3;
- vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, sadpb, further_steps, 1,
- &cpi->fn_ptr[bsize], &ref_mv.as_mv, &tmp_mv->as_mv);
+ if (cpi->sf.search_method == FAST_HEX) {
+ vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, &cpi->fn_ptr[bsize],
+ 1, &ref_mv.as_mv, &tmp_mv->as_mv);
+ } else {
+ vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, sadpb, further_steps,
+ 1, &cpi->fn_ptr[bsize], &ref_mv.as_mv,
+ &tmp_mv->as_mv);
+ }
+
x->mv_col_min = tmp_col_min;
x->mv_col_max = tmp_col_max;
x->mv_row_min = tmp_row_min;
@@ -183,9 +190,11 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bsize) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
+ struct macroblock_plane *const p = &x->plane[0];
+ struct macroblockd_plane *const pd = &xd->plane[0];
const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
- MB_PREDICTION_MODE this_mode;
- MV_REFERENCE_FRAME ref_frame;
+ MB_PREDICTION_MODE this_mode, best_mode = ZEROMV;
+ MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
@@ -240,38 +249,51 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd);
clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd);
+ mbmi->ref_frame[0] = ref_frame;
+
for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
int rate = cost[INTER_OFFSET(this_mode)];
int64_t dist;
if (this_mode == NEWMV) {
+ if (this_rd < 500)
+ continue;
+
x->mode_sad[ref_frame][INTER_OFFSET(NEWMV)] =
full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
&frame_mv[NEWMV][ref_frame], &rate_mv);
if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV)
continue;
+
+ sub_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
+ &frame_mv[NEWMV][ref_frame]);
}
- dist = x->mode_sad[ref_frame][INTER_OFFSET(this_mode)];
+ mbmi->mode = this_mode;
+ mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
+ vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
+
+ dist = cpi->fn_ptr[bsize].sdf(p->src.buf, p->src.stride,
+ pd->dst.buf, pd->dst.stride, INT_MAX);
this_rd = rate + dist;
if (this_rd < best_rd) {
best_rd = this_rd;
- mbmi->mode = this_mode;
- mbmi->ref_frame[0] = ref_frame;
- mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
- xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
- mbmi->uv_mode = this_mode;
+ best_mode = this_mode;
+ best_ref_frame = ref_frame;
}
}
}
+ mbmi->mode = best_mode;
+ mbmi->ref_frame[0] = best_ref_frame;
+ mbmi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
+ xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
+
// Perform intra prediction search, if the best SAD is above a certain
// threshold.
if (best_rd > inter_mode_thresh) {
- struct macroblock_plane *const p = &x->plane[0];
- struct macroblockd_plane *const pd = &xd->plane[0];
for (this_mode = DC_PRED; this_mode <= DC_PRED; ++this_mode) {
vp9_predict_intra_block(xd, 0, b_width_log2(bsize),
mbmi->tx_size, this_mode,
@@ -288,18 +310,10 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->mode = this_mode;
mbmi->ref_frame[0] = INTRA_FRAME;
mbmi->uv_mode = this_mode;
+ mbmi->mv[0].as_int = INVALID_MV;
}
}
}
- // Perform sub-pixel motion search, if NEWMV is chosen
- if (mbmi->mode == NEWMV) {
- ref_frame = mbmi->ref_frame[0];
- sub_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
- &frame_mv[NEWMV][ref_frame]);
- mbmi->mv[0].as_int = frame_mv[NEWMV][ref_frame].as_int;
- xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
- }
-
return INT64_MAX;
}
diff --git a/vp9/encoder/vp9_psnr.c b/vp9/encoder/vp9_psnr.c
deleted file mode 100644
index 58294e15a..000000000
--- a/vp9/encoder/vp9_psnr.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <math.h>
-
-#include "vpx_scale/yv12config.h"
-
-#define MAX_PSNR 100
-
-double vp9_mse2psnr(double samples, double peak, double mse) {
- double psnr;
-
- if (mse > 0.0)
- psnr = 10.0 * log10(peak * peak * samples / mse);
- else
- psnr = MAX_PSNR; // Limit to prevent / 0
-
- if (psnr > MAX_PSNR)
- psnr = MAX_PSNR;
-
- return psnr;
-}
diff --git a/vp9/encoder/vp9_psnr.h b/vp9/encoder/vp9_psnr.h
deleted file mode 100644
index ffe00ed2c..000000000
--- a/vp9/encoder/vp9_psnr.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-
-#ifndef VP9_ENCODER_VP9_PSNR_H_
-#define VP9_ENCODER_VP9_PSNR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-double vp9_mse2psnr(double samples, double peak, double mse);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // VP9_ENCODER_VP9_PSNR_H_
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index f78ebfe18..89aa82140 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -8,23 +8,24 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
#include <assert.h>
+#include <limits.h>
#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vpx_mem/vpx_mem.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_common.h"
-#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/common/vp9_entropymode.h"
-#include "vpx_mem/vpx_mem.h"
-#include "vp9/common/vp9_systemdependent.h"
-#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_seg_common.h"
+#include "vp9/common/vp9_systemdependent.h"
+
+#include "vp9/encoder/vp9_encodemv.h"
+#include "vp9/encoder/vp9_ratectrl.h"
#define LIMIT_QRANGE_FOR_ALTREF_AND_KEY 1
@@ -958,17 +959,10 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
}
// Clip the active best and worst quality values to limits.
- if (active_worst_quality > rc->worst_quality)
- active_worst_quality = rc->worst_quality;
-
- if (active_best_quality < rc->best_quality)
- active_best_quality = rc->best_quality;
-
- if (active_best_quality > rc->worst_quality)
- active_best_quality = rc->worst_quality;
-
- if (active_worst_quality < active_best_quality)
- active_worst_quality = active_best_quality;
+ active_best_quality = clamp(active_best_quality,
+ rc->best_quality, rc->worst_quality);
+ active_worst_quality = clamp(active_worst_quality,
+ active_best_quality, rc->worst_quality);
*top_index = active_worst_quality;
*bottom_index = active_best_quality;
@@ -1041,7 +1035,7 @@ int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi,
// JBB : This is realtime mode. In real time mode the first frame
// should be larger. Q of 0 is disabled because we force tx size to be
// 16x16...
- if (cpi->sf.use_pick_mode) {
+ if (cpi->sf.use_nonrd_pick_mode) {
if (cpi->common.current_video_frame == 0)
q /= 3;
if (q == 0)
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 35d8f1672..7cf1bdf06 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -296,7 +296,7 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi) {
set_block_thresholds(cpi);
- if (!cpi->sf.use_pick_mode) {
+ if (!cpi->sf.use_nonrd_pick_mode) {
fill_token_costs(x->token_costs, cm->fc.coef_probs);
for (i = 0; i < PARTITION_CONTEXTS; i++)
@@ -304,15 +304,14 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi) {
vp9_partition_tree);
}
- if (!cpi->sf.use_pick_mode || (cm->current_video_frame & 0x07) == 1) {
+ if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1) {
fill_mode_costs(cpi);
if (!frame_is_intra_only(cm)) {
vp9_build_nmv_cost_table(x->nmvjointcost,
cm->allow_high_precision_mv ? x->nmvcost_hp
: x->nmvcost,
- &cm->fc.nmvc,
- cm->allow_high_precision_mv, 1, 1);
+ &cm->fc.nmvc, cm->allow_high_precision_mv);
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
vp9_cost_tokens((int *)x->inter_mode_cost[i],
@@ -566,18 +565,16 @@ static INLINE int cost_coeffs(MACROBLOCK *x,
const PLANE_TYPE type = pd->plane_type;
const int16_t *band_count = &band_counts[tx_size][1];
const int eob = p->eobs[block];
- const int16_t *const qcoeff_ptr = BLOCK_OFFSET(p->qcoeff, block);
- const int ref = mbmi->ref_frame[0] != INTRA_FRAME;
+ const int16_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
- x->token_costs[tx_size][type][ref];
- const ENTROPY_CONTEXT above_ec = !!*A, left_ec = !!*L;
+ x->token_costs[tx_size][type][is_inter_block(mbmi)];
uint8_t *p_tok = x->token_cache;
- int pt = combine_entropy_contexts(above_ec, left_ec);
+ int pt = combine_entropy_contexts(*A, *L);
int c, cost;
// Check for consistency of tx_size with mode info
assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
- : get_uv_tx_size(mbmi) == tx_size);
+ : get_uv_tx_size(mbmi) == tx_size);
if (eob == 0) {
// single eob token
@@ -587,7 +584,7 @@ static INLINE int cost_coeffs(MACROBLOCK *x,
int band_left = *band_count++;
// dc token
- int v = qcoeff_ptr[0];
+ int v = qcoeff[0];
int prev_t = vp9_dct_value_tokens_ptr[v].token;
cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v];
p_tok[0] = vp9_pt_energy_class[prev_t];
@@ -598,7 +595,7 @@ static INLINE int cost_coeffs(MACROBLOCK *x,
const int rc = scan[c];
int t;
- v = qcoeff_ptr[rc];
+ v = qcoeff[rc];
t = vp9_dct_value_tokens_ptr[v].token;
pt = get_coef_context(nb, p_tok, c);
cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v];
@@ -695,10 +692,16 @@ static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
}
}
-void vp9_get_entropy_contexts(TX_SIZE tx_size,
- ENTROPY_CONTEXT t_above[16], ENTROPY_CONTEXT t_left[16],
- const ENTROPY_CONTEXT *above, const ENTROPY_CONTEXT *left,
- int num_4x4_w, int num_4x4_h) {
+void vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size,
+ const struct macroblockd_plane *pd,
+ ENTROPY_CONTEXT t_above[16],
+ ENTROPY_CONTEXT t_left[16]) {
+ const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
+ const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
+ const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
+ const ENTROPY_CONTEXT *const above = pd->above_context;
+ const ENTROPY_CONTEXT *const left = pd->left_context;
+
int i;
switch (tx_size) {
case TX_4X4:
@@ -735,9 +738,6 @@ static void txfm_rd_in_plane(MACROBLOCK *x,
BLOCK_SIZE bsize, TX_SIZE tx_size) {
MACROBLOCKD *const xd = &x->e_mbd;
struct macroblockd_plane *const pd = &xd->plane[plane];
- const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
- const int num_4x4_w = num_4x4_blocks_wide_lookup[bs];
- const int num_4x4_h = num_4x4_blocks_high_lookup[bs];
struct rdcost_block_args args = { 0 };
args.x = x;
args.best_rd = ref_best_rd;
@@ -745,9 +745,7 @@ static void txfm_rd_in_plane(MACROBLOCK *x,
if (plane == 0)
xd->mi_8x8[0]->mbmi.tx_size = tx_size;
- vp9_get_entropy_contexts(tx_size, args.t_above, args.t_left,
- pd->above_context, pd->left_context,
- num_4x4_w, num_4x4_h);
+ vp9_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
args.so = get_scan(xd, tx_size, pd->plane_type, 0);
@@ -938,27 +936,23 @@ static void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x,
}
}
-static void super_block_yrd(VP9_COMP *cpi,
- MACROBLOCK *x, int *rate, int64_t *distortion,
- int *skip, int64_t *psse, BLOCK_SIZE bs,
- int64_t txfm_cache[TX_MODES],
- int64_t ref_best_rd) {
+static void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
+ int64_t *distortion, int *skip,
+ int64_t *psse, BLOCK_SIZE bs,
+ int64_t txfm_cache[TX_MODES],
+ int64_t ref_best_rd) {
int r[TX_SIZES][2], s[TX_SIZES];
int64_t d[TX_SIZES], sse[TX_SIZES];
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
- const int b_inter_mode = is_inter_block(mbmi);
const TX_SIZE max_tx_size = max_txsize_lookup[bs];
TX_SIZE tx_size;
-
assert(bs == mbmi->sb_type);
- if (b_inter_mode)
- vp9_subtract_plane(x, bs, 0);
- if (cpi->sf.tx_size_search_method == USE_LARGESTALL ||
- (cpi->sf.tx_size_search_method != USE_FULL_RD &&
- !b_inter_mode)) {
+ vp9_subtract_plane(x, bs, 0);
+
+ if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
ref_best_rd, bs);
@@ -967,8 +961,7 @@ static void super_block_yrd(VP9_COMP *cpi,
return;
}
- if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER &&
- b_inter_mode) {
+ if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER) {
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
model_rd_for_sb_y_tx(cpi, bs, tx_size, x, xd,
&r[tx_size][0], &d[tx_size], &s[tx_size]);
@@ -986,6 +979,36 @@ static void super_block_yrd(VP9_COMP *cpi,
*psse = sse[mbmi->tx_size];
}
+static void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
+ int64_t *distortion, int *skip,
+ int64_t *psse, BLOCK_SIZE bs,
+ int64_t txfm_cache[TX_MODES],
+ int64_t ref_best_rd) {
+ int64_t sse[TX_SIZES];
+ MACROBLOCKD *xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+
+ assert(bs == mbmi->sb_type);
+ if (cpi->sf.tx_size_search_method != USE_FULL_RD) {
+ vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
+ choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
+ ref_best_rd, bs);
+ } else {
+ int r[TX_SIZES][2], s[TX_SIZES];
+ int64_t d[TX_SIZES];
+ TX_SIZE tx_size;
+ for (tx_size = TX_4X4; tx_size <= max_txsize_lookup[bs]; ++tx_size)
+ txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
+ &s[tx_size], &sse[tx_size],
+ ref_best_rd, 0, bs, tx_size);
+ choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
+ skip, txfm_cache, bs);
+ }
+ if (psse)
+ *psse = sse[mbmi->tx_size];
+}
+
+
static int conditional_skipintra(MB_PREDICTION_MODE mode,
MB_PREDICTION_MODE best_intra_mode) {
if (mode == D117_PRED &&
@@ -1240,8 +1263,8 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
mic->mbmi.mode = mode;
- super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
- bsize, local_tx_cache, best_rd);
+ intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, local_tx_cache, best_rd);
if (this_rate_tokenonly == INT_MAX)
continue;
@@ -1276,7 +1299,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
return best_rd;
}
-static void super_block_uvrd(VP9_COMP *const cpi, MACROBLOCK *x,
+static void super_block_uvrd(MACROBLOCK *x,
int *rate, int64_t *distortion, int *skippable,
int64_t *sse, BLOCK_SIZE bsize,
int64_t ref_best_rd) {
@@ -1326,6 +1349,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
int *rate, int *rate_tokenonly,
int64_t *distortion, int *skippable,
BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
+ MACROBLOCKD *xd = &x->e_mbd;
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE mode_selected = DC_PRED;
int64_t best_rd = INT64_MAX, this_rd;
@@ -1336,9 +1360,9 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
continue;
- x->e_mbd.mi_8x8[0]->mbmi.uv_mode = mode;
+ xd->mi_8x8[0]->mbmi.uv_mode = mode;
- super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ super_block_uvrd(x, &this_rate_tokenonly,
&this_distortion, &s, &this_sse, bsize, best_rd);
if (this_rate_tokenonly == INT_MAX)
continue;
@@ -1356,7 +1380,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (!x->select_txfm_size) {
int i;
struct macroblock_plane *const p = x->plane;
- struct macroblockd_plane *const pd = x->e_mbd.plane;
+ struct macroblockd_plane *const pd = xd->plane;
for (i = 1; i < MAX_MB_PLANE; ++i) {
p[i].coeff = ctx->coeff_pbuf[i][2];
p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
@@ -1377,25 +1401,21 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
}
- x->e_mbd.mi_8x8[0]->mbmi.uv_mode = mode_selected;
+ xd->mi_8x8[0]->mbmi.uv_mode = mode_selected;
return best_rd;
}
-static int64_t rd_sbuv_dcpred(VP9_COMP *cpi, MACROBLOCK *x,
+static int64_t rd_sbuv_dcpred(const VP9_COMMON *cm, MACROBLOCK *x,
int *rate, int *rate_tokenonly,
int64_t *distortion, int *skippable,
BLOCK_SIZE bsize) {
- int64_t this_rd;
- int64_t this_sse;
+ int64_t unused;
x->e_mbd.mi_8x8[0]->mbmi.uv_mode = DC_PRED;
- super_block_uvrd(cpi, x, rate_tokenonly, distortion,
- skippable, &this_sse, bsize, INT64_MAX);
- *rate = *rate_tokenonly +
- x->intra_uv_mode_cost[cpi->common.frame_type][DC_PRED];
- this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
-
- return this_rd;
+ super_block_uvrd(x, rate_tokenonly, distortion,
+ skippable, &unused, bsize, INT64_MAX);
+ *rate = *rate_tokenonly + x->intra_uv_mode_cost[cm->frame_type][DC_PRED];
+ return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
}
static void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
@@ -1408,8 +1428,8 @@ static void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
// Use an estimated rd for uv_intra based on DC_PRED if the
// appropriate speed flag is set.
if (cpi->sf.use_uv_intra_rd_estimate) {
- rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
- bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
+ rd_sbuv_dcpred(&cpi->common, x, rate_uv, rate_uv_tokenonly, dist_uv,
+ skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
// Else do a proper rd search for each possible transform size that may
// be considered in the main rd loop.
} else {
@@ -1423,8 +1443,7 @@ static void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
static int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode,
int mode_context) {
MACROBLOCK *const x = &cpi->mb;
- MACROBLOCKD *const xd = &x->e_mbd;
- const int segment_id = xd->mi_8x8[0]->mbmi.segment_id;
+ const int segment_id = x->e_mbd.mi_8x8[0]->mbmi.segment_id;
// Don't account for mode here if segment skip is enabled.
if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
@@ -1449,7 +1468,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int *rate_mv);
static int labels2mode(MACROBLOCK *x, int i,
- MB_PREDICTION_MODE this_mode,
+ MB_PREDICTION_MODE mode,
int_mv *this_mv, int_mv *this_second_mv,
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
int_mv seg_mvs[MAX_REF_FRAMES],
@@ -1459,23 +1478,18 @@ static int labels2mode(MACROBLOCK *x, int i,
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *const mic = xd->mi_8x8[0];
MB_MODE_INFO *mbmi = &mic->mbmi;
- int cost = 0, thismvcost = 0;
+ int thismvcost = 0;
int idx, idy;
const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
const int has_second_rf = has_second_ref(mbmi);
- /* We have to be careful retrieving previously-encoded motion vectors.
- Ones from this macroblock have to be pulled from the BLOCKD array
- as they have not yet made it to the bmi array in our MB_MODE_INFO. */
- MB_PREDICTION_MODE m;
-
// the only time we should do costing for new motion vector or mode
// is when we are on a new label (jbb May 08, 2007)
- switch (m = this_mode) {
+ switch (mode) {
case NEWMV:
this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
- thismvcost = vp9_mv_bit_cost(&this_mv->as_mv, &best_ref_mv->as_mv,
+ thismvcost += vp9_mv_bit_cost(&this_mv->as_mv, &best_ref_mv->as_mv,
mvjcost, mvcost, MV_COST_WEIGHT_SUB);
if (has_second_rf) {
this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
@@ -1487,14 +1501,12 @@ static int labels2mode(MACROBLOCK *x, int i,
case NEARESTMV:
this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
if (has_second_rf)
- this_second_mv->as_int =
- frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
+ this_second_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
break;
case NEARMV:
this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
if (has_second_rf)
- this_second_mv->as_int =
- frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
+ this_second_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
break;
case ZEROMV:
this_mv->as_int = 0;
@@ -1505,22 +1517,19 @@ static int labels2mode(MACROBLOCK *x, int i,
break;
}
- cost = cost_mv_ref(cpi, this_mode,
- mbmi->mode_context[mbmi->ref_frame[0]]);
-
mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
if (has_second_rf)
mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
- mic->bmi[i].as_mode = m;
+ mic->bmi[i].as_mode = mode;
for (idy = 0; idy < num_4x4_blocks_high; ++idy)
for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
vpx_memcpy(&mic->bmi[i + idy * 2 + idx],
&mic->bmi[i], sizeof(mic->bmi[i]));
- cost += thismvcost;
- return cost;
+ return cost_mv_ref(cpi, mode, mbmi->mode_context[mbmi->ref_frame[0]]) +
+ thismvcost;
}
static int64_t encode_inter_mb_segment(VP9_COMP *cpi,
@@ -2369,7 +2378,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int sadpb = x->sadperbit16;
MV mvp_full;
int ref = mbmi->ref_frame[0];
- int_mv ref_mv = mbmi->ref_mvs[ref][0];
+ MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
int tmp_col_min = x->mv_col_min;
int tmp_col_max = x->mv_col_max;
@@ -2379,10 +2388,10 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
ref);
- int_mv pred_mv[3];
- pred_mv[0] = mbmi->ref_mvs[ref][0];
- pred_mv[1] = mbmi->ref_mvs[ref][1];
- pred_mv[2] = x->pred_mv[ref];
+ MV pred_mv[3];
+ pred_mv[0] = mbmi->ref_mvs[ref][0].as_mv;
+ pred_mv[1] = mbmi->ref_mvs[ref][1].as_mv;
+ pred_mv[2] = x->pred_mv[ref].as_mv;
if (scaled_ref_frame) {
int i;
@@ -2395,7 +2404,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
}
- vp9_set_mv_search_range(x, &ref_mv.as_mv);
+ vp9_set_mv_search_range(x, &ref_mv);
// Work out the size of the first step in the mv step search.
// 0 here is maximum length first step. 1 is MAX >> 1 etc.
@@ -2440,7 +2449,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
}
}
- mvp_full = pred_mv[x->mv_best_ref_index[ref]].as_mv;
+ mvp_full = pred_mv[x->mv_best_ref_index[ref]];
mvp_full.col >>= 3;
mvp_full.row >>= 3;
@@ -2451,24 +2460,24 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
if (cpi->sf.search_method == FAST_HEX) {
bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb,
&cpi->fn_ptr[bsize], 1,
- &ref_mv.as_mv, &tmp_mv->as_mv);
+ &ref_mv, &tmp_mv->as_mv);
} else if (cpi->sf.search_method == HEX) {
bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
- &ref_mv.as_mv, &tmp_mv->as_mv);
+ &ref_mv, &tmp_mv->as_mv);
} else if (cpi->sf.search_method == SQUARE) {
bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
- &ref_mv.as_mv, &tmp_mv->as_mv);
+ &ref_mv, &tmp_mv->as_mv);
} else if (cpi->sf.search_method == BIGDIA) {
bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
- &ref_mv.as_mv, &tmp_mv->as_mv);
+ &ref_mv, &tmp_mv->as_mv);
} else {
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 1,
&cpi->fn_ptr[bsize],
- &ref_mv.as_mv, &tmp_mv->as_mv);
+ &ref_mv, &tmp_mv->as_mv);
}
x->mv_col_min = tmp_col_min;
@@ -2478,7 +2487,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
if (bestsme < INT_MAX) {
int dis; /* TODO: use dis in distortion calculation later. */
- cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv.as_mv,
+ cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
cm->allow_high_precision_mv,
x->errorperbit,
&cpi->fn_ptr[bsize],
@@ -2487,7 +2496,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
x->nmvjointcost, x->mvcost,
&dis, &x->pred_sse[ref]);
}
- *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv,
+ *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
if (cpi->sf.adaptive_motion_search && cpi->common.show_frame)
@@ -2728,7 +2737,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
frame_mv[refs[0]].as_int == 0 &&
!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
(num_refs == 1 || frame_mv[refs[1]].as_int == 0)) {
- int rfc = mbmi->mode_context[mbmi->ref_frame[0]];
+ int rfc = mbmi->mode_context[refs[0]];
int c1 = cost_mv_ref(cpi, NEARMV, rfc);
int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
@@ -2743,17 +2752,17 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
assert(this_mode == ZEROMV);
if (num_refs == 1) {
if ((c3 >= c2 &&
- mode_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0) ||
+ mode_mv[NEARESTMV][refs[0]].as_int == 0) ||
(c3 >= c1 &&
- mode_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0))
+ mode_mv[NEARMV][refs[0]].as_int == 0))
return INT64_MAX;
} else {
if ((c3 >= c2 &&
- mode_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0 &&
- mode_mv[NEARESTMV][mbmi->ref_frame[1]].as_int == 0) ||
+ mode_mv[NEARESTMV][refs[0]].as_int == 0 &&
+ mode_mv[NEARESTMV][refs[1]].as_int == 0) ||
(c3 >= c1 &&
- mode_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0 &&
- mode_mv[NEARMV][mbmi->ref_frame[1]].as_int == 0))
+ mode_mv[NEARMV][refs[0]].as_int == 0 &&
+ mode_mv[NEARMV][refs[1]].as_int == 0))
return INT64_MAX;
}
}
@@ -2784,8 +2793,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
* 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 */
- *rate2 += cost_mv_ref(cpi, this_mode,
- mbmi->mode_context[mbmi->ref_frame[0]]);
+ *rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]);
if (!(*mode_excluded))
*mode_excluded = is_comp_pred ? cm->reference_mode == SINGLE_REFERENCE
@@ -3003,8 +3011,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int64_t rdcosty = INT64_MAX;
// Y cost and distortion
- super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
- bsize, txfm_cache, ref_best_rd);
+ inter_super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
+ bsize, txfm_cache, ref_best_rd);
if (*rate_y == INT_MAX) {
*rate2 = INT_MAX;
@@ -3019,7 +3027,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
- super_block_uvrd(cpi, x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
+ super_block_uvrd(x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
bsize, ref_best_rd - rdcosty);
if (*rate_uv == INT_MAX) {
*rate2 = INT_MAX;
@@ -3204,25 +3212,69 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
// All modes from vp9_mode_order that use this frame as any ref
static const int ref_frame_mask_all[] = {
- 0x123291, 0x25c444, 0x39b722
+ 0x0, 0x123291, 0x25c444, 0x39b722
};
// Fixed mv modes (NEARESTMV, NEARMV, ZEROMV) from vp9_mode_order that use
// this frame as their primary ref
static const int ref_frame_mask_fixedmv[] = {
- 0x121281, 0x24c404, 0x080102
+ 0x0, 0x121281, 0x24c404, 0x080102
};
if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
// Skip modes for missing references
- mode_skip_mask |= ref_frame_mask_all[ref_frame - LAST_FRAME];
+ mode_skip_mask |= ref_frame_mask_all[ref_frame];
} else if (cpi->sf.reference_masking) {
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
// Skip fixed mv modes for poor references
if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
- mode_skip_mask |= ref_frame_mask_fixedmv[ref_frame - LAST_FRAME];
+ mode_skip_mask |= ref_frame_mask_fixedmv[ref_frame];
break;
}
}
}
+ // If the segment reference frame feature is enabled....
+ // then do nothing if the current ref frame is not allowed..
+ if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
+ vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
+ mode_skip_mask |= ref_frame_mask_all[ref_frame];
+ }
+ }
+
+ // If the segment skip feature is enabled....
+ // then do nothing if the current mode is not allowed..
+ if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
+ const int inter_non_zero_mode_mask = 0x1F7F7;
+ mode_skip_mask |= inter_non_zero_mode_mask;
+ }
+
+ // Disable this drop out case if the ref frame
+ // segment level feature is enabled for this segment. This is to
+ // prevent the possibility that we end up unable to pick any mode.
+ if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
+ // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
+ // unless ARNR filtering is enabled in which case we want
+ // an unfiltered alternative. We allow near/nearest as well
+ // because they may result in zero-zero MVs but be cheaper.
+ if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
+ const int altref_zero_mask =
+ ~((1 << THR_NEARESTA) | (1 << THR_NEARA) | (1 << THR_ZEROA));
+ mode_skip_mask |= altref_zero_mask;
+ if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
+ mode_skip_mask |= (1 << THR_NEARA);
+ if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
+ mode_skip_mask |= (1 << THR_NEARESTA);
+ }
+ }
+
+ // 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) {
+ const int new_modes_mask =
+ (1 << THR_NEWMV) | (1 << THR_NEWG) | (1 << THR_NEWA) |
+ (1 << THR_COMP_NEWLA) | (1 << THR_COMP_NEWGA);
+ mode_skip_mask |= new_modes_mask;
}
for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
@@ -3274,11 +3326,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
- // Do not allow compound prediction if the segment level reference
- // frame feature is in use as in this case there can only be one
- // reference.
- if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
- continue;
if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
continue;
@@ -3294,47 +3341,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
mode_excluded : cm->reference_mode == COMPOUND_REFERENCE;
}
- // If the segment reference frame feature is enabled....
- // then do nothing if the current ref frame is not allowed..
- if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
- vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) !=
- (int)ref_frame) {
- continue;
- // If the segment skip feature is enabled....
- // then do nothing if the current mode is not allowed..
- } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) &&
- (this_mode != ZEROMV && ref_frame != INTRA_FRAME)) {
- continue;
- // Disable this drop out case if the ref frame
- // segment level feature is enabled for this segment. This is to
- // prevent the possibility that we end up unable to pick any mode.
- } else if (!vp9_segfeature_active(seg, segment_id,
- SEG_LVL_REF_FRAME)) {
- // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
- // unless ARNR filtering is enabled in which case we want
- // an unfiltered alternative. We allow near/nearest as well
- // because they may result in zero-zero MVs but be cheaper.
- if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
- if ((this_mode != ZEROMV &&
- !(this_mode == NEARMV &&
- frame_mv[NEARMV][ALTREF_FRAME].as_int == 0) &&
- !(this_mode == NEARESTMV &&
- frame_mv[NEARESTMV][ALTREF_FRAME].as_int == 0)) ||
- ref_frame != ALTREF_FRAME) {
- continue;
- }
- }
- }
- // 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 (ref_frame == INTRA_FRAME) {
// Disable intra modes other than DC_PRED for blocks with low variance
// Threshold for intra skipping based on source variance
@@ -3389,8 +3395,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
- super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
- bsize, tx_cache, best_rd);
+ intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
+ bsize, tx_cache, best_rd);
if (rate_y == INT_MAX)
continue;
@@ -4146,7 +4152,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
// then dont bother looking at UV
vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
BLOCK_8X8);
- super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
+ super_block_uvrd(x, &rate_uv, &distortion_uv, &uv_skippable,
&uv_sse, BLOCK_8X8, tmp_best_rdu);
if (rate_uv == INT_MAX)
continue;
diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h
index 96cea4216..6b85d67f8 100644
--- a/vp9/encoder/vp9_rdopt.h
+++ b/vp9/encoder/vp9_rdopt.h
@@ -80,10 +80,10 @@ void vp9_init_me_luts();
void vp9_set_mbmode_and_mvs(MACROBLOCKD *xd, MB_PREDICTION_MODE mode,
const MV *mv);
-void vp9_get_entropy_contexts(TX_SIZE tx_size,
- ENTROPY_CONTEXT t_above[16], ENTROPY_CONTEXT t_left[16],
- const ENTROPY_CONTEXT *above, const ENTROPY_CONTEXT *left,
- int num_4x4_w, int num_4x4_h);
+void vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size,
+ const struct macroblockd_plane *pd,
+ ENTROPY_CONTEXT t_above[16],
+ ENTROPY_CONTEXT t_left[16]);
#ifdef __cplusplus
} // extern "C"
diff --git a/vp9/encoder/vp9_resize.c b/vp9/encoder/vp9_resize.c
index 0766b5107..4e6efaeb9 100644
--- a/vp9/encoder/vp9_resize.c
+++ b/vp9/encoder/vp9_resize.c
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include "vp9/common/vp9_common.h"
#include "vp9/encoder/vp9_resize.h"
@@ -24,9 +25,6 @@
#define SUBPEL_MASK ((1 << SUBPEL_BITS) - 1)
#define INTERP_PRECISION_BITS 32
-#define ROUND_POWER_OF_TWO(value, n) \
- (((value) + (1 << ((n) - 1))) >> (n))
-
typedef int16_t interp_kernel[INTERP_TAPS];
// Filters for interpolation (0.5-band) - note this also filters integer pels.
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index 004047773..502e4b678 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -20,7 +20,6 @@
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_onyx_int.h"
-#include "vp9/encoder/vp9_psnr.h"
#include "vp9/encoder/vp9_quantize.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_segmentation.h"
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index 2be00ff62..7ae110707 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -23,8 +23,8 @@
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
const TOKENVALUE *vp9_dct_value_tokens_ptr;
-static int dct_value_cost[DCT_MAX_VALUE * 2];
-const int *vp9_dct_value_cost_ptr;
+static int16_t dct_value_cost[DCT_MAX_VALUE * 2];
+const int16_t *vp9_dct_value_cost_ptr;
// Array indices are identical to previously-existing CONTEXT_NODE indices
const vp9_tree_index vp9_coef_tree[TREE_SIZE(ENTROPY_TOKENS)] = {
diff --git a/vp9/encoder/vp9_tokenize.h b/vp9/encoder/vp9_tokenize.h
index ea86240be..063c0bafe 100644
--- a/vp9/encoder/vp9_tokenize.h
+++ b/vp9/encoder/vp9_tokenize.h
@@ -47,7 +47,7 @@ struct VP9_COMP;
void vp9_tokenize_sb(struct VP9_COMP *cpi, TOKENEXTRA **t, int dry_run,
BLOCK_SIZE bsize);
-extern const int *vp9_dct_value_cost_ptr;
+extern const int16_t *vp9_dct_value_cost_ptr;
/* TODO: The Token field should be broken out into a separate char array to
* improve cache locality, since it's needed for costing when the rest of the
* fields are not.
diff --git a/vp9/vp9_common.mk b/vp9/vp9_common.mk
index a448b3c52..9fb611504 100644
--- a/vp9/vp9_common.mk
+++ b/vp9/vp9_common.mk
@@ -25,7 +25,6 @@ VP9_COMMON_SRCS-yes += common/vp9_filter.c
VP9_COMMON_SRCS-yes += common/vp9_filter.h
VP9_COMMON_SRCS-yes += common/vp9_frame_buffers.c
VP9_COMMON_SRCS-yes += common/vp9_frame_buffers.h
-VP9_COMMON_SRCS-yes += common/generic/vp9_systemdependent.c
VP9_COMMON_SRCS-yes += common/vp9_idct.c
VP9_COMMON_SRCS-yes += common/vp9_alloccommon.h
VP9_COMMON_SRCS-yes += common/vp9_blockd.h
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index a4162e942..d7713fd3f 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -355,6 +355,13 @@ static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf,
oxcf->ss_number_layers = cfg.ss_number_layers;
+ if (oxcf->ss_number_layers > 1) {
+ memcpy(oxcf->ss_target_bitrate, cfg.ss_target_bitrate,
+ sizeof(cfg.ss_target_bitrate));
+ } else if (oxcf->ss_number_layers == 1) {
+ oxcf->ss_target_bitrate[0] = oxcf->target_bandwidth;
+ }
+
oxcf->ts_number_layers = cfg.ts_number_layers;
if (oxcf->ts_number_layers > 1) {
@@ -1160,6 +1167,7 @@ static vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map[] = {
9999, /* kf_max_dist */
VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
+ {0}, /* ss_target_bitrate */
1, /* ts_number_layers */
{0}, /* ts_target_bitrate */
{0}, /* ts_rate_decimator */
diff --git a/vp9/vp9cx.mk b/vp9/vp9cx.mk
index 27dd6f625..6679f89be 100644
--- a/vp9/vp9cx.mk
+++ b/vp9/vp9cx.mk
@@ -38,7 +38,6 @@ VP9_CX_SRCS-yes += encoder/vp9_lookahead.c
VP9_CX_SRCS-yes += encoder/vp9_lookahead.h
VP9_CX_SRCS-yes += encoder/vp9_mcomp.h
VP9_CX_SRCS-yes += encoder/vp9_onyx_int.h
-VP9_CX_SRCS-yes += encoder/vp9_psnr.h
VP9_CX_SRCS-yes += encoder/vp9_quantize.h
VP9_CX_SRCS-yes += encoder/vp9_ratectrl.h
VP9_CX_SRCS-yes += encoder/vp9_rdopt.h
@@ -50,7 +49,6 @@ VP9_CX_SRCS-yes += encoder/vp9_mcomp.c
VP9_CX_SRCS-yes += encoder/vp9_onyx_if.c
VP9_CX_SRCS-yes += encoder/vp9_picklpf.c
VP9_CX_SRCS-yes += encoder/vp9_picklpf.h
-VP9_CX_SRCS-yes += encoder/vp9_psnr.c
VP9_CX_SRCS-yes += encoder/vp9_quantize.c
VP9_CX_SRCS-yes += encoder/vp9_ratectrl.c
VP9_CX_SRCS-yes += encoder/vp9_rdopt.c