 Chromium Code Reviews
 Chromium Code Reviews Issue 12157002:
  Adding YUVA support for enabling Alpha Playback  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 12157002:
  Adding YUVA support for enabling Alpha Playback  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| Index: cc/gl_renderer.cc | 
| diff --git a/cc/gl_renderer.cc b/cc/gl_renderer.cc | 
| index b3bad726fbef27b43eb65f2414cddf9aa8695f15..a4db58f32864d000c3b1b963c2297f6b18898d98 100644 | 
| --- a/cc/gl_renderer.cc | 
| +++ b/cc/gl_renderer.cc | 
| @@ -62,6 +62,26 @@ bool needsIOSurfaceReadbackWorkaround() | 
| } // anonymous namespace | 
| +// These values are magic numbers that are used in the transformation from YUV to RGB color values. | 
| 
jzern
2013/02/13 19:56:14
these are actually ITU-R BT.601
 | 
| +// They are taken from the following webpage: http://www.fourcc.org/fccyvrgb.php | 
| +float yuv2RGB[9] = { | 
| 
jzern
2013/02/13 19:56:14
these should be moved into the anonymous namespace
 
vigneshv
2013/02/15 18:05:02
Done.
 | 
| + 1.164f, 1.164f, 1.164f, | 
| + 0.f, -.391f, 2.018f, | 
| + 1.596f, -.813f, 0.f, | 
| +}; | 
| + | 
| +// These values map to 16, 128, and 128 respectively, and are computed | 
| +// as a fraction over 256 (e.g. 16 / 256 = 0.0625). | 
| +// They are used in the YUV to RGBA conversion formula: | 
| +// Y - 16 : Gives 16 values of head and footroom for overshooting | 
| +// U - 128 : Turns unsigned U into signed U [-128,127] | 
| +// V - 128 : Turns unsigned V into signed V [-128,127] | 
| +float yuvAdjust[3] = { | 
| + -0.0625f, | 
| + -0.5f, | 
| + -0.5f, | 
| +}; | 
| + | 
| scoped_ptr<GLRenderer> GLRenderer::create(RendererClient* client, OutputSurface* outputSurface, ResourceProvider* resourceProvider) | 
| { | 
| scoped_ptr<GLRenderer> renderer(make_scoped_ptr(new GLRenderer(client, outputSurface, resourceProvider))); | 
| @@ -296,6 +316,9 @@ void GLRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad) | 
| case DrawQuad::YUV_VIDEO_CONTENT: | 
| drawYUVVideoQuad(frame, YUVVideoDrawQuad::MaterialCast(quad)); | 
| break; | 
| + case DrawQuad::YUVA_VIDEO_CONTENT: | 
| + drawYUVAVideoQuad(frame, YUVAVideoDrawQuad::MaterialCast(quad)); | 
| + break; | 
| } | 
| } | 
| @@ -917,26 +940,9 @@ void GLRenderer::drawYUVVideoQuad(const DrawingFrame& frame, const YUVVideoDrawQ | 
| GLC(context(), context()->uniform1i(program->fragmentShader().uTextureLocation(), 2)); | 
| GLC(context(), context()->uniform1i(program->fragmentShader().vTextureLocation(), 3)); | 
| - // These values are magic numbers that are used in the transformation from YUV to RGB color values. | 
| - // They are taken from the following webpage: http://www.fourcc.org/fccyvrgb.php | 
| - float yuv2RGB[9] = { | 
| - 1.164f, 1.164f, 1.164f, | 
| - 0.f, -.391f, 2.018f, | 
| - 1.596f, -.813f, 0.f, | 
| - }; | 
| + | 
| 
jzern
2013/02/13 19:56:14
drop this line
 
vigneshv
2013/02/15 18:05:02
Done.
 | 
| GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().yuvMatrixLocation(), 1, 0, yuv2RGB)); | 
| - // These values map to 16, 128, and 128 respectively, and are computed | 
| - // as a fraction over 256 (e.g. 16 / 256 = 0.0625). | 
| - // They are used in the YUV to RGBA conversion formula: | 
| - // Y - 16 : Gives 16 values of head and footroom for overshooting | 
| - // U - 128 : Turns unsigned U into signed U [-128,127] | 
| - // V - 128 : Turns unsigned V into signed V [-128,127] | 
| - float yuvAdjust[3] = { | 
| - -0.0625f, | 
| - -0.5f, | 
| - -0.5f, | 
| - }; | 
| GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocation(), 1, yuvAdjust)); | 
| setShaderOpacity(quad->opacity(), program->fragmentShader().alphaLocation()); | 
| @@ -946,6 +952,53 @@ void GLRenderer::drawYUVVideoQuad(const DrawingFrame& frame, const YUVVideoDrawQ | 
| GLC(context(), context()->activeTexture(GL_TEXTURE0)); | 
| } | 
| +void GLRenderer::drawYUVAVideoQuad(const DrawingFrame& frame, const YUVAVideoDrawQuad* quad) | 
| +{ | 
| + const VideoYUVAProgram* program = videoYUVAProgram(); | 
| + DCHECK(program && program->initialized()); | 
| + const VideoLayerImpl::FramePlane& yPlane = quad->y_plane; | 
| + const VideoLayerImpl::FramePlane& uPlane = quad->u_plane; | 
| + const VideoLayerImpl::FramePlane& vPlane = quad->v_plane; | 
| + const VideoLayerImpl::FramePlane& aPlane = quad->a_plane; | 
| + | 
| + ResourceProvider::ScopedReadLockGL yPlaneLock(m_resourceProvider, yPlane.resourceId); | 
| + ResourceProvider::ScopedReadLockGL uPlaneLock(m_resourceProvider, uPlane.resourceId); | 
| + ResourceProvider::ScopedReadLockGL vPlaneLock(m_resourceProvider, vPlane.resourceId); | 
| + ResourceProvider::ScopedReadLockGL aPlaneLock(m_resourceProvider, aPlane.resourceId); | 
| + GLC(context(), context()->activeTexture(GL_TEXTURE1)); | 
| + GLC(context(), context()->bindTexture(GL_TEXTURE_2D, yPlaneLock.textureId())); | 
| + GLC(context(), context()->activeTexture(GL_TEXTURE2)); | 
| + GLC(context(), context()->bindTexture(GL_TEXTURE_2D, uPlaneLock.textureId())); | 
| + GLC(context(), context()->activeTexture(GL_TEXTURE3)); | 
| + GLC(context(), context()->bindTexture(GL_TEXTURE_2D, vPlaneLock.textureId())); | 
| + GLC(context(), context()->activeTexture(GL_TEXTURE4)); | 
| + GLC(context(), context()->bindTexture(GL_TEXTURE_2D, aPlaneLock.textureId())); | 
| 
jamesr
2013/02/14 01:55:19
it looks like you could use some for loops here.
 | 
| + | 
| + GLC(context(), context()->useProgram(program->program())); | 
| + | 
| + // Arbitrarily take the y sizes because y and a dimensions are identical. | 
| + float yWidthScaleFactor = static_cast<float>(yPlane.size.width()) / yPlane.size.width(); | 
| + // Arbitrarily take the u sizes because u and v dimensions are identical. | 
| + float uvWidthScaleFactor = static_cast<float>(uPlane.size.width()) / uPlane.size.width(); | 
| + //GLC(context(), context()->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor)); | 
| 
jzern
2013/02/13 19:56:14
dead code
 
vigneshv
2013/02/15 18:05:02
Done.
 | 
| + //GLC(context(), context()->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor)); | 
| + GLC(context(), context()->uniform2f(program->vertexShader().texScaleLocation(), quad->tex_scale.width(), quad->tex_scale.height())); | 
| + GLC(context(), context()->uniform1i(program->fragmentShader().yTextureLocation(), 1)); | 
| + GLC(context(), context()->uniform1i(program->fragmentShader().uTextureLocation(), 2)); | 
| + GLC(context(), context()->uniform1i(program->fragmentShader().vTextureLocation(), 3)); | 
| + GLC(context(), context()->uniform1i(program->fragmentShader().aTextureLocation(), 4)); | 
| + GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().yuvMatrixLocation(), 1, 0, yuv2RGB)); | 
| + | 
| + GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocation(), 1, yuvAdjust)); | 
| + | 
| + setShaderOpacity(quad->opacity(), program->fragmentShader().alphaLocation()); | 
| + drawQuadGeometry(frame, quad->quadTransform(), quad->rect, program->vertexShader().matrixLocation()); | 
| + | 
| + // Reset active texture back to texture 0. | 
| + GLC(context(), context()->activeTexture(GL_TEXTURE0)); | 
| + | 
| +} | 
| + | 
| void GLRenderer::drawStreamVideoQuad(const DrawingFrame& frame, const StreamVideoDrawQuad* quad) | 
| { | 
| static float glMatrix[16]; | 
| @@ -1728,6 +1781,18 @@ const GLRenderer::VideoYUVProgram* GLRenderer::videoYUVProgram() | 
| return m_videoYUVProgram.get(); | 
| } | 
| +const GLRenderer::VideoYUVAProgram* GLRenderer::videoYUVAProgram() | 
| +{ | 
| + if (!m_videoYUVAProgram) | 
| + m_videoYUVAProgram = make_scoped_ptr(new VideoYUVAProgram(m_context)); | 
| + if (!m_videoYUVAProgram->initialized()) { | 
| + TRACE_EVENT0("cc", "GLRenderer::videoYUVAProgram::initialize"); | 
| + m_videoYUVAProgram->initialize(m_context, m_isUsingBindUniform); | 
| + } | 
| + return m_videoYUVAProgram.get(); | 
| +} | 
| + | 
| + | 
| const GLRenderer::VideoStreamTextureProgram* GLRenderer::videoStreamTextureProgram() | 
| { | 
| if (!m_videoStreamTextureProgram) | 
| @@ -1778,6 +1843,8 @@ void GLRenderer::cleanupSharedObjects() | 
| if (m_videoYUVProgram) | 
| m_videoYUVProgram->cleanup(m_context); | 
| + if (m_videoYUVAProgram) | 
| + m_videoYUVAProgram->cleanup(m_context); | 
| if (m_videoStreamTextureProgram) | 
| m_videoStreamTextureProgram->cleanup(m_context); |