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