Merge change 9510
* changes: Untangle MediaPlayer, MediaRecorder, MediaScanner and MediaMetadataRetriever JNI code, so that creating one of those doesn't initialize all the others. Shaves a hundred milliseconds or so off music app startup time.
This commit is contained in:
@@ -35,6 +35,7 @@ public class MediaMetadataRetriever
|
||||
{
|
||||
static {
|
||||
System.loadLibrary("media_jni");
|
||||
native_init();
|
||||
}
|
||||
|
||||
// The field below is accessed by native methods
|
||||
@@ -211,7 +212,8 @@ public class MediaMetadataRetriever
|
||||
* allocated internally.
|
||||
*/
|
||||
public native void release();
|
||||
private native void native_setup();
|
||||
private native void native_setup();
|
||||
private static native void native_init();
|
||||
|
||||
private native final void native_finalize();
|
||||
|
||||
|
||||
@@ -466,6 +466,7 @@ public class MediaPlayer
|
||||
|
||||
static {
|
||||
System.loadLibrary("media_jni");
|
||||
native_init();
|
||||
}
|
||||
|
||||
private final static String TAG = "MediaPlayer";
|
||||
@@ -1109,6 +1110,7 @@ public class MediaPlayer
|
||||
*/
|
||||
private native final int native_setMetadataFilter(Parcel request);
|
||||
|
||||
private static native final void native_init();
|
||||
private native final void native_setup(Object mediaplayer_this);
|
||||
private native final void native_finalize();
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ public class MediaRecorder
|
||||
{
|
||||
static {
|
||||
System.loadLibrary("media_jni");
|
||||
native_init();
|
||||
}
|
||||
private final static String TAG = "MediaRecorder";
|
||||
|
||||
@@ -655,6 +656,8 @@ public class MediaRecorder
|
||||
*/
|
||||
public native void release();
|
||||
|
||||
private static native final void native_init();
|
||||
|
||||
private native final void native_setup(Object mediarecorder_this) throws IllegalStateException;
|
||||
|
||||
private native final void native_finalize();
|
||||
|
||||
@@ -99,6 +99,7 @@ public class MediaScanner
|
||||
{
|
||||
static {
|
||||
System.loadLibrary("media_jni");
|
||||
native_init();
|
||||
}
|
||||
|
||||
private final static String TAG = "MediaScanner";
|
||||
@@ -1404,6 +1405,7 @@ public class MediaScanner
|
||||
|
||||
public native byte[] extractAlbumArt(FileDescriptor fd);
|
||||
|
||||
private static native final void native_init();
|
||||
private native final void native_setup();
|
||||
private native final void native_finalize();
|
||||
@Override
|
||||
|
||||
@@ -169,13 +169,6 @@ static JNINativeMethod gMethods[] = {
|
||||
int register_android_media_AmrInputStream(JNIEnv *env)
|
||||
{
|
||||
const char* const kClassPathName = "android/media/AmrInputStream";
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass(kClassPathName);
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find %s", kClassPathName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
kClassPathName, gMethods, NELEM(gMethods));
|
||||
|
||||
@@ -40,6 +40,7 @@ struct fields_t {
|
||||
|
||||
static fields_t fields;
|
||||
static Mutex sLock;
|
||||
static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
|
||||
|
||||
static void process_media_retriever_call(JNIEnv *env, status_t opStatus, const char* exception, const char *message)
|
||||
{
|
||||
@@ -269,6 +270,36 @@ static void android_media_MediaMetadataRetriever_native_finalize(JNIEnv *env, jo
|
||||
android_media_MediaMetadataRetriever_release(env, thiz);
|
||||
}
|
||||
|
||||
// This function gets a field ID, which in turn causes class initialization.
|
||||
// It is called from a static block in MediaMetadataRetriever, which won't run until the
|
||||
// first time an instance of this class is used.
|
||||
static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env)
|
||||
{
|
||||
jclass clazz = env->FindClass(kClassPathName);
|
||||
if (clazz == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaMetadataRetriever");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaMetadataRetriever.mNativeContext");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
|
||||
if (fields.bitmapClazz == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
|
||||
if (fields.bitmapConstructor == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
LOGV("native_setup");
|
||||
@@ -292,36 +323,13 @@ static JNINativeMethod nativeMethods[] = {
|
||||
{"release", "()V", (void *)android_media_MediaMetadataRetriever_release},
|
||||
{"native_finalize", "()V", (void *)android_media_MediaMetadataRetriever_native_finalize},
|
||||
{"native_setup", "()V", (void *)android_media_MediaMetadataRetriever_native_setup},
|
||||
{"native_init", "()V", (void *)android_media_MediaMetadataRetriever_native_init},
|
||||
};
|
||||
|
||||
// Register native mehtods with Android runtime environment
|
||||
// This function only registers the native methods, and is called from
|
||||
// JNI_OnLoad in android_media_MediaPlayer.cpp
|
||||
int register_android_media_MediaMetadataRetriever(JNIEnv *env)
|
||||
{
|
||||
static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
|
||||
jclass clazz = env->FindClass(kClassPathName);
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find class: %s", kClassPathName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
LOGE("Can't find MediaMetadataRetriever.mNativeContext");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
|
||||
if (fields.bitmapClazz == NULL) {
|
||||
LOGE("Bitmap class is not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
|
||||
if (fields.bitmapConstructor == NULL) {
|
||||
LOGE("Bitmap constructor is not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods
|
||||
(env, kClassPathName, nativeMethods, NELEM(nativeMethods));
|
||||
(env, kClassPathName, nativeMethods, NELEM(nativeMethods));
|
||||
}
|
||||
|
||||
@@ -511,6 +511,51 @@ android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update
|
||||
return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
|
||||
}
|
||||
|
||||
// This function gets some field IDs, which in turn causes class initialization.
|
||||
// It is called from a static block in MediaPlayer, which won't run until the
|
||||
// first time an instance of this class is used.
|
||||
static void
|
||||
android_media_MediaPlayer_native_init(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/media/MediaPlayer");
|
||||
if (clazz == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaPlayer");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mNativeContext");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
|
||||
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
|
||||
if (fields.post_event == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.postEventFromNative");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
|
||||
if (fields.surface == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mSurface");
|
||||
return;
|
||||
}
|
||||
|
||||
jclass surface = env->FindClass("android/view/Surface");
|
||||
if (surface == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
|
||||
if (fields.surface_native == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
|
||||
@@ -576,53 +621,16 @@ static JNINativeMethod gMethods[] = {
|
||||
{"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
|
||||
{"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
|
||||
{"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
|
||||
{"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
|
||||
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
|
||||
};
|
||||
|
||||
static const char* const kClassPathName = "android/media/MediaPlayer";
|
||||
|
||||
// This function only registers the native methods
|
||||
static int register_android_media_MediaPlayer(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/media/MediaPlayer");
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find android/media/MediaPlayer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
LOGE("Can't find MediaPlayer.mNativeContext");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
|
||||
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
|
||||
if (fields.post_event == NULL) {
|
||||
LOGE("Can't find MediaPlayer.postEventFromNative");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
|
||||
if (fields.surface == NULL) {
|
||||
LOGE("Can't find MediaPlayer.mSurface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jclass surface = env->FindClass("android/view/Surface");
|
||||
if (surface == NULL) {
|
||||
LOGE("Can't find android/view/Surface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
|
||||
if (fields.surface_native == NULL) {
|
||||
LOGE("Can't find Surface fields");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
"android/media/MediaPlayer", gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
@@ -371,6 +371,53 @@ android_media_MediaRecorder_release(JNIEnv *env, jobject thiz)
|
||||
}
|
||||
}
|
||||
|
||||
// This function gets some field IDs, which in turn causes class initialization.
|
||||
// It is called from a static block in MediaRecorder, which won't run until the
|
||||
// first time an instance of this class is used.
|
||||
static void
|
||||
android_media_MediaRecorder_native_init(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/media/MediaRecorder");
|
||||
if (clazz == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaRecorder");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mNativeContext");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
|
||||
if (fields.surface == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mSurface");
|
||||
return;
|
||||
}
|
||||
|
||||
jclass surface = env->FindClass("android/view/Surface");
|
||||
if (surface == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
|
||||
if (fields.surface_native == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
|
||||
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
|
||||
if (fields.post_event == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "MediaRecorder.postEventFromNative");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
|
||||
{
|
||||
@@ -418,55 +465,19 @@ static JNINativeMethod gMethods[] = {
|
||||
{"getMaxAmplitude", "()I", (void *)android_media_MediaRecorder_native_getMaxAmplitude},
|
||||
{"start", "()V", (void *)android_media_MediaRecorder_start},
|
||||
{"stop", "()V", (void *)android_media_MediaRecorder_stop},
|
||||
{"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
|
||||
{"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
|
||||
{"release", "()V", (void *)android_media_MediaRecorder_release},
|
||||
{"native_init", "()V", (void *)android_media_MediaRecorder_native_init},
|
||||
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaRecorder_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
|
||||
};
|
||||
|
||||
static const char* const kClassPathName = "android/media/MediaRecorder";
|
||||
|
||||
// This function only registers the native methods, and is called from
|
||||
// JNI_OnLoad in android_media_MediaPlayer.cpp
|
||||
int register_android_media_MediaRecorder(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/media/MediaRecorder");
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find android/media/MediaRecorder");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
LOGE("Can't find MediaRecorder.mNativeContext");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
|
||||
if (fields.surface == NULL) {
|
||||
LOGE("Can't find MediaRecorder.mSurface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jclass surface = env->FindClass("android/view/Surface");
|
||||
if (surface == NULL) {
|
||||
LOGE("Can't find android/view/Surface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
|
||||
if (fields.surface_native == NULL) {
|
||||
LOGE("Can't find Surface fields");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
|
||||
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
|
||||
if (fields.post_event == NULL) {
|
||||
LOGE("Can't find MediaRecorder.postEventFromNative");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
"android/media/MediaRecorder", gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
@@ -241,6 +241,27 @@ done:
|
||||
return array;
|
||||
}
|
||||
|
||||
// This function gets a field ID, which in turn causes class initialization.
|
||||
// It is called from a static block in MediaScanner, which won't run until the
|
||||
// first time an instance of this class is used.
|
||||
static void
|
||||
android_media_MediaScanner_native_init(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/media/MediaScanner");
|
||||
if (clazz == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaScanner");
|
||||
return;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaScanner.mNativeContext");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
@@ -275,28 +296,17 @@ static JNINativeMethod gMethods[] = {
|
||||
(void *)android_media_MediaScanner_processFile},
|
||||
{"setLocale", "(Ljava/lang/String;)V", (void *)android_media_MediaScanner_setLocale},
|
||||
{"extractAlbumArt", "(Ljava/io/FileDescriptor;)[B", (void *)android_media_MediaScanner_extractAlbumArt},
|
||||
{"native_init", "()V", (void *)android_media_MediaScanner_native_init},
|
||||
{"native_setup", "()V", (void *)android_media_MediaScanner_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_MediaScanner_native_finalize},
|
||||
};
|
||||
|
||||
static const char* const kClassPathName = "android/media/MediaScanner";
|
||||
|
||||
// This function only registers the native methods, and is called from
|
||||
// JNI_OnLoad in android_media_MediaPlayer.cpp
|
||||
int register_android_media_MediaScanner(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/media/MediaScanner");
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find android/media/MediaScanner");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
|
||||
if (fields.context == NULL) {
|
||||
LOGE("Can't find MediaScanner.mNativeContext");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
"android/media/MediaScanner", gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
@@ -128,13 +128,6 @@ static JNINativeMethod gMethods[] = {
|
||||
int register_android_media_ResampleInputStream(JNIEnv *env)
|
||||
{
|
||||
const char* const kClassPathName = "android/media/ResampleInputStream";
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass(kClassPathName);
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find %s", kClassPathName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
kClassPathName, gMethods, NELEM(gMethods));
|
||||
|
||||
Reference in New Issue
Block a user