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 #include "vpx_scale/yv12config.h" 13 #include "vpx_mem/vpx_mem.h" 14 #include "vpx_scale/vpxscale.h" 15 16 /**************************************************************************** 17 * Exports 18 ****************************************************************************/ 19 20 /**************************************************************************** 21 * 22 ****************************************************************************/ 23 void 24 vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf) 25 { 26 int i; 27 unsigned char *src_ptr1, *src_ptr2; 28 unsigned char *dest_ptr1, *dest_ptr2; 29 30 unsigned int Border; 31 int plane_stride; 32 int plane_height; 33 int plane_width; 34 35 /***********/ 36 /* Y Plane */ 37 /***********/ 38 Border = ybf->border; 39 plane_stride = ybf->y_stride; 40 plane_height = ybf->y_height; 41 plane_width = ybf->y_width; 42 43 /* copy the left and right most columns out */ 44 src_ptr1 = ybf->y_buffer; 45 src_ptr2 = src_ptr1 + plane_width - 1; 46 dest_ptr1 = src_ptr1 - Border; 47 dest_ptr2 = src_ptr2 + 1; 48 49 for (i = 0; i < plane_height; i++) 50 { 51 vpx_memset(dest_ptr1, src_ptr1[0], Border); 52 vpx_memset(dest_ptr2, src_ptr2[0], Border); 53 src_ptr1 += plane_stride; 54 src_ptr2 += plane_stride; 55 dest_ptr1 += plane_stride; 56 dest_ptr2 += plane_stride; 57 } 58 59 /* Now copy the top and bottom source lines into each line of the respective borders */ 60 src_ptr1 = ybf->y_buffer - Border; 61 src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; 62 dest_ptr1 = src_ptr1 - (Border * plane_stride); 63 dest_ptr2 = src_ptr2 + plane_stride; 64 65 for (i = 0; i < (int)Border; i++) 66 { 67 vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); 68 vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); 69 dest_ptr1 += plane_stride; 70 dest_ptr2 += plane_stride; 71 } 72 73 74 /***********/ 75 /* U Plane */ 76 /***********/ 77 plane_stride = ybf->uv_stride; 78 plane_height = ybf->uv_height; 79 plane_width = ybf->uv_width; 80 Border /= 2; 81 82 /* copy the left and right most columns out */ 83 src_ptr1 = ybf->u_buffer; 84 src_ptr2 = src_ptr1 + plane_width - 1; 85 dest_ptr1 = src_ptr1 - Border; 86 dest_ptr2 = src_ptr2 + 1; 87 88 for (i = 0; i < plane_height; i++) 89 { 90 vpx_memset(dest_ptr1, src_ptr1[0], Border); 91 vpx_memset(dest_ptr2, src_ptr2[0], Border); 92 src_ptr1 += plane_stride; 93 src_ptr2 += plane_stride; 94 dest_ptr1 += plane_stride; 95 dest_ptr2 += plane_stride; 96 } 97 98 /* Now copy the top and bottom source lines into each line of the respective borders */ 99 src_ptr1 = ybf->u_buffer - Border; 100 src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; 101 dest_ptr1 = src_ptr1 - (Border * plane_stride); 102 dest_ptr2 = src_ptr2 + plane_stride; 103 104 for (i = 0; i < (int)(Border); i++) 105 { 106 vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); 107 vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); 108 dest_ptr1 += plane_stride; 109 dest_ptr2 += plane_stride; 110 } 111 112 /***********/ 113 /* V Plane */ 114 /***********/ 115 116 /* copy the left and right most columns out */ 117 src_ptr1 = ybf->v_buffer; 118 src_ptr2 = src_ptr1 + plane_width - 1; 119 dest_ptr1 = src_ptr1 - Border; 120 dest_ptr2 = src_ptr2 + 1; 121 122 for (i = 0; i < plane_height; i++) 123 { 124 vpx_memset(dest_ptr1, src_ptr1[0], Border); 125 vpx_memset(dest_ptr2, src_ptr2[0], Border); 126 src_ptr1 += plane_stride; 127 src_ptr2 += plane_stride; 128 dest_ptr1 += plane_stride; 129 dest_ptr2 += plane_stride; 130 } 131 132 /* Now copy the top and bottom source lines into each line of the respective borders */ 133 src_ptr1 = ybf->v_buffer - Border; 134 src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; 135 dest_ptr1 = src_ptr1 - (Border * plane_stride); 136 dest_ptr2 = src_ptr2 + plane_stride; 137 138 for (i = 0; i < (int)(Border); i++) 139 { 140 vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); 141 vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); 142 dest_ptr1 += plane_stride; 143 dest_ptr2 += plane_stride; 144 } 145 } 146 147 148 static void 149 extend_frame_borders_yonly(YV12_BUFFER_CONFIG *ybf) 150 { 151 int i; 152 unsigned char *src_ptr1, *src_ptr2; 153 unsigned char *dest_ptr1, *dest_ptr2; 154 155 unsigned int Border; 156 int plane_stride; 157 int plane_height; 158 int plane_width; 159 160 /***********/ 161 /* Y Plane */ 162 /***********/ 163 Border = ybf->border; 164 plane_stride = ybf->y_stride; 165 plane_height = ybf->y_height; 166 plane_width = ybf->y_width; 167 168 /* copy the left and right most columns out */ 169 src_ptr1 = ybf->y_buffer; 170 src_ptr2 = src_ptr1 + plane_width - 1; 171 dest_ptr1 = src_ptr1 - Border; 172 dest_ptr2 = src_ptr2 + 1; 173 174 for (i = 0; i < plane_height; i++) 175 { 176 vpx_memset(dest_ptr1, src_ptr1[0], Border); 177 vpx_memset(dest_ptr2, src_ptr2[0], Border); 178 src_ptr1 += plane_stride; 179 src_ptr2 += plane_stride; 180 dest_ptr1 += plane_stride; 181 dest_ptr2 += plane_stride; 182 } 183 184 /* Now copy the top and bottom source lines into each line of the respective borders */ 185 src_ptr1 = ybf->y_buffer - Border; 186 src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; 187 dest_ptr1 = src_ptr1 - (Border * plane_stride); 188 dest_ptr2 = src_ptr2 + plane_stride; 189 190 for (i = 0; i < (int)Border; i++) 191 { 192 vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); 193 vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); 194 dest_ptr1 += plane_stride; 195 dest_ptr2 += plane_stride; 196 } 197 198 plane_stride /= 2; 199 plane_height /= 2; 200 plane_width /= 2; 201 Border /= 2; 202 203 } 204 205 206 207 /**************************************************************************** 208 * 209 * ROUTINE : vp8_yv12_copy_frame 210 * 211 * INPUTS : 212 * 213 * OUTPUTS : None. 214 * 215 * RETURNS : void 216 * 217 * FUNCTION : Copies the source image into the destination image and 218 * updates the destination's UMV borders. 219 * 220 * SPECIAL NOTES : The frames are assumed to be identical in size. 221 * 222 ****************************************************************************/ 223 void 224 vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc) 225 { 226 int row; 227 unsigned char *source, *dest; 228 229 source = src_ybc->y_buffer; 230 dest = dst_ybc->y_buffer; 231 232 for (row = 0; row < src_ybc->y_height; row++) 233 { 234 vpx_memcpy(dest, source, src_ybc->y_width); 235 source += src_ybc->y_stride; 236 dest += dst_ybc->y_stride; 237 } 238 239 source = src_ybc->u_buffer; 240 dest = dst_ybc->u_buffer; 241 242 for (row = 0; row < src_ybc->uv_height; row++) 243 { 244 vpx_memcpy(dest, source, src_ybc->uv_width); 245 source += src_ybc->uv_stride; 246 dest += dst_ybc->uv_stride; 247 } 248 249 source = src_ybc->v_buffer; 250 dest = dst_ybc->v_buffer; 251 252 for (row = 0; row < src_ybc->uv_height; row++) 253 { 254 vpx_memcpy(dest, source, src_ybc->uv_width); 255 source += src_ybc->uv_stride; 256 dest += dst_ybc->uv_stride; 257 } 258 259 vp8_yv12_extend_frame_borders_ptr(dst_ybc); 260 } 261 262 void 263 vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc) 264 { 265 int row; 266 unsigned char *source, *dest; 267 268 269 source = src_ybc->y_buffer; 270 dest = dst_ybc->y_buffer; 271 272 for (row = 0; row < src_ybc->y_height; row++) 273 { 274 vpx_memcpy(dest, source, src_ybc->y_width); 275 source += src_ybc->y_stride; 276 dest += dst_ybc->y_stride; 277 } 278 279 extend_frame_borders_yonly(dst_ybc); 280 } 281