[webkit-reviews] review denied: [Bug 34005] Safari pegs CPU and drops tons of frames using HTML5 Vimeo player : [Attachment 54599] Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Apr 30 17:58:28 PDT 2010


Anders Carlsson <andersca at apple.com> has denied Jer Noble
<jer.noble at apple.com>'s request for review:
Bug 34005: Safari pegs CPU and drops tons of frames using HTML5 Vimeo player
https://bugs.webkit.org/show_bug.cgi?id=34005

Attachment 54599: Part 2: QTMovieWin: New Classes QTPixelBuffer,
QTCFDictionary, and QTMovieVisualContext
https://bugs.webkit.org/attachment.cgi?id=54599&action=review

------- Additional Comments from Anders Carlsson <andersca at apple.com>
> Index: WebCore/platform/graphics/win/QTCFDictionary.cpp
> ===================================================================
> --- WebCore/platform/graphics/win/QTCFDictionary.cpp	(revision 0)
> +++ WebCore/platform/graphics/win/QTCFDictionary.cpp	(revision 0)
> @@ -0,0 +1,60 @@
> +/*
> + * Copyright (C) 2007, 2008, 2009, 2010 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. 
> + */
> +
> +#include "config.h"
> +
> +#include "QTCFDictionary.h"
> +
> +#include <CFData.h>
> +#include <windows.h>
> +
> +CFDataRef QTCFPropertyListCreateXMLData(CFAllocatorRef allocator,
CFPropertyListRef propertyList)
> +{
> +
> +    typedef CFDataRef (* pfnCFPropertyListCreateXMLData)(CFAllocatorRef
allocator, CFPropertyListRef propertyList);
> +    static pfnCFPropertyListCreateXMLData pCFPropertyListCreateXMLData = 0;
> +    if (!pCFPropertyListCreateXMLData) {
> +	   HMODULE qtcfDLL = LoadLibraryW(L"QTCF.dll");
> +	   if (qtcfDLL)
> +	       pCFPropertyListCreateXMLData =
reinterpret_cast<pfnCFPropertyListCreateXMLData>(GetProcAddress(qtcfDLL,
"QTCF_CFPropertyListCreateXMLData"));
> +    }
> +
> +    if (pCFPropertyListCreateXMLData)
> +	   return pCFPropertyListCreateXMLData(allocator, propertyList);
> +    return 0;
> +}
> +
> +CFDictionaryRef QTCFDictionaryCreateCopyWithDataCallback(CFAllocatorRef
allocator, CFDictionaryRef dictionary, QTCFDictonaryCreateFromDataCallback
callback) 
> +{
> +    ASSERT(dictionary);
> +    ASSERT(callback);
> +
> +    CFDataRef data = QTCFPropertyListCreateXMLData(kCFAllocatorDefault,
dictionary);
> +    CFDictionaryRef outputDictionary = callback(allocator,
CFDataGetBytePtr(data), CFDataGetLength(data));
> +    if (data)
> +	   CFRelease(data);
> +
> +    return outputDictionary;
> +}
> Index: WebCore/platform/graphics/win/QTCFDictionary.h
> ===================================================================
> --- WebCore/platform/graphics/win/QTCFDictionary.h	(revision 0)
> +++ WebCore/platform/graphics/win/QTCFDictionary.h	(revision 0)
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2007, 2008, 2009, 2010 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. 
> + */
> +
> +#ifndef QTCFDictionary_h
> +#define QTCFDictionary_h
> +
> +#ifdef QTMOVIEWIN_EXPORTS
> +#define QTMOVIEWIN_API __declspec(dllexport)
> +#else
> +#define QTMOVIEWIN_API __declspec(dllimport)
> +#endif
> +
> +#include <CoreFoundation/CFBase.h>
> +
> +typedef const struct __CFDictionary * CFDictionaryRef;
> +typedef const struct __CFAllocator * CFAllocatorRef;
> +
> +typedef CFDictionaryRef (*
QTCFDictonaryCreateFromDataCallback)(CFAllocatorRef, const UInt8*, CFIndex);
> +
> +QTMOVIEWIN_API CFDictionaryRef
QTCFDictionaryCreateCopyWithDataCallback(CFAllocatorRef, CFDictionaryRef,
QTCFDictonaryCreateFromDataCallback);
> +
> +#endif
> Index: WebCore/platform/graphics/win/QTMovieVisualContext.cpp
> ===================================================================
> --- WebCore/platform/graphics/win/QTMovieVisualContext.cpp	(revision 0)
> +++ WebCore/platform/graphics/win/QTMovieVisualContext.cpp	(revision 0)
> @@ -0,0 +1,252 @@
> +/*
> + * Copyright (C) 2007, 2008, 2009, 2010 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. 
> + */
> +#include "config.h"
> +
> +#include "QTMovieVisualContext.h"
> +
> +#include "QTMovieTask.h"
> +#include <CVBase.h>
> +#include <CVHostTime.h>
> +#include <ImageCompression.h>
> +#include <Movies.h>
> +#include <d3d9types.h>
> +#include <windows.h>
> +
> +struct QTCVTimeStamp {
> +    CVTimeStamp t;
> +};
> +
> +class QTMovieVisualContextPriv {
> +public:
> +    QTMovieVisualContextPriv(QTMovieVisualContext* parent,
QTMovieVisualContextClient* client, CFDictionaryRef options);
> +    ~QTMovieVisualContextPriv();
> +
> +    bool isImageAvailableForTime(const QTCVTimeStamp*);
> +    QTPixelBuffer imageForTime(const QTCVTimeStamp*);
> +    void task();
> +
> +    QTVisualContextRef get();
> +
> +    double getCurrentHostTime();
> +    double getHostClockFrequency();
> +
> +    void setMovie(RefPtr<QTMovie>);
> +    RefPtr<QTMovie> movie() const;
> +    
> +    static void imageAvailableCallback(QTVisualContextRef visualContext,
const CVTimeStamp *timeStamp, void *refCon);
> +
> +private:
> +    QTMovieVisualContext* m_parent;
> +    QTMovieVisualContextClient* m_client;
> +    QTVisualContextRef m_visualContext;
> +    RefPtr<QTMovie> m_movie;
> +
> +};
> +
> +QTMovieVisualContextPriv::QTMovieVisualContextPriv(QTMovieVisualContext*
parent, QTMovieVisualContextClient* client, CFDictionaryRef options) 
> +	   : m_parent(parent)
> +	   , m_client(client)
> +	   , m_visualContext(0)
> +{
> +    HMODULE qtmlDLL = ::LoadLibraryW(L"QTMLClient.dll");
> +    if (qtmlDLL) {
> +	   typedef OSStatus ( __cdecl
*pfnQTPixelBufferContextCreate)(CFAllocatorRef, CFDictionaryRef,
QTVisualContextRef*);
> +	   pfnQTPixelBufferContextCreate pPixelBufferContextCreate =
reinterpret_cast<pfnQTPixelBufferContextCreate>(GetProcAddress(qtmlDLL,
"QTPixelBufferContextCreate"));
> +	   if (pPixelBufferContextCreate) {
> +	       OSStatus status = pPixelBufferContextCreate(kCFAllocatorDefault,
options, &m_visualContext);
> +	       if (status == noErr && m_visualContext)
> +		   QTVisualContextSetImageAvailableCallback(m_visualContext,
&QTMovieVisualContextPriv::imageAvailableCallback, static_cast<void*>(this));
> +	   }
> +    }
> +}
> +
> +QTMovieVisualContextPriv::~QTMovieVisualContextPriv()
> +{
> +}
> +
> +bool QTMovieVisualContextPriv::isImageAvailableForTime(const QTCVTimeStamp*
timeStamp)
> +{
> +    if (!m_visualContext)
> +	   return false;
> +
> +    return QTVisualContextIsNewImageAvailable(m_visualContext,
reinterpret_cast<const CVTimeStamp*>(timeStamp)); 
> +}
> +
> +QTPixelBuffer QTMovieVisualContextPriv::imageForTime(const QTCVTimeStamp*
timeStamp)
> +{
> +    QTPixelBuffer pixelBuffer;
> +    if (m_visualContext) {
> +	   CVImageBufferRef newImage = 0;
> +	   OSStatus status = QTVisualContextCopyImageForTime(m_visualContext,
kCFAllocatorDefault, reinterpret_cast<const CVTimeStamp*>(timeStamp),
&newImage);
> +	   if (status == noErr) {
> +	       pixelBuffer.set(newImage);
> +	       CVPixelBufferRelease(newImage);
> +	   }
> +    }
> +    return pixelBuffer;
> +}
> +
> +void QTMovieVisualContextPriv::task()
> +{
> +    if (m_visualContext)
> +	   QTVisualContextTask(m_visualContext);
> +}
> +
> +QTVisualContextRef QTMovieVisualContextPriv::get() 
> +{
> +    return m_visualContext;
> +}
> +
> +void QTMovieVisualContextPriv::setMovie(RefPtr<QTMovie> movie)
> +{
> +    if (m_movie) {
> +	   SetMovieVisualContext(m_movie->getMovieHandle(), 0);
> +	   m_movie = 0;
> +    }
> +
> +    if (movie)
> +	   OSStatus status = SetMovieVisualContext(movie->getMovieHandle(),
m_visualContext);
> +    
> +    m_movie = movie;
> +}
> +
> +RefPtr<QTMovie> QTMovieVisualContextPriv::movie() const
> +{
> +    return m_movie;
> +}
> +
> +void QTMovieVisualContextPriv::imageAvailableCallback(QTVisualContextRef
visualContext, const CVTimeStamp *timeStamp, void *refCon) 
> +{
> +    if (!refCon)
> +	   return;
> +
> +    QTMovieVisualContextPriv* vc =
static_cast<QTMovieVisualContextPriv*>(refCon);
> +    if (!vc->m_client)
> +	   return;
> +
> +    vc->m_client->imageAvailableForTime(reinterpret_cast<const
QTCVTimeStamp*>(timeStamp));
> +}
> +
> +static OSStatus SetNumberValue(CFMutableDictionaryRef inDict, CFStringRef
inKey, SInt32 inValue)
> +{
> +    CFNumberRef number;
> + 
> +    number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
&inValue);
> +    if (!number) 
> +	   return coreFoundationUnknownErr;
> + 
> +    CFDictionarySetValue(inDict, inKey, number);
> + 
> +    CFRelease(number);
> + 
> +    return noErr;
> +}
> +
> +CFDictionaryRef QTMovieVisualContext::getCGImageOptions()
> +{
> +    static CFDictionaryRef options = 0;
> +
> +    if (!options) {
> +	   CFMutableDictionaryRef  pixelBufferOptions = 0;
> +	   CFMutableDictionaryRef  visualContextOptions = 0;
> +	   OSStatus		   status = noErr;
> +	   
> +	   // Pixel Buffer attributes
> +	   pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
> +							 
&kCFTypeDictionaryKeyCallBacks,
> +							 
&kCFTypeDictionaryValueCallBacks);
> +
> +	   // Use the k32BGRAPixelFormat, as QuartzCore will be able to use the
pixels directly,
> +	   // without needing an aditional copy or rendering pass:s
> +	   SetNumberValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey,
k32BGRAPixelFormat);
> +	       
> +	   // alignment
> +	   SetNumberValue(pixelBufferOptions,
kCVPixelBufferBytesPerRowAlignmentKey, 16);
> +
> +	   // compatability
> +	   SetNumberValue(pixelBufferOptions,
kCVPixelBufferCGImageCompatibilityKey, 1);
> +	
> +	   // QT Visual Context attributes
> +	   visualContextOptions =
CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
> +							   
&kCFTypeDictionaryKeyCallBacks,
> +							   
&kCFTypeDictionaryValueCallBacks);
> +	
> +	   // set the pixel buffer attributes for the visual context
> +	   CFDictionarySetValue(visualContextOptions,
> +				kQTVisualContextPixelBufferAttributesKey,
> +				pixelBufferOptions);
> +
> +	   if (pixelBufferOptions)
> +	       CFRelease(pixelBufferOptions);
> +    
> +	   options = visualContextOptions;
> +    }
> +
> +    return options;
> +}
> +
> +QTMovieVisualContext::QTMovieVisualContext(QTMovieVisualContextClient*
client, CFDictionaryRef options) 
> +    : m_private(new QTMovieVisualContextPriv(this, client, options))
> +{
> +}
> +
> +QTMovieVisualContext::~QTMovieVisualContext()
> +{
> +}
> +
> +bool QTMovieVisualContext::isImageAvailableForTime(const QTCVTimeStamp*
timeStamp)
> +{
> +    return m_private->isImageAvailableForTime(timeStamp);
> +}
> +
> +QTPixelBuffer QTMovieVisualContext::imageForTime(const QTCVTimeStamp*
timeStamp)
> +{
> +    return m_private->imageForTime(timeStamp);
> +}
> +
> +void QTMovieVisualContext::task()
> +{
> +    m_private->task();
> +}
> +
> +QTVisualContextRef QTMovieVisualContext::get() 
> +{
> +    return m_private->get();
> +}
> +
> +void QTMovieVisualContext::setMovie(RefPtr<QTMovie> movie)
> +{
> +    m_private->setMovie(movie);
> +}
> +
> +RefPtr<QTMovie> QTMovieVisualContext::movie() const
> +{
> +    return m_private->movie();
> +}
> +
> +double QTMovieVisualContext::currentHostTime()
> +{
> +    return CVGetCurrentHostTime() / CVGetHostClockFrequency();
> +}
> Index: WebCore/platform/graphics/win/QTMovieVisualContext.h
> ===================================================================
> --- WebCore/platform/graphics/win/QTMovieVisualContext.h	(revision 0)
> +++ WebCore/platform/graphics/win/QTMovieVisualContext.h	(revision 0)
> @@ -0,0 +1,81 @@
> +/*
> + * Copyright (C) 2007, 2008, 2009, 2010 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. 
> + */
> +
> +#ifndef QTMovieVisualContext_h
> +#define QTMovieVisualContext_h
> +
> +#ifdef QTMOVIEWIN_EXPORTS
> +#define QTMOVIEWIN_API __declspec(dllexport)
> +#else
> +#define QTMOVIEWIN_API __declspec(dllimport)
> +#endif
> +
> +#include "QTMovie.h"
> +#include "QTMovieTask.h"
> +#include "QTPixelBuffer.h"
> +#include <WTF/OwnPtr.h>
> +#include <WTF/RefCounted.h>
> +
> +typedef struct OpaqueQTVisualContext*   QTVisualContextRef;
> +
> +// QTCVTimeStamp is a struct containing only a CVTimeStamp.	This is to 
> +// work around the inability of CVTimeStamp to be forward declared, in 
> +// addition to it being declared in different header files when building
> +// the QTMovieWin and WebCore projects.
> +struct QTCVTimeStamp;
> +
> +class QTMovieVisualContextClient {
> +public:
> +    virtual void imageAvailableForTime(const QTCVTimeStamp*) = 0;
> +};
> +
> +class QTMOVIEWIN_API QTMovieVisualContext : public
RefCounted<QTMovieVisualContext> {
> +public:
> +    QTMovieVisualContext(QTMovieVisualContextClient*, CFDictionaryRef
options = 0);
> +    ~QTMovieVisualContext();
> +
> +    bool isImageAvailableForTime(const QTCVTimeStamp*);
> +    QTPixelBuffer imageForTime(const QTCVTimeStamp*);
> +    void task();
> +
> +    QTVisualContextRef get();
> +
> +    double getCurrentHostTime();
> +    double getHostClockFrequency();
> +
> +    void setMovie(RefPtr<QTMovie>);
> +    RefPtr<QTMovie> movie() const;
> +
> +    static CFDictionaryRef getCGImageOptions();
> +    static double currentHostTime();
> +
> +protected:
> +    void setupVisualContext();
> +
> +    friend class QTMovieVisualContextPriv;
> +    OwnPtr<QTMovieVisualContextPriv> m_private;
> +};
> +
> +#endif
> Index: WebCore/platform/graphics/win/QTPixelBuffer.cpp
> ===================================================================
> --- WebCore/platform/graphics/win/QTPixelBuffer.cpp	(revision 0)
> +++ WebCore/platform/graphics/win/QTPixelBuffer.cpp	(revision 0)
> @@ -0,0 +1,209 @@
> +/*
> + * Copyright (C) 2007, 2008, 2009, 2010 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. 
> + */
> +#include "config.h"
> +
> +#include "QTPixelBuffer.h"
> +
> +#include <CFString.h>
> +#include <CGColorSpace.h>
> +#include <CGImage.h>
> +#include <CVPixelBuffer.h>
> +#include <QuickDraw.h>
> +
> +QTPixelBuffer::QTPixelBuffer() : m_pixelBuffer(0) {}
> +
> +QTPixelBuffer::QTPixelBuffer(const QTPixelBuffer& p) :
m_pixelBuffer(p.m_pixelBuffer) 
> +{
> +    CVPixelBufferRetain(m_pixelBuffer);
> +}
> +
> +QTPixelBuffer::QTPixelBuffer(CVPixelBufferRef ref) : m_pixelBuffer(ref)
> +{
> +    CVPixelBufferRetain(m_pixelBuffer);
> +}
> +
> +QTPixelBuffer::~QTPixelBuffer() 
> +{
> +    clear();
> +}
> +
> +QTPixelBuffer& QTPixelBuffer::operator=(const QTPixelBuffer& p) 
> +{
> +    set(p.m_pixelBuffer);
> +    return *this;
> +}
> +
> +void QTPixelBuffer::set(CVPixelBufferRef ref)
> +{
> +    CVPixelBufferRetain(ref);
> +    CVPixelBufferRelease(m_pixelBuffer);
> +    m_pixelBuffer = ref;
> +}
> +
> +CVPixelBufferRef QTPixelBuffer::get()
> +{
> +    return m_pixelBuffer;
> +}
> +
> +void QTPixelBuffer::clear()
> +{
> +    CVPixelBufferRelease(m_pixelBuffer);
> +    m_pixelBuffer = 0;
> +}
> +
> +CVReturn QTPixelBuffer::lockBaseAddress()
> +{
> +    return CVPixelBufferLockBaseAddress(m_pixelBuffer, 0);
> +}
> +
> +CVReturn QTPixelBuffer::unlockBaseAddress()
> +{
> +    return CVPixelBufferUnlockBaseAddress(m_pixelBuffer, 0);
> +}
> +
> +size_t QTPixelBuffer::width()
> +{
> +    return CVPixelBufferGetWidth(m_pixelBuffer);
> +}
> +
> +size_t QTPixelBuffer::height()
> +{
> +    return CVPixelBufferGetHeight(m_pixelBuffer);
> +}
> +
> +unsigned long QTPixelBuffer::pixelFormatType()
> +{
> +    OSType pixelFormatType = CVPixelBufferGetPixelFormatType(m_pixelBuffer);

> +    return pixelFormatType;
> +}
> +
> +bool QTPixelBuffer::pixelFormatIs32ARGB()
> +{
> +    return CVPixelBufferGetPixelFormatType(m_pixelBuffer) ==
k32ARGBPixelFormat;
> +}
> +
> +bool QTPixelBuffer::pixelFormatIs32BGRA()
> +{
> +    return CVPixelBufferGetPixelFormatType(m_pixelBuffer) ==
k32BGRAPixelFormat;
> +}
> +
> +void* QTPixelBuffer::baseAddress()
> +{
> +    return CVPixelBufferGetBaseAddress(m_pixelBuffer);
> +}
> +
> +size_t QTPixelBuffer::bytesPerRow()
> +{
> +    return CVPixelBufferGetBytesPerRow(m_pixelBuffer);
> +}
> +
> +size_t QTPixelBuffer::dataSize()
> +{
> +    return CVPixelBufferGetDataSize(m_pixelBuffer);
> +}
> +
> +
> +bool QTPixelBuffer::isPlanar()
> +{
> +    return CVPixelBufferIsPlanar(m_pixelBuffer);
> +}
> +
> +size_t QTPixelBuffer::planeCount()
> +{
> +    return CVPixelBufferGetPlaneCount(m_pixelBuffer);
> +}
> +
> +size_t QTPixelBuffer::widthOfPlane(size_t plane)
> +{
> +    return CVPixelBufferGetWidthOfPlane(m_pixelBuffer, plane);
> +}
> +
> +size_t QTPixelBuffer::heightOfPlane(size_t plane)
> +{
> +    return CVPixelBufferGetHeightOfPlane(m_pixelBuffer, plane);
> +}
> +
> +void* QTPixelBuffer::baseAddressOfPlane(size_t plane)
> +{
> +    return CVPixelBufferGetBaseAddressOfPlane(m_pixelBuffer, plane);
> +}
> +
> +size_t QTPixelBuffer::bytesPerRowOfPlane(size_t plane)
> +{
> +    return CVPixelBufferGetBytesPerRowOfPlane(m_pixelBuffer, plane);
> +}
> +
> +void QTPixelBuffer::getExtendedPixels(size_t* left, size_t* right, size_t*
top, size_t* bottom)
> +{
> +    return CVPixelBufferGetExtendedPixels(m_pixelBuffer, left, right, top,
bottom);
> +}
> +
> +CFDictionaryRef QTPixelBuffer::attachments()
> +{
> +    CFDictionaryRef propogated = CVBufferGetAttachments(m_pixelBuffer,
kCVAttachmentMode_ShouldPropagate);
> +    return propogated;
> +}
> +
> +void QTPixelBuffer::retainCallback(void* refcon)
> +{
> +    CVPixelBufferRetain(static_cast<CVPixelBufferRef>(refcon));
> +}
> +
> +void QTPixelBuffer::releaseCallback(void* refcon)
> +{
> +    CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon));
> +}
> +
> +void QTPixelBuffer::imageQueueReleaseCallback(unsigned int type, uint64_t
id, void* refcon)
> +{
> +    CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon));
> +}
> +
> +void QTPixelBuffer::dataProviderReleaseBytePointerCallback(void* refcon,
const void* pointer)
> +{
> +    CVPixelBufferUnlockBaseAddress(static_cast<CVPixelBufferRef>(refcon),
0);
> +}
> +
> +const void* QTPixelBuffer::dataProviderGetBytePointerCallback(void* refcon)
> +{
> +    CVPixelBufferLockBaseAddress(static_cast<CVPixelBufferRef>(refcon), 0);
> +    return
CVPixelBufferGetBaseAddress(static_cast<CVPixelBufferRef>(refcon));
> +}
> +
> +size_t QTPixelBuffer::dataProviderGetBytesAtPositionCallback(void* refcon,
void* buffer, size_t position, size_t count)
> +{
> +    char* data =
(char*)CVPixelBufferGetBaseAddress(static_cast<CVPixelBufferRef>(refcon));
> +    size_t size =
CVPixelBufferGetDataSize(static_cast<CVPixelBufferRef>(refcon));
> +    if (size - position < count)
> +	   count = size - position;
> +
> +    memcpy(buffer, data+position, count);
> +    return count;
> +}
> +
> +void QTPixelBuffer::dataProviderReleaseInfoCallback(void* refcon)
> +{
> +    CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon));
> +}
> Index: WebCore/platform/graphics/win/QTPixelBuffer.h
> ===================================================================
> --- WebCore/platform/graphics/win/QTPixelBuffer.h	(revision 0)
> +++ WebCore/platform/graphics/win/QTPixelBuffer.h	(revision 0)
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (C) 2007, 2008, 2009, 2010 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. 
> + */
> +
> +#ifndef QTPixelBuffer_h
> +#define QTPixelBuffer_h
> +
> +#ifdef QTMOVIEWIN_EXPORTS
> +#define QTMOVIEWIN_API __declspec(dllexport)
> +#else
> +#define QTMOVIEWIN_API __declspec(dllimport)
> +#endif
> +
> +#include <stdint.h>
> +#include <wtf/RefCounted.h>
> +
> +typedef struct __CVBuffer *CVBufferRef;
> +typedef CVBufferRef CVPixelBufferRef;
> +typedef struct CGImage* CGImageRef;
> +typedef int32_t CVReturn;
> +typedef const struct __CFDictionary * CFDictionaryRef;
> +
> +// QTPixelBuffer wraps QuickTime's implementation of CVPixelBuffer, so its
functions are
> +// safe to call within WebKit.
> +class QTMOVIEWIN_API QTPixelBuffer : RefCounted<QTPixelBuffer> {
> +public:
> +    QTPixelBuffer();
> +    QTPixelBuffer(const QTPixelBuffer&);
> +    QTPixelBuffer(CVPixelBufferRef);
> +    QTPixelBuffer& operator=(const QTPixelBuffer&);
> +    ~QTPixelBuffer();
> +
> +    void set(CVPixelBufferRef);
> +    CVPixelBufferRef get();
> +    void clear();
> +
> +    CVReturn lockBaseAddress();
> +    CVReturn unlockBaseAddress();
> +    size_t width();
> +    size_t height();
> +
> +    unsigned long pixelFormatType();
> +    bool pixelFormatIs32ARGB();
> +    bool pixelFormatIs32BGRA();
> +    void* baseAddress();
> +    size_t bytesPerRow();
> +    size_t dataSize();
> +
> +    bool isPlanar();
> +    size_t planeCount();
> +    size_t widthOfPlane(size_t);
> +    size_t heightOfPlane(size_t);
> +    void* baseAddressOfPlane(size_t);
> +    size_t bytesPerRowOfPlane(size_t);
> +
> +    void getExtendedPixels(size_t* left, size_t* right, size_t* top, size_t*
bottom);
> +    CFDictionaryRef attachments();
> +
> +    // Generic CFRetain/CFRelease callbacks
> +    static void releaseCallback(void* refcon);
> +    static void retainCallback(void* refcon);
> +
> +    // CAImageQueue callbacks
> +    static void imageQueueReleaseCallback(unsigned int type, uint64_t id,
void* refcon);
> +
> +    // CGDataProvider callbacks
> +    static void dataProviderReleaseBytePointerCallback(void* refcon, const
void* pointer);
> +    static const void* dataProviderGetBytePointerCallback(void* refcon);
> +    static size_t dataProviderGetBytesAtPositionCallback(void* refcon, void*
buffer, size_t position, size_t count);
> +    static void dataProviderReleaseInfoCallback(void* refcon);
> +
> +private:
> +    CVPixelBufferRef m_pixelBuffer;
> +};
> +
> +#endif
WebCore/platform/graphics/win/QTMovieVisualContext.cpp:50
 +	QTVisualContextRef get();
