yv12extend.c revision 91037db265ecdd914a26e056cf69207b4f50924e
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#include <assert.h> 12#include "./vpx_config.h" 13#include "vpx_scale/yv12config.h" 14#include "vpx_mem/vpx_mem.h" 15#include "vpx_scale/vpx_scale.h" 16 17/**************************************************************************** 18* Exports 19****************************************************************************/ 20 21/**************************************************************************** 22 * 23 ****************************************************************************/ 24static void extend_plane(uint8_t *s, /* source */ 25 int sp, /* source pitch */ 26 int w, /* width */ 27 int h, /* height */ 28 int et, /* extend top border */ 29 int el, /* extend left border */ 30 int eb, /* extend bottom border */ 31 int er) { /* extend right border */ 32 int i; 33 uint8_t *src_ptr1, *src_ptr2; 34 uint8_t *dest_ptr1, *dest_ptr2; 35 int linesize; 36 37 /* copy the left and right most columns out */ 38 src_ptr1 = s; 39 src_ptr2 = s + w - 1; 40 dest_ptr1 = s - el; 41 dest_ptr2 = s + w; 42 43 for (i = 0; i < h; i++) { 44 vpx_memset(dest_ptr1, src_ptr1[0], el); 45 vpx_memset(dest_ptr2, src_ptr2[0], er); 46 src_ptr1 += sp; 47 src_ptr2 += sp; 48 dest_ptr1 += sp; 49 dest_ptr2 += sp; 50 } 51 52 /* Now copy the top and bottom lines into each line of the respective 53 * borders 54 */ 55 src_ptr1 = s - el; 56 src_ptr2 = s + sp * (h - 1) - el; 57 dest_ptr1 = s + sp * (-et) - el; 58 dest_ptr2 = s + sp * (h) - el; 59 linesize = el + er + w; 60 61 for (i = 0; i < et; i++) { 62 vpx_memcpy(dest_ptr1, src_ptr1, linesize); 63 dest_ptr1 += sp; 64 } 65 66 for (i = 0; i < eb; i++) { 67 vpx_memcpy(dest_ptr2, src_ptr2, linesize); 68 dest_ptr2 += sp; 69 } 70} 71 72void 73vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { 74 assert(ybf->y_height - ybf->y_crop_height < 16); 75 assert(ybf->y_width - ybf->y_crop_width < 16); 76 assert(ybf->y_height - ybf->y_crop_height >= 0); 77 assert(ybf->y_width - ybf->y_crop_width >= 0); 78 79 extend_plane(ybf->y_buffer, ybf->y_stride, 80 ybf->y_crop_width, ybf->y_crop_height, 81 ybf->border, ybf->border, 82 ybf->border + ybf->y_height - ybf->y_crop_height, 83 ybf->border + ybf->y_width - ybf->y_crop_width); 84 85 extend_plane(ybf->u_buffer, ybf->uv_stride, 86 (ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2, 87 ybf->border / 2, ybf->border / 2, 88 (ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2, 89 (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2); 90 91 extend_plane(ybf->v_buffer, ybf->uv_stride, 92 (ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2, 93 ybf->border / 2, ybf->border / 2, 94 (ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2, 95 (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2); 96} 97 98#if CONFIG_VP9 99static void extend_frame(YV12_BUFFER_CONFIG *ybf, 100 int subsampling_x, int subsampling_y, 101 int ext_size) { 102 const int c_w = (ybf->y_crop_width + subsampling_x) >> subsampling_x; 103 const int c_h = (ybf->y_crop_height + subsampling_y) >> subsampling_y; 104 const int c_et = ext_size >> subsampling_y; 105 const int c_el = ext_size >> subsampling_x; 106 const int c_eb = (ext_size + ybf->y_height - ybf->y_crop_height + 107 subsampling_y) >> subsampling_y; 108 const int c_er = (ext_size + ybf->y_width - ybf->y_crop_width + 109 subsampling_x) >> subsampling_x; 110 111 assert(ybf->y_height - ybf->y_crop_height < 16); 112 assert(ybf->y_width - ybf->y_crop_width < 16); 113 assert(ybf->y_height - ybf->y_crop_height >= 0); 114 assert(ybf->y_width - ybf->y_crop_width >= 0); 115 116 extend_plane(ybf->y_buffer, ybf->y_stride, 117 ybf->y_crop_width, ybf->y_crop_height, 118 ext_size, ext_size, 119 ext_size + ybf->y_height - ybf->y_crop_height, 120 ext_size + ybf->y_width - ybf->y_crop_width); 121 122 extend_plane(ybf->u_buffer, ybf->uv_stride, 123 c_w, c_h, c_et, c_el, c_eb, c_er); 124 125 extend_plane(ybf->v_buffer, ybf->uv_stride, 126 c_w, c_h, c_et, c_el, c_eb, c_er); 127} 128 129 130void vp9_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf, 131 int subsampling_x, int subsampling_y) { 132 extend_frame(ybf, subsampling_x, subsampling_y, ybf->border); 133} 134 135void vp9_extend_frame_inner_borders_c(YV12_BUFFER_CONFIG *ybf, 136 int subsampling_x, int subsampling_y) { 137 const int inner_bw = ybf->border > VP9INNERBORDERINPIXLES ? 138 VP9INNERBORDERINPIXLES : ybf->border; 139 extend_frame(ybf, subsampling_x, subsampling_y, inner_bw); 140} 141#endif 142 143/**************************************************************************** 144 * 145 * ROUTINE : vp8_yv12_copy_frame 146 * 147 * INPUTS : 148 * 149 * OUTPUTS : None. 150 * 151 * RETURNS : void 152 * 153 * FUNCTION : Copies the source image into the destination image and 154 * updates the destination's UMV borders. 155 * 156 * SPECIAL NOTES : The frames are assumed to be identical in size. 157 * 158 ****************************************************************************/ 159void 160vp8_yv12_copy_frame_c(YV12_BUFFER_CONFIG *src_ybc, 161 YV12_BUFFER_CONFIG *dst_ybc) { 162 int row; 163 unsigned char *source, *dest; 164 165#if 0 166 /* These assertions are valid in the codec, but the libvpx-tester uses 167 * this code slightly differently. 168 */ 169 assert(src_ybc->y_width == dst_ybc->y_width); 170 assert(src_ybc->y_height == dst_ybc->y_height); 171#endif 172 173 source = src_ybc->y_buffer; 174 dest = dst_ybc->y_buffer; 175 176 for (row = 0; row < src_ybc->y_height; row++) { 177 vpx_memcpy(dest, source, src_ybc->y_width); 178 source += src_ybc->y_stride; 179 dest += dst_ybc->y_stride; 180 } 181 182 source = src_ybc->u_buffer; 183 dest = dst_ybc->u_buffer; 184 185 for (row = 0; row < src_ybc->uv_height; row++) { 186 vpx_memcpy(dest, source, src_ybc->uv_width); 187 source += src_ybc->uv_stride; 188 dest += dst_ybc->uv_stride; 189 } 190 191 source = src_ybc->v_buffer; 192 dest = dst_ybc->v_buffer; 193 194 for (row = 0; row < src_ybc->uv_height; row++) { 195 vpx_memcpy(dest, source, src_ybc->uv_width); 196 source += src_ybc->uv_stride; 197 dest += dst_ybc->uv_stride; 198 } 199 200 vp8_yv12_extend_frame_borders_c(dst_ybc); 201} 202 203void vp8_yv12_copy_y_c(YV12_BUFFER_CONFIG *src_ybc, 204 YV12_BUFFER_CONFIG *dst_ybc) { 205 int row; 206 unsigned char *source, *dest; 207 208 209 source = src_ybc->y_buffer; 210 dest = dst_ybc->y_buffer; 211 212 for (row = 0; row < src_ybc->y_height; row++) { 213 vpx_memcpy(dest, source, src_ybc->y_width); 214 source += src_ybc->y_stride; 215 dest += dst_ybc->y_stride; 216 } 217} 218