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 /*****************************************************************************/
impeg2_copy_frm_yuv420p(UWORD8 * pu1_src_y,UWORD8 * pu1_src_u,UWORD8 * pu1_src_v,UWORD8 * pu1_dst_y,UWORD8 * pu1_dst_u,UWORD8 * pu1_dst_v,UWORD32 u4_width,UWORD32 u4_height,UWORD32 u4_src_stride_y,UWORD32 u4_src_stride_u,UWORD32 u4_src_stride_v,UWORD32 u4_dst_stride_y,UWORD32 u4_dst_stride_u,UWORD32 u4_dst_stride_v)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 {
119     WORD32 i4_cnt;
120     WORD32  i4_y_height     = (WORD32) u4_height;
121     WORD32  i4_uv_height    = u4_height >> 1;
122     WORD32  i4_uv_width     = u4_width >> 1;
123 
124     for(i4_cnt = 0; i4_cnt < i4_y_height; i4_cnt++)
125     {
126         memcpy(pu1_dst_y, pu1_src_y, u4_width);
127         pu1_dst_y += (u4_dst_stride_y);
128         pu1_src_y += (u4_src_stride_y);
129     }
130 
131     for(i4_cnt = 0; i4_cnt < i4_uv_height; i4_cnt++)
132     {
133         memcpy(pu1_dst_u, pu1_src_u, i4_uv_width);
134         pu1_dst_u += (u4_dst_stride_u);
135         pu1_src_u += (u4_src_stride_u);
136 
137     }
138 
139     for(i4_cnt = 0; i4_cnt < i4_uv_height; i4_cnt++)
140     {
141         memcpy(pu1_dst_v, pu1_src_v, i4_uv_width);
142         pu1_dst_v += (u4_dst_stride_v);
143         pu1_src_v += (u4_src_stride_v);
144 
145     }
146 
147 }
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 
impeg2_fmt_conv_yuv420p_to_yuv422ile(register UWORD8 * pu1_y,register UWORD8 * pu1_u,register UWORD8 * pu1_v,void * pv_yuv422i,UWORD32 u4_width,UWORD32 u4_height,UWORD32 u4_stride_y,UWORD32 u4_stride_u,UWORD32 u4_stride_v,UWORD32 u4_stride_yuv422i)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 {
197     /* Declare local variables */
198     register WORD16  i,j;
199     register UWORD16 u2_offset1,u2_offset2,u2_offset3,u2_offset_yuv422i;
200     register UWORD8  u1_y1,u1_uv;
201     register UWORD32 u4_pixel;
202     register UWORD16 u2_width_cnt;
203     register UWORD32 *pu4_yuv422i;
204 
205     UWORD8 u1_flag;             /* This flag is used to indicate wether the row is even or odd */
206 
207     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     u2_offset1       = u4_stride_y - u4_width;
211     u2_offset2       = u4_stride_u - ((u4_width + 1) >> 1);
212     u2_offset3       = u4_stride_v - ((u4_width + 1) >> 1);
213     u2_offset_yuv422i = (u4_stride_yuv422i >> 1) -((u4_width + 1) >> 1);
214 
215     /* Type cast the output pointer to UWORD32 */
216     pu4_yuv422i      = (UWORD32 *)pv_yuv422i;
217 
218     /* Calculate the loop counter for inner loop */
219     u2_width_cnt     = u4_width >> 1;
220 
221     /* Run the loop for height of input buffer */
222     for(i = u4_height; i > 0; i--)
223     {
224         /* Run the loop for width/2 */
225         for(j = u2_width_cnt; j > 0; j--)
226         {
227             /* Store the value in output buffer in the order U0Y0V0Y1U2Y2V2Y3.... */
228             /* Load Y0 */
229             u1_y1          = *pu1_y++;
230             /* Load Y1 */
231             u4_pixel       = *pu1_y++;
232             /* Load V0 */
233             u1_uv          = *pu1_v++;
234             u4_pixel       = (u4_pixel << 8) + u1_uv;
235             /* Load U0 */
236             u1_uv          = *pu1_u++;
237             u4_pixel       = (u4_pixel << 8) + u1_y1;
238             u4_pixel       = (u4_pixel << 8) + u1_uv;
239             *pu4_yuv422i++ = u4_pixel;
240         }
241         /* Incase of width is odd number take care of last pixel */
242         if(u4_width & 0x1)
243         {
244             /* Store the value in output buffer in the order U0Y0V0Y1U2Y2V2Y3.... */
245             /* Load Y0 */
246             u1_y1          = *pu1_y++;
247             /* Load V0 */
248             u1_uv          = *pu1_v++;
249             /* Take Y0 as Y1 */
250             u4_pixel       = u1_y1;
251             u4_pixel       = (u4_pixel << 8) + u1_uv;
252             /* Load U0 */
253             u1_uv          = *pu1_u++;
254             u4_pixel       = (u4_pixel << 8) + u1_y1;
255             u4_pixel       = (u4_pixel << 8) + u1_uv;
256             *pu4_yuv422i++ = u4_pixel;
257         }
258         /* Make the pointers to buffer to point to next row */
259         pu1_y = pu1_y       + u2_offset1;
260         if(!u1_flag)
261         {
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             pu1_u = pu1_u - ((u4_width + 1) >> 1);
265             pu1_v = pu1_v - ((u4_width + 1) >> 1);
266         }
267         else
268         {
269             /* Adjust the u and v buffer pointers so that they will point to next row */
270             pu1_u = pu1_u + u2_offset2;
271             pu1_v = pu1_v + u2_offset3;
272         }
273 
274         /* Adjust the output buffer pointer for next row */
275         pu4_yuv422i = pu4_yuv422i + u2_offset_yuv422i;
276         /* Toggle the flag to convert between odd and even row */
277         u1_flag= u1_flag ^ 0x1;
278     }
279 }
280 
281 
282 
283 
impeg2_fmt_conv_yuv420p_to_yuv420sp_vu(UWORD8 * pu1_y,UWORD8 * pu1_u,UWORD8 * pu1_v,UWORD8 * pu1_dest_y,UWORD8 * pu1_dest_uv,UWORD32 u4_height,UWORD32 u4_width,UWORD32 u4_stridey,UWORD32 u4_strideu,UWORD32 u4_stridev,UWORD32 u4_dest_stride_y,UWORD32 u4_dest_stride_uv,UWORD32 u4_convert_uv_only)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 {
293 
294 
295     UWORD8 *pu1_src,*pu1_dst;
296     UWORD8 *pu1_src_u, *pu1_src_v;
297     UWORD16 i;
298     UWORD32 u2_width_uv;
299 
300     UWORD32 u4_dest_inc_y=0, u4_dest_inc_uv=0;
301 
302 
303     /* Copy Y buffer */
304     pu1_dst = (UWORD8 *)pu1_dest_y;
305     pu1_src = (UWORD8 *)pu1_y;
306 
307     u4_dest_inc_y =    u4_dest_stride_y;
308     u4_dest_inc_uv =   u4_dest_stride_uv;
309 
310     if(0 == u4_convert_uv_only)
311     {
312         for(i = 0; i < u4_height; i++)
313         {
314             memcpy((void *)pu1_dst,(void *)pu1_src, u4_width);
315             pu1_dst += u4_dest_inc_y;
316             pu1_src += u4_stridey;
317         }
318     }
319 
320     /* Interleave Cb and Cr buffers */
321     pu1_src_u = pu1_u;
322     pu1_src_v = pu1_v;
323     pu1_dst = pu1_dest_uv ;
324 
325     u4_height = (u4_height + 1) >> 1;
326     u2_width_uv = (u4_width + 1) >> 1;
327     for(i = 0; i < u4_height ; i++)
328     {
329         UWORD32 j;
330         for(j = 0; j < u2_width_uv; j++)
331         {
332             *pu1_dst++ = *pu1_src_v++;
333             *pu1_dst++ = *pu1_src_u++;
334 
335         }
336 
337         pu1_dst += u4_dest_inc_uv - u4_width;
338         pu1_src_u  += u4_strideu - u2_width_uv;
339         pu1_src_v  += u4_stridev - u2_width_uv;
340     }
341 }
342 
impeg2_fmt_conv_yuv420p_to_yuv420sp_uv(UWORD8 * pu1_y,UWORD8 * pu1_u,UWORD8 * pu1_v,UWORD8 * pu1_dest_y,UWORD8 * pu1_dest_uv,UWORD32 u4_height,UWORD32 u4_width,UWORD32 u4_stridey,UWORD32 u4_strideu,UWORD32 u4_stridev,UWORD32 u4_dest_stride_y,UWORD32 u4_dest_stride_uv,UWORD32 u4_convert_uv_only)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 {
351 
352 
353     UWORD8 *pu1_src,*pu1_dst;
354     UWORD8 *pu1_src_u, *pu1_src_v;
355     UWORD16 i;
356     UWORD32 u2_width_uv;
357 
358     UWORD32 u4_dest_inc_y=0, u4_dest_inc_uv=0;
359 
360 
361     /* Copy Y buffer */
362     pu1_dst = (UWORD8 *)pu1_dest_y;
363     pu1_src = (UWORD8 *)pu1_y;
364 
365     u4_dest_inc_y =    u4_dest_stride_y;
366     u4_dest_inc_uv =   u4_dest_stride_uv;
367 
368     if(0 == u4_convert_uv_only)
369     {
370         for(i = 0; i < u4_height; i++)
371         {
372             memcpy((void *)pu1_dst,(void *)pu1_src, u4_width);
373             pu1_dst += u4_dest_inc_y;
374             pu1_src += u4_stridey;
375         }
376     }
377 
378     /* Interleave Cb and Cr buffers */
379     pu1_src_u = pu1_u;
380     pu1_src_v = pu1_v;
381     pu1_dst = pu1_dest_uv ;
382 
383     u4_height = (u4_height + 1) >> 1;
384     u2_width_uv = (u4_width + 1) >> 1;
385     for(i = 0; i < u4_height ; i++)
386     {
387         UWORD32 j;
388         for(j = 0; j < u2_width_uv; j++)
389         {
390             *pu1_dst++ = *pu1_src_u++;
391             *pu1_dst++ = *pu1_src_v++;
392         }
393 
394         pu1_dst += u4_dest_inc_uv - u4_width;
395         pu1_src_u  += u4_strideu - u2_width_uv;
396         pu1_src_v  += u4_stridev - u2_width_uv;
397     }
398 
399 }
400 
401 
402