jni: add CJNISurfaceTextureOnFrameAvailableListener
authordavilla <davilla@4pi.com>
Thu, 26 Sep 2013 13:37:48 +0000 (09:37 -0400)
committerdavilla <davilla@4pi.com>
Wed, 2 Oct 2013 15:33:46 +0000 (11:33 -0400)
tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCOnFrameAvailableListener.java [new file with mode: 0644]
xbmc/android/activity/android_main.cpp
xbmc/android/jni/SurfaceTexture.cpp
xbmc/android/jni/SurfaceTexture.h

diff --git a/tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCOnFrameAvailableListener.java b/tools/android/packaging/xbmc/src/org/xbmc/xbmc/XBMCOnFrameAvailableListener.java
new file mode 100644 (file)
index 0000000..6d1732f
--- /dev/null
@@ -0,0 +1,20 @@
+package org.xbmc.xbmc;
+
+import android.graphics.SurfaceTexture;
+import android.graphics.SurfaceTexture.OnFrameAvailableListener;
+
+public class XBMCOnFrameAvailableListener implements OnFrameAvailableListener
+{
+  native void _onFrameAvailable(SurfaceTexture surfaceTexture);
+
+  private synchronized void signalNewFrame(SurfaceTexture surfaceTexture)
+  {
+    _onFrameAvailable(surfaceTexture);
+  }
+
+  @Override
+  public void onFrameAvailable(SurfaceTexture surfaceTexture)
+  {
+    signalNewFrame(surfaceTexture);
+  }
+}
index bc331bf..6ee97c2 100644 (file)
@@ -23,6 +23,7 @@
 #include <android_native_app_glue.h>
 #include "EventLoop.h"
 #include "XBMCApp.h"
+#include "android/jni/SurfaceTexture.h"
 
 // copied from new android_native_app_glue.c
 static void process_input(struct android_app* app, struct android_poll_source* source) {
@@ -81,18 +82,38 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
   if (vm->GetEnv(reinterpret_cast<void**>(&env), version) != JNI_OK)
     return -1;
 
-  jclass cMain = env->FindClass("org/xbmc/xbmc/XBMCBroadcastReceiver");
+  jclass cMain = env->FindClass("org/xbmc/xbmc/Main");
   if(cMain)
   {
-    JNINativeMethod mOnReceive =   { "_onReceive",     "(Landroid/content/Intent;)V", (void*)&CJNIBroadcastReceiver::_onReceive};
-    env->RegisterNatives(cMain, &mOnReceive, 1);
+    JNINativeMethod mOnNewIntent = {
+      "_onNewIntent",
+      "(Landroid/content/Intent;)V",
+      (void*)&CJNIContext::_onNewIntent
+    };
+    env->RegisterNatives(cMain, &mOnNewIntent, 1);
   }
 
-  jclass cBroadcastReceiver = env->FindClass("org/xbmc/xbmc/Main");
+  jclass cBroadcastReceiver = env->FindClass("org/xbmc/xbmc/XBMCBroadcastReceiver");
   if(cBroadcastReceiver)
   {
-    JNINativeMethod mOnNewIntent = { "_onNewIntent",   "(Landroid/content/Intent;)V", (void*)&CJNIContext::_onNewIntent};
-    env->RegisterNatives(cBroadcastReceiver, &mOnNewIntent, 1);
+    JNINativeMethod mOnReceive =  {
+      "_onReceive",
+      "(Landroid/content/Intent;)V",
+      (void*)&CJNIBroadcastReceiver::_onReceive
+    };
+    env->RegisterNatives(cBroadcastReceiver, &mOnReceive, 1);
   }
+
+  jclass cFrameAvailableListener = env->FindClass("org/xbmc/xbmc/XBMCOnFrameAvailableListener");
+  if(cFrameAvailableListener)
+  {
+    JNINativeMethod mOnFrameAvailable = {
+      "_onFrameAvailable",
+      "(Landroid/graphics/SurfaceTexture;)V",
+      (void*)&CJNISurfaceTextureOnFrameAvailableListener::_onFrameAvailable
+    };
+    env->RegisterNatives(cFrameAvailableListener, &mOnFrameAvailable, 1);
+  }
+
   return version;
 }
