Slow loading Libsvm on android phone - android

I am trying to load a libsvm model on an android phone. The model is about 3MB, but it takes about 20s to load this model file which is not acceptable for a small App. I am using the libsvm official Java API to load it from my internal storage.
PS: I am trying to use libsvm c++ API to load this model via JNI too. but I meet the following problem:
JNIEXPORT void JNICALL Java_ca_uwo_csd_Threads_FoodRecgNativeLib_loadsvm
(JNIEnv *env, jclass cls, jstring path)
{
const char* path_char = env->GetStringUTFChars(path,0);//path is correct!
LOGI(TAG,"Loading start");
svm_model* model = svm_load_model(path_char); // fatal signal 11 here!!!
LOGI(TAG,"Loading OK");
}
If I comment the load model line, everything goes well. Can anyone help?

I solved it myself. Calling C++ loading function svm_load_model() via JNI is much faster than Java version(444ms in my case). The fatal signal 11 error happens at
char *old_locale = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "C");
and any other places that call the parameter and function in svm.cpp file (like free the points to it). So comment these and loading file will work.
Can anyone explain why this happens?

Related

How to get device model as appears in 'Google Play Developer Console'?

I am a developer and trying to block a specific model of the Samsung Galaxy Note4 in Google Play Developer Console, problem is I can't find a correlation between the device model to what they write in the console.
For example, I want to know what SM-N910C translates to from the below list I took from the console:
Any ideas how to do that? Manually or programmatically...
I don't think it's part of the http://developer.android.com/reference/android/os/Build.html
So this is undoubtedly too late for you, but I have recently had the same question, so I decided to look into it, and I've developed a working theory.
I believe that the two strings that appear in the Google Play Developer Console are Android system properties. The more user-friendly one is "ro.product.model" and the other is "ro.product.device". This mapping appears to work, at least with the devices I have available right now. If anyone finds that these two values do not match what Google provides, please comment to that effect!
Programmatically reading Android system properties requires a JNI call into native code, like so:
package com.example;
class Native {
// pass a String[2]
public static native void readModelAndDevice(String[] _results);
}
-
#include <jni.h>
#include <sys/system_properties.h>
char model[256], device[256];
extern "C" JNIEXPORT void JNICALL com_example_Native_readModelAndDevice
(
JNIEnv * _java, jclass _class, jobjectArray _array
)
{
__system_property_get("ro.product.model", model);
__system_property_get("ro.product.device", device);
jstring jmodel = _java->NewStringUTF(model);
jstring jdevice = _java->NewStringUTF(device);
_java->SetObjectArrayElement(_array, 0, jmodel);
_java->SetObjectArrayElement(_array, 1, jdevice);
return;
}
Anyone who has never done JNI in Android Studio before should complete a JNI tutorial before trying this example.

Calling Android debug method from C++

I have spent a ridiculous amount of time trying to figure this out and I am at an absolute loss.
I am working with the JUCE library and have modified one of their sample projects. My goal is to have a very simple Android app that is written in C++ and then ported to Android. I need a function in C++ that I can call that will then call a function on the Android side that will return my heap size and other characteristics to my C++ code so that I can manage memory there.
If anyone has a simple solution that would be amazing. Right now my current snag is this:
char const buf[] = "From JNI";
jstring jstr = env->NewStringUTF(buf);
jclass clazz = env->FindClass("android/os/Debug");
But I keep getting an error saying that 'NewStringUTF' is not a _JNIEnv member... but if I right click on the method and jump to the definition, I see it in my jni.h file... any suggestions? I'm working in Xcode by the way...
Is it plain C, not C++? Perhaps your file has a .c extension.
If it's plain C it should be
JNIEnv* env;
JNI_CreateJavaVM(&jvm, (void **)&env, &args);
(*env)->NewStringUTF(env, buf);

Remove the instance of native library from app using dlclose(Android NDK)

