Changeset 45060 in webkit


Ignore:
Timestamp:
Jun 23, 2009 11:19:31 PM (15 years ago)
Author:
oliver@apple.com
Message:

<rdar://problem/6164797> Add Canvas API to allow drawing of <video> frames
<https://bugs.webkit.org/show_bug.cgi?id=25920>

Reviewed by Sam Weinig and Dave Hyatt.

Add support for drawing the contents of the video element to the canvas
in accordance with the current HTML5 draft.

Test: media/video-canvas.html

Location:
trunk
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r45039 r45060  
     12009-06-23  Oliver Hunt  <oliver@apple.com> and Eric Carlson  <eric.carlson@apple.com>
     2
     3        Reviewed by Sam Weinig and Dave Hyatt.
     4
     5        <rdar://problem/6164797> Add Canvas API to allow drawing of <video> frames
     6        <https://bugs.webkit.org/show_bug.cgi?id=25920>
     7
     8        Add tests for drawing a video to the canvas element.
     9
     10        * media/video-canvas-expected.txt: Added.
     11        * media/video-canvas.html: Added.
     12
    1132009-06-23  Oliver Hunt  <oliver@apple.com>
    214
  • trunk/WebCore/ChangeLog

    r45038 r45060  
     12009-06-23  Oliver Hunt  <oliver@apple.com> and Eric Carlson  <eric.carlson@apple.com>
     2
     3        Reviewed by Sam Weinig and Dave Hyatt.
     4
     5        <rdar://problem/6164797> Add Canvas API to allow drawing of <video> frames
     6        <https://bugs.webkit.org/show_bug.cgi?id=25920>
     7
     8        Add support for drawing the contents of the video element to the canvas
     9        in accordance with the current HTML5 draft.
     10
     11        Test: media/video-canvas.html
     12
     13        * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
     14        (WebCore::JSCanvasRenderingContext2D::drawImage):
     15          Standard custom bindings stuff we need to do for all canvas methods.
     16        * html/CanvasRenderingContext2D.cpp:
     17        (WebCore::size): Helper function for finding the size of a video element
     18        (WebCore::CanvasRenderingContext2D::checkOrigin): moved up in the file.
     19        (WebCore::CanvasRenderingContext2D::drawImage): The various overloads of HTML5's drawImage(<video>)
     20        * html/CanvasRenderingContext2D.h:
     21        * html/HTMLMediaElement.h:
     22        (WebCore::HTMLMediaElement::hasSingleSecurityOrigin):
     23          hasSingleSecurityOrigin is needed for security, currently all implementations are trivial
     24          as we force QT to maintain a single origin.
     25        * html/HTMLVideoElement.cpp:
     26        (WebCore::HTMLVideoElement::paint):
     27            Paint routine on video so we don't have to look at MediaPlayer directly
     28        * html/HTMLVideoElement.h:
     29        * platform/graphics/MediaPlayer.cpp:
     30        (WebCore::NullMediaPlayerPrivate::hasSingleSecurityOrigin):
     31        (WebCore::MediaPlayer::hasSingleSecurityOrigin):
     32            Default implementations of hasSingleSecurityOrigin
     33        * platform/graphics/MediaPlayer.h:
     34        * platform/graphics/MediaPlayerPrivate.h:
     35        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
     36        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
     37        (WebCore::MediaPlayerPrivate::setUpVideoRendering):
     38            A video may need a player now even if it is not visible.
     39        (WebCore::MediaPlayerPrivate::hasSingleSecurityOrigin):
     40            Always return true due to restrictions we've placed on QT.
     41        * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
     42        (WebCore::MediaPlayerPrivate::paint):
     43            Jump through some hoops to allow windows QT to draw to an intermediate buffer.
     44            In the long term we'd like to cache the HDC, but this will do for now.
     45        (WebCore::MediaPlayerPrivate::hasSingleSecurityOrigin):
     46        * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h:
     47            As for Mac we force QT to only allow same origin loads.
     48
    1492009-06-23  Adam Langley  <agl@google.com>
    250
  • trunk/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp

    r43122 r45060  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    2929#include "HTMLCanvasElement.h"
    3030#include "HTMLImageElement.h"
     31#include "HTMLVideoElement.h"
    3132#include "ImageData.h"
    3233#include "JSCanvasGradient.h"
     
    3435#include "JSHTMLCanvasElement.h"
    3536#include "JSHTMLImageElement.h"
     37#include "JSHTMLVideoElement.h"
    3638#include "JSImageData.h"
    3739#include <runtime/Error.h>
     
    231233                return throwError(exec, SyntaxError);
    232234        }
     235#if ENABLE(VIDEO)
     236    } else if (o->inherits(&JSHTMLVideoElement::s_info)) {
     237            HTMLVideoElement* video = static_cast<HTMLVideoElement*>(static_cast<JSHTMLElement*>(o)->impl());
     238            switch (args.size()) {
     239                case 3:
     240                    context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec));
     241                    break;
     242                case 5:
     243                    context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec),
     244                                       args.at(3).toFloat(exec), args.at(4).toFloat(exec), ec);
     245                    setDOMException(exec, ec);
     246                    break;
     247                case 9:
     248                    context->drawImage(video, FloatRect(args.at(1).toFloat(exec), args.at(2).toFloat(exec),
     249                                       args.at(3).toFloat(exec), args.at(4).toFloat(exec)),
     250                                       FloatRect(args.at(5).toFloat(exec), args.at(6).toFloat(exec),
     251                                       args.at(7).toFloat(exec), args.at(8).toFloat(exec)), ec);
     252                    setDOMException(exec, ec);
     253                    break;
     254                default:
     255                    return throwError(exec, SyntaxError);
     256        }
     257#endif
    233258    } else {
    234259        setDOMException(exec, TYPE_MISMATCH_ERR);
  • trunk/WebCore/html/CanvasRenderingContext2D.cpp

    r44542 r45060  
    11/*
    2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
    44 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
     
    5757#include "StrokeStyleApplier.h"
    5858#include "TextMetrics.h"
     59#include "HTMLVideoElement.h"
    5960#include <stdio.h>
    6061
     
    912913    return IntSize();
    913914}
     915   
     916static IntSize size(HTMLVideoElement* video)
     917{
     918    if (MediaPlayer* player = video->player())
     919        return player->naturalSize();
     920    return IntSize();
     921}
    914922
    915923static inline FloatRect normalizeRect(const FloatRect& rect)
     
    921929}
    922930
     931void CanvasRenderingContext2D::checkOrigin(const KURL& url)
     932{
     933    RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
     934    if (!m_canvas->document()->securityOrigin()->canAccess(origin.get()))
     935        m_canvas->setOriginTainted();
     936}
     937
    923938void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y)
    924939{
     
    935950    IntSize s = size(image);
    936951    drawImage(image, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
    937 }
    938 
    939 void CanvasRenderingContext2D::checkOrigin(const KURL& url)
    940 {
    941     RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
    942     if (!m_canvas->document()->securityOrigin()->canAccess(origin.get()))
    943         m_canvas->setOriginTainted();
    944952}
    945953
     
    10321040    willDraw(destRect); // This call comes after drawImage, since the buffer we draw into may be our own, and we need to make sure it is dirty.
    10331041                        // FIXME: Arguably willDraw should become didDraw and occur after drawing calls and not before them to avoid problems like this.
     1042}
     1043
     1044void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y)
     1045{
     1046    ASSERT(video);
     1047    IntSize s = size(video);
     1048    ExceptionCode ec;
     1049    drawImage(video, x, y, s.width(), s.height(), ec);
     1050}
     1051
     1052void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
     1053                                         float x, float y, float width, float height, ExceptionCode& ec)
     1054{
     1055    ASSERT(video);
     1056    IntSize s = size(video);
     1057    drawImage(video, FloatRect(0, 0, s.width(), s.height()), FloatRect(x, y, width, height), ec);
     1058}
     1059
     1060void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect,
     1061                                         ExceptionCode& ec)
     1062{
     1063    ASSERT(video);
     1064   
     1065    ec = 0;
     1066    FloatRect videoRect = FloatRect(FloatPoint(), size(video));
     1067    if (!videoRect.contains(normalizeRect(srcRect)) || srcRect.width() == 0 || srcRect.height() == 0) {
     1068        ec = INDEX_SIZE_ERR;
     1069        return;
     1070    }
     1071   
     1072    if (!dstRect.width() || !dstRect.height())
     1073        return;
     1074   
     1075    GraphicsContext* c = drawingContext();
     1076    if (!c)
     1077        return;
     1078    if (!state().m_invertibleCTM)
     1079        return;
     1080
     1081    if (m_canvas->originClean())
     1082        checkOrigin(video->src());
     1083
     1084    if (m_canvas->originClean() && !video->hasSingleSecurityOrigin())
     1085        m_canvas->setOriginTainted();
     1086
     1087    FloatRect sourceRect = c->roundToDevicePixels(srcRect);
     1088    FloatRect destRect = c->roundToDevicePixels(dstRect);
     1089    willDraw(destRect);
     1090
     1091    c->save();
     1092    c->clip(destRect);
     1093    c->translate(destRect.x(), destRect.y());
     1094    c->scale(FloatSize(destRect.width()/sourceRect.width(), destRect.height()/sourceRect.height()));
     1095    c->translate(-sourceRect.x(), -sourceRect.y());
     1096    video->paint(c, IntRect(IntPoint(), size(video)));
     1097    c->restore();
    10341098}
    10351099
  • trunk/WebCore/html/CanvasRenderingContext2D.h

    r41616 r45060  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4848    class HTMLCanvasElement;
    4949    class HTMLImageElement;
     50    class HTMLVideoElement;
    5051    class ImageData;
    5152    class KURL;
     
    160161        void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionCode&);
    161162        void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
     163        void drawImage(HTMLVideoElement*, float x, float y);
     164        void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionCode&);
     165        void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionCode&);
    162166
    163167        void drawImageFromRect(HTMLImageElement*, float sx, float sy, float sw, float sh,
  • trunk/WebCore/html/HTMLMediaElement.h

    r44999 r45060  
    144144#endif
    145145
     146    bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
     147
    146148protected:
    147149    float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const;
  • trunk/WebCore/html/HTMLVideoElement.cpp

    r43187 r45060  
    11/*
    2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    187187}
    188188
    189 }
    190 #endif
     189void HTMLVideoElement::paint(GraphicsContext* context, const IntRect& r)
     190{
     191    // FIXME: We should also be able to paint the poster image.
     192
     193    MediaPlayer* player = HTMLMediaElement::player();
     194    if (!player)
     195        return;
     196
     197    player->setVisible(true); // Make player visible or it won't draw.
     198    player->paint(context, r);
     199}
     200
     201}
     202#endif
  • trunk/WebCore/html/HTMLVideoElement.h

    r41042 r45060  
    11/*
    2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6767    void updatePosterImage();
    6868
     69    // Used by canvas to gain raw pixel access
     70    void paint(GraphicsContext*, const IntRect&);
     71
    6972private:
    7073    OwnPtr<HTMLImageLoader> m_imageLoader;
  • trunk/WebCore/platform/graphics/MediaPlayer.cpp

    r44999 r45060  
    104104    virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
    105105#endif
     106
     107    virtual bool hasSingleSecurityOrigin() const { return true; }
    106108};
    107109
     
    530532}
    531533
    532 }
    533 #endif
     534bool MediaPlayer::hasSingleSecurityOrigin() const
     535{
     536    return m_private->hasSingleSecurityOrigin();
     537}
     538
     539}
     540#endif
  • trunk/WebCore/platform/graphics/MediaPlayer.h

    r44999 r45060  
    192192#endif
    193193
     194    bool hasSingleSecurityOrigin() const;
     195
    194196private:
    195197    static void initializeMediaEngines();
  • trunk/WebCore/platform/graphics/MediaPlayerPrivate.h

    r44999 r45060  
    100100    virtual void acceleratedRenderingStateChanged() { }
    101101#endif
     102
     103    virtual bool hasSingleSecurityOrigin() const { return false; }
    102104};
    103105
  • trunk/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h

    r44999 r45060  
    6969    void didEnd();
    7070
     71    bool hasSingleSecurityOrigin() const;
    7172private:
    7273    MediaPlayerPrivate(MediaPlayer*);
  • trunk/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm

    r44999 r45060  
    498498    MediaRenderingMode currentMode = currentRenderingMode();
    499499    MediaRenderingMode preferredMode = preferredRenderingMode();
    500     if (currentMode == preferredMode)
     500    if (currentMode == preferredMode && currentMode != MediaRenderingNone)
    501501        return;
    502502
     
    505505
    506506    switch (preferredMode) {
    507     case MediaRenderingNone:
    508         break;
    509507    case MediaRenderingMovieView:
    510508        createQTMovieView();
    511509        break;
     510    case MediaRenderingNone:
    512511    case MediaRenderingSoftwareRenderer:
    513512        createQTVideoRenderer();
     
    13101309#endif
    13111310
     1311bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
     1312{
     1313    // We tell quicktime to disallow resources that come from different origins
     1314    // so we know all media is single origin.
     1315    return true;
     1316}
     1317
    13121318} // namespace WebCore
    13131319
  • trunk/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp

    r44999 r45060  
    428428    if (p->paintingDisabled() || !m_qtMovie || m_hasUnsupportedTracks)
    429429        return;
     430
     431    bool usingTempBitmap = false;
     432    OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
    430433    HDC hdc = p->getWindowsContext(r);
     434    if (!hdc) {
     435        // The graphics context doesn't have an associated HDC so create a temporary
     436        // bitmap where QTMovieWin can draw the frame and we can copy it.
     437        usingTempBitmap = true;
     438        bitmap.set(p->createWindowsBitmap(r.size()));
     439        hdc = bitmap->hdc();
     440
     441        // FIXME: is this necessary??
     442        XFORM xform;
     443        xform.eM11 = 1.0f;
     444        xform.eM12 = 0.0f;
     445        xform.eM21 = 0.0f;
     446        xform.eM22 = 1.0f;
     447        xform.eDx = -r.x();
     448        xform.eDy = -r.y();
     449        SetWorldTransform(hdc, &xform);
     450    }
     451
    431452    m_qtMovie->paint(hdc, r.x(), r.y());
    432     p->releaseWindowsContext(hdc, r);
     453    if (usingTempBitmap)
     454        p->drawWindowsBitmap(bitmap.get(), r.topLeft());
     455    else
     456        p->releaseWindowsContext(hdc, r);
    433457
    434458#if DRAW_FRAME_RATE
     
    542566}
    543567
    544 }
    545 
    546 #endif
    547 
     568bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
     569{
     570    // We tell quicktime to disallow resources that come from different origins
     571    // so we all media is single origin.
     572    return true;
     573}
     574
     575}
     576
     577#endif
     578
  • trunk/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h

    r44999 r45060  
    9191    void paint(GraphicsContext*, const IntRect&);
    9292   
     93    bool hasSingleSecurityOrigin() const;
    9394
    9495private:
Note: See TracChangeset for help on using the changeset viewer.