From 86772c601f6ccc0e1d0e0eca429cc2a73c6c3207 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Thu, 8 Sep 2011 11:25:50 -0400 Subject: Add Plugin API for a video framerate callback. bug: 5239378 Change-Id: I5f7d33302d5a40f58ec12a3c0be63cb51d4ffc75 --- Source/WebCore/platform/graphics/android/MediaLayer.cpp | 7 +++++++ Source/WebCore/platform/graphics/android/MediaLayer.h | 1 + Source/WebCore/platform/graphics/android/MediaListener.h | 16 ++++++++++++++-- .../WebCore/platform/graphics/android/MediaTexture.cpp | 12 ++++++++++-- Source/WebCore/platform/graphics/android/MediaTexture.h | 3 +++ Source/WebKit/android/plugins/ANPVideoInterface.cpp | 16 ++++++++++++++++ Source/WebKit/android/plugins/ANPVideo_npapi.h | 15 +++++++++++++++ 7 files changed, 66 insertions(+), 4 deletions(-) (limited to 'Source') diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/MediaLayer.cpp index 5625bbe..85fb92f 100644 --- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp +++ b/Source/WebCore/platform/graphics/android/MediaLayer.cpp @@ -137,6 +137,13 @@ void MediaLayer::releaseNativeWindowForVideo(ANativeWindow* window) m_videoTexture->releaseNativeWindow(); } +void MediaLayer::setFramerateCallback(const ANativeWindow* window, FramerateCallbackProc callback) +{ + if (window != m_videoTexture->getNativeWindow()) + return; + m_videoTexture->setFramerateCallback(callback); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.h b/Source/WebCore/platform/graphics/android/MediaLayer.h index 6d08ed6..cd15d9e 100644 --- a/Source/WebCore/platform/graphics/android/MediaLayer.h +++ b/Source/WebCore/platform/graphics/android/MediaLayer.h @@ -53,6 +53,7 @@ public: ANativeWindow* acquireNativeWindowForVideo(); void setWindowDimensionsForVideo(const ANativeWindow* window, const SkRect& dimensions); void releaseNativeWindowForVideo(ANativeWindow* window); + void setFramerateCallback(const ANativeWindow* window, FramerateCallbackProc callback); private: bool m_isCopy; diff --git a/Source/WebCore/platform/graphics/android/MediaListener.h b/Source/WebCore/platform/graphics/android/MediaListener.h index 0a85574..5fcbbb2 100644 --- a/Source/WebCore/platform/graphics/android/MediaListener.h +++ b/Source/WebCore/platform/graphics/android/MediaListener.h @@ -20,8 +20,10 @@ #if USE(ACCELERATED_COMPOSITING) #include +#include #include #include +#include "MediaTexture.h" #include "WebCoreJni.h" #ifdef DEBUG @@ -44,10 +46,15 @@ namespace WebCore { class MediaListener : public android::SurfaceTexture::FrameAvailableListener { public: - MediaListener(jobject weakWebViewRef) + MediaListener(jobject weakWebViewRef, + const sp& surfaceTexture, + const sp& nativeWindow) : m_weakWebViewRef(weakWebViewRef) , m_postInvalMethod(0) , m_frameAvailable(false) + , m_surfaceTexture(surfaceTexture) + , m_nativeWindow(nativeWindow) + , m_framerateCallback(0) { if (!m_weakWebViewRef) return; @@ -75,15 +82,20 @@ public: if (!m_frameAvailable) { m_frameAvailable = true; } + if (m_framerateCallback) + m_framerateCallback(m_nativeWindow.get(), m_surfaceTexture->getTimestamp()); } - void resetFrameAvailable() { m_frameAvailable = false; } bool isFrameAvailable() { return m_frameAvailable; } + void setFramerateCallback(FramerateCallbackProc callback) { m_framerateCallback = callback; } private: jobject m_weakWebViewRef; jmethodID m_postInvalMethod; bool m_frameAvailable; + sp m_surfaceTexture; + sp m_nativeWindow; + FramerateCallbackProc m_framerateCallback; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.cpp b/Source/WebCore/platform/graphics/android/MediaTexture.cpp index eb143a4..0de7dfa 100644 --- a/Source/WebCore/platform/graphics/android/MediaTexture.cpp +++ b/Source/WebCore/platform/graphics/android/MediaTexture.cpp @@ -61,7 +61,6 @@ MediaTexture::MediaTexture(jobject webViewRef) : android::LightRefBaseresetFrameAvailable(); + m_mediaListener = new MediaListener(m_weakWebViewRef, + m_surfaceTexture, + m_surfaceTextureClient); m_surfaceTexture->setFrameAvailableListener(m_mediaListener); m_newWindowRequest = false; @@ -210,6 +211,7 @@ void MediaTexture::releaseNativeWindow() m_surfaceTexture->setFrameAvailableListener(0); // clear the strong pointer references + m_mediaListener.clear(); m_surfaceTextureClient.clear(); m_surfaceTexture.clear(); } @@ -220,6 +222,12 @@ void MediaTexture::setDimensions(const SkRect& dimensions) m_dimensions = dimensions; } +void MediaTexture::setFramerateCallback(FramerateCallbackProc callback) +{ + android::Mutex::Autolock lock(m_mediaLock); + m_mediaListener->setFramerateCallback(callback); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.h b/Source/WebCore/platform/graphics/android/MediaTexture.h index c617264..d5ecd7b 100644 --- a/Source/WebCore/platform/graphics/android/MediaTexture.h +++ b/Source/WebCore/platform/graphics/android/MediaTexture.h @@ -31,6 +31,8 @@ namespace android { namespace WebCore { +typedef void (*FramerateCallbackProc)(ANativeWindow* window, int64_t timestamp); + class MediaListener; class MediaTexture : public android::LightRefBase { @@ -47,6 +49,7 @@ public: ANativeWindow* getNativeWindow(); void releaseNativeWindow(); void setDimensions(const SkRect& dimensions); + void setFramerateCallback(FramerateCallbackProc callback); private: diff --git a/Source/WebKit/android/plugins/ANPVideoInterface.cpp b/Source/WebKit/android/plugins/ANPVideoInterface.cpp index 8eb9846..f39d0b1 100644 --- a/Source/WebKit/android/plugins/ANPVideoInterface.cpp +++ b/Source/WebKit/android/plugins/ANPVideoInterface.cpp @@ -70,6 +70,14 @@ static void anp_releaseNativeWindow(NPP instance, ANativeWindow* window) { mediaLayer->releaseNativeWindowForVideo(window); } +static void anp_setFramerateCallback(NPP instance, const ANativeWindow* window, ANPVideoFrameCallbackProc callback) { + WebCore::MediaLayer* mediaLayer = mediaLayerForInstance(instance); + if (!mediaLayer) + return; + + mediaLayer->setFramerateCallback(window, callback); +} + /////////////////////////////////////////////////////////////////////////////// #define ASSIGN(obj, name) (obj)->name = anp_##name @@ -81,3 +89,11 @@ void ANPVideoInterfaceV0_Init(ANPInterface* value) { ASSIGN(i, setWindowDimensions); ASSIGN(i, releaseNativeWindow); } + +void ANPVideoInterfaceV1_Init(ANPInterface* value) { + // initialize the functions from the previous interface + ANPVideoInterfaceV0_Init(value); + // add any new functions or override existing functions + ANPVideoInterfaceV1* i = reinterpret_cast(value); + ASSIGN(i, setFramerateCallback); +} diff --git a/Source/WebKit/android/plugins/ANPVideo_npapi.h b/Source/WebKit/android/plugins/ANPVideo_npapi.h index 3d234f2..02e8392 100644 --- a/Source/WebKit/android/plugins/ANPVideo_npapi.h +++ b/Source/WebKit/android/plugins/ANPVideo_npapi.h @@ -58,4 +58,19 @@ struct ANPVideoInterfaceV0 : ANPInterface { void (*releaseNativeWindow)(NPP instance, ANativeWindow* window); }; +/** Called to notify the plugin that a video frame has been composited by the + * browser for display. This will be called in a separate thread and as such + * you cannot call releaseNativeWindow from the callback. + * + * The timestamp is in nanoseconds, and is monotonically increasing. + */ +typedef void (*ANPVideoFrameCallbackProc)(ANativeWindow* window, int64_t timestamp); + +struct ANPVideoInterfaceV1 : ANPVideoInterfaceV0 { + /** Set a callback to be notified when an ANativeWindow is composited by + * the browser. + */ + void (*setFramerateCallback)(NPP instance, const ANativeWindow* window, ANPVideoFrameCallbackProc); +}; + #endif // ANPVideo_npapi_h -- cgit v1.1