I think this should be renamed to visualContext() or something other than
get().


WebCore/platform/graphics/win/QTMovieVisualContext.cpp:54
 +  
We mostly use get for functions that have out parameters. This should be
currentHostTime() and hostClockFrequency(). Can these be const?

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:56
 +	RefPtr<QTMovie> movie() const;
No need for this to return a RefPtr.

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:55
 +	void setMovie(RefPtr<QTMovie>);
This should take a PassRefPtr to reduce ref churn.

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:73
 +	HMODULE qtmlDLL = ::LoadLibraryW(L"QTMLClient.dll");
Should this be a static variable? Is it OK to load the library everytime a
QTMovieVisualContextPriv object is created?

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:74
 +	if (qtmlDLL) {
An early return here would reduce indentation.

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:105
 +		CVPixelBufferRelease(newImage);
Could QTPixelBuffer have an "adopt" member function that would take a
reference? If so the CVPixelBufferRelease call could be omitted.

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:134
 +  
Yup, looks like this could take a PassRefPtr.

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:138
 +  }
And this could return a QTMovie * instead of a RefPtr.

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:47
 +	QTPixelBuffer imageForTime(const QTCVTimeStamp*);
Can these be const?

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:123
 +  {
You could return early here if (movie == m_movie). (Especially when movie is a
PassRefPtr).

WebCore/platform/graphics/win/QTMovieVisualContext.h:63
 +	QTVisualContextRef get();
Again, a better name for this would be visualContext().

WebCore/platform/graphics/win/QTMovieVisualContext.h:66
 +	double getHostClockFrequency();
Same comments here as in QTMovieVisualContextPrivate.

WebCore/platform/graphics/win/QTMovieVisualContext.h:70
 +  
Same comments here as in QTMovieVisualContextPrivate.

WebCore/platform/graphics/win/QTPixelBuffer.cpp:35
 +  QTPixelBuffer::QTPixelBuffer() : m_pixelBuffer(0) {}
member initializers should go on a separate row.

WebCore/platform/graphics/win/QTPixelBuffer.cpp:37
 +  QTPixelBuffer::QTPixelBuffer(const QTPixelBuffer& p) :
m_pixelBuffer(p.m_pixelBuffer) 
Ditto.

WebCore/platform/graphics/win/QTPixelBuffer.cpp:42
 +  QTPixelBuffer::QTPixelBuffer(CVPixelBufferRef ref) : m_pixelBuffer(ref)
Ditto.

WebCore/platform/graphics/win/QTPixelBuffer.cpp:68
 +  }
