diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2012-01-17 16:34:51 -0800 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2012-01-18 14:24:18 -0800 |
commit | 17dd0d4d7d8ec66c8fb4acb5c580b38d9465d272 (patch) | |
tree | 0ab6108bd4cfa836e1196a4dabb03517a05e5792 /Source/WebCore/platform/graphics/android | |
parent | 95740c40dc0b78f1342ec0c257664b4300a07e6b (diff) | |
download | external_webkit-17dd0d4d7d8ec66c8fb4acb5c580b38d9465d272.zip external_webkit-17dd0d4d7d8ec66c8fb4acb5c580b38d9465d272.tar.gz external_webkit-17dd0d4d7d8ec66c8fb4acb5c580b38d9465d272.tar.bz2 |
Support aspect ratio for the inline video
Previously the aspect ratio is using the element attributes, now we honor the
aspect ratio reported by the video.
bug:5880615
Change-Id: I1ed29e9e8df3f9ec3d67c027838ce3edfa3aefd4
Diffstat (limited to 'Source/WebCore/platform/graphics/android')
4 files changed, 67 insertions, 18 deletions
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp index 58f47d0..a527e6a 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp @@ -180,6 +180,22 @@ void VideoLayerAndroid::showPreparingAnimation(const SkRect& rect, m_rotateDegree += ROTATESTEP; } +SkRect VideoLayerAndroid::calVideoRect(const SkRect& rect) +{ + SkRect videoRect = rect; + VideoLayerManager* manager = TilesManager::instance()->videoLayerManager(); + float aspectRatio = manager->getAspectRatio(uniqueId()); + float deltaY = rect.height() - rect.width() / aspectRatio; + if (deltaY >= 0) + videoRect.inset(0, deltaY / 2); + else { + float deltaX = rect.width() - rect.height() * aspectRatio; + if (deltaX >= 0) + videoRect.inset(deltaX / 2, 0); + } + return videoRect; +} + bool VideoLayerAndroid::drawGL() { // Lazily allocated the textures. @@ -193,17 +209,26 @@ bool VideoLayerAndroid::drawGL() m_createdTexture = true; } + ShaderProgram* shader = TilesManager::instance()->shader(); + SkRect rect = SkRect::MakeSize(getSize()); GLfloat surfaceMatrix[16]; - SkRect innerRect = SkRect(buttonRect); - if (innerRect.contains(rect)) - innerRect = rect; - - innerRect.offset((rect.width() - IMAGESIZE) / 2 , (rect.height() - IMAGESIZE) / 2); + // Calculate the video rect based on the aspect ratio and the element rect. + SkRect videoRect = calVideoRect(rect); + if (videoRect != rect) { + // Paint the whole video element with black color when video content + // can't cover the whole area. + shader->drawLayerQuad(m_drawTransform, rect, 0, 1, true, GL_TEXTURE_2D, + Color(0, 0, 0, 255)); + } - ShaderProgram* shader = TilesManager::instance()->shader(); - VideoLayerManager* manager = TilesManager::instance()->videoLayerManager(); + // Inner rect is for the progressing / play / pause animation. + SkRect innerRect = SkRect(buttonRect); + if (innerRect.contains(videoRect)) + innerRect = videoRect; + innerRect.offset(videoRect.fLeft + (videoRect.width() - IMAGESIZE) / 2, + videoRect.fTop + (videoRect.height() - IMAGESIZE) / 2); // When we are drawing the animation of the play/pause button in the // middle of the video, we need to ask for redraw. @@ -211,9 +236,10 @@ bool VideoLayerAndroid::drawGL() // Draw the poster image, the progressing image or the Video depending // on the player's state. + VideoLayerManager* manager = TilesManager::instance()->videoLayerManager(); if (m_playerState == PREPARING) { // Show the progressing animation, with two rotating circles - showPreparingAnimation(rect, innerRect); + showPreparingAnimation(videoRect, innerRect); needRedraw = true; } else if (m_playerState == PLAYING && m_surfaceTexture.get()) { // Show the real video. @@ -221,12 +247,12 @@ bool VideoLayerAndroid::drawGL() m_surfaceTexture->getTransformMatrix(surfaceMatrix); GLuint textureId = manager->getTextureId(uniqueId()); shader->drawVideoLayerQuad(m_drawTransform, surfaceMatrix, - rect, textureId); + videoRect, textureId); manager->updateMatrix(uniqueId(), surfaceMatrix); // Use the scale to control the fading the sizing during animation double scale = manager->drawIcon(uniqueId(), PlayIcon); - if (scale != 0) { + if (scale) { innerRect.inset(IMAGESIZE / 4 * scale, IMAGESIZE / 4 * scale); shader->drawLayerQuad(m_drawTransform, innerRect, m_playTextureId, scale, true); @@ -239,10 +265,10 @@ bool VideoLayerAndroid::drawGL() if (textureId && matrix) { // Show the screen shot for each video. shader->drawVideoLayerQuad(m_drawTransform, matrix, - rect, textureId); + videoRect, textureId); } else { // Show the static poster b/c there is no screen shot available. - shader->drawLayerQuad(m_drawTransform, rect, m_backgroundTextureId, + shader->drawLayerQuad(m_drawTransform, videoRect, m_backgroundTextureId, 1, true); shader->drawLayerQuad(m_drawTransform, innerRect, m_posterTextureId, 1, true); @@ -250,7 +276,7 @@ bool VideoLayerAndroid::drawGL() // Use the scale to control the fading and the sizing during animation. double scale = manager->drawIcon(uniqueId(), PauseIcon); - if (scale != 0) { + if (scale) { innerRect.inset(IMAGESIZE / 4 * scale, IMAGESIZE / 4 * scale); shader->drawLayerQuad(m_drawTransform, innerRect, m_pauseTextureId, scale, true); diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h index cdb37f3..6bd9fa1 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h @@ -71,6 +71,7 @@ private: void init(); void showPreparingAnimation(const SkRect& rect, const SkRect innerRect); + SkRect calVideoRect(const SkRect& rect); // Surface texture for showing the video is actually allocated in Java side // and passed into this native code. sp<android::SurfaceTexture> m_surfaceTexture; diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp index d0fc873..521b623 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp +++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "VideoLayerManager.h" + #include <wtf/CurrentTime.h> #if USE(ACCELERATED_COMPOSITING) @@ -54,6 +55,10 @@ // screenshots would not be above 8M. #define MAX_VIDEOSIZE_SUM 2097152 +// We don't preload the video data, so we don't have the exact size yet. +// Assuming 16:9 by default, this will be corrected after video prepared. +#define DEFAULT_VIDEO_ASPECT_RATIO 1.78 + namespace WebCore { VideoLayerManager::VideoLayerManager() @@ -71,6 +76,16 @@ GLuint VideoLayerManager::getTextureId(const int layerId) return result; } +// Getting the aspect ratio for GL draw call, in the UI thread. +float VideoLayerManager::getAspectRatio(const int layerId) +{ + android::Mutex::Autolock lock(m_videoLayerInfoMapLock); + float result = 0; + if (m_videoLayerInfoMap.contains(layerId)) + result = m_videoLayerInfoMap.get(layerId)->aspectRatio; + return result; +} + // Getting matrix for GL draw call, in the UI thread. GLfloat* VideoLayerManager::getMatrix(const int layerId) { @@ -108,6 +123,7 @@ void VideoLayerManager::registerTexture(const int layerId, const GLuint textureI pInfo->textureId = textureId; memset(pInfo->surfaceMatrix, 0, sizeof(pInfo->surfaceMatrix)); pInfo->videoSize = 0; + pInfo->aspectRatio = DEFAULT_VIDEO_ASPECT_RATIO; m_currentTimeStamp++; pInfo->timeStamp = m_currentTimeStamp; pInfo->lastIconShownTime = 0; @@ -122,13 +138,16 @@ void VideoLayerManager::registerTexture(const int layerId, const GLuint textureI // Only when the video is prepared, we got the video size. So we should update // the size for the video accordingly. // This is called from webcore thread, from MediaPlayerPrivateAndroid. -void VideoLayerManager::updateVideoLayerSize(const int layerId, const int size ) +void VideoLayerManager::updateVideoLayerSize(const int layerId, const int size, + const float ratio) { android::Mutex::Autolock lock(m_videoLayerInfoMapLock); if (m_videoLayerInfoMap.contains(layerId)) { VideoLayerInfo* pInfo = m_videoLayerInfoMap.get(layerId); - if (pInfo) + if (pInfo) { pInfo->videoSize = size; + pInfo->aspectRatio = ratio; + } } // If the memory usage is out of bound, then just delete the oldest ones. @@ -255,7 +274,7 @@ double VideoLayerManager::drawIcon(const int layerId, IconType type) VideoLayerInfo* pInfo = m_videoLayerInfoMap.get(layerId); // If this is state switching moment, reset the time and state if ((type == PlayIcon && pInfo->iconState != PlayIconShown) - ||(type == PauseIcon && pInfo->iconState != PauseIconShown)) { + || (type == PauseIcon && pInfo->iconState != PauseIconShown)) { pInfo->lastIconShownTime = WTF::currentTime(); pInfo->iconState = (type == PlayIcon) ? PlayIconShown : PauseIconShown; } @@ -269,7 +288,7 @@ double VideoLayerManager::drawIcon(const int layerId, IconType type) } } - if (ratio > 1 || ratio < 0 ) + if (ratio > 1 || ratio < 0) ratio = 0; return ratio; } diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/VideoLayerManager.h index a427269..d554362 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerManager.h +++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.h @@ -50,6 +50,7 @@ enum IconType { struct VideoLayerInfo { GLuint textureId; // GL texture bound with the surface texture. int videoSize; // The size of the video. + float aspectRatio; // The aspect ratio of the video. int timeStamp; // Used to decide which VideoLayerInfo is the oldest one. GLfloat surfaceMatrix[16]; @@ -68,7 +69,7 @@ public: // Register the texture when we got setSurfaceTexture call. void registerTexture(const int layerId, const GLuint textureId); // Update the size when the video is prepared. - void updateVideoLayerSize(const int layerId, const int size); + void updateVideoLayerSize(const int layerId, const int size, const float ratio); // At draw time, update the matrix for every video frame update. void updateMatrix(const int layerId, const GLfloat* matrix); // Remove the layer info from the mapping. @@ -78,6 +79,8 @@ public: GLuint getTextureId(const int layerId); // Return the matrix for surface texture corresponding to the layerId GLfloat* getMatrix(const int layerId); + // Return the aspect ratio for the video corresponding to the layerId + float getAspectRatio(const int layerId); // Delete the GL textures void deleteUnusedTextures(); |