16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/* 26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * 46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Use of this source code is governed by a BSD-style license 56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * that can be found in the LICENSE file in the root of the source 66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * tree. An additional intellectual property rights grant can be found 76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * in the file PATENTS. All contributing project authors may 86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * be found in the AUTHORS file in the root of the source tree. 96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */ 106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx_mem/vpx_mem.h" 126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org#include "vp9/common/vp9_common.h" 14d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vp9/encoder/vp9_extend.h" 1553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org 163f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.orgstatic void copy_and_extend_plane(const uint8_t *src, int src_pitch, 173f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org uint8_t *dst, int dst_pitch, 183f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org int w, int h, 193f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org int extend_top, int extend_left, 203f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org int extend_bottom, int extend_right) { 213f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org int i, linesize; 223f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 233f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org // copy the left and right most columns out 243f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const uint8_t *src_ptr1 = src; 253f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const uint8_t *src_ptr2 = src + w - 1; 263f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org uint8_t *dst_ptr1 = dst - extend_left; 273f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org uint8_t *dst_ptr2 = dst + w; 286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (i = 0; i < h; i++) { 303f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org vpx_memset(dst_ptr1, src_ptr1[0], extend_left); 313f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org vpx_memcpy(dst_ptr1 + extend_left, src_ptr1, w); 323f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org vpx_memset(dst_ptr2, src_ptr2[0], extend_right); 333f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src_ptr1 += src_pitch; 343f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src_ptr2 += src_pitch; 353f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst_ptr1 += dst_pitch; 363f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst_ptr2 += dst_pitch; 376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 393f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org // Now copy the top and bottom lines into each line of the respective 403f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org // borders 413f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src_ptr1 = dst - extend_left; 423f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src_ptr2 = dst + dst_pitch * (h - 1) - extend_left; 433f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst_ptr1 = dst + dst_pitch * (-extend_top) - extend_left; 443f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst_ptr2 = dst + dst_pitch * (h) - extend_left; 453f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org linesize = extend_left + extend_right + w; 463f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 473f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org for (i = 0; i < extend_top; i++) { 483f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org vpx_memcpy(dst_ptr1, src_ptr1, linesize); 493f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst_ptr1 += dst_pitch; 506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 523f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org for (i = 0; i < extend_bottom; i++) { 533f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org vpx_memcpy(dst_ptr2, src_ptr2, linesize); 543f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst_ptr2 += dst_pitch; 556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 583f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.orgvoid vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src, 596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org YV12_BUFFER_CONFIG *dst) { 60f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org // Extend src frame in buffer 61f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org // Altref filtering assumes 16 pixel extension 62f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int et_y = 16; 63f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int el_y = 16; 64f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org // Motion estimation may use src block variance with the block size up 65d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // to 64x64, so the right and bottom need to be extended to 64 multiple 66f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org // or up to 16, whichever is greater. 67f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int eb_y = MAX(ALIGN_POWER_OF_TWO(src->y_width, 6) - src->y_width, 68f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 16); 69f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int er_y = MAX(ALIGN_POWER_OF_TWO(src->y_height, 6) - src->y_height, 70f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 16); 71f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int uv_width_subsampling = (src->uv_width != src->y_width); 72f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int uv_height_subsampling = (src->uv_height != src->y_height); 73f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int et_uv = et_y >> uv_height_subsampling; 74f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int el_uv = el_y >> uv_width_subsampling; 75f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int eb_uv = eb_y >> uv_height_subsampling; 76f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int er_uv = er_y >> uv_width_subsampling; 7710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org copy_and_extend_plane(src->y_buffer, src->y_stride, 796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dst->y_buffer, dst->y_stride, 803f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src->y_width, src->y_height, 813f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org et_y, el_y, eb_y, er_y); 826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org copy_and_extend_plane(src->u_buffer, src->uv_stride, 846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dst->u_buffer, dst->uv_stride, 853f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src->uv_width, src->uv_height, 863f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org et_uv, el_uv, eb_uv, er_uv); 876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org copy_and_extend_plane(src->v_buffer, src->uv_stride, 896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dst->v_buffer, dst->uv_stride, 903f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org src->uv_width, src->uv_height, 9110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org et_uv, el_uv, eb_uv, er_uv); 926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 943f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.orgvoid vp9_copy_and_extend_frame_with_rect(const YV12_BUFFER_CONFIG *src, 956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org YV12_BUFFER_CONFIG *dst, 966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int srcy, int srcx, 976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int srch, int srcw) { 986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // If the side is not touching the bounder then don't extend. 993f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int et_y = srcy ? 0 : dst->border; 1003f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int el_y = srcx ? 0 : dst->border; 1013f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int eb_y = srcy + srch != src->y_height ? 0 : 1023f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst->border + dst->y_height - src->y_height; 1033f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int er_y = srcx + srcw != src->y_width ? 0 : 1043f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst->border + dst->y_width - src->y_width; 1053f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int src_y_offset = srcy * src->y_stride + srcx; 1063f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int dst_y_offset = srcy * dst->y_stride + srcx; 1073f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 10853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org const int et_uv = ROUND_POWER_OF_TWO(et_y, 1); 10953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org const int el_uv = ROUND_POWER_OF_TWO(el_y, 1); 11053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org const int eb_uv = ROUND_POWER_OF_TWO(eb_y, 1); 11153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org const int er_uv = ROUND_POWER_OF_TWO(er_y, 1); 1123f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1); 1133f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1); 11453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org const int srch_uv = ROUND_POWER_OF_TWO(srch, 1); 11553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org const int srcw_uv = ROUND_POWER_OF_TWO(srcw, 1); 1163f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 1173f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org copy_and_extend_plane(src->y_buffer + src_y_offset, src->y_stride, 1183f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst->y_buffer + dst_y_offset, dst->y_stride, 1193f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org srcw, srch, 1203f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org et_y, el_y, eb_y, er_y); 1213f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 1223f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org copy_and_extend_plane(src->u_buffer + src_uv_offset, src->uv_stride, 1233f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst->u_buffer + dst_uv_offset, dst->uv_stride, 1243f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org srcw_uv, srch_uv, 1253f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org et_uv, el_uv, eb_uv, er_uv); 1263f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 1273f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org copy_and_extend_plane(src->v_buffer + src_uv_offset, src->uv_stride, 1283f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org dst->v_buffer + dst_uv_offset, dst->uv_stride, 1293f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org srcw_uv, srch_uv, 1303f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org et_uv, el_uv, eb_uv, er_uv); 1316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 132