xref: /aosp_15_r20/external/libvpx/vpx_scale/mips/dspr2/yv12extend_dspr2.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
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, int width,
20                          int height, int extend_top, int extend_left,
21                          int extend_bottom, int extend_right) {
22   int i, j;
23   uint8_t *left_src, *right_src;
24   uint8_t *left_dst_start, *right_dst_start;
25   uint8_t *left_dst, *right_dst;
26   uint8_t *top_src, *bot_src;
27   uint8_t *top_dst, *bot_dst;
28   uint32_t left_pix;
29   uint32_t right_pix;
30   uint32_t linesize;
31 
32   /* copy the left and right most columns out */
33   left_src = src;
34   right_src = src + width - 1;
35   left_dst_start = src - extend_left;
36   right_dst_start = src + width;
37 
38   for (i = height; i--;) {
39     left_dst = left_dst_start;
40     right_dst = right_dst_start;
41 
42     __asm__ __volatile__(
43         "lb        %[left_pix],     0(%[left_src])      \n\t"
44         "lb        %[right_pix],    0(%[right_src])     \n\t"
45         "replv.qb  %[left_pix],     %[left_pix]         \n\t"
46         "replv.qb  %[right_pix],    %[right_pix]        \n\t"
47 
48         : [left_pix] "=&r"(left_pix), [right_pix] "=&r"(right_pix)
49         : [left_src] "r"(left_src), [right_src] "r"(right_src));
50 
51     for (j = extend_left / 4; j--;) {
52       __asm__ __volatile__(
53           "sw     %[left_pix],    0(%[left_dst])     \n\t"
54           "sw     %[right_pix],   0(%[right_dst])    \n\t"
55 
56           :
57           : [left_dst] "r"(left_dst), [left_pix] "r"(left_pix),
58             [right_dst] "r"(right_dst), [right_pix] "r"(right_pix));
59 
60       left_dst += 4;
61       right_dst += 4;
62     }
63 
64     for (j = extend_left % 4; j--;) {
65       __asm__ __volatile__(
66           "sb     %[left_pix],    0(%[left_dst])     \n\t"
67           "sb     %[right_pix],   0(%[right_dst])     \n\t"
68 
69           :
70           : [left_dst] "r"(left_dst), [left_pix] "r"(left_pix),
71             [right_dst] "r"(right_dst), [right_pix] "r"(right_pix));
72 
73       left_dst += 1;
74       right_dst += 1;
75     }
76 
77     left_src += src_stride;
78     right_src += src_stride;
79     left_dst_start += src_stride;
80     right_dst_start += src_stride;
81   }
82 
83   /* Now copy the top and bottom lines into each line of the respective
84    * borders
85    */
86   top_src = src - extend_left;
87   bot_src = src + src_stride * (height - 1) - extend_left;
88   top_dst = src + src_stride * (-extend_top) - extend_left;
89   bot_dst = src + src_stride * (height)-extend_left;
90   linesize = extend_left + extend_right + width;
91 
92   for (i = 0; i < extend_top; i++) {
93     memcpy(top_dst, top_src, linesize);
94     top_dst += src_stride;
95   }
96 
97   for (i = 0; i < extend_bottom; i++) {
98     memcpy(bot_dst, bot_src, linesize);
99     bot_dst += src_stride;
100   }
101 }
102 
extend_frame(YV12_BUFFER_CONFIG * const ybf,int ext_size)103 static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) {
104   const int c_w = ybf->uv_crop_width;
105   const int c_h = ybf->uv_crop_height;
106   const int ss_x = ybf->uv_width < ybf->y_width;
107   const int ss_y = ybf->uv_height < ybf->y_height;
108   const int c_et = ext_size >> ss_y;
109   const int c_el = ext_size >> ss_x;
110   const int c_eb = c_et + ybf->uv_height - ybf->uv_crop_height;
111   const int c_er = c_el + ybf->uv_width - ybf->uv_crop_width;
112 
113   assert(ybf->y_height - ybf->y_crop_height < 16);
114   assert(ybf->y_width - ybf->y_crop_width < 16);
115   assert(ybf->y_height - ybf->y_crop_height >= 0);
116   assert(ybf->y_width - ybf->y_crop_width >= 0);
117 
118   extend_plane(ybf->y_buffer, ybf->y_stride, ybf->y_crop_width,
119                ybf->y_crop_height, ext_size, ext_size,
120                ext_size + ybf->y_height - ybf->y_crop_height,
121                ext_size + ybf->y_width - ybf->y_crop_width);
122 
123   extend_plane(ybf->u_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er);
124 
125   extend_plane(ybf->v_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er);
126 }
127 
vpx_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG * ybf)128 void vpx_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf) {
129   extend_frame(ybf, ybf->border);
130 }
131 
vpx_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG * ybf)132 void vpx_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf) {
133   const int inner_bw = (ybf->border > VP9INNERBORDERINPIXELS)
134                            ? VP9INNERBORDERINPIXELS
135                            : ybf->border;
136   extend_frame(ybf, inner_bw);
137 }
138 #endif
139