From b90072147252e646f58b5c2013fdcd9d6e6367ef Mon Sep 17 00:00:00 2001 From: "fischman@webrtc.org" Date: Mon, 12 Nov 2012 16:39:25 +0000 Subject: [PATCH] Fix OpenGL rendering of WebRTCDemo by accounting for stride != width. BUG=998 Review URL: https://webrtc-codereview.appspot.com/936021 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3079 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../android/video_render_opengles20.cc | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/webrtc/modules/video_render/android/video_render_opengles20.cc b/webrtc/modules/video_render/android/video_render_opengles20.cc index 5bcf148c2..3f16030c4 100644 --- a/webrtc/modules/video_render/android/video_render_opengles20.cc +++ b/webrtc/modules/video_render/android/video_render_opengles20.cc @@ -383,33 +383,46 @@ void VideoRenderOpenGles20::SetupTextures(const I420VideoFrame& frameToRender) { _textureHeight = height; } +// Uploads a plane of pixel data, accounting for stride != width*bpp. +static void GlTexSubImage2D(GLsizei width, GLsizei height, int stride, + const uint8_t* plane) { + if (stride == width) { + // Yay! We can upload the entire plane in a single GL call. + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, + GL_UNSIGNED_BYTE, + static_cast(plane)); + } else { + // Boo! Since GLES2 doesn't have GL_UNPACK_ROW_LENGTH and Android doesn't + // have GL_EXT_unpack_subimage we have to upload a row at a time. Ick. + for (int row = 0; row < height; ++row) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, row, width, 1, GL_LUMINANCE, + GL_UNSIGNED_BYTE, + static_cast(plane + (row * stride))); + } + } +} + void VideoRenderOpenGles20::UpdateTextures(const I420VideoFrame& frameToRender) { const GLsizei width = frameToRender.width(); const GLsizei height = frameToRender.height(); - GLuint currentTextureId = _textureIds[0]; // Y - glActiveTexture( GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, currentTextureId); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, - GL_UNSIGNED_BYTE, - (const GLvoid*) frameToRender.buffer(kYPlane)); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _textureIds[0]); + GlTexSubImage2D(width, height, frameToRender.stride(kYPlane), + frameToRender.buffer(kYPlane)); - currentTextureId = _textureIds[1]; // U - glActiveTexture( GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, currentTextureId); - const WebRtc_UWord8* uComponent = frameToRender.buffer(kUPlane); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, - GL_LUMINANCE, GL_UNSIGNED_BYTE, (const GLvoid*) uComponent); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, _textureIds[1]); + GlTexSubImage2D(width / 2, height / 2, frameToRender.stride(kUPlane), + frameToRender.buffer(kUPlane)); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, _textureIds[2]); + GlTexSubImage2D(width / 2, height / 2, frameToRender.stride(kVPlane), + frameToRender.buffer(kVPlane)); - currentTextureId = _textureIds[2]; // V - glActiveTexture( GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, currentTextureId); - const WebRtc_UWord8* vComponent = frameToRender.buffer(kVPlane); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, - GL_LUMINANCE, GL_UNSIGNED_BYTE, (const GLvoid*) vComponent); checkGlError("UpdateTextures"); - } } // namespace webrtc