1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp8/common/extend.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,188 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 + 1.15 +#include "extend.h" 1.16 +#include "vpx_mem/vpx_mem.h" 1.17 + 1.18 + 1.19 +static void copy_and_extend_plane 1.20 +( 1.21 + unsigned char *s, /* source */ 1.22 + int sp, /* source pitch */ 1.23 + unsigned char *d, /* destination */ 1.24 + int dp, /* destination pitch */ 1.25 + int h, /* height */ 1.26 + int w, /* width */ 1.27 + int et, /* extend top border */ 1.28 + int el, /* extend left border */ 1.29 + int eb, /* extend bottom border */ 1.30 + int er /* extend right border */ 1.31 +) 1.32 +{ 1.33 + int i; 1.34 + unsigned char *src_ptr1, *src_ptr2; 1.35 + unsigned char *dest_ptr1, *dest_ptr2; 1.36 + int linesize; 1.37 + 1.38 + /* copy the left and right most columns out */ 1.39 + src_ptr1 = s; 1.40 + src_ptr2 = s + w - 1; 1.41 + dest_ptr1 = d - el; 1.42 + dest_ptr2 = d + w; 1.43 + 1.44 + for (i = 0; i < h; i++) 1.45 + { 1.46 + vpx_memset(dest_ptr1, src_ptr1[0], el); 1.47 + vpx_memcpy(dest_ptr1 + el, src_ptr1, w); 1.48 + vpx_memset(dest_ptr2, src_ptr2[0], er); 1.49 + src_ptr1 += sp; 1.50 + src_ptr2 += sp; 1.51 + dest_ptr1 += dp; 1.52 + dest_ptr2 += dp; 1.53 + } 1.54 + 1.55 + /* Now copy the top and bottom lines into each line of the respective 1.56 + * borders 1.57 + */ 1.58 + src_ptr1 = d - el; 1.59 + src_ptr2 = d + dp * (h - 1) - el; 1.60 + dest_ptr1 = d + dp * (-et) - el; 1.61 + dest_ptr2 = d + dp * (h) - el; 1.62 + linesize = el + er + w; 1.63 + 1.64 + for (i = 0; i < et; i++) 1.65 + { 1.66 + vpx_memcpy(dest_ptr1, src_ptr1, linesize); 1.67 + dest_ptr1 += dp; 1.68 + } 1.69 + 1.70 + for (i = 0; i < eb; i++) 1.71 + { 1.72 + vpx_memcpy(dest_ptr2, src_ptr2, linesize); 1.73 + dest_ptr2 += dp; 1.74 + } 1.75 +} 1.76 + 1.77 + 1.78 +void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, 1.79 + YV12_BUFFER_CONFIG *dst) 1.80 +{ 1.81 + int et = dst->border; 1.82 + int el = dst->border; 1.83 + int eb = dst->border + dst->y_height - src->y_height; 1.84 + int er = dst->border + dst->y_width - src->y_width; 1.85 + 1.86 + copy_and_extend_plane(src->y_buffer, src->y_stride, 1.87 + dst->y_buffer, dst->y_stride, 1.88 + src->y_height, src->y_width, 1.89 + et, el, eb, er); 1.90 + 1.91 + et = dst->border >> 1; 1.92 + el = dst->border >> 1; 1.93 + eb = (dst->border >> 1) + dst->uv_height - src->uv_height; 1.94 + er = (dst->border >> 1) + dst->uv_width - src->uv_width; 1.95 + 1.96 + copy_and_extend_plane(src->u_buffer, src->uv_stride, 1.97 + dst->u_buffer, dst->uv_stride, 1.98 + src->uv_height, src->uv_width, 1.99 + et, el, eb, er); 1.100 + 1.101 + copy_and_extend_plane(src->v_buffer, src->uv_stride, 1.102 + dst->v_buffer, dst->uv_stride, 1.103 + src->uv_height, src->uv_width, 1.104 + et, el, eb, er); 1.105 +} 1.106 + 1.107 + 1.108 +void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, 1.109 + YV12_BUFFER_CONFIG *dst, 1.110 + int srcy, int srcx, 1.111 + int srch, int srcw) 1.112 +{ 1.113 + int et = dst->border; 1.114 + int el = dst->border; 1.115 + int eb = dst->border + dst->y_height - src->y_height; 1.116 + int er = dst->border + dst->y_width - src->y_width; 1.117 + int src_y_offset = srcy * src->y_stride + srcx; 1.118 + int dst_y_offset = srcy * dst->y_stride + srcx; 1.119 + int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1); 1.120 + int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1); 1.121 + 1.122 + /* If the side is not touching the bounder then don't extend. */ 1.123 + if (srcy) 1.124 + et = 0; 1.125 + if (srcx) 1.126 + el = 0; 1.127 + if (srcy + srch != src->y_height) 1.128 + eb = 0; 1.129 + if (srcx + srcw != src->y_width) 1.130 + er = 0; 1.131 + 1.132 + copy_and_extend_plane(src->y_buffer + src_y_offset, 1.133 + src->y_stride, 1.134 + dst->y_buffer + dst_y_offset, 1.135 + dst->y_stride, 1.136 + srch, srcw, 1.137 + et, el, eb, er); 1.138 + 1.139 + et = (et + 1) >> 1; 1.140 + el = (el + 1) >> 1; 1.141 + eb = (eb + 1) >> 1; 1.142 + er = (er + 1) >> 1; 1.143 + srch = (srch + 1) >> 1; 1.144 + srcw = (srcw + 1) >> 1; 1.145 + 1.146 + copy_and_extend_plane(src->u_buffer + src_uv_offset, 1.147 + src->uv_stride, 1.148 + dst->u_buffer + dst_uv_offset, 1.149 + dst->uv_stride, 1.150 + srch, srcw, 1.151 + et, el, eb, er); 1.152 + 1.153 + copy_and_extend_plane(src->v_buffer + src_uv_offset, 1.154 + src->uv_stride, 1.155 + dst->v_buffer + dst_uv_offset, 1.156 + dst->uv_stride, 1.157 + srch, srcw, 1.158 + et, el, eb, er); 1.159 +} 1.160 + 1.161 + 1.162 +/* note the extension is only for the last row, for intra prediction purpose */ 1.163 +void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, 1.164 + unsigned char *YPtr, 1.165 + unsigned char *UPtr, 1.166 + unsigned char *VPtr) 1.167 +{ 1.168 + int i; 1.169 + 1.170 + YPtr += ybf->y_stride * 14; 1.171 + UPtr += ybf->uv_stride * 6; 1.172 + VPtr += ybf->uv_stride * 6; 1.173 + 1.174 + for (i = 0; i < 4; i++) 1.175 + { 1.176 + YPtr[i] = YPtr[-1]; 1.177 + UPtr[i] = UPtr[-1]; 1.178 + VPtr[i] = VPtr[-1]; 1.179 + } 1.180 + 1.181 + YPtr += ybf->y_stride; 1.182 + UPtr += ybf->uv_stride; 1.183 + VPtr += ybf->uv_stride; 1.184 + 1.185 + for (i = 0; i < 4; i++) 1.186 + { 1.187 + YPtr[i] = YPtr[-1]; 1.188 + UPtr[i] = UPtr[-1]; 1.189 + VPtr[i] = VPtr[-1]; 1.190 + } 1.191 +}