Loading media/libmediaplayer2/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ cc_library { srcs: [ "JAudioTrack.cpp", "JavaVMHelper.cpp", "MediaPlayer2AudioOutput.cpp", "mediaplayer2.cpp", ], Loading Loading @@ -49,6 +50,10 @@ cc_library { "media_plugin_headers", ], include_dirs: [ "frameworks/base/core/jni", ], static_libs: [ "libmedia_helper", "libstagefright_nuplayer2", Loading media/libmediaplayer2/JAudioTrack.cpp +30 −30 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include "mediaplayer2/JAudioTrack.h" #include <android_media_AudioErrors.h> #include <android_runtime/AndroidRuntime.h> #include <mediaplayer2/JavaVMHelper.h> namespace android { Loading @@ -39,7 +39,7 @@ JAudioTrack::JAudioTrack( // < Usages of the argumen const audio_attributes_t* pAttributes, // AudioAttributes float maxRequiredSpeed) { // bufferSizeInBytes JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jAudioTrackCls = env->FindClass("android/media/AudioTrack"); mAudioTrackCls = (jclass) env->NewGlobalRef(jAudioTrackCls); Loading Loading @@ -116,19 +116,19 @@ JAudioTrack::JAudioTrack( // < Usages of the argumen } JAudioTrack::~JAudioTrack() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); env->DeleteGlobalRef(mAudioTrackCls); } size_t JAudioTrack::frameCount() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetBufferSizeInFrames = env->GetMethodID( mAudioTrackCls, "getBufferSizeInFrames", "()I"); return env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames); } size_t JAudioTrack::channelCount() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetChannelCount = env->GetMethodID(mAudioTrackCls, "getChannelCount", "()I"); return env->CallIntMethod(mAudioTrackObj, jGetChannelCount); } Loading @@ -143,7 +143,7 @@ status_t JAudioTrack::getPosition(uint32_t *position) { return BAD_VALUE; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetPlaybackHeadPosition = env->GetMethodID( mAudioTrackCls, "getPlaybackHeadPosition", "()I"); *position = env->CallIntMethod(mAudioTrackObj, jGetPlaybackHeadPosition); Loading @@ -152,7 +152,7 @@ status_t JAudioTrack::getPosition(uint32_t *position) { } bool JAudioTrack::getTimestamp(AudioTimestamp& timestamp) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jAudioTimeStampCls = env->FindClass("android/media/AudioTimestamp"); jobject jAudioTimeStampObj = env->AllocObject(jAudioTimeStampCls); Loading Loading @@ -189,7 +189,7 @@ status_t JAudioTrack::getTimestamp(ExtendedTimestamp *timestamp __unused) { status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) { // TODO: existing native AudioTrack returns INVALID_OPERATION on offload/direct/fast tracks. // Should we do the same thing? JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams"); jmethodID jPlaybackParamsCtor = env->GetMethodID(jPlaybackParamsCls, "<init>", "()V"); Loading Loading @@ -224,7 +224,7 @@ status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) { } const AudioPlaybackRate JAudioTrack::getPlaybackRate() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetPlaybackParams = env->GetMethodID( mAudioTrackCls, "getPlaybackParams", "()Landroid/media/PlaybackParams;"); Loading Loading @@ -266,7 +266,7 @@ media::VolumeShaper::Status JAudioTrack::applyVolumeShaper( return media::VolumeShaper::Status(BAD_VALUE); } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jCreateVolumeShaper = env->GetMethodID(mAudioTrackCls, "createVolumeShaper", "(Landroid/media/VolumeShaper$Configuration;)Landroid/media/VolumeShaper;"); Loading @@ -282,7 +282,7 @@ media::VolumeShaper::Status JAudioTrack::applyVolumeShaper( } status_t JAudioTrack::setAuxEffectSendLevel(float level) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jSetAuxEffectSendLevel = env->GetMethodID( mAudioTrackCls, "setAuxEffectSendLevel", "(F)I"); int result = env->CallIntMethod(mAudioTrackObj, jSetAuxEffectSendLevel, level); Loading @@ -290,14 +290,14 @@ status_t JAudioTrack::setAuxEffectSendLevel(float level) { } status_t JAudioTrack::attachAuxEffect(int effectId) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jAttachAuxEffect = env->GetMethodID(mAudioTrackCls, "attachAuxEffect", "(I)I"); int result = env->CallIntMethod(mAudioTrackObj, jAttachAuxEffect, effectId); return javaToNativeStatus(result); } status_t JAudioTrack::setVolume(float left, float right) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); // TODO: Java setStereoVolume is deprecated. Do we really need this method? jmethodID jSetStereoVolume = env->GetMethodID(mAudioTrackCls, "setStereoVolume", "(FF)I"); int result = env->CallIntMethod(mAudioTrackObj, jSetStereoVolume, left, right); Loading @@ -305,14 +305,14 @@ status_t JAudioTrack::setVolume(float left, float right) { } status_t JAudioTrack::setVolume(float volume) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jSetVolume = env->GetMethodID(mAudioTrackCls, "setVolume", "(F)I"); int result = env->CallIntMethod(mAudioTrackObj, jSetVolume, volume); return javaToNativeStatus(result); } status_t JAudioTrack::start() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jPlay = env->GetMethodID(mAudioTrackCls, "play", "()V"); // TODO: Should we catch the Java IllegalStateException from play()? env->CallVoidMethod(mAudioTrackObj, jPlay); Loading @@ -324,7 +324,7 @@ ssize_t JAudioTrack::write(const void* buffer, size_t size, bool blocking) { return BAD_VALUE; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jbyteArray jAudioData = env->NewByteArray(size); env->SetByteArrayRegion(jAudioData, 0, size, (jbyte *) buffer); Loading Loading @@ -353,7 +353,7 @@ ssize_t JAudioTrack::write(const void* buffer, size_t size, bool blocking) { } void JAudioTrack::stop() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jStop = env->GetMethodID(mAudioTrackCls, "stop", "()V"); env->CallVoidMethod(mAudioTrackObj, jStop); // TODO: Should we catch IllegalStateException? Loading @@ -365,20 +365,20 @@ bool JAudioTrack::stopped() const { } void JAudioTrack::flush() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jFlush = env->GetMethodID(mAudioTrackCls, "flush", "()V"); env->CallVoidMethod(mAudioTrackObj, jFlush); } void JAudioTrack::pause() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jPause = env->GetMethodID(mAudioTrackCls, "pause", "()V"); env->CallVoidMethod(mAudioTrackObj, jPause); // TODO: Should we catch IllegalStateException? } bool JAudioTrack::isPlaying() const { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetPlayState = env->GetMethodID(mAudioTrackCls, "getPlayState", "()I"); int currentPlayState = env->CallIntMethod(mAudioTrackObj, jGetPlayState); Loading @@ -393,7 +393,7 @@ bool JAudioTrack::isPlaying() const { } uint32_t JAudioTrack::getSampleRate() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetSampleRate = env->GetMethodID(mAudioTrackCls, "getSampleRate", "()I"); return env->CallIntMethod(mAudioTrackObj, jGetSampleRate); } Loading @@ -403,7 +403,7 @@ status_t JAudioTrack::getBufferDurationInUs(int64_t *duration) { return BAD_VALUE; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetBufferSizeInFrames = env->GetMethodID( mAudioTrackCls, "getBufferSizeInFrames", "()I"); int bufferSizeInFrames = env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames); Loading @@ -417,7 +417,7 @@ status_t JAudioTrack::getBufferDurationInUs(int64_t *duration) { } audio_format_t JAudioTrack::format() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetAudioFormat = env->GetMethodID(mAudioTrackCls, "getAudioFormat", "()I"); int javaFormat = env->CallIntMethod(mAudioTrackObj, jGetAudioFormat); return audioFormatToNative(javaFormat); Loading Loading @@ -454,7 +454,7 @@ status_t JAudioTrack::dump(int fd, const Vector<String16>& args __unused) const } audio_port_handle_t JAudioTrack::getRoutedDeviceId() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetRoutedDevice = env->GetMethodID(mAudioTrackCls, "getRoutedDevice", "()Landroid/media/AudioDeviceInfo;"); jobject jAudioDeviceInfoObj = env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice); Loading @@ -469,14 +469,14 @@ audio_port_handle_t JAudioTrack::getRoutedDeviceId() { } audio_session_t JAudioTrack::getAudioSessionId() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetAudioSessionId = env->GetMethodID(mAudioTrackCls, "getAudioSessionId", "()I"); jint sessionId = env->CallIntMethod(mAudioTrackObj, jGetAudioSessionId); return (audio_session_t) sessionId; } status_t JAudioTrack::setOutputDevice(audio_port_handle_t deviceId) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jMP2ImplCls = env->FindClass("android/media/MediaPlayer2Impl"); jmethodID jSetAudioOutputDeviceById = env->GetMethodID( jMP2ImplCls, "setAudioOutputDeviceById", "(Landroid/media/AudioTrack;I)Z"); Loading Loading @@ -550,7 +550,7 @@ jobject JAudioTrack::createVolumeShaperConfigurationObj( return NULL; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); // Referenced "android_media_VolumeShaper.h". jfloatArray xarray = nullptr; Loading Loading @@ -595,7 +595,7 @@ jobject JAudioTrack::createVolumeShaperConfigurationObj( jobject JAudioTrack::createVolumeShaperOperationObj( const sp<media::VolumeShaper::Operation>& operation) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Operation$Builder"); jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V"); Loading Loading @@ -647,7 +647,7 @@ jobject JAudioTrack::createVolumeShaperOperationObj( } jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jCallbackCls = env->FindClass("android/media/MediaPlayer2Impl$StreamEventCallback"); jmethodID jCallbackCtor = env->GetMethodID(jCallbackCls, "<init>", "(JJJ)V"); jobject jCallbackObj = env->NewObject(jCallbackCls, jCallbackCtor, this, cbf, user); Loading @@ -655,7 +655,7 @@ jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) { } jobject JAudioTrack::createCallbackExecutor() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jExecutorsCls = env->FindClass("java/util/concurrent/Executors"); jmethodID jNewSingleThreadExecutor = env->GetStaticMethodID(jExecutorsCls, "newSingleThreadExecutor", "()Ljava/util/concurrent/ExecutorService;"); Loading media/libmediaplayer2/JavaVMHelper.cpp 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * Copyright 2018 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_TAG "JavaVMHelper" #include "mediaplayer2/JavaVMHelper.h" #include <media/stagefright/foundation/ADebug.h> #include <stdlib.h> namespace android { // static std::atomic<JavaVM *> JavaVMHelper::sJavaVM(NULL); // static JNIEnv *JavaVMHelper::getJNIEnv() { JNIEnv *env; JavaVM *vm = sJavaVM.load(); CHECK(vm != NULL); if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) { return NULL; } return env; } // static void JavaVMHelper::setJavaVM(JavaVM *vm) { sJavaVM.store(vm); } } // namespace android media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 JAVA_VM_HELPER_H_ #define JAVA_VM_HELPER_H_ #include "jni.h" #include <atomic> namespace android { struct JavaVMHelper { static JNIEnv *getJNIEnv(); static void setJavaVM(JavaVM *vm); private: // Once a valid JavaVM has been set, it should never be reset or changed. // However, as it may be accessed from multiple threads, access needs to be // synchronized. static std::atomic<JavaVM *> sJavaVM; }; } // namespace android #endif // JAVA_VM_HELPER_H_ Loading
media/libmediaplayer2/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ cc_library { srcs: [ "JAudioTrack.cpp", "JavaVMHelper.cpp", "MediaPlayer2AudioOutput.cpp", "mediaplayer2.cpp", ], Loading Loading @@ -49,6 +50,10 @@ cc_library { "media_plugin_headers", ], include_dirs: [ "frameworks/base/core/jni", ], static_libs: [ "libmedia_helper", "libstagefright_nuplayer2", Loading
media/libmediaplayer2/JAudioTrack.cpp +30 −30 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include "mediaplayer2/JAudioTrack.h" #include <android_media_AudioErrors.h> #include <android_runtime/AndroidRuntime.h> #include <mediaplayer2/JavaVMHelper.h> namespace android { Loading @@ -39,7 +39,7 @@ JAudioTrack::JAudioTrack( // < Usages of the argumen const audio_attributes_t* pAttributes, // AudioAttributes float maxRequiredSpeed) { // bufferSizeInBytes JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jAudioTrackCls = env->FindClass("android/media/AudioTrack"); mAudioTrackCls = (jclass) env->NewGlobalRef(jAudioTrackCls); Loading Loading @@ -116,19 +116,19 @@ JAudioTrack::JAudioTrack( // < Usages of the argumen } JAudioTrack::~JAudioTrack() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); env->DeleteGlobalRef(mAudioTrackCls); } size_t JAudioTrack::frameCount() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetBufferSizeInFrames = env->GetMethodID( mAudioTrackCls, "getBufferSizeInFrames", "()I"); return env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames); } size_t JAudioTrack::channelCount() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetChannelCount = env->GetMethodID(mAudioTrackCls, "getChannelCount", "()I"); return env->CallIntMethod(mAudioTrackObj, jGetChannelCount); } Loading @@ -143,7 +143,7 @@ status_t JAudioTrack::getPosition(uint32_t *position) { return BAD_VALUE; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetPlaybackHeadPosition = env->GetMethodID( mAudioTrackCls, "getPlaybackHeadPosition", "()I"); *position = env->CallIntMethod(mAudioTrackObj, jGetPlaybackHeadPosition); Loading @@ -152,7 +152,7 @@ status_t JAudioTrack::getPosition(uint32_t *position) { } bool JAudioTrack::getTimestamp(AudioTimestamp& timestamp) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jAudioTimeStampCls = env->FindClass("android/media/AudioTimestamp"); jobject jAudioTimeStampObj = env->AllocObject(jAudioTimeStampCls); Loading Loading @@ -189,7 +189,7 @@ status_t JAudioTrack::getTimestamp(ExtendedTimestamp *timestamp __unused) { status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) { // TODO: existing native AudioTrack returns INVALID_OPERATION on offload/direct/fast tracks. // Should we do the same thing? JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams"); jmethodID jPlaybackParamsCtor = env->GetMethodID(jPlaybackParamsCls, "<init>", "()V"); Loading Loading @@ -224,7 +224,7 @@ status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) { } const AudioPlaybackRate JAudioTrack::getPlaybackRate() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetPlaybackParams = env->GetMethodID( mAudioTrackCls, "getPlaybackParams", "()Landroid/media/PlaybackParams;"); Loading Loading @@ -266,7 +266,7 @@ media::VolumeShaper::Status JAudioTrack::applyVolumeShaper( return media::VolumeShaper::Status(BAD_VALUE); } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jCreateVolumeShaper = env->GetMethodID(mAudioTrackCls, "createVolumeShaper", "(Landroid/media/VolumeShaper$Configuration;)Landroid/media/VolumeShaper;"); Loading @@ -282,7 +282,7 @@ media::VolumeShaper::Status JAudioTrack::applyVolumeShaper( } status_t JAudioTrack::setAuxEffectSendLevel(float level) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jSetAuxEffectSendLevel = env->GetMethodID( mAudioTrackCls, "setAuxEffectSendLevel", "(F)I"); int result = env->CallIntMethod(mAudioTrackObj, jSetAuxEffectSendLevel, level); Loading @@ -290,14 +290,14 @@ status_t JAudioTrack::setAuxEffectSendLevel(float level) { } status_t JAudioTrack::attachAuxEffect(int effectId) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jAttachAuxEffect = env->GetMethodID(mAudioTrackCls, "attachAuxEffect", "(I)I"); int result = env->CallIntMethod(mAudioTrackObj, jAttachAuxEffect, effectId); return javaToNativeStatus(result); } status_t JAudioTrack::setVolume(float left, float right) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); // TODO: Java setStereoVolume is deprecated. Do we really need this method? jmethodID jSetStereoVolume = env->GetMethodID(mAudioTrackCls, "setStereoVolume", "(FF)I"); int result = env->CallIntMethod(mAudioTrackObj, jSetStereoVolume, left, right); Loading @@ -305,14 +305,14 @@ status_t JAudioTrack::setVolume(float left, float right) { } status_t JAudioTrack::setVolume(float volume) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jSetVolume = env->GetMethodID(mAudioTrackCls, "setVolume", "(F)I"); int result = env->CallIntMethod(mAudioTrackObj, jSetVolume, volume); return javaToNativeStatus(result); } status_t JAudioTrack::start() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jPlay = env->GetMethodID(mAudioTrackCls, "play", "()V"); // TODO: Should we catch the Java IllegalStateException from play()? env->CallVoidMethod(mAudioTrackObj, jPlay); Loading @@ -324,7 +324,7 @@ ssize_t JAudioTrack::write(const void* buffer, size_t size, bool blocking) { return BAD_VALUE; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jbyteArray jAudioData = env->NewByteArray(size); env->SetByteArrayRegion(jAudioData, 0, size, (jbyte *) buffer); Loading Loading @@ -353,7 +353,7 @@ ssize_t JAudioTrack::write(const void* buffer, size_t size, bool blocking) { } void JAudioTrack::stop() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jStop = env->GetMethodID(mAudioTrackCls, "stop", "()V"); env->CallVoidMethod(mAudioTrackObj, jStop); // TODO: Should we catch IllegalStateException? Loading @@ -365,20 +365,20 @@ bool JAudioTrack::stopped() const { } void JAudioTrack::flush() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jFlush = env->GetMethodID(mAudioTrackCls, "flush", "()V"); env->CallVoidMethod(mAudioTrackObj, jFlush); } void JAudioTrack::pause() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jPause = env->GetMethodID(mAudioTrackCls, "pause", "()V"); env->CallVoidMethod(mAudioTrackObj, jPause); // TODO: Should we catch IllegalStateException? } bool JAudioTrack::isPlaying() const { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetPlayState = env->GetMethodID(mAudioTrackCls, "getPlayState", "()I"); int currentPlayState = env->CallIntMethod(mAudioTrackObj, jGetPlayState); Loading @@ -393,7 +393,7 @@ bool JAudioTrack::isPlaying() const { } uint32_t JAudioTrack::getSampleRate() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetSampleRate = env->GetMethodID(mAudioTrackCls, "getSampleRate", "()I"); return env->CallIntMethod(mAudioTrackObj, jGetSampleRate); } Loading @@ -403,7 +403,7 @@ status_t JAudioTrack::getBufferDurationInUs(int64_t *duration) { return BAD_VALUE; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetBufferSizeInFrames = env->GetMethodID( mAudioTrackCls, "getBufferSizeInFrames", "()I"); int bufferSizeInFrames = env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames); Loading @@ -417,7 +417,7 @@ status_t JAudioTrack::getBufferDurationInUs(int64_t *duration) { } audio_format_t JAudioTrack::format() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetAudioFormat = env->GetMethodID(mAudioTrackCls, "getAudioFormat", "()I"); int javaFormat = env->CallIntMethod(mAudioTrackObj, jGetAudioFormat); return audioFormatToNative(javaFormat); Loading Loading @@ -454,7 +454,7 @@ status_t JAudioTrack::dump(int fd, const Vector<String16>& args __unused) const } audio_port_handle_t JAudioTrack::getRoutedDeviceId() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetRoutedDevice = env->GetMethodID(mAudioTrackCls, "getRoutedDevice", "()Landroid/media/AudioDeviceInfo;"); jobject jAudioDeviceInfoObj = env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice); Loading @@ -469,14 +469,14 @@ audio_port_handle_t JAudioTrack::getRoutedDeviceId() { } audio_session_t JAudioTrack::getAudioSessionId() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jmethodID jGetAudioSessionId = env->GetMethodID(mAudioTrackCls, "getAudioSessionId", "()I"); jint sessionId = env->CallIntMethod(mAudioTrackObj, jGetAudioSessionId); return (audio_session_t) sessionId; } status_t JAudioTrack::setOutputDevice(audio_port_handle_t deviceId) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jMP2ImplCls = env->FindClass("android/media/MediaPlayer2Impl"); jmethodID jSetAudioOutputDeviceById = env->GetMethodID( jMP2ImplCls, "setAudioOutputDeviceById", "(Landroid/media/AudioTrack;I)Z"); Loading Loading @@ -550,7 +550,7 @@ jobject JAudioTrack::createVolumeShaperConfigurationObj( return NULL; } JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); // Referenced "android_media_VolumeShaper.h". jfloatArray xarray = nullptr; Loading Loading @@ -595,7 +595,7 @@ jobject JAudioTrack::createVolumeShaperConfigurationObj( jobject JAudioTrack::createVolumeShaperOperationObj( const sp<media::VolumeShaper::Operation>& operation) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Operation$Builder"); jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V"); Loading Loading @@ -647,7 +647,7 @@ jobject JAudioTrack::createVolumeShaperOperationObj( } jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jCallbackCls = env->FindClass("android/media/MediaPlayer2Impl$StreamEventCallback"); jmethodID jCallbackCtor = env->GetMethodID(jCallbackCls, "<init>", "(JJJ)V"); jobject jCallbackObj = env->NewObject(jCallbackCls, jCallbackCtor, this, cbf, user); Loading @@ -655,7 +655,7 @@ jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) { } jobject JAudioTrack::createCallbackExecutor() { JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = JavaVMHelper::getJNIEnv(); jclass jExecutorsCls = env->FindClass("java/util/concurrent/Executors"); jmethodID jNewSingleThreadExecutor = env->GetStaticMethodID(jExecutorsCls, "newSingleThreadExecutor", "()Ljava/util/concurrent/ExecutorService;"); Loading
media/libmediaplayer2/JavaVMHelper.cpp 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * Copyright 2018 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_TAG "JavaVMHelper" #include "mediaplayer2/JavaVMHelper.h" #include <media/stagefright/foundation/ADebug.h> #include <stdlib.h> namespace android { // static std::atomic<JavaVM *> JavaVMHelper::sJavaVM(NULL); // static JNIEnv *JavaVMHelper::getJNIEnv() { JNIEnv *env; JavaVM *vm = sJavaVM.load(); CHECK(vm != NULL); if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) { return NULL; } return env; } // static void JavaVMHelper::setJavaVM(JavaVM *vm) { sJavaVM.store(vm); } } // namespace android
media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 JAVA_VM_HELPER_H_ #define JAVA_VM_HELPER_H_ #include "jni.h" #include <atomic> namespace android { struct JavaVMHelper { static JNIEnv *getJNIEnv(); static void setJavaVM(JavaVM *vm); private: // Once a valid JavaVM has been set, it should never be reset or changed. // However, as it may be accessed from multiple threads, access needs to be // synchronized. static std::atomic<JavaVM *> sJavaVM; }; } // namespace android #endif // JAVA_VM_HELPER_H_