diff options
Diffstat (limited to 'cc')
-rw-r--r-- | cc/DEPS | 1 | ||||
-rw-r--r-- | cc/cc.gyp | 1 | ||||
-rw-r--r-- | cc/cc_tests.gyp | 1 | ||||
-rw-r--r-- | cc/gl_renderer.cc | 1 | ||||
-rw-r--r-- | cc/layer_tree_host_impl_unittest.cc | 73 | ||||
-rw-r--r-- | cc/software_renderer.cc | 7 | ||||
-rw-r--r-- | cc/software_renderer.h | 5 | ||||
-rw-r--r-- | cc/video_layer.cc | 17 | ||||
-rw-r--r-- | cc/video_layer.h | 17 | ||||
-rw-r--r-- | cc/video_layer_impl.cc | 168 | ||||
-rw-r--r-- | cc/video_layer_impl.h | 29 |
11 files changed, 214 insertions, 106 deletions
@@ -4,6 +4,7 @@ include_rules = [ "+third_party/khronos/GLES2/gl2.h", "+third_party/khronos/GLES2/gl2ext.h", "+ui/gfx", + "+media", # http://crbug.com/144542 "+third_party/WebKit/Source/WebCore/platform/graphics/FloatPoint.h", "+third_party/WebKit/Source/WebCore/platform/graphics/FloatPoint3D.h", @@ -236,6 +236,7 @@ '<(DEPTH)/base/base.gyp:base', '<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '<(DEPTH)/skia/skia.gyp:skia', + '<(DEPTH)/media/media.gyp:media', '<(DEPTH)/ui/gl/gl.gyp:gl', '<(DEPTH)/ui/ui.gyp:ui', '<(webkit_src_dir)/Source/WTF/WTF.gyp/WTF.gyp:wtf', diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index b3bd9ca..1c48219 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -88,6 +88,7 @@ 'type': '<(gtest_target_type)', 'dependencies': [ '../base/base.gyp:test_support_base', + '../media/media.gyp:media', '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', diff --git a/cc/gl_renderer.cc b/cc/gl_renderer.cc index 1c4fec2..020e854 100644 --- a/cc/gl_renderer.cc +++ b/cc/gl_renderer.cc @@ -37,7 +37,6 @@ #include "ui/gfx/rect_conversions.h" #include <public/WebGraphicsContext3D.h> #include <public/WebSharedGraphicsContext3D.h> -#include <public/WebVideoFrame.h> #include <set> #include <string> #include <vector> diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc index 64cec3b..2d50654 100644 --- a/cc/layer_tree_host_impl_unittest.cc +++ b/cc/layer_tree_host_impl_unittest.cc @@ -6,6 +6,7 @@ #include "cc/layer_tree_host_impl.h" +#include "base/bind.h" #include "base/command_line.h" #include "base/hash_tables.h" #include "cc/delegated_renderer_layer_impl.h" @@ -34,6 +35,8 @@ #include "cc/tile_draw_quad.h" #include "cc/tiled_layer_impl.h" #include "cc/video_layer_impl.h" +#include "media/base/media.h" +#include "media/base/video_frame.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include <public/WebVideoFrame.h> @@ -44,6 +47,7 @@ using namespace LayerTestCommon; using namespace WebKit; using namespace WebKitTests; +using media::VideoFrame; using ::testing::Mock; using ::testing::Return; using ::testing::AnyNumber; @@ -63,6 +67,7 @@ public: , m_didRequestRedraw(false) , m_reduceMemoryResult(true) { + media::InitializeMediaLibraryForTesting(); } virtual void SetUp() @@ -2532,25 +2537,31 @@ private: base::hash_set<unsigned> m_allocatedTextureIds; }; -// Fake video frame that represents a 4x4 YUV video frame. +// Fake WebVideoFrame wrapper of media::VideoFrame. class FakeVideoFrame: public WebVideoFrame { public: - FakeVideoFrame() : m_textureId(0) { memset(m_data, 0x80, sizeof(m_data)); } + explicit FakeVideoFrame(const scoped_refptr<VideoFrame>& frame) : m_frame(frame) { } virtual ~FakeVideoFrame() { } - virtual Format format() const { return m_textureId ? FormatNativeTexture : FormatYV12; } - virtual unsigned width() const { return 4; } - virtual unsigned height() const { return 4; } - virtual unsigned planes() const { return m_textureId ? 0 : 3; } - virtual int stride(unsigned plane) const { return 4; } - virtual const void* data(unsigned plane) const { return m_data; } - virtual unsigned textureId() const { return m_textureId; } - virtual unsigned textureTarget() const { return m_textureId ? GL_TEXTURE_2D : 0; } - void setTextureId(unsigned id) { m_textureId = id; } + virtual Format format() const { NOTREACHED(); return FormatInvalid; } + virtual unsigned width() const { NOTREACHED(); return 0; } + virtual unsigned height() const { NOTREACHED(); return 0; } + virtual unsigned planes() const { NOTREACHED(); return 0; } + virtual int stride(unsigned plane) const { NOTREACHED(); return 0; } + virtual const void* data(unsigned plane) const { NOTREACHED(); return NULL; } + virtual unsigned textureId() const { NOTREACHED(); return 0; } + virtual unsigned textureTarget() const { NOTREACHED(); return 0; } + + static VideoFrame* toVideoFrame(WebVideoFrame* web_video_frame) { + FakeVideoFrame* wrapped_frame = + static_cast<FakeVideoFrame*>(web_video_frame); + if (wrapped_frame) + return wrapped_frame->m_frame.get(); + return NULL; + } private: - char m_data[16]; - unsigned m_textureId; + scoped_refptr<VideoFrame> m_frame; }; // Fake video frame provider that always provides the same FakeVideoFrame. @@ -2695,10 +2706,15 @@ TEST_P(LayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) textureLayerWithMask->setMaskLayer(maskLayer.PassAs<LayerImpl>()); rootLayer->addChild(textureLayerWithMask.PassAs<LayerImpl>()); - FakeVideoFrame videoFrame; + FakeVideoFrame videoFrame(VideoFrame::CreateColorFrame(gfx::Size(4, 4), + 0x80, 0x80, 0x80, + base::TimeDelta())); + VideoLayerImpl::FrameUnwrapper unwrapper = + base::Bind(FakeVideoFrame::toVideoFrame); FakeVideoFrameProvider provider; provider.setFrame(&videoFrame); - scoped_ptr<VideoLayerImpl> videoLayer = VideoLayerImpl::create(layerId++, &provider); + scoped_ptr<VideoLayerImpl> videoLayer = + VideoLayerImpl::create(layerId++, &provider, unwrapper); videoLayer->setBounds(IntSize(10, 10)); videoLayer->setAnchorPoint(FloatPoint(0, 0)); videoLayer->setContentBounds(IntSize(10, 10)); @@ -2706,10 +2722,9 @@ TEST_P(LayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) videoLayer->setLayerTreeHostImpl(m_hostImpl.get()); rootLayer->addChild(videoLayer.PassAs<LayerImpl>()); - FakeVideoFrame hwVideoFrame; FakeVideoFrameProvider hwProvider; - hwProvider.setFrame(&hwVideoFrame); - scoped_ptr<VideoLayerImpl> hwVideoLayer = VideoLayerImpl::create(layerId++, &hwProvider); + scoped_ptr<VideoLayerImpl> hwVideoLayer = + VideoLayerImpl::create(layerId++, &hwProvider, unwrapper); hwVideoLayer->setBounds(IntSize(10, 10)); hwVideoLayer->setAnchorPoint(FloatPoint(0, 0)); hwVideoLayer->setContentBounds(IntSize(10, 10)); @@ -2756,7 +2771,13 @@ TEST_P(LayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) // Use a context that supports IOSurfaces m_hostImpl->initializeRenderer(FakeWebCompositorOutputSurface::create(scoped_ptr<WebKit::WebGraphicsContext3D>(new FakeWebGraphicsContext3DWithIOSurface)).PassAs<GraphicsContext>()); - hwVideoFrame.setTextureId(m_hostImpl->resourceProvider()->graphicsContext3D()->createTexture()); + FakeVideoFrame hwVideoFrame( + VideoFrame::WrapNativeTexture( + m_hostImpl->resourceProvider()->graphicsContext3D()->createTexture(), + GL_TEXTURE_2D, + gfx::Size(4, 4), gfx::Size(4, 4), base::TimeDelta(), + VideoFrame::ReadPixelsCB(), base::Closure())); + hwProvider.setFrame(&hwVideoFrame); m_hostImpl->setRootLayer(rootLayer.Pass()); @@ -2786,8 +2807,13 @@ TEST_P(LayerTreeHostImplTest, dontUseOldResourcesAfterLostContext) m_hostImpl->didDrawAllLayers(frame); m_hostImpl->swapBuffers(); - hwVideoFrame.setTextureId(m_hostImpl->resourceProvider()->graphicsContext3D()->createTexture()); - hwProvider.setFrame(&hwVideoFrame); + FakeVideoFrame hwVideoFrame2( + VideoFrame::WrapNativeTexture( + m_hostImpl->resourceProvider()->graphicsContext3D()->createTexture(), + GL_TEXTURE_2D, + gfx::Size(4, 4), gfx::Size(4, 4), base::TimeDelta(), + VideoFrame::ReadPixelsCB(), base::Closure())); + hwProvider.setFrame(&hwVideoFrame2); EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); m_hostImpl->drawLayers(frame); @@ -2862,8 +2888,11 @@ TEST_P(LayerTreeHostImplTest, layersFreeTextures) textureLayer->setTextureId(1); rootLayer->addChild(textureLayer.PassAs<LayerImpl>()); + VideoLayerImpl::FrameUnwrapper unwrapper = + base::Bind(FakeVideoFrame::toVideoFrame); FakeVideoFrameProvider provider; - scoped_ptr<VideoLayerImpl> videoLayer = VideoLayerImpl::create(4, &provider); + scoped_ptr<VideoLayerImpl> videoLayer = + VideoLayerImpl::create(4, &provider, unwrapper); videoLayer->setBounds(IntSize(10, 10)); videoLayer->setAnchorPoint(FloatPoint(0, 0)); videoLayer->setContentBounds(IntSize(10, 10)); diff --git a/cc/software_renderer.cc b/cc/software_renderer.cc index 52256cc..312d873 100644 --- a/cc/software_renderer.cc +++ b/cc/software_renderer.cc @@ -17,12 +17,12 @@ #include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/effects/SkLayerRasterizer.h" #include "ui/gfx/rect_conversions.h" +#include <public/WebCompositorSoftwareOutputDevice.h> #include <public/WebImage.h> #include <public/WebSize.h> #include <public/WebTransformationMatrix.h> using WebKit::WebCompositorSoftwareOutputDevice; -using WebKit::WebImage; using WebKit::WebSize; using WebKit::WebTransformationMatrix; @@ -255,11 +255,12 @@ void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureD // FIXME: Add support for non-premultiplied alpha. ResourceProvider::ScopedReadLockSoftware quadResourceLock(m_resourceProvider, quad->resourceId()); - gfx::RectF uvRect = gfx::ScaleRect(quad->uvRect(), quad->quadRect().width(), quad->quadRect().height()); + const SkBitmap* bitmap = quadResourceLock.skBitmap(); + gfx::RectF uvRect = gfx::ScaleRect(quad->uvRect(), bitmap->width(), bitmap->height()); SkIRect skUvRect = toSkIRect(gfx::ToEnclosingRect(uvRect)); if (quad->flipped()) m_skCurrentCanvas->scale(1, -1); - m_skCurrentCanvas->drawBitmapRect(*quadResourceLock.skBitmap(), &skUvRect, toSkRect(quadVertexRect()), &m_skCurrentPaint); + m_skCurrentCanvas->drawBitmapRect(*bitmap, &skUvRect, toSkRect(quadVertexRect()), &m_skCurrentPaint); } void SoftwareRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* quad) diff --git a/cc/software_renderer.h b/cc/software_renderer.h index 1f1604b..0e4251a 100644 --- a/cc/software_renderer.h +++ b/cc/software_renderer.h @@ -7,7 +7,10 @@ #include "base/basictypes.h" #include "cc/direct_renderer.h" -#include <public/WebCompositorSoftwareOutputDevice.h> + +namespace WebKit { +class WebCompositorSoftwareOutputDevice; +} namespace cc { diff --git a/cc/video_layer.cc b/cc/video_layer.cc index 190063e..1d3e7d8 100644 --- a/cc/video_layer.cc +++ b/cc/video_layer.cc @@ -10,14 +10,17 @@ namespace cc { -scoped_refptr<VideoLayer> VideoLayer::create(WebKit::WebVideoFrameProvider* provider) +scoped_refptr<VideoLayer> VideoLayer::create( + WebKit::WebVideoFrameProvider* provider, + const FrameUnwrapper& unwrapper) { - return make_scoped_refptr(new VideoLayer(provider)); + return make_scoped_refptr(new VideoLayer(provider, unwrapper)); } -VideoLayer::VideoLayer(WebKit::WebVideoFrameProvider* provider) - : Layer() - , m_provider(provider) +VideoLayer::VideoLayer(WebKit::WebVideoFrameProvider* provider, + const FrameUnwrapper& unwrapper) + : m_provider(provider) + , m_unwrapper(unwrapper) { DCHECK(m_provider); } @@ -28,7 +31,7 @@ VideoLayer::~VideoLayer() scoped_ptr<LayerImpl> VideoLayer::createLayerImpl() { - return VideoLayerImpl::create(m_layerId, m_provider).PassAs<LayerImpl>(); + return VideoLayerImpl::create(m_layerId, m_provider, m_unwrapper).PassAs<LayerImpl>(); } -} // namespace cc +} // namespace cc diff --git a/cc/video_layer.h b/cc/video_layer.h index 5d71fff..756c502 100644 --- a/cc/video_layer.h +++ b/cc/video_layer.h @@ -5,12 +5,18 @@ #ifndef VideoLayerChromium_h #define VideoLayerChromium_h +#include "base/callback.h" #include "cc/layer.h" namespace WebKit { +class WebVideoFrame; class WebVideoFrameProvider; } +namespace media { +class VideoFrame; +} + namespace cc { class VideoLayerImpl; @@ -18,17 +24,22 @@ class VideoLayerImpl; // A Layer that contains a Video element. class VideoLayer : public Layer { public: - static scoped_refptr<VideoLayer> create(WebKit::WebVideoFrameProvider*); + typedef base::Callback<media::VideoFrame* (WebKit::WebVideoFrame*)> FrameUnwrapper; + + static scoped_refptr<VideoLayer> create(WebKit::WebVideoFrameProvider*, + const FrameUnwrapper&); virtual scoped_ptr<LayerImpl> createLayerImpl() OVERRIDE; private: - explicit VideoLayer(WebKit::WebVideoFrameProvider*); + VideoLayer(WebKit::WebVideoFrameProvider*, const FrameUnwrapper&); virtual ~VideoLayer(); // This pointer is only for passing to VideoLayerImpl's constructor. It should never be dereferenced by this class. WebKit::WebVideoFrameProvider* m_provider; + FrameUnwrapper m_unwrapper; }; -} +} // namespace cc + #endif diff --git a/cc/video_layer_impl.cc b/cc/video_layer_impl.cc index 86cf037..43e8864 100644 --- a/cc/video_layer_impl.cc +++ b/cc/video_layer_impl.cc @@ -6,7 +6,7 @@ #include "cc/video_layer_impl.h" -#include "NotImplemented.h" +#include "base/logging.h" #include "cc/io_surface_draw_quad.h" #include "cc/layer_tree_host_impl.h" #include "cc/proxy.h" @@ -15,16 +15,21 @@ #include "cc/stream_video_draw_quad.h" #include "cc/texture_draw_quad.h" #include "cc/yuv_video_draw_quad.h" +#include "media/filters/skcanvas_video_renderer.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" -#include <public/WebVideoFrame.h> namespace cc { -VideoLayerImpl::VideoLayerImpl(int id, WebKit::WebVideoFrameProvider* provider) +VideoLayerImpl::VideoLayerImpl(int id, WebKit::WebVideoFrameProvider* provider, + const FrameUnwrapper& unwrapper) : LayerImpl(id) , m_provider(provider) + , m_unwrapper(unwrapper) + , m_webFrame(0) , m_frame(0) + , m_format(GL_INVALID_VALUE) + , m_convertYUV(false) , m_externalTextureResource(0) { // This matrix is the default transformation for stream textures, and flips on the Y axis. @@ -53,8 +58,8 @@ VideoLayerImpl::~VideoLayerImpl() freePlaneData(layerTreeHostImpl()->resourceProvider()); #ifndef NDEBUG - for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) - DCHECK(!m_framePlanes[i].resourceId); + for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i) + DCHECK(!m_framePlanes[i].resourceId); DCHECK(!m_externalTextureResource); #endif } @@ -68,24 +73,50 @@ void VideoLayerImpl::stopUsingProvider() m_provider = 0; } -// Convert WebKit::WebVideoFrame::Format to GraphicsContext3D's format enum values. -static GLenum convertVFCFormatToGC3DFormat(const WebKit::WebVideoFrame& frame) +// Convert media::VideoFrame::Format to OpenGL enum values. +static GLenum convertVFCFormatToGLenum(const media::VideoFrame& frame) { switch (frame.format()) { - case WebKit::WebVideoFrame::FormatYV12: - case WebKit::WebVideoFrame::FormatYV16: + case media::VideoFrame::YV12: + case media::VideoFrame::YV16: return GL_LUMINANCE; - case WebKit::WebVideoFrame::FormatNativeTexture: - return frame.textureTarget(); - case WebKit::WebVideoFrame::FormatInvalid: - case WebKit::WebVideoFrame::FormatRGB32: - case WebKit::WebVideoFrame::FormatEmpty: - case WebKit::WebVideoFrame::FormatI420: - notImplemented(); + case media::VideoFrame::NATIVE_TEXTURE: + return frame.texture_target(); + case media::VideoFrame::INVALID: + case media::VideoFrame::RGB32: + case media::VideoFrame::EMPTY: + case media::VideoFrame::I420: + NOTREACHED(); + break; } return GL_INVALID_VALUE; } +size_t VideoLayerImpl::numPlanes() const +{ + if (!m_frame) + return 0; + + if (m_convertYUV) + return 1; + + switch (m_frame->format()) { + case media::VideoFrame::RGB32: + return 1; + case media::VideoFrame::YV12: + case media::VideoFrame::YV16: + return 3; + case media::VideoFrame::INVALID: + case media::VideoFrame::EMPTY: + case media::VideoFrame::I420: + break; + case media::VideoFrame::NATIVE_TEXTURE: + return 0; + } + NOTREACHED(); + return 0; +} + void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider) { DCHECK(Proxy::isImplThread()); @@ -117,39 +148,45 @@ void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider) return; } - m_frame = m_provider->getCurrentFrame(); + m_webFrame = m_provider->getCurrentFrame(); + m_frame = m_unwrapper.Run(m_webFrame); if (!m_frame) return; - m_format = convertVFCFormatToGC3DFormat(*m_frame); + m_format = convertVFCFormatToGLenum(*m_frame); if (m_format == GL_INVALID_VALUE) { - m_provider->putCurrentFrame(m_frame); + m_provider->putCurrentFrame(m_webFrame); m_frame = 0; return; } - if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { - m_provider->putCurrentFrame(m_frame); - m_frame = 0; - return; - } + // FIXME: If we're in software compositing mode, we do the YUV -> RGB + // conversion here. That involves an extra copy of each frame to a bitmap. + // Obviously, this is suboptimal and should be addressed once ubercompositor + // starts shaping up. + m_convertYUV = resourceProvider->defaultResourceType() == ResourceProvider::Bitmap && + (m_frame->format() == media::VideoFrame::YV12 || + m_frame->format() == media::VideoFrame::YV16); + + if (m_convertYUV) + m_format = GL_RGBA; if (!allocatePlaneData(resourceProvider)) { - m_provider->putCurrentFrame(m_frame); + m_provider->putCurrentFrame(m_webFrame); m_frame = 0; return; } if (!copyPlaneData(resourceProvider)) { - m_provider->putCurrentFrame(m_frame); + m_provider->putCurrentFrame(m_webFrame); m_frame = 0; return; } if (m_format == GL_TEXTURE_2D) - m_externalTextureResource = resourceProvider->createResourceFromExternalTexture(m_frame->textureId()); + m_externalTextureResource = resourceProvider->createResourceFromExternalTexture(m_frame->texture_id()); } void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData) @@ -165,25 +202,24 @@ void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad // FIXME: When we pass quads out of process, we need to double-buffer, or // otherwise synchonize use of all textures in the quad. - IntRect quadRect(IntPoint(), contentBounds()); + gfx::Rect quadRect(contentBounds()); switch (m_format) { case GL_LUMINANCE: { // YUV software decoder. - const FramePlane& yPlane = m_framePlanes[WebKit::WebVideoFrame::yPlane]; - const FramePlane& uPlane = m_framePlanes[WebKit::WebVideoFrame::uPlane]; - const FramePlane& vPlane = m_framePlanes[WebKit::WebVideoFrame::vPlane]; + const FramePlane& yPlane = m_framePlanes[media::VideoFrame::kYPlane]; + const FramePlane& uPlane = m_framePlanes[media::VideoFrame::kUPlane]; + const FramePlane& vPlane = m_framePlanes[media::VideoFrame::kVPlane]; scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create(sharedQuadState, quadRect, yPlane, uPlane, vPlane); quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData); break; } case GL_RGBA: { // RGBA software decoder. - const FramePlane& plane = m_framePlanes[WebKit::WebVideoFrame::rgbPlane]; - float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width(); - + const FramePlane& plane = m_framePlanes[media::VideoFrame::kRGBPlane]; bool premultipliedAlpha = true; - FloatRect uvRect(0, 0, widthScaleFactor, 1); + float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width(); + gfx::RectF uvRect(widthScaleFactor, 1); bool flipped = false; scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(sharedQuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped); quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); @@ -192,26 +228,26 @@ void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad case GL_TEXTURE_2D: { // NativeTexture hardware decoder. bool premultipliedAlpha = true; - FloatRect uvRect(0, 0, 1, 1); + gfx::RectF uvRect(1, 1); bool flipped = false; scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(sharedQuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flipped); quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); break; } case GL_TEXTURE_RECTANGLE_ARB: { - IntSize textureSize(m_frame->width(), m_frame->height()); - scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create(sharedQuadState, quadRect, textureSize, m_frame->textureId(), IOSurfaceDrawQuad::Unflipped); + scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create(sharedQuadState, quadRect, m_frame->data_size(), m_frame->texture_id(), IOSurfaceDrawQuad::Unflipped); quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); break; } case GL_TEXTURE_EXTERNAL_OES: { // StreamTexture hardware decoder. - scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::create(sharedQuadState, quadRect, m_frame->textureId(), m_streamTextureMatrix); + scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::create(sharedQuadState, quadRect, m_frame->texture_id(), m_streamTextureMatrix); quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); break; } default: - CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but update this! + NOTREACHED(); // Someone updated convertVFCFormatToGLenum above but update this! + break; } } @@ -233,29 +269,29 @@ void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) m_externalTextureResource = 0; } - m_provider->putCurrentFrame(m_frame); + m_provider->putCurrentFrame(m_webFrame); m_frame = 0; m_providerLock.Release(); } -static int videoFrameDimension(int originalDimension, unsigned plane, int format) +static int videoFrameDimension(int originalDimension, size_t plane, int format) { - if (format == WebKit::WebVideoFrame::FormatYV12 && plane != WebKit::WebVideoFrame::yPlane) + if (format == media::VideoFrame::YV12 && plane != media::VideoFrame::kYPlane) return originalDimension / 2; return originalDimension; } -static bool hasPaddingBytes(const WebKit::WebVideoFrame& frame, unsigned plane) +static bool hasPaddingBytes(const media::VideoFrame& frame, size_t plane) { - return frame.stride(plane) > videoFrameDimension(frame.width(), plane, frame.format()); + return frame.stride(plane) > videoFrameDimension(frame.data_size().width(), plane, frame.format()); } -IntSize VideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame, unsigned plane) +IntSize computeVisibleSize(const media::VideoFrame& frame, size_t plane) { - int visibleWidth = videoFrameDimension(frame.width(), plane, frame.format()); + int visibleWidth = videoFrameDimension(frame.data_size().width(), plane, frame.format()); int originalWidth = visibleWidth; - int visibleHeight = videoFrameDimension(frame.height(), plane, frame.format()); + int visibleHeight = videoFrameDimension(frame.data_size().height(), plane, frame.format()); // When there are dead pixels at the edge of the texture, decrease // the frame width by 1 to prevent the rightmost pixels from @@ -267,8 +303,8 @@ IntSize VideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame, u // one V value. If we decrease the width of the UV plane, we must decrease the // width of the Y texture by 2 for proper alignment. This must happen // always, even if Y's texture does not have padding bytes. - if (plane == WebKit::WebVideoFrame::yPlane && frame.format() == WebKit::WebVideoFrame::FormatYV12) { - if (hasPaddingBytes(frame, WebKit::WebVideoFrame::uPlane)) + if (plane == media::VideoFrame::kYPlane && frame.format() == media::VideoFrame::YV12) { + if (hasPaddingBytes(frame, media::VideoFrame::kUPlane)) visibleWidth = originalWidth - 2; } @@ -295,11 +331,12 @@ void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider) bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) { - int maxTextureSize = resourceProvider->maxTextureSize(); - for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex) { + const int maxTextureSize = resourceProvider->maxTextureSize(); + const size_t planeCount = numPlanes(); + for (size_t planeIndex = 0; planeIndex < planeCount; ++planeIndex) { VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; - IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimension(m_frame->height(), planeIndex, m_frame->format())); + IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimension(m_frame->data_size().height(), planeIndex, m_frame->format())); // FIXME: Remove the test against maxTextureSize when tiled layers are implemented. if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTextureSize || requiredTextureSize.height() > maxTextureSize) return false; @@ -321,13 +358,22 @@ bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) { - size_t softwarePlaneCount = m_frame->planes(); - if (!softwarePlaneCount) + const size_t planeCount = numPlanes(); + if (!planeCount) return true; - for (size_t softwarePlaneIndex = 0; softwarePlaneIndex < softwarePlaneCount; ++softwarePlaneIndex) { - VideoLayerImpl::FramePlane& plane = m_framePlanes[softwarePlaneIndex]; - const uint8_t* softwarePlanePixels = static_cast<const uint8_t*>(m_frame->data(softwarePlaneIndex)); + if (m_convertYUV) { + if (!m_videoRenderer) + m_videoRenderer.reset(new media::SkCanvasVideoRenderer); + VideoLayerImpl::FramePlane& plane = m_framePlanes[media::VideoFrame::kRGBPlane]; + ResourceProvider::ScopedWriteLockSoftware lock(resourceProvider, plane.resourceId); + m_videoRenderer->Paint(m_frame, lock.skCanvas(), gfx::Rect(plane.size), 0xFF); + return true; + } + + for (size_t planeIndex = 0; planeIndex < planeCount; ++planeIndex) { + VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; + const uint8_t* softwarePlanePixels = m_frame->data(planeIndex); IntRect planeRect(IntPoint(), plane.size); resourceProvider->upload(plane.resourceId, softwarePlanePixels, planeRect, planeRect, IntSize()); } @@ -336,14 +382,14 @@ bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider) { - for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) + for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i) m_framePlanes[i].freeData(resourceProvider); } void VideoLayerImpl::freeUnusedPlaneData(ResourceProvider* resourceProvider) { - unsigned firstUnusedPlane = m_frame ? m_frame->planes() : 0; - for (unsigned i = firstUnusedPlane; i < WebKit::WebVideoFrame::maxPlanes; ++i) + size_t firstUnusedPlane = numPlanes(); + for (size_t i = firstUnusedPlane; i < media::VideoFrame::kMaxPlanes; ++i) m_framePlanes[i].freeData(resourceProvider); } diff --git a/cc/video_layer_impl.h b/cc/video_layer_impl.h index 47172d0..964d35c 100644 --- a/cc/video_layer_impl.h +++ b/cc/video_layer_impl.h @@ -6,8 +6,10 @@ #define CCVideoLayerImpl_h #include "IntSize.h" +#include "base/callback.h" #include "base/synchronization/lock.h" #include "cc/layer_impl.h" +#include "media/base/video_frame.h" #include "third_party/khronos/GLES2/gl2.h" #include <public/WebTransformationMatrix.h> #include <public/WebVideoFrameProvider.h> @@ -16,17 +18,24 @@ namespace WebKit { class WebVideoFrame; } +namespace media { +class SkCanvasVideoRenderer; +} + namespace cc { class LayerTreeHostImpl; class VideoLayerImpl; class VideoLayerImpl : public LayerImpl - , public WebKit::WebVideoFrameProvider::Client { + , public WebKit::WebVideoFrameProvider::Client { public: - static scoped_ptr<VideoLayerImpl> create(int id, WebKit::WebVideoFrameProvider* provider) + typedef base::Callback<media::VideoFrame* (WebKit::WebVideoFrame*)> FrameUnwrapper; + + static scoped_ptr<VideoLayerImpl> create(int id, WebKit::WebVideoFrameProvider* provider, + const FrameUnwrapper& unwrapper) { - return make_scoped_ptr(new VideoLayerImpl(id, provider)); + return make_scoped_ptr(new VideoLayerImpl(id, provider, unwrapper)); } virtual ~VideoLayerImpl(); @@ -58,9 +67,8 @@ public: }; private: - VideoLayerImpl(int, WebKit::WebVideoFrameProvider*); + VideoLayerImpl(int, WebKit::WebVideoFrameProvider*, const FrameUnwrapper&); - static IntSize computeVisibleSize(const WebKit::WebVideoFrame&, unsigned plane); virtual const char* layerTypeAsString() const OVERRIDE; void willDrawInternal(ResourceProvider*); @@ -68,6 +76,7 @@ private: bool copyPlaneData(ResourceProvider*); void freePlaneData(ResourceProvider*); void freeUnusedPlaneData(ResourceProvider*); + size_t numPlanes() const; // Guards the destruction of m_provider and the frame that it provides base::Lock m_providerLock; @@ -75,12 +84,16 @@ private: WebKit::WebTransformationMatrix m_streamTextureMatrix; - WebKit::WebVideoFrame* m_frame; + FrameUnwrapper m_unwrapper; + WebKit::WebVideoFrame *m_webFrame; + media::VideoFrame* m_frame; GLenum m_format; + bool m_convertYUV; ResourceProvider::ResourceId m_externalTextureResource; + scoped_ptr<media::SkCanvasVideoRenderer> m_videoRenderer; - // Each index in this array corresponds to a plane in WebKit::WebVideoFrame. - FramePlane m_framePlanes[WebKit::WebVideoFrame::maxPlanes]; + // Each index in this array corresponds to a plane in media::VideoFrame. + FramePlane m_framePlanes[media::VideoFrame::kMaxPlanes]; }; } // namespace cc |