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 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 memcpy(top_dst, top_src, linesize); 98 top_dst += src_stride; 99 } 100 101 for (i = 0; i < extend_bottom; i++) { 102 memcpy(bot_dst, bot_src, linesize); 103 bot_dst += src_stride; 104 } 105 } 106 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 135 void vpx_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf) { 136 extend_frame(ybf, ybf->border); 137 } 138 139 void vpx_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