1085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org/*
2085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *
4085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *  Use of this source code is governed by a BSD-style license
5085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *  that can be found in the LICENSE file in the root of the source
6085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *  tree. An additional intellectual property rights grant can be found
7085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *  in the file PATENTS.  All contributing project authors may
8085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org */
10085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
11085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#include <assert.h>
12085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
13085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#include "./vpx_config.h"
14085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#include "vpx_scale/yv12config.h"
15085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#include "vpx_mem/vpx_mem.h"
16085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#include "vpx_scale/vpx_scale.h"
17085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
18085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#if HAVE_DSPR2
19085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.orgstatic void extend_plane(uint8_t *const src, int src_stride,
20085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org                         int width, int height,
21085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org                         int extend_top, int extend_left,
22085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org                         int extend_bottom, int extend_right) {
23085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  int       i, j;
24085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint8_t   *left_src, *right_src;
25085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint8_t   *left_dst_start, *right_dst_start;
26085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint8_t   *left_dst, *right_dst;
27085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint8_t   *top_src, *bot_src;
28085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint8_t   *top_dst, *bot_dst;
29085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint32_t  left_pix;
30085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint32_t  right_pix;
31085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  uint32_t  linesize;
32085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
33085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  /* copy the left and right most columns out */
34085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  left_src  = src;
35085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  right_src = src + width - 1;
36085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  left_dst_start = src - extend_left;
37085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  right_dst_start = src + width;
38085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
39085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  for (i = height; i--; ) {
40085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    left_dst  = left_dst_start;
41085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    right_dst = right_dst_start;
42085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
43085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    __asm__ __volatile__ (
44085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "lb        %[left_pix],     0(%[left_src])      \n\t"
45085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "lb        %[right_pix],    0(%[right_src])     \n\t"
46085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "replv.qb  %[left_pix],     %[left_pix]         \n\t"
47085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "replv.qb  %[right_pix],    %[right_pix]        \n\t"
48085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
49085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        : [left_pix] "=&r" (left_pix), [right_pix] "=&r" (right_pix)
50085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        : [left_src] "r" (left_src), [right_src] "r" (right_src)
51085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    );
52085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
53085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    for (j = extend_left/4; j--; ) {
54085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      __asm__ __volatile__ (
55085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "sw     %[left_pix],    0(%[left_dst])     \n\t"
56085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "sw     %[right_pix],   0(%[right_dst])    \n\t"
57085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
58085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        :
59085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        : [left_dst] "r" (left_dst), [left_pix] "r" (left_pix),
60085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org          [right_dst] "r" (right_dst), [right_pix] "r" (right_pix)
61085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      );
62085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
63085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      left_dst += 4;
64085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      right_dst += 4;
65085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    }
66085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
67085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    for (j = extend_left%4; j--; ) {
68085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      __asm__ __volatile__ (
69085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "sb     %[left_pix],    0(%[left_dst])     \n\t"
70085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        "sb     %[right_pix],   0(%[right_dst])     \n\t"
71085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
72085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        :
73085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org        : [left_dst] "r" (left_dst), [left_pix] "r" (left_pix),
74085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org          [right_dst] "r" (right_dst), [right_pix] "r" (right_pix)
75085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      );
76085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
77085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      left_dst += 1;
78085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org      right_dst += 1;
79085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    }
80085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
81085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    left_src  += src_stride;
82085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    right_src += src_stride;
83085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    left_dst_start += src_stride;
84085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    right_dst_start += src_stride;
85085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  }
86085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
87085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  /* Now copy the top and bottom lines into each line of the respective
88085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org   * borders
89085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org   */
90085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  top_src = src - extend_left;
91085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  bot_src = src + src_stride * (height - 1) - extend_left;
92085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  top_dst = src + src_stride * (-extend_top) - extend_left;
93085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  bot_dst = src + src_stride * (height) - extend_left;
94085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  linesize = extend_left + extend_right + width;
95085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
96085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  for (i = 0; i < extend_top; i++) {
97085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    vpx_memcpy(top_dst, top_src, linesize);
98085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    top_dst += src_stride;
99085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  }
100085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
101085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  for (i = 0; i < extend_bottom; i++) {
102085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    vpx_memcpy(bot_dst, bot_src, linesize);
103085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    bot_dst += src_stride;
104085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  }
105085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org}
106085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
10788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgstatic void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) {
108dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const int c_w = ybf->uv_crop_width;
109dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const int c_h = ybf->uv_crop_height;
11088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int ss_x = ybf->uv_width < ybf->y_width;
11188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int ss_y = ybf->uv_height < ybf->y_height;
11288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int c_et = ext_size >> ss_y;
11388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int c_el = ext_size >> ss_x;
11488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int c_eb = c_et + ybf->uv_height - ybf->uv_crop_height;
11588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int c_er = c_el + ybf->uv_width - ybf->uv_crop_width;
116085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
117085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  assert(ybf->y_height - ybf->y_crop_height < 16);
118085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  assert(ybf->y_width - ybf->y_crop_width < 16);
119085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  assert(ybf->y_height - ybf->y_crop_height >= 0);
120085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  assert(ybf->y_width - ybf->y_crop_width >= 0);
121085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
122085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  extend_plane(ybf->y_buffer, ybf->y_stride,
123085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org               ybf->y_crop_width, ybf->y_crop_height,
124085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org               ext_size, ext_size,
125085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org               ext_size + ybf->y_height - ybf->y_crop_height,
126085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org               ext_size + ybf->y_width - ybf->y_crop_width);
127085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
128085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  extend_plane(ybf->u_buffer, ybf->uv_stride,
129085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org               c_w, c_h, c_et, c_el, c_eb, c_er);
130085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
131085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  extend_plane(ybf->v_buffer, ybf->uv_stride,
132085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org               c_w, c_h, c_et, c_el, c_eb, c_er);
133085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org}
134085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
13588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid vp9_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf) {
13688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  extend_frame(ybf, ybf->border);
137085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org}
138085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org
13988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid vp9_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf) {
140085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  const int inner_bw = (ybf->border > VP9INNERBORDERINPIXELS) ?
141085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org                       VP9INNERBORDERINPIXELS : ybf->border;
14288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  extend_frame(ybf, inner_bw);
143085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org}
144085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org#endif
145