Merge "vp8cx.h: vpx/vpx_encoder.h -> ./vpx_encoder.h"
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index e209788..20cf686 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -83,8 +83,7 @@
}
}
-void vp9_free_ref_frame_buffers(VP9_COMMON *cm) {
- BufferPool *const pool = cm->buffer_pool;
+void vp9_free_ref_frame_buffers(BufferPool *pool) {
int i;
for (i = 0; i < FRAME_BUFFERS; ++i) {
@@ -97,10 +96,14 @@
pool->frame_bufs[i].mvs = NULL;
vp9_free_frame_buffer(&pool->frame_bufs[i].buf);
}
+}
+void vp9_free_postproc_buffers(VP9_COMMON *cm) {
#if CONFIG_VP9_POSTPROC
vp9_free_frame_buffer(&cm->post_proc_buffer);
vp9_free_frame_buffer(&cm->post_proc_buffer_int);
+#else
+ (void)cm;
#endif
}
@@ -142,7 +145,6 @@
}
void vp9_remove_common(VP9_COMMON *cm) {
- vp9_free_ref_frame_buffers(cm);
vp9_free_context_buffers(cm);
vpx_free(cm->fc);
diff --git a/vp9/common/vp9_alloccommon.h b/vp9/common/vp9_alloccommon.h
index d82397f..c0e51a6 100644
--- a/vp9/common/vp9_alloccommon.h
+++ b/vp9/common/vp9_alloccommon.h
@@ -19,6 +19,7 @@
#endif
struct VP9Common;
+struct BufferPool;
void vp9_remove_common(struct VP9Common *cm);
@@ -26,7 +27,8 @@
void vp9_init_context_buffers(struct VP9Common *cm);
void vp9_free_context_buffers(struct VP9Common *cm);
-void vp9_free_ref_frame_buffers(struct VP9Common *cm);
+void vp9_free_ref_frame_buffers(struct BufferPool *pool);
+void vp9_free_postproc_buffers(struct VP9Common *cm);
int vp9_alloc_state_buffers(struct VP9Common *cm, int width, int height);
void vp9_free_state_buffers(struct VP9Common *cm);
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 7ca24a5..62e4ee7 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -88,7 +88,7 @@
int col;
} RefCntBuffer;
-typedef struct {
+typedef struct BufferPool {
// Protect BufferPool from being accessed by several FrameWorkers at
// the same time during frame parallel decode.
// TODO(hkuang): Try to use atomic variable instead of locking the whole pool.
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index 1668b99..f832a3b 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -30,6 +30,25 @@
ADST_ADST, // TM
};
+enum {
+ NEED_LEFT = 1 << 1,
+ NEED_ABOVE = 1 << 2,
+ NEED_ABOVERIGHT = 1 << 3,
+};
+
+static const uint8_t extend_modes[INTRA_MODES] = {
+ NEED_ABOVE | NEED_LEFT, // DC
+ NEED_ABOVE, // V
+ NEED_LEFT, // H
+ NEED_ABOVERIGHT, // D45
+ NEED_LEFT | NEED_ABOVE, // D135
+ NEED_LEFT | NEED_ABOVE, // D117
+ NEED_LEFT | NEED_ABOVE, // D153
+ NEED_LEFT, // D207
+ NEED_ABOVERIGHT, // D63
+ NEED_LEFT | NEED_ABOVE, // TM
+};
+
// This serves as a wrapper function, so that all the prediction functions
// can be unified and accessed as a pointer array. Note that the boundary
// above and left are not necessarily used all the time.
@@ -790,75 +809,106 @@
x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
- vpx_memset(left_col, 129, 64);
-
- // left
- if (left_available) {
- if (xd->mb_to_bottom_edge < 0) {
- /* slower path if the block needs border extension */
- if (y0 + bs <= frame_height) {
+ // NEED_LEFT
+ if (extend_modes[mode] & NEED_LEFT) {
+ if (left_available) {
+ if (xd->mb_to_bottom_edge < 0) {
+ /* slower path if the block needs border extension */
+ if (y0 + bs <= frame_height) {
+ for (i = 0; i < bs; ++i)
+ left_col[i] = ref[i * ref_stride - 1];
+ } else {
+ const int extend_bottom = frame_height - y0;
+ for (i = 0; i < extend_bottom; ++i)
+ left_col[i] = ref[i * ref_stride - 1];
+ for (; i < bs; ++i)
+ left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
+ }
+ } else {
+ /* faster path if the block does not need extension */
for (i = 0; i < bs; ++i)
left_col[i] = ref[i * ref_stride - 1];
- } else {
- const int extend_bottom = frame_height - y0;
- for (i = 0; i < extend_bottom; ++i)
- left_col[i] = ref[i * ref_stride - 1];
- for (; i < bs; ++i)
- left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
}
} else {
- /* faster path if the block does not need extension */
- for (i = 0; i < bs; ++i)
- left_col[i] = ref[i * ref_stride - 1];
+ vpx_memset(left_col, 129, bs);
}
}
- // TODO(hkuang) do not extend 2*bs pixels for all modes.
- // above
- if (up_available) {
- const uint8_t *above_ref = ref - ref_stride;
- if (xd->mb_to_right_edge < 0) {
- /* slower path if the block needs border extension */
- if (x0 + 2 * bs <= frame_width) {
- if (right_available && bs == 4) {
- vpx_memcpy(above_row, above_ref, 2 * bs);
- } else {
+ // NEED_ABOVE
+ if (extend_modes[mode] & NEED_ABOVE) {
+ if (up_available) {
+ const uint8_t *above_ref = ref - ref_stride;
+ if (xd->mb_to_right_edge < 0) {
+ /* slower path if the block needs border extension */
+ if (x0 + bs <= frame_width) {
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) {
+ } else if (x0 <= frame_width) {
+ const int r = frame_width - x0;
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
- x0 + 2 * bs - frame_width);
+ x0 + bs - frame_width);
+ }
+ } else {
+ /* faster path if the block does not need extension */
+ if (bs == 4 && right_available && left_available) {
+ const_above_row = above_ref;
} else {
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;
- 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;
} else {
- /* faster path if the block does not need extension */
- if (bs == 4 && right_available && left_available) {
- const_above_row = above_ref;
- } else {
- vpx_memcpy(above_row, above_ref, bs);
- if (bs == 4 && right_available)
- vpx_memcpy(above_row + bs, above_ref + bs, bs);
- else
- vpx_memset(above_row + bs, above_row[bs - 1], bs);
- above_row[-1] = left_available ? above_ref[-1] : 129;
- }
+ vpx_memset(above_row, 127, bs);
+ above_row[-1] = 127;
}
- } else {
- vpx_memset(above_row, 127, bs * 2);
- above_row[-1] = 127;
+ }
+
+ // NEED_ABOVERIGHT
+ if (extend_modes[mode] & NEED_ABOVERIGHT) {
+ if (up_available) {
+ const uint8_t *above_ref = ref - ref_stride;
+ if (xd->mb_to_right_edge < 0) {
+ /* slower path if the block needs border extension */
+ if (x0 + 2 * bs <= frame_width) {
+ if (right_available && bs == 4) {
+ vpx_memcpy(above_row, above_ref, 2 * bs);
+ } else {
+ 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, above_ref, r);
+ vpx_memset(above_row + r, above_row[r - 1],
+ x0 + 2 * bs - frame_width);
+ } else {
+ 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;
+ vpx_memcpy(above_row, above_ref, r);
+ vpx_memset(above_row + r, above_row[r - 1],
+ x0 + 2 * bs - frame_width);
+ }
+ } else {
+ /* faster path if the block does not need extension */
+ if (bs == 4 && right_available && left_available) {
+ const_above_row = above_ref;
+ } else {
+ vpx_memcpy(above_row, above_ref, bs);
+ if (bs == 4 && right_available)
+ vpx_memcpy(above_row + bs, above_ref + bs, bs);
+ else
+ vpx_memset(above_row + bs, above_row[bs - 1], bs);
+ }
+ }
+ above_row[-1] = left_available ? above_ref[-1] : 129;
+ } else {
+ vpx_memset(above_row, 127, bs * 2);
+ above_row[-1] = 127;
+ }
}
// predict
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 273fcf5..fc05811 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -314,7 +314,10 @@
vpx_free(cpi->active_map.map);
cpi->active_map.map = NULL;
- vp9_free_ref_frame_buffers(cm);
+ vp9_free_ref_frame_buffers(cm->buffer_pool);
+#if CONFIG_VP9_POSTPROC
+ vp9_free_postproc_buffers(cm);
+#endif
vp9_free_context_buffers(cm);
vp9_free_frame_buffer(&cpi->last_frame_uf);
@@ -1919,6 +1922,10 @@
#endif
vp9_remove_common(cm);
+ vp9_free_ref_frame_buffers(cm->buffer_pool);
+#if CONFIG_VP9_POSTPROC
+ vp9_free_postproc_buffers(cm);
+#endif
vpx_free(cpi);
#if CONFIG_VP9_TEMPORAL_DENOISING
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index 9e4c1a5..7350cb3 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -116,6 +116,9 @@
(FrameWorkerData *)worker->data1;
vp9_get_worker_interface()->end(worker);
vp9_remove_common(&frame_worker_data->pbi->common);
+#if CONFIG_VP9_POSTPROC
+ vp9_free_postproc_buffers(&frame_worker_data->pbi->common);
+#endif
vp9_decoder_remove(frame_worker_data->pbi);
vpx_free(frame_worker_data->scratch_buffer);
#if CONFIG_MULTITHREAD
@@ -129,8 +132,10 @@
#endif
}
- if (ctx->buffer_pool)
+ if (ctx->buffer_pool) {
+ vp9_free_ref_frame_buffers(ctx->buffer_pool);
vp9_free_internal_frame_buffers(&ctx->buffer_pool->int_frame_buffers);
+ }
vpx_free(ctx->frame_workers);
vpx_free(ctx->buffer_pool);