summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/common/vp9_blockd.h7
-rw-r--r--vp9/common/vp9_loopfilter.h2
-rw-r--r--vp9/common/vp9_onyx.h8
-rw-r--r--vp9/decoder/vp9_decodemv.c18
-rw-r--r--vp9/decoder/vp9_decodframe.c2
-rw-r--r--vp9/encoder/vp9_bitstream.c35
-rw-r--r--vp9/encoder/vp9_encodeframe.c2
-rw-r--r--vp9/encoder/vp9_onyx_if.c29
-rw-r--r--vp9/encoder/vp9_segmentation.c120
-rw-r--r--vpx/vp8cx.h10
10 files changed, 121 insertions, 112 deletions
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 5b89aff88..6b4f607b1 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -23,7 +23,8 @@
// #define MODE_STATS
-#define MB_FEATURE_TREE_PROBS 3
+#define MAX_MB_SEGMENTS 8
+#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1)
#define PREDICTION_PROBS 3
#define DEFAULT_PRED_PROB_0 120
@@ -32,8 +33,6 @@
#define MBSKIP_CONTEXTS 3
-#define MAX_MB_SEGMENTS 4
-
#define MAX_REF_LF_DELTAS 4
#define MAX_MODE_LF_DELTAS 4
@@ -398,7 +397,7 @@ typedef struct macroblockd {
/* are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO */
// Probability Tree used to code Segment number
- vp9_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
+ vp9_prob mb_segment_tree_probs[MB_SEG_TREE_PROBS];
// Segment features
signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
diff --git a/vp9/common/vp9_loopfilter.h b/vp9/common/vp9_loopfilter.h
index 3b81146e2..81745e48a 100644
--- a/vp9/common/vp9_loopfilter.h
+++ b/vp9/common/vp9_loopfilter.h
@@ -36,7 +36,7 @@ typedef struct {
lim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]);
DECLARE_ALIGNED(SIMD_WIDTH, unsigned char,
hev_thr[4][SIMD_WIDTH]);
- unsigned char lvl[4][4][4];
+ unsigned char lvl[MAX_MB_SEGMENTS][4][4];
unsigned char mode_lf_lut[MB_MODE_COUNT];
} loop_filter_info_n;
diff --git a/vp9/common/vp9_onyx.h b/vp9/common/vp9_onyx.h
index 422f3885f..b85b88968 100644
--- a/vp9/common/vp9_onyx.h
+++ b/vp9/common/vp9_onyx.h
@@ -21,6 +21,9 @@ extern "C"
#include "vpx/vp8cx.h"
#include "vpx_scale/yv12config.h"
#include "vp9/common/vp9_ppflags.h"
+
+#define MAX_MB_SEGMENTS 8
+
typedef int *VP9_PTR;
/* Create/destroy static data structures. */
@@ -225,8 +228,9 @@ extern "C"
int vp9_set_roimap(VP9_PTR comp, unsigned char *map,
unsigned int rows, unsigned int cols,
- int delta_q[4], int delta_lf[4],
- unsigned int threshold[4]);
+ int delta_q[MAX_MB_SEGMENTS],
+ int delta_lf[MAX_MB_SEGMENTS],
+ unsigned int threshold[MAX_MB_SEGMENTS]);
int vp9_set_active_map(VP9_PTR comp, unsigned char *map,
unsigned int rows, unsigned int cols);
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 801e41a43..5352a0839 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -75,8 +75,22 @@ static MB_PREDICTION_MODE read_uv_mode(vp9_reader *r, const vp9_prob *p) {
static int read_mb_segid(vp9_reader *r, MACROBLOCKD *xd) {
const vp9_prob *const p = xd->mb_segment_tree_probs;
- return vp9_read(r, p[0]) ? 2 + vp9_read(r, p[2])
- : vp9_read(r, p[1]);
+ int ret_val;
+
+ if (vp9_read(r, p[0])) {
+ if (vp9_read(r, p[4])) {
+ ret_val = 6 + vp9_read(r, p[6]);
+ } else {
+ ret_val = 4 + vp9_read(r, p[5]);
+ }
+ } else {
+ if (vp9_read(r, p[1])) {
+ ret_val = 2 + vp9_read(r, p[3]);
+ } else {
+ ret_val = vp9_read(r, p[2]);
+ }
+ }
+ return ret_val;
}
static void set_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi,
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 2bd200ef7..864eb82fd 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1107,7 +1107,7 @@ static void setup_segmentation(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_reader *r) {
xd->allow_implicit_segment_update = vp9_read_bit(r);
#endif
if (xd->update_mb_segmentation_map) {
- for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+ 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;
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 33db0de7d..e80c9ccb7 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -537,24 +537,49 @@ static void write_mb_segid(vp9_writer *bc,
case 0:
vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
vp9_write(bc, 0, xd->mb_segment_tree_probs[1]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[2]);
break;
case 1:
vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
- vp9_write(bc, 1, xd->mb_segment_tree_probs[1]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[1]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[2]);
break;
case 2:
- vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
- vp9_write(bc, 0, xd->mb_segment_tree_probs[2]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[1]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[3]);
break;
case 3:
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[1]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[3]);
+ break;
+ case 4:
vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
- vp9_write(bc, 1, xd->mb_segment_tree_probs[2]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[4]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[5]);
+ break;
+ case 5:
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[4]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[5]);
+ break;
+ case 6:
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[4]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[6]);
+ break;
+ case 7:
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[0]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[4]);
+ vp9_write(bc, 1, xd->mb_segment_tree_probs[6]);
break;
// TRAP.. This should not happen
default:
vp9_write(bc, 0, xd->mb_segment_tree_probs[0]);
vp9_write(bc, 0, xd->mb_segment_tree_probs[1]);
+ vp9_write(bc, 0, xd->mb_segment_tree_probs[2]);
break;
}
}
@@ -1977,7 +2002,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
vp9_choose_segmap_coding_method(cpi);
// Send the tree probabilities used to decode unpredicted
// macro-block segments
- for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) {
+ for (i = 0; i < MB_SEG_TREE_PROBS; i++) {
const int prob = xd->mb_segment_tree_probs[i];
if (prob != 255) {
vp9_write_bit(&header_bc, 1);
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 0837931e5..b1b28c785 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -594,7 +594,7 @@ static void set_offsets(VP9_COMP *cpi,
mbmi->segment_id = find_seg_id(cm->last_frame_seg_map, bsize,
mb_row, cm->mb_rows, mb_col, cm->mb_cols);
}
- assert(mbmi->segment_id <= 3);
+ assert(mbmi->segment_id <= (MAX_MB_SEGMENTS-1));
vp9_mb_init_quantizer(cpi, x);
if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 03a8388ef..c2c587e10 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -4204,8 +4204,9 @@ int vp9_get_preview_raw_frame(VP9_PTR comp, YV12_BUFFER_CONFIG *dest,
}
int vp9_set_roimap(VP9_PTR comp, unsigned char *map, unsigned int rows,
- unsigned int cols, int delta_q[4], int delta_lf[4],
- unsigned int threshold[4]) {
+ unsigned int cols, int delta_q[MAX_MB_SEGMENTS],
+ int delta_lf[MAX_MB_SEGMENTS],
+ unsigned int threshold[MAX_MB_SEGMENTS]) {
VP9_COMP *cpi = (VP9_COMP *) comp;
signed char feature_data[SEG_LVL_MAX][MAX_MB_SEGMENTS];
MACROBLOCKD *xd = &cpi->mb.e_mbd;
@@ -4225,25 +4226,15 @@ int vp9_set_roimap(VP9_PTR comp, unsigned char *map, unsigned int rows,
// Activate segmentation.
vp9_enable_segmentation((VP9_PTR)cpi);
- // Set up the quant segment data
- feature_data[SEG_LVL_ALT_Q][0] = delta_q[0];
- feature_data[SEG_LVL_ALT_Q][1] = delta_q[1];
- feature_data[SEG_LVL_ALT_Q][2] = delta_q[2];
- feature_data[SEG_LVL_ALT_Q][3] = delta_q[3];
-
- // Set up the loop segment data s
- feature_data[SEG_LVL_ALT_LF][0] = delta_lf[0];
- feature_data[SEG_LVL_ALT_LF][1] = delta_lf[1];
- feature_data[SEG_LVL_ALT_LF][2] = delta_lf[2];
- feature_data[SEG_LVL_ALT_LF][3] = delta_lf[3];
-
- cpi->segment_encode_breakout[0] = threshold[0];
- cpi->segment_encode_breakout[1] = threshold[1];
- cpi->segment_encode_breakout[2] = threshold[2];
- cpi->segment_encode_breakout[3] = threshold[3];
+ // Set up the quan, LF and breakout threshold segment data
+ for (i = 0; i < MAX_MB_SEGMENTS; i++) {
+ feature_data[SEG_LVL_ALT_Q][i] = delta_q[i];
+ feature_data[SEG_LVL_ALT_LF][i] = delta_lf[i];
+ cpi->segment_encode_breakout[i] = threshold[i];
+ }
// Enable the loop and quant changes in the feature mask
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < MAX_MB_SEGMENTS; i++) {
if (delta_q[i])
vp9_enable_segfeature(xd, i, SEG_LVL_ALT_Q);
else
diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c
index 1d3e8529d..56484e693 100644
--- a/vp9/encoder/vp9_segmentation.c
+++ b/vp9/encoder/vp9_segmentation.c
@@ -63,16 +63,18 @@ void vp9_set_segment_data(VP9_PTR ptr,
static void calc_segtree_probs(MACROBLOCKD *xd,
int *segcounts,
vp9_prob *segment_tree_probs) {
- int count1, count2;
-
- // Total count for all segments
- count1 = segcounts[0] + segcounts[1];
- count2 = segcounts[2] + segcounts[3];
-
// Work out probabilities of each segment
- segment_tree_probs[0] = get_binary_prob(count1, count2);
- segment_tree_probs[1] = get_prob(segcounts[0], count1);
- segment_tree_probs[2] = get_prob(segcounts[2], count2);
+ segment_tree_probs[0] =
+ get_binary_prob(segcounts[0] + segcounts[1] + segcounts[2] + segcounts[3],
+ segcounts[4] + segcounts[5] + segcounts[6] + segcounts[7]);
+ segment_tree_probs[1] =
+ get_binary_prob(segcounts[0] + segcounts[1], segcounts[2] + segcounts[3]);
+ segment_tree_probs[2] = get_binary_prob(segcounts[0], segcounts[1]);
+ segment_tree_probs[3] = get_binary_prob(segcounts[2], segcounts[3]);
+ segment_tree_probs[4] =
+ get_binary_prob(segcounts[4] + segcounts[5], segcounts[6] + segcounts[7]);
+ segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]);
+ segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]);
}
// Based on set of segment counts and probabilities calculate a cost estimate
@@ -83,68 +85,38 @@ static int cost_segmap(MACROBLOCKD *xd,
int count1, count2;
// Cost the top node of the tree
- count1 = segcounts[0] + segcounts[1];
- count2 = segcounts[2] + segcounts[3];
+ count1 = segcounts[0] + segcounts[1] + segcounts[2] + segcounts[3];
+ count2 = segcounts[3] + segcounts[4] + segcounts[5] + segcounts[6];
cost = count1 * vp9_cost_zero(probs[0]) +
count2 * vp9_cost_one(probs[0]);
- // Now add the cost of each individual segment branch
- if (count1 > 0)
- cost += segcounts[0] * vp9_cost_zero(probs[1]) +
- segcounts[1] * vp9_cost_one(probs[1]);
-
- if (count2 > 0)
- cost += segcounts[2] * vp9_cost_zero(probs[2]) +
- segcounts[3] * vp9_cost_one(probs[2]);
-
- return cost;
-}
-
-// Based on set of segment counts calculate a probability tree
-static void calc_segtree_probs_pred(MACROBLOCKD *xd,
- int (*segcounts)[MAX_MB_SEGMENTS],
- vp9_prob *segment_tree_probs) {
- int count[4];
-
- assert(!segcounts[0][0] && !segcounts[1][1] &&
- !segcounts[2][2] && !segcounts[3][3]);
-
- // Total count for all segments
- count[0] = segcounts[3][0] + segcounts[1][0] + segcounts[2][0];
- count[1] = segcounts[2][1] + segcounts[0][1] + segcounts[3][1];
- count[2] = segcounts[0][2] + segcounts[3][2] + segcounts[1][2];
- count[3] = segcounts[1][3] + segcounts[2][3] + segcounts[0][3];
-
- // Work out probabilities of each segment
- segment_tree_probs[0] = get_binary_prob(count[0] + count[1],
- count[2] + count[3]);
- segment_tree_probs[1] = get_binary_prob(count[0], count[1]);
- segment_tree_probs[2] = get_binary_prob(count[2], count[3]);
-}
+ // Cost subsequent levels
+ if (count1 > 0) {
+ count1 = segcounts[0] + segcounts[1];
+ count2 = segcounts[2] + segcounts[3];
+ cost += count1 * vp9_cost_zero(probs[1]) +
+ count2 * vp9_cost_one(probs[1]);
+
+ if (count1 > 0)
+ cost += segcounts[0] * vp9_cost_zero(probs[2]) +
+ segcounts[1] * vp9_cost_one(probs[2]);
+ if (count2 > 0)
+ cost += segcounts[2] * vp9_cost_zero(probs[3]) +
+ segcounts[3] * vp9_cost_one(probs[3]);
+ }
-// Based on set of segment counts and probabilities calculate a cost estimate
-static int cost_segmap_pred(MACROBLOCKD *xd,
- int (*segcounts)[MAX_MB_SEGMENTS],
- vp9_prob *probs) {
- int pred_seg, cost = 0;
-
- for (pred_seg = 0; pred_seg < MAX_MB_SEGMENTS; pred_seg++) {
- int count1, count2;
-
- // Cost the top node of the tree
- count1 = segcounts[pred_seg][0] + segcounts[pred_seg][1];
- count2 = segcounts[pred_seg][2] + segcounts[pred_seg][3];
- cost += count1 * vp9_cost_zero(probs[0]) +
- count2 * vp9_cost_one(probs[0]);
-
- // Now add the cost of each individual segment branch
- if (pred_seg >= 2 && count1) {
- cost += segcounts[pred_seg][0] * vp9_cost_zero(probs[1]) +
- segcounts[pred_seg][1] * vp9_cost_one(probs[1]);
- } else if (pred_seg < 2 && count2 > 0) {
- cost += segcounts[pred_seg][2] * vp9_cost_zero(probs[2]) +
- segcounts[pred_seg][3] * vp9_cost_one(probs[2]);
- }
+ if (count2 > 0) {
+ count1 = segcounts[4] + segcounts[5];
+ count2 = segcounts[6] + segcounts[7];
+ cost += count1 * vp9_cost_zero(probs[4]) +
+ count2 * vp9_cost_one(probs[4]);
+
+ if (count1 > 0)
+ cost += segcounts[4] * vp9_cost_zero(probs[5]) +
+ segcounts[5] * vp9_cost_one(probs[5]);
+ if (count2 > 0)
+ cost += segcounts[6] * vp9_cost_zero(probs[6]) +
+ segcounts[7] * vp9_cost_one(probs[6]);
}
return cost;
@@ -154,7 +126,7 @@ static void count_segs(VP9_COMP *cpi,
MODE_INFO *mi,
int *no_pred_segcounts,
int (*temporal_predictor_count)[2],
- int (*t_unpred_seg_counts)[MAX_MB_SEGMENTS],
+ int *t_unpred_seg_counts,
int bw, int bh, int mb_row, int mb_col) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
@@ -184,7 +156,7 @@ static void count_segs(VP9_COMP *cpi,
if (!seg_predicted)
// Update the "unpredicted" segment count
- t_unpred_seg_counts[pred_seg_id][segment_id]++;
+ t_unpred_seg_counts[segment_id]++;
}
}
@@ -200,10 +172,10 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
int temporal_predictor_count[PREDICTION_PROBS][2];
int no_pred_segcounts[MAX_MB_SEGMENTS];
- int t_unpred_seg_counts[MAX_MB_SEGMENTS][MAX_MB_SEGMENTS];
+ int t_unpred_seg_counts[MAX_MB_SEGMENTS];
- vp9_prob no_pred_tree[MB_FEATURE_TREE_PROBS];
- vp9_prob t_pred_tree[MB_FEATURE_TREE_PROBS];
+ vp9_prob no_pred_tree[MB_SEG_TREE_PROBS];
+ vp9_prob t_pred_tree[MB_SEG_TREE_PROBS];
vp9_prob t_nopred_prob[PREDICTION_PROBS];
const int mis = cm->mode_info_stride;
@@ -318,8 +290,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
if (cm->frame_type != KEY_FRAME) {
// Work out probability tree for coding those segments not
// predicted using the temporal method and the cost.
- calc_segtree_probs_pred(xd, t_unpred_seg_counts, t_pred_tree);
- t_pred_cost = cost_segmap_pred(xd, t_unpred_seg_counts, t_pred_tree);
+ calc_segtree_probs(xd, t_unpred_seg_counts, t_pred_tree);
+ t_pred_cost = cost_segmap(xd, t_unpred_seg_counts, t_pred_tree);
// Add in the cost of the signalling for each prediction context
for (i = 0; i < PREDICTION_PROBS; i++) {
diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h
index 7f19dd033..f8e2ef9c3 100644
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -215,9 +215,13 @@ typedef struct vpx_roi_map {
unsigned char *roi_map; /**< specify an id between 0 and 3 for each 16x16 region within a frame */
unsigned int rows; /**< number of rows */
unsigned int cols; /**< number of cols */
- int delta_q[4]; /**< quantizer delta [-63, 63] off baseline for regions with id between 0 and 3*/
- int delta_lf[4]; /**< loop filter strength delta [-63, 63] for regions with id between 0 and 3 */
- unsigned int static_threshold[4];/**< threshold for region to be treated as static */
+ // TODO(paulwilkins): broken for VP9 which has 8 segments
+ // q and loop filter deltas for each segment
+ // (see MAX_MB_SEGMENTS)
+ int delta_q[4];
+ int delta_lf[4];
+ // Static breakout threshold for each segment
+ unsigned int static_threshold[4];
} vpx_roi_map_t;
/*!\brief vpx active region map