IntSize CCVideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame, unsigned plane) { int visibleWidth = videoFrameDimension(frame.width(), plane, frame.format()); int originalWidth = visibleWidth; int visibleHeight = videoFrameDimension(frame.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 // interpolating with the dead pixels. if (hasPaddingBytes(frame, plane)) --visibleWidth; // In YV12, every 2x2 square of Y values corresponds to one U and // 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)) visibleWidth = originalWidth - 2; } return IntSize(visibleWidth, visibleHeight); }
// Convert WebKit::WebVideoFrame::Format to GraphicsContext3D's format enum values. static GC3Denum convertVFCFormatToGC3DFormat(const WebKit::WebVideoFrame& frame) { switch (frame.format()) { case WebKit::WebVideoFrame::FormatYV12: case WebKit::WebVideoFrame::FormatYV16: return GraphicsContext3D::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(); } return GraphicsContext3D::INVALID_VALUE; }
static bool hasPaddingBytes(const WebKit::WebVideoFrame& frame, unsigned plane) { return frame.stride(plane) > videoFrameDimension(frame.width(), plane, frame.format()); }
bool CCVideoLayerImpl::reserveTextures(const WebKit::WebVideoFrame& frame, GC3Denum format, LayerRendererChromium* layerRenderer) { if (frame.planes() > MaxPlanes) return false; int maxTextureSize = layerRenderer->capabilities().maxTextureSize; for (unsigned plane = 0; plane < frame.planes(); ++plane) { IntSize requiredTextureSize(frame.stride(plane), videoFrameDimension(frame.height(), plane, frame.format())); // If the renderer cannot handle this large of a texture, return false. // FIXME: Remove this test when tiled layers are implemented. if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTextureSize || requiredTextureSize.height() > maxTextureSize) return false; if (!m_textures[plane].m_texture) { m_textures[plane].m_texture = ManagedTexture::create(layerRenderer->renderSurfaceTextureManager()); if (!m_textures[plane].m_texture) return false; m_textures[plane].m_visibleSize = IntSize(); } else { // The renderSurfaceTextureManager may have been destroyed and recreated since the last frame, so pass the new one. // This is a no-op if the TextureManager is still around. m_textures[plane].m_texture->setTextureManager(layerRenderer->renderSurfaceTextureManager()); } if (m_textures[plane].m_texture->size() != requiredTextureSize) m_textures[plane].m_visibleSize = computeVisibleSize(frame, plane); if (!m_textures[plane].m_texture->reserve(requiredTextureSize, format)) return false; } return true; }