index 5ead3c7..63ca382 100644 (file)
  */
 
 #include "JNIBase.h"
+#include "Context.h"
+#include "ClassLoader.h"
 #include "SurfaceTexture.h"
 
 #include "jutils/jutils-details.hpp"
 
 using namespace jni;
 
+//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+CJNISurfaceTextureOnFrameAvailableListener* CJNISurfaceTextureOnFrameAvailableListener::m_listenerInstance(NULL);
+
+CJNISurfaceTextureOnFrameAvailableListener::CJNISurfaceTextureOnFrameAvailableListener()
+: CJNIBase("org/xbmc/xbmc/XBMCOnFrameAvailableListener")
+{
+  CJNIContext *appInstance = CJNIContext::GetAppInstance();
+  if (!appInstance)
+    return;
+
+  // Convert "the/class/name" to "the.class.name" as loadClass() expects it.
+  std::string dotClassName = GetClassName();
+  for (std::string::iterator it = dotClassName.begin(); it != dotClassName.end(); ++it)
+  {
+    if (*it == '/')
+      *it = '.';
+  }
+  m_object = new_object(appInstance->getClassLoader().loadClass(dotClassName));
+  m_object.setGlobal();
+
+  m_listenerInstance = this;
+}
+
+void CJNISurfaceTextureOnFrameAvailableListener::_onFrameAvailable(JNIEnv *env, jobject context, jobject surface)
+{
+  (void)env;
+  (void)context;
+  if (m_listenerInstance)
+  {
+    CJNISurfaceTexture jni_surface = jhobject(surface);
+    m_listenerInstance->OnFrameAvailable(jni_surface);
+  }
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 CJNISurfaceTexture::CJNISurfaceTexture(int texName) : CJNIBase("android/graphics/SurfaceTexture")
 {
   m_object = new_object(GetClassName(), "<init>", "(I)V", texName);
   m_object.setGlobal();
 }
 
-/*
-void setOnFrameAvailableListener(const CJNISurfaceTextureOnFrameAvailableListener &listener)
+void CJNISurfaceTexture::setOnFrameAvailableListener(const CJNISurfaceTextureOnFrameAvailableListener &listener)
 {
+  call_method<void>(m_object,
+    "setOnFrameAvailableListener",
+    "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", listener.get_raw());
 }
-*/
 
 void CJNISurfaceTexture::setDefaultBufferSize(int width, int height)
 {
index fcdd9b5..7ea3598 100644 (file)
 
 #include "JNIBase.h"
 
+class CJNISurfaceTexture;
+
+class CJNISurfaceTextureOnFrameAvailableListener : public CJNIBase
+{
+public:
+  CJNISurfaceTextureOnFrameAvailableListener(const jni::jhobject &object) : CJNIBase(object) {};
+  virtual ~CJNISurfaceTextureOnFrameAvailableListener() {};
+
+  static void _onFrameAvailable(JNIEnv *env, jobject context, jobject surface);
+
+protected:
+  CJNISurfaceTextureOnFrameAvailableListener();
+
+  virtual void OnFrameAvailable(CJNISurfaceTexture &surface)=0;
+
+private:
+  static CJNISurfaceTextureOnFrameAvailableListener *m_listenerInstance;
+};
+
 class CJNISurfaceTexture : public CJNIBase
 {
 public:
@@ -28,7 +47,7 @@ public:
   CJNISurfaceTexture(int texName);
   ~CJNISurfaceTexture() {};
 
-  //void    setOnFrameAvailableListener(const CJNISurfaceTextureOnFrameAvailableListener &listener)
+  void    setOnFrameAvailableListener(const CJNISurfaceTextureOnFrameAvailableListener &listener);
   void    setDefaultBufferSize(int width, int height);
   void    updateTexImage();
   void    detachFromGLContext();