1 /*
2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <assert.h>
12
13 #include "./vpx_config.h"
14 #include "vpx_scale/yv12config.h"
15 #include "vpx_mem/vpx_mem.h"
16 #include "vpx_scale/vpx_scale.h"
17
18 #if HAVE_DSPR2
extend_plane(uint8_t * const src,int src_stride,int width,int height,int extend_top,int extend_left,int extend_bottom,int extend_right)19 static void extend_plane(uint8_t *const src, int src_stride,
20 int width, int height,
21 int extend_top, int extend_left,
22 int extend_bottom, int extend_right) {
23 int i, j;
24 uint8_t *left_src, *right_src;
25 uint8_t *left_dst_start, *right_dst_start;
26 uint8_t *left_dst, *right_dst;
27 uint8_t *top_src, *bot_src;
28 uint8_t *top_dst, *bot_dst;
29 uint32_t left_pix;
30 uint32_t right_pix;
31 uint32_t linesize;
32
33 /* copy the left and right most columns out */
34 left_src = src;
35 right_src = src + width - 1;
36 left_dst_start = src - extend_left;
37 right_dst_start = src + width;
38
39 for (i = height; i--; ) {
40 left_dst = left_dst_start;
41 right_dst = right_dst_start;
42
43 __asm__ __volatile__ (
44 "lb %[left_pix], 0(%[left_src]) \n\t"
45 "lb %[right_pix], 0(%[right_src]) \n\t"
46 "replv.qb %[left_pix], %[left_pix] \n\t"
47 "replv.qb %[right_pix], %[right_pix] \n\t"
48
49 : [left_pix] "=&r" (left_pix), [right_pix] "=&r" (right_pix)
50 : [left_src] "r" (left_src), [right_src] "r" (right_src)
51 );
52
53 for (j = extend_left/4; j--; ) {
54 __asm__ __volatile__ (
55 "sw %[left_pix], 0(%[left_dst]) \n\t"
56 "sw %[right_pix], 0(%[right_dst]) \n\t"
57
58 :
59 : [left_dst] "r" (left_dst), [left_pix] "r" (left_pix),
60 [right_dst] "r" (right_dst), [right_pix] "r" (right_pix)
61 );
62
63 left_dst += 4;
64 right_dst += 4;
65 }
66
67 for (j = extend_left%4; j--; ) {
68 __asm__ __volatile__ (
69 "sb %[left_pix], 0(%[left_dst]) \n\t"
70 "sb %[right_pix], 0(%[right_dst]) \n\t"
71
72 :
73 : [left_dst] "r" (left_dst), [left_pix] "r" (left_pix),
74 [right_dst] "r" (right_dst), [right_pix] "r" (right_pix)
75 );
76
77 left_dst += 1;
78 right_dst += 1;
79 }
80
81 left_src += src_stride;
82 right_src += src_stride;
83 left_dst_start += src_stride;
84 right_dst_start += src_stride;
85 }
86
87 /* Now copy the top and bottom lines into each line of the respective
88 * borders
89 */
90 top_src = src - extend_left;
91 bot_src = src + src_stride * (height - 1) - extend_left;
92 top_dst = src + src_stride * (-extend_top) - extend_left;
93 bot_dst = src + src_stride * (height) - extend_left;
94 linesize = extend_left + extend_right + width;
95
96 for (i = 0; i < extend_top; i++) {
97 vpx_memcpy(top_dst, top_src, linesize);
98 top_dst += src_stride;
99 }
100
101 for (i = 0; i < extend_bottom; i++) {
102 vpx_memcpy(bot_dst, bot_src, linesize);
103 bot_dst += src_stride;
104 }
105 }
106
extend_frame(YV12_BUFFER_CONFIG * const ybf,int ext_size)107 static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) {
108 const int c_w = ybf->uv_crop_width;
109 const int c_h = ybf->uv_crop_height;
110 const int ss_x = ybf->uv_width < ybf->y_width;
111 const int ss_y = ybf->uv_height < ybf->y_height;
112 const int c_et = ext_size >> ss_y;
113 const int c_el = ext_size >> ss_x;
114 const int c_eb = c_et + ybf->uv_height - ybf->uv_crop_height;
115 const int c_er = c_el + ybf->uv_width - ybf->uv_crop_width;
116
117 assert(ybf->y_height - ybf->y_crop_height < 16);
118 assert(ybf->y_width - ybf->y_crop_width < 16);
119 assert(ybf->y_height - ybf->y_crop_height >= 0);
120 assert(ybf->y_width - ybf->y_crop_width >= 0);
121
122 extend_plane(ybf->y_buffer, ybf->y_stride,
123 ybf->y_crop_width, ybf->y_crop_height,
124 ext_size, ext_size,
125 ext_size + ybf->y_height - ybf->y_crop_height,
126 ext_size + ybf->y_width - ybf->y_crop_width);
127
128 extend_plane(ybf->u_buffer, ybf->uv_stride,
129 c_w, c_h, c_et, c_el, c_eb, c_er);
130
131 extend_plane(ybf->v_buffer, ybf->uv_stride,
132 c_w, c_h, c_et, c_el, c_eb, c_er);
133 }
134
vp9_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG * ybf)135 void vp9_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf) {
136 extend_frame(ybf, ybf->border);
137 }
138
vp9_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG * ybf)139 void vp9_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf) {
140 const int inner_bw = (ybf->border > VP9INNERBORDERINPIXELS) ?
141 VP9INNERBORDERINPIXELS : ybf->border;
142 extend_frame(ybf, inner_bw);
143 }
144 #endif
145