| Index: cc/video_layer_impl.cc
|
| diff --git a/cc/video_layer_impl.cc b/cc/video_layer_impl.cc
|
| index 86cf037eb8baa87676451710629a73fdde0bc619..97fe941bafdf743e606d47da81028bc45fa8365b 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"
|
| @@ -14,17 +14,22 @@
|
| #include "cc/resource_provider.h"
|
| #include "cc/stream_video_draw_quad.h"
|
| #include "cc/texture_draw_quad.h"
|
| +#include "cc/video_frame_draw_quad.h"
|
| #include "cc/yuv_video_draw_quad.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_emitFrameQuad(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,44 @@ 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;
|
| }
|
|
|
| +static size_t numPlanes(const media::VideoFrame& frame)
|
| +{
|
| + switch (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 +142,42 @@ 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;
|
| + m_emitFrameQuad = resourceProvider->defaultResourceType() == ResourceProvider::Bitmap ||
|
| + m_frame->format() == media::VideoFrame::YV12 ||
|
| + m_frame->format() == media::VideoFrame::YV16;
|
| +
|
| + // Don't allocate plane data if we'll emit the frame itself
|
| + if (m_emitFrameQuad)
|
| return;
|
| - }
|
|
|
| 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,21 +193,28 @@ 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());
|
| +
|
| + if (m_emitFrameQuad) {
|
| + scoped_ptr<VideoFrameDrawQuad> drawQuad =
|
| + VideoFrameDrawQuad::create(sharedQuadState, quadRect, m_frame);
|
| + quadSink.append(drawQuad.PassAs<DrawQuad>(), appendQuadsData);
|
| + return;
|
| + }
|
|
|
| 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];
|
| + const FramePlane& plane = m_framePlanes[media::VideoFrame::kRGBPlane];
|
| float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width();
|
|
|
| bool premultipliedAlpha = true;
|
| @@ -199,19 +234,20 @@ void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad
|
| 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);
|
| + IntSize textureSize(m_frame->data_size().width(), m_frame->data_size().height());
|
| + scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create(sharedQuadState, quadRect, textureSize, 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,14 @@ void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider)
|
|
|
| bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider)
|
| {
|
| - int maxTextureSize = resourceProvider->maxTextureSize();
|
| - for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex) {
|
| + DCHECK(!m_emitFrameQuad);
|
| +
|
| + const int maxTextureSize = resourceProvider->maxTextureSize();
|
| + const size_t planeCount = numPlanes(*m_frame);
|
| + 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 +360,15 @@ bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider)
|
|
|
| bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider)
|
| {
|
| - size_t softwarePlaneCount = m_frame->planes();
|
| - if (!softwarePlaneCount)
|
| + DCHECK(!m_emitFrameQuad);
|
| +
|
| + const size_t planeCount = numPlanes(*m_frame);
|
| + 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));
|
| + 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 +377,16 @@ 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 = 0;
|
| + if (m_frame && !m_emitFrameQuad)
|
| + firstUnusedPlane = numPlanes(*m_frame);
|
| + for (size_t i = firstUnusedPlane; i < media::VideoFrame::kMaxPlanes; ++i)
|
| m_framePlanes[i].freeData(resourceProvider);
|
| }
|
|
|
|
|