2010-01-12 Eric Carlson <eric.carlson@apple.com>
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jan 2010 18:23:36 +0000 (18:23 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jan 2010 18:23:36 +0000 (18:23 +0000)
        Reviewed by Darin Adler and Simon Fraser.

        rdar://problem/5684062
        https://bugs.webkit.org/show_bug.cgi?id=23094
        Flash of white when switching from poster image to video playback

        https://bugs.webkit.org/show_bug.cgi?id=23140
        <video> poster should scale like a video frame

        * html/HTMLMediaElement.cpp:
        (WebCore::HTMLMediaElement::setReadyState): Only call updatePosterImage from one place

        * html/HTMLVideoElement.cpp:
        (WebCore::HTMLVideoElement::HTMLVideoElement): m_shouldShowPosterImage -> m_shouldDisplayPoster.
        (WebCore::HTMLVideoElement::createRenderer): Always create a RenderVideo.
        (WebCore::HTMLVideoElement::attach): Call updatePosterImage before checking to see if we
            should display the poster image. renderer() is never a RenderImage, don't need to check.
            m_shouldShowPosterImage -> m_shouldDisplayPoster.
        (WebCore::HTMLVideoElement::detach): m_shouldShowPosterImage -> m_shouldDisplayPoster.
        (WebCore::HTMLVideoElement::parseMappedAttribute): Cache poster attribute when it is set since
            it is checked frequently. m_shouldShowPosterImage -> m_shouldDisplayPoster.
        (WebCore::HTMLVideoElement::updatePosterImage): Don't bother looking at the network state,
            display the poster as long as the attribute is valid and the media engine says it hasn't
            rendered a video frame. m_shouldShowPosterImage -> m_shouldDisplayPoster.
        (WebCore::HTMLVideoElement::hasAvailableVideoFrame): New, ask the media engine if a video frame
            is available to render.
        * html/HTMLVideoElement.h:
        (WebCore::HTMLVideoElement::poster):
        (WebCore::HTMLVideoElement::shouldDisplayPoster):

        * loader/ImageLoader.cpp:
        (WebCore::ImageLoader::updateRenderer): Call setCachedImage for render video too.

        * manual-tests/video-player.html: Remove bit-rot from manual test so it works again.

        * platform/graphics/MediaPlayer.cpp:
        (WebCore::MediaPlayer::hasAvailableVideoFrame): New, ask the media engine if a video frame
            is available to render.

        * platform/graphics/MediaPlayer.h: Prototype for hasAvailableVideoFrame.
        * platform/graphics/MediaPlayerPrivate.h: Ditto.

        * platform/graphics/mac/MediaPlayerPrivateQTKit.h: Declare hasAvailableVideoFrame, declare
            all bool variables to aid packing.
        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Initialize m_videoFrameHasDrawn. Cleanup
            floating point initializers to match coding guidelines.
        (WebCore::MediaPlayerPrivate::load): Initialize m_videoFrameHasDrawn.
        (WebCore::MediaPlayerPrivate::hasAvailableVideoFrame): New.
        (WebCore::MediaPlayerPrivate::repaint): Set m_videoFrameHasDrawn.

        (WebCore::RenderImage::paintReplaced): Split part out into paint method.
        (WebCore::RenderImage::paint): New.
        * rendering/RenderImage.h: Declare paint. Make isWidthSpecified and isHeightSpecified protected
            instead of private so RenderVideo can use them.

        * rendering/RenderMedia.cpp:
        (WebCore::RenderMedia::RenderMedia): Inherit from RenderImage, not RenderReplaced
        (WebCore::RenderMedia::destroy): Ditto.
        (WebCore::RenderMedia::styleDidChange): Ditto.
        (WebCore::RenderMedia::layout): Ditto.
        (WebCore::RenderMedia::lowestPosition): Ditto.
        (WebCore::RenderMedia::rightmostPosition): Ditto.
        (WebCore::RenderMedia::leftmostPosition): Ditto.
        * rendering/RenderMedia.h: Declare isImage and isRenderImage.

        * rendering/RenderVideo.cpp:
        (WebCore::RenderVideo::intrinsicSizeChanged): New, call RenderVideo::intrinsicSizeChanged
            when displaying a poster so it is sized correctly.
        (WebCore::RenderVideo::imageChanged): Override so we can cache the image's intrisic size and
        use it when we also know the movie's intrinsic size but still need to draw the poster.
        (WebCore::RenderVideo::videoBox): Use the poster's intrinsic size when drawing the poster,
        use the movie's intrinsic size when drawing frames.
        (WebCore::RenderVideo::paintReplaced): Call RenderImage::paint when drawing the poster.
        (WebCore::RenderVideo::videoElement): New.
        (WebCore::RenderVideo::updatePlayer):
        * rendering/RenderVideo.h:
        (WebCore::RenderVideo::minimumReplacedHeight): Added.

2010-01-12  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Darin Adler and Simon Fraser.

        rdar://problem/5684062
        https://bugs.webkit.org/show_bug.cgi?id=23094
        Flash of white when switching from poster image to video playback

        https://bugs.webkit.org/show_bug.cgi?id=23140
        <video> poster should scale like a video frame

        * media/video-poster-expected.txt: Remove blank line at beginning of test result present
        as a side effect of the media element using RenderImage to display the poster.
        * media/video-poster-scale.html: New.
        * media/video-poster-scale-expected.txt: New.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53146 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
LayoutTests/ChangeLog
LayoutTests/media/video-poster-expected.txt
LayoutTests/media/video-poster-scale-expected.txt [new file with mode: 0644]
LayoutTests/media/video-poster-scale.html [new file with mode: 0644]
LayoutTests/platform/gtk/Skipped
WebCore/ChangeLog
WebCore/html/HTMLMediaElement.cpp
WebCore/html/HTMLVideoElement.cpp
WebCore/html/HTMLVideoElement.h
WebCore/loader/ImageLoader.cpp
WebCore/manual-tests/video-player.html
WebCore/platform/graphics/MediaPlayer.cpp
WebCore/platform/graphics/MediaPlayer.h
WebCore/platform/graphics/MediaPlayerPrivate.h
WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
WebCore/rendering/RenderImage.cpp
WebCore/rendering/RenderImage.h
WebCore/rendering/RenderMedia.cpp
WebCore/rendering/RenderMedia.h
WebCore/rendering/RenderVideo.cpp
WebCore/rendering/RenderVideo.h

index 16dc064..74e34bd 100644 (file)
@@ -1,3 +1,19 @@
+2010-01-12  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Darin Adler and Simon Fraser.
+
+        rdar://problem/5684062
+        https://bugs.webkit.org/show_bug.cgi?id=23094
+        Flash of white when switching from poster image to video playback
+        
+        https://bugs.webkit.org/show_bug.cgi?id=23140
+        <video> poster should scale like a video frame
+
+        * media/video-poster-expected.txt: Remove blank line at beginning of test result present
+        as a side effect of the media element using RenderImage to display the poster.
+        * media/video-poster-scale.html: New.
+        * media/video-poster-scale-expected.txt: New.
+
 2010-01-12  Tony Chang  <tony@chromium.org>
 
         Reviewed by Maciej Stachowiak.
index 79011e8..e87f26d 100644 (file)
@@ -1,4 +1,3 @@
-
 EXPECTED (video.getAttribute('poster') == 'content/greenbox.png') OK
 EXPECTED (relativeURL(video.poster) == 'content/greenbox.png') OK
 EXPECTED (video.getAttribute('poster') == 'content/abe.png') OK
diff --git a/LayoutTests/media/video-poster-scale-expected.txt b/LayoutTests/media/video-poster-scale-expected.txt
new file mode 100644 (file)
index 0000000..2fd065f
--- /dev/null
@@ -0,0 +1,33 @@
+CONSOLE MESSAGE: line 24: ReferenceError: Can't find variable: testExpected
+layer at (0,0) size 785x619
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x619
+  RenderBlock {HTML} at (0,0) size 785x619
+    RenderBody {BODY} at (8,8) size 769x603
+      RenderText {#text} at (326,142) size 4x18
+        text run at (326,142) width 4: " "
+      RenderBR {BR} at (0,0) size 0x0
+      RenderText {#text} at (82,255) size 4x18
+        text run at (82,255) width 4: " "
+      RenderText {#text} at (168,255) size 4x18
+        text run at (168,255) width 4: " "
+      RenderBR {BR} at (0,0) size 0x0
+      RenderText {#text} at (56,585) size 4x18
+        text run at (56,585) width 4: " "
+      RenderText {#text} at (386,585) size 4x18
+        text run at (386,585) width 4: " "
+      RenderText {#text} at (716,585) size 4x18
+        text run at (716,585) width 4: " "
+      RenderBR {BR} at (0,0) size 0x0
+layer at (8,8) size 326x156
+  RenderVideo {VIDEO} at (0,0) size 326x156 [bgcolor=#EE00EE] [border: (3px solid #FF0000)]
+layer at (8,168) size 82x109
+  RenderVideo {VIDEO} at (0,160) size 82x109 [bgcolor=#EE00EE] [border: (3px solid #FF0000)]
+layer at (94,168) size 82x109
+  RenderVideo {VIDEO} at (86,160) size 82x109 [bgcolor=#EE00EE] [border: (3px solid #FF0000)]
+layer at (8,281) size 56x326
+  RenderVideo {VIDEO} at (0,273) size 56x326 [bgcolor=#EE00EE] [border: (3px solid #FF0000)]
+layer at (68,361) size 326x246
+  RenderVideo {VIDEO} at (60,353) size 326x246 [bgcolor=#EE00EE] [border: (3px solid #FF0000)]
+layer at (398,551) size 326x56
+  RenderVideo {VIDEO} at (390,543) size 326x56 [bgcolor=#EE00EE] [border: (3px solid #FF0000)]
diff --git a/LayoutTests/media/video-poster-scale.html b/LayoutTests/media/video-poster-scale.html
new file mode 100644 (file)
index 0000000..7a036ba
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML5>
+
+<html>
+    <head>
+        <title>'poster' aspect ratio test</title>
+        <style> 
+            video { 
+                border: 3px solid red; 
+                background-color: #ee00ee;
+            } 
+            #wide { width: 320px; height: 150px; }
+            #tall { width: 150px; height: 320px; }
+            #big { width: 320px; height: 240px; }
+            #skinny { width: 50px; height: 320px; }
+            #short { width: 320px; height: 50px; }
+            #just_right { width: 76px; height: 103px; }
+        </style>
+        <script>
+            var videos;
+            function start()
+            {
+                videos = document.getElementsByTagName('video');
+                for (var ndx = 0; ndx < videos.length; ndx++ ) {
+                    testExpected("videos[" + ndx + "].getAttribute('poster')", "content/abe.png");
+                    testExpected("relativeURL(videos[" + ndx + "].poster)", "content/abe.png");
+                }
+
+                endTest();
+            }
+        </script>
+    </head>
+
+
+    <body onload="start()">
+        <video poster="content/abe.png" id=wide></video>
+        <br>
+        <video poster="content/abe.png" id=just_right></video>
+        <video poster="content/abe.png" id=no-style></video>
+        <br>
+        <video poster="content/abe.png" id=skinny></video>
+        <video poster="content/abe.png" id=big></video>
+        <video poster="content/abe.png" id=short></video>
+        <br>
+    </body>
+</html>
\ No newline at end of file
index e11b8ed..0296594 100644 (file)
@@ -5730,10 +5730,6 @@ fast/dom/Element/id-in-deletebutton.html
 # See https://bugs.webkit.org/show_bug.cgi?id=33014
 fast/dom/prototype-inheritance-2.html
 
-# Fails on and off locally, but always on the release bot
-# See https://bugs.webkit.org/show_bug.cgi?id=33015
-media/video-seek-past-end-playing.html
-
 # Hits ASSERTION, see https://bugs.webkit.org/show_bug.cgi?id=33050
 fast/inline/inline-body-with-scrollbar-crash.html
 
index 28b0090..e51dc0f 100644 (file)
@@ -1,3 +1,84 @@
+2010-01-12  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Darin Adler and Simon Fraser.
+
+        rdar://problem/5684062
+        https://bugs.webkit.org/show_bug.cgi?id=23094
+        Flash of white when switching from poster image to video playback
+        
+        https://bugs.webkit.org/show_bug.cgi?id=23140
+        <video> poster should scale like a video frame
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::setReadyState): Only call updatePosterImage from one place
+
+        * html/HTMLVideoElement.cpp:
+        (WebCore::HTMLVideoElement::HTMLVideoElement): m_shouldShowPosterImage -> m_shouldDisplayPoster.
+        (WebCore::HTMLVideoElement::createRenderer): Always create a RenderVideo.
+        (WebCore::HTMLVideoElement::attach): Call updatePosterImage before checking to see if we
+            should display the poster image. renderer() is never a RenderImage, don't need to check.
+            m_shouldShowPosterImage -> m_shouldDisplayPoster.
+        (WebCore::HTMLVideoElement::detach): m_shouldShowPosterImage -> m_shouldDisplayPoster.
+        (WebCore::HTMLVideoElement::parseMappedAttribute): Cache poster attribute when it is set since
+            it is checked frequently. m_shouldShowPosterImage -> m_shouldDisplayPoster.
+        (WebCore::HTMLVideoElement::updatePosterImage): Don't bother looking at the network state, 
+            display the poster as long as the attribute is valid and the media engine says it hasn't
+            rendered a video frame. m_shouldShowPosterImage -> m_shouldDisplayPoster.
+        (WebCore::HTMLVideoElement::hasAvailableVideoFrame): New, ask the media engine if a video frame
+            is available to render.
+        * html/HTMLVideoElement.h:
+        (WebCore::HTMLVideoElement::poster):
+        (WebCore::HTMLVideoElement::shouldDisplayPoster):
+
+        * loader/ImageLoader.cpp:
+        (WebCore::ImageLoader::updateRenderer): Call setCachedImage for render video too.
+
+        * manual-tests/video-player.html: Remove bit-rot from manual test so it works again.
+
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::hasAvailableVideoFrame): New, ask the media engine if a video frame
+            is available to render.
+
+        * platform/graphics/MediaPlayer.h: Prototype for hasAvailableVideoFrame.
+        * platform/graphics/MediaPlayerPrivate.h: Ditto.
+
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.h: Declare hasAvailableVideoFrame, declare
+            all bool variables to aid packing.
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm: 
+        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Initialize m_videoFrameHasDrawn. Cleanup
+            floating point initializers to match coding guidelines.
+        (WebCore::MediaPlayerPrivate::load): Initialize m_videoFrameHasDrawn.
+        (WebCore::MediaPlayerPrivate::hasAvailableVideoFrame): New.
+        (WebCore::MediaPlayerPrivate::repaint): Set m_videoFrameHasDrawn.
+
+        (WebCore::RenderImage::paintReplaced): Split part out into paint method.
+        (WebCore::RenderImage::paint): New.
+        * rendering/RenderImage.h: Declare paint. Make isWidthSpecified and isHeightSpecified protected
+            instead of private so RenderVideo can use them.
+
+        * rendering/RenderMedia.cpp:
+        (WebCore::RenderMedia::RenderMedia): Inherit from RenderImage, not RenderReplaced
+        (WebCore::RenderMedia::destroy): Ditto.
+        (WebCore::RenderMedia::styleDidChange): Ditto.
+        (WebCore::RenderMedia::layout): Ditto.
+        (WebCore::RenderMedia::lowestPosition): Ditto.
+        (WebCore::RenderMedia::rightmostPosition): Ditto.
+        (WebCore::RenderMedia::leftmostPosition): Ditto.
+        * rendering/RenderMedia.h: Declare isImage and isRenderImage.
+
+        * rendering/RenderVideo.cpp:
+        (WebCore::RenderVideo::intrinsicSizeChanged): New, call RenderVideo::intrinsicSizeChanged
+            when displaying a poster so it is sized correctly.
+        (WebCore::RenderVideo::imageChanged): Override so we can cache the image's intrisic size and
+        use it when we also know the movie's intrinsic size but still need to draw the poster.
+        (WebCore::RenderVideo::videoBox): Use the poster's intrinsic size when drawing the poster,
+        use the movie's intrinsic size when drawing frames.
+        (WebCore::RenderVideo::paintReplaced): Call RenderImage::paint when drawing the poster.
+        (WebCore::RenderVideo::videoElement): New.
+        (WebCore::RenderVideo::updatePlayer):
+        * rendering/RenderVideo.h:
+        (WebCore::RenderVideo::minimumReplacedHeight): Added.
+
 2010-01-12  Tony Chang  <tony@chromium.org>
 
         Reviewed by Maciej Stachowiak.
index 65aa943..5d90a58 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -806,6 +806,8 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
         m_player->seek(0);
     }
 
+    bool shouldUpdatePosterImage = false;
+
     // 4.8.10.7 says loadeddata is sent only when the new state *is* HAVE_CURRENT_DATA: "If the
     // previous ready state was HAVE_METADATA and the new ready state is HAVE_CURRENT_DATA", 
     // but the event table at the end of the spec says it is sent when: "readyState newly 
@@ -813,6 +815,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
     // We go with the later because it seems useful to count on getting this event
     if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) {
         m_haveFiredLoadedData = true;
+        shouldUpdatePosterImage = true;
         scheduleEvent(eventNames().loadeddataEvent);
     }
 
@@ -821,9 +824,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
         scheduleEvent(eventNames().canplayEvent);
         if (isPotentiallyPlaying)
             scheduleEvent(eventNames().playingEvent);
-
-        if (isVideo())
-            static_cast<HTMLVideoElement*>(this)->updatePosterImage();
+        shouldUpdatePosterImage = true;
     }
 
     if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA) {
@@ -841,10 +842,12 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
             scheduleEvent(eventNames().playingEvent);
         }
 
-        if (isVideo())
-            static_cast<HTMLVideoElement*>(this)->updatePosterImage();
+        shouldUpdatePosterImage = true;
     }
 
+    if (shouldUpdatePosterImage && isVideo())
+        static_cast<HTMLVideoElement*>(this)->updatePosterImage();
+
     updatePlayState();
 }
 
index 20cbc1d..1fae354 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -46,11 +46,11 @@ using namespace HTMLNames;
 
 HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* doc)
     : HTMLMediaElement(tagName, doc)
-    , m_shouldShowPosterImage(false)
+    , m_shouldDisplayPosterImage(false)
 {
     ASSERT(hasTagName(videoTag));
 }
-    
+
 bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style) 
 {
     return HTMLElement::rendererIsNeeded(style); 
@@ -59,8 +59,6 @@ bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
 RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
 {
-    if (m_shouldShowPosterImage)
-        return new (arena) RenderImage(this);
     return new (arena) RenderVideo(this);
 }
 #endif
@@ -70,11 +68,12 @@ void HTMLVideoElement::attach()
     HTMLMediaElement::attach();
 
 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-    if (m_shouldShowPosterImage) {
+    updatePosterImage();
+    if (m_shouldDisplayPosterImage) {
         if (!m_imageLoader)
             m_imageLoader.set(new HTMLImageLoader(this));
         m_imageLoader->updateFromElement();
-        if (renderer() && renderer()->isImage()) {
+        if (renderer()) {
             RenderImage* imageRenderer = toRenderImage(renderer());
             imageRenderer->setCachedImage(m_imageLoader->image()); 
         }
@@ -86,7 +85,7 @@ void HTMLVideoElement::detach()
 {
     HTMLMediaElement::detach();
     
-    if (!m_shouldShowPosterImage)
+    if (!m_shouldDisplayPosterImage)
         if (m_imageLoader)
             m_imageLoader.clear();
 }
@@ -96,8 +95,9 @@ void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
     const QualifiedName& attrName = attr->name();
 
     if (attrName == posterAttr) {
+        m_posterURL = document()->completeURL(attr->value());
         updatePosterImage();
-        if (m_shouldShowPosterImage) {
+        if (m_shouldDisplayPosterImage) {
 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
             if (!m_imageLoader)
                 m_imageLoader.set(new HTMLImageLoader(this));
@@ -166,11 +166,6 @@ void HTMLVideoElement::setHeight(unsigned value)
     setAttribute(heightAttr, String::number(value));
 }
 
-KURL HTMLVideoElement::poster() const
-{
-    return document()->completeURL(getAttribute(posterAttr));
-}
-
 void HTMLVideoElement::setPoster(const String& value)
 {
     setAttribute(posterAttr, value);
@@ -189,16 +184,14 @@ const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
 void HTMLVideoElement::updatePosterImage()
 {
 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-    bool oldShouldShowPosterImage = m_shouldShowPosterImage;
+    bool oldShouldShowPosterImage = m_shouldDisplayPosterImage;
 #endif
 
-    m_shouldShowPosterImage = !poster().isEmpty() && readyState() < HAVE_CURRENT_DATA;
+    m_shouldDisplayPosterImage = !poster().isEmpty() && !hasAvailableVideoFrame();
 
 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-    if (attached() && oldShouldShowPosterImage != m_shouldShowPosterImage) {
-        detach();
-        attach();
-    }
+    if (renderer() && oldShouldShowPosterImage != m_shouldDisplayPosterImage)
+        renderer()->updateFromElement();
 #endif
 }
 
@@ -226,5 +219,13 @@ void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, cons
     player->paintCurrentFrameInContext(context, destRect);
 }
 
+bool HTMLVideoElement::hasAvailableVideoFrame() const
+{
+    if (!m_player)
+        return false;
+    
+    return m_player->hasAvailableVideoFrame();
+}
+
 }
 #endif
index 096eb53..834ec4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -38,7 +38,7 @@ class HTMLImageLoader;
 class HTMLVideoElement : public HTMLMediaElement {
 public:
     HTMLVideoElement(const QualifiedName&, Document*);
-    
+
     virtual int tagPriority() const { return 5; }
     virtual bool rendererIsNeeded(RenderStyle*);
 #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
@@ -61,18 +61,22 @@ public:
     unsigned videoWidth() const;
     unsigned videoHeight() const;
     
-    KURL poster() const;
+    const KURL& poster() const { return m_posterURL; }
     void setPoster(const String&);
 
     void updatePosterImage();
+    bool shouldDisplayPosterImage() const { return m_shouldDisplayPosterImage; }
 
     void paint(GraphicsContext*, const IntRect&);
     // Used by canvas to gain raw pixel access
     void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
 
 private:
+    virtual bool hasAvailableVideoFrame() const;
+
     OwnPtr<HTMLImageLoader> m_imageLoader;
-    bool m_shouldShowPosterImage;
+    KURL m_posterURL;
+    bool m_shouldDisplayPosterImage;
 };
 
 } //namespace
index 25b9096..9c237cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -186,7 +186,7 @@ void ImageLoader::notifyFinished(CachedResource*)
 void ImageLoader::updateRenderer()
 {
     if (RenderObject* renderer = m_element->renderer()) {
-        if (!renderer->isImage())
+        if (!renderer->isImage() && !renderer->isVideo())
             return;
         RenderImage* imageRenderer = toRenderImage(renderer);
         
index 2bced51..74f0a38 100644 (file)
@@ -37,10 +37,7 @@ function stoppedPlaying() {
 function updateProgress(ev) {
     if (!showProgress)
        return;
-    if (ev.total)
-        playButton.innerHTML = "Loading " + (100*ev.loaded/ev.total).toFixed(0) + "%";
-    else
-        playButton.innerHTML = "Loading...";
+    playButton.innerHTML = "Loading...";
     playButton.className = "videobutton videoloading";
 }
 function initVideo() {
@@ -90,12 +87,8 @@ function initVideo() {
     playButton.addEventListener("click", function () {
         if (videoElem.paused) {
             if (!videoElem.src)
-                //videoElem.src = "sample.mov";
                 videoElem.src = "http://movies.apple.com/movies/us/apple/ipoditunes/2007/touch/ads/apple_ipodtouch_touch_r640-9cie.mov";
-            if (videoElem.readyState == HTMLMediaElement.DATA_UNAVAILABLE)
-                videoElem.load();
-            if (videoElem.readyState == HTMLMediaElement.CAN_PLAY_THROUGH)
-                videoElem.play();
+            videoElem.play();
         } else
             videoElem.pause();
     } );
index b37351d..a9a288e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -259,6 +259,11 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
         m_private.set(createNullMediaPlayer(this));
 }    
 
+bool MediaPlayer::hasAvailableVideoFrame() const
+{
+    return m_private->hasAvailableVideoFrame();
+}
+    
 bool MediaPlayer::canLoadPoster() const
 {
     return m_private->canLoadPoster();
index ec8ac33..0e5460d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -213,6 +213,8 @@ public:
 
     MediaPlayerClient* mediaPlayerClient() const { return m_mediaPlayerClient; }
 
+    bool hasAvailableVideoFrame() const;
+
     bool canLoadPoster() const;
     void setPoster(const String&);
 
index 03906bd..e8b472c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -99,6 +99,8 @@ public:
 
     virtual void setAutobuffer(bool) { };
 
+    virtual bool hasAvailableVideoFrame() const { return readyState() >= MediaPlayer::HaveCurrentData; }
+
     virtual bool canLoadPoster() const { return false; }
     virtual void setPoster(const String&) { }
 
index 7aaf95d..48cac4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -120,6 +120,8 @@ private:
     void setVisible(bool);
     void setSize(const IntSize&);
     
+    virtual bool hasAvailableVideoFrame() const;
+
     void paint(GraphicsContext*, const IntRect&);
     void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
 
@@ -176,18 +178,19 @@ private:
     Timer<MediaPlayerPrivate> m_seekTimer;
     MediaPlayer::NetworkState m_networkState;
     MediaPlayer::ReadyState m_readyState;
-    bool m_startedPlaying;
-    bool m_isStreaming;
-    bool m_visible;
     IntRect m_rect;
     FloatSize m_scaleFactor;
     unsigned m_enabledTrackCount;
     unsigned m_totalTrackCount;
-    bool m_hasUnsupportedTracks;
     float m_reportedDuration;
     float m_cachedDuration;
     float m_timeToRestore;
     RetainPtr<QTMovieLayer> m_qtVideoLayer;
+    bool m_startedPlaying;
+    bool m_isStreaming;
+    bool m_visible;
+    bool m_hasUnsupportedTracks;
+    bool m_videoFrameHasDrawn;
 #if DRAW_FRAME_RATE
     int  m_frameCountWhilePlaying;
     double m_timeStartedPlaying;
index ff5a9df..43f9fb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -204,17 +204,18 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
     , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
     , m_networkState(MediaPlayer::Empty)
     , m_readyState(MediaPlayer::HaveNothing)
-    , m_startedPlaying(false)
-    , m_isStreaming(false)
-    , m_visible(false)
     , m_rect()
     , m_scaleFactor(1, 1)
     , m_enabledTrackCount(0)
     , m_totalTrackCount(0)
+    , m_reportedDuration(-1)
+    , m_cachedDuration(-1)
+    , m_timeToRestore(-1)
+    , m_startedPlaying(false)
+    , m_isStreaming(false)
+    , m_visible(false)
     , m_hasUnsupportedTracks(false)
-    , m_reportedDuration(-1.0f)
-    , m_cachedDuration(-1.0f)
-    , m_timeToRestore(-1.0f)
+    , m_videoFrameHasDrawn(false)
 #if DRAW_FRAME_RATE
     , m_frameCountWhilePlaying(0)
     , m_timeStartedPlaying(0)
@@ -556,6 +557,7 @@ void MediaPlayerPrivate::load(const String& url)
         m_player->readyStateChanged();
     }
     cancelSeek();
+    m_videoFrameHasDrawn = false;
     
     [m_objcObserver.get() setDelayCallbacks:YES];
 
@@ -1086,6 +1088,20 @@ void MediaPlayerPrivate::setVisible(bool b)
     }
 }
 
+bool MediaPlayerPrivate::hasAvailableVideoFrame() const
+{
+    // When using a QTMovieLayer return true as soon as the movie reaches QTMovieLoadStatePlayable 
+    // because although we don't *know* when the first frame has decoded, by the time we get and 
+    // process the notificaiton a frame should have propagated the VisualContext and been set on
+    // the layer.
+    if (currentRenderingMode() == MediaRenderingMovieLayer)
+        return m_readyState >= MediaPlayer::HaveCurrentData;
+
+    // When using the software renderer QuickTime signals that a frame is available so we might as well
+    // wait until we know that a frame has been drawn.
+    return m_videoFrameHasDrawn;
+}
+
 void MediaPlayerPrivate::repaint()
 {
     if (m_hasUnsupportedTracks)
@@ -1100,6 +1116,7 @@ void MediaPlayerPrivate::repaint()
             m_timeStartedPlaying = [NSDate timeIntervalSinceReferenceDate];
     }
 #endif
+    m_videoFrameHasDrawn = true;
     m_player->repaint();
 }
 
index eb822c1..c10ab8e 100644 (file)
@@ -4,7 +4,7 @@
  *           (C) 2000 Dirk Mueller (mueller@kde.org)
  *           (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
  *           (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -420,14 +420,26 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 #endif
 
         IntSize contentSize(cWidth, cHeight);
-        bool useLowQualityScaling = RenderImageScaleObserver::shouldImagePaintAtLowQuality(this, contentSize);
         IntRect rect(IntPoint(tx + leftBorder + leftPad, ty + topBorder + topPad), contentSize);
-        HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
-        CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
-        context->drawImage(image(cWidth, cHeight), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
+        paintIntoRect(context, rect);
     }
 }
 
+void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
+{
+    if (!hasImage() || errorOccurred() || rect.width() <= 0 || rect.height() <= 0)
+        return;
+
+    Image* img = image(rect.width(), rect.height());
+    if (!img || img->isNull())
+        return;
+
+    HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
+    CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
+    bool useLowQualityScaling = RenderImageScaleObserver::shouldImagePaintAtLowQuality(this, rect.size());
+    context->drawImage(image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
+}
+
 int RenderImage::minimumReplacedHeight() const
 {
     return errorOccurred() ? intrinsicSize().height() : 0;
index 2224412..ab94667 100644 (file)
@@ -3,7 +3,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) 
  *           (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -57,6 +57,11 @@ protected:
 
     virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
 
+    virtual void paintIntoRect(GraphicsContext*, const IntRect&);
+
+    bool isWidthSpecified() const;
+    bool isHeightSpecified() const;
+
 private:
     virtual const char* renderName() const { return "RenderImage"; }
 
@@ -87,9 +92,6 @@ private:
     int calcAspectRatioWidth() const;
     int calcAspectRatioHeight() const;
 
-    bool isWidthSpecified() const;
-    bool isHeightSpecified() const;
-
 protected:
     // The image we are rendering.
     CachedResourceHandle<CachedImage> m_cachedImage;
index 2ff50df..8e4e7af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -50,7 +50,7 @@ static const double cOpacityAnimationDurationFadeIn = 0.1;
 static const double cOpacityAnimationDurationFadeOut = 0.3;
 
 RenderMedia::RenderMedia(HTMLMediaElement* video)
-    : RenderReplaced(video)
+    : RenderImage(video)
     , m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
     , m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
     , m_mouseOver(false)
@@ -62,7 +62,7 @@ RenderMedia::RenderMedia(HTMLMediaElement* video)
 }
 
 RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
-    : RenderReplaced(video, intrinsicSize)
+    : RenderImage(video)
     , m_timeUpdateTimer(this, &RenderMedia::timeUpdateTimerFired)
     , m_opacityAnimationTimer(this, &RenderMedia::opacityAnimationTimerFired)
     , m_mouseOver(false)
@@ -71,6 +71,7 @@ RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
     , m_opacityAnimationFrom(0)
     , m_opacityAnimationTo(1.0f)
 {
+    setIntrinsicSize(intrinsicSize);
 }
 
 RenderMedia::~RenderMedia()
@@ -89,7 +90,7 @@ void RenderMedia::destroy()
         m_controlsShadowRoot->detach();
         m_controlsShadowRoot = 0;
     }
-    RenderReplaced::destroy();
+    RenderImage::destroy();
 }
 
 HTMLMediaElement* RenderMedia::mediaElement() const
@@ -104,7 +105,7 @@ MediaPlayer* RenderMedia::player() const
 
 void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
-    RenderReplaced::styleDidChange(diff, oldStyle);
+    RenderImage::styleDidChange(diff, oldStyle);
 
     if (m_controlsShadowRoot) {
         if (m_panel)
@@ -146,7 +147,7 @@ void RenderMedia::layout()
 {
     IntSize oldSize = contentBoxRect().size();
 
-    RenderReplaced::layout();
+    RenderImage::layout();
 
     RenderBox* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0;
     if (!controlsRenderer)
@@ -573,7 +574,7 @@ void RenderMedia::forwardEvent(Event* event)
 
 int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
 {
-    int bottom = RenderReplaced::lowestPosition(includeOverflowInterior, includeSelf);
+    int bottom = RenderImage::lowestPosition(includeOverflowInterior, includeSelf);
     if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
         return bottom;
     
@@ -582,7 +583,7 @@ int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf)
 
 int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
 {
-    int right = RenderReplaced::rightmostPosition(includeOverflowInterior, includeSelf);
+    int right = RenderImage::rightmostPosition(includeOverflowInterior, includeSelf);
     if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
         return right;
     
@@ -591,7 +592,7 @@ int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSel
 
 int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
 {
-    int left = RenderReplaced::leftmostPosition(includeOverflowInterior, includeSelf);
+    int left = RenderImage::leftmostPosition(includeOverflowInterior, includeSelf);
     if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
         return left;
     
index 066b83d..0d24c4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * 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
@@ -28,7 +28,7 @@
 
 #if ENABLE(VIDEO)
 
-#include "RenderReplaced.h"
+#include "RenderImage.h"
 #include "Timer.h"
 
 namespace WebCore {
@@ -51,12 +51,12 @@ class MediaControlVolumeSliderContainerElement;
 class MediaControlElement;
 class MediaPlayer;
 
-class RenderMedia : public RenderReplaced {
+class RenderMedia : public RenderImage {
 public:
     RenderMedia(HTMLMediaElement*);
     RenderMedia(HTMLMediaElement*, const IntSize& intrinsicSize);
     virtual ~RenderMedia();
-    
+
     const RenderObjectChildList* children() const { return &m_children; }
     RenderObjectChildList* children() { return &m_children; }
 
@@ -83,6 +83,7 @@ private:
     
     virtual const char* renderName() const { return "RenderMedia"; }
     virtual bool isMedia() const { return true; }
+    virtual bool isImage() const { return false; }
 
     virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
     virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
index 246d0c0..f433f8c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ * 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
@@ -34,6 +34,7 @@
 #include "HTMLNames.h"
 #include "HTMLVideoElement.h"
 #include "MediaPlayer.h"
+#include "RenderView.h"
 
 #if USE(ACCELERATED_COMPOSITING)
 #include "RenderLayer.h"
@@ -73,7 +74,15 @@ RenderVideo::~RenderVideo()
         p->setFrameView(0);
     }
 }
-    
+
+void RenderVideo::intrinsicSizeChanged()
+{
+    if (videoElement()->shouldDisplayPosterImage())
+        RenderVideo::intrinsicSizeChanged();
+    videoSizeChanged(); 
+}
+
+
 void RenderVideo::videoSizeChanged()
 {
     if (!player())
@@ -86,41 +95,72 @@ void RenderVideo::videoSizeChanged()
     }
 }
 
-IntRect RenderVideo::videoBox() const 
+void RenderVideo::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
 {
+    RenderImage::imageChanged(newImage, rect);
+
+    // Cache the image intrinsic size so we can continue to use it to draw the image correctly
+    // even after we know the video intrisic size but aren't able to draw video frames yet
+    // (we don't want to scale the poster to the video size).
+    if (videoElement()->shouldDisplayPosterImage())
+        m_cachedImageSize = intrinsicSize();
+}
+
+IntRect RenderVideo::videoBox() const
+{
+    if (m_cachedImageSize.isEmpty() && videoElement()->shouldDisplayPosterImage())
+        return IntRect();
+
+    IntSize elementSize;
+    if (videoElement()->shouldDisplayPosterImage())
+        elementSize = m_cachedImageSize;
+    else
+        elementSize = intrinsicSize();
+
     IntRect contentRect = contentBoxRect();
-    
-    if (intrinsicSize().isEmpty() || contentRect.isEmpty())
+    if (elementSize.isEmpty() || contentRect.isEmpty())
         return IntRect();
 
-    IntRect resultRect = contentRect;
-    int ratio = contentRect.width() * intrinsicSize().height() - contentRect.height() * intrinsicSize().width();
+    IntRect renderBox = contentRect;
+    int ratio = renderBox.width() * elementSize.height() - renderBox.height() * elementSize.width();
     if (ratio > 0) {
-        int newWidth = contentRect.height() * intrinsicSize().width() / intrinsicSize().height();
+        int newWidth = renderBox.height() * elementSize.width() / elementSize.height();
         // Just fill the whole area if the difference is one pixel or less (in both sides)
-        if (resultRect.width() - newWidth > 2)
-            resultRect.setWidth(newWidth);
-        resultRect.move((contentRect.width() - resultRect.width()) / 2, 0);
+        if (renderBox.width() - newWidth > 2)
+            renderBox.setWidth(newWidth);
+        renderBox.move((contentRect.width() - renderBox.width()) / 2, 0);
     } else if (ratio < 0) {
-        int newHeight = contentRect.width() * intrinsicSize().height() / intrinsicSize().width();
-        if (resultRect.height() - newHeight > 2)
-            resultRect.setHeight(newHeight);
-        resultRect.move(0, (contentRect.height() - resultRect.height()) / 2);
+        int newHeight = renderBox.width() * elementSize.height() / elementSize.width();
+        if (renderBox.height() - newHeight > 2)
+            renderBox.setHeight(newHeight);
+        renderBox.move(0, (contentRect.height() - renderBox.height()) / 2);
     }
-    return resultRect;
+
+    return renderBox;
 }
     
 void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 {
     MediaPlayer* mediaPlayer = player();
-    if (!mediaPlayer)
+    bool displayingPoster = videoElement()->shouldDisplayPosterImage();
+
+    if (displayingPoster && document()->printing() && !view()->printImages())
         return;
-    updatePlayer();
+
+    if (!displayingPoster) {
+        if (!mediaPlayer)
+            return;
+        updatePlayer();
+    }
+
     IntRect rect = videoBox();
     if (rect.isEmpty())
         return;
     rect.move(tx, ty);
-    mediaPlayer->paint(paintInfo.context, rect);
+    if (displayingPoster)
+        paintIntoRect(paintInfo.context, rect);
+    else
+        mediaPlayer->paint(paintInfo.context, rect);
 }
 
 void RenderVideo::layout()
@@ -129,6 +169,12 @@ void RenderVideo::layout()
     updatePlayer();
 }
     
+HTMLVideoElement* RenderVideo::videoElement() const
+{
+    ASSERT(node()->hasTagName(videoTag));
+    return static_cast<HTMLVideoElement*>(node()); 
+}
+
 void RenderVideo::updateFromElement()
 {
     RenderMedia::updateFromElement();
@@ -140,7 +186,7 @@ void RenderVideo::updatePlayer()
     MediaPlayer* mediaPlayer = player();
     if (!mediaPlayer)
         return;
-    if (!mediaElement()->inActiveDocument()) {
+    if (!videoElement()->inActiveDocument()) {
         mediaPlayer->setVisible(false);
         return;
     }
@@ -155,40 +201,6 @@ void RenderVideo::updatePlayer()
     mediaPlayer->setVisible(true);
 }
 
-bool RenderVideo::isWidthSpecified() const
-{
-    switch (style()->width().type()) {
-        case Fixed:
-        case Percent:
-            return true;
-        case Auto:
-        case Relative: // FIXME: Shouldn't this case return true? It doesn't for images.
-        case Static:
-        case Intrinsic:
-        case MinIntrinsic:
-            return false;
-    }
-    ASSERT(false);
-    return false;
-}
-
-bool RenderVideo::isHeightSpecified() const
-{
-    switch (style()->height().type()) {
-        case Fixed:
-        case Percent:
-            return true;
-        case Auto:
-        case Relative: // FIXME: Shouldn't this case return true? It doesn't for images.
-        case Static:
-        case Intrinsic:
-        case MinIntrinsic:
-            return false;
-    }
-    ASSERT(false);
-    return false;
-}
-
 int RenderVideo::calcReplacedWidth(bool includeMaxWidth) const
 {
     int width;
@@ -235,24 +247,9 @@ int RenderVideo::calcAspectRatioHeight() const
     return RenderBox::calcReplacedWidth() * intrinsicHeight / intrinsicWidth;
 }
 
-void RenderVideo::calcPrefWidths()
+int RenderVideo::minimumReplacedHeight() const 
 {
-    ASSERT(prefWidthsDirty());
-
-    int paddingAndBorders = paddingLeft() + paddingRight() + borderLeft() + borderRight();
-    m_maxPrefWidth = calcReplacedWidth(false) + paddingAndBorders;
-
-    if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength)
-        m_maxPrefWidth = min(m_maxPrefWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? paddingAndBorders : 0));
-
-    if (style()->width().isPercent() || style()->height().isPercent() || 
-        style()->maxWidth().isPercent() || style()->maxHeight().isPercent() ||
-        style()->minWidth().isPercent() || style()->minHeight().isPercent())
-        m_minPrefWidth = 0;
-    else
-        m_minPrefWidth = m_maxPrefWidth;
-
-    setPrefWidthsDirty(false);
+    return 0; 
 }
 
 #if USE(ACCELERATED_COMPOSITING)
index 79e5b4e..709a048 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 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
@@ -33,6 +33,7 @@
 namespace WebCore {
     
 class HTMLMediaElement;
+class HTMLVideoElement;
 #if USE(ACCELERATED_COMPOSITING)
 class GraphicsLayer;
 #endif
@@ -53,8 +54,10 @@ public:
 
 private:
     virtual void updateFromElement();
+    inline HTMLVideoElement* videoElement() const;
 
-    virtual void intrinsicSizeChanged() { videoSizeChanged(); }
+    virtual void intrinsicSizeChanged();
+    virtual void imageChanged(WrappedImagePtr, const IntRect*);
 
     virtual const char* renderName() const { return "RenderVideo"; }
 
@@ -67,16 +70,14 @@ private:
 
     virtual int calcReplacedWidth(bool includeMaxWidth = true) const;
     virtual int calcReplacedHeight() const;
-
-    virtual void calcPrefWidths();
+    virtual int minimumReplacedHeight() const;
     
     int calcAspectRatioWidth() const;
     int calcAspectRatioHeight() const;
 
-    bool isWidthSpecified() const;
-    bool isHeightSpecified() const;
-    
     void updatePlayer();
+
+    IntSize m_cachedImageSize;
 };
 
 inline RenderVideo* toRenderVideo(RenderObject* object)