Changeset 887

Show
Ignore:
Timestamp:
05/22/08 16:45:06 (6 months ago)
Author:
astrange
Message:

Merge trunk to 1.1 branch.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/perian-1.1

    • Property svn:externals changed from
      ffmpeg -r11099 svn://svn.mplayerhq.hu/ffmpeg/trunk
      libebml -r1297 http://svn.matroska.org/svn/matroska/trunk/libebml
      libmatroska -r1297 http://svn.matroska.org/svn/matroska/trunk/libmatroska
      a52codec -r61 http://svn.cod3r.com/a52codec/trunk
      to
      ffmpeg -r 13239 svn://svn.mplayerhq.hu/ffmpeg/trunk
      libebml -r 1306 https://services.corecodec.com/svn/matroska/trunk/libebml
      libmatroska -r 1306 https://services.corecodec.com/svn/matroska/trunk/libmatroska
      a52codec -r 64 http://svn.cod3r.com/a52codec/trunk
  • branches/perian-1.1/CAPublicUtility/CAStreamBasicDescription.cpp

    r741 r887  
    5050        #include <Endian.h> 
    5151#endif 
    52  
    53 #import "CodecIDs.h" 
    5452 
    5553const AudioStreamBasicDescription       CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
     
    274272                 
    275273                case kAudioFormatAC3: 
    276                 case kAudioFormatAC3MS: 
    277274                        strcpy(outName, "AC-3"); 
    278275                        break; 
  • branches/perian-1.1/Codecprintf.c

    r332 r887  
    1515#ifdef DEBUG_BUILD 
    1616#define CODEC_HEADER                    "Perian Codec: " 
     17#define FILELOG 
    1718 
    1819static int Codecvprintf(FILE *fileLog, const char *format, va_list va, int print_header) 
     
    2425        { 
    2526                if(print_header) 
    26                         fprintf(glob->fileLog, CODEC_HEADER); 
     27                        fprintf(fileLog, CODEC_HEADER); 
    2728                ret = vfprintf(fileLog, format, va); 
    28                 fflush(glob->fileLog); 
     29                fflush(fileLog); 
    2930        } 
    3031        else 
     
    4748        va_list va; 
    4849        va_start(va, format); 
    49         ret = Codecvprintf(fileLog, format, va, 1); 
     50        ret = Codecvprintf(fileLog, format, va, !fileLog); 
    5051        va_end(va); 
    5152        return ret; 
    5253} 
    5354 
    54 void FourCCprintf (char *string, unsigned long a
     55const char *FourCCString(FourCharCode c
    5556{ 
    56     if (a < 64) 
    57     { 
    58         Codecprintf(NULL, "%s%ld\n", string, a); 
    59     } 
    60     else 
    61     { 
    62         Codecprintf(NULL, "%s%c%c%c%c\n", string, 
    63                            (unsigned char)((a >> 24) & 0xff),  
    64                            (unsigned char)((a >> 16) & 0xff),  
    65                            (unsigned char)((a >> 8) & 0xff),  
    66                            (unsigned char)(a & 0xff)); 
    67     } 
     57    static unsigned char fourcc[5] = {0}; 
     58    int i; 
     59     
     60    for (i = 0; i < 4; i++) fourcc[i] = c >> 8*(3-i); 
     61     
     62    return (char*)fourcc; 
    6863} 
     64 
     65void FourCCprintf (char *string, FourCharCode a) 
     66{ 
     67    Codecprintf(NULL, "%s%s\n", string, FourCCString(a)); 
     68} 
     69 
    6970#else 
    7071#define Codecvprintf(file, fmt, va, print_header) /**/ 
  • branches/perian-1.1/Codecprintf.h

    r214 r887  
    1414#ifdef DEBUG_BUILD 
    1515int Codecprintf(FILE *, const char *format, ...); 
    16 void FourCCprintf(char *string, unsigned long a); 
     16void FourCCprintf(char *string, FourCharCode a); 
     17const char *FourCCString(FourCharCode c); 
    1718#else 
    1819#define Codecprintf(file, fmt, ...) /**/ 
  • branches/perian-1.1/ColorConversions.c

    r629 r887  
    2424#include <sys/sysctl.h> 
    2525 
     26#ifndef GOOD_COMPILER 
     27#define noinline __attribute__((noinline)) 
     28#else 
     29#define noinline 
     30#endif 
     31 
     32#define unlikely(x) __builtin_expect(x, 0) 
     33 
    2634//----------------------------------------------------------------- 
    2735// FastY420 
     
    5866// have a decent OS/QT version. 
    5967//----------------------------------------------------------------- 
     68 
     69static void noinline Y420toY422_lastrow(UInt8 *o, const UInt8 *yc, const UInt8 *uc, const UInt8 *vc, unsigned halfWidth) 
     70{ 
     71        unsigned x; 
     72        for(x=0; x < halfWidth; x++) 
     73        { 
     74                unsigned x4 = x*4, x2 = x*2; 
     75                o[x4] = uc[x]; 
     76                o[x4+1] = yc[x2]; 
     77                o[x4+2] = vc[x]; 
     78                o[x4+3] = yc[x2+1]; 
     79        } 
     80} 
     81 
     82#define HandleLastRow(o, yc, uc, vc, halfWidth, height) if (unlikely(height & 1)) Y420toY422_lastrow(o, yc, uc, vc, halfWidth) 
    6083 
    6184#ifdef __BIG_ENDIAN__ 
     
    104127                 baseAddr += outRB * 2; 
    105128         } 
     129         
     130        HandleLastRow(baseAddr, inY, inU, inV, halfWidth, height); 
    106131 } 
    107132 
     
    154179                vc += rV; 
    155180        } 
     181         
     182        HandleLastRow(o, yc, uc, vc, width / 2, height); 
    156183} 
    157184 
     
    186213                __m128i * uv = (__m128i*)uc,* vv  = (__m128i*)vc; 
    187214                 
     215#if 0 
     216                asm volatile( 
     217                        "\n0:                   \n\t" 
     218                        "movdqa         (%2),   %%xmm0  \n\t" 
     219                        "movdqa         16(%2), %%xmm2  \n\t" 
     220                        "movdqa         (%3),           %%xmm1  \n\t" 
     221                        "movdqa         16(%3), %%xmm3  \n\t" 
     222                        "movdqu         (%4),   %%xmm4  \n\t" 
     223                        "movdqu         (%5),   %%xmm5  \n\t" 
     224                        "addl           $32,    %2              \n\t" 
     225                        "addl           $32,    %3              \n\t" 
     226                        "addl           $16,    %4              \n\t" 
     227                        "addl           $16,    %5              \n\t" 
     228                        "movdqa         %%xmm4, %%xmm6  \n\t" 
     229                        "punpcklbw      %%xmm5, %%xmm4  \n\t" /*chroma_l*/ 
     230                        "punpckhbw      %%xmm5, %%xmm6  \n\t" /*chroma_h*/ 
     231                        "movdqa         %%xmm4, %%xmm5  \n\t" 
     232                        "punpcklbw      %%xmm0, %%xmm5  \n\t" 
     233                        "movntdq        %%xmm5, (%0)    \n\t" /*ov[x4]*/ 
     234                        "movdqa         %%xmm4, %%xmm5  \n\t" 
     235                        "punpckhbw      %%xmm0, %%xmm5  \n\t" 
     236                        "movntdq        %%xmm5, 16(%0)  \n\t" /*ov[x4+1]*/ 
     237                        "movdqa         %%xmm6, %%xmm5  \n\t" 
     238                        "punpcklbw      %%xmm2, %%xmm5  \n\t" 
     239                        "movntdq        %%xmm5, 32(%0)  \n\t" /*ov[x4+2]*/ 
     240                        "movdqa         %%xmm6, %%xmm5  \n\t" 
     241                        "punpckhbw      %%xmm2, %%xmm5  \n\t" 
     242                        "movntdq        %%xmm5, 48(%0)  \n\t" /*ov[x4+3]*/ 
     243                        "addl           $64,    %0              \n\t" 
     244                        "movdqa         %%xmm4, %%xmm5  \n\t" 
     245                        "punpcklbw      %%xmm1, %%xmm5  \n\t" 
     246                        "movntdq        %%xmm5, (%1)    \n\t" /*ov2[x4]*/ 
     247                        "punpckhbw      %%xmm1, %%xmm4  \n\t" 
     248                        "movntdq        %%xmm4, 16(%1)  \n\t" /*ov2[x4+1]*/ 
     249                        "movdqa         %%xmm6, %%xmm5  \n\t" 
     250                        "punpcklbw      %%xmm3, %%xmm5  \n\t" 
     251                        "movntdq        %%xmm5, 32(%1)  \n\t" /*ov2[x4+2]*/ 
     252                        "punpckhbw      %%xmm3, %%xmm6  \n\t" 
     253                        "movntdq        %%xmm6, 48(%1)  \n\t" /*ov2[x4+3]*/ 
     254                        "addl           $64,    %1              \n\t" 
     255                        "dec            %6                              \n\t" 
     256                        "jnz            0b                              \n\t" 
     257                        : "+r" (ov), "+r" (ov2), 
     258                        "+r" (yv), "+r" (yv2), "+r" (uv), "+r" (vv) 
     259                        : "r" (vWidth) 
     260                        ); 
     261#else 
    188262                for (x = 0; x < vWidth; x++) { 
    189263                        unsigned x2 = x*2, x4 = x*4; 
     
    205279                        _mm_stream_si128(&ov2[x4+3],_mm_unpackhi_epi8(chroma_h, tmp_y4)); 
    206280                } 
    207                  
    208                 for (x = x * 16; x < halfwidth; x++) { 
     281#endif 
     282 
     283                for (x=vWidth * 16; x < halfwidth; x++) { 
    209284                        unsigned x4 = x*4, x2 = x*2; 
    210285                        o2[x4] = o[x4] = uc[x]; 
     
    221296                vc += rV; 
    222297        } 
    223 
    224  
    225  
    226 static void __attribute__((noinline)) Y420toY422_x86_scalar(UInt8 * o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 
     298         
     299        _mm_sfence(); 
     300         
     301        HandleLastRow(o, yc, uc, vc, halfwidth, height); 
     302
     303 
     304 
     305static void noinline Y420toY422_x86_scalar(UInt8 * o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 
    227306{ 
    228307        UInt8           *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2]; 
     
    248327                v += rV; 
    249328        } 
     329 
     330        HandleLastRow(o, yc, u, v, halfwidth, height); 
    250331} 
    251332 
     
    255336 
    256337        //make sure the ffmpeg picture buffers are aligned enough, they're only guaranteed to be 8-byte for some reason... 
    257         if ((yc | picture->linesize[0]) % 16 == 0) { 
    258                 Y420toY422_sse2(o, outRB, width, height, picture); 
    259                 _mm_sfence(); 
    260         } else Y420toY422_x86_scalar(o, outRB, width, height, picture); 
     338        if (!unlikely((yc | picture->linesize[0]) % 16)) Y420toY422_sse2(o, outRB, width, height, picture);  
     339        else Y420toY422_x86_scalar(o, outRB, width, height, picture); 
    261340} 
    262341#endif 
     342 
     343void YA420toV408(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 
     344{ 
     345        UInt8          *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2], *a = picture->data[3]; 
     346        unsigned       rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2], rA = picture->linesize[3], y, x; 
     347         
     348        for (y = 0; y < height; y++) { 
     349                for (x = 0; x < width; x++) { 
     350                        o[x*4] = u[x/2]; 
     351                        o[x*4+1] = yc[x]; 
     352                        o[x*4+2] = v[x/2]; 
     353                        o[x*4+3] = a[x]; 
     354                } 
     355                 
     356                o += outRB; 
     357                yc += rY; 
     358                a += rA; 
     359                if (y & 1) { 
     360                        u += rU; 
     361                        v += rV; 
     362                } 
     363        } 
     364} 
    263365 
    264366void BGR24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture) 
     
    266368        unsigned i, j; 
    267369        UInt8 *srcPtr = picture->data[0]; 
    268         unsigned width_third = width / 3; 
    269370         
    270371        for (i = 0; i < height; ++i) 
    271372        { 
    272                 for (j = 0; j < width_third; j ++) 
     373                for (j = 0; j < width; j ++) 
    273374                { 
    274375                        unsigned j3 = j * 3; 
     
    301402} 
    302403 
     404void RGB24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture) 
     405{ 
     406        unsigned y; 
     407        UInt8 *srcPtr = picture->data[0]; 
     408         
     409        for (y = 0; y < height; y++) { 
     410                memcpy(baseAddr, srcPtr, width * 3); 
     411                 
     412                baseAddr += rowBytes; 
     413                srcPtr += picture->linesize[0]; 
     414        } 
     415} 
     416 
    303417void Y422toY422(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 
    304418{ 
  • branches/perian-1.1/ColorConversions.h

    r344 r887  
    2323extern void FastY420(UInt8 *baseAddr, AVFrame *picture); 
    2424extern void Y420toY422(UInt8* baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame * picture); 
     25extern void YA420toV408(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture); 
    2526extern void RGB32toRGB32(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture); 
     27extern void RGB24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture); 
    2628extern void BGR24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture); 
    2729extern void Y422toY422(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture); 
  • branches/perian-1.1/CommonUtils.c

    r761 r887  
    286286        return 0; 
    287287} 
     288 
     289int IsFrameDroppingEnabled() 
     290{ 
     291        static int enabled = -1; 
     292         
     293        if (enabled == -1) enabled = getenv("PerianNoFrameDropping") == NULL; 
     294         
     295        return enabled; 
     296} 
  • branches/perian-1.1/CommonUtils.h

    r585 r887  
    3939int isImageDescriptionExtensionPresent(ImageDescriptionHandle desc, long type); 
    4040 
     41int IsFrameDroppingEnabled(); 
     42 
    4143#ifdef __cplusplus 
    4244} 
  • branches/perian-1.1/FFissionCodec/FFissionCodec.cpp

    r525 r887  
    2525#include "FFissionCodec.h" 
    2626 
    27 extern "C" void initLib(); 
     27extern "C" void init_FFmpeg(); 
    2828 
    2929FFissionCodec::FFissionCodec(UInt32 inInputBufferByteSize) : ACSimpleCodec(inInputBufferByteSize) 
    3030{ 
    31         initLib(); 
     31        init_FFmpeg(); 
    3232         
    3333        avContext = avcodec_alloc_context(); 
  • branches/perian-1.1/FFusionCodec.c

    r805 r887  
    6262        bool            used; 
    6363        long            frameNumber; 
     64        AVFrame         returnedFrame; 
    6465} FFusionBuffer; 
    6566 
     
    8990        long                    lastFrame; 
    9091        FFusionBuffer   *futureBuffer; 
     92}; 
     93 
     94struct per_frame_decode_stats 
     95{ 
     96        unsigned                begin_calls; 
     97        unsigned                decode_calls; 
     98        unsigned                draw_calls; 
     99        unsigned                end_calls; 
     100}; 
     101 
     102struct decode_stats 
     103{ 
     104        struct per_frame_decode_stats type[4]; 
     105        int             max_frames_begun; 
     106        int             max_frames_decoded; 
    91107}; 
    92108 
     
    108124        int                             lastAllocatedBuffer;            // the index of the buffer which was last allocated  
    109125                                                                                                // by the codec (and is the latest in decode order)      
     126        int                             shouldUseReturnedFrame; 
    110127        struct begin_glob       begin; 
    111128        FFusionData             data; 
    112129        struct decode_glob      decode; 
     130        struct decode_stats stats; 
    113131} FFusionGlobalsRecord, *FFusionGlobals; 
    114132 
     
    132150//--------------------------------------------------------------------------- 
    133151 
    134 static OSErr FFusionDecompress(AVCodecContext *context, UInt8 *dataPtr, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture, long length); 
     152static OSErr FFusionDecompress(FFusionGlobals glob, AVCodecContext *context, UInt8 *dataPtr, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture, long length); 
    135153static int FFusionGetBuffer(AVCodecContext *s, AVFrame *pic); 
    136154static void FFusionReleaseBuffer(AVCodecContext *s, AVFrame *pic); 
     
    143161void ChangeHintText(int value, ControlRef staticTextField); 
    144162 
    145 extern void initLib(); 
     163extern void init_FFmpeg(); 
    146164extern CFMutableStringRef GetHomeDirectory(); 
     165 
     166#define FFusionDebugPrint(x...) if (glob->fileLog) Codecprintf(glob->fileLog, x); 
     167#define not(x) ((x) ? "" : "not ") 
    147168 
    148169//--------------------------------------------------------------------------- 
     
    165186#include <QuickTime/ComponentDispatchHelper.c> 
    166187 
    167 void *launchUpdateChecker(void *args) 
     188static void *launchUpdateChecker(void *args) 
    168189{ 
    169190        FSRef *ref = (FSRef *)args; 
     
    209230} 
    210231 
     232static void RecomputeMaxCounts(FFusionGlobals glob) 
     233{ 
     234        int i; 
     235        unsigned begun = 0, decoded = 0, ended = 0, drawn = 0; 
     236         
     237        for (i = 0; i < 4; i++) { 
     238                struct per_frame_decode_stats *f = &glob->stats.type[i]; 
     239                 
     240                begun += f->begin_calls; 
     241                decoded += f->decode_calls; 
     242                drawn += f->draw_calls; 
     243                ended += f->end_calls; 
     244        } 
     245         
     246        signed begin_diff = begun - ended, decode_diff = decoded - drawn; 
     247         
     248        if (abs(begin_diff) > glob->stats.max_frames_begun) glob->stats.max_frames_begun = begin_diff; 
     249        if (abs(decode_diff) > glob->stats.max_frames_decoded) glob->stats.max_frames_decoded = decode_diff; 
     250} 
     251 
     252static void DumpFrameDropStats(FFusionGlobals glob) 
     253{ 
     254        static const char types[4] = {'?', 'I', 'P', 'B'}; 
     255        int i; 
     256         
     257        if (!glob->fileLog || glob->decode.lastFrame == 0) return; 
     258         
     259        Codecprintf(glob->fileLog, "Type\t| BeginBand\t| DecodeBand\t| DrawBand\t| dropped before decode\t| dropped before draw\n"); 
     260         
     261        for (i = 0; i < 4; i++) { 
     262                struct per_frame_decode_stats *f = &glob->stats.type[i]; 
     263                                 
     264                Codecprintf(glob->fileLog, "%c\t| %d\t\t| %d\t\t| %d\t\t| %d/%f%%\t\t| %d/%f%%\n", types[i], f->begin_calls, f->decode_calls, f->draw_calls, 
     265                                        f->begin_calls - f->decode_calls,(f->begin_calls > f->decode_calls) ? ((float)(f->begin_calls - f->decode_calls)/(float)f->begin_calls) * 100. : 0., 
     266                                        f->decode_calls - f->draw_calls,(f->decode_calls > f->draw_calls) ? ((float)(f->decode_calls - f->draw_calls)/(float)f->decode_calls) * 100. : 0.); 
     267        } 
     268} 
     269 
    211270//--------------------------------------------------------------------------- 
    212271// Component Routines 
     
    241300         
    242301  //  FourCCprintf("Opening component for type ", descout.componentSubType); 
    243          
    244302    // Allocate memory for our globals, set them up and inform the component manager that we've done so 
    245303         
     
    264322                glob->data.frames = NULL; 
    265323                glob->begin.parser = NULL; 
    266 #ifdef FILELOG 
    267                 glob->fileLog = fopen("/tmp/perian.log", "a"); 
    268 #else 
    269                 glob->fileLog = NULL; 
    270 #endif 
     324                if (getenv("PerianDebugLogging")) glob->fileLog = fopen("/tmp/perian.log", "a"); 
     325                else glob->fileLog = NULL; 
     326                glob->shouldUseReturnedFrame = 0; 
    271327                 
    272328//        c = FindNextComponent(c, &cd); 
     
    306362    } 
    307363     
     364    FFusionDebugPrint("%p opened for '%s'\n", glob, FourCCString(glob->componentType)); 
    308365    return err; 
    309366} 
     
    315372pascal ComponentResult FFusionCodecClose(FFusionGlobals glob, ComponentInstance self) 
    316373{ 
     374    FFusionDebugPrint("%p closed.\n", glob); 
     375        DumpFrameDropStats(glob); 
     376 
    317377    // Make sure to close the base component and deallocate our storage 
    318      
    319378    if (glob)  
    320379    { 
     
    417476pascal ComponentResult FFusionCodecInitialize(FFusionGlobals glob, ImageSubCodecDecompressCapabilities *cap) 
    418477{ 
     478        Boolean doExperimentalFlags = getenv("PerianExperimentalQTFlags") != NULL; 
    419479         
    420480    // Secifies the size of the ImageSubCodecDecompressRecord structure 
     
    433493                cap->subCodecSupportsOutOfOrderDisplayTimes = true; 
    434494                cap->baseCodecShouldCallDecodeBandForAllFrames = true; 
    435                 cap->subCodecSupportsScheduledBackwardsPlaybackWithDifferenceFrames = true; 
    436                  
    437         //  XXX enabling this seems to cause rare visible artifacts in h.264? 
    438         //      cap->subCodecSupportsDrawInDecodeOrder = true;  
     495                cap->subCodecSupportsScheduledBackwardsPlaybackWithDifferenceFrames = !doExperimentalFlags; 
     496                cap->subCodecSupportsDrawInDecodeOrder = doExperimentalFlags;  
    439497                cap->subCodecSupportsDecodeSmoothing = true;  
    440498        } 
     
    468526    // to the fourCC if it has not been done before 
    469527     
     528        FFusionDebugPrint("%p Preflight called.\n", glob); 
     529         
    470530    if (!glob->avCodec) 
    471531    { 
    472532                enum CodecID codecID = CODEC_ID_MPEG4; 
    473533                 
    474                 initLib(); 
     534                init_FFmpeg(); 
    475535                initFFusionParsers(); 
    476536                 
     
    577637                        case 'VP30': 
    578638                        case 'VP31': 
     639                                glob->shouldUseReturnedFrame = TRUE; 
    579640                                codecID = CODEC_ID_VP3; 
    580641                                break; 
     
    612673                codecID = CODEC_ID_NUV; 
    613674                break; 
    614  
     675                        case 'tscc': 
     676                                codecID = CODEC_ID_TSCC; 
     677                                break; 
     678                                 
     679                        case 'ZMBV': 
     680                                codecID = CODEC_ID_ZMBV; 
     681                                break; 
     682                                 
     683                        case 'VP6A': 
     684                                codecID = CODEC_ID_VP6A; 
     685                                break; 
    615686                                 
    616687            default: 
     
    622693                        glob->begin.parser = ffusionParserInit(codecID); 
    623694                 
     695                if ((codecID == CODEC_ID_MPEG4 || codecID == CODEC_ID_H264) && !glob->begin.parser) 
     696                        Codecprintf(glob->fileLog, "This is a parseable format, but we couldn't open a parser!\n"); 
     697                 
    624698        // we do the same for the AVCodecContext since all context values are 
    625699        // correctly initialized when calling the alloc function 
     
    634708        glob->avContext->width = (**p->imageDescription).width; 
    635709        glob->avContext->height = (**p->imageDescription).height; 
     710                glob->avContext->bits_per_sample = (**p->imageDescription).depth; 
    636711                 
    637712        // We also pass the FourCC since it allows the H263 hybrid decoder 
     
    686761                } 
    687762                 
     763                FFusionDebugPrint("%p preflighted for %dx%d '%s'. (%d bytes of extradata)\n", glob, (**p->imageDescription).width, (**p->imageDescription).height, FourCCString(glob->componentType), glob->avContext->extradata_size); 
     764         
    688765                if(glob->avContext->extradata_size != 0 && glob->begin.parser != NULL) 
    689766                        ffusionParseExtraData(glob->begin.parser, glob->avContext->extradata, glob->avContext->extradata_size); 
     
    757834                case PIX_FMT_RGB32: 
    758835                        pos[index++] = k32ARGBPixelFormat; 
     836                        break; 
     837                case PIX_FMT_RGB24: 
     838                        pos[index++] = k24RGBPixelFormat; 
     839                        break; 
     840                case PIX_FMT_YUVA420P: 
     841                        pos[index++] = k4444YpCbCrA8PixelFormat; 
    759842                        break; 
    760843                case PIX_FMT_YUV420P: 
     
    786869        capabilities->flags |= codecCanAsync | codecCanAsyncWhen; 
    787870         
     871        FFusionDebugPrint("%p Preflight requesting colorspace '%s'. (error %d)\n", glob, FourCCString(pos[0]), err); 
     872         
    788873    return err; 
    789874} 
     
    796881                        return kCodecFrameTypeKey; 
    797882        } 
    798         else if(skippable
     883        else if(skippable && IsFrameDroppingEnabled()
    799884                return kCodecFrameTypeDroppableDifference; 
    800885        else if(fftype != 0) 
     
    822907    FFusionDecompressRecord *myDrp = (FFusionDecompressRecord *)drp->userDecompressRecord; 
    823908        int redisplayFirstFrame = 0; 
     909        int type = 0; 
     910        int skippable = 0; 
    824911         
    825912    ////// 
     
    847934        myDrp->frameData = NULL; 
    848935        myDrp->buffer = NULL; 
     936         
     937        FFusionDebugPrint("%p BeginBand #%d. (%sdecoded, packed %d)\n", glob, p->frameNumber, not(myDrp->decoded), glob->packedType); 
    849938         
    850939        if (!glob->avContext) { 
     
    897986        { 
    898987                int parsedBufSize; 
    899                 int type = 0; 
    900                 int skippable = 0; 
    901988                uint8_t *buffer = (uint8_t *)drp->codecData; 
    902989                int bufferSize = p->bufferSize; 
     
    9211008                        else 
    9221009                        { 
    923                                 Codecprintf(NULL, "parse failed frame %d with size %d\n", p->frameNumber, bufferSize); 
     1010                                Codecprintf(glob->fileLog, "parse failed frame %d with size %d\n", p->frameNumber, bufferSize); 
    9241011                                if(glob->data.unparsedFrames.dataSize != 0) 
    925                                         Codecprintf(NULL, ", parser had extra data\n");                                
     1012                                        Codecprintf(glob->fileLog, ", parser had extra data\n");                               
    9261013                        } 
    9271014                } 
     
    10121099        myDrp->frameNumber = p->frameNumber; 
    10131100        myDrp->GOPStartFrameNumber = glob->begin.lastIFrame; 
     1101         
     1102        glob->stats.type[drp->frameType].begin_calls++; 
     1103        RecomputeMaxCounts(glob); 
     1104        FFusionDebugPrint("%p BeginBand: frame #%d type %d. (%sskippable)\n", glob, myDrp->frameNumber, type, not(skippable)); 
     1105         
    10141106    return noErr; 
    10151107} 
    10161108 
    1017 static OSErr PrereqDecompress(FrameData *prereq, AVCodecContext *context, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture) 
    1018 
     1109static OSErr PrereqDecompress(FFusionGlobals glob, FrameData *prereq, AVCodecContext *context, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture) 
     1110
     1111        FFusionDebugPrint("%p prereq-decompressing frame #%d.\n", glob, prereq->frameNumber); 
     1112         
    10191113        FrameData *preprereq = FrameDataCheckPrereq(prereq); 
    10201114        if(preprereq) 
    1021                 PrereqDecompress(preprereq, context, dataProc, width, height, picture); 
     1115                PrereqDecompress(glob, preprereq, context, dataProc, width, height, picture); 
    10221116         
    10231117        unsigned char *dataPtr = (unsigned char *)prereq->buffer; 
    10241118        int dataSize = prereq->dataSize; 
    10251119         
    1026         OSErr err = FFusionDecompress(context, dataPtr, dataProc, width, height, picture, dataSize); 
     1120        OSErr err = FFusionDecompress(glob, context, dataPtr, dataProc, width, height, picture, dataSize); 
    10271121         
    10281122        return err; 
     
    10351129 
    10361130    FFusionDecompressRecord *myDrp = (FFusionDecompressRecord *)drp->userDecompressRecord; 
     1131         
     1132        glob->stats.type[drp->frameType].decode_calls++; 
     1133        RecomputeMaxCounts(glob); 
     1134        FFusionDebugPrint("%p DecodeBand #%d qtType %d. (packed %d)\n", glob, myDrp->frameNumber, drp->frameType, glob->packedType); 
    10371135 
    10381136        avcodec_get_frame_defaults(&tempFrame); 
     
    10431141        { 
    10441142                /* Skipped some frames in here */ 
     1143                FFusionDebugPrint("%p - frames skipped.\n", glob); 
    10451144                if(drp->frameType == kCodecFrameTypeKey || myDrp->GOPStartFrameNumber > glob->decode.lastFrame || myDrp->frameNumber < glob->decode.lastFrame) 
    10461145                { 
    10471146                        /* If this is a key frame or the P frame before us is after the last frame (skip ahead), or we are before the last decoded frame (skip back) * 
    10481147                         * then we are in a whole new GOP */ 
     1148                        FFusionDebugPrint("%p - in a new GOP.\n", glob); 
    10491149                        avcodec_flush_buffers(glob->avContext); 
    10501150                } 
     
    10591159                if(nextFrame != NULL) 
    10601160                { 
    1061                         FFusionDecompress(glob->avContext, nextFrame->buffer, NULL, myDrp->width, myDrp->height, &tempFrame, nextFrame->dataSize); 
     1161                        FFusionDecompress(glob, glob->avContext, nextFrame->buffer, NULL, myDrp->width, myDrp->height, &tempFrame, nextFrame->dataSize); 
    10621162                        if(tempFrame.data[0] != NULL) 
    10631163                        { 
     
    10851185                if(prereq) 
    10861186                { 
    1087                         err = PrereqDecompress(prereq, glob->avContext, NULL, myDrp->width, myDrp->height, &tempFrame); 
     1187                        err = PrereqDecompress(glob, prereq, glob->avContext, NULL, myDrp->width, myDrp->height, &tempFrame); 
    10881188                        if(tempFrame.data[0] != NULL) 
    10891189                        { 
     
    11061206                 
    11071207        avcodec_get_frame_defaults(&tempFrame); 
    1108         err = FFusionDecompress(glob->avContext, dataPtr, dataProc, myDrp->width, myDrp->height, &tempFrame, dataSize); 
    1109          
     1208        err = FFusionDecompress(glob, glob->avContext, dataPtr, dataProc, myDrp->width, myDrp->height, &tempFrame, dataSize); 
     1209                
    11101210        if (glob->packedType == PACKED_QUICKTIME_KNOWS_ORDER) { 
    11111211                myDrp->buffer = &glob->buffers[glob->lastAllocatedBuffer]; 
    11121212                myDrp->buffer->frameNumber = myDrp->frameNumber; 
     1213                myDrp->buffer->returnedFrame = tempFrame; 
    11131214                myDrp->decoded = true; 
    11141215                return err; 
     
    11241225        glob->decode.lastFrame = myDrp->frameNumber; 
    11251226        myDrp->decoded = true; 
     1227        if (myDrp->buffer) myDrp->buffer->returnedFrame = tempFrame; 
    11261228         
    11271229        FFusionDataMarkRead(&(glob->data), frameData); 
     1230         
     1231        FFusionDebugPrint("%p DecodeBand decoded #%d.\n", glob, glob->decode.lastFrame); 
    11281232 
    11291233        return err; 
     
    11581262        int i, j; 
    11591263         
     1264        glob->stats.type[drp->frameType].draw_calls++; 
     1265        RecomputeMaxCounts(glob); 
     1266        FFusionDebugPrint("%p DrawBand #%d. (%sdecoded)\n", glob, myDrp->frameNumber, not(myDrp->decoded)); 
     1267         
    11601268        if(!myDrp->decoded) 
    11611269                err = FFusionCodecDecodeBand(glob, drp, 0); 
     
    11701278        if(!picture || picture->data[0] == 0) 
    11711279        { 
    1172                 if(glob->lastDisplayedFrame.data[0] != NULL) 
     1280                if(glob->shouldUseReturnedFrame && myDrp->buffer->returnedFrame.data[0]) 
     1281                        //Some decoders (vp3) keep their internal buffers in an unusable state 
     1282                        picture = &myDrp->buffer->returnedFrame; 
     1283                else if(glob->lastDisplayedFrame.data[0] != NULL) 
    11731284                        //Display last frame 
    11741285                        picture = &(glob->lastDisplayedFrame); 
     
    12121323                RGB32toRGB32((UInt8 *)drp->baseAddr, drp->rowBytes, myDrp->width, myDrp->height, picture); 
    12131324        } 
     1325        else if (myDrp->pixelFormat == k24RGBPixelFormat && glob->avContext->pix_fmt == PIX_FMT_RGB24) 
     1326        { 
     1327                RGB24toRGB24((UInt8 *)drp->baseAddr, drp->rowBytes, myDrp->width, myDrp->height, picture); 
     1328        }