summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorWei Jia <wjia@google.com>2015-02-09 16:05:53 -0800
committerWei Jia <wjia@google.com>2015-03-03 14:43:55 -0800
commitd93fcf400222e4d8b27a1025f6aa307839239b9f (patch)
tree2ee5493da351f10720df1885972fa4035f9ffca4 /media
parent4bd091414a8eab104875d0115347307411e27ebd (diff)
downloadframeworks_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.java69
-rw-r--r--media/jni/android_media_MediaPlayer.cpp13
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},