diff options
author | Wei Jia <wjia@google.com> | 2015-02-09 16:05:53 -0800 |
---|---|---|
committer | Wei Jia <wjia@google.com> | 2015-03-03 14:43:55 -0800 |
commit | d93fcf400222e4d8b27a1025f6aa307839239b9f (patch) | |
tree | 2ee5493da351f10720df1885972fa4035f9ffca4 /media | |
parent | 4bd091414a8eab104875d0115347307411e27ebd (diff) | |
download | frameworks_base-d93fcf400222e4d8b27a1025f6aa307839239b9f.zip frameworks_base-d93fcf400222e4d8b27a1025f6aa307839239b9f.tar.gz frameworks_base-d93fcf400222e4d8b27a1025f6aa307839239b9f.tar.bz2 |
MediaPlayer: add setPlaybackRate JAVA API.
Bug: 19196501
Change-Id: I43daced7d9b53bcaca4e6a8d81ca729b32efc79f
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/MediaPlayer.java | 69 | ||||
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 13 |
2 files changed, 82 insertions, 0 deletions
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index d61610d..d77fcd8 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -16,6 +16,7 @@ package android.media; +import android.annotation.IntDef; import android.app.ActivityThread; import android.app.AppOpsManager; import android.content.ContentResolver; @@ -61,6 +62,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.Runnable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.InetSocketAddress; import java.util.Map; import java.util.Scanner; @@ -472,6 +475,11 @@ import java.lang.ref.WeakReference; * <td>{} </p></td> * <td>This method can be called in any state and calling it does not change * the object state. </p></td></tr> + * <tr><td>setPlaybackRate</p></td> + * <td>any </p></td> + * <td>{} </p></td> + * <td>This method can be called in any state and calling it does not change + * the object state. </p></td></tr> * <tr><td>setVolume </p></td> * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused, * PlaybackCompleted}</p></td> @@ -1319,6 +1327,59 @@ public class MediaPlayer implements SubtitleController.Listener public native boolean isPlaying(); /** + * Specifies resampling as audio mode for variable rate playback, i.e., + * resample the waveform based on the requested playback rate to get + * a new waveform, and play back the new waveform at the original sampling + * frequency. + * When rate is larger than 1.0, pitch becomes higher. + * When rate is smaller than 1.0, pitch becomes lower. + */ + public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; + + /** + * Specifies time stretching as audio mode for variable rate playback. + * Time stretching changes the duration of the audio samples without + * affecting its pitch. + * FIXME: implement time strectching. + * @hide + */ + public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; + + /** @hide */ + @IntDef( + value = { + PLAYBACK_RATE_AUDIO_MODE_RESAMPLE, + PLAYBACK_RATE_AUDIO_MODE_STRETCH }) + @Retention(RetentionPolicy.SOURCE) + public @interface PlaybackRateAudioMode {} + + /** + * Sets playback rate and audio mode. + * + * <p> The supported audio modes are: + * <ul> + * <li> {@link #PLAYBACK_RATE_AUDIO_MODE_RESAMPLE} + * </ul> + * + * @param rate the ratio between desired playback rate and normal one. + * @param audioMode audio playback mode. Must be one of the supported + * audio modes. + * + * @throws IllegalStateException if the internal player engine has not been + * initialized. + * @throws IllegalArgumentException if audioMode is not supported. + */ + public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) { + if (!isAudioPlaybackModeSupported(audioMode)) { + final String msg = "Audio playback mode " + audioMode + " is not supported"; + throw new IllegalArgumentException(msg); + } + _setPlaybackRate(rate); + } + + private native void _setPlaybackRate(float rate) throws IllegalStateException; + + /** * Seeks to specified time position. * * @param msec the offset in milliseconds from the start to seek to @@ -3078,6 +3139,14 @@ public class MediaPlayer implements SubtitleController.Listener mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); } + /* + * Test whether a given audio playback mode is supported. + * TODO query supported AudioPlaybackMode from player. + */ + private boolean isAudioPlaybackModeSupported(int mode) { + return (mode == PLAYBACK_RATE_AUDIO_MODE_RESAMPLE); + } + /** @hide */ static class TimeProvider implements MediaPlayer.OnSeekCompleteListener, MediaTimeProvider { diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 820de5b..55643f7 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -402,6 +402,18 @@ android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz) } static void +android_media_MediaPlayer_setPlaybackRate(JNIEnv *env, jobject thiz, jfloat rate) +{ + sp<MediaPlayer> mp = getMediaPlayer(env, thiz); + if (mp == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", NULL); + return; + } + ALOGV("setPlaybackRate: %f", rate); + process_media_player_call(env, thiz, mp->setPlaybackRate(rate), NULL, NULL); +} + +static void android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec) { sp<MediaPlayer> mp = getMediaPlayer(env, thiz); @@ -867,6 +879,7 @@ static JNINativeMethod gMethods[] = { {"_stop", "()V", (void *)android_media_MediaPlayer_stop}, {"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth}, {"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight}, + {"_setPlaybackRate", "(F)V", (void *)android_media_MediaPlayer_setPlaybackRate}, {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo}, {"_pause", "()V", (void *)android_media_MediaPlayer_pause}, {"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying}, |