Home | History | Annotate | Download | only in dm642
      1 /*
      2  *  Copyright (c) 2010 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 
     12 /****************************************************************************
     13  *
     14  *   Module Title :     yv12extend.c
     15  *
     16  *   Description  :
     17  *
     18  ***************************************************************************/
     19 
     20 /****************************************************************************
     21 *  Header Files
     22 ****************************************************************************/
     23 //#include <stdlib.h>
     24 #include "csl_dat.h"
     25 #include "vpx_scale/yv12config.h"
     26 #include "vpx_mem/vpx_mem.h"
     27 
     28 /****************************************************************************
     29 *  Exports
     30 ****************************************************************************/
     31 #define UINT8 unsigned char
     32 #define UINT32 unsigned int
     33 
     34 
     35 static inline
     36 void copy_yleft_right_border(
     37     UINT8 *restrict src_ptr1,
     38     UINT8 *restrict src_ptr2,
     39     UINT8 *restrict dest_ptr1,
     40     UINT8 *restrict dest_ptr2,
     41     UINT32  plane_height,
     42     UINT32  plane_stride
     43 )
     44 {
     45     UINT32 left, right, left2, left4, right2, right4;
     46     double dl, dr;
     47     int i;
     48 
     49 #pragma MUST_ITERATE(16,16,16)
     50 
     51     for (i = 0; i < plane_height; i++)
     52     {
     53         left  = src_ptr1[0];
     54         right = src_ptr2[0];
     55 
     56         left2 = _pack2(left, left);
     57         left4 = _packl4(left2, left2);
     58 
     59         right2 = _pack2(right, right);
     60         right4 = _packl4(right2, right2);
     61 
     62         dl = _itod(left4, left4);
     63         dr = _itod(right4, right4);
     64 
     65         _amemd8(&dest_ptr1[ 0]) = dl;
     66         _amemd8(&dest_ptr2[ 0]) = dr;
     67 
     68         _amemd8(&dest_ptr1[ 8]) = dl;
     69         _amemd8(&dest_ptr2[ 8]) = dr;
     70 
     71         _amemd8(&dest_ptr1[16]) = dl;
     72         _amemd8(&dest_ptr2[16]) = dr;
     73 
     74         _amemd8(&dest_ptr1[24]) = dl;
     75         _amemd8(&dest_ptr2[24]) = dr;
     76 
     77         _amemd8(&dest_ptr1[32]) = dl;
     78         _amemd8(&dest_ptr2[32]) = dr;
     79 
     80         _amemd8(&dest_ptr1[40]) = dl;
     81         _amemd8(&dest_ptr2[40]) = dr;
     82 
     83 
     84         src_ptr1 += plane_stride;
     85         src_ptr2 += plane_stride;
     86         dest_ptr1 += plane_stride;
     87         dest_ptr2 += plane_stride;
     88     }
     89 }
     90 /****************************************************************************
     91  *
     92  *
     93  ****************************************************************************/
     94 static
     95 void copy_uvleft_right_border(
     96     UINT8 *restrict src_ptr1,
     97     UINT8 *restrict src_ptr2,
     98     UINT8 *restrict dest_ptr1,
     99     UINT8 *restrict dest_ptr2,
    100     UINT32  plane_height,
    101     UINT32  plane_stride
    102 )
    103 {
    104     UINT32 left, right, left2, left4, right2, right4;
    105     double dl, dr;
    106     int i;
    107 
    108 #pragma MUST_ITERATE(8,8 ,8)
    109 
    110     for (i = 0; i < plane_height; i++)
    111     {
    112         left  = src_ptr1[0];
    113         right = src_ptr2[0];
    114 
    115         left2 = _pack2(left, left);
    116         left4 = _packl4(left2, left2);
    117 
    118         right2 = _pack2(right, right);
    119         right4 = _packl4(right2, right2);
    120 
    121         dl = _itod(left4, left4);
    122         dr = _itod(right4, right4);
    123 
    124         _amemd8(&dest_ptr1[ 0]) = dl;
    125         _amemd8(&dest_ptr2[ 0]) = dr;
    126 
    127         _amemd8(&dest_ptr1[ 8]) = dl;
    128         _amemd8(&dest_ptr2[ 8]) = dr;
    129 
    130         _amemd8(&dest_ptr1[16]) = dl;
    131         _amemd8(&dest_ptr2[16]) = dr;
    132 
    133 
    134         src_ptr1 += plane_stride;
    135         src_ptr2 += plane_stride;
    136         dest_ptr1 += plane_stride;
    137         dest_ptr2 += plane_stride;
    138     }
    139 }
    140 /****************************************************************************
    141  *
    142  ****************************************************************************/
    143 void
    144 vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf)
    145 {
    146     int i;
    147     unsigned char *src_ptr1, *src_ptr2;
    148     unsigned char *dest_ptr1, *dest_ptr2;
    149 
    150     unsigned int Border;
    151     int plane_stride;
    152     int plane_height;
    153     int plane_width;
    154 
    155     /***********/
    156     /* Y Plane */
    157     /***********/
    158     Border = ybf->border;
    159     plane_stride = ybf->y_stride;
    160     plane_height = ybf->y_height;
    161     plane_width = ybf->y_width;
    162 
    163 #if 1
    164     // copy the left and right most columns out
    165     src_ptr1 = ybf->y_buffer;
    166     src_ptr2 = src_ptr1 + plane_width - 1;
    167     dest_ptr1 = src_ptr1 - Border;
    168     dest_ptr2 = src_ptr2 + 1;
    169     copy_yleft_right_border(src_ptr1, src_ptr2, dest_ptr1, dest_ptr2, plane_height, plane_stride);
    170 #endif
    171 
    172     // Now copy the top and bottom source lines into each line of the respective borders
    173     src_ptr1 = ybf->y_buffer - Border;
    174     src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
    175     dest_ptr1 = src_ptr1 - (Border * plane_stride);
    176     dest_ptr2 = src_ptr2 + plane_stride;
    177 
    178     for (i = 0; i < (int)Border; i++)
    179     {
    180         vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
    181         vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
    182         dest_ptr1 += plane_stride;
    183         dest_ptr2 += plane_stride;
    184     }
    185 
    186     plane_stride /= 2;
    187     plane_height /= 2;
    188     plane_width /= 2;
    189     Border /= 2;
    190 
    191     /***********/
    192     /* U Plane */
    193     /***********/
    194 #if 1
    195     // copy the left and right most columns out
    196     src_ptr1 = ybf->u_buffer;
    197     src_ptr2 = src_ptr1 + plane_width - 1;
    198     dest_ptr1 = src_ptr1 - Border;
    199     dest_ptr2 = src_ptr2 + 1;
    200 
    201     copy_uvleft_right_border(src_ptr1, src_ptr2, dest_ptr1, dest_ptr2, plane_height, plane_stride);
    202 
    203 
    204 #endif
    205 
    206     // Now copy the top and bottom source lines into each line of the respective borders
    207     src_ptr1 = ybf->u_buffer - Border;
    208     src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
    209     dest_ptr1 = src_ptr1 - (Border * plane_stride);
    210     dest_ptr2 = src_ptr2 + plane_stride;
    211 
    212     for (i = 0; i < (int)(Border); i++)
    213     {
    214         vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
    215         vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
    216         dest_ptr1 += plane_stride;
    217         dest_ptr2 += plane_stride;
    218     }
    219 
    220     /***********/
    221     /* V Plane */
    222     /***********/
    223 #if 1
    224     // copy the left and right most columns out
    225     src_ptr1 = ybf->v_buffer;
    226     src_ptr2 = src_ptr1 + plane_width - 1;
    227     dest_ptr1 = src_ptr1 - Border;
    228     dest_ptr2 = src_ptr2 + 1;
    229 
    230     copy_uvleft_right_border(src_ptr1, src_ptr2, dest_ptr1, dest_ptr2, plane_height, plane_stride);
    231 
    232 #endif
    233 
    234     // Now copy the top and bottom source lines into each line of the respective borders
    235     src_ptr1 = ybf->v_buffer - Border;
    236     src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
    237     dest_ptr1 = src_ptr1 - (Border * plane_stride);
    238     dest_ptr2 = src_ptr2 + plane_stride;
    239 
    240     for (i = 0; i < (int)(Border); i++)
    241     {
    242         vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
    243         vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
    244         dest_ptr1 += plane_stride;
    245         dest_ptr2 += plane_stride;
    246     }
    247 }
    248 /****************************************************************************
    249  *
    250  ****************************************************************************/
    251 void
    252 vpxyv12_extend_frame_tbborders(YV12_BUFFER_CONFIG *ybf)
    253 {
    254     int i;
    255     unsigned char *src_ptr1, *src_ptr2;
    256     unsigned char *dest_ptr1, *dest_ptr2;
    257     int tid1, tid2;
    258 
    259     unsigned int Border;
    260     int plane_stride;
    261     int plane_height;
    262     int plane_width;
    263 
    264     /***********/
    265     /* Y Plane */
    266     /***********/
    267     Border = ybf->border;
    268     plane_stride = ybf->y_stride;
    269     plane_height = ybf->y_height;
    270     plane_width = ybf->y_width;
    271 
    272 
    273     // Now copy the top and bottom source lines into each line of the respective borders
    274     src_ptr1 = ybf->y_buffer - Border;
    275     src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
    276     dest_ptr1 = src_ptr1 - (Border * plane_stride);
    277     dest_ptr2 = src_ptr2 + plane_stride;
    278 
    279 
    280     for (i = 0; i < (int)Border; i++)
    281     {
    282         dat_copy(src_ptr1, dest_ptr1, plane_stride);
    283         dat_copy(src_ptr2, dest_ptr2, plane_stride);
    284         dest_ptr1 += plane_stride;
    285         dest_ptr2 += plane_stride;
    286     }
    287 
    288     plane_stride /= 2;
    289     plane_height /= 2;
    290     plane_width /= 2;
    291     Border /= 2;
    292 
    293     /***********/
    294     /* U Plane */
    295     /***********/
    296     // Now copy the top and bottom source lines into each line of the respective borders
    297     src_ptr1 = ybf->u_buffer - Border;
    298     src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
    299     dest_ptr1 = src_ptr1 - (Border * plane_stride);
    300     dest_ptr2 = src_ptr2 + plane_stride;
    301 
    302     for (i = 0; i < (int)(Border); i++)
    303     {
    304         dat_copy(src_ptr1, dest_ptr1, plane_stride);
    305         dat_copy(src_ptr2, dest_ptr2, plane_stride);
    306         dest_ptr1 += plane_stride;
    307         dest_ptr2 += plane_stride;
    308     }
    309 
    310     /***********/
    311     /* V Plane */
    312     /***********/
    313     // Now copy the top and bottom source lines into each line of the respective borders
    314     src_ptr1 = ybf->v_buffer - Border;
    315     src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
    316     dest_ptr1 = src_ptr1 - (Border * plane_stride);
    317     dest_ptr2 = src_ptr2 + plane_stride;
    318 
    319     for (i = 0; i < (int)(Border); i++)
    320     {
    321         tid1 = dat_copy(src_ptr1, dest_ptr1, plane_stride);
    322         tid2 = dat_copy(src_ptr2, dest_ptr2, plane_stride);
    323         dest_ptr1 += plane_stride;
    324         dest_ptr2 += plane_stride;
    325     }
    326 
    327     dat_wait(tid1);
    328     dat_wait(tid2);
    329 }
    330 
    331 /****************************************************************************
    332  *
    333  *  ROUTINE       : vp8_yv12_copy_frame
    334  *
    335  *  INPUTS        :
    336  *
    337  *  OUTPUTS       : None.
    338  *
    339  *  RETURNS       : void
    340  *
    341  *  FUNCTION      : Copies the source image into the destination image and
    342  *                  updates the destination's UMV borders.  Because the
    343  *                  borders have been update prior to this so the whole frame
    344  *                  is copied, borders and all.  This is also to circumvent
    345  *                  using copy_left_right Border functions when copying data
    346  *                  between L2 and main memory.  When that occurs a cache
    347  *                  clean needs to be done, which would require invalidating
    348  *                  an entire frame.
    349  *
    350  *  SPECIAL NOTES : The frames are assumed to be identical in size.
    351  *
    352  ****************************************************************************/
    353 void
    354 vpxyv12_copy_frame_dma(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
    355 {
    356     int yheight, uv_height;
    357     int ystride, uv_stride;
    358     int border;
    359     int yoffset, uvoffset;
    360 
    361     border = src_ybc->border;
    362     yheight = src_ybc->y_height;
    363     uv_height = src_ybc->uv_height;
    364 
    365     ystride = src_ybc->y_stride;
    366     uv_stride = src_ybc->uv_stride;
    367 
    368     yoffset = border * (ystride + 1);
    369     uvoffset = border / 2 * (uv_stride + 1);
    370 
    371     dat_copy2d(DAT_2D2D,
    372                src_ybc->y_buffer - yoffset,
    373                dst_ybc->y_buffer - yoffset,
    374                ystride,
    375                yheight + 2 * border,
    376                ystride);
    377     dat_copy2d(DAT_2D2D,
    378                src_ybc->u_buffer - uvoffset,
    379                dst_ybc->u_buffer - uvoffset,
    380                uv_stride,
    381                uv_height + border,
    382                uv_stride);
    383     dat_copy2d(DAT_2D2D,
    384                src_ybc->v_buffer - uvoffset,
    385                dst_ybc->v_buffer - uvoffset,
    386                uv_stride,
    387                uv_height + border,
    388                uv_stride);
    389 
    390 }
    391 
    392 
    393 /****************************************************************************
    394  *
    395  *  ROUTINE       : vp8_yv12_copy_frame
    396  *
    397  *  INPUTS        :
    398  *
    399  *  OUTPUTS       : None.
    400  *
    401  *  RETURNS       : void
    402  *
    403  *  FUNCTION      : Copies the source image into the destination image and
    404  *                  updates the destination's UMV borders.
    405  *
    406  *  SPECIAL NOTES : The frames are assumed to be identical in size.
    407  *
    408  ****************************************************************************/
    409 void
    410 vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
    411 {
    412     int row;
    413     unsigned char *source, *dest;
    414 
    415     source = src_ybc->y_buffer;
    416     dest = dst_ybc->y_buffer;
    417 
    418     for (row = 0; row < src_ybc->y_height; row++)
    419     {
    420         vpx_memcpy(dest, source, src_ybc->y_width);
    421         source += src_ybc->y_stride;
    422         dest   += dst_ybc->y_stride;
    423     }
    424 
    425     source = src_ybc->u_buffer;
    426     dest = dst_ybc->u_buffer;
    427 
    428     for (row = 0; row < src_ybc->uv_height; row++)
    429     {
    430         vpx_memcpy(dest, source, src_ybc->uv_width);
    431         source += src_ybc->uv_stride;
    432         dest   += dst_ybc->uv_stride;
    433     }
    434 
    435     source = src_ybc->v_buffer;
    436     dest = dst_ybc->v_buffer;
    437 
    438     for (row = 0; row < src_ybc->uv_height; row++)
    439     {
    440         vpx_memcpy(dest, source, src_ybc->uv_width);
    441         source += src_ybc->uv_stride;
    442         dest   += dst_ybc->uv_stride;
    443     }
    444 
    445     vp8_yv12_extend_frame_borders(dst_ybc);
    446 }
    447