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 { 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 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 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 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