Bug 34005 - Safari pegs CPU and drops tons of frames using HTML5 Vimeo player
Summary: Safari pegs CPU and drops tons of frames using HTML5 Vimeo player
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Media (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows XP
: P2 Normal
Assignee: Nobody
URL: http://vimeo.com/7352118
Keywords: InRadar, PlatformOnly
Depends on:
Blocks: 38689
  Show dependency treegraph
 
Reported: 2010-01-22 08:56 PST by Adam Roben (:aroben)
Modified: 2010-05-08 00:00 PDT (History)
7 users (show)

See Also:


Attachments
Patch which breaks up QTMovieWin into QTMovieWin and QTMovie (65.83 KB, patch)
2010-04-27 19:06 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
New classes in QTMovieWin (31.67 KB, patch)
2010-04-27 19:07 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Changes to MediaPlayerPrivateQuickTimeWin (7.84 KB, patch)
2010-04-27 19:08 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
New class MediaPlayerPrivateQuickTimeVisualContext (39.68 KB, patch)
2010-04-27 19:09 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
New class MediaPlayerPrivateTaskTimer (4.24 KB, patch)
2010-04-27 19:11 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Added MediaPlayerPrivateQuickTimeWin support to MediaPlayer (907 bytes, patch)
2010-04-27 19:17 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Added cancelCallOnMainThread (3.83 KB, patch)
2010-04-27 19:17 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
ChangeLog changes. (9.07 KB, patch)
2010-04-27 19:18 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
VCProj project file changes (31.76 KB, patch)
2010-04-27 19:20 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Patch which breaks up QTMovieWin into QTMovieWin and QTMovie (66.18 KB, patch)
2010-04-27 20:46 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
New classes in QTMovieWin (32.38 KB, patch)
2010-04-27 20:47 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Changes to MediaPlayerPrivateQuickTimeWin (8.01 KB, patch)
2010-04-27 20:48 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
New class MediaPlayerPrivateQuickTimeVisualContext (39.85 KB, patch)
2010-04-27 20:49 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
New class MediaPlayerPrivateTaskTimer (4.41 KB, patch)
2010-04-27 20:49 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Added MediaPlayerPrivateQuickTimeWin support to MediaPlayer (985 bytes, patch)
2010-04-27 20:49 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 3: JavaScriptCore: Added cancelCallOnMainThread (4.01 KB, patch)
2010-04-27 20:51 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
ChangeLog changes. (9.09 KB, patch)
2010-04-27 20:52 PDT, Jer Noble
mjs: review-
Details | Formatted Diff | Diff
Part 1.1: QTMovieWin: The breakup of QTMovieWin (76.06 KB, patch)
2010-04-28 10:51 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext (26.86 KB, patch)
2010-04-28 10:52 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 1.2: WebCore: The breakup of MediaPlayerPrivateQuickTimeWin (12.39 KB, patch)
2010-04-28 10:53 PDT, Jer Noble
mjs: review+
Details | Formatted Diff | Diff
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext (37.79 KB, patch)
2010-04-28 10:55 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 5: WebCore: MediaPlayer adds MediaPlayerQuickTimeVisualContext to its list of MediaPlayerPrivates (979 bytes, patch)
2010-04-28 10:56 PDT, Jer Noble
eric.carlson: review+
Details | Formatted Diff | Diff
Part 6: VCProj project file changes (24.05 KB, patch)
2010-04-28 10:57 PDT, Jer Noble
eric.carlson: review+
Details | Formatted Diff | Diff
Part 1.1: QTMovieWin: The breakup of QTMovieWin (117.02 KB, patch)
2010-04-28 11:29 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext (43.84 KB, patch)
2010-04-28 11:30 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext (26.83 KB, patch)
2010-04-28 11:44 PDT, Jer Noble
andersca: review-
Details | Formatted Diff | Diff
Part 1.1: QTMovieWin: The breakup of QTMovieWin (117.12 KB, patch)
2010-04-28 11:44 PDT, Jer Noble
sam: review-
Details | Formatted Diff | Diff
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext (75.38 KB, patch)
2010-04-28 11:45 PDT, Jer Noble
eric.carlson: review-
Details | Formatted Diff | Diff
Part 3: JavaScriptCore: Added cancelCallOnMainThread (4.29 KB, patch)
2010-04-28 11:56 PDT, Jer Noble
mjs: review+
Details | Formatted Diff | Diff
Part 1.1: QTMovieWin: The breakup of QTMovieWin (95.50 KB, patch)
2010-05-04 15:28 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
Part 4.1: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext, the copy (35.12 KB, patch)
2010-05-04 15:29 PDT, Jer Noble
eric.carlson: review+
Details | Formatted Diff | Diff
Part 4.2: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext, the modification (40.28 KB, patch)
2010-05-04 15:30 PDT, Jer Noble
eric.carlson: review+
Details | Formatted Diff | Diff
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext (27.15 KB, patch)
2010-05-04 15:32 PDT, Jer Noble
andersca: review+
Details | Formatted Diff | Diff
Part 1.1: QTMovieWin: The breakup of QTMovieWin (27.15 KB, patch)
2010-05-04 15:35 PDT, Jer Noble
no flags Details | Formatted Diff | Diff
ChangeLog changes. (10.90 KB, patch)
2010-05-04 15:39 PDT, Jer Noble
mjs: review+
Details | Formatted Diff | Diff
Part 1.1: QTMovieWin: The breakup of QTMovieWin (165.41 KB, patch)
2010-05-05 13:23 PDT, Jer Noble
eric.carlson: review+
Details | Formatted Diff | Diff
Part 7: WebKit: FullscreenVideoController and QTMovieGWorld (2.45 KB, patch)
2010-05-07 18:21 PDT, Jer Noble
adele: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Roben (:aroben) 2010-01-22 08:56:35 PST
To reproduce:

1. Go to http://vimeo.com/7352118
2. Click "Switch to HTML5 player" in the bottom-right
3. When the page reloads, click the play button in the video player
4. Look in Task Manager

Safari is pegging the CPU and is dropping tons of video frames.

This does not happen on Mac.
Comment 1 Adam Roben (:aroben) 2010-01-22 08:57:12 PST
<rdar://problem/7569713>
Comment 2 Eric Carlson 2010-01-23 09:41:14 PST
https://bugs.webkit.org/show_bug.cgi?id=34007 makes the performance much better, though it still isn't great.
Comment 3 Jer Noble 2010-04-27 19:05:04 PDT
I am about to attach a number of patches to address this bug.  Each are interdependent on the others, and the build will likely fail unless all are submitted at once.
Comment 4 Jer Noble 2010-04-27 19:06:09 PDT
Created attachment 54499 [details]
Patch which breaks up QTMovieWin into QTMovieWin and QTMovie
Comment 5 Jer Noble 2010-04-27 19:07:46 PDT
Created attachment 54500 [details]
New classes in QTMovieWin
Comment 6 Jer Noble 2010-04-27 19:08:32 PDT
Created attachment 54501 [details]
Changes to MediaPlayerPrivateQuickTimeWin
Comment 7 Jer Noble 2010-04-27 19:09:32 PDT
Created attachment 54502 [details]
New class MediaPlayerPrivateQuickTimeVisualContext
Comment 8 Jer Noble 2010-04-27 19:11:38 PDT
Created attachment 54504 [details]
New class MediaPlayerPrivateTaskTimer
Comment 9 Jer Noble 2010-04-27 19:17:11 PDT
Created attachment 54505 [details]
Added MediaPlayerPrivateQuickTimeWin support to MediaPlayer
Comment 10 Jer Noble 2010-04-27 19:17:48 PDT
Created attachment 54506 [details]
Added cancelCallOnMainThread
Comment 11 Jer Noble 2010-04-27 19:18:31 PDT
Created attachment 54507 [details]
ChangeLog changes.
Comment 12 Jer Noble 2010-04-27 19:20:17 PDT
Created attachment 54508 [details]
VCProj project file changes
Comment 13 Jer Noble 2010-04-27 19:20:56 PDT
The proposed patches have now all been added.  The bug as a whole is ready for review.
Comment 14 Jer Noble 2010-04-27 20:46:38 PDT
Created attachment 54512 [details]
Patch which breaks up QTMovieWin into QTMovieWin and QTMovie

Corrected index prefix of patch.
Comment 15 Jer Noble 2010-04-27 20:47:35 PDT
Created attachment 54513 [details]
New classes in QTMovieWin

Corrected index prefix of patch.
Comment 16 Jer Noble 2010-04-27 20:48:33 PDT
Created attachment 54514 [details]
Changes to MediaPlayerPrivateQuickTimeWin

Corrected index prefix of patch.
Comment 17 Jer Noble 2010-04-27 20:49:00 PDT
Created attachment 54515 [details]
New class MediaPlayerPrivateQuickTimeVisualContext 

Corrected index prefix of patch.
Comment 18 Jer Noble 2010-04-27 20:49:32 PDT
Created attachment 54516 [details]
New class MediaPlayerPrivateTaskTimer 

Corrected index prefix of patch.
Comment 19 Jer Noble 2010-04-27 20:49:55 PDT
Created attachment 54517 [details]
Added MediaPlayerPrivateQuickTimeWin support to MediaPlayer 

Corrected index prefix of patch.
Comment 20 Jer Noble 2010-04-27 20:51:13 PDT
Created attachment 54518 [details]
Part 3: JavaScriptCore: Added cancelCallOnMainThread

Corrected index prefix of patch.
Comment 21 Jer Noble 2010-04-27 20:52:45 PDT
Created attachment 54519 [details]
ChangeLog changes. 

Corrected index prefix of patch.
Comment 22 WebKit Review Bot 2010-04-27 20:54:41 PDT
Attachment 54517 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1
WebCore/platform/graphics/MediaPlayer.cpp:50:  Alphabetical sorting problem.  [build/include_order] [4]
Total errors found: 1 in 1 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 23 Simon Fraser (smfr) 2010-04-27 21:06:58 PDT
It's going to be really hard to review this. Is it possible to make a set of incremental patches, each of which can stand on its own?
Comment 24 Adam Roben (:aroben) 2010-04-28 05:50:08 PDT
It looks like these patches introduce dependencies on CoreVideo. But CoreVideo isn't included in WebKitSupportLibrary, so this won't work.
Comment 25 Jer Noble 2010-04-28 08:13:14 PDT
The calls to CVGetCurrentHostTime and CVGetHostClockFrequency could be moved into QTMovieWin, which links against CVClient.lib, included in the QuickTime SDK.  I'll update the patches, removing the dependency on CoreVideo in WebKit.
Comment 26 Adam Roben (:aroben) 2010-04-28 08:18:36 PDT
(In reply to comment #25)
> The calls to CVGetCurrentHostTime and CVGetHostClockFrequency could be moved
> into QTMovieWin, which links against CVClient.lib, included in the QuickTime
> SDK.  I'll update the patches, removing the dependency on CoreVideo in WebKit.

Oh, I didn't realize CoreVideo was part of the QuickTime SDK. I think the only reason we have a separate QTMovieWin.dll is to work around conflicts between QuickTime's CF and the one used by WebKit. If that isn't an issue here, then having WebKit link to CoreVideo seems fine. (But your solution sounds like it will work, too.)
Comment 27 Jer Noble 2010-04-28 09:20:14 PDT
(In reply to comment #26)
> Oh, I didn't realize CoreVideo was part of the QuickTime SDK. I think the only
> reason we have a separate QTMovieWin.dll is to work around conflicts between
> QuickTime's CF and the one used by WebKit. If that isn't an issue here, then
> having WebKit link to CoreVideo seems fine. 

Unfortunately, QuickTime doesn't link against the same CoreVideo that we would, so there's a similar situation there to the CF one.

The only remaining issue is one of constants defined in CoreVideo headers.  Right now, we're doing things like: 
    if (buffer.pixelFormat() == kCVPixelFormat_32ARGB).  
We could convert those checks into things like: 
    if (buffer.pixelFormatIs32ARGB())
...and be in the clear there too.
Comment 28 Jer Noble 2010-04-28 10:51:09 PDT
Created attachment 54578 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

In this patch, QTMovie.cpp/h are new files.  In the obseleted patch <https://bugs.webkit.org/attachment.cgi?id=54512&action=edit> those files are diffed as modified copies of QTMovieWin.cpp/h.  The old patch may be easier to read while reviewing.
Comment 29 Jer Noble 2010-04-28 10:52:04 PDT
Created attachment 54580 [details]
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext
Comment 30 Jer Noble 2010-04-28 10:53:41 PDT
Created attachment 54581 [details]
Part 1.2: WebCore: The breakup of MediaPlayerPrivateQuickTimeWin
Comment 31 Adam Roben (:aroben) 2010-04-28 10:54:27 PDT
(In reply to comment #28)
> Created an attachment (id=54578) [details]
> Part 1.1: QTMovieWin: The breakup of QTMovieWin
> 
> In this patch, QTMovie.cpp/h are new files.  In the obseleted patch
> <https://bugs.webkit.org/attachment.cgi?id=54512&action=edit> those files are
> diffed as modified copies of QTMovieWin.cpp/h.  The old patch may be easier to
> read while reviewing.

Why not do it that way in this patch, too? Not only does it ease reviewing, but it preserves the code's history in Subversion.
Comment 32 Jer Noble 2010-04-28 10:55:05 PDT
Created attachment 54582 [details]
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext
Comment 33 Jer Noble 2010-04-28 10:56:25 PDT
Created attachment 54583 [details]
Part 5: WebCore: MediaPlayer adds MediaPlayerQuickTimeVisualContext to its list of MediaPlayerPrivates
Comment 34 Jer Noble 2010-04-28 10:57:41 PDT
Created attachment 54584 [details]
Part 6: VCProj project file changes
Comment 35 Jer Noble 2010-04-28 11:29:18 PDT
Created attachment 54594 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

QTMovie.cpp/h are back to being modified copies of QTMovieWin.cpp/h.
Comment 36 Jer Noble 2010-04-28 11:30:07 PDT
Created attachment 54595 [details]
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext

MediaPlayerPrivateQuickTimeVisualContext.cpp/h are back to being modified copies of MediaPlayerPrivateQuickTimeWin.cpp/h
Comment 37 WebKit Review Bot 2010-04-28 11:31:50 PDT
Attachment 54580 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1
WebCore/platform/graphics/win/QTMovieVisualContext.cpp:252:  Could not find a newline character at the end of the file.  [whitespace/ending_newline] [5]
WebCore/platform/graphics/win/QTPixelBuffer.cpp:30:  Alphabetical sorting problem.  [build/include_order] [4]
Total errors found: 2 in 6 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 38 WebKit Review Bot 2010-04-28 11:33:42 PDT
Attachment 54594 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1
WebCore/platform/graphics/win/QTMovie.cpp:32:  Alphabetical sorting problem.  [build/include_order] [4]
WebCore/platform/graphics/win/QTMovieWin.cpp:32:  Alphabetical sorting problem.  [build/include_order] [4]
Total errors found: 2 in 6 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 39 WebKit Review Bot 2010-04-28 11:34:16 PDT
Attachment 54595 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h:26:  #ifndef header guard has wrong style, please use: MediaPlayerPrivateQuickTimeVisualContext_h  [build/header_guard] [5]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:29:  Found other header before a header this file implements. Should be: config.h, primary header, blank line, and then alphabetically sorted.  [build/include_order] [4]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:31:  Alphabetical sorting problem.  [build/include_order] [4]
Total errors found: 3 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 40 Jer Noble 2010-04-28 11:44:08 PDT
Created attachment 54599 [details]
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext

Fixed style errors.
Comment 41 Jer Noble 2010-04-28 11:44:40 PDT
Created attachment 54600 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

Fixed style errors.
Comment 42 Jer Noble 2010-04-28 11:45:19 PDT
Created attachment 54601 [details]
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext

Fixed style errors.
Comment 43 Jer Noble 2010-04-28 11:48:25 PDT
Okay, the patches should finally be back to review-ready.  Simon, I've structured the patches so that each "Part" is intra-dependent and only depends on previous parts.  You should be able to review them in order.
Comment 44 Jer Noble 2010-04-28 11:56:43 PDT
Created attachment 54602 [details]
Part 3: JavaScriptCore: Added cancelCallOnMainThread

Updated the patch so that it will (hopefully) succeed against the latest revision of JavaScriptCore.
Comment 45 Maciej Stachowiak 2010-04-29 16:49:57 PDT
Comment on attachment 54602 [details]
Part 3: JavaScriptCore: Added cancelCallOnMainThread

It would be cleaner if callOnMainThread returned some kind of unique ID that you could pass to cancelCallOnMainThread, but perhaps that would be a more intrusive change. This seems like an ok approach though.

r=me (assuming there are appropriate ChangeLog entries with the other chunks; or it's ok to land this standalone w/ its own ChangeLog entry).
Comment 46 Maciej Stachowiak 2010-04-29 16:53:18 PDT
Comment on attachment 54581 [details]
Part 1.2: WebCore: The breakup of MediaPlayerPrivateQuickTimeWin

r=me assuming appropriate ChangeLog entry.
Comment 47 Maciej Stachowiak 2010-04-29 16:54:56 PDT
Comment on attachment 54519 [details]
ChangeLog changes. 

If you plan to land these separately, I suggest including them in the individual patches. Also, you should have the title of the bug above the bugzilla bug URL in our ChangeLog format.
Comment 48 Eric Carlson 2010-04-29 22:14:22 PDT
Comment on attachment 54584 [details]
Part 6: VCProj project file changes

> -<?xml version="1.0" encoding="Windows-1252"?>
> +<?xml version="1.0" encoding="windows-1251"?>
>
Please check with aroben or sfalken to see if the encoding change is significant.

rs=me assuming this change is OK.
Comment 49 Eric Carlson 2010-04-29 22:30:47 PDT
Comment on attachment 54601 [details]
Part 4: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext

It looks like in this patch you have both renamed the file and changed the code? If so it will be much easier to review if you svn mv it in one patch and changed the code in a follow up patch.
Comment 50 Adam Roben (:aroben) 2010-04-30 06:53:01 PDT
(In reply to comment #48)
> (From update of attachment 54584 [details])
> > -<?xml version="1.0" encoding="Windows-1252"?>
> > +<?xml version="1.0" encoding="windows-1251"?>
> >
> Please check with aroben or sfalken to see if the encoding change is
> significant.
> 
> rs=me assuming this change is OK.

Yes, this is fine.
Comment 51 Anders Carlsson 2010-04-30 17:58:29 PDT
Comment on attachment 54599 [details]
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext

> 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.
Comment 52 Sam Weinig 2010-04-30 18:03:25 PDT
Comment on attachment 54600 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

WebCore/platform/graphics/win/QTMovie.cpp:266
 +          m_private->m_clients.remove(indexOfClient);
Is this correct?  Do you really never want to remove the first client?

WebCore/platform/graphics/win/QTMovie.h:60
 +  class QTMOVIEWIN_API QTMovie : public RefCounted<QTMovie> {
It seems like this class should be renamed something like QTMovieView or QTMovieGWorld.  If you don't want to rename it in this round, please add a comment.

WebCore/platform/graphics/win/QTMovieTask.cpp:46
 +      static QTMovieTask* s_sharedTask = new QTMovieTask();
This should use the DEFINE_GLOBAL macro.

r=me but please consider those changes.WebCore/platform/graphics/win/QTMovieWin.h:75
 +      RefPtr<QTMovie> movie() const;
We don't ever pass or return RefPtr's.  Please see http://webkit.org/coding/RefPtr.html for more on that.
Comment 53 Jer Noble 2010-04-30 18:49:09 PDT
(In reply to comment #52)
> (From update of attachment 54600 [details])
> WebCore/platform/graphics/win/QTMovie.cpp:266
>  +          m_private->m_clients.remove(indexOfClient);
> Is this correct?  Do you really never want to remove the first client?

You're right, that should be a ">="

> WebCore/platform/graphics/win/QTMovie.h:60
>  +  class QTMOVIEWIN_API QTMovie : public RefCounted<QTMovie> {
> It seems like this class should be renamed something like QTMovieView or
> QTMovieGWorld.  If you don't want to rename it in this round, please add a
> comment.

I agree that QTMovieWin isn't the correct name, and that QTMovieGWorld would be better.  I don't mind doing the re-naming this pass.

> 
> WebCore/platform/graphics/win/QTMovieTask.cpp:46
>  +      static QTMovieTask* s_sharedTask = new QTMovieTask();
> This should use the DEFINE_GLOBAL macro.
> 
> r=me but please consider those
> changes.WebCore/platform/graphics/win/QTMovieWin.h:75
>  +      RefPtr<QTMovie> movie() const;
> We don't ever pass or return RefPtr's.  Please see
> http://webkit.org/coding/RefPtr.html for more on that.

It seems like the convention is to move the default constructor into protected: and add a static constructor method which returns a PassRefPtr.  Should I do that as well to QTMovie, QTMovieGWorld, and QTMovieVisualContext?
Comment 54 Jer Noble 2010-04-30 20:37:45 PDT
(In reply to comment #51)
> WebCore/platform/graphics/win/QTMovieVisualContext.cpp:50
>  +      QTVisualContextRef get();
> I think this should be renamed to visualContext() or something other than
> get().

Originally, I didn't like the looks of foo->visualContext()->visualContext().  (If the class "Foo" had an accessor which returned a QTVisualContext*.)  I considered "platformVisualContext()" or "rawVisualContext()" but didn't like any of those either.  "get()" was a cop-out.

How about "visualContextRef()"?

> 
> 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?

Better, they can be static.  Also, I'll just combine those two calls into one which does the division and returns a CFTimeInterval.

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

PassRefPtr instead.

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

Yup.

> 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?

It absolutely can be.  LoadLibrary won't do any extra work if the DLL is already loaded, but it should be static anyway.

> 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.

Yep.

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

Ok.

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

Why not a return PassRefPtr?

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

Originally, I had thought that if they were, this->m_visualContext would be a "const CVPixelBufferRef", and I'd have to const_cast away the constness before passing it on to QTVisualContextIsImageAvailableForTime.  Apparently, (I just tried) this compiles just fine without the const_cast.   So, yes. :)

However, calling QTVisualContextCopyImageForTime may change the internal state of the QTVisualContext, so it's not necessarily a "const" operation.

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

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

Yep.

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

Yep.


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

Yep.

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

Ok.

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

Ok.

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

Ok.

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

Similarly, perhaps "pixelBufferRef()"?

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

Yep.

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

Same as above, yes.

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

All of the "consty" ones can, yes.

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

Sure.

> 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?

The references will just be turned into pointers when we call CVPixelBufferGetExtendedPixels.  And if the caller only wanted to get the "left" extended pixel, they would still have to define and pass in all the other parameters anyway.

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

Sure thing.  (There used to be a CFShow() between those two lines, for debugging purposes.)

> 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?

Nope.  These could be moved into private: and unimplemented.  

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

Funny story.  You can't pass a CVPixelBuffer ref created in QTMovieWin.dll to a CFRetain or CFRelease defined in CoreFoundation.dll.  So whenever a retain or a release needs to be called on a CVPixelBufferRef, it needs to occur within QTMovieWin.dll.  

I defined three different types of retain/release callbacks in the QTPixelBuffer class: a straight CF-style retain/release callback that takes a single parameter, a CAImageQueue style release callback that takes a few other extraneous parameters, and a CGDataProvider style release callback.  

The CF-style retain/release callbacks are so you can put a CVPixelBufferRef in a CFArray (with the correct retain/release callbacks passed in during CFArray creation).  The CAImageQueue callbacks are for use with CAImageQueues (which don't take CVPixelBuffers directly, but want a callback they can use to release the underlying pixel data).  And the CGDataProvider callbacks are so the QTPixelBuffers can be used to create CGImages, backed by CGDataProviders, referencing the original pixel data in the CVPixelBuffer.

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

Sure thing.  I'll post a replacement patch.
Comment 55 Anders Carlsson 2010-05-03 10:20:16 PDT
(In reply to comment #54)
> (In reply to comment #51)
> > WebCore/platform/graphics/win/QTMovieVisualContext.cpp:50
> >  +      QTVisualContextRef get();
> > I think this should be renamed to visualContext() or something other than
> > get().
> 
> Originally, I didn't like the looks of foo->visualContext()->visualContext(). 
> (If the class "Foo" had an accessor which returned a QTVisualContext*.)  I
> considered "platformVisualContext()" or "rawVisualContext()" but didn't like
> any of those either.  "get()" was a cop-out.
> 
> How about "visualContextRef()"?

I like that!

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

You don't want it to return a PassRefPtr, because then if someone does

context->movie()->doSomething()

that's going to ref and then deref the QTMovie object for no good reason.

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

See my comment above.

> 
> > WebCore/platform/graphics/win/QTMovieVisualContext.cpp:47
> >  +      QTPixelBuffer imageForTime(const QTCVTimeStamp*);
> > Can these be const?
> 
> Originally, I had thought that if they were, this->m_visualContext would be a
> "const CVPixelBufferRef", and I'd have to const_cast away the constness before
> passing it on to QTVisualContextIsImageAvailableForTime.  Apparently, (I just
> tried) this compiles just fine without the const_cast.   So, yes. :)
> 
> However, calling QTVisualContextCopyImageForTime may change the internal state
> of the QTVisualContext, so it's not necessarily a "const" operation.
>

Makes sense!
 
> > WebCore/platform/graphics/win/QTMovieVisualContext.cpp:123
> >  +  {
> > You could return early here if (movie == m_movie). (Especially when movie is a
> > PassRefPtr).
> 
> Yep.
> 
> > WebCore/platform/graphics/win/QTMovieVisualContext.h:63
> >  +      QTVisualContextRef get();
> > Again, a better name for this would be visualContext().
> 
> Yep.
> 

Or visualContextRef() :)

> > WebCore/platform/graphics/win/QTPixelBuffer.cpp:68
> >  +  }
> > Should be called "pixelBuffer" or something other than get.
> 
> Similarly, perhaps "pixelBufferRef()"?
> 

Sounds good.

> > 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?
> 
> The references will just be turned into pointers when we call
> CVPixelBufferGetExtendedPixels.  And if the caller only wanted to get the
> "left" extended pixel, they would still have to define and pass in all the
> other parameters anyway.

OK!

> 
> > 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?
> 
> Nope.  These could be moved into private: and unimplemented.  

The way we do this is by inheriting from the "Noncopyable" object.

> 
> > WebCore/platform/graphics/win/QTPixelBuffer.h:82
> >  +      static void retainCallback(void* refcon);
> > What are these used for?
> 
> Funny story.  You can't pass a CVPixelBuffer ref created in QTMovieWin.dll to a
> CFRetain or CFRelease defined in CoreFoundation.dll.  So whenever a retain or a
> release needs to be called on a CVPixelBufferRef, it needs to occur within
> QTMovieWin.dll.  
> 
> I defined three different types of retain/release callbacks in the
> QTPixelBuffer class: a straight CF-style retain/release callback that takes a
> single parameter, a CAImageQueue style release callback that takes a few other
> extraneous parameters, and a CGDataProvider style release callback.  
> 
> The CF-style retain/release callbacks are so you can put a CVPixelBufferRef in
> a CFArray (with the correct retain/release callbacks passed in during CFArray
> creation).  The CAImageQueue callbacks are for use with CAImageQueues (which
> don't take CVPixelBuffers directly, but want a callback they can use to release
> the underlying pixel data).  And the CGDataProvider callbacks are so the
> QTPixelBuffers can be used to create CGImages, backed by CGDataProviders,
> referencing the original pixel data in the CVPixelBuffer.
> 

Ah, I see!

> > Patch looks good overall, but I'd like to see my comments addressed in a new
> > patch.
> 
> Sure thing.  I'll post a replacement patch.

Great!
Comment 56 Jer Noble 2010-05-04 15:28:12 PDT
Created attachment 55053 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

Sam, I addressed your comments in this patch, except for the DEFINE_STATIC change.  That I left out because I could not find a way to declare a static non-const pointer with that macro.  Also, it appeared that the macro in question was designed to avoid file-level static initializers, and this static is function level.  If you want, I can still use the DEFINE_STATIC macro, and const_cast away the constness of the static variable before returning it.
Comment 57 Jer Noble 2010-05-04 15:29:16 PDT
Created attachment 55054 [details]
Part 4.1: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext, the copy
Comment 58 Jer Noble 2010-05-04 15:30:05 PDT
Created attachment 55056 [details]
Part 4.2: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext, the modification
Comment 59 Jer Noble 2010-05-04 15:32:43 PDT
Created attachment 55057 [details]
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext

Anders, I addressed all of your suggestions in this patch.  However, instead of making QTPixelBuffer non-copyable, I made it non-refcounted.  It was never used as a refcounted pointer, so there was no need for refcounting in the first place.
Comment 60 Jer Noble 2010-05-04 15:35:18 PDT
Created attachment 55058 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

Attached the wrong patch file previously.
Comment 61 WebKit Review Bot 2010-05-04 15:36:49 PDT
Attachment 55054 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h:26:  #ifndef header guard has wrong style, please use: MediaPlayerPrivateQuickTimeVisualContext_h  [build/header_guard] [5]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:29:  Found other header before a header this file implements. Should be: config.h, primary header, blank line, and then alphabetically sorted.  [build/include_order] [4]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:31:  Alphabetical sorting problem.  [build/include_order] [4]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:57:  "FrameView.h" already included at WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:34  [build/include] [4]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:58:  "Frame.h" already included at WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:33  [build/include] [4]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:59:  Alphabetical sorting problem.  [build/include_order] [4]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:391:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp:905:  Extra space before last semicolon. If this should be an empty statement, use { } instead.  [whitespace/semicolon] [5]
Total errors found: 8 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 62 Jer Noble 2010-05-04 15:39:34 PDT
Created attachment 55063 [details]
ChangeLog changes. 

Maciej, I added the title of the bug above the bug URL in each of the ChangeLog entries.  However, I did not break the ChangeLog diffs into each individual .patch, as there's a very good chance that committing the patches would cause collisions in the ChangeLog.  I thought it would be safer to leave the ChangeLog in its own, separate patch.
Comment 63 Jer Noble 2010-05-04 15:42:10 PDT
For Parts 4.1 and 4.2, the style check is failing because the copy and modification portions are in separate patches.  if this is going to block submission, let me know and I'll re-unify them.
Comment 64 Chris Marrin 2010-05-05 12:26:27 PDT
Looks like "Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext" and "Part 1.1: QTMovieWin: The breakup of QTMovieWin" are a copy of the same thing.
Comment 65 Jer Noble 2010-05-05 13:23:22 PDT
Created attachment 55149 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

Chris, you're right.  I must have uploaded the wrong patch as Part 1.1. Replacing that attachment with a new one now.
Comment 66 Anders Carlsson 2010-05-05 17:25:28 PDT
Comment on attachment 55057 [details]
Part 2: QTMovieWin: New Classes QTPixelBuffer, QTCFDictionary, and QTMovieVisualContext

WebCore/platform/graphics/win/QTMovieVisualContext.cpp:76
 +          pPixelBufferContextCreate = reinterpret_cast<pfnQTPixelBufferContextCreate>(GetProcAddress(qtmlDLL, "QTPixelBufferContextCreate"));
Add :: to the GetProcAddress call like you did with LoadLibraryW.

WebCore/platform/graphics/win/QTPixelBuffer.cpp:68
 +      m_pixelBuffer = ref;
If you want to, you could return early if ref == m_pixelBuffer.

(I don't feel strongly about it though).


Looks great otherwise, r=me!
Comment 67 Maciej Stachowiak 2010-05-06 13:09:36 PDT
Comment on attachment 55063 [details]
ChangeLog changes. 

r=me
Comment 68 Eric Carlson 2010-05-06 22:47:29 PDT
Comment on attachment 55056 [details]
Part 4.2: WebCore: New class MediaPlayerPrivateQuickTimeVisualContext, the modification


> +void MediaPlayerPrivateQuickTimeVisualContext::retrieveCurrentImage()
> +{
> +    if (!m_visualContext)
> +        return;
> +
> +    if (!m_qtVideoLayer)
> +        return;
> +
> +    QTPixelBuffer buffer = m_visualContext->imageForTime(0);
> +    if (!buffer.pixelBufferRef())
> +        return;
> +
I assume imageForTime(0) gets the image for "now"? I realize that it just 
wraps QTVisualContextCopyImageForTime and that functions defines the magic value, but it would be nice
to define a constant instead of passing "0" - "kCurrentMovieTime" maybe ?


> +
> +        CFTimeInterval imageTime = QTMovieVisualContext::currentHostTime();
> +
"imageTime" isn't used anywhere, left over from earlier revision?

r=me
Comment 69 Jer Noble 2010-05-06 23:44:51 PDT
(In reply to comment #68)
> I assume imageForTime(0) gets the image for "now"? I realize that it just 
> wraps QTVisualContextCopyImageForTime and that functions defines the magic
> value, but it would be nice
> to define a constant instead of passing "0" - "kCurrentMovieTime" maybe ?

I think I'd rather add a second function called QTMovieVisualContext::currentImage(), or ::imageForCurrentTime().  The constant is an implementation detail, and could change in the future outside of our own control.

> "imageTime" isn't used anywhere, left over from earlier revision?

Yup, deleted!

Thanks!
Comment 70 Eric Carlson 2010-05-07 08:58:30 PDT
Comment on attachment 55149 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

>              if (shouldRestorePlaybackState && m_timeToRestore != -1.0f) {
>                  m_movieWin->setCurrentTime(m_timeToRestore);
> @@ -281,7 +190,7 @@ void QTMovieWinPrivate::task()
>                  m_rateToRestore = -1.0f;
>              }

I know you didn't add this, but as long as you are cleaning things up you might as well change "-1.0f" to "-1" to match style guidelines.


> +    size_t indexOfClient = m_private->m_clients.find(client);
> +    if (indexOfClient >= 0)
> +        m_private->m_clients.remove(indexOfClient);

Is ever this OK for this search to fail? If not, add an ASSERT() so we can track down the source of the problem.

Nice refactoring!

r=me
Comment 71 Adam Roben (:aroben) 2010-05-07 09:29:19 PDT
Comment on attachment 55149 [details]
Part 1.1: QTMovieWin: The breakup of QTMovieWin

> +    size_t indexOfClient = m_private->m_clients.find(client);
> +    if (indexOfClient >= 0)
> +        m_private->m_clients.remove(indexOfClient);

This test will always be true. size_t is an unsigned value. The correct test is:

if (indexOfClient != notFound)
Comment 72 Jer Noble 2010-05-07 10:44:26 PDT
(In reply to comment #71)
> (From update of attachment 55149 [details])
> > +    size_t indexOfClient = m_private->m_clients.find(client);
> > +    if (indexOfClient >= 0)
> > +        m_private->m_clients.remove(indexOfClient);
> 
> This test will always be true. size_t is an unsigned value. The correct test
> is:
> 
> if (indexOfClient != notFound)

Good catch!  Changed.
Comment 73 Jer Noble 2010-05-07 18:21:54 PDT
Created attachment 55446 [details]
Part 7: WebKit: FullscreenVideoController and QTMovieGWorld

FullscreenVideoController dangerously casts a QTMovie* to a QTMovieWin*.  This patch doesn't fix that, but it does fix the compile error now that QTMovieWin has been renamed QTMovieGWorld.  The dangerous cast problem will be tracked in: https://bugs.webkit.org/show_bug.cgi?id=37832
Comment 74 Jer Noble 2010-05-07 23:25:40 PDT
Manually committed r59001: http://trac.webkit.org/changeset/59001
Comment 75 Eric Seidel (no email) 2010-05-07 23:39:51 PDT
This broke the windows build:
http://build.webkit.org/builders/Windows%20Debug%20(Build)/builds/15023/steps/compile-webkit/logs/stdio
Comment 76 Jer Noble 2010-05-08 00:00:12 PDT
Manually committed r59003: http://trac.webkit.org/changeset/59003