11553Srgrimes#include "gfx_util.h" 21553Srgrimes 31553Srgrimes#include <strings.h> 41553Srgrimes#include <stdio.h> 51553Srgrimes 61553Srgrimes#include "CpuCapabilities.h" 71553Srgrimes#include "gfx_conv_c.h" 81553Srgrimes#include "gfx_conv_mmx.h" 91553Srgrimes 101553Srgrimes 111553Srgrimes// ref docs 121553Srgrimes// http://www.joemaller.com/fcp/fxscript_yuv_color.shtml 131553Srgrimes 141553Srgrimes 151553Srgrimes#if 1 161553Srgrimes #define TRACE(a...) printf(a) 171553Srgrimes#else 181553Srgrimes #define TRACE(a...) 191553Srgrimes#endif 201553Srgrimes 211553Srgrimes 221553Srgrimes//! This function will try to find the best colorspaces for both the ff-codec 231553Srgrimes// and the Media Kit sides. 241553Srgrimesgfx_convert_func 251553Srgrimesresolve_colorspace(color_space colorSpace, PixelFormat pixelFormat, int width, 261553Srgrimes int height) 271553Srgrimes{ 281553Srgrimes CPUCapabilities cpu; 291553Srgrimes 301553Srgrimes switch (colorSpace) { 3130642Scharnier case B_RGB32: 321553Srgrimes // Planar Formats 3330642Scharnier if (pixelFormat == PIX_FMT_YUV410P) { 3430642Scharnier TRACE("resolve_colorspace: gfx_conv_yuv410p_rgb32_c\n"); 3550479Speter return gfx_conv_yuv410p_rgb32_c; 361553Srgrimes } 371553Srgrimes 381553Srgrimes if (pixelFormat == PIX_FMT_YUV411P) { 391553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_c\n"); 401553Srgrimes return gfx_conv_yuv411p_rgb32_c; 411553Srgrimes } 421553Srgrimes 431553Srgrimes if (pixelFormat == PIX_FMT_YUV420P 441553Srgrimes || pixelFormat == PIX_FMT_YUVJ420P) { 451553Srgrimes if (cpu.HasSSSE3() && width % 8 == 0 && height % 2 == 0) { 461553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_ssse3\n"); 47246209Scharnier return gfx_conv_yuv420p_rgba32_ssse3; 481553Srgrimes } else if (cpu.HasSSE2() && width % 8 == 0 && height % 2 == 0) { 491553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse2\n"); 501553Srgrimes return gfx_conv_yuv420p_rgba32_sse2; 511553Srgrimes } else if (cpu.HasSSE1() && width % 4 == 0 521553Srgrimes && height % 2 == 0) { 531553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse\n"); 541553Srgrimes return gfx_conv_yuv420p_rgba32_sse; 551553Srgrimes } else { 561553Srgrimes TRACE("resolve_colorspace: gfx_conv_YCbCr420p_RGB32_c\n"); 571553Srgrimes return gfx_conv_YCbCr420p_RGB32_c; 581553Srgrimes } 591553Srgrimes } 601553Srgrimes 611553Srgrimes if (pixelFormat == PIX_FMT_YUV422P 621553Srgrimes || pixelFormat == PIX_FMT_YUVJ422P) { 631553Srgrimes if (cpu.HasSSSE3() && width % 8 == 0) { 641553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv422p_RGB32_ssse3\n"); 651553Srgrimes return gfx_conv_yuv422p_rgba32_ssse3; 661553Srgrimes } else if (cpu.HasSSE2() && width % 8 == 0) { 671553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv422p_RGB32_sse2\n"); 681553Srgrimes return gfx_conv_yuv422p_rgba32_sse2; 691553Srgrimes } else if (cpu.HasSSE1() && width % 4 == 0) { 701553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv422p_RGB32_sse\n"); 711553Srgrimes return gfx_conv_yuv422p_rgba32_sse; 721553Srgrimes } else { 731553Srgrimes TRACE("resolve_colorspace: gfx_conv_YCbCr422p_RGB32_c\n"); 741553Srgrimes return gfx_conv_YCbCr422_RGB32_c; 751553Srgrimes } 761553Srgrimes } 771553Srgrimes 7830830Scharnier // Packed Formats 791553Srgrimes if (pixelFormat == PIX_FMT_YUYV422) { 801553Srgrimes if (cpu.HasSSSE3() && width % 8 == 0) { 811553Srgrimes return gfx_conv_yuv422_rgba32_ssse3; 821553Srgrimes } else if (cpu.HasSSE2() && width % 8 == 0) { 831553Srgrimes return gfx_conv_yuv422_rgba32_sse2; 841553Srgrimes } else if (cpu.HasSSE1() && width % 4 == 0 851553Srgrimes && height % 2 == 0) { 861553Srgrimes return gfx_conv_yuv422_rgba32_sse; 871553Srgrimes } else { 881553Srgrimes return gfx_conv_YCbCr422_RGB32_c; 891553Srgrimes } 901553Srgrimes } 911553Srgrimes 921553Srgrimes TRACE("resolve_colorspace: %s => B_RGB32: NULL\n", 931553Srgrimes pixfmt_to_string(pixelFormat)); 941553Srgrimes return NULL; 951553Srgrimes 961553Srgrimes case B_RGB24_BIG: 971553Srgrimes TRACE("resolve_colorspace: %s => B_RGB24_BIG: NULL\n", 981553Srgrimes pixfmt_to_string(pixelFormat)); 991553Srgrimes return NULL; 1001553Srgrimes 1011553Srgrimes case B_RGB24: 1021553Srgrimes TRACE("resolve_colorspace: %s => B_RGB24: NULL\n", 1031553Srgrimes pixfmt_to_string(pixelFormat)); 1041553Srgrimes return NULL; 1051553Srgrimes 1061553Srgrimes case B_YCbCr422: 1071553Srgrimes if (pixelFormat == PIX_FMT_YUV410P) { 1081553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv410p_ycbcr422_c\n"); 1091553Srgrimes return gfx_conv_yuv410p_ycbcr422_c; 1101553Srgrimes } 1111553Srgrimes 1121553Srgrimes if (pixelFormat == PIX_FMT_YUV411P) { 1131553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv411p_ycbcr422_c\n"); 1141553Srgrimes return gfx_conv_yuv411p_ycbcr422_c; 1151553Srgrimes } 1161553Srgrimes 1171553Srgrimes if (pixelFormat == PIX_FMT_YUV420P 1181553Srgrimes || pixelFormat == PIX_FMT_YUVJ420P) { 1191553Srgrimes TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_c\n"); 1201553Srgrimes return gfx_conv_yuv420p_ycbcr422_c; 1218857Srgrimes } 1221553Srgrimes 1231553Srgrimes if (pixelFormat == PIX_FMT_YUYV422) { 1241553Srgrimes TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: " 1251553Srgrimes "gfx_conv_null\n"); 1261553Srgrimes return gfx_conv_null; 1271553Srgrimes } 1281553Srgrimes 1291553Srgrimes TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", 1301553Srgrimes pixfmt_to_string(pixelFormat)); 1311553Srgrimes return NULL; 1321553Srgrimes 1331553Srgrimes default: 1341553Srgrimes TRACE("resolve_colorspace: default: NULL!!!\n"); 1351553Srgrimes return NULL; 1361553Srgrimes } 13730830Scharnier} 1381553Srgrimes 1391553Srgrimes 1401553Srgrimesconst char* 1411553Srgrimespixfmt_to_string(int pixFormat) 1421553Srgrimes{ 1431553Srgrimes switch (pixFormat) { 1441553Srgrimes case PIX_FMT_NONE: 1451553Srgrimes return "PIX_FMT_NONE"; 1461553Srgrimes 1471553Srgrimes case PIX_FMT_YUV420P: 1481553Srgrimes // planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) 1491553Srgrimes return "PIX_FMT_YUV420P"; 1501553Srgrimes 1511553Srgrimes case PIX_FMT_YUYV422: 1521553Srgrimes // packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr 1531553Srgrimes return "PIX_FMT_YUYV422"; 1541553Srgrimes 1551553Srgrimes case PIX_FMT_RGB24: 1561553Srgrimes // packed RGB 8:8:8, 24bpp, RGBRGB... 1571553Srgrimes return "PIX_FMT_RGB24"; 1581553Srgrimes 1591553Srgrimes case PIX_FMT_BGR24: 1601553Srgrimes // packed RGB 8:8:8, 24bpp, BGRBGR... 1611553Srgrimes return "PIX_FMT_BGR24"; 1621553Srgrimes 163 case PIX_FMT_YUV422P: 164 // planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) 165 return "PIX_FMT_YUV422P"; 166 167 case PIX_FMT_YUV444P: 168 // planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) 169 return "PIX_FMT_YUV444P"; 170 171 case PIX_FMT_RGB32: 172 // packed RGB 8:8:8, 32bpp, (msb)8A 8R 8G 8B(lsb), in CPU 173 // endianness 174 return "PIX_FMT_RGB32"; 175 176 case PIX_FMT_YUV410P: 177 // planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) 178 return "PIX_FMT_YUV410P"; 179 180 case PIX_FMT_YUV411P: 181 // planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) 182 return "PIX_FMT_YUV411P"; 183 184 case PIX_FMT_RGB565: 185 // packed RGB 5:6:5, 16bpp, (msb)5R 6G 5B(lsb), in CPU endianness 186 return "PIX_FMT_RGB565"; 187 188 case PIX_FMT_RGB555: 189 // packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), in CPU 190 // endianness, most significant bit to 0 191 return "PIX_FMT_RGB555"; 192 193 case PIX_FMT_GRAY8: 194 // Y, 8bpp 195 return "PIX_FMT_GRAY8"; 196 197 case PIX_FMT_MONOWHITE: 198 // Y, 1bpp, 0 is white, 1 is black 199 return "PIX_FMT_MONOWHITE"; 200 201 case PIX_FMT_MONOBLACK: 202 // Y, 1bpp, 0 is black, 1 is white 203 return "PIX_FMT_MONOBLACK"; 204 205 case PIX_FMT_PAL8: 206 // 8 bit with PIX_FMT_RGB32 palette 207 return "PIX_FMT_PAL8"; 208 209 case PIX_FMT_YUVJ420P: 210 // planar YUV 4:2:0, 12bpp, full scale (JPEG) 211 return "PIX_FMT_YUVJ420P - YUV420P (Jpeg)"; 212 213 case PIX_FMT_YUVJ422P: 214 // planar YUV 4:2:2, 16bpp, full scale (JPEG) 215 return "PIX_FMT_YUVJ422P - YUV422P (Jpeg)"; 216 217 case PIX_FMT_YUVJ444P: 218 // planar YUV 4:4:4, 24bpp, full scale (JPEG) 219 return "PIX_FMT_YUVJ444P"; 220 221 case PIX_FMT_XVMC_MPEG2_MC: 222 // XVideo Motion Acceleration via common packet passing 223 return "PIX_FMT_XVMC_MPEG2_MC"; 224 225 case PIX_FMT_XVMC_MPEG2_IDCT: 226 return "PIX_FMT_XVMC_MPEG2_IDCT"; 227 case PIX_FMT_UYVY422: 228 // packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 229 return "PIX_FMT_UYVY422"; 230 231 case PIX_FMT_UYYVYY411: 232 // packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 233 return "PIX_FMT_UYYVYY411"; 234 235 case PIX_FMT_BGR32: 236 // packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in CPU 237 // endianness 238 return "PIX_FMT_BGR32"; 239 240 case PIX_FMT_BGR565: 241 // packed RGB 5:6:5, 16bpp, (msb)5B 6G 5R(lsb), in CPU endianness 242 return "PIX_FMT_BGR565"; 243 244 case PIX_FMT_BGR555: 245 // packed RGB 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), in CPU 246 // endianness, most significant bit to 1 247 return "PIX_FMT_BGR555"; 248 249 case PIX_FMT_BGR8: 250 // packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) 251 return "PIX_FMT_BGR8"; 252 253 case PIX_FMT_BGR4: 254 // packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb) 255 return "PIX_FMT_BGR4"; 256 257 case PIX_FMT_BGR4_BYTE: 258 // packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) 259 return "PIX_FMT_BGR4_BYTE"; 260 261 case PIX_FMT_RGB8: 262 // packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) 263 return "PIX_FMT_RGB8"; 264 265 case PIX_FMT_RGB4: 266 // packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb) 267 return "PIX_FMT_RGB4"; 268 269 case PIX_FMT_RGB4_BYTE: 270 // packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) 271 return "PIX_FMT_RGB4_BYTE"; 272 273 case PIX_FMT_NV12: 274 // planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV 275 return "PIX_FMT_NV12"; 276 277 case PIX_FMT_NV21: 278 // as above, but U and V bytes are swapped 279 return "PIX_FMT_NV21"; 280 281 case PIX_FMT_RGB32_1: 282 // packed RGB 8:8:8, 32bpp, (msb)8R 8G 8B 8A(lsb), in CPU 283 // endianness 284 return "PIX_FMT_RGB32_1"; 285 286 case PIX_FMT_BGR32_1: 287 // packed RGB 8:8:8, 32bpp, (msb)8B 8G 8R 8A(lsb), in CPU 288 // endianness 289 return "PIX_FMT_BGR32_1"; 290 291 case PIX_FMT_GRAY16BE: 292 // Y, 16bpp, big-endian 293 return "PIX_FMT_GRAY16BE"; 294 295 case PIX_FMT_GRAY16LE: 296 // Y, 16bpp, little-endian 297 return "PIX_FMT_GRAY16LE"; 298 299 case PIX_FMT_YUV440P: 300 // planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) 301 return "PIX_FMT_YUV440P"; 302 303 case PIX_FMT_YUVJ440P: 304 // planar YUV 4:4:0 full scale (JPEG) 305 return "PIX_FMT_YUVJ440P - YUV440P (Jpeg)"; 306 307 case PIX_FMT_YUVA420P: 308 // planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A 309 // samples) 310 return "PIX_FMT_YUVA420P - YUV420P (Alpha)"; 311 312 case PIX_FMT_VDPAU_H264: 313 // H.264 HW decoding with VDPAU, data[0] contains a 314 // vdpau_render_state struct which contains the bitstream of the 315 // slices as well as various fields extracted from headers 316 return "PIX_FMT_VDPAU_H264"; 317 318 case PIX_FMT_VDPAU_MPEG1: 319 // MPEG-1 HW decoding with VDPAU, data[0] contains a 320 // vdpau_render_state struct which contains the bitstream of the 321 // slices as well as various fields extracted from headers 322 return "PIX_FMT_VDPAU_MPEG1"; 323 324 case PIX_FMT_VDPAU_MPEG2: 325 // MPEG-2 HW decoding with VDPAU, data[0] contains a 326 // vdpau_render_state struct which contains the bitstream of the 327 // slices as well as various fields extracted from headers 328 return "PIX_FMT_VDPAU_MPEG2"; 329 330 case PIX_FMT_VDPAU_WMV3: 331 // WMV3 HW decoding with VDPAU, data[0] contains a 332 // vdpau_render_state struct which contains the bitstream of the 333 // slices as well as various fields extracted from headers 334 return "PIX_FMT_VDPAU_WMV3"; 335 336 case PIX_FMT_VDPAU_VC1: 337 // VC-1 HW decoding with VDPAU, data[0] contains a 338 // vdpau_render_state struct which contains the bitstream of the 339 // slices as well as various fields extracted from headers 340 return "PIX_FMT_VDPAU_VC1"; 341 342 case PIX_FMT_RGB48BE: 343 // packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian 344 return "PIX_FMT_RGB48BE"; 345 346 case PIX_FMT_RGB48LE: 347 // packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian 348 return "PIX_FMT_RGB48LE"; 349 350 case PIX_FMT_VAAPI_MOCO: 351 // HW acceleration through VA API at motion compensation 352 // entry-point, Picture.data[0] contains a vaapi_render_state 353 // struct which contains macroblocks as well as various fields 354 // extracted from headers 355 return "PIX_FMT_VAAPI_MOCO"; 356 357 case PIX_FMT_VAAPI_IDCT: 358 // HW acceleration through VA API at IDCT entry-point, 359 // Picture.data[0] contains a vaapi_render_state struct which 360 // contains fields extracted from headers 361 return "PIX_FMT_VAAPI_IDCT"; 362 363 case PIX_FMT_VAAPI_VLD: 364 // HW decoding through VA API, Picture.data[0] contains a 365 // vaapi_render_state struct which contains the bitstream of the 366 // slices as well as various fields extracted from headers 367 return "PIX_FMT_VAAPI_VLD"; 368 369 default: 370 return "(unknown)"; 371 } 372} 373 374 375color_space 376pixfmt_to_colorspace(int pixFormat) 377{ 378 switch(pixFormat) { 379 default: 380 TRACE("No BE API colorspace definition for pixel format " 381 "\"%s\".\n", pixfmt_to_string(pixFormat)); 382 // Supposed to fall through. 383 case PIX_FMT_NONE: 384 return B_NO_COLOR_SPACE; 385 386 // NOTE: See pixfmt_to_colorspace() for what these are. 387 case PIX_FMT_YUV420P: 388 return B_YUV420; 389 case PIX_FMT_YUYV422: 390 return B_YUV422; 391 case PIX_FMT_RGB24: 392 return B_RGB24_BIG; 393 case PIX_FMT_BGR24: 394 return B_RGB24; 395 case PIX_FMT_YUV422P: 396 return B_YUV422; 397 case PIX_FMT_YUV444P: 398 return B_YUV444; 399 case PIX_FMT_RGB32: 400 return B_RGBA32_BIG; 401 case PIX_FMT_YUV410P: 402 return B_YUV9; 403 case PIX_FMT_YUV411P: 404 return B_YUV12; 405 case PIX_FMT_RGB565: 406 return B_RGB16_BIG; 407 case PIX_FMT_RGB555: 408 return B_RGB15_BIG; 409 case PIX_FMT_GRAY8: 410 return B_GRAY8; 411 case PIX_FMT_MONOBLACK: 412 return B_GRAY1; 413 case PIX_FMT_PAL8: 414 return B_CMAP8; 415 case PIX_FMT_BGR32: 416 return B_RGB32; 417 case PIX_FMT_BGR565: 418 return B_RGB16; 419 case PIX_FMT_BGR555: 420 return B_RGB15; 421 } 422} 423 424 425PixelFormat 426colorspace_to_pixfmt(color_space format) 427{ 428 switch(format) { 429 default: 430 case B_NO_COLOR_SPACE: 431 return PIX_FMT_NONE; 432 433 // NOTE: See pixfmt_to_colorspace() for what these are. 434 case B_YUV420: 435 return PIX_FMT_YUV420P; 436 case B_YUV422: 437 return PIX_FMT_YUV422P; 438 case B_RGB24_BIG: 439 return PIX_FMT_RGB24; 440 case B_RGB24: 441 return PIX_FMT_BGR24; 442 case B_YUV444: 443 return PIX_FMT_YUV444P; 444 case B_RGBA32_BIG: 445 case B_RGB32_BIG: 446 return PIX_FMT_BGR32; 447 case B_YUV9: 448 return PIX_FMT_YUV410P; 449 case B_YUV12: 450 return PIX_FMT_YUV411P; 451 // TODO: YCbCr color spaces! These are not the same as YUV! 452 case B_RGB16_BIG: 453 return PIX_FMT_RGB565; 454 case B_RGB15_BIG: 455 return PIX_FMT_RGB555; 456 case B_GRAY8: 457 return PIX_FMT_GRAY8; 458 case B_GRAY1: 459 return PIX_FMT_MONOBLACK; 460 case B_CMAP8: 461 return PIX_FMT_PAL8; 462 case B_RGBA32: 463 case B_RGB32: 464 return PIX_FMT_RGB32; 465 case B_RGB16: 466 return PIX_FMT_BGR565; 467 case B_RGB15: 468 return PIX_FMT_BGR555; 469 } 470} 471 472 473#define BEGIN_TAG "\033[31m" 474#define END_TAG "\033[0m" 475 476void 477dump_ffframe(AVFrame* frame, const char* name) 478{ 479 const char* picttypes[] = {"no pict type", "intra", "predicted", 480 "bidir pre", "s(gmc)-vop"}; 481 printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, " 482 " ]\n"END_TAG, 483 name, 484 frame->pts, 485 frame->coded_picture_number, 486 frame->display_picture_number, 487// frame->quality, 488 frame->key_frame?"keyframe, ":"", 489 picttypes[frame->pict_type]); 490// printf(BEGIN_TAG"\t\tlinesize[] = {%ld, %ld, %ld, %ld}\n"END_TAG, 491// frame->linesize[0], frame->linesize[1], frame->linesize[2], 492// frame->linesize[3]); 493} 494 495