Should be called "pixelBuffer" or something other than get.

WebCore/platform/graphics/win/QTPixelBuffer.cpp:74
 +  }
Does CVPixelBufferRelease work if m_pixelBuffer is 0?

WebCore/platform/graphics/win/QTPixelBuffer.h:62
 +  
Can width and height be const?

WebCore/platform/graphics/win/QTPixelBuffer.h:69
 +  
Can these be const? (Or at least some of them).

WebCore/platform/graphics/win/QTPixelBuffer.h:76
 +  
Const?

WebCore/platform/graphics/win/QTPixelBuffer.h:77
 +	void getExtendedPixels(size_t* left, size_t* right, size_t* top,
size_t* bottom);
Maybe references would be better than pointers here?

WebCore/platform/graphics/win/QTPixelBuffer.cpp:166
 +	return propogated;
Can just merge these into a single line.

WebCore/platform/graphics/win/QTPixelBuffer.h:51
 +	QTPixelBuffer& operator=(const QTPixelBuffer&);
Come to think of it, I don't think ref counted objects should be copyable. Are
the copy constructor and copy-assignment operators really needed?

WebCore/platform/graphics/win/QTPixelBuffer.h:82
 +	static void retainCallback(void* refcon);
What are these used for?

Patch looks good overall, but I'd like to see my comments addressed in a new
patch.


More information about the webkit-reviews mailing list