diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
commit | b798689749c64baba81f02e10cf2157c747d6b46 (patch) | |
tree | da394a395ddb1a6cf69193314846b03fe47a397e /core/jni/android_media_JetPlayer.cpp | |
parent | f013e1afd1e68af5e3b868c26a653bbfb39538f8 (diff) | |
download | frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.zip frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.gz frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.bz2 |
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'core/jni/android_media_JetPlayer.cpp')
-rw-r--r-- | core/jni/android_media_JetPlayer.cpp | 485 |
1 files changed, 485 insertions, 0 deletions
diff --git a/core/jni/android_media_JetPlayer.cpp b/core/jni/android_media_JetPlayer.cpp new file mode 100644 index 0000000..994f161 --- /dev/null +++ b/core/jni/android_media_JetPlayer.cpp @@ -0,0 +1,485 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//FIXME: remove log before release +#define LOG_NDEBUG 0 +#define LOG_TAG "JET_JNI" + + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> + +#include "jni.h" +#include "JNIHelp.h" +#include "android_runtime/AndroidRuntime.h" + +#include "utils/Log.h" +#include "media/JetPlayer.h" + + +using namespace android; + +// ---------------------------------------------------------------------------- +static const char* const kClassPathName = "android/media/JetPlayer"; + +// ---------------------------------------------------------------------------- +struct fields_t { + // these fields provide access from C++ to the... + jclass jetClass; // JetPlayer java class global ref + jmethodID postNativeEventInJava; // java method to post events to the Java thread from native + jfieldID nativePlayerInJavaObj; // stores in Java the native JetPlayer object +}; + +static fields_t javaJetPlayerFields; + + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +/* + * This function is called from JetPlayer instance's render thread + */ +static void +jetPlayerEventCallback(int what, int arg1=0, int arg2=0, void* javaTarget = NULL) +{ + JNIEnv *env = AndroidRuntime::getJNIEnv(); + if(env) { + env->CallStaticVoidMethod( + javaJetPlayerFields.jetClass, javaJetPlayerFields.postNativeEventInJava, + javaTarget, + what, arg1, arg2); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + } else { + LOGE("JET jetPlayerEventCallback(): No JNI env for JET event callback, can't post event."); + return; + } +} + + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +static jboolean +android_media_JetPlayer_setup(JNIEnv *env, jobject thiz, jobject weak_this, + jint maxTracks, jint trackBufferSize) +{ + //LOGV("android_media_JetPlayer_setup(): entering."); + JetPlayer* lpJet = new JetPlayer(weak_this, maxTracks, trackBufferSize); + + EAS_RESULT result = lpJet->init(); + + if(result==EAS_SUCCESS) { + // save our newly created C++ JetPlayer in the "nativePlayerInJavaObj" field + // of the Java object (in mNativePlayerInJavaObj) + env->SetIntField(thiz, javaJetPlayerFields.nativePlayerInJavaObj, (int)lpJet); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_setup(): initialization failed with EAS error code %d", (int)result); + delete lpJet; + env->SetIntField(weak_this, javaJetPlayerFields.nativePlayerInJavaObj, 0); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static void +android_media_JetPlayer_finalize(JNIEnv *env, jobject thiz) +{ + LOGV("android_media_JetPlayer_finalize(): entering."); + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if(lpJet != NULL) { + lpJet->release(); + delete lpJet; + } + + LOGV("android_media_JetPlayer_finalize(): exiting."); +} + + +// ---------------------------------------------------------------------------- +static void +android_media_JetPlayer_release(JNIEnv *env, jobject thiz) +{ + android_media_JetPlayer_finalize(env, thiz); + env->SetIntField(thiz, javaJetPlayerFields.nativePlayerInJavaObj, 0); + LOGV("android_media_JetPlayer_release() done"); +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_openFile(JNIEnv *env, jobject thiz, jstring path) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + // set up event callback function + lpJet->setEventCallback(jetPlayerEventCallback); + + + const char *pathStr = env->GetStringUTFChars(path, NULL); + if (pathStr == NULL) { // Out of memory + LOGE("android_media_JetPlayer_openFile(): aborting, out of memory"); + jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); + return JNI_FALSE; + } + + LOGV("android_media_JetPlayer_openFile(): trying to open %s", pathStr ); + EAS_RESULT result = lpJet->openFile(pathStr); + env->ReleaseStringUTFChars(path, pathStr); + + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_openFile(): file successfully opened"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_openFile(): failed to open file with EAS error %d", + (int)result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_closeFile(JNIEnv *env, jobject thiz) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + if( lpJet->closeFile()==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_closeFile(): file successfully closed"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_closeFile(): failed to close file"); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_play(JNIEnv *env, jobject thiz) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result = lpJet->play(); + if( result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_play(): play successful"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_play(): failed to play with EAS error code %ld", + result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_pause(JNIEnv *env, jobject thiz) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result = lpJet->pause(); + if( result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_pause(): pause successful"); + return JNI_TRUE; + } else { + if(result==EAS_ERROR_QUEUE_IS_EMPTY) { + LOGV("android_media_JetPlayer_pause(): paused with an empty queue"); + return JNI_TRUE; + } else + LOGE("android_media_JetPlayer_pause(): failed to pause with EAS error code %ld", + result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_queueSegment(JNIEnv *env, jobject thiz, + jint segmentNum, jint libNum, jint repeatCount, jint transpose, jint muteFlags, + jbyte userID) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result + = lpJet->queueSegment(segmentNum, libNum, repeatCount, transpose, muteFlags, userID); + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_queueSegment(): segment successfully queued"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_queueSegment(): failed with EAS error code %ld", + result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_queueSegmentMuteArray(JNIEnv *env, jobject thiz, + jint segmentNum, jint libNum, jint repeatCount, jint transpose, jbooleanArray muteArray, + jbyte userID) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result=EAS_FAILURE; + + jboolean *muteTracks = NULL; + muteTracks = env->GetBooleanArrayElements(muteArray, NULL); + if (muteTracks == NULL) { + LOGE("android_media_JetPlayer_queueSegment(): failed to read track mute mask."); + return JNI_FALSE; + } + + EAS_U32 muteMask=0; + int maxTracks = lpJet->getMaxTracks(); + for (jint trackIndex=0; trackIndex<maxTracks; trackIndex++) { + if(muteTracks[maxTracks-1-trackIndex]==JNI_TRUE) + muteMask = (muteMask << 1) | 0x00000001; + else + muteMask = muteMask << 1; + } + //LOGV("android_media_JetPlayer_queueSegmentMuteArray(): FINAL mute mask =0x%08lX", mask); + + result = lpJet->queueSegment(segmentNum, libNum, repeatCount, transpose, muteMask, userID); + + env->ReleaseBooleanArrayElements(muteArray, muteTracks, 0); + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_queueSegmentMuteArray(): segment successfully queued"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_queueSegmentMuteArray(): failed with EAS error code %ld", + result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_setMuteFlags(JNIEnv *env, jobject thiz, + jint muteFlags /*unsigned?*/, jboolean bSync) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result; + result = lpJet->setMuteFlags(muteFlags, bSync==JNI_TRUE ? true : false); + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_setMuteFlags(): mute flags successfully updated"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_setMuteFlags(): failed with EAS error code %ld", result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_setMuteArray(JNIEnv *env, jobject thiz, + jbooleanArray muteArray, jboolean bSync) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result=EAS_FAILURE; + + jboolean *muteTracks = NULL; + muteTracks = env->GetBooleanArrayElements(muteArray, NULL); + if (muteTracks == NULL) { + LOGE("android_media_JetPlayer_setMuteArray(): failed to read track mute mask."); + return JNI_FALSE; + } + + EAS_U32 muteMask=0; + int maxTracks = lpJet->getMaxTracks(); + for (jint trackIndex=0; trackIndex<maxTracks; trackIndex++) { + if(muteTracks[maxTracks-1-trackIndex]==JNI_TRUE) + muteMask = (muteMask << 1) | 0x00000001; + else + muteMask = muteMask << 1; + } + //LOGV("android_media_JetPlayer_setMuteArray(): FINAL mute mask =0x%08lX", muteMask); + + result = lpJet->setMuteFlags(muteMask, bSync==JNI_TRUE ? true : false); + + env->ReleaseBooleanArrayElements(muteArray, muteTracks, 0); + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_setMuteArray(): mute flags successfully updated"); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_setMuteArray(): failed to update mute flags with EAS error code %ld", result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_setMuteFlag(JNIEnv *env, jobject thiz, + jint trackId, jboolean muteFlag, jboolean bSync) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result; + result = lpJet->setMuteFlag(trackId, + muteFlag==JNI_TRUE ? true : false, bSync==JNI_TRUE ? true : false); + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_setMuteFlag(): mute flag successfully updated for track %d", trackId); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_setMuteFlag(): failed to update mute flag for track %d with EAS error code %ld", + trackId, result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +static jboolean +android_media_JetPlayer_triggerClip(JNIEnv *env, jobject thiz, jint clipId) +{ + JetPlayer *lpJet = (JetPlayer *)env->GetIntField( + thiz, javaJetPlayerFields.nativePlayerInJavaObj); + if (lpJet == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", + "Unable to retrieve JetPlayer pointer for openFile()"); + } + + EAS_RESULT result; + result = lpJet->triggerClip(clipId); + if(result==EAS_SUCCESS) { + //LOGV("android_media_JetPlayer_triggerClip(): triggerClip successful for clip %d", clipId); + return JNI_TRUE; + } else { + LOGE("android_media_JetPlayer_triggerClip(): triggerClip for clip %d failed with EAS error code %ld", + clipId, result); + return JNI_FALSE; + } +} + + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +static JNINativeMethod gMethods[] = { + // name, signature, funcPtr + {"native_setup", "(Ljava/lang/Object;II)Z", (void *)android_media_JetPlayer_setup}, + {"native_finalize", "()V", (void *)android_media_JetPlayer_finalize}, + {"native_release", "()V", (void *)android_media_JetPlayer_release}, + {"native_openJetFile", "(Ljava/lang/String;)Z", (void *)android_media_JetPlayer_openFile}, + {"native_closeJetFile","()Z", (void *)android_media_JetPlayer_closeFile}, + {"native_playJet", "()Z", (void *)android_media_JetPlayer_play}, + {"native_pauseJet", "()Z", (void *)android_media_JetPlayer_pause}, + {"native_queueJetSegment", + "(IIIIIB)Z", (void *)android_media_JetPlayer_queueSegment}, + {"native_queueJetSegmentMuteArray", + "(IIII[ZB)Z", (void *)android_media_JetPlayer_queueSegmentMuteArray}, + {"native_setMuteFlags","(IZ)Z", (void *)android_media_JetPlayer_setMuteFlags}, + {"native_setMuteArray","([ZZ)Z", (void *)android_media_JetPlayer_setMuteArray}, + {"native_setMuteFlag", "(IZZ)Z", (void *)android_media_JetPlayer_setMuteFlag}, + {"native_triggerClip", "(I)Z", (void *)android_media_JetPlayer_triggerClip}, +}; + +#define JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME "mNativePlayerInJavaObj" +#define JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME "postEventFromNative" + + +int register_android_media_JetPlayer(JNIEnv *env) +{ + jclass jetPlayerClass = NULL; + javaJetPlayerFields.jetClass = NULL; + javaJetPlayerFields.postNativeEventInJava = NULL; + javaJetPlayerFields.nativePlayerInJavaObj = NULL; + + // Get the JetPlayer java class + jetPlayerClass = env->FindClass(kClassPathName); + if (jetPlayerClass == NULL) { + LOGE("Can't find %s", kClassPathName); + return -1; + } + javaJetPlayerFields.jetClass = (jclass)env->NewGlobalRef(jetPlayerClass); + + // Get the mNativePlayerInJavaObj variable field + javaJetPlayerFields.nativePlayerInJavaObj = env->GetFieldID( + jetPlayerClass, + JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME, "I"); + if (javaJetPlayerFields.nativePlayerInJavaObj == NULL) { + LOGE("Can't find AudioTrack.%s", JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME); + return -1; + } + + // Get the callback to post events from this native code to Java + javaJetPlayerFields.postNativeEventInJava = env->GetStaticMethodID(javaJetPlayerFields.jetClass, + JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;III)V"); + if (javaJetPlayerFields.postNativeEventInJava == NULL) { + LOGE("Can't find Jet.%s", JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME); + return -1; + } + + return AndroidRuntime::registerNativeMethods(env, + kClassPathName, gMethods, NELEM(gMethods)); +} |