I have compiled FFmpeg library using NDK and use it to trim videos and get thumbnails from a video in my app, so basically I have ffmpeg.so and video-trimmer.so libraries up and running.
The problem however is strange, the trim or getThumbnail operations are successful but just one time i.e. the first time and the operations fail the second time. However it is successful the third time, I googled it and got two similar posts on SO related to my problem
POST 1:
POST 2:
Interestingly they suggest the same solution and I am unable to solve the issue being a naive in C programming language.
Here is what I have done
void Java_com_example_demo_natives_LibraryLoader_loadTrimmerLibrary(JNIEnv* env, jclass class, jstring libffmpeg_path, jstring inputFile, jstring outFile,
jstring startTime, jstring length)
{
const char* path;
void* handle;
int *(*Java_com_example_demo_natives_VideoTrimmer_trim)(JNIEnv *, jclass, jstring, jstring, jstring, jstring);
path = (*env)->GetStringUTFChars(env, libffmpeg_path, 0);
handle = dlopen(path, RTLD_LAZY);
Java_com_example_demo_natives_VideoTrimmer_trim = dlsym(handle, "Java_com_example_demo_natives_VideoTrimmer_trim");
(*Java_com_example_demo_natives_VideoTrimmer_trim)(env, class, inputFile, outFile, startTime, length);
(*env)->ReleaseStringUTFChars(env, libffmpeg_path, path);
dlclose(handle);
}
Despite of calling dlclose the library instance still exists in memory, what I am doing wrong here?
I come to know that library instance still exists because when I load the libraries again in some other activity the error message says library already exists in CL.
I want to get rid of the instance of that library from memory, please help...
try moving the position of the 'ReleaseString...'
it should be after the 'dlopen'
it should be before the call into the other shared lib...
(*env)->GetStringUTFChars
dlopen
(*env)->ReleaseStringUTFChars
make the main call
dlclose

Freeing Local References in android JNI

In the jni layer of the android code that I have written, am returning an array from the jni layer to the java layer. I am using DeleteLocalRef() to free the local reference before passing the result. i just wanted to make sure that the code i have written is proper. Please find the code below.Any help is appreciated.
extern "C"
{
JNIEXPORT jbyteArray JNICALL Java_com_jni_btRead(JNIEnv* env, jobject)
{
unsigned char* reply = btRead();
jbyteArray jba;
if(reply)
{
jba = env->NewByteArray(2048);
env->SetByteArrayRegion(jba, 0, 2048, reinterpret_cast<jbyte*>(reply));
}
else
{
jba = env->NewByteArray(0);
}
env->DeleteLocalRef(jba);
return jba;
}
}
Local variables are always created in stack segment and hence destroyed after returning from function. This diagram may help.
A quote from here:
A local reference is valid only within the dynamic context of the
native method that creates it, and only within that one invocation of
the native method. All local references created during the execution
of a native method will be freed once the native method returns.
So you may not free your local reference as it gets freed automatically.

Using OpenCV Android porting

I want to use the OpenCV Android porting, that you can find HERE, to make some image transformations for an Augmented Reality application. I've found no problem configuring and building the library, I receive no error and I succed put it within my Android application throght JNI process: the library libopencv.so is in the correct directory "\libs\armeabi\" under my project's directory.
And now the problems:
1) First I want to understand what version of the original openCV library this porting derive from. Is important for me know if it derive from version 1.5, 2.0 or 2.1 because same functions are very different and others are absent.
2) Before starting with real time video manipulation, I'd try make some simple operations on a single image or saved video:
JNIEXPORT
jstring
JNICALL
Java_org_examples_testOpenCV_OpenCV_LoadImage(JNIEnv* env, jobject thiz)
{
IplImage* imgIn = cvLoadImage("/sdcard/testimage.jpg", -1);
if (!imgIn) return env->NewStringUTF("Error");
cvReleaseImage( &imgIn );
return env->NewStringUTF("Ok");
}
JNIEXPORT
jstring
JNICALL
Java_balmas_examples_testOpenCV_OpenCV_manageVideo(JNIEnv* env, jobject thiz)
{
CvCapture* capture = cvCaptureFromFile("/sdcard/video_galaxyspica_352x288_15fps.3gp");
if (!capture) return env->NewStringUTF("Error");
return env->NewStringUTF("Ok");
}
In both cases I receive "Error". There are no problems with files on the sdcard becouse I try to make this:
FILE* file = fopen("/sdcard/video_galaxyspica_352x288_15fps.3gp","w+");
//FILE* file = fopen("/sdcard/testimage.jpg","w+");
if (!file) return env->NewStringUTF("Error");
else {
fflush(file);
fclose(file);
return env->NewStringUTF("OK");
}
and I receive "OK".
I realize that there is some problem within highgui library but I don't understand what and wath I should make to avoid the problem.
Some suggestions!!!
Thank you everyone
guys- you may want to try this link, it ports the C++ 'modern' interface to opencv. The IplImage stuff is deprecated, but new versions leave wrappers if you need to support legacy code.
http://code.google.com/p/android-opencv/
There's a sample camera-calibration app, you click snap a few times and it will solve for the K matrix.
Note: you'll need the crystax ndk for STL classes, http://www.crystax.net/android/ndk-r4.php

Categories

Resources