Home | History | Annotate | Download | only in dspr2
      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