Changeset 1039

Show
Ignore:
Timestamp:
04/03/09 17:10:18 (1 year ago)
Author:
astrange
Message:

* Remove fast y420 path that never worked.
* Merge code dealing with ff->qt pixel format conversions.
* Add RGB16 LE -> RGB16 BE conversion.
(fixes mphq sample V-codecs/tscc/TI_1_Einfuehrung.avi)
* Get rid of a direct call to fprintf() and some other pointless repetitive logging.
* Bail when possible if a codec returns a PixelFormat? we can't handle.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ColorConversions.c

    r1038 r1039  
    3838#define unlikely(x) __builtin_expect(x, 0) 
    3939#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 offsets 
    47     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.c 
    52     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 } 
    5640 
    5741//Handles the last row for Y420 videos with an odd number of luma rows 
     
    377361} 
    378362 
    379 static FASTCALL void RGB24toRGB24(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height
     363static FASTCALL void RGBtoRGB(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height, unsigned bytesPerPixel
    380364{ 
    381365        UInt8 *srcPtr = picture->data[0]; 
     
    384368         
    385369        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 
     377static FASTCALL void RGB24toRGB24(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 
     378
     379        RGBtoRGB(picture, baseAddr, rowBytes, width, height, 3); 
     380
     381 
     382static FASTCALL void RGB16toRGB16(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 
     383
     384        RGBtoRGB(picture, baseAddr, rowBytes, width, height, 2); 
     385
     386 
     387static 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]);} 
    387396                 
    388397                baseAddr += rowBytes; 
     
    432441{ 
    433442        ClearRGB(baseAddr, rowBytes, width, height, 3); 
     443} 
     444 
     445static FASTCALL void ClearRGB16(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 
     446{ 
     447        ClearRGB(baseAddr, rowBytes, width, height, 2); 
    434448} 
    435449 
     
    468482} 
    469483 
    470 static FASTCALL void ClearNone(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height) 
    471 
     484OSType 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        } 
    472505} 
    473506 
    474507int 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                         
    485513#ifdef __ppc__ 
    486                 if (IsAltivecSupported()) 
    487                         funcs->convert = Y420toY422_ppc_altivec; 
    488                 else 
    489                         funcs->convert = Y420toY422_ppc_scalar; 
     514                       if (IsAltivecSupported()) 
     515                               funcs->convert = Y420toY422_ppc_altivec; 
     516                       else 
     517                               funcs->convert = Y420toY422_ppc_scalar; 
    490518#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; 
    528558        } 
    529559         
  • trunk/ColorConversions.h

    r1038 r1039  
    4040} ColorConversionFuncs; 
    4141 
     42extern OSType ColorConversionDstForPixFmt(enum PixelFormat ffPixFmt); 
    4243extern int ColorConversionFindFor(ColorConversionFuncs *funcs, enum PixelFormat ffPixFmt, AVFrame *ffPicture, OSType qtPixFmt); 
  • trunk/FFusionCodec.c

    r1036 r1039  
    118118    AVCodecContext      *avContext; 
    119119    OSType                      componentType; 
    120     char                        hasy420; 
    121120        FILE                    *fileLog; 
    122121        AVFrame                 lastDisplayedFrame; 
     
    317316    ComponentResult err; 
    318317    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; 
    328318     
    329319    GetComponentInfo((Component)self, &descout, 0, 0, 0); 
     
    349339        glob->pixelTypes = NewHandle(10 * sizeof(OSType)); 
    350340        glob->avCodec = 0; 
    351         glob->hasy420 = 0; 
    352341        glob->componentType = descout.componentSubType; 
    353342                glob->packedType = PACKED_ALL_IN_FIRST_FRAME;  //Unless we have reason to believe otherwise. 
     
    360349                } 
    361350                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         else 
    376         { 
    377   //          Codecprintf(glob->fileLog, "Use slow y420 component\n"); 
    378         } 
    379351                 
    380352        // Open and target an instance of the base decompressor as we delegate 
     
    875847    capabilities->wantedPixelSize = 0; 
    876848     
    877     // Type of pixels used in output 
    878     // If QuickTime got the y420 component it is cool 
    879     // since libavcodec ouputs y420 
    880     // If not we'll do some king of conversion to 2vuy 
    881      
    882849    HLock(glob->pixelTypes); 
    883850    pos = *((OSType **)glob->pixelTypes); 
     
    886853         
    887854        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; 
    914869        } 
    915870     
     
    1018973         
    1019974        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"); 
    1021976                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); 
    1022981        } 
    1023982         
     
    13651324                        if (!glob->colorConv.clear) { 
    13661325                                err = ColorConversionFindFor(&glob->colorConv, glob->avContext->pix_fmt, NULL, myDrp->pixelFormat); 
    1367                                  
    13681326                                if (err) goto err; 
    13691327                        } 
     
    13811339        if (!glob->colorConv.convert) { 
    13821340                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; 
    13891342        } 
    13901343