diff options
Diffstat (limited to 'media/jni/android_media_MediaPlayer.cpp')
| -rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 202 |
1 files changed, 200 insertions, 2 deletions
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 820de5b..5b55a61 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -20,6 +20,7 @@ #include "utils/Log.h" #include <media/mediaplayer.h> +#include <media/AudioResamplerPublic.h> #include <media/IMediaHTTPService.h> #include <media/MediaPlayerInterface.h> #include <stdio.h> @@ -36,6 +37,9 @@ #include "utils/Errors.h" // for status_t #include "utils/KeyedVector.h" #include "utils/String8.h" +#include "android_media_MediaDataSource.h" +#include "android_media_PlaybackSettings.h" +#include "android_media_SyncSettings.h" #include "android_media_Utils.h" #include "android_os_Parcel.h" @@ -65,6 +69,9 @@ struct fields_t { }; static fields_t fields; +static PlaybackSettings::fields_t gPlaybackSettingsFields; +static SyncSettings::fields_t gSyncSettingsFields; + static Mutex sLock; // ---------------------------------------------------------------------------- @@ -167,6 +174,8 @@ static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStat } else { // Throw exception! if ( opStatus == (status_t) INVALID_OPERATION ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); + } else if ( opStatus == (status_t) BAD_VALUE ) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); } else if ( opStatus == (status_t) PERMISSION_DENIED ) { jniThrowException(env, "java/lang/SecurityException", NULL); } else if ( opStatus != (status_t) OK ) { @@ -251,6 +260,23 @@ android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fil process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." ); } +static void +android_media_MediaPlayer_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource) +{ + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL ) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return; + } + + if (dataSource == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return; + } + sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource); + process_media_player_call(env, thiz, mp->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed." ); +} + static sp<IGraphicBufferProducer> getVideoSurfaceTexture(JNIEnv* env, jobject thiz) { IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture); @@ -402,6 +428,155 @@ android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz) } static void +android_media_MediaPlayer_setPlaybackSettings(JNIEnv *env, jobject thiz, jobject settings) +{ + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return; + } + + PlaybackSettings pbs; + pbs.fillFromJobject(env, gPlaybackSettingsFields, settings); + ALOGV("setPlaybackSettings: %d:%f %d:%f %d:%u %d:%u", + pbs.speedSet, pbs.audioRate.mSpeed, + pbs.pitchSet, pbs.audioRate.mPitch, + pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode, + pbs.audioStretchModeSet, pbs.audioRate.mStretchMode); + + AudioPlaybackRate rate; + status_t err = mp->getPlaybackSettings(&rate); + if (err == OK) { + bool updatedRate = false; + if (pbs.speedSet) { + rate.mSpeed = pbs.audioRate.mSpeed; + updatedRate = true; + } + if (pbs.pitchSet) { + rate.mPitch = pbs.audioRate.mPitch; + updatedRate = true; + } + if (pbs.audioFallbackModeSet) { + rate.mFallbackMode = pbs.audioRate.mFallbackMode; + updatedRate = true; + } + if (pbs.audioStretchModeSet) { + rate.mStretchMode = pbs.audioRate.mStretchMode; + updatedRate = true; + } + if (updatedRate) { + err = mp->setPlaybackSettings(rate); + } + } + process_media_player_call( + env, thiz, err, + "java/lang/IllegalStateException", "unexpected error"); +} + +static jobject +android_media_MediaPlayer_getPlaybackSettings(JNIEnv *env, jobject thiz) +{ + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return NULL; + } + + PlaybackSettings pbs; + AudioPlaybackRate &audioRate = pbs.audioRate; + process_media_player_call( + env, thiz, mp->getPlaybackSettings(&audioRate), + "java/lang/IllegalStateException", "unexpected error"); + ALOGV("getPlaybackSettings: %f %f %d %d", + audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode); + + pbs.speedSet = true; + pbs.pitchSet = true; + pbs.audioFallbackModeSet = true; + pbs.audioStretchModeSet = true; + + return pbs.asJobject(env, gPlaybackSettingsFields); +} + +static void +android_media_MediaPlayer_setSyncSettings(JNIEnv *env, jobject thiz, jobject settings) +{ + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return; + } + + SyncSettings scs; + scs.fillFromJobject(env, gSyncSettingsFields, settings); + ALOGV("setSyncSettings: %d:%d %d:%d %d:%f %d:%f", + scs.syncSourceSet, scs.sync.mSource, + scs.audioAdjustModeSet, scs.sync.mAudioAdjustMode, + scs.toleranceSet, scs.sync.mTolerance, + scs.frameRateSet, scs.frameRate); + + AVSyncSettings avsync; + float videoFrameRate; + status_t err = mp->getSyncSettings(&avsync, &videoFrameRate); + if (err == OK) { + bool updatedSync = scs.frameRateSet; + if (scs.syncSourceSet) { + avsync.mSource = scs.sync.mSource; + updatedSync = true; + } + if (scs.audioAdjustModeSet) { + avsync.mAudioAdjustMode = scs.sync.mAudioAdjustMode; + updatedSync = true; + } + if (scs.toleranceSet) { + avsync.mTolerance = scs.sync.mTolerance; + updatedSync = true; + } + if (updatedSync) { + err = mp->setSyncSettings(avsync, scs.frameRateSet ? scs.frameRate : -1.f); + } + } + process_media_player_call( + env, thiz, err, + "java/lang/IllegalStateException", "unexpected error"); +} + +static jobject +android_media_MediaPlayer_getSyncSettings(JNIEnv *env, jobject thiz) +{ + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return NULL; + } + + SyncSettings scs; + scs.frameRate = -1.f; + process_media_player_call( + env, thiz, mp->getSyncSettings(&scs.sync, &scs.frameRate), + "java/lang/IllegalStateException", "unexpected error"); + + ALOGV("getSyncSettings: %d %d %f %f", + scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate); + + // sanity check settings + if (scs.sync.mSource >= AVSYNC_SOURCE_MAX + || scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX + || scs.sync.mTolerance < 0.f + || scs.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return NULL; + } + + scs.syncSourceSet = true; + scs.audioAdjustModeSet = true; + scs.toleranceSet = true; + scs.frameRateSet = scs.frameRate >= 0.f; + + return scs.asJobject(env, gSyncSettingsFields); +} + +static void android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec) { sp<MediaPlayer> mp = getMediaPlayer(env, thiz); @@ -667,6 +842,8 @@ android_media_MediaPlayer_native_init(JNIEnv *env) return; } + env->DeleteLocalRef(clazz); + clazz = env->FindClass("android/net/ProxyInfo"); if (clazz == NULL) { return; @@ -680,6 +857,11 @@ android_media_MediaPlayer_native_init(JNIEnv *env) fields.proxyConfigGetExclusionList = env->GetMethodID(clazz, "getExclusionListAsString", "()Ljava/lang/String;"); + + env->DeleteLocalRef(clazz); + + gPlaybackSettingsFields.init(env); + gSyncSettingsFields.init(env); } static void @@ -859,7 +1041,8 @@ static JNINativeMethod gMethods[] = { (void *)android_media_MediaPlayer_setDataSourceAndHeaders }, - {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD}, + {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD}, + {"_setDataSource", "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback }, {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface}, {"_prepare", "()V", (void *)android_media_MediaPlayer_prepare}, {"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync}, @@ -867,6 +1050,10 @@ static JNINativeMethod gMethods[] = { {"_stop", "()V", (void *)android_media_MediaPlayer_stop}, {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth}, {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight}, + {"setPlaybackSettings", "(Landroid/media/PlaybackSettings;)V", (void *)android_media_MediaPlayer_setPlaybackSettings}, + {"getPlaybackSettings", "()Landroid/media/PlaybackSettings;", (void *)android_media_MediaPlayer_getPlaybackSettings}, + {"setSyncSettings", "(Landroid/media/SyncSettings;)V", (void *)android_media_MediaPlayer_setSyncSettings}, + {"getSyncSettings", "()Landroid/media/SyncSettings;", (void *)android_media_MediaPlayer_getSyncSettings}, {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo}, {"_pause", "()V", (void *)android_media_MediaPlayer_pause}, {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying}, @@ -901,8 +1088,8 @@ static int register_android_media_MediaPlayer(JNIEnv *env) return AndroidRuntime::registerNativeMethods(env, "android/media/MediaPlayer", gMethods, NELEM(gMethods)); } - extern int register_android_media_ImageReader(JNIEnv *env); +extern int register_android_media_ImageWriter(JNIEnv *env); extern int register_android_media_Crypto(JNIEnv *env); extern int register_android_media_Drm(JNIEnv *env); extern int register_android_media_MediaCodec(JNIEnv *env); @@ -913,6 +1100,7 @@ extern int register_android_media_MediaMetadataRetriever(JNIEnv *env); extern int register_android_media_MediaMuxer(JNIEnv *env); extern int register_android_media_MediaRecorder(JNIEnv *env); extern int register_android_media_MediaScanner(JNIEnv *env); +extern int register_android_media_MediaSync(JNIEnv *env); extern int register_android_media_ResampleInputStream(JNIEnv *env); extern int register_android_media_MediaProfiles(JNIEnv *env); extern int register_android_media_AmrInputStream(JNIEnv *env); @@ -931,6 +1119,11 @@ jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) } assert(env != NULL); + if (register_android_media_ImageWriter(env) != JNI_OK) { + ALOGE("ERROR: ImageWriter native registration failed"); + goto bail; + } + if (register_android_media_ImageReader(env) < 0) { ALOGE("ERROR: ImageReader native registration failed"); goto bail; @@ -991,6 +1184,11 @@ jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) goto bail; } + if (register_android_media_MediaSync(env) < 0) { + ALOGE("ERROR: MediaSync native registration failed"); + goto bail; + } + if (register_android_media_MediaExtractor(env) < 0) { ALOGE("ERROR: MediaCodec native registration failed"); goto bail; |
