Adding Dalvik Virtual Machine routines and macros

This commit is contained in:
Youness Alaoui 2012-10-17 19:42:59 -04:00 committed by Nicolas Dufresne
parent 347dbf123d
commit 21f60289db
3 changed files with 266 additions and 2 deletions

View file

@ -19,7 +19,8 @@ libgstandroidmedia_la_SOURCES = \
video/video.c \
video/gstvideodecoder.c \
video/gstvideoencoder.c \
video/gstvideoutils.c
video/gstvideoutils.c \
gst-dvm.c
noinst_HEADERS = \
gstamc.h \
@ -29,7 +30,8 @@ noinst_HEADERS = \
video/video.h \
video/gstvideodecoder.h \
video/gstvideoencoder.h \
video/gstvideoutils.h
video/gstvideoutils.h \
gst-dvm.h
if !HAVE_GST_0_10_37
libgstandroidmedia_la_SOURCES += $(VIDEO_BASE_CLASSES_C)

159
sys/androidcamera/gst-dvm.c Normal file
View file

@ -0,0 +1,159 @@
/*
* Copyright (C) 2012, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
* Copyright (C) 2012, Cisco Systems, Inc.
* Author: Youness Alaoui <youness.alaoui@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gst-dvm.h"
#include <pthread.h>
GST_DEBUG_CATEGORY (gst_dvm_debug);
#define GST_CAT_DEFAULT gst_dvm_debug
static GModule *java_module;
static jint (*get_created_java_vms) (JavaVM ** vmBuf, jsize bufLen,
jsize * nVMs);
static jint (*create_java_vm) (JavaVM ** p_vm, JNIEnv ** p_env, void *vm_args);
static JavaVM *java_vm = NULL;
static gboolean started_java_vm = FALSE;
static pthread_key_t current_jni_env;
static JNIEnv *
gst_dvm_attach_current_thread (void)
{
JNIEnv *env;
JavaVMAttachArgs args;
GST_DEBUG ("Attaching thread %p", g_thread_self ());
args.version = JNI_VERSION_1_6;
args.name = NULL;
args.group = NULL;
if ((*java_vm)->AttachCurrentThread (java_vm, &env, &args) < 0) {
GST_ERROR ("Failed to attach current thread");
return NULL;
}
return env;
}
static void
gst_dvm_detach_current_thread (void *env)
{
GST_DEBUG ("Detaching thread %p", g_thread_self ());
(*java_vm)->DetachCurrentThread (java_vm);
}
JNIEnv *
gst_dvm_get_env (void)
{
JNIEnv *env;
if ((env = pthread_getspecific (current_jni_env)) == NULL) {
env = gst_dvm_attach_current_thread ();
pthread_setspecific (current_jni_env, env);
}
return env;
}
gboolean
gst_dvm_init (void)
{
jsize n_vms;
GST_DEBUG_CATEGORY_INIT (gst_dvm_debug, "dvm", 0, "DVM");
pthread_key_create (&current_jni_env, gst_dvm_detach_current_thread);
java_module = g_module_open ("libdvm", G_MODULE_BIND_LOCAL);
if (!java_module)
goto load_failed;
if (!g_module_symbol (java_module, "JNI_CreateJavaVM",
(gpointer *) & create_java_vm))
goto symbol_error;
if (!g_module_symbol (java_module, "JNI_GetCreatedJavaVMs",
(gpointer *) & get_created_java_vms))
goto symbol_error;
n_vms = 0;
if (get_created_java_vms (&java_vm, 1, &n_vms) < 0)
goto get_created_failed;
if (n_vms > 0) {
GST_DEBUG ("Successfully got existing Java VM %p", java_vm);
} else {
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[4];
options[0].optionString = "-verbose:jni";
options[1].optionString = "-verbose:gc";
options[2].optionString = "-Xcheck:jni";
options[3].optionString = "-Xdebug";
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = 4;
vm_args.ignoreUnrecognized = JNI_TRUE;
if (create_java_vm (&java_vm, &env, &vm_args) < 0)
goto create_failed;
GST_DEBUG ("Successfully created Java VM %p", java_vm);
started_java_vm = TRUE;
}
return java_vm != NULL;
load_failed:
{
GST_ERROR ("Failed to load libdvm: %s", g_module_error ());
return FALSE;
}
symbol_error:
{
GST_ERROR ("Failed to locate required JNI symbols in libdvm: %s",
g_module_error ());
g_module_close (java_module);
java_module = NULL;
return FALSE;
}
get_created_failed:
{
GST_ERROR ("Failed to get already created VMs");
g_module_close (java_module);
java_module = NULL;
return FALSE;
}
create_failed:
{
GST_ERROR ("Failed to create a Java VM");
g_module_close (java_module);
java_module = NULL;
return FALSE;
}
}

103
sys/androidcamera/gst-dvm.h Normal file
View file

@ -0,0 +1,103 @@
/* Dalvik Virtual Machine helper functions
*
* Copyright (C) 2012, Collabora Ltd.
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
* Copyright (C) 2012, Cisco Systems, Inc.
* Author: Youness Alaoui <youness.alaoui@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __GST_DVM_H__
#define __GST_DVM_H__
#include <gst/gst.h>
#include <jni.h>
#define GST_DVM_GET_CLASS(k, name) { \
jclass tmp; \
\
tmp = (*env)->FindClass (env, name); \
if (!tmp) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get class %s", name); \
return FALSE; \
} \
\
k.klass = (*env)->NewGlobalRef (env, tmp); \
if (!k.klass) { \
(*env)->ExceptionClear (env); \
(*env)->DeleteLocalRef (env, tmp); \
GST_ERROR ("Failed to get %s class global reference", name); \
return FALSE; \
} \
(*env)->DeleteLocalRef (env, tmp); \
}
#define GST_DVM_GET_STATIC_METHOD(k, method, signature) \
k.method = (*env)->GetStaticMethodID (env, k.klass, #method, \
signature); \
if (!k.method) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get static method %s for %s", #method, #k); \
return FALSE; \
}
#define GST_DVM_GET_METHOD(k, method, signature) \
k.method = (*env)->GetMethodID (env, k.klass, #method, signature); \
if (!k.method) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get method %s for %s", #method, #k); \
return FALSE; \
}
#define GST_DVM_GET_CONSTRUCTOR(k, field, signature) \
k.field = (*env)->GetMethodID (env, k.klass, "<init>", signature); \
if (!k.field) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get constructor %s for %s", #field, #k); \
return FALSE; \
}
#define GST_DVM_GET_FIELD(k, field, signature) \
k.field = (*env)->GetFieldID (env, k.klass, #field, signature); \
if (!k.field) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get field %s for %s", #field, #k); \
return FALSE; \
}
#define GST_DVM_GET_CONSTANT(k, field, type, signature) { \
jfieldID id; \
\
id = (*env)->GetStaticFieldID (env, k.klass, #field, signature); \
if (!id) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get static field %s for %s", #field, #k); \
return FALSE; \
} \
k.field = (*env)->GetStatic##type##Field (env, k.klass, id); \
if ((*env)->ExceptionCheck (env)) { \
(*env)->ExceptionClear (env); \
GST_ERROR ("Failed to get " #type " constant %s", #field); \
return FALSE; \
} \
}
JNIEnv *gst_dvm_get_env (void);
gboolean gst_dvm_init (void);
#endif /* __GST_DVM_H__ */