Index: source/libvpx/vpx_scale/generic/yv12extend.c |
=================================================================== |
--- source/libvpx/vpx_scale/generic/yv12extend.c (revision 291857) |
+++ source/libvpx/vpx_scale/generic/yv12extend.c (working copy) |
@@ -13,6 +13,9 @@ |
#include "vpx/vpx_integer.h" |
#include "vpx_mem/vpx_mem.h" |
#include "vpx_scale/yv12config.h" |
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
+#include "vp9/common/vp9_common.h" |
+#endif |
static void extend_plane(uint8_t *const src, int src_stride, |
int width, int height, |
@@ -55,6 +58,50 @@ |
} |
} |
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
+static void extend_plane_high(uint8_t *const src8, int src_stride, |
+ int width, int height, |
+ int extend_top, int extend_left, |
+ int extend_bottom, int extend_right) { |
+ int i; |
+ const int linesize = extend_left + extend_right + width; |
+ uint16_t *src = CONVERT_TO_SHORTPTR(src8); |
+ |
+ /* copy the left and right most columns out */ |
+ uint16_t *src_ptr1 = src; |
+ uint16_t *src_ptr2 = src + width - 1; |
+ uint16_t *dst_ptr1 = src - extend_left; |
+ uint16_t *dst_ptr2 = src + width; |
+ |
+ for (i = 0; i < height; ++i) { |
+ vpx_memset16(dst_ptr1, src_ptr1[0], extend_left); |
+ vpx_memset16(dst_ptr2, src_ptr2[0], extend_right); |
+ src_ptr1 += src_stride; |
+ src_ptr2 += src_stride; |
+ dst_ptr1 += src_stride; |
+ dst_ptr2 += src_stride; |
+ } |
+ |
+ /* Now copy the top and bottom lines into each line of the respective |
+ * borders |
+ */ |
+ src_ptr1 = src - extend_left; |
+ src_ptr2 = src + src_stride * (height - 1) - extend_left; |
+ dst_ptr1 = src + src_stride * -extend_top - extend_left; |
+ dst_ptr2 = src + src_stride * height - extend_left; |
+ |
+ for (i = 0; i < extend_top; ++i) { |
+ vpx_memcpy(dst_ptr1, src_ptr1, linesize * sizeof(uint16_t)); |
+ dst_ptr1 += src_stride; |
+ } |
+ |
+ for (i = 0; i < extend_bottom; ++i) { |
+ vpx_memcpy(dst_ptr2, src_ptr2, linesize * sizeof(uint16_t)); |
+ dst_ptr2 += src_stride; |
+ } |
+} |
+#endif |
+ |
void vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { |
const int uv_border = ybf->border / 2; |
@@ -64,6 +111,31 @@ |
assert(ybf->y_height - ybf->y_crop_height >= 0); |
assert(ybf->y_width - ybf->y_crop_width >= 0); |
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
+ if (ybf->flags & YV12_FLAG_HIGHBITDEPTH) { |
+ extend_plane_high( |
+ ybf->y_buffer, ybf->y_stride, |
+ ybf->y_crop_width, ybf->y_crop_height, |
+ ybf->border, ybf->border, |
+ ybf->border + ybf->y_height - ybf->y_crop_height, |
+ ybf->border + ybf->y_width - ybf->y_crop_width); |
+ |
+ extend_plane_high( |
+ ybf->u_buffer, ybf->uv_stride, |
+ (ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2, |
+ ybf->border / 2, ybf->border / 2, |
+ (ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2, |
+ (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2); |
+ |
+ extend_plane_high( |
+ ybf->v_buffer, ybf->uv_stride, |
+ (ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2, |
+ ybf->border / 2, ybf->border / 2, |
+ (ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2, |
+ (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2); |
+ return; |
+ } |
+#endif |
extend_plane(ybf->y_buffer, ybf->y_stride, |
ybf->y_crop_width, ybf->y_crop_height, |
ybf->border, ybf->border, |
@@ -99,6 +171,20 @@ |
assert(ybf->y_height - ybf->y_crop_height >= 0); |
assert(ybf->y_width - ybf->y_crop_width >= 0); |
+#if CONFIG_VP9_HIGHBITDEPTH |
+ if (ybf->flags & YV12_FLAG_HIGHBITDEPTH) { |
+ extend_plane_high(ybf->y_buffer, ybf->y_stride, |
+ ybf->y_crop_width, ybf->y_crop_height, |
+ ext_size, ext_size, |
+ ext_size + ybf->y_height - ybf->y_crop_height, |
+ ext_size + ybf->y_width - ybf->y_crop_width); |
+ extend_plane_high(ybf->u_buffer, ybf->uv_stride, |
+ c_w, c_h, c_et, c_el, c_eb, c_er); |
+ extend_plane_high(ybf->v_buffer, ybf->uv_stride, |
+ c_w, c_h, c_et, c_el, c_eb, c_er); |
+ return; |
+ } |
+#endif |
extend_plane(ybf->y_buffer, ybf->y_stride, |
ybf->y_crop_width, ybf->y_crop_height, |
ext_size, ext_size, |
@@ -121,6 +207,14 @@ |
VP9INNERBORDERINPIXELS : ybf->border; |
extend_frame(ybf, inner_bw); |
} |
+ |
+#if CONFIG_VP9_HIGHBITDEPTH |
+void memcpy_short_addr(uint8_t *dst8, const uint8_t *src8, int num) { |
+ uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); |
+ uint16_t *src = CONVERT_TO_SHORTPTR(src8); |
+ vpx_memcpy(dst, src, num * sizeof(uint16_t)); |
+} |
+#endif // CONFIG_VP9_HIGHBITDEPTH |
#endif // CONFIG_VP9 |
// Copies the source image into the destination image and updates the |
@@ -140,6 +234,40 @@ |
assert(src_ybc->y_height == dst_ybc->y_height); |
#endif |
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
+ if (src_ybc->flags & YV12_FLAG_HIGHBITDEPTH) { |
+ assert(dst_ybc->flags & YV12_FLAG_HIGHBITDEPTH); |
+ for (row = 0; row < src_ybc->y_height; ++row) { |
+ memcpy_short_addr(dst, src, src_ybc->y_width); |
+ src += src_ybc->y_stride; |
+ dst += dst_ybc->y_stride; |
+ } |
+ |
+ src = src_ybc->u_buffer; |
+ dst = dst_ybc->u_buffer; |
+ |
+ for (row = 0; row < src_ybc->uv_height; ++row) { |
+ memcpy_short_addr(dst, src, src_ybc->uv_width); |
+ src += src_ybc->uv_stride; |
+ dst += dst_ybc->uv_stride; |
+ } |
+ |
+ src = src_ybc->v_buffer; |
+ dst = dst_ybc->v_buffer; |
+ |
+ for (row = 0; row < src_ybc->uv_height; ++row) { |
+ memcpy_short_addr(dst, src, src_ybc->uv_width); |
+ src += src_ybc->uv_stride; |
+ dst += dst_ybc->uv_stride; |
+ } |
+ |
+ vp8_yv12_extend_frame_borders_c(dst_ybc); |
+ return; |
+ } else { |
+ assert(!(dst_ybc->flags & YV12_FLAG_HIGHBITDEPTH)); |
+ } |
+#endif |
+ |
for (row = 0; row < src_ybc->y_height; ++row) { |
vpx_memcpy(dst, src, src_ybc->y_width); |
src += src_ybc->y_stride; |
@@ -173,6 +301,19 @@ |
const uint8_t *src = src_ybc->y_buffer; |
uint8_t *dst = dst_ybc->y_buffer; |
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
+ if (src_ybc->flags & YV12_FLAG_HIGHBITDEPTH) { |
+ const uint16_t *src16 = CONVERT_TO_SHORTPTR(src); |
+ uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst); |
+ for (row = 0; row < src_ybc->y_height; ++row) { |
+ vpx_memcpy(dst16, src16, src_ybc->y_width * sizeof(uint16_t)); |
+ src16 += src_ybc->y_stride; |
+ dst16 += dst_ybc->y_stride; |
+ } |
+ return; |
+ } |
+#endif |
+ |
for (row = 0; row < src_ybc->y_height; ++row) { |
vpx_memcpy(dst, src, src_ybc->y_width); |
src += src_ybc->y_stride; |