mirror of
https://github.com/defold/extension-camera
synced 2025-06-27 10:27:45 +02:00
Merge pull request #9 from defold/mutex_scope
Smaller mutex scope + use new SDK android methods (Defold 1.2.188)
This commit is contained in:
commit
8832fc1588
@ -48,16 +48,25 @@ void Camera_QueueMessage(CameraMessage message)
|
|||||||
|
|
||||||
static void Camera_ProcessQueue()
|
static void Camera_ProcessQueue()
|
||||||
{
|
{
|
||||||
DM_MUTEX_SCOPED_LOCK(g_DefoldCamera.m_Mutex);
|
if (g_DefoldCamera.m_MessageQueue.Empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i != g_DefoldCamera.m_MessageQueue.Size(); ++i)
|
dmArray<CameraMessage> tmp;
|
||||||
|
{
|
||||||
|
DM_MUTEX_SCOPED_LOCK(g_DefoldCamera.m_Mutex);
|
||||||
|
tmp.Swap(g_DefoldCamera.m_MessageQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i != tmp.Size(); ++i)
|
||||||
{
|
{
|
||||||
lua_State* L = dmScript::GetCallbackLuaContext(g_DefoldCamera.m_Callback);
|
lua_State* L = dmScript::GetCallbackLuaContext(g_DefoldCamera.m_Callback);
|
||||||
if (!dmScript::SetupCallback(g_DefoldCamera.m_Callback))
|
if (!dmScript::SetupCallback(g_DefoldCamera.m_Callback))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CameraMessage message = g_DefoldCamera.m_MessageQueue[i];
|
CameraMessage message = tmp[i];
|
||||||
|
|
||||||
if (message == CAMERA_STARTED)
|
if (message == CAMERA_STARTED)
|
||||||
{
|
{
|
||||||
@ -80,7 +89,6 @@ static void Camera_ProcessQueue()
|
|||||||
}
|
}
|
||||||
dmScript::TeardownCallback(g_DefoldCamera.m_Callback);
|
dmScript::TeardownCallback(g_DefoldCamera.m_Callback);
|
||||||
}
|
}
|
||||||
g_DefoldCamera.m_MessageQueue.SetSize(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Camera_DestroyCallback()
|
static void Camera_DestroyCallback()
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#if defined(DM_PLATFORM_ANDROID)
|
#if defined(DM_PLATFORM_ANDROID)
|
||||||
|
|
||||||
#include "camera_private.h"
|
#include "camera_private.h"
|
||||||
|
#include <dmsdk/dlib/android.h>
|
||||||
|
|
||||||
static jclass g_CameraClass = 0;
|
static jclass g_CameraClass = 0;
|
||||||
static jobject g_CameraObject = 0;
|
static jobject g_CameraObject = 0;
|
||||||
@ -20,53 +21,20 @@ static CaptureQuality g_Quality;
|
|||||||
|
|
||||||
static dmBuffer::HBuffer* g_Buffer = 0;
|
static dmBuffer::HBuffer* g_Buffer = 0;
|
||||||
|
|
||||||
|
|
||||||
static JNIEnv* Attach()
|
|
||||||
{
|
|
||||||
JNIEnv* env;
|
|
||||||
JavaVM* vm = dmGraphics::GetNativeAndroidJavaVM();
|
|
||||||
vm->AttachCurrentThread(&env, NULL);
|
|
||||||
return env;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool Detach(JNIEnv* env)
|
|
||||||
{
|
|
||||||
bool exception = (bool) env->ExceptionCheck();
|
|
||||||
env->ExceptionClear();
|
|
||||||
JavaVM* vm = dmGraphics::GetNativeAndroidJavaVM();
|
|
||||||
vm->DetachCurrentThread();
|
|
||||||
return !exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jclass GetClass(JNIEnv* env, const char* classname)
|
|
||||||
{
|
|
||||||
jclass activity_class = env->FindClass("android/app/NativeActivity");
|
|
||||||
jmethodID get_class_loader = env->GetMethodID(activity_class,"getClassLoader", "()Ljava/lang/ClassLoader;");
|
|
||||||
jobject cls = env->CallObjectMethod(dmGraphics::GetNativeAndroidActivity(), get_class_loader);
|
|
||||||
jclass class_loader = env->FindClass("java/lang/ClassLoader");
|
|
||||||
jmethodID find_class = env->GetMethodID(class_loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
|
||||||
|
|
||||||
jstring str_class_name = env->NewStringUTF(classname);
|
|
||||||
jclass outcls = (jclass)env->CallObjectMethod(cls, find_class, str_class_name);
|
|
||||||
env->DeleteLocalRef(str_class_name);
|
|
||||||
return outcls;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_frameUpdate(JNIEnv * env, jobject jobj, jintArray data);
|
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_frameUpdate(JNIEnv * env, jobject jobj, jintArray data);
|
||||||
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_queueMessage(JNIEnv * env, jobject jobj, jint message);
|
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_queueMessage(JNIEnv * env, jobject jobj, jint message);
|
||||||
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_captureStarted(JNIEnv * env, jobject jobj, jint width, jint height);
|
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_captureStarted(JNIEnv * env, jobject jobj, jint width, jint height);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_frameUpdate(JNIEnv * env, jobject jobj, jintArray data)
|
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_frameUpdate(JNIEnv * env, jobject jobj, jintArray data)
|
||||||
{
|
{
|
||||||
if(!g_FrameLock)
|
if(!g_FrameLock)
|
||||||
{
|
{
|
||||||
env->GetIntArrayRegion(data, 0, g_Width * g_Height, g_Data);
|
env->GetIntArrayRegion(data, 0, g_Width * g_Height, g_Data);
|
||||||
g_FrameLock = true;
|
g_FrameLock = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_queueMessage(JNIEnv * env, jobject jobj, jint message)
|
JNIEXPORT void JNICALL Java_com_defold_android_camera_AndroidCamera_queueMessage(JNIEnv * env, jobject jobj, jint message)
|
||||||
@ -98,19 +66,15 @@ void CameraPlatform_GetCameraInfo(CameraInfo& outparams)
|
|||||||
|
|
||||||
int CameraPlatform_Initialize()
|
int CameraPlatform_Initialize()
|
||||||
{
|
{
|
||||||
JNIEnv* env = Attach();
|
dmAndroid::ThreadAttacher threadAttacher;
|
||||||
if(!env)
|
JNIEnv* env = threadAttacher.GetEnv();
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the AndroidCamera class
|
// get the AndroidCamera class
|
||||||
jclass tmp = GetClass(env, "com.defold.android.camera/AndroidCamera");
|
jclass tmp = dmAndroid::LoadClass(env, "com.defold.android.camera/AndroidCamera");
|
||||||
g_CameraClass = (jclass)env->NewGlobalRef(tmp);
|
g_CameraClass = (jclass)env->NewGlobalRef(tmp);
|
||||||
if(!g_CameraClass)
|
if(!g_CameraClass)
|
||||||
{
|
{
|
||||||
dmLogError("Could not find class 'com.defold.android.camera/AndroidCamera'.");
|
dmLogError("Could not find class 'com.defold.android.camera/AndroidCamera'.");
|
||||||
Detach(env);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +83,6 @@ int CameraPlatform_Initialize()
|
|||||||
if(!g_GetCameraMethodId)
|
if(!g_GetCameraMethodId)
|
||||||
{
|
{
|
||||||
dmLogError("Could not get static method 'getCamera'.");
|
dmLogError("Could not get static method 'getCamera'.");
|
||||||
Detach(env);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +91,6 @@ int CameraPlatform_Initialize()
|
|||||||
if(!g_CameraObject)
|
if(!g_CameraObject)
|
||||||
{
|
{
|
||||||
dmLogError("Could not create instance.");
|
dmLogError("Could not create instance.");
|
||||||
Detach(env);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,18 +99,15 @@ int CameraPlatform_Initialize()
|
|||||||
if(!g_StartPreviewMethodId)
|
if(!g_StartPreviewMethodId)
|
||||||
{
|
{
|
||||||
dmLogError("Could not get startPreview() method.");
|
dmLogError("Could not get startPreview() method.");
|
||||||
Detach(env);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
g_StopPreviewMethodId = env->GetMethodID(g_CameraClass, "stopPreview", "()V");
|
g_StopPreviewMethodId = env->GetMethodID(g_CameraClass, "stopPreview", "()V");
|
||||||
if(!g_StopPreviewMethodId)
|
if(!g_StopPreviewMethodId)
|
||||||
{
|
{
|
||||||
dmLogError("Could not get stopPreview() method.");
|
dmLogError("Could not get stopPreview() method.");
|
||||||
Detach(env);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Detach(env);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +123,9 @@ void CameraPlatform_StartCapture(dmBuffer::HBuffer* buffer, CameraType type, Cap
|
|||||||
g_Type = type;
|
g_Type = type;
|
||||||
g_Quality = quality;
|
g_Quality = quality;
|
||||||
|
|
||||||
JNIEnv* env = Attach();
|
dmAndroid::ThreadAttacher threadAttacher;
|
||||||
env->CallVoidMethod(g_CameraObject, g_StartPreviewMethodId);
|
JNIEnv* env = threadAttacher.GetEnv();
|
||||||
Detach(env);
|
env->CallVoidMethod(g_CameraObject, g_StartPreviewMethodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraPlatform_StopCapture()
|
void CameraPlatform_StopCapture()
|
||||||
@ -177,15 +136,15 @@ void CameraPlatform_StopCapture()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv* env = Attach();
|
dmAndroid::ThreadAttacher threadAttacher;
|
||||||
|
JNIEnv* env = threadAttacher.GetEnv();
|
||||||
env->CallVoidMethod(g_CameraObject, g_StopPreviewMethodId);
|
env->CallVoidMethod(g_CameraObject, g_StopPreviewMethodId);
|
||||||
Detach(env);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraPlatform_UpdateCapture()
|
void CameraPlatform_UpdateCapture()
|
||||||
{
|
{
|
||||||
if(g_FrameLock)
|
if(g_FrameLock)
|
||||||
{
|
{
|
||||||
int width = g_Width;
|
int width = g_Width;
|
||||||
int height = g_Height;
|
int height = g_Height;
|
||||||
int numChannels = 4;
|
int numChannels = 4;
|
||||||
@ -209,8 +168,8 @@ void CameraPlatform_UpdateCapture()
|
|||||||
out[index+2] = (argb>>16)&0xFF; // B
|
out[index+2] = (argb>>16)&0xFF; // B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_FrameLock = false;
|
g_FrameLock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DM_PLATFORM_ANDROID
|
#endif // DM_PLATFORM_ANDROID
|
||||||
|
Loading…
x
Reference in New Issue
Block a user