/src/libmpeg2/common/impeg2_format_conv.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2015 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | /*****************************************************************************/ |
21 | | /* */ |
22 | | /* File Name : impeg2_format_conv .c */ |
23 | | /* */ |
24 | | /* Description : Contains functions needed to convert the images in */ |
25 | | /* different color spaces to yuv 422i color space */ |
26 | | /* */ |
27 | | /* List of Functions : YUV420toYUV420() */ |
28 | | /* YUV420toYUV422I() */ |
29 | | /* YUV420toYUV420SP_VU() */ |
30 | | /* YUV420toYUV420SP_UU() */ |
31 | | /* */ |
32 | | /* Issues / Problems : None */ |
33 | | /* */ |
34 | | /* Revision History : */ |
35 | | /* */ |
36 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
37 | | /* 28 08 2007 Naveen Kumar T Draft */ |
38 | | /* */ |
39 | | /*****************************************************************************/ |
40 | | /*****************************************************************************/ |
41 | | /* File Includes */ |
42 | | /*****************************************************************************/ |
43 | | |
44 | | /* System include files */ |
45 | | |
46 | | /* User include files */ |
47 | | #include <stdio.h> |
48 | | #include <string.h> |
49 | | #include "iv_datatypedef.h" |
50 | | #include "iv.h" |
51 | | #include "ithread.h" |
52 | | |
53 | | #include "iv_datatypedef.h" |
54 | | #include "impeg2_macros.h" |
55 | | #include "impeg2_buf_mgr.h" |
56 | | #include "impeg2_disp_mgr.h" |
57 | | #include "impeg2_defs.h" |
58 | | #include "impeg2_platform_macros.h" |
59 | | |
60 | | #include "impeg2_job_queue.h" |
61 | | #include "impeg2_format_conv.h" |
62 | | |
63 | | |
64 | | /*****************************************************************************/ |
65 | | /* */ |
66 | | /* Function Name : impeg2_copy_frm_yuv420p() */ |
67 | | /* */ |
68 | | /* Description : This function performs conversion from YUV420 to */ |
69 | | /* YUV422I color space. */ |
70 | | /* */ |
71 | | /* Inputs : pu1_src_y, - UWORD8 pointer to source y plane. */ |
72 | | /* pu1_src_u, - UWORD8 pointer to source u plane. */ |
73 | | /* pu1_src_v, - UWORD8 pointer to source v plane. */ |
74 | | /* pu1_dst_y, - UWORD8 pointer to dest y plane. */ |
75 | | /* pu1_dst_u, - UWORD8 pointer to dest u plane. */ |
76 | | /* pu1_dst_v, - UWORD8 pointer to dest v plane. */ |
77 | | /* u4_width, - Width of image. */ |
78 | | /* u4_height, - Height of image. */ |
79 | | /* u4_src_stride_y - Stride in pixels of source Y plane. */ |
80 | | /* u4_src_stride_u - Stride in pixels of source U plane. */ |
81 | | /* u4_src_stride_v - Stride in pixels of source V plane. */ |
82 | | /* u4_dst_stride_y - Stride in pixels of dest Y plane. */ |
83 | | /* u4_dst_stride_u - Stride in pixels of dest U plane. */ |
84 | | /* u4_dst_stride_v - Stride in pixels of dest V plane. */ |
85 | | /* */ |
86 | | /* Globals : None */ |
87 | | /* */ |
88 | | /* Processing : One row is processed at a time. The one iteration of the */ |
89 | | /* code will rearrange pixels into YUV422 interleaved */ |
90 | | /* format. */ |
91 | | /* */ |
92 | | /* Outputs : None */ |
93 | | /* */ |
94 | | /* Returns : None */ |
95 | | /* */ |
96 | | /* Issues : None */ |
97 | | /* */ |
98 | | /* Revision History: */ |
99 | | /* */ |
100 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
101 | | /* 29 08 2007 Naveen Kumar T Draft */ |
102 | | /* */ |
103 | | /*****************************************************************************/ |
104 | | void impeg2_copy_frm_yuv420p(UWORD8 *pu1_src_y, |
105 | | UWORD8 *pu1_src_u, |
106 | | UWORD8 *pu1_src_v, |
107 | | UWORD8 *pu1_dst_y, |
108 | | UWORD8 *pu1_dst_u, |
109 | | UWORD8 *pu1_dst_v, |
110 | | UWORD32 u4_width, |
111 | | UWORD32 u4_height, |
112 | | UWORD32 u4_src_stride_y, |
113 | | UWORD32 u4_src_stride_u, |
114 | | UWORD32 u4_src_stride_v, |
115 | | UWORD32 u4_dst_stride_y, |
116 | | UWORD32 u4_dst_stride_u, |
117 | | UWORD32 u4_dst_stride_v) |
118 | 30.4k | { |
119 | 30.4k | WORD32 i4_cnt; |
120 | 30.4k | WORD32 i4_y_height = (WORD32) u4_height; |
121 | 30.4k | WORD32 i4_uv_height = u4_height >> 1; |
122 | 30.4k | WORD32 i4_uv_width = u4_width >> 1; |
123 | | |
124 | 1.56M | for(i4_cnt = 0; i4_cnt < i4_y_height; i4_cnt++) |
125 | 1.53M | { |
126 | 1.53M | memcpy(pu1_dst_y, pu1_src_y, u4_width); |
127 | 1.53M | pu1_dst_y += (u4_dst_stride_y); |
128 | 1.53M | pu1_src_y += (u4_src_stride_y); |
129 | 1.53M | } |
130 | | |
131 | 923k | for(i4_cnt = 0; i4_cnt < i4_uv_height; i4_cnt++) |
132 | 893k | { |
133 | 893k | memcpy(pu1_dst_u, pu1_src_u, i4_uv_width); |
134 | 893k | pu1_dst_u += (u4_dst_stride_u); |
135 | 893k | pu1_src_u += (u4_src_stride_u); |
136 | | |
137 | 893k | } |
138 | | |
139 | 919k | for(i4_cnt = 0; i4_cnt < i4_uv_height; i4_cnt++) |
140 | 888k | { |
141 | 888k | memcpy(pu1_dst_v, pu1_src_v, i4_uv_width); |
142 | 888k | pu1_dst_v += (u4_dst_stride_v); |
143 | 888k | pu1_src_v += (u4_src_stride_v); |
144 | | |
145 | 888k | } |
146 | | |
147 | 30.4k | } |
148 | | |
149 | | /*****************************************************************************/ |
150 | | /* */ |
151 | | /* Function Name : impeg2_fmt_conv_yuv420p_to_yuv422ile() */ |
152 | | /* */ |
153 | | /* Description : This function performs conversion from YUV420 to */ |
154 | | /* YUV422I color space. */ |
155 | | /* */ |
156 | | /* Inputs : pu1_y - UWORD8 pointer to y plane. */ |
157 | | /* pu1_u - UWORD8 pointer to u plane. */ |
158 | | /* pu1_v - UWORD8 pointer to u plane. */ |
159 | | /* pu2_yuv422i - UWORD16 pointer to yuv422iimage. */ |
160 | | /* u4_width - Width of the Y plane. */ |
161 | | /* u4_height - Height of the Y plane. */ |
162 | | /* u4_stride_y - Stride in pixels of Y plane. */ |
163 | | /* u4_stride_u - Stride in pixels of U plane. */ |
164 | | /* u4_stride_v - Stride in pixels of V plane. */ |
165 | | /* u4_stride_yuv422i- Stride in pixels of yuv422i image. */ |
166 | | /* */ |
167 | | /* Globals : None */ |
168 | | /* */ |
169 | | /* Processing : One row is processed at a time. The one iteration of the */ |
170 | | /* code will rearrange pixels into YUV422 interleaved */ |
171 | | /* format. */ |
172 | | /* */ |
173 | | /* Outputs : None */ |
174 | | /* */ |
175 | | /* Returns : None */ |
176 | | /* */ |
177 | | /* Issues : None */ |
178 | | /* */ |
179 | | /* Revision History: */ |
180 | | /* */ |
181 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
182 | | /* 29 08 2007 Naveen Kumar T Draft */ |
183 | | /* */ |
184 | | /*****************************************************************************/ |
185 | | |
186 | | void impeg2_fmt_conv_yuv420p_to_yuv422ile(register UWORD8 *pu1_y, |
187 | | register UWORD8 *pu1_u, |
188 | | register UWORD8 *pu1_v, |
189 | | void *pv_yuv422i, |
190 | | UWORD32 u4_width, |
191 | | UWORD32 u4_height, |
192 | | UWORD32 u4_stride_y, |
193 | | UWORD32 u4_stride_u, |
194 | | UWORD32 u4_stride_v, |
195 | | UWORD32 u4_stride_yuv422i) |
196 | 0 | { |
197 | | /* Declare local variables */ |
198 | 0 | register WORD16 i,j; |
199 | 0 | register UWORD16 u2_offset1,u2_offset2,u2_offset3,u2_offset_yuv422i; |
200 | 0 | register UWORD8 u1_y1,u1_uv; |
201 | 0 | register UWORD32 u4_pixel; |
202 | 0 | register UWORD16 u2_width_cnt; |
203 | 0 | register UWORD32 *pu4_yuv422i; |
204 | |
|
205 | 0 | UWORD8 u1_flag; /* This flag is used to indicate wether the row is even or odd */ |
206 | |
|
207 | 0 | u1_flag=0x0; /* Intialize it with 0 indicating odd row */ |
208 | | |
209 | | /* Calculate the offsets necessary to make input and output buffers to point next row */ |
210 | 0 | u2_offset1 = u4_stride_y - u4_width; |
211 | 0 | u2_offset2 = u4_stride_u - ((u4_width + 1) >> 1); |
212 | 0 | u2_offset3 = u4_stride_v - ((u4_width + 1) >> 1); |
213 | 0 | u2_offset_yuv422i = (u4_stride_yuv422i >> 1) -((u4_width + 1) >> 1); |
214 | | |
215 | | /* Type cast the output pointer to UWORD32 */ |
216 | 0 | pu4_yuv422i = (UWORD32 *)pv_yuv422i; |
217 | | |
218 | | /* Calculate the loop counter for inner loop */ |
219 | 0 | u2_width_cnt = u4_width >> 1; |
220 | | |
221 | | /* Run the loop for height of input buffer */ |
222 | 0 | for(i = u4_height; i > 0; i--) |
223 | 0 | { |
224 | | /* Run the loop for width/2 */ |
225 | 0 | for(j = u2_width_cnt; j > 0; j--) |
226 | 0 | { |
227 | | /* Store the value in output buffer in the order U0Y0V0Y1U2Y2V2Y3.... */ |
228 | | /* Load Y0 */ |
229 | 0 | u1_y1 = *pu1_y++; |
230 | | /* Load Y1 */ |
231 | 0 | u4_pixel = *pu1_y++; |
232 | | /* Load V0 */ |
233 | 0 | u1_uv = *pu1_v++; |
234 | 0 | u4_pixel = (u4_pixel << 8) + u1_uv; |
235 | | /* Load U0 */ |
236 | 0 | u1_uv = *pu1_u++; |
237 | 0 | u4_pixel = (u4_pixel << 8) + u1_y1; |
238 | 0 | u4_pixel = (u4_pixel << 8) + u1_uv; |
239 | 0 | *pu4_yuv422i++ = u4_pixel; |
240 | 0 | } |
241 | | /* Incase of width is odd number take care of last pixel */ |
242 | 0 | if(u4_width & 0x1) |
243 | 0 | { |
244 | | /* Store the value in output buffer in the order U0Y0V0Y1U2Y2V2Y3.... */ |
245 | | /* Load Y0 */ |
246 | 0 | u1_y1 = *pu1_y++; |
247 | | /* Load V0 */ |
248 | 0 | u1_uv = *pu1_v++; |
249 | | /* Take Y0 as Y1 */ |
250 | 0 | u4_pixel = u1_y1; |
251 | 0 | u4_pixel = (u4_pixel << 8) + u1_uv; |
252 | | /* Load U0 */ |
253 | 0 | u1_uv = *pu1_u++; |
254 | 0 | u4_pixel = (u4_pixel << 8) + u1_y1; |
255 | 0 | u4_pixel = (u4_pixel << 8) + u1_uv; |
256 | 0 | *pu4_yuv422i++ = u4_pixel; |
257 | 0 | } |
258 | | /* Make the pointers to buffer to point to next row */ |
259 | 0 | pu1_y = pu1_y + u2_offset1; |
260 | 0 | if(!u1_flag) |
261 | 0 | { |
262 | | /* Restore the pointers of u and v buffer back so that the row of pixels are also */ |
263 | | /* Processed with same row of u and values again */ |
264 | 0 | pu1_u = pu1_u - ((u4_width + 1) >> 1); |
265 | 0 | pu1_v = pu1_v - ((u4_width + 1) >> 1); |
266 | 0 | } |
267 | 0 | else |
268 | 0 | { |
269 | | /* Adjust the u and v buffer pointers so that they will point to next row */ |
270 | 0 | pu1_u = pu1_u + u2_offset2; |
271 | 0 | pu1_v = pu1_v + u2_offset3; |
272 | 0 | } |
273 | | |
274 | | /* Adjust the output buffer pointer for next row */ |
275 | 0 | pu4_yuv422i = pu4_yuv422i + u2_offset_yuv422i; |
276 | | /* Toggle the flag to convert between odd and even row */ |
277 | 0 | u1_flag= u1_flag ^ 0x1; |
278 | 0 | } |
279 | 0 | } |
280 | | |
281 | | |
282 | | |
283 | | |
284 | | void impeg2_fmt_conv_yuv420p_to_yuv420sp_vu(UWORD8 *pu1_y, UWORD8 *pu1_u, UWORD8 *pu1_v, |
285 | | UWORD8 *pu1_dest_y, UWORD8 *pu1_dest_uv, |
286 | | UWORD32 u4_height, UWORD32 u4_width,UWORD32 u4_stridey, |
287 | | UWORD32 u4_strideu, UWORD32 u4_stridev, |
288 | | UWORD32 u4_dest_stride_y, UWORD32 u4_dest_stride_uv, |
289 | | UWORD32 u4_convert_uv_only |
290 | | ) |
291 | | |
292 | 33.9k | { |
293 | | |
294 | | |
295 | 33.9k | UWORD8 *pu1_src,*pu1_dst; |
296 | 33.9k | UWORD8 *pu1_src_u, *pu1_src_v; |
297 | 33.9k | UWORD16 i; |
298 | 33.9k | UWORD32 u2_width_uv; |
299 | | |
300 | 33.9k | UWORD32 u4_dest_inc_y=0, u4_dest_inc_uv=0; |
301 | | |
302 | | |
303 | | /* Copy Y buffer */ |
304 | 33.9k | pu1_dst = (UWORD8 *)pu1_dest_y; |
305 | 33.9k | pu1_src = (UWORD8 *)pu1_y; |
306 | | |
307 | 33.9k | u4_dest_inc_y = u4_dest_stride_y; |
308 | 33.9k | u4_dest_inc_uv = u4_dest_stride_uv; |
309 | | |
310 | 33.9k | if(0 == u4_convert_uv_only) |
311 | 18.3k | { |
312 | 1.13M | for(i = 0; i < u4_height; i++) |
313 | 1.11M | { |
314 | 1.11M | memcpy((void *)pu1_dst,(void *)pu1_src, u4_width); |
315 | 1.11M | pu1_dst += u4_dest_inc_y; |
316 | 1.11M | pu1_src += u4_stridey; |
317 | 1.11M | } |
318 | 18.3k | } |
319 | | |
320 | | /* Interleave Cb and Cr buffers */ |
321 | 33.9k | pu1_src_u = pu1_u; |
322 | 33.9k | pu1_src_v = pu1_v; |
323 | 33.9k | pu1_dst = pu1_dest_uv ; |
324 | 33.9k | u4_width = ((u4_width + 1) >> 1) << 1; |
325 | 33.9k | u4_height = (u4_height + 1) >> 1; |
326 | 33.9k | u2_width_uv = (u4_width + 1) >> 1; |
327 | 1.08M | for(i = 0; i < u4_height ; i++) |
328 | 1.05M | { |
329 | 1.05M | UWORD32 j; |
330 | 492M | for(j = 0; j < u2_width_uv; j++) |
331 | 491M | { |
332 | 491M | *pu1_dst++ = *pu1_src_v++; |
333 | 491M | *pu1_dst++ = *pu1_src_u++; |
334 | | |
335 | 491M | } |
336 | | |
337 | 1.05M | pu1_dst += u4_dest_inc_uv - u4_width; |
338 | 1.05M | pu1_src_u += u4_strideu - u2_width_uv; |
339 | 1.05M | pu1_src_v += u4_stridev - u2_width_uv; |
340 | 1.05M | } |
341 | 33.9k | } |
342 | | |
343 | | void impeg2_fmt_conv_yuv420p_to_yuv420sp_uv(UWORD8 *pu1_y, UWORD8 *pu1_u, UWORD8 *pu1_v, |
344 | | UWORD8 *pu1_dest_y, UWORD8 *pu1_dest_uv, |
345 | | UWORD32 u4_height, UWORD32 u4_width,UWORD32 u4_stridey, |
346 | | UWORD32 u4_strideu, UWORD32 u4_stridev, |
347 | | UWORD32 u4_dest_stride_y, UWORD32 u4_dest_stride_uv, |
348 | | UWORD32 u4_convert_uv_only) |
349 | | |
350 | 64.2k | { |
351 | | |
352 | | |
353 | 64.2k | UWORD8 *pu1_src,*pu1_dst; |
354 | 64.2k | UWORD8 *pu1_src_u, *pu1_src_v; |
355 | 64.2k | UWORD16 i; |
356 | 64.2k | UWORD32 u2_width_uv; |
357 | | |
358 | 64.2k | UWORD32 u4_dest_inc_y=0, u4_dest_inc_uv=0; |
359 | | |
360 | | |
361 | | /* Copy Y buffer */ |
362 | 64.2k | pu1_dst = (UWORD8 *)pu1_dest_y; |
363 | 64.2k | pu1_src = (UWORD8 *)pu1_y; |
364 | | |
365 | 64.2k | u4_dest_inc_y = u4_dest_stride_y; |
366 | 64.2k | u4_dest_inc_uv = u4_dest_stride_uv; |
367 | | |
368 | 64.2k | if(0 == u4_convert_uv_only) |
369 | 38.6k | { |
370 | 2.37M | for(i = 0; i < u4_height; i++) |
371 | 2.33M | { |
372 | 2.33M | memcpy((void *)pu1_dst,(void *)pu1_src, u4_width); |
373 | 2.33M | pu1_dst += u4_dest_inc_y; |
374 | 2.33M | pu1_src += u4_stridey; |
375 | 2.33M | } |
376 | 38.6k | } |
377 | | |
378 | | /* Interleave Cb and Cr buffers */ |
379 | 64.2k | pu1_src_u = pu1_u; |
380 | 64.2k | pu1_src_v = pu1_v; |
381 | 64.2k | pu1_dst = pu1_dest_uv ; |
382 | 64.2k | u4_width = ((u4_width + 1) >> 1) << 1; |
383 | 64.2k | u4_height = (u4_height + 1) >> 1; |
384 | 64.2k | u2_width_uv = (u4_width + 1) >> 1; |
385 | 2.09M | for(i = 0; i < u4_height ; i++) |
386 | 2.03M | { |
387 | 2.03M | UWORD32 j; |
388 | 1.27G | for(j = 0; j < u2_width_uv; j++) |
389 | 1.27G | { |
390 | 1.27G | *pu1_dst++ = *pu1_src_u++; |
391 | 1.27G | *pu1_dst++ = *pu1_src_v++; |
392 | 1.27G | } |
393 | | |
394 | 2.03M | pu1_dst += u4_dest_inc_uv - u4_width; |
395 | 2.03M | pu1_src_u += u4_strideu - u2_width_uv; |
396 | 2.03M | pu1_src_v += u4_stridev - u2_width_uv; |
397 | 2.03M | } |
398 | | |
399 | 64.2k | } |
400 | | |
401 | | |