/*
 * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#import "config.h"

#if ENABLE(VIDEO)

#import "MediaPlayerPrivateQTKit.h"

#import "BlockExceptions.h"
#import "DocumentLoader.h"
#import "Frame.h"
#import "FrameView.h"
#import "HostWindow.h"
#import "GraphicsContext.h"
#import "KURL.h"
#import "Logging.h"
#import "MIMETypeRegistry.h"
#import "SecurityOrigin.h"
#import "SoftLinking.h"
#import "TimeRanges.h"
#import "WebCoreSystemInterface.h"
#import <QTKit/QTKit.h>
#import <objc/objc-runtime.h>
#import <wtf/UnusedParam.h>

#if USE(ACCELERATED_COMPOSITING)
#include "PlatformLayer.h"
#endif

#if DRAW_FRAME_RATE
#import "Font.h"
#import "Document.h"
#import "RenderObject.h"
#import "RenderStyle.h"
#endif

SOFT_LINK_FRAMEWORK(QTKit)

SOFT_LINK(QTKit, QTMakeTime, QTTime, (long long timeValue, long timeScale), (timeValue, timeScale))

SOFT_LINK_CLASS(QTKit, QTMovie)
SOFT_LINK_CLASS(QTKit, QTMovieView)
SOFT_LINK_CLASS(QTKit, QTMovieLayer)

SOFT_LINK_POINTER(QTKit, QTTrackMediaTypeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeBase, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeMPEG, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeSound, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeText, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeVideo, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieAskUnresolvedDataRefsAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoopsAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDataAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDataSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDidEndNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieHasVideoAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieHasAudioAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieIsActiveAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoadStateAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoadStateDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieNaturalSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieCurrentSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMoviePreventExternalURLLinksAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieRateChangesPreservePitchAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieRateDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieSizeDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieTimeDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieTimeScaleAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieURLAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieVolumeDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTSecurityPolicyNoCrossSiteAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTVideoRendererWebKitOnlyNewImageAvailableNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieApertureModeClean, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieApertureModeAttribute, NSString *)

SOFT_LINK_POINTER_OPTIONAL(QTKit, QTSecurityPolicyNoLocalToRemoteSiteAttribute, NSString *)
SOFT_LINK_POINTER_OPTIONAL(QTKit, QTSecurityPolicyNoRemoteToLocalSiteAttribute, NSString *)

#define QTMovie getQTMovieClass()
#define QTMovieView getQTMovieViewClass()
#define QTMovieLayer getQTMovieLayerClass()

#define QTTrackMediaTypeAttribute getQTTrackMediaTypeAttribute()
#define QTMediaTypeAttribute getQTMediaTypeAttribute()
#define QTMediaTypeBase getQTMediaTypeBase()
#define QTMediaTypeMPEG getQTMediaTypeMPEG()
#define QTMediaTypeSound getQTMediaTypeSound()
#define QTMediaTypeText getQTMediaTypeText()
#define QTMediaTypeVideo getQTMediaTypeVideo()
#define QTMovieAskUnresolvedDataRefsAttribute getQTMovieAskUnresolvedDataRefsAttribute()
#define QTMovieLoopsAttribute getQTMovieLoopsAttribute()
#define QTMovieDataAttribute getQTMovieDataAttribute()
#define QTMovieDataSizeAttribute getQTMovieDataSizeAttribute()
#define QTMovieDidEndNotification getQTMovieDidEndNotification()
#define QTMovieHasVideoAttribute getQTMovieHasVideoAttribute()
#define QTMovieHasAudioAttribute getQTMovieHasAudioAttribute()
#define QTMovieIsActiveAttribute getQTMovieIsActiveAttribute()
#define QTMovieLoadStateAttribute getQTMovieLoadStateAttribute()
#define QTMovieLoadStateDidChangeNotification getQTMovieLoadStateDidChangeNotification()
#define QTMovieNaturalSizeAttribute getQTMovieNaturalSizeAttribute()
#define QTMovieCurrentSizeAttribute getQTMovieCurrentSizeAttribute()
#define QTMoviePreventExternalURLLinksAttribute getQTMoviePreventExternalURLLinksAttribute()
#define QTMovieRateChangesPreservePitchAttribute getQTMovieRateChangesPreservePitchAttribute()
#define QTMovieRateDidChangeNotification getQTMovieRateDidChangeNotification()
#define QTMovieSizeDidChangeNotification getQTMovieSizeDidChangeNotification()
#define QTMovieTimeDidChangeNotification getQTMovieTimeDidChangeNotification()
#define QTMovieTimeScaleAttribute getQTMovieTimeScaleAttribute()
#define QTMovieURLAttribute getQTMovieURLAttribute()
#define QTMovieVolumeDidChangeNotification getQTMovieVolumeDidChangeNotification()
#define QTSecurityPolicyNoCrossSiteAttribute getQTSecurityPolicyNoCrossSiteAttribute()
#define QTSecurityPolicyNoLocalToRemoteSiteAttribute getQTSecurityPolicyNoLocalToRemoteSiteAttribute()
#define QTSecurityPolicyNoRemoteToLocalSiteAttribute getQTSecurityPolicyNoRemoteToLocalSiteAttribute()
#define QTVideoRendererWebKitOnlyNewImageAvailableNotification getQTVideoRendererWebKitOnlyNewImageAvailableNotification()
#define QTMovieApertureModeClean getQTMovieApertureModeClean()
#define QTMovieApertureModeAttribute getQTMovieApertureModeAttribute()

// Older versions of the QTKit header don't have these constants.
#if !defined QTKIT_VERSION_MAX_ALLOWED || QTKIT_VERSION_MAX_ALLOWED <= QTKIT_VERSION_7_0
enum {
    QTMovieLoadStateError = -1L,
    QTMovieLoadStateLoaded  = 2000L,
    QTMovieLoadStatePlayable = 10000L,
    QTMovieLoadStatePlaythroughOK = 20000L,
    QTMovieLoadStateComplete = 100000L
};
#endif

@interface FakeQTMovieView : NSObject
- (WebCoreMovieObserver *)delegate;
@end

using namespace WebCore;
using namespace std;

@interface WebCoreMovieObserver : NSObject
{
    MediaPlayerPrivateQTKit* m_callback;
    NSView* m_view;
    BOOL m_delayCallbacks;
}
-(id)initWithCallback:(MediaPlayerPrivateQTKit*)callback;
-(void)disconnect;
-(void)setView:(NSView*)view;
-(void)repaint;
-(void)setDelayCallbacks:(BOOL)shouldDelay;
-(void)loadStateChanged:(NSNotification *)notification;
-(void)rateChanged:(NSNotification *)notification;
-(void)sizeChanged:(NSNotification *)notification;
-(void)timeChanged:(NSNotification *)notification;
-(void)didEnd:(NSNotification *)notification;
-(void)layerHostChanged:(NSNotification *)notification;
@end

@protocol WebKitVideoRenderingDetails
-(void)setMovie:(id)movie;
-(void)drawInRect:(NSRect)rect;
@end

namespace WebCore {

PassOwnPtr<MediaPlayerPrivateInterface> MediaPlayerPrivateQTKit::create(MediaPlayer* player)
{ 
    return adoptPtr(new MediaPlayerPrivateQTKit(player));
}

void MediaPlayerPrivateQTKit::registerMediaEngine(MediaEngineRegistrar registrar)
{
    if (isAvailable())
#if ENABLE(ENCRYPTED_MEDIA)
        registrar(create, getSupportedTypes, extendedSupportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite);
#else
        registrar(create, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite);
#endif
}

MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player)
    : m_player(player)
    , m_objcObserver(AdoptNS, [[WebCoreMovieObserver alloc] initWithCallback:this])
    , m_seekTo(-1)
    , m_seekTimer(this, &MediaPlayerPrivateQTKit::seekTimerFired)
    , m_networkState(MediaPlayer::Empty)
    , m_readyState(MediaPlayer::HaveNothing)
    , m_rect()
    , m_scaleFactor(1, 1)
    , m_enabledTrackCount(0)
    , m_totalTrackCount(0)
    , m_reportedDuration(-1)
    , m_cachedDuration(-1)
    , m_timeToRestore(-1)
    , m_preload(MediaPlayer::Auto)
    , m_startedPlaying(false)
    , m_isStreaming(false)
    , m_visible(false)
    , m_hasUnsupportedTracks(false)
    , m_videoFrameHasDrawn(false)
    , m_isAllowedToRender(false)
    , m_privateBrowsing(false)
    , m_maxTimeLoadedAtLastDidLoadingProgress(0)
#if DRAW_FRAME_RATE
    , m_frameCountWhilePlaying(0)
    , m_timeStartedPlaying(0)
    , m_timeStoppedPlaying(0)
#endif
{
}

MediaPlayerPrivateQTKit::~MediaPlayerPrivateQTKit()
{
    LOG(Media, "MediaPlayerPrivateQTKit::~MediaPlayerPrivateQTKit(%p)", this);
    tearDownVideoRendering();

    [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()];
    [m_objcObserver.get() disconnect];
}

NSMutableDictionary *MediaPlayerPrivateQTKit::commonMovieAttributes() 
{
    NSMutableDictionary *movieAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
            [NSNumber numberWithBool:m_player->preservesPitch()], QTMovieRateChangesPreservePitchAttribute,
            [NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
            [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
            [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
            [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute",
            QTMovieApertureModeClean, QTMovieApertureModeAttribute,
            nil];

    // Check to see if QTSecurityPolicyNoRemoteToLocalSiteAttribute is defined, which was added in QTKit 7.6.3.
    // If not, just set NoCrossSite = YES, which does the same thing as NoRemoteToLocal = YES and 
    // NoLocalToRemote = YES in QTKit < 7.6.3.
    if (QTSecurityPolicyNoRemoteToLocalSiteAttribute) {
        [movieAttributes setValue:[NSNumber numberWithBool:NO] forKey:QTSecurityPolicyNoCrossSiteAttribute];
        [movieAttributes setValue:[NSNumber numberWithBool:YES] forKey:QTSecurityPolicyNoRemoteToLocalSiteAttribute];
        [movieAttributes setValue:[NSNumber numberWithBool:YES] forKey:QTSecurityPolicyNoLocalToRemoteSiteAttribute];
    } else
        [movieAttributes setValue:[NSNumber numberWithBool:YES] forKey:QTSecurityPolicyNoCrossSiteAttribute];

    if (m_preload < MediaPlayer::Auto)
        [movieAttributes setValue:[NSNumber numberWithBool:YES] forKey:@"QTMovieLimitReadAheadAttribute"];

    return movieAttributes;
}

void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
{
    KURL kURL(ParsedURLString, url);
    NSURL *cocoaURL = kURL;
    NSMutableDictionary *movieAttributes = commonMovieAttributes();    
    [movieAttributes setValue:cocoaURL forKey:QTMovieURLAttribute];

#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
    CFArrayRef proxiesForURL = CFNetworkCopyProxiesForURL((CFURLRef)cocoaURL, proxySettings);
    BOOL willUseProxy = YES;
    
    if (!proxiesForURL || !CFArrayGetCount(proxiesForURL))
        willUseProxy = NO;
    
    if (CFArrayGetCount(proxiesForURL) == 1) {
        CFDictionaryRef proxy = (CFDictionaryRef)CFArrayGetValueAtIndex(proxiesForURL, 0);
        ASSERT(CFGetTypeID(proxy) == CFDictionaryGetTypeID());
        
        CFStringRef proxyType = (CFStringRef)CFDictionaryGetValue(proxy, kCFProxyTypeKey);
        ASSERT(CFGetTypeID(proxyType) == CFStringGetTypeID());
        
        if (CFStringCompare(proxyType, kCFProxyTypeNone, 0) == kCFCompareEqualTo)
            willUseProxy = NO;
    }

    if (!willUseProxy && !kURL.protocolIsData()) {
        // Only pass the QTMovieOpenForPlaybackAttribute flag if there are no proxy servers, due
        // to rdar://problem/7531776, or if not loading a data:// url due to rdar://problem/8103801.
        [movieAttributes setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
    }
    
    if (proxiesForURL)
        CFRelease(proxiesForURL);
    if (proxySettings)
        CFRelease(proxySettings);
#endif
    
    createQTMovie(cocoaURL, movieAttributes);
}

static void disableComponentsOnce()
{
    static bool sComponentsDisabled = false;
    if (sComponentsDisabled)
        return;
    sComponentsDisabled = true;

    // eat/PDF and grip/PDF components must be disabled twice since they are registered twice
    // with different flags.  However, there is currently a bug in 64-bit QTKit (<rdar://problem/8378237>)
    // which causes subsequent disable component requests of exactly the same type to be ignored if
    // QTKitServer has not yet started.  As a result, we must pass in exactly the flags we want to
    // disable per component.  As a failsafe, if in the future these flags change, we will disable the
    // PDF components for a third time with a wildcard flags field:
    uint32_t componentsToDisable[11][5] = {
        {'eat ', 'TEXT', 'text', 0, 0},
        {'eat ', 'TXT ', 'text', 0, 0},    
        {'eat ', 'utxt', 'text', 0, 0},  
        {'eat ', 'TEXT', 'tx3g', 0, 0},  
        {'eat ', 'PDF ', 'vide', 0x44802, 0},
        {'eat ', 'PDF ', 'vide', 0x45802, 0},
        {'eat ', 'PDF ', 'vide', 0, 0},  
        {'grip', 'PDF ', 'appl', 0x844a00, 0},
        {'grip', 'PDF ', 'appl', 0x845a00, 0},
        {'grip', 'PDF ', 'appl', 0, 0},  
        {'imdc', 'pdf ', 'appl', 0, 0},  
    };

    for (size_t i = 0; i < WTF_ARRAY_LENGTH(componentsToDisable); ++i) 
        wkQTMovieDisableComponent(componentsToDisable[i]);
}

void MediaPlayerPrivateQTKit::createQTMovie(NSURL *url, NSDictionary *movieAttributes)
{
    LOG(Media, "MediaPlayerPrivateQTKit::createQTMovie(%p) ", this);
    disableComponentsOnce();

    [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()];
    
    bool recreating = false;
    if (m_qtMovie) {
        recreating = true;
        destroyQTVideoRenderer();
        m_qtMovie = 0;
    }
    
    // Disable rtsp streams for now, <rdar://problem/5693967>
    if (protocolIs([url scheme], "rtsp"))
        return;
    
    NSError *error = nil;
    m_qtMovie.adoptNS([[QTMovie alloc] initWithAttributes:movieAttributes error:&error]);
    
    if (!m_qtMovie)
        return;
    
    [m_qtMovie.get() setVolume:m_player->volume()];

    if (recreating && hasVideo())
        createQTVideoRenderer(QTVideoRendererModeListensForNewImages);
    
    [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                             selector:@selector(loadStateChanged:) 
                                                 name:QTMovieLoadStateDidChangeNotification 
                                               object:m_qtMovie.get()];

    // In updateState(), we track when maxTimeLoaded() == duration().
    // In newer version of QuickTime, a notification is emitted when maxTimeLoaded changes.
    // In older version of QuickTime, QTMovieLoadStateDidChangeNotification be fired.
    if (NSString *maxTimeLoadedChangeNotification = wkQTMovieMaxTimeLoadedChangeNotification()) {
        [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                                 selector:@selector(loadedRangesChanged:)
                                                     name:maxTimeLoadedChangeNotification
                                                   object:m_qtMovie.get()];        
    }

    [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                             selector:@selector(rateChanged:) 
                                                 name:QTMovieRateDidChangeNotification 
                                               object:m_qtMovie.get()];
    [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                             selector:@selector(sizeChanged:) 
                                                 name:QTMovieSizeDidChangeNotification 
                                               object:m_qtMovie.get()];
    [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                             selector:@selector(timeChanged:) 
                                                 name:QTMovieTimeDidChangeNotification 
                                               object:m_qtMovie.get()];
    [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                             selector:@selector(didEnd:) 
                                                 name:QTMovieDidEndNotification 
                                               object:m_qtMovie.get()];
#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
    [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                             selector:@selector(layerHostChanged:)
                                                 name:@"WebKitLayerHostChanged"
                                               object:nil];
#endif
}

static void mainThreadSetNeedsDisplay(id self, SEL)
{
    id view = [self superview];
    ASSERT(!view || [view isKindOfClass:[QTMovieView class]]);
    if (!view || ![view isKindOfClass:[QTMovieView class]])
        return;

    FakeQTMovieView *movieView = static_cast<FakeQTMovieView *>(view);
    WebCoreMovieObserver* delegate = [movieView delegate];
    ASSERT(!delegate || [delegate isKindOfClass:[WebCoreMovieObserver class]]);
    if (!delegate || ![delegate isKindOfClass:[WebCoreMovieObserver class]])
        return;

    [delegate repaint];
}

static Class QTVideoRendererClass()
{
     static Class QTVideoRendererWebKitOnlyClass = NSClassFromString(@"QTVideoRendererWebKitOnly");
     return QTVideoRendererWebKitOnlyClass;
}

void MediaPlayerPrivateQTKit::createQTMovieView()
{
    LOG(Media, "MediaPlayerPrivateQTKit::createQTMovieView(%p)", this);
    detachQTMovieView();

    static bool addedCustomMethods = false;
    if (!m_player->inMediaDocument() && !addedCustomMethods) {
        Class QTMovieContentViewClass = NSClassFromString(@"QTMovieContentView");
        ASSERT(QTMovieContentViewClass);

        Method mainThreadSetNeedsDisplayMethod = class_getInstanceMethod(QTMovieContentViewClass, @selector(_mainThreadSetNeedsDisplay));
        ASSERT(mainThreadSetNeedsDisplayMethod);

        method_setImplementation(mainThreadSetNeedsDisplayMethod, reinterpret_cast<IMP>(mainThreadSetNeedsDisplay));
        addedCustomMethods = true;
    }

    // delay callbacks as we *will* get notifications during setup
    [m_objcObserver.get() setDelayCallbacks:YES];

    m_qtMovieView.adoptNS([[QTMovieView alloc] init]);
    setSize(m_player->size());
    NSView* parentView = 0;
#if PLATFORM(MAC)
    parentView = m_player->frameView()->documentView();
    [parentView addSubview:m_qtMovieView.get()];
#endif
    [m_qtMovieView.get() setDelegate:m_objcObserver.get()];
    [m_objcObserver.get() setView:m_qtMovieView.get()];
    [m_qtMovieView.get() setMovie:m_qtMovie.get()];
    [m_qtMovieView.get() setControllerVisible:NO];
    [m_qtMovieView.get() setPreservesAspectRatio:NO];
    // the area not covered by video should be transparent
    [m_qtMovieView.get() setFillColor:[NSColor clearColor]];

    // If we're in a media document, allow QTMovieView to render in its default mode;
    // otherwise tell it to draw synchronously.
    // Note that we expect mainThreadSetNeedsDisplay to be invoked only when synchronous drawing is requested.
    if (!m_player->inMediaDocument())
        wkQTMovieViewSetDrawSynchronously(m_qtMovieView.get(), YES);

    [m_objcObserver.get() setDelayCallbacks:NO];
}

void MediaPlayerPrivateQTKit::detachQTMovieView()
{
    LOG(Media, "MediaPlayerPrivateQTKit::detachQTMovieView(%p)", this);
    if (m_qtMovieView) {
        [m_objcObserver.get() setView:nil];
        [m_qtMovieView.get() setDelegate:nil];
        [m_qtMovieView.get() removeFromSuperview];
        m_qtMovieView = nil;
    }
}

void MediaPlayerPrivateQTKit::createQTVideoRenderer(QTVideoRendererMode rendererMode)
{
    LOG(Media, "MediaPlayerPrivateQTKit::createQTVideoRenderer(%p)", this);
    destroyQTVideoRenderer();

    m_qtVideoRenderer.adoptNS([[QTVideoRendererClass() alloc] init]);
    if (!m_qtVideoRenderer)
        return;
    
    // associate our movie with our instance of QTVideoRendererWebKitOnly
    [(id<WebKitVideoRenderingDetails>)m_qtVideoRenderer.get() setMovie:m_qtMovie.get()];

    if (rendererMode == QTVideoRendererModeListensForNewImages) {
        // listen to QTVideoRendererWebKitOnly's QTVideoRendererWebKitOnlyNewImageDidBecomeAvailableNotification
        [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
                                                 selector:@selector(newImageAvailable:)
                                                     name:QTVideoRendererWebKitOnlyNewImageAvailableNotification
                                                   object:m_qtVideoRenderer.get()];
    }
}

void MediaPlayerPrivateQTKit::destroyQTVideoRenderer()
{
    LOG(Media, "MediaPlayerPrivateQTKit::destroyQTVideoRenderer(%p)", this);
    if (!m_qtVideoRenderer)
        return;

    // stop observing the renderer's notifications before we toss it
    [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()
                                                    name:QTVideoRendererWebKitOnlyNewImageAvailableNotification
                                                  object:m_qtVideoRenderer.get()];

    // disassociate our movie from our instance of QTVideoRendererWebKitOnly
    [(id<WebKitVideoRenderingDetails>)m_qtVideoRenderer.get() setMovie:nil];    

    m_qtVideoRenderer = nil;
}

void MediaPlayerPrivateQTKit::createQTMovieLayer()
{
    LOG(Media, "MediaPlayerPrivateQTKit::createQTMovieLayer(%p)", this);
#if USE(ACCELERATED_COMPOSITING) && !(PLATFORM(QT) && USE(QTKIT))
    if (!m_qtMovie)
        return;

    ASSERT(supportsAcceleratedRendering());
    
    if (!m_qtVideoLayer) {
        m_qtVideoLayer.adoptNS([[QTMovieLayer alloc] init]);
        if (!m_qtVideoLayer)
            return;

        [m_qtVideoLayer.get() setMovie:m_qtMovie.get()];
#ifndef NDEBUG
        [(CALayer *)m_qtVideoLayer.get() setName:@"Video layer"];
#endif
        // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration().
    }
#endif
}

void MediaPlayerPrivateQTKit::destroyQTMovieLayer()
{
    LOG(Media, "MediaPlayerPrivateQTKit::destroyQTMovieLayer(%p)", this);
#if USE(ACCELERATED_COMPOSITING)
    if (!m_qtVideoLayer)
        return;

    // disassociate our movie from our instance of QTMovieLayer
    [m_qtVideoLayer.get() setMovie:nil];    
    m_qtVideoLayer = nil;
#endif
}

MediaPlayerPrivateQTKit::MediaRenderingMode MediaPlayerPrivateQTKit::currentRenderingMode() const
{
    if (m_qtMovieView)
        return MediaRenderingMovieView;
    
    if (m_qtVideoLayer)
        return MediaRenderingMovieLayer;

    if (m_qtVideoRenderer)
        return MediaRenderingSoftwareRenderer;
    
    return MediaRenderingNone;
}

MediaPlayerPrivateQTKit::MediaRenderingMode MediaPlayerPrivateQTKit::preferredRenderingMode() const
{
    if (!m_player->frameView() || !m_qtMovie)
        return MediaRenderingNone;

#if USE(ACCELERATED_COMPOSITING) && !(PLATFORM(QT) && USE(QTKIT))
    if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player))
        return MediaRenderingMovieLayer;
#endif

    if (!QTVideoRendererClass())
        return MediaRenderingMovieView;
    
    return MediaRenderingSoftwareRenderer;
}

void MediaPlayerPrivateQTKit::setUpVideoRendering()
{
    LOG(Media, "MediaPlayerPrivateQTKit::setUpVideoRendering(%p)", this);
    if (!isReadyForVideoSetup())
        return;

    MediaRenderingMode currentMode = currentRenderingMode();
    MediaRenderingMode preferredMode = preferredRenderingMode();
    if (currentMode == preferredMode && currentMode != MediaRenderingNone)
        return;

    if (currentMode != MediaRenderingNone)  
        tearDownVideoRendering();

    switch (preferredMode) {
    case MediaRenderingMovieView:
        createQTMovieView();
        break;
    case MediaRenderingNone:
    case MediaRenderingSoftwareRenderer:
        createQTVideoRenderer(QTVideoRendererModeListensForNewImages);
        break;
    case MediaRenderingMovieLayer:
        createQTMovieLayer();
        break;
    }

    // If using a movie layer, inform the client so the compositing tree is updated.
    if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer)
        m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
}

void MediaPlayerPrivateQTKit::tearDownVideoRendering()
{
    LOG(Media, "MediaPlayerPrivateQTKit::tearDownVideoRendering(%p)", this);
    if (m_qtMovieView)
        detachQTMovieView();
    if (m_qtVideoRenderer)
        destroyQTVideoRenderer();
    if (m_qtVideoLayer)
        destroyQTMovieLayer();
}

bool MediaPlayerPrivateQTKit::hasSetUpVideoRendering() const
{
    return m_qtMovieView
        || m_qtVideoLayer
        || m_qtVideoRenderer;
}

QTTime MediaPlayerPrivateQTKit::createQTTime(float time) const
{
    if (!metaDataAvailable())
        return QTMakeTime(0, 600);
    long timeScale = [[m_qtMovie.get() attributeForKey:QTMovieTimeScaleAttribute] longValue];
    return QTMakeTime(lroundf(time * timeScale), timeScale);
}

void MediaPlayerPrivateQTKit::resumeLoad()
{
    if (!m_movieURL.isNull())
        loadInternal(m_movieURL);
}

void MediaPlayerPrivateQTKit::load(const String& url)
{
    LOG(Media, "MediaPlayerPrivateQTKit::load(%p)", this);
    m_movieURL = url;

    // If the element is not supposed to load any data return immediately.
    if (m_preload == MediaPlayer::None)
        return;

    loadInternal(url);
}

void MediaPlayerPrivateQTKit::loadInternal(const String& url)
{
    if (m_networkState != MediaPlayer::Loading) {
        m_networkState = MediaPlayer::Loading;
        m_player->networkStateChanged();
    }
    if (m_readyState != MediaPlayer::HaveNothing) {
        m_readyState = MediaPlayer::HaveNothing;
        m_player->readyStateChanged();
    }
    cancelSeek();
    m_videoFrameHasDrawn = false;
    
    [m_objcObserver.get() setDelayCallbacks:YES];

    createQTMovie(url);

    [m_objcObserver.get() loadStateChanged:nil];
    [m_objcObserver.get() setDelayCallbacks:NO];
}

void MediaPlayerPrivateQTKit::prepareToPlay()
{
    LOG(Media, "MediaPlayerPrivateQTKit::prepareToPlay(%p)", this);
    setPreload(MediaPlayer::Auto);
}

PlatformMedia MediaPlayerPrivateQTKit::platformMedia() const
{
    PlatformMedia pm;
    pm.type = PlatformMedia::QTMovieType;
    pm.media.qtMovie = m_qtMovie.get();
    return pm;
}

#if USE(ACCELERATED_COMPOSITING) && !(PLATFORM(QT) && USE(QTKIT))
PlatformLayer* MediaPlayerPrivateQTKit::platformLayer() const
{
    return m_qtVideoLayer.get();
}
#endif

void MediaPlayerPrivateQTKit::play()
{
    LOG(Media, "MediaPlayerPrivateQTKit::play(%p)", this);
    if (!metaDataAvailable())
        return;
    m_startedPlaying = true;
#if DRAW_FRAME_RATE
    m_frameCountWhilePlaying = 0;
#endif
    [m_objcObserver.get() setDelayCallbacks:YES];
    [m_qtMovie.get() setRate:m_player->rate()];
    [m_objcObserver.get() setDelayCallbacks:NO];
}

void MediaPlayerPrivateQTKit::pause()
{
    LOG(Media, "MediaPlayerPrivateQTKit::pause(%p)", this);
    if (!metaDataAvailable())
        return;
    m_startedPlaying = false;
#if DRAW_FRAME_RATE
    m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate];
#endif
    [m_objcObserver.get() setDelayCallbacks:YES];
    [m_qtMovie.get() stop];
    [m_objcObserver.get() setDelayCallbacks:NO];
}

float MediaPlayerPrivateQTKit::duration() const
{
    if (!metaDataAvailable())
        return 0;

    if (m_cachedDuration != MediaPlayer::invalidTime())
        return m_cachedDuration;

    QTTime time = [m_qtMovie.get() duration];
    if (time.flags == kQTTimeIsIndefinite)
        return numeric_limits<float>::infinity();
    return static_cast<float>(time.timeValue) / time.timeScale;
}

float MediaPlayerPrivateQTKit::currentTime() const
{
    if (!metaDataAvailable())
        return 0;
    QTTime time = [m_qtMovie.get() currentTime];
    return static_cast<float>(time.timeValue) / time.timeScale;
}

void MediaPlayerPrivateQTKit::seek(float time)
{
    LOG(Media, "MediaPlayerPrivateQTKit::seek(%p) - time %f", this, time);
    // Nothing to do if we are already in the middle of a seek to the same time.
    if (time == m_seekTo)
        return;

    cancelSeek();
    
    if (!metaDataAvailable())
        return;
    
    if (time > duration())
        time = duration();

    m_seekTo = time;
    if (maxTimeSeekable() >= m_seekTo)
        doSeek();
    else 
        m_seekTimer.start(0, 0.5f);
}

void MediaPlayerPrivateQTKit::doSeek() 
{
    QTTime qttime = createQTTime(m_seekTo);
    // setCurrentTime generates several event callbacks, update afterwards
    [m_objcObserver.get() setDelayCallbacks:YES];
    float oldRate = [m_qtMovie.get() rate];

    if (oldRate)
        [m_qtMovie.get() setRate:0];
    [m_qtMovie.get() setCurrentTime:qttime];

    // restore playback only if not at end, otherwise QTMovie will loop
    float timeAfterSeek = currentTime();
    if (oldRate && timeAfterSeek < duration())
        [m_qtMovie.get() setRate:oldRate];

    cancelSeek();
    [m_objcObserver.get() setDelayCallbacks:NO];
}

void MediaPlayerPrivateQTKit::cancelSeek()
{
    LOG(Media, "MediaPlayerPrivateQTKit::cancelSeek(%p)", this);
    m_seekTo = -1;
    m_seekTimer.stop();
}

void MediaPlayerPrivateQTKit::seekTimerFired(Timer<MediaPlayerPrivateQTKit>*)
{        
    if (!metaDataAvailable()|| !seeking() || currentTime() == m_seekTo) {
        cancelSeek();
        updateStates();
        m_player->timeChanged(); 
        return;
    } 

    if (maxTimeSeekable() >= m_seekTo)
        doSeek();
    else {
        MediaPlayer::NetworkState state = networkState();
        if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) {
            cancelSeek();
            updateStates();
            m_player->timeChanged();
        }
    }
}

bool MediaPlayerPrivateQTKit::paused() const
{
    if (!metaDataAvailable())
        return true;
    return [m_qtMovie.get() rate] == 0;
}

bool MediaPlayerPrivateQTKit::seeking() const
{
    if (!metaDataAvailable())
        return false;
    return m_seekTo >= 0;
}

IntSize MediaPlayerPrivateQTKit::naturalSize() const
{
    if (!metaDataAvailable())
        return IntSize();

    // In spite of the name of this method, return QTMovieNaturalSizeAttribute transformed by the 
    // initial movie scale because the spec says intrinsic size is:
    //
    //    ... the dimensions of the resource in CSS pixels after taking into account the resource's 
    //    dimensions, aspect ratio, clean aperture, resolution, and so forth, as defined for the 
    //    format used by the resource
    
    FloatSize naturalSize([[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]);
    if (naturalSize.isEmpty() && m_isStreaming) {
        // HTTP Live Streams will occasionally return {0,0} natural sizes while scrubbing.
        // Work around this problem (<rdar://problem/9078563>) by returning the last valid 
        // cached natural size:
        naturalSize = m_cachedNaturalSize;
    } else {
        // Unfortunately, due to another QTKit bug (<rdar://problem/9082071>) we won't get a sizeChanged
        // event when this happens, so we must cache the last valid naturalSize here:
        m_cachedNaturalSize = naturalSize;
    }
        
    return IntSize(naturalSize.width() * m_scaleFactor.width(), naturalSize.height() * m_scaleFactor.height());
}

bool MediaPlayerPrivateQTKit::hasVideo() const
{
    if (!metaDataAvailable())
        return false;
    return [[m_qtMovie.get() attributeForKey:QTMovieHasVideoAttribute] boolValue];
}

bool MediaPlayerPrivateQTKit::hasAudio() const
{
    if (!m_qtMovie)
        return false;
    return [[m_qtMovie.get() attributeForKey:QTMovieHasAudioAttribute] boolValue];
}

bool MediaPlayerPrivateQTKit::supportsFullscreen() const
{
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    return true;
#else
    // See <rdar://problem/7389945>
    return false;
#endif
}

void MediaPlayerPrivateQTKit::setVolume(float volume)
{
    LOG(Media, "MediaPlayerPrivateQTKit::setVolume(%p) - volume %f", this, volume);
    if (m_qtMovie)
        [m_qtMovie.get() setVolume:volume];  
}

bool MediaPlayerPrivateQTKit::hasClosedCaptions() const
{
    if (!metaDataAvailable())
        return false;
    return wkQTMovieHasClosedCaptions(m_qtMovie.get());  
}

void MediaPlayerPrivateQTKit::setClosedCaptionsVisible(bool closedCaptionsVisible)
{
    if (metaDataAvailable()) {
        wkQTMovieSetShowClosedCaptions(m_qtMovie.get(), closedCaptionsVisible);

#if USE(ACCELERATED_COMPOSITING) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    if (closedCaptionsVisible && m_qtVideoLayer) {
        // Captions will be rendered upside down unless we flag the movie as flipped (again). See <rdar://7408440>.
        [m_qtVideoLayer.get() setGeometryFlipped:YES];
    }
#endif
    }
}

void MediaPlayerPrivateQTKit::setRate(float rate)
{
    LOG(Media, "MediaPlayerPrivateQTKit::setRate(%p) - rate %f", this, rate);
    if (m_qtMovie)
        [m_qtMovie.get() setRate:rate];
}

void MediaPlayerPrivateQTKit::setPreservesPitch(bool preservesPitch)
{
    LOG(Media, "MediaPlayerPrivateQTKit::setPreservesPitch(%p) - preservesPitch %d", this, (int)preservesPitch);
    if (!m_qtMovie)
        return;

    // QTMovieRateChangesPreservePitchAttribute cannot be changed dynamically after QTMovie creation.
    // If the passed in value is different than what already exists, we need to recreate the QTMovie for it to take effect.
    if ([[m_qtMovie.get() attributeForKey:QTMovieRateChangesPreservePitchAttribute] boolValue] == preservesPitch)
        return;

    RetainPtr<NSDictionary> movieAttributes(AdoptNS, [[m_qtMovie.get() movieAttributes] mutableCopy]);
    ASSERT(movieAttributes);
    [movieAttributes.get() setValue:[NSNumber numberWithBool:preservesPitch] forKey:QTMovieRateChangesPreservePitchAttribute];
    m_timeToRestore = currentTime();

    createQTMovie([movieAttributes.get() valueForKey:QTMovieURLAttribute], movieAttributes.get());
}

PassRefPtr<TimeRanges> MediaPlayerPrivateQTKit::buffered() const
{
    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
    float loaded = maxTimeLoaded();
    if (loaded > 0)
        timeRanges->add(0, loaded);
    return timeRanges.release();
}

float MediaPlayerPrivateQTKit::maxTimeSeekable() const
{
    if (!metaDataAvailable())
        return 0;

    // infinite duration means live stream
    if (isinf(duration()))
        return 0;

    return wkQTMovieMaxTimeSeekable(m_qtMovie.get());
}

float MediaPlayerPrivateQTKit::maxTimeLoaded() const
{
    if (!metaDataAvailable())
        return 0;
    return wkQTMovieMaxTimeLoaded(m_qtMovie.get()); 
}

bool MediaPlayerPrivateQTKit::didLoadingProgress() const
{
    if (!duration() || !totalBytes())
        return false;
    float currentMaxTimeLoaded = maxTimeLoaded();
    bool didLoadingProgress = currentMaxTimeLoaded != m_maxTimeLoadedAtLastDidLoadingProgress;
    m_maxTimeLoadedAtLastDidLoadingProgress = currentMaxTimeLoaded;
    return didLoadingProgress;
}

unsigned MediaPlayerPrivateQTKit::totalBytes() const
{
    if (!metaDataAvailable())
        return 0;
    return [[m_qtMovie.get() attributeForKey:QTMovieDataSizeAttribute] intValue];
}

void MediaPlayerPrivateQTKit::cancelLoad()
{
    LOG(Media, "MediaPlayerPrivateQTKit::cancelLoad(%p)", this);
    // FIXME: Is there a better way to check for this?
    if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
        return;
    
    tearDownVideoRendering();
    m_qtMovie = nil;
    
    updateStates();
}

void MediaPlayerPrivateQTKit::cacheMovieScale()
{
    NSSize initialSize = NSZeroSize;
    NSSize naturalSize = [[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];

#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    // QTMovieCurrentSizeAttribute is not allowed with instances of QTMovie that have been 
    // opened with QTMovieOpenForPlaybackAttribute, so ask for the display transform attribute instead.
    NSAffineTransform *displayTransform = [m_qtMovie.get() attributeForKey:@"QTMoviePreferredTransformAttribute"];
    if (displayTransform)
        initialSize = [displayTransform transformSize:naturalSize];
    else {
        initialSize.width = naturalSize.width;
        initialSize.height = naturalSize.height;
    }
#else
    initialSize = [[m_qtMovie.get() attributeForKey:QTMovieCurrentSizeAttribute] sizeValue];
#endif

    if (naturalSize.width)
        m_scaleFactor.setWidth(initialSize.width / naturalSize.width);
    if (naturalSize.height)
        m_scaleFactor.setHeight(initialSize.height / naturalSize.height);
}

bool MediaPlayerPrivateQTKit::isReadyForVideoSetup() const
{
    return m_readyState >= MediaPlayer::HaveMetadata && m_player->visible();
}

void MediaPlayerPrivateQTKit::prepareForRendering()
{
    LOG(Media, "MediaPlayerPrivateQTKit::prepareForRendering(%p)", this);
    if (m_isAllowedToRender)
        return;
    m_isAllowedToRender = true;

    if (!hasSetUpVideoRendering())
        setUpVideoRendering();

    // If using a movie layer, inform the client so the compositing tree is updated. This is crucial if the movie
    // has a poster, as it will most likely not have a layer and we will now be rendering frames to the movie layer.
    if (currentRenderingMode() == MediaRenderingMovieLayer || preferredRenderingMode() == MediaRenderingMovieLayer)
        m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
}

void MediaPlayerPrivateQTKit::updateStates()
{
    MediaPlayer::NetworkState oldNetworkState = m_networkState;
    MediaPlayer::ReadyState oldReadyState = m_readyState;

    LOG(Media, "MediaPlayerPrivateQTKit::updateStates(%p) - entering with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState));

    
    long loadState = m_qtMovie ? [[m_qtMovie.get() attributeForKey:QTMovieLoadStateAttribute] longValue] : static_cast<long>(QTMovieLoadStateError);

    if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata) {
        disableUnsupportedTracks();
        if (m_player->inMediaDocument()) {
            if (!m_enabledTrackCount || m_hasUnsupportedTracks) {
                // This has a type of media that we do not handle directly with a <video> 
                // element, eg. a rtsp track or QuickTime VR. Tell the MediaPlayerClient
                // that we noticed.
                sawUnsupportedTracks();
                return;
            }
        } else if (!m_enabledTrackCount)
            loadState = QTMovieLoadStateError;

        if (loadState != QTMovieLoadStateError) {
            wkQTMovieSelectPreferredAlternates(m_qtMovie.get());
            cacheMovieScale();
            MediaPlayer::MovieLoadType movieType = movieLoadType();
            m_isStreaming = movieType == MediaPlayer::StoredStream || movieType == MediaPlayer::LiveStream;
        }
    }
    
    // If this movie is reloading and we mean to restore the current time/rate, this might be the right time to do it.
    if (loadState >= QTMovieLoadStateLoaded && oldNetworkState < MediaPlayer::Loaded && m_timeToRestore != MediaPlayer::invalidTime()) {
        QTTime qttime = createQTTime(m_timeToRestore);
        m_timeToRestore = MediaPlayer::invalidTime();
            
        // Disable event callbacks from setCurrentTime for restoring time in a recreated video
        [m_objcObserver.get() setDelayCallbacks:YES];
        [m_qtMovie.get() setCurrentTime:qttime];
        [m_qtMovie.get() setRate:m_player->rate()];
        [m_objcObserver.get() setDelayCallbacks:NO];
    }

    BOOL completelyLoaded = !m_isStreaming && (loadState >= QTMovieLoadStateComplete);

    // Note: QT indicates that we are fully loaded with QTMovieLoadStateComplete.
    // However newer versions of QT do not, so we check maxTimeLoaded against duration.
    if (!completelyLoaded && !m_isStreaming && metaDataAvailable())
        completelyLoaded = maxTimeLoaded() == duration();

    if (completelyLoaded) {
        // "Loaded" is reserved for fully buffered movies, never the case when streaming
        m_networkState = MediaPlayer::Loaded;
        m_readyState = MediaPlayer::HaveEnoughData;
    } else if (loadState >= QTMovieLoadStatePlaythroughOK) {
        m_readyState = MediaPlayer::HaveEnoughData;
        m_networkState = MediaPlayer::Loading;
    } else if (loadState >= QTMovieLoadStatePlayable) {
        // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967>
        m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
        m_networkState = MediaPlayer::Loading;
    } else if (loadState >= QTMovieLoadStateLoaded) {
        m_readyState = MediaPlayer::HaveMetadata;
        m_networkState = MediaPlayer::Loading;
    } else if (loadState > QTMovieLoadStateError) {
        m_readyState = MediaPlayer::HaveNothing;
        m_networkState = MediaPlayer::Loading;
    } else {
        // Loading or decoding failed.

        if (m_player->inMediaDocument()) {
            // Something went wrong in the loading of media within a standalone file. 
            // This can occur with chained refmovies pointing to streamed media.
            sawUnsupportedTracks();
            return;
        }

        float loaded = maxTimeLoaded();
        if (!loaded)
            m_readyState = MediaPlayer::HaveNothing;

        if (!m_enabledTrackCount)
            m_networkState = MediaPlayer::FormatError;
        else {
            // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692>
            if (loaded > 0)
                m_networkState = MediaPlayer::DecodeError;
            else
                m_readyState = MediaPlayer::HaveNothing;
        }
    }

    if (isReadyForVideoSetup() && !hasSetUpVideoRendering())
        setUpVideoRendering();

    if (seeking())
        m_readyState = m_readyState >= MediaPlayer::HaveMetadata ? MediaPlayer::HaveMetadata : MediaPlayer::HaveNothing;

    // Streaming movies don't use the network when paused.
    if (m_isStreaming && m_readyState >= MediaPlayer::HaveMetadata && m_networkState >= MediaPlayer::Loading && [m_qtMovie.get() rate] == 0)
        m_networkState = MediaPlayer::Idle;

    if (m_networkState != oldNetworkState)
        m_player->networkStateChanged();

    if (m_readyState != oldReadyState)
        m_player->readyStateChanged();

    if (loadState >= QTMovieLoadStateLoaded) {
        float dur = duration();
        if (dur != m_reportedDuration) {
            if (m_reportedDuration != MediaPlayer::invalidTime())
                m_player->durationChanged();
            m_reportedDuration = dur;
        }
    }

    LOG(Media, "MediaPlayerPrivateQTKit::updateStates(%p) - exiting with networkState = %i, readyState = %i", this, static_cast<int>(m_networkState), static_cast<int>(m_readyState));
}

void MediaPlayerPrivateQTKit::loadStateChanged()
{
    LOG(Media, "MediaPlayerPrivateQTKit::loadStateChanged(%p) - loadState = %li", this, [[m_qtMovie.get() attributeForKey:QTMovieLoadStateAttribute] longValue]);

    if (!m_hasUnsupportedTracks)
        updateStates();
}

void MediaPlayerPrivateQTKit::loadedRangesChanged()
{
    LOG(Media, "MediaPlayerPrivateQTKit::loadedRangesChanged(%p) - loadState = %li", this, [[m_qtMovie.get() attributeForKey:QTMovieLoadStateAttribute] longValue]);

    if (!m_hasUnsupportedTracks)
        updateStates();
}

void MediaPlayerPrivateQTKit::rateChanged()
{
    LOG(Media, "MediaPlayerPrivateQTKit::rateChanged(%p) - rate = %li", this, [m_qtMovie.get() rate]);
    if (m_hasUnsupportedTracks)
        return;

    updateStates();
    m_player->rateChanged();
}

void MediaPlayerPrivateQTKit::sizeChanged()
{
    LOG(Media, "MediaPlayerPrivateQTKit::sizeChanged(%p)", this);
    if (!m_hasUnsupportedTracks)
        m_player->sizeChanged();
}

void MediaPlayerPrivateQTKit::timeChanged()
{
    LOG(Media, "MediaPlayerPrivateQTKit::timeChanged(%p)", this);
    if (m_hasUnsupportedTracks)
        return;

    // It may not be possible to seek to a specific time in a streamed movie. When seeking in a 
    // stream QuickTime sets the movie time to closest time possible and posts a timechanged 
    // notification. Update m_seekTo so we can detect when the seek completes.
    if (m_seekTo != -1)
        m_seekTo = currentTime();

    m_timeToRestore = MediaPlayer::invalidTime();
    updateStates();
    m_player->timeChanged();
}

void MediaPlayerPrivateQTKit::didEnd()
{
    LOG(Media, "MediaPlayerPrivateQTKit::didEnd(%p)", this);
    if (m_hasUnsupportedTracks)
        return;

    m_startedPlaying = false;
#if DRAW_FRAME_RATE
    m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate];
#endif

    // Hang onto the current time and use it as duration from now on since QuickTime is telling us we
    // are at the end. Do this because QuickTime sometimes reports one time for duration and stops
    // playback at another time, which causes problems in HTMLMediaElement. QTKit's 'ended' event 
    // fires when playing in reverse so don't update duration when at time zero!
    float now = currentTime();
    if (now > 0)
        m_cachedDuration = now;

    updateStates();
    m_player->timeChanged();
}

#if USE(ACCELERATED_COMPOSITING) && !(PLATFORM(QT) && USE(QTKIT))
#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
static bool layerIsDescendentOf(PlatformLayer* child, PlatformLayer* descendent)
{
    if (!child || !descendent)
        return false;

    do {
        if (child == descendent)
            return true;
    } while((child = [child superlayer]));

    return false;
}
#endif

void MediaPlayerPrivateQTKit::layerHostChanged(PlatformLayer* rootLayer)
{
#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
    if (!rootLayer)
        return;

    if (layerIsDescendentOf(m_qtVideoLayer.get(), rootLayer)) {
        // We own a child layer of a layer which has switched contexts.  
        // Tear down our layer, and set m_visible to false, so that the 
        // next time setVisible(true) is called, the layer will be re-
        // created in the correct context.
        tearDownVideoRendering();
        m_visible = false;
    }
#else
    UNUSED_PARAM(rootLayer);
#endif
}
#endif

void MediaPlayerPrivateQTKit::setSize(const IntSize&) 
{ 
    // Don't resize the view now because [view setFrame] also resizes the movie itself, and because
    // the renderer calls this function immediately when we report a size change (QTMovieSizeDidChangeNotification)
    // we can get into a feedback loop observing the size change and resetting the size, and this can cause
    // QuickTime to miss resetting a movie's size when the media size changes (as happens with an rtsp movie
    // once the rtsp server sends the track sizes). Instead we remember the size passed to paint() and resize
    // the view when it changes.
    // <rdar://problem/6336092> REGRESSION: rtsp movie does not resize correctly
}

void MediaPlayerPrivateQTKit::setVisible(bool b)
{
    if (m_visible != b) {
        m_visible = b;
        if (b)
            setUpVideoRendering();
        else
            tearDownVideoRendering();
    }
}

bool MediaPlayerPrivateQTKit::hasAvailableVideoFrame() const
{
    // When using a QTMovieLayer return true as soon as the movie reaches QTMovieLoadStatePlayable 
    // because although we don't *know* when the first frame has decoded, by the time we get and 
    // process the notification a frame should have propagated the VisualContext and been set on
    // the layer.
    if (currentRenderingMode() == MediaRenderingMovieLayer)
        return m_readyState >= MediaPlayer::HaveCurrentData;

    // When using the software renderer QuickTime signals that a frame is available so we might as well
    // wait until we know that a frame has been drawn.
    return m_videoFrameHasDrawn;
}

void MediaPlayerPrivateQTKit::repaint()
{
    if (m_hasUnsupportedTracks)
        return;

#if DRAW_FRAME_RATE
    if (m_startedPlaying) {
        m_frameCountWhilePlaying++;
        // to eliminate preroll costs from our calculation,
        // our frame rate calculation excludes the first frame drawn after playback starts
        if (1==m_frameCountWhilePlaying)
            m_timeStartedPlaying = [NSDate timeIntervalSinceReferenceDate];
    }
#endif
    m_videoFrameHasDrawn = true;
    m_player->repaint();
}

void MediaPlayerPrivateQTKit::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& r)
{
    id qtVideoRenderer = m_qtVideoRenderer.get();
    if (!qtVideoRenderer && currentRenderingMode() == MediaRenderingMovieLayer) {
        // We're being told to render into a context, but we already have the
        // MovieLayer going. This probably means we've been called from <canvas>.
        // Set up a QTVideoRenderer to use, but one that doesn't register for
        // update callbacks. That way, it won't bother us asking to repaint.
        createQTVideoRenderer(QTVideoRendererModeDefault);
        qtVideoRenderer = m_qtVideoRenderer.get();
    }
    paint(context, r);
}

void MediaPlayerPrivateQTKit::paint(GraphicsContext* context, const IntRect& r)
{
    if (context->paintingDisabled() || m_hasUnsupportedTracks)
        return;
    NSView *view = m_qtMovieView.get();
    id qtVideoRenderer = m_qtVideoRenderer.get();
    if (!view && !qtVideoRenderer)
        return;

    [m_objcObserver.get() setDelayCallbacks:YES];
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    NSGraphicsContext* newContext;
    FloatSize scaleFactor(1.0f, -1.0f);
    IntRect paintRect(IntPoint(0, 0), IntSize(r.width(), r.height()));

#if PLATFORM(QT) && USE(QTKIT)
    // In Qt, GraphicsContext is a QPainter so every transformations applied on it won't matter because here
    // the video is rendered by QuickTime not by Qt.
    CGContextRef cgContext = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
    CGContextSaveGState(cgContext);
    CGContextSetInterpolationQuality(cgContext, kCGInterpolationLow);
    CGContextTranslateCTM(cgContext, r.x(), r.y() + r.height());
    CGContextScaleCTM(cgContext, scaleFactor.width(), scaleFactor.height());

    newContext = [NSGraphicsContext currentContext];
#else
    GraphicsContextStateSaver stateSaver(*context);
    context->translate(r.x(), r.y() + r.height());
    context->scale(scaleFactor);
    context->setImageInterpolationQuality(InterpolationLow);

    newContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context->platformContext() flipped:NO];
#endif
    // draw the current video frame
    if (qtVideoRenderer) {
        [NSGraphicsContext saveGraphicsState];
        [NSGraphicsContext setCurrentContext:newContext];
        [(id<WebKitVideoRenderingDetails>)qtVideoRenderer drawInRect:paintRect];
        [NSGraphicsContext restoreGraphicsState];
    } else {
        if (m_rect != r) {
             m_rect = r;
            if (m_player->inMediaDocument()) {
                // the QTMovieView needs to be placed in the proper location for document mode
                [view setFrame:m_rect];
            }
            else {
                // We don't really need the QTMovieView in any specific location so let's just get it out of the way
                // where it won't intercept events or try to bring up the context menu.
                IntRect farAwayButCorrectSize(m_rect);
                farAwayButCorrectSize.move(-1000000, -1000000);
                [view setFrame:farAwayButCorrectSize];
            }
        }

        if (m_player->inMediaDocument()) {
            // If we're using a QTMovieView in a media document, the view may get layer-backed. AppKit won't update
            // the layer hosting correctly if we call displayRectIgnoringOpacity:inContext:, so use displayRectIgnoringOpacity:
            // in this case. See <rdar://problem/6702882>.
            [view displayRectIgnoringOpacity:paintRect];
        } else
            [view displayRectIgnoringOpacity:paintRect inContext:newContext];
    }

#if DRAW_FRAME_RATE
    // Draw the frame rate only after having played more than 10 frames.
    if (m_frameCountWhilePlaying > 10) {
        Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;
        Document* document = frame ? frame->document() : NULL;
        RenderObject* renderer = document ? document->renderer() : NULL;
        RenderStyle* styleToUse = renderer ? renderer->style() : NULL;
        if (styleToUse) {
            double frameRate = (m_frameCountWhilePlaying - 1) / ( m_startedPlaying ? ([NSDate timeIntervalSinceReferenceDate] - m_timeStartedPlaying) :
                (m_timeStoppedPlaying - m_timeStartedPlaying) );
            String text = String::format("%1.2f", frameRate);
            TextRun textRun(text.characters(), text.length());
            const Color color(255, 0, 0);
            context->scale(FloatSize(1.0f, -1.0f));    
            context->setStrokeColor(color, styleToUse->colorSpace());
            context->setStrokeStyle(SolidStroke);
            context->setStrokeThickness(1.0f);
            context->setFillColor(color, styleToUse->colorSpace());
            context->drawText(styleToUse->font(), textRun, IntPoint(2, -3));
        }
    }
#endif
#if PLATFORM(QT) && USE(QTKIT)
    CGContextRestoreGState(cgContext);
#endif
    END_BLOCK_OBJC_EXCEPTIONS;
    [m_objcObserver.get() setDelayCallbacks:NO];
}

static void addFileTypesToCache(NSArray * fileTypes, HashSet<String> &cache)
{
    int count = [fileTypes count];
    for (int n = 0; n < count; n++) {
        CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]);
        RetainPtr<CFStringRef> uti(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL));
        if (!uti)
            continue;
        RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType));
        if (mime)
            cache.add(mime.get());

        // -movieFileTypes: returns both file extensions and OSTypes. The later are surrounded by single
        // quotes, eg. 'MooV', so don't bother looking at those.
        if (CFStringGetCharacterAtIndex(ext, 0) != '\'') {
            // UTI is missing many media related MIME types supported by QTKit (see rdar://6434168), and not all
            // web servers use the MIME type UTI returns for an extension (see rdar://7875393), so even if UTI 
            // has a type for this extension add any types in hard coded table in the MIME type regsitry.
            Vector<String> typesForExtension = MIMETypeRegistry::getMediaMIMETypesForExtension(ext);
            unsigned count = typesForExtension.size();
            for (unsigned ndx = 0; ndx < count; ++ndx) {
                if (!cache.contains(typesForExtension[ndx]))
                    cache.add(typesForExtension[ndx]);
            }
        }
    }    
}

static HashSet<String> mimeCommonTypesCache()
{
    DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
    static bool typeListInitialized = false;

    if (!typeListInitialized) {
        typeListInitialized = true;
        NSArray* fileTypes = [QTMovie movieFileTypes:QTIncludeCommonTypes];
        addFileTypesToCache(fileTypes, cache);
    }
    
    return cache;
} 

static HashSet<String> mimeModernTypesCache()
{
    DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
    static bool typeListInitialized = false;
    
    if (!typeListInitialized) {
        typeListInitialized = true;
        NSArray* fileTypes = [QTMovie movieFileTypes:(QTMovieFileTypeOptions)wkQTIncludeOnlyModernMediaFileTypes()];
        addFileTypesToCache(fileTypes, cache);
    }
    
    return cache;
} 

void MediaPlayerPrivateQTKit::getSupportedTypes(HashSet<String>& supportedTypes)
{
    supportedTypes = mimeModernTypesCache();
    
    // Note: this method starts QTKitServer if it isn't already running when in 64-bit because it has to return the list 
    // of every MIME type supported by QTKit.
    HashSet<String> commonTypes = mimeCommonTypesCache();
    HashSet<String>::const_iterator it = commonTypes.begin();
    HashSet<String>::const_iterator end = commonTypes.end();
    for (; it != end; ++it)
        supportedTypes.add(*it);
} 

MediaPlayer::SupportsType MediaPlayerPrivateQTKit::supportsType(const String& type, const String& codecs, const KURL&)
{
    // Only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an
    // extended MIME type yet.

    // Due to <rdar://problem/10777059>, avoid calling the mime types cache functions if at
    // all possible:
    if (!type.startsWith("video/") && !type.startsWith("audio/"))
        return MediaPlayer::IsNotSupported;

    // We check the "modern" type cache first, as it doesn't require QTKitServer to start.
    if (mimeModernTypesCache().contains(type) || mimeCommonTypesCache().contains(type))
        return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported;

    return MediaPlayer::IsNotSupported;
}

#if ENABLE(ENCRYPTED_MEDIA)
MediaPlayer::SupportsType MediaPlayerPrivateQTKit::extendedSupportsType(const String& type, const String& codecs, const String& keySystem, const KURL& url)
{
    // QTKit does not support any encrytped media, so return IsNotSupported if the keySystem is non-NULL:
    if (!keySystem.isNull() || !keySystem.isEmpty())
        return MediaPlayer::IsNotSupported;

    return supportsType(type, codecs, url);;
}
#endif

bool MediaPlayerPrivateQTKit::isAvailable()
{
    // On 10.5 and higher, QuickTime will always be new enough for <video> and <audio> support, so we just check that the framework can be loaded.
    return QTKitLibrary();
}

void MediaPlayerPrivateQTKit::getSitesInMediaCache(Vector<String>& sites) 
{
    NSArray *mediaSites = wkQTGetSitesInMediaDownloadCache();
    for (NSString *site in mediaSites)
        sites.append(site);
}

void MediaPlayerPrivateQTKit::clearMediaCache()
{
    LOG(Media, "MediaPlayerPrivateQTKit::clearMediaCache()");
    wkQTClearMediaDownloadCache();
}

void MediaPlayerPrivateQTKit::clearMediaCacheForSite(const String& site)
{
    LOG(Media, "MediaPlayerPrivateQTKit::clearMediaCacheForSite()");
    wkQTClearMediaDownloadCacheForSite(site);
}

void MediaPlayerPrivateQTKit::disableUnsupportedTracks()
{
    LOG(Media, "MediaPlayerPrivateQTKit::disableUnsupportedTracks(%p)", this);

    if (!m_qtMovie) {
        m_enabledTrackCount = 0;
        m_totalTrackCount = 0;
        return;
    }
    
    static HashSet<String>* allowedTrackTypes = 0;
    if (!allowedTrackTypes) {
        allowedTrackTypes = new HashSet<String>;
        allowedTrackTypes->add(QTMediaTypeVideo);
        allowedTrackTypes->add(QTMediaTypeSound);
        allowedTrackTypes->add(QTMediaTypeText);
        allowedTrackTypes->add(QTMediaTypeBase);
        allowedTrackTypes->add(QTMediaTypeMPEG);
        allowedTrackTypes->add("clcp"); // Closed caption
        allowedTrackTypes->add("sbtl"); // Subtitle
        allowedTrackTypes->add("odsm"); // MPEG-4 object descriptor stream
        allowedTrackTypes->add("sdsm"); // MPEG-4 scene description stream
        allowedTrackTypes->add("tmcd"); // timecode
        allowedTrackTypes->add("tc64"); // timcode-64
        allowedTrackTypes->add("tmet"); // timed metadata
    }
    
    NSArray *tracks = [m_qtMovie.get() tracks];
    
    m_totalTrackCount = [tracks count];
    m_enabledTrackCount = m_totalTrackCount;
    for (unsigned trackIndex = 0; trackIndex < m_totalTrackCount; trackIndex++) {
        // Grab the track at the current index. If there isn't one there, then
        // we can move onto the next one.
        QTTrack *track = [tracks objectAtIndex:trackIndex];
        if (!track)
            continue;
        
        // Check to see if the track is disabled already, we should move along.
        // We don't need to re-disable it.
        if (![track isEnabled]) {
            --m_enabledTrackCount;
            continue;
        }
        
        // Get the track's media type.
        NSString *mediaType = [track attributeForKey:QTTrackMediaTypeAttribute];
        if (!mediaType)
            continue;

        // Test whether the media type is in our white list.
        if (!allowedTrackTypes->contains(mediaType)) {
            // If this track type is not allowed, then we need to disable it.
            [track setEnabled:NO];
            --m_enabledTrackCount;
            m_hasUnsupportedTracks = true;
        }

        // Disable chapter tracks. These are most likely to lead to trouble, as
        // they will be composited under the video tracks, forcing QT to do extra
        // work.
        QTTrack *chapterTrack = [track performSelector:@selector(chapterlist)];
        if (!chapterTrack)
            continue;
        
        // Try to grab the media for the track.
        QTMedia *chapterMedia = [chapterTrack media];
        if (!chapterMedia)
            continue;
        
        // Grab the media type for this track.
        id chapterMediaType = [chapterMedia attributeForKey:QTMediaTypeAttribute];
        if (!chapterMediaType)
            continue;
        
        // Check to see if the track is a video track. We don't care about
        // other non-video tracks.
        if (![chapterMediaType isEqual:QTMediaTypeVideo])
            continue;
        
        // Check to see if the track is already disabled. If it is, we
        // should move along.
        if (![chapterTrack isEnabled])
            continue;
        
        // Disable the evil, evil track.
        [chapterTrack setEnabled:NO];
        --m_enabledTrackCount;
        m_hasUnsupportedTracks = true;
    }
}

void MediaPlayerPrivateQTKit::sawUnsupportedTracks()
{
    m_hasUnsupportedTracks = true;
    m_player->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_player);
}

#if USE(ACCELERATED_COMPOSITING) && !(PLATFORM(QT) && USE(QTKIT))
bool MediaPlayerPrivateQTKit::supportsAcceleratedRendering() const
{
    return isReadyForVideoSetup() && getQTMovieLayerClass() != Nil;
}

void MediaPlayerPrivateQTKit::acceleratedRenderingStateChanged()
{
    // Set up or change the rendering path if necessary.
    setUpVideoRendering();
}
#endif

bool MediaPlayerPrivateQTKit::hasSingleSecurityOrigin() const
{
    if (!m_qtMovie)
        return false;

    RefPtr<SecurityOrigin> resolvedOrigin = SecurityOrigin::create(KURL(wkQTMovieResolvedURL(m_qtMovie.get())));
    RefPtr<SecurityOrigin> requestedOrigin = SecurityOrigin::createFromString(m_movieURL);
    return resolvedOrigin->isSameSchemeHostPort(requestedOrigin.get());
}

MediaPlayer::MovieLoadType MediaPlayerPrivateQTKit::movieLoadType() const
{
    if (!m_qtMovie)
        return MediaPlayer::Unknown;

    MediaPlayer::MovieLoadType movieType = (MediaPlayer::MovieLoadType)wkQTMovieGetType(m_qtMovie.get());

    // Can't include WebKitSystemInterface from WebCore so we can't get the enum returned
    // by wkQTMovieGetType, but at least verify that the value is in the valid range.
    ASSERT(movieType >= MediaPlayer::Unknown && movieType <= MediaPlayer::LiveStream);

    return movieType;
}

void MediaPlayerPrivateQTKit::setPreload(MediaPlayer::Preload preload)
{
    m_preload = preload;
    if (m_preload == MediaPlayer::None)
        return;

    if (!m_qtMovie)
        resumeLoad();
    else if (m_preload == MediaPlayer::Auto)
        [m_qtMovie.get() setAttribute:[NSNumber numberWithBool:NO] forKey:@"QTMovieLimitReadAheadAttribute"];
}

float MediaPlayerPrivateQTKit::mediaTimeForTimeValue(float timeValue) const
{
    if (!metaDataAvailable())
        return timeValue;

    QTTime qttime = createQTTime(timeValue);
    return static_cast<float>(qttime.timeValue) / qttime.timeScale;
}

void MediaPlayerPrivateQTKit::setPrivateBrowsingMode(bool privateBrowsing)
{
    m_privateBrowsing = privateBrowsing;
    if (!m_qtMovie)
        return;
    [m_qtMovie.get() setAttribute:[NSNumber numberWithBool:!privateBrowsing] forKey:@"QTMovieAllowPersistentCacheAttribute"];
}

} // namespace WebCore

@implementation WebCoreMovieObserver

- (id)initWithCallback:(MediaPlayerPrivateQTKit*)callback
{
    m_callback = callback;
    return [super init];
}

- (void)disconnect
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    m_callback = 0;
}

-(NSMenu*)menuForEventDelegate:(NSEvent*)theEvent
{
    // Get the contextual menu from the QTMovieView's superview, the frame view
    return [[m_view superview] menuForEvent:theEvent];
}

-(void)setView:(NSView*)view
{
    m_view = view;
}

-(void)repaint
{
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0.];
    else if (m_callback)
        m_callback->repaint();
}

- (void)loadStateChanged:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0];
    else
        m_callback->loadStateChanged();
}

- (void)loadedRangesChanged:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0];
    else
        m_callback->loadedRangesChanged();
}

- (void)rateChanged:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0];
    else
        m_callback->rateChanged();
}

- (void)sizeChanged:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0];
    else
        m_callback->sizeChanged();
}

- (void)timeChanged:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0];
    else
        m_callback->timeChanged();
}

- (void)didEnd:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    if (m_delayCallbacks)
        [self performSelector:_cmd withObject:nil afterDelay:0];
    else
        m_callback->didEnd();
}

- (void)newImageAvailable:(NSNotification *)unusedNotification
{
    UNUSED_PARAM(unusedNotification);
    [self repaint];
}

- (void)layerHostChanged:(NSNotification *)notification
{
#if USE(ACCELERATED_COMPOSITING) && !(PLATFORM(QT) && USE(QTKIT))
    CALayer* rootLayer = static_cast<CALayer*>([notification object]);
    m_callback->layerHostChanged(rootLayer);
#else
    UNUSED_PARAM(notification);
#endif
}

- (void)setDelayCallbacks:(BOOL)shouldDelay
{
    m_delayCallbacks = shouldDelay;
}

@end

#endif
