Changeset 1039
- Timestamp:
- 04/03/09 17:10:18 (1 year ago)
- Files:
-
- trunk/ColorConversions.c (modified) (5 diffs)
- trunk/ColorConversions.h (modified) (1 diff)
- trunk/FFusionCodec.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ColorConversions.c
r1038 r1039 38 38 #define unlikely(x) __builtin_expect(x, 0) 39 39 #define likely(x) __builtin_expect(x, 1) 40 41 static FASTCALL void FastY420(AVFrame *picture, UInt8 *baseAddr, int outRowBytes, unsigned outWidth, unsigned outHeight)42 {43 PlanarPixmapInfoYUV420 *planar = (PlanarPixmapInfoYUV420 *)baseAddr;44 /*From Docs: PixMap baseAddr points to a big-endian PlanarPixmapInfoYUV420 struct; see ImageCodec.i. */45 46 // if ya can't set da poiners, set da offsets47 planar->componentInfoY.offset = EndianU32_NtoB(picture->data[0] - baseAddr);48 planar->componentInfoCb.offset = EndianU32_NtoB(picture->data[1] - baseAddr);49 planar->componentInfoCr.offset = EndianU32_NtoB(picture->data[2] - baseAddr);50 51 // for the 16/32 add look at EDGE in mpegvideo.c52 planar->componentInfoY.rowBytes = EndianU32_NtoB(picture->linesize[0]);53 planar->componentInfoCb.rowBytes = EndianU32_NtoB(picture->linesize[1]);54 planar->componentInfoCr.rowBytes = EndianU32_NtoB(picture->linesize[2]);55 }56 40 57 41 //Handles the last row for Y420 videos with an odd number of luma rows … … 377 361 } 378 362 379 static FASTCALL void RGB 24toRGB24(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)363 static FASTCALL void RGBtoRGB(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height, unsigned bytesPerPixel) 380 364 { 381 365 UInt8 *srcPtr = picture->data[0]; … … 384 368 385 369 for (y = 0; y < height; y++) { 386 memcpy(baseAddr, srcPtr, width * 3); 370 memcpy(baseAddr, srcPtr, width * bytesPerPixel); 371 372 baseAddr += rowBytes; 373 srcPtr += srcRB; 374 } 375 } 376 377 static FASTCALL void RGB24toRGB24(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 378 { 379 RGBtoRGB(picture, baseAddr, rowBytes, width, height, 3); 380 } 381 382 static FASTCALL void RGB16toRGB16(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 383 { 384 RGBtoRGB(picture, baseAddr, rowBytes, width, height, 2); 385 } 386 387 static FASTCALL void RGB16LEtoRGB16(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 388 { 389 UInt8 *srcPtr = picture->data[0]; 390 int srcRB = picture->linesize[0]; 391 int y, x; 392 393 for (y = 0; y < height; y++) { 394 UInt16 *oRow = (UInt16 *)baseAddr, *iRow = (UInt16 *)srcPtr; 395 for (x = 0; x < width; x++) {oRow[x] = EndianU16_LtoB(iRow[x]);} 387 396 388 397 baseAddr += rowBytes; … … 432 441 { 433 442 ClearRGB(baseAddr, rowBytes, width, height, 3); 443 } 444 445 static FASTCALL void ClearRGB16(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 446 { 447 ClearRGB(baseAddr, rowBytes, width, height, 2); 434 448 } 435 449 … … 468 482 } 469 483 470 static FASTCALL void ClearNone(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 471 { 484 OSType ColorConversionDstForPixFmt(enum PixelFormat ffPixFmt) 485 { 486 switch (ffPixFmt) { 487 case PIX_FMT_YUV420P: 488 return k2vuyPixelFormat; //disables "fast YUV" path 489 case PIX_FMT_BGR24: 490 return k24RGBPixelFormat; //XXX try k24BGRPixelFormat 491 case PIX_FMT_RGB32: // XXX not a specific pixel format 492 return k32ARGBPixelFormat; 493 case PIX_FMT_RGB24: 494 return k24RGBPixelFormat; 495 case PIX_FMT_YUV422P: 496 return k2vuyPixelFormat; 497 case PIX_FMT_YUVA420P: 498 return k4444YpCbCrA8PixelFormat; 499 case PIX_FMT_RGB555LE: 500 case PIX_FMT_RGB555BE: 501 return k16BE555PixelFormat; 502 default: 503 return 0; // error 504 } 472 505 } 473 506 474 507 int ColorConversionFindFor(ColorConversionFuncs *funcs, enum PixelFormat ffPixFmt, AVFrame *ffPicture, OSType qtPixFmt) 475 { 476 if (qtPixFmt == kYUV420CodecType && ffPixFmt == PIX_FMT_YUV420P) 477 { 478 funcs->clear = ClearNone; 479 funcs->convert = FastY420; 480 } 481 else if (qtPixFmt == k2vuyPixelFormat && ffPixFmt == PIX_FMT_YUV420P) 482 { 483 funcs->clear = ClearY422; 484 508 { 509 switch (ffPixFmt) { 510 case PIX_FMT_YUV420P: 511 funcs->clear = ClearY422; 512 485 513 #ifdef __ppc__ 486 if (IsAltivecSupported())487 funcs->convert = Y420toY422_ppc_altivec;488 else489 funcs->convert = Y420toY422_ppc_scalar;514 if (IsAltivecSupported()) 515 funcs->convert = Y420toY422_ppc_altivec; 516 else 517 funcs->convert = Y420toY422_ppc_scalar; 490 518 #else 491 //can't set this without the first real frame 492 if (ffPicture) { 493 if (ffPicture->linesize[0] % 16) 494 funcs->convert = Y420toY422_x86_scalar; 495 else 496 funcs->convert = Y420toY422_sse2; 497 } 498 #endif 499 } 500 else if (qtPixFmt == k24RGBPixelFormat && ffPixFmt == PIX_FMT_BGR24) 501 { 502 funcs->clear = ClearRGB24; 503 funcs->convert = BGR24toRGB24; 504 } 505 else if (qtPixFmt == k32ARGBPixelFormat && ffPixFmt == PIX_FMT_RGB32) 506 { 507 funcs->clear = ClearRGB32; 508 funcs->convert = RGB32toRGB32; 509 } 510 else if (qtPixFmt == k24RGBPixelFormat && ffPixFmt == PIX_FMT_RGB24) 511 { 512 funcs->clear = ClearRGB24; 513 funcs->convert = RGB24toRGB24; 514 } 515 else if (qtPixFmt == k2vuyPixelFormat && ffPixFmt == PIX_FMT_YUV422P) 516 { 517 funcs->clear = ClearY422; 518 funcs->convert = Y422toY422; 519 } 520 else if (qtPixFmt == k4444YpCbCrA8PixelFormat && ffPixFmt == PIX_FMT_YUVA420P) 521 { 522 funcs->clear = ClearV408; 523 funcs->convert = YA420toV408; 524 } 525 else 526 { 527 return paramErr; 519 //can't set this without the first real frame 520 if (ffPicture) { 521 if (ffPicture->linesize[0] % 16) 522 funcs->convert = Y420toY422_x86_scalar; 523 else 524 funcs->convert = Y420toY422_sse2; 525 } 526 #endif 527 break; 528 case PIX_FMT_BGR24: 529 funcs->clear = ClearRGB24; 530 funcs->convert = BGR24toRGB24; 531 break; 532 case PIX_FMT_RGB32: 533 funcs->clear = ClearRGB32; 534 funcs->convert = RGB32toRGB32; 535 break; 536 case PIX_FMT_RGB24: 537 funcs->clear = ClearRGB24; 538 funcs->convert = RGB24toRGB24; 539 break; 540 case PIX_FMT_YUV422P: 541 funcs->clear = ClearY422; 542 funcs->convert = Y422toY422; 543 break; 544 case PIX_FMT_YUVA420P: 545 funcs->clear = ClearV408; 546 funcs->convert = YA420toV408; 547 break; 548 case PIX_FMT_RGB555LE: 549 funcs->clear = ClearRGB16; 550 funcs->convert = RGB16LEtoRGB16; 551 break; 552 case PIX_FMT_RGB555BE: 553 funcs->clear = ClearRGB16; 554 funcs->convert = RGB16toRGB16; 555 break; 556 default: 557 return paramErr; 528 558 } 529 559 trunk/ColorConversions.h
r1038 r1039 40 40 } ColorConversionFuncs; 41 41 42 extern OSType ColorConversionDstForPixFmt(enum PixelFormat ffPixFmt); 42 43 extern int ColorConversionFindFor(ColorConversionFuncs *funcs, enum PixelFormat ffPixFmt, AVFrame *ffPicture, OSType qtPixFmt); trunk/FFusionCodec.c
r1036 r1039 118 118 AVCodecContext *avContext; 119 119 OSType componentType; 120 char hasy420;121 120 FILE *fileLog; 122 121 AVFrame lastDisplayedFrame; … … 317 316 ComponentResult err; 318 317 ComponentDescription descout; 319 ComponentDescription cd;320 Component c = 0;321 long bitfield;322 323 cd.componentType = 'imdc';324 cd.componentSubType = 'y420';325 cd.componentManufacturer = 0;326 cd.componentFlags = 0;327 cd.componentFlagsMask = 0;328 318 329 319 GetComponentInfo((Component)self, &descout, 0, 0, 0); … … 349 339 glob->pixelTypes = NewHandle(10 * sizeof(OSType)); 350 340 glob->avCodec = 0; 351 glob->hasy420 = 0;352 341 glob->componentType = descout.componentSubType; 353 342 glob->packedType = PACKED_ALL_IN_FIRST_FRAME; //Unless we have reason to believe otherwise. … … 360 349 } 361 350 glob->shouldUseReturnedFrame = 0; 362 363 // c = FindNextComponent(c, &cd);364 365 if (c != 0)366 {367 Gestalt(gestaltSystemVersion, &bitfield);368 369 if (bitfield >= 0x1010)370 {371 // Codecprintf(glob->fileLog, "Use speedy y420 component\n");372 glob->hasy420 = 1;373 }374 }375 else376 {377 // Codecprintf(glob->fileLog, "Use slow y420 component\n");378 }379 351 380 352 // Open and target an instance of the base decompressor as we delegate … … 875 847 capabilities->wantedPixelSize = 0; 876 848 877 // Type of pixels used in output878 // If QuickTime got the y420 component it is cool879 // since libavcodec ouputs y420880 // If not we'll do some king of conversion to 2vuy881 882 849 HLock(glob->pixelTypes); 883 850 pos = *((OSType **)glob->pixelTypes); … … 886 853 887 854 if (!err) { 888 switch (glob->avContext->pix_fmt) 889 { 890 case PIX_FMT_BGR24: 891 pos[index++] = k24RGBPixelFormat; 892 break; 893 case PIX_FMT_RGB32: 894 pos[index++] = k32ARGBPixelFormat; 895 break; 896 case PIX_FMT_RGB24: 897 pos[index++] = k24RGBPixelFormat; 898 break; 899 case PIX_FMT_YUVA420P: 900 pos[index++] = k4444YpCbCrA8PixelFormat; 901 break; 902 case PIX_FMT_YUV420P: 903 default: 904 if (glob->hasy420) 905 { 906 pos[index++] = 'y420'; 907 } 908 else 909 { 910 pos[index++] = k2vuyPixelFormat; 911 } 912 break; 913 } 855 OSType qtPixFmt = ColorConversionDstForPixFmt(glob->avContext->pix_fmt); 856 857 /* 858 an error here means either 859 1) a color converter for this format isn't implemented 860 2) we know QT doesn't like this format and will give us argb 32bit instead 861 862 in the case of 2 we have to special-case bail right here, since errors 863 in BeginBand are ignored 864 */ 865 if (qtPixFmt) 866 pos[index++] = qtPixFmt; 867 else 868 err = featureUnsupported; 914 869 } 915 870 … … 1018 973 1019 974 if (!glob->avContext) { 1020 fprintf(stderr, "Perian: QT tried to call BeginBand without preflighting!\n");975 Codecprintf(glob->fileLog, "Perian: QT tried to call BeginBand without preflighting!\n"); 1021 976 return internalComponentErr; 977 } 978 979 if (p->frameNumber == 0 && myDrp->pixelFormat != ColorConversionDstForPixFmt(glob->avContext->pix_fmt)) { 980 Codecprintf(glob->fileLog, "QT gave us unwanted pixelFormat %s (%08x), this will not work\n", FourCCString(myDrp->pixelFormat), myDrp->pixelFormat); 1022 981 } 1023 982 … … 1365 1324 if (!glob->colorConv.clear) { 1366 1325 err = ColorConversionFindFor(&glob->colorConv, glob->avContext->pix_fmt, NULL, myDrp->pixelFormat); 1367 1368 1326 if (err) goto err; 1369 1327 } … … 1381 1339 if (!glob->colorConv.convert) { 1382 1340 err = ColorConversionFindFor(&glob->colorConv, glob->avContext->pix_fmt, picture, myDrp->pixelFormat); 1383 1384 if (err) { 1385 Codecprintf(glob->fileLog, "Unsupported conversion from pixel format %d to %s (%08x) buffer\n", 1386 glob->avContext->pix_fmt, FourCCString(myDrp->pixelFormat), myDrp->pixelFormat); 1387 goto err; 1388 } 1341 if (err) goto err; 1389 1342 } 1390 1343
