MediaPlayer: add setPlaybackRate JAVA API.
Bug: 19196501
Change-Id: I43daced7d9b53bcaca4e6a8d81ca729b32efc79f
diff --git a/api/current.txt b/api/current.txt
index 0046938..707999b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15404,6 +15404,7 @@
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
+ method public void setPlaybackRate(float, int);
method public void setScreenOnWhilePlaying(boolean);
method public void setSurface(android.view.Surface);
method public void setVideoScalingMode(int);
@@ -15429,6 +15430,7 @@
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
+ field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; // 0x0
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
}
diff --git a/api/system-current.txt b/api/system-current.txt
index d48fd0d..2ffc4e1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -16400,6 +16400,7 @@
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
+ method public void setPlaybackRate(float, int);
method public void setScreenOnWhilePlaying(boolean);
method public void setSurface(android.view.Surface);
method public void setVideoScalingMode(int);
@@ -16425,6 +16426,7 @@
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
+ field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; // 0x0
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
}
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.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 @@
* <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 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 @@
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 @@
}
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 @@
{"_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},