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)
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;
#if USE(ACCELERATED_COMPOSITING)
#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
#include <jni.h>
#include <JNIUtility.h>
+#include "MediaTexture.h"
#include "WebCoreJni.h"
#ifdef DEBUG
class MediaListener : public android::SurfaceTexture::FrameAvailableListener {
public:
- MediaListener(jobject weakWebViewRef)
+ MediaListener(jobject weakWebViewRef,
+ const sp<android::SurfaceTexture>& surfaceTexture,
+ const sp<ANativeWindow>& nativeWindow)
: m_weakWebViewRef(weakWebViewRef)
, m_postInvalMethod(0)
, m_frameAvailable(false)
+ , m_surfaceTexture(surfaceTexture)
+ , m_nativeWindow(nativeWindow)
+ , m_framerateCallback(0)
{
if (!m_weakWebViewRef)
return;
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<android::SurfaceTexture> m_surfaceTexture;
+ sp<ANativeWindow> m_nativeWindow;
+ FramerateCallbackProc m_framerateCallback;
};
} // namespace WebCore
m_dimensions.setEmpty();
m_newWindowRequest = false;
m_newWindowReady = false;
- m_mediaListener = new MediaListener(m_weakWebViewRef);
}
MediaTexture::~MediaTexture()
m_surfaceTextureClient = new android::SurfaceTextureClient(m_surfaceTexture);
//setup callback
- m_mediaListener->resetFrameAvailable();
+ m_mediaListener = new MediaListener(m_weakWebViewRef,
+ m_surfaceTexture,
+ m_surfaceTextureClient);
m_surfaceTexture->setFrameAvailableListener(m_mediaListener);
m_newWindowRequest = false;
m_surfaceTexture->setFrameAvailableListener(0);
// clear the strong pointer references
+ m_mediaListener.clear();
m_surfaceTextureClient.clear();
m_surfaceTexture.clear();
}
m_dimensions = dimensions;
}
+void MediaTexture::setFramerateCallback(FramerateCallbackProc callback)
+{
+ android::Mutex::Autolock lock(m_mediaLock);
+ m_mediaListener->setFramerateCallback(callback);
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
namespace WebCore {
+typedef void (*FramerateCallbackProc)(ANativeWindow* window, int64_t timestamp);
+
class MediaListener;
class MediaTexture : public android::LightRefBase<MediaTexture> {
ANativeWindow* getNativeWindow();
void releaseNativeWindow();
void setDimensions(const SkRect& dimensions);
+ void setFramerateCallback(FramerateCallbackProc callback);
private:
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
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<ANPVideoInterfaceV1*>(value);
+ ASSIGN(i, setFramerateCallback);
+}
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