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
vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG * ybf)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
extend_frame_borders_yonly(YV12_BUFFER_CONFIG * ybf)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
vp8_yv12_copy_frame(YV12_BUFFER_CONFIG * src_ybc,YV12_BUFFER_CONFIG * dst_ybc)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
vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG * src_ybc,YV12_BUFFER_CONFIG * dst_ybc)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