summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/common/vp9_alloccommon.c57
-rw-r--r--vp9/common/vp9_alloccommon.h2
-rw-r--r--vp9/common/vp9_entropymode.c3
-rw-r--r--vp9/common/vp9_onyxc_int.h13
-rw-r--r--vp9/decoder/vp9_decodemv.c6
-rw-r--r--vp9/decoder/vp9_decoder.c2
6 files changed, 69 insertions, 14 deletions
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index f847e1276..04081f107 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -55,7 +55,7 @@ static void setup_mi(VP9_COMMON *cm) {
static int alloc_mi(VP9_COMMON *cm, int mi_size) {
int i;
- for (i = 0; i < 2; ++i) {
+ for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) {
cm->mip_array[i] =
(MODE_INFO *)vpx_calloc(mi_size, sizeof(*cm->mip));
if (cm->mip_array[i] == NULL)
@@ -82,7 +82,7 @@ static int alloc_mi(VP9_COMMON *cm, int mi_size) {
static void free_mi(VP9_COMMON *cm) {
int i;
- for (i = 0; i < 2; ++i) {
+ for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) {
vpx_free(cm->mip_array[i]);
cm->mip_array[i] = NULL;
vpx_free(cm->mi_grid_base_array[i]);
@@ -95,6 +95,37 @@ static void free_mi(VP9_COMMON *cm) {
cm->prev_mi_grid_base = NULL;
}
+static int alloc_seg_map(VP9_COMMON *cm, int seg_map_size) {
+ int i;
+
+ for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) {
+ cm->seg_map_array[i] = (uint8_t *)vpx_calloc(seg_map_size, 1);
+ if (cm->seg_map_array[i] == NULL)
+ return 1;
+ }
+
+ // Init the index.
+ cm->seg_map_idx = 0;
+ cm->prev_seg_map_idx = 1;
+
+ cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx];
+ cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx];
+
+ return 0;
+}
+
+static void free_seg_map(VP9_COMMON *cm) {
+ int i;
+
+ for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) {
+ vpx_free(cm->seg_map_array[i]);
+ cm->seg_map_array[i] = NULL;
+ }
+
+ cm->current_frame_seg_map = NULL;
+ cm->last_frame_seg_map = NULL;
+}
+
void vp9_free_frame_buffers(VP9_COMMON *cm) {
int i;
BufferPool *const pool = cm->buffer_pool;
@@ -115,8 +146,7 @@ void vp9_free_frame_buffers(VP9_COMMON *cm) {
void vp9_free_context_buffers(VP9_COMMON *cm) {
free_mi(cm);
- vpx_free(cm->last_frame_seg_map);
- cm->last_frame_seg_map = NULL;
+ free_seg_map(cm);
vpx_free(cm->above_context);
cm->above_context = NULL;
@@ -147,9 +177,8 @@ int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) {
setup_mi(cm);
// Create the segmentation map structure and set to 0.
- vpx_free(cm->last_frame_seg_map);
- cm->last_frame_seg_map = (uint8_t *)vpx_calloc(cm->mi_rows * cm->mi_cols, 1);
- if (!cm->last_frame_seg_map)
+ free_seg_map(cm);
+ if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols))
goto fail;
vpx_free(cm->above_context);
@@ -270,8 +299,8 @@ void vp9_update_frame_size(VP9_COMMON *cm) {
setup_mi(cm);
// Initialize the previous frame segment map to 0.
- if (cm->last_frame_seg_map)
- vpx_memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols);
+ if (cm->current_frame_seg_map)
+ vpx_memset(cm->current_frame_seg_map, 0, cm->mi_rows * cm->mi_cols);
}
void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) {
@@ -292,3 +321,13 @@ void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) {
cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
}
+
+void vp9_swap_current_and_last_seg_map(VP9_COMMON *cm) {
+ // Swap indices.
+ const int tmp = cm->seg_map_idx;
+ cm->seg_map_idx = cm->prev_seg_map_idx;
+ cm->prev_seg_map_idx = tmp;
+
+ cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx];
+ cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx];
+}
diff --git a/vp9/common/vp9_alloccommon.h b/vp9/common/vp9_alloccommon.h
index c4b1b8d2d..1207d6e24 100644
--- a/vp9/common/vp9_alloccommon.h
+++ b/vp9/common/vp9_alloccommon.h
@@ -34,6 +34,8 @@ void vp9_update_frame_size(struct VP9Common *cm);
void vp9_swap_mi_and_prev_mi(struct VP9Common *cm);
+void vp9_swap_current_and_last_seg_map(struct VP9Common *cm);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 5b00b0082..79c8b9bc5 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -442,6 +442,9 @@ void vp9_setup_past_independence(VP9_COMMON *cm) {
if (cm->last_frame_seg_map)
vpx_memset(cm->last_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols));
+ if (cm->current_frame_seg_map)
+ vpx_memset(cm->current_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols));
+
// Reset the mode ref deltas for loop filter
vp9_zero(lf->last_ref_deltas);
vp9_zero(lf->last_mode_deltas);
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index f31e137b0..13c500147 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -44,6 +44,8 @@ extern "C" {
#define FRAME_CONTEXTS_LOG2 2
#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
+#define NUM_PING_PONG_BUFFERS 2
+
extern const struct {
PARTITION_CONTEXT above;
PARTITION_CONTEXT left;
@@ -163,8 +165,8 @@ typedef struct VP9Common {
int mi_idx;
int prev_mi_idx;
- MODE_INFO *mip_array[2];
- MODE_INFO **mi_grid_base_array[2];
+ MODE_INFO *mip_array[NUM_PING_PONG_BUFFERS];
+ MODE_INFO **mi_grid_base_array[NUM_PING_PONG_BUFFERS];
MODE_INFO *mip; /* Base of allocated array */
MODE_INFO *mi; /* Corresponds to upper left visible macroblock */
@@ -177,7 +179,12 @@ typedef struct VP9Common {
MODE_INFO **prev_mi_grid_visible;
// Persistent mb segment id map used in prediction.
- unsigned char *last_frame_seg_map;
+ int seg_map_idx;
+ int prev_seg_map_idx;
+
+ uint8_t *seg_map_array[NUM_PING_PONG_BUFFERS];
+ uint8_t *last_frame_seg_map;
+ uint8_t *current_frame_seg_map;
INTERP_FILTER interp_filter;
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 1afaee1e3..187ff1307 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -96,7 +96,7 @@ static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE bsize,
for (y = 0; y < ymis; y++)
for (x = 0; x < xmis; x++)
- cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
+ cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}
static int read_intra_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
@@ -129,8 +129,10 @@ static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
predicted_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
bsize, mi_row, mi_col);
- if (!seg->update_map)
+ if (!seg->update_map) {
+ set_segment_id(cm, bsize, mi_row, mi_col, predicted_segment_id);
return predicted_segment_id;
+ }
if (seg->temporal_update) {
const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c
index 75283ab93..07fe2899d 100644
--- a/vp9/decoder/vp9_decoder.c
+++ b/vp9/decoder/vp9_decoder.c
@@ -295,6 +295,8 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
cm->current_video_frame++;
}
+ vp9_swap_current_and_last_seg_map(cm);
+
pbi->ready_for_new_data = 0;
cm->error.setjmp = 0;