diff options
author | 2019-10-17 08:55:52 -0700 | |
---|---|---|
committer | 2019-10-17 21:33:07 +0000 | |
commit | f0ef85669cc77a48123501e80fccade531068bb4 (patch) | |
tree | 6dfcaec3fe58b121014d9cd45479e810d34f522c | |
parent | 0d5b27b2db22f94bb8e54b53efd522bf0ecd5b2f (diff) |
Move JetPlayer implemention and JNI
The JetPlayer implementation in libmedia was only used by the
JetPlayer JNI code in libandroid_runtime. This change moves
both implementation and JNI to libmedia_jni. This reduces
libandroid_runtime's dependency on libmedia, and results in
a net size reduction of the libraries involved.
Test: atest JetPlayerTest
Change-Id: I028c774fdea167924b064855267254c15f22fddb
Merged-In: I028c774fdea167924b064855267254c15f22fddb
-rw-r--r-- | core/jni/Android.bp | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | media/java/android/media/JetPlayer.java | 12 | ||||
-rw-r--r-- | media/jni/Android.bp | 9 | ||||
-rw-r--r-- | media/jni/JetPlayer.cpp | 471 | ||||
-rw-r--r-- | media/jni/JetPlayer.h | 126 | ||||
-rw-r--r-- | media/jni/android_media_JetPlayer.cpp (renamed from core/jni/android_media_JetPlayer.cpp) | 2 | ||||
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 6 |
8 files changed, 619 insertions, 10 deletions
diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 6270d89ca720..486d24c781d9 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -169,7 +169,6 @@ cc_library_shared { "android_media_AudioVolumeGroups.cpp", "android_media_AudioVolumeGroupCallback.cpp", "android_media_DeviceCallback.cpp", - "android_media_JetPlayer.cpp", "android_media_MediaMetricsJNI.cpp", "android_media_MicrophoneInfo.cpp", "android_media_midi.cpp", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 571c2cb6e172..9a90555041d7 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -113,7 +113,6 @@ extern int register_android_media_AudioProductStrategies(JNIEnv *env); extern int register_android_media_AudioVolumeGroups(JNIEnv *env); extern int register_android_media_AudioVolumeGroupChangeHandler(JNIEnv *env); extern int register_android_media_MicrophoneInfo(JNIEnv *env); -extern int register_android_media_JetPlayer(JNIEnv *env); extern int register_android_media_ToneGenerator(JNIEnv *env); extern int register_android_media_midi(JNIEnv *env); @@ -1589,7 +1588,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_media_AudioProductStrategies), REG_JNI(register_android_media_AudioVolumeGroups), REG_JNI(register_android_media_AudioVolumeGroupChangeHandler), - REG_JNI(register_android_media_JetPlayer), REG_JNI(register_android_media_MicrophoneInfo), REG_JNI(register_android_media_RemoteDisplay), REG_JNI(register_android_media_ToneGenerator), diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java index b12e647acc4b..e85b3ff99104 100644 --- a/media/java/android/media/JetPlayer.java +++ b/media/java/android/media/JetPlayer.java @@ -17,18 +17,17 @@ package android.media; -import java.io.FileDescriptor; -import java.lang.ref.WeakReference; -import java.lang.CloneNotSupportedException; - import android.annotation.UnsupportedAppUsage; import android.content.res.AssetFileDescriptor; -import android.os.Looper; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.util.AndroidRuntimeException; import android.util.Log; +import java.io.FileDescriptor; +import java.lang.ref.WeakReference; + /** * JetPlayer provides access to JET content playback and control. * @@ -120,6 +119,9 @@ public class JetPlayer private static JetPlayer singletonRef; + static { + System.loadLibrary("media_jni"); + } //-------------------------------- // Used exclusively by native code diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 45ee210c80c9..e6c1c67b98e5 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -4,6 +4,7 @@ cc_library_shared { srcs: [ "android_media_ImageWriter.cpp", "android_media_ImageReader.cpp", + "android_media_JetPlayer.cpp", "android_media_MediaCrypto.cpp", "android_media_MediaCodec.cpp", "android_media_MediaCodecList.cpp", @@ -25,10 +26,12 @@ cc_library_shared { "android_mtp_MtpDatabase.cpp", "android_mtp_MtpDevice.cpp", "android_mtp_MtpServer.cpp", + "JetPlayer.cpp", ], shared_libs: [ "libandroid_runtime", + "libaudioclient", "libnativehelper", "libnativewindow", "libutils", @@ -53,6 +56,7 @@ cc_library_shared { "libandroidfw", "libhidlallocatorutils", "libhidlbase", + "libsonivox", "android.hardware.cas@1.0", "android.hardware.cas.native@1.0", "android.hidl.memory@1.0", @@ -64,7 +68,10 @@ cc_library_shared { "libmediadrm_headers", ], - static_libs: ["libgrallocusage"], + static_libs: [ + "libgrallocusage", + "libmedia_midiiowrapper", + ], include_dirs: [ "frameworks/base/core/jni", diff --git a/media/jni/JetPlayer.cpp b/media/jni/JetPlayer.cpp new file mode 100644 index 000000000000..358feb7f73d9 --- /dev/null +++ b/media/jni/JetPlayer.cpp @@ -0,0 +1,471 @@ +/* + * 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. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "JetPlayer-C" + +#include <utils/Log.h> +#include "JetPlayer.h" + + +namespace android +{ + +static const int MIX_NUM_BUFFERS = 4; +static const S_EAS_LIB_CONFIG* pLibConfig = NULL; + +//------------------------------------------------------------------------------------------------- +JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) : + mEventCallback(NULL), + mJavaJetPlayerRef(javaJetPlayer), + mTid(-1), + mRender(false), + mPaused(false), + mMaxTracks(maxTracks), + mEasData(NULL), + mIoWrapper(NULL), + mTrackBufferSize(trackBufferSize) +{ + ALOGV("JetPlayer constructor"); + mPreviousJetStatus.currentUserID = -1; + mPreviousJetStatus.segmentRepeatCount = -1; + mPreviousJetStatus.numQueuedSegments = -1; + mPreviousJetStatus.paused = true; +} + +//------------------------------------------------------------------------------------------------- +JetPlayer::~JetPlayer() +{ + ALOGV("~JetPlayer"); + release(); +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::init() +{ + //Mutex::Autolock lock(&mMutex); + + EAS_RESULT result; + + // retrieve the EAS library settings + if (pLibConfig == NULL) + pLibConfig = EAS_Config(); + if (pLibConfig == NULL) { + ALOGE("JetPlayer::init(): EAS library configuration could not be retrieved, aborting."); + return EAS_FAILURE; + } + + // init the EAS library + result = EAS_Init(&mEasData); + if (result != EAS_SUCCESS) { + ALOGE("JetPlayer::init(): Error initializing Sonivox EAS library, aborting."); + mState = EAS_STATE_ERROR; + return result; + } + // init the JET library with the default app event controller range + result = JET_Init(mEasData, NULL, sizeof(S_JET_CONFIG)); + if (result != EAS_SUCCESS) { + ALOGE("JetPlayer::init(): Error initializing JET library, aborting."); + mState = EAS_STATE_ERROR; + return result; + } + + // create the output AudioTrack + mAudioTrack = new AudioTrack(); + status_t status = mAudioTrack->set(AUDIO_STREAM_MUSIC, //TODO parameterize this + pLibConfig->sampleRate, + AUDIO_FORMAT_PCM_16_BIT, + audio_channel_out_mask_from_count(pLibConfig->numChannels), + (size_t) mTrackBufferSize, + AUDIO_OUTPUT_FLAG_NONE); + if (status != OK) { + ALOGE("JetPlayer::init(): Error initializing JET library; AudioTrack error %d", status); + mAudioTrack.clear(); + mState = EAS_STATE_ERROR; + return EAS_FAILURE; + } + + // create render and playback thread + { + Mutex::Autolock l(mMutex); + ALOGV("JetPlayer::init(): trying to start render thread"); + mThread = new JetPlayerThread(this); + mThread->run("jetRenderThread", ANDROID_PRIORITY_AUDIO); + mCondition.wait(mMutex); + } + if (mTid > 0) { + // render thread started, we're ready + ALOGV("JetPlayer::init(): render thread(%d) successfully started.", mTid); + mState = EAS_STATE_READY; + } else { + ALOGE("JetPlayer::init(): failed to start render thread."); + mState = EAS_STATE_ERROR; + return EAS_FAILURE; + } + + return EAS_SUCCESS; +} + +void JetPlayer::setEventCallback(jetevent_callback eventCallback) +{ + Mutex::Autolock l(mMutex); + mEventCallback = eventCallback; +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::release() +{ + ALOGV("JetPlayer::release()"); + Mutex::Autolock lock(mMutex); + mPaused = true; + mRender = false; + if (mEasData) { + JET_Pause(mEasData); + JET_CloseFile(mEasData); + JET_Shutdown(mEasData); + EAS_Shutdown(mEasData); + } + delete mIoWrapper; + mIoWrapper = NULL; + if (mAudioTrack != 0) { + mAudioTrack->stop(); + mAudioTrack->flush(); + mAudioTrack.clear(); + } + if (mAudioBuffer) { + delete mAudioBuffer; + mAudioBuffer = NULL; + } + mEasData = NULL; + + return EAS_SUCCESS; +} + + +//------------------------------------------------------------------------------------------------- +int JetPlayer::render() { + EAS_RESULT result = EAS_FAILURE; + EAS_I32 count; + int temp; + bool audioStarted = false; + + ALOGV("JetPlayer::render(): entering"); + + // allocate render buffer + mAudioBuffer = + new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS]; + + // signal main thread that we started + { + Mutex::Autolock l(mMutex); + mTid = gettid(); + ALOGV("JetPlayer::render(): render thread(%d) signal", mTid); + mCondition.signal(); + } + + while (1) { + + mMutex.lock(); // [[[[[[[[ LOCK --------------------------------------- + + if (mEasData == NULL) { + mMutex.unlock(); + ALOGV("JetPlayer::render(): NULL EAS data, exiting render."); + goto threadExit; + } + + // nothing to render, wait for client thread to wake us up + while (!mRender) + { + ALOGV("JetPlayer::render(): signal wait"); + if (audioStarted) { + mAudioTrack->pause(); + // we have to restart the playback once we start rendering again + audioStarted = false; + } + mCondition.wait(mMutex); + ALOGV("JetPlayer::render(): signal rx'd"); + } + + // render midi data into the input buffer + int num_output = 0; + EAS_PCM* p = mAudioBuffer; + for (int i = 0; i < MIX_NUM_BUFFERS; i++) { + result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count); + if (result != EAS_SUCCESS) { + ALOGE("JetPlayer::render(): EAS_Render returned error %ld", result); + } + p += count * pLibConfig->numChannels; + num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM); + + // send events that were generated (if any) to the event callback + fireEventsFromJetQueue(); + } + + // update playback state + //ALOGV("JetPlayer::render(): updating state"); + JET_Status(mEasData, &mJetStatus); + fireUpdateOnStatusChange(); + mPaused = mJetStatus.paused; + + mMutex.unlock(); // UNLOCK ]]]]]]]] ----------------------------------- + + // check audio output track + if (mAudioTrack == NULL) { + ALOGE("JetPlayer::render(): output AudioTrack was not created"); + goto threadExit; + } + + // Write data to the audio hardware + //ALOGV("JetPlayer::render(): writing to audio output"); + if ((temp = mAudioTrack->write(mAudioBuffer, num_output)) < 0) { + ALOGE("JetPlayer::render(): Error in writing:%d",temp); + return temp; + } + + // start audio output if necessary + if (!audioStarted) { + ALOGV("JetPlayer::render(): starting audio playback"); + mAudioTrack->start(); + audioStarted = true; + } + + }//while (1) + +threadExit: + if (mAudioTrack != NULL) { + mAudioTrack->stop(); + mAudioTrack->flush(); + } + delete [] mAudioBuffer; + mAudioBuffer = NULL; + mMutex.lock(); + mTid = -1; + mCondition.signal(); + mMutex.unlock(); + return result; +} + + +//------------------------------------------------------------------------------------------------- +// fire up an update if any of the status fields has changed +// precondition: mMutex locked +void JetPlayer::fireUpdateOnStatusChange() +{ + if ( (mJetStatus.currentUserID != mPreviousJetStatus.currentUserID) + ||(mJetStatus.segmentRepeatCount != mPreviousJetStatus.segmentRepeatCount) ) { + if (mEventCallback) { + mEventCallback( + JetPlayer::JET_USERID_UPDATE, + mJetStatus.currentUserID, + mJetStatus.segmentRepeatCount, + mJavaJetPlayerRef); + } + mPreviousJetStatus.currentUserID = mJetStatus.currentUserID; + mPreviousJetStatus.segmentRepeatCount = mJetStatus.segmentRepeatCount; + } + + if (mJetStatus.numQueuedSegments != mPreviousJetStatus.numQueuedSegments) { + if (mEventCallback) { + mEventCallback( + JetPlayer::JET_NUMQUEUEDSEGMENT_UPDATE, + mJetStatus.numQueuedSegments, + -1, + mJavaJetPlayerRef); + } + mPreviousJetStatus.numQueuedSegments = mJetStatus.numQueuedSegments; + } + + if (mJetStatus.paused != mPreviousJetStatus.paused) { + if (mEventCallback) { + mEventCallback(JetPlayer::JET_PAUSE_UPDATE, + mJetStatus.paused, + -1, + mJavaJetPlayerRef); + } + mPreviousJetStatus.paused = mJetStatus.paused; + } + +} + + +//------------------------------------------------------------------------------------------------- +// fire up all the JET events in the JET engine queue (until the queue is empty) +// precondition: mMutex locked +void JetPlayer::fireEventsFromJetQueue() +{ + if (!mEventCallback) { + // no callback, just empty the event queue + while (JET_GetEvent(mEasData, NULL, NULL)) { } + return; + } + + EAS_U32 rawEvent; + while (JET_GetEvent(mEasData, &rawEvent, NULL)) { + mEventCallback( + JetPlayer::JET_EVENT, + rawEvent, + -1, + mJavaJetPlayerRef); + } +} + + +//------------------------------------------------------------------------------------------------- +int JetPlayer::loadFromFile(const char* path) +{ + ALOGV("JetPlayer::loadFromFile(): path=%s", path); + + Mutex::Autolock lock(mMutex); + + delete mIoWrapper; + mIoWrapper = new MidiIoWrapper(path); + + EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator()); + if (result != EAS_SUCCESS) + mState = EAS_STATE_ERROR; + else + mState = EAS_STATE_OPEN; + return( result ); +} + + +//------------------------------------------------------------------------------------------------- +int JetPlayer::loadFromFD(const int fd, const long long offset, const long long length) +{ + ALOGV("JetPlayer::loadFromFD(): fd=%d offset=%lld length=%lld", fd, offset, length); + + Mutex::Autolock lock(mMutex); + + delete mIoWrapper; + mIoWrapper = new MidiIoWrapper(fd, offset, length); + + EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator()); + if (result != EAS_SUCCESS) + mState = EAS_STATE_ERROR; + else + mState = EAS_STATE_OPEN; + return( result ); +} + + +//------------------------------------------------------------------------------------------------- +int JetPlayer::closeFile() +{ + Mutex::Autolock lock(mMutex); + return JET_CloseFile(mEasData); +} + + +//------------------------------------------------------------------------------------------------- +int JetPlayer::play() +{ + ALOGV("JetPlayer::play(): entering"); + Mutex::Autolock lock(mMutex); + + EAS_RESULT result = JET_Play(mEasData); + + mPaused = false; + mRender = true; + + JET_Status(mEasData, &mJetStatus); + this->dumpJetStatus(&mJetStatus); + + fireUpdateOnStatusChange(); + + // wake up render thread + ALOGV("JetPlayer::play(): wakeup render thread"); + mCondition.signal(); + + return result; +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::pause() +{ + Mutex::Autolock lock(mMutex); + mPaused = true; + EAS_RESULT result = JET_Pause(mEasData); + + mRender = false; + + JET_Status(mEasData, &mJetStatus); + this->dumpJetStatus(&mJetStatus); + fireUpdateOnStatusChange(); + + + return result; +} + + +//------------------------------------------------------------------------------------------------- +int JetPlayer::queueSegment(int segmentNum, int libNum, int repeatCount, int transpose, + EAS_U32 muteFlags, EAS_U8 userID) +{ + ALOGV("JetPlayer::queueSegment segmentNum=%d, libNum=%d, repeatCount=%d, transpose=%d", + segmentNum, libNum, repeatCount, transpose); + Mutex::Autolock lock(mMutex); + return JET_QueueSegment(mEasData, segmentNum, libNum, repeatCount, transpose, muteFlags, + userID); +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::setMuteFlags(EAS_U32 muteFlags, bool sync) +{ + Mutex::Autolock lock(mMutex); + return JET_SetMuteFlags(mEasData, muteFlags, sync); +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::setMuteFlag(int trackNum, bool muteFlag, bool sync) +{ + Mutex::Autolock lock(mMutex); + return JET_SetMuteFlag(mEasData, trackNum, muteFlag, sync); +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::triggerClip(int clipId) +{ + ALOGV("JetPlayer::triggerClip clipId=%d", clipId); + Mutex::Autolock lock(mMutex); + return JET_TriggerClip(mEasData, clipId); +} + +//------------------------------------------------------------------------------------------------- +int JetPlayer::clearQueue() +{ + ALOGV("JetPlayer::clearQueue"); + Mutex::Autolock lock(mMutex); + return JET_Clear_Queue(mEasData); +} + +//------------------------------------------------------------------------------------------------- +void JetPlayer::dump() +{ +} + +void JetPlayer::dumpJetStatus(S_JET_STATUS* pJetStatus) +{ + if (pJetStatus!=NULL) + ALOGV(">> current JET player status: userID=%d segmentRepeatCount=%d numQueuedSegments=%d " + "paused=%d", + pJetStatus->currentUserID, pJetStatus->segmentRepeatCount, + pJetStatus->numQueuedSegments, pJetStatus->paused); + else + ALOGE(">> JET player status is NULL"); +} + + +} // end namespace android diff --git a/media/jni/JetPlayer.h b/media/jni/JetPlayer.h new file mode 100644 index 000000000000..bb569bcad7be --- /dev/null +++ b/media/jni/JetPlayer.h @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#ifndef JETPLAYER_H_ +#define JETPLAYER_H_ + +#include <utils/threads.h> + +#include <libsonivox/jet.h> +#include <libsonivox/eas_types.h> +#include <media/AudioTrack.h> +#include <media/MidiIoWrapper.h> + + +namespace android { + +typedef void (*jetevent_callback)(int eventType, int val1, int val2, void *cookie); + +class JetPlayer { + +public: + + // to keep in sync with the JetPlayer class constants + // defined in frameworks/base/media/java/android/media/JetPlayer.java + static const int JET_EVENT = 1; + static const int JET_USERID_UPDATE = 2; + static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3; + static const int JET_PAUSE_UPDATE = 4; + + JetPlayer(void *javaJetPlayer, + int maxTracks = 32, + int trackBufferSize = 1200); + ~JetPlayer(); + int init(); + int release(); + + int loadFromFile(const char* url); + int loadFromFD(const int fd, const long long offset, const long long length); + int closeFile(); + int play(); + int pause(); + int queueSegment(int segmentNum, int libNum, int repeatCount, int transpose, + EAS_U32 muteFlags, EAS_U8 userID); + int setMuteFlags(EAS_U32 muteFlags, bool sync); + int setMuteFlag(int trackNum, bool muteFlag, bool sync); + int triggerClip(int clipId); + int clearQueue(); + + void setEventCallback(jetevent_callback callback); + + int getMaxTracks() { return mMaxTracks; }; + + +private: + int render(); + void fireUpdateOnStatusChange(); + void fireEventsFromJetQueue(); + + JetPlayer() {} // no default constructor + void dump(); + void dumpJetStatus(S_JET_STATUS* pJetStatus); + + jetevent_callback mEventCallback; + + void* mJavaJetPlayerRef; + Mutex mMutex; // mutex to sync the render and playback thread with the JET calls + pid_t mTid; + Condition mCondition; + volatile bool mRender; + bool mPaused; + + EAS_STATE mState; + int* mMemFailedVar; + + int mMaxTracks; // max number of MIDI tracks, usually 32 + EAS_DATA_HANDLE mEasData; + MidiIoWrapper* mIoWrapper; + EAS_PCM* mAudioBuffer;// EAS renders the MIDI data into this buffer, + sp<AudioTrack> mAudioTrack; // and we play it in this audio track + int mTrackBufferSize; + S_JET_STATUS mJetStatus; + S_JET_STATUS mPreviousJetStatus; + + class JetPlayerThread : public Thread { + public: + JetPlayerThread(JetPlayer *player) : mPlayer(player) { + } + + protected: + virtual ~JetPlayerThread() {} + + private: + JetPlayer *mPlayer; + + bool threadLoop() { + int result; + result = mPlayer->render(); + return false; + } + + JetPlayerThread(const JetPlayerThread &); + JetPlayerThread &operator=(const JetPlayerThread &); + }; + + sp<JetPlayerThread> mThread; + +}; // end class JetPlayer + +} // end namespace android + + + +#endif /*JETPLAYER_H_*/ diff --git a/core/jni/android_media_JetPlayer.cpp b/media/jni/android_media_JetPlayer.cpp index da116bf7c96a..8a05f85e4285 100644 --- a/core/jni/android_media_JetPlayer.cpp +++ b/media/jni/android_media_JetPlayer.cpp @@ -27,7 +27,7 @@ #include "core_jni_helpers.h" #include <utils/Log.h> -#include <media/JetPlayer.h> +#include "JetPlayer.h" using namespace android; diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index d24edc7552ae..ec0ce8759571 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -1436,6 +1436,7 @@ static int register_android_media_MediaPlayer(JNIEnv *env) } extern int register_android_media_ImageReader(JNIEnv *env); extern int register_android_media_ImageWriter(JNIEnv *env); +extern int register_android_media_JetPlayer(JNIEnv *env); extern int register_android_media_Crypto(JNIEnv *env); extern int register_android_media_Drm(JNIEnv *env); extern int register_android_media_Descrambler(JNIEnv *env); @@ -1475,6 +1476,11 @@ jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) goto bail; } + if (register_android_media_JetPlayer(env) < 0) { + ALOGE("ERROR: JetPlayer native registration failed"); + goto bail; + } + if (register_android_media_MediaPlayer(env) < 0) { ALOGE("ERROR: MediaPlayer native registration failed\n"); goto bail; |