summaryrefslogtreecommitdiffstats
path: root/variablespeed
diff options
context:
space:
mode:
authorFlavio Lerda <flerda@google.com>2011-08-31 15:49:53 +0100
committerFlavio Lerda <flerda@google.com>2011-09-01 12:23:19 +0100
commitdc442b4d99512bf7c41ee5ceae6c93a3c3568b57 (patch)
treeeb6fdb06d27051aeb9b780f5b0074b537d49cb32 /variablespeed
parentaabf88787c8edb2cc207ad8e94e2045bf727c60d (diff)
downloadandroid_frameworks_ex-dc442b4d99512bf7c41ee5ceae6c93a3c3568b57.tar.gz
android_frameworks_ex-dc442b4d99512bf7c41ee5ceae6c93a3c3568b57.tar.bz2
android_frameworks_ex-dc442b4d99512bf7c41ee5ceae6c93a3c3568b57.zip
Allows selecting the audio stream used for playback.
Adds setAudioStreamType() to the MediaPlayerProxy interface and implements it in the variable speed player. Bug: 5240848 Change-Id: I1bb9fdbee7aa6113c5d5d5a8000e9794800fad9f
Diffstat (limited to 'variablespeed')
-rw-r--r--variablespeed/jni/jni_entry.cc4
-rw-r--r--variablespeed/jni/variablespeed.cc37
-rw-r--r--variablespeed/jni/variablespeed.h7
-rw-r--r--variablespeed/src/com/android/ex/variablespeed/EngineParameters.java19
-rw-r--r--variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java1
-rw-r--r--variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java5
-rw-r--r--variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java15
-rw-r--r--variablespeed/src/com/android/ex/variablespeed/VariableSpeedNative.java4
8 files changed, 77 insertions, 15 deletions
diff --git a/variablespeed/jni/jni_entry.cc b/variablespeed/jni/jni_entry.cc
index 0069956..368d230 100644
--- a/variablespeed/jni/jni_entry.cc
+++ b/variablespeed/jni/jni_entry.cc
@@ -79,11 +79,11 @@ JNI_METHOD(initializeEngine, void) (JNIEnv*, jclass,
int targetFrames, float windowDuration,
float windowOverlapDuration, size_t maxPlayBufferCount,
float initialRate, size_t decodeInitialSize, size_t decodeMaxSize,
- size_t startPositionMillis) {
+ size_t startPositionMillis, int audioStreamType) {
MethodLog _("initializeEngine");
AudioEngine::SetEngine(new AudioEngine(targetFrames,
windowDuration, windowOverlapDuration, maxPlayBufferCount, initialRate,
- decodeInitialSize, decodeMaxSize, startPositionMillis));
+ decodeInitialSize, decodeMaxSize, startPositionMillis, audioStreamType));
}
JNI_METHOD(shutdownEngine, void) (JNIEnv*, jclass) {
diff --git a/variablespeed/jni/variablespeed.cc b/variablespeed/jni/variablespeed.cc
index e29846e..6162242 100644
--- a/variablespeed/jni/variablespeed.cc
+++ b/variablespeed/jni/variablespeed.cc
@@ -194,6 +194,23 @@ static void DecodingEventCb(SLPlayItf caller, void*, SLuint32 event) {
// ****************************************************************************
// Static utility methods.
+// Set the audio stream type for the player.
+//
+// Must be called before it is realized.
+//
+// The caller must have requested the SL_IID_ANDROIDCONFIGURATION interface when
+// creating the player.
+static void setAudioStreamType(SLObjectItf audioPlayer, SLint32 audioStreamType) {
+ SLAndroidConfigurationItf playerConfig;
+ OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDCONFIGURATION, &playerConfig);
+ // The STREAM_XXX constants defined by android.media.AudioManager match the
+ // corresponding SL_ANDROID_STREAM_XXX constants defined by
+ // include/SLES/OpenSLES_AndroidConfiguration.h, so we can just pass the
+ // value across.
+ OpenSL(playerConfig, SetConfiguration, SL_ANDROID_KEY_STREAM_TYPE,
+ &audioStreamType, sizeof(audioStreamType));
+}
+
// Must be called with callbackLock_ held.
static void ReadSampleRateAndChannelCount(CallbackContext *pContext,
SLuint32 *sampleRateOut, SLuint32 *channelsOut) {
@@ -254,7 +271,8 @@ static void RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
AudioEngine::AudioEngine(size_t targetFrames, float windowDuration,
float windowOverlapDuration, size_t maxPlayBufferCount, float initialRate,
- size_t decodeInitialSize, size_t decodeMaxSize, size_t startPositionMillis)
+ size_t decodeInitialSize, size_t decodeMaxSize, size_t startPositionMillis,
+ int audioStreamType)
: decodeBuffer_(decodeInitialSize, decodeMaxSize),
playingBuffers_(), freeBuffers_(), timeScaler_(NULL),
floatBuffer_(NULL), injectBuffer_(NULL),
@@ -264,6 +282,7 @@ AudioEngine::AudioEngine(size_t targetFrames, float windowDuration,
windowOverlapDuration_(windowOverlapDuration),
maxPlayBufferCount_(maxPlayBufferCount), initialRate_(initialRate),
startPositionMillis_(startPositionMillis),
+ audioStreamType_(audioStreamType),
totalDurationMs_(0), decoderCurrentPosition_(0), startRequested_(false),
stopRequested_(false), finishedDecoding_(false) {
}
@@ -534,7 +553,7 @@ SLuint32 AudioEngine::GetChannelCount() {
}
static void CreateAndRealizeAudioPlayer(SLuint32 slSampleRate,
- size_t channelCount, SLuint32 slChannels, SLObjectItf &outputMix,
+ size_t channelCount, SLuint32 slChannels, SLint32 audioStreamType, SLObjectItf &outputMix,
SLObjectItf &audioPlayer, SLEngineItf &engineInterface) {
// Define the source and sink for the audio player: comes from a buffer queue
// and goes to the output mix.
@@ -549,12 +568,13 @@ static void CreateAndRealizeAudioPlayer(SLuint32 slSampleRate,
// Create the audio player, which will play from the buffer queue and send to
// the output mix.
- const size_t playerInterfaceCount = 1;
+ const size_t playerInterfaceCount = 2;
const SLInterfaceID iids[playerInterfaceCount] = {
- SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
+ SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
const SLboolean reqs[playerInterfaceCount] = { SL_BOOLEAN_TRUE };
OpenSL(engineInterface, CreateAudioPlayer, &audioPlayer, &playingSrc,
&audioSnk, playerInterfaceCount, iids, reqs);
+ setAudioStreamType(audioPlayer, audioStreamType);
OpenSL(audioPlayer, Realize, SL_BOOLEAN_FALSE);
}
@@ -582,16 +602,18 @@ bool AudioEngine::PlayFromThisSource(const SLDataSource& audioSrc) {
SLDataSink decDest = { &decBuffQueue, &pcm };
// Create the decoder with the given source and sink.
- const size_t decoderInterfaceCount = 4;
+ const size_t decoderInterfaceCount = 5;
SLObjectItf decoder;
const SLInterfaceID decodePlayerInterfaces[decoderInterfaceCount] = {
SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_PREFETCHSTATUS, SL_IID_SEEK,
- SL_IID_METADATAEXTRACTION };
+ SL_IID_METADATAEXTRACTION, SL_IID_ANDROIDCONFIGURATION };
const SLboolean decodePlayerRequired[decoderInterfaceCount] = {
SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
SLDataSource sourceCopy(audioSrc);
OpenSL(engineInterface, CreateAudioPlayer, &decoder, &sourceCopy, &decDest,
decoderInterfaceCount, decodePlayerInterfaces, decodePlayerRequired);
+ // Not sure if this is necessary, but just in case.
+ setAudioStreamType(decoder, audioStreamType_);
OpenSL(decoder, Realize, SL_BOOLEAN_FALSE);
// Get the play interface from the decoder, and register event callbacks.
@@ -653,7 +675,8 @@ bool AudioEngine::PlayFromThisSource(const SLDataSource& audioSrc) {
OpenSL(engineInterface, CreateOutputMix, &outputMix, 0, NULL, NULL);
OpenSL(outputMix, Realize, SL_BOOLEAN_FALSE);
CreateAndRealizeAudioPlayer(GetSLSampleRate(), GetChannelCount(),
- GetSLChannels(), outputMix, audioPlayer, engineInterface);
+ GetSLChannels(), audioStreamType_, outputMix, audioPlayer,
+ engineInterface);
OpenSL(audioPlayer, GetInterface, SL_IID_PLAY, &audioPlayerPlay);
OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&audioPlayerQueue);
diff --git a/variablespeed/jni/variablespeed.h b/variablespeed/jni/variablespeed.h
index 05b27a5..07cba0f 100644
--- a/variablespeed/jni/variablespeed.h
+++ b/variablespeed/jni/variablespeed.h
@@ -45,7 +45,7 @@ class AudioEngine {
AudioEngine(size_t targetFrames, float windowDuration,
float windowOverlapDuration, size_t maxPlayBufferCount,
float initialRate, size_t decodeInitialSize, size_t decodeMaxSize,
- size_t startPositionMillis);
+ size_t startPositionMillis, int audioStreamType);
virtual ~AudioEngine();
bool PlayUri(const char* uri);
@@ -123,6 +123,11 @@ class AudioEngine {
size_t maxPlayBufferCount_;
float initialRate_;
size_t startPositionMillis_;
+ // The type of audio stream as defined by the STREAM_XXX constants in
+ // android.media.AudioManager. These constant values actually match the
+ // corresponding SL_ANDROID_STREAM_XXX constants defined by
+ // include/SLES/OpenSLES_AndroidConfiguration.h
+ int audioStreamType_;
// The prefetch callback signal, for letting the prefetch callback method
// indicate when it is done.
diff --git a/variablespeed/src/com/android/ex/variablespeed/EngineParameters.java b/variablespeed/src/com/android/ex/variablespeed/EngineParameters.java
index e57e9f9..1cc4012 100644
--- a/variablespeed/src/com/android/ex/variablespeed/EngineParameters.java
+++ b/variablespeed/src/com/android/ex/variablespeed/EngineParameters.java
@@ -16,6 +16,8 @@
package com.android.ex.variablespeed;
+import android.media.AudioManager;
+
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
@@ -35,6 +37,7 @@ import javax.annotation.concurrent.NotThreadSafe;
private final int mDecodeBufferInitialSize;
private final int mDecodeBufferMaxSize;
private final int mStartPositionMillis;
+ private final int mAudioStreamType;
public int getTargetFrames() {
return mTargetFrames;
@@ -68,9 +71,13 @@ import javax.annotation.concurrent.NotThreadSafe;
return mStartPositionMillis;
}
+ public int getAudioStreamType() {
+ return mAudioStreamType;
+ }
+
private EngineParameters(int targetFrames, int maxPlayBufferCount, float windowDuration,
float windowOverlapDuration, float initialRate, int decodeBufferInitialSize,
- int decodeBufferMaxSize, int startPositionMillis) {
+ int decodeBufferMaxSize, int startPositionMillis, int audioStreamType) {
mTargetFrames = targetFrames;
mMaxPlayBufferCount = maxPlayBufferCount;
mWindowDuration = windowDuration;
@@ -79,6 +86,7 @@ import javax.annotation.concurrent.NotThreadSafe;
mDecodeBufferInitialSize = decodeBufferInitialSize;
mDecodeBufferMaxSize = decodeBufferMaxSize;
mStartPositionMillis = startPositionMillis;
+ mAudioStreamType = audioStreamType;
}
/**
@@ -98,11 +106,13 @@ import javax.annotation.concurrent.NotThreadSafe;
private int mDecodeBufferInitialSize = 5 * 1024;
private int mDecodeBufferMaxSize = 20 * 1024;
private int mStartPositionMillis = 0;
+ private int mAudioStreamType = AudioManager.STREAM_MUSIC;
public EngineParameters build() {
return new EngineParameters(mTargetFrames, mMaxPlayBufferCount,
mWindowDuration, mWindowOverlapDuration, mInitialRate,
- mDecodeBufferInitialSize, mDecodeBufferMaxSize, mStartPositionMillis);
+ mDecodeBufferInitialSize, mDecodeBufferMaxSize, mStartPositionMillis,
+ mAudioStreamType);
}
public Builder maxPlayBufferCount(int maxPlayBufferCount) {
@@ -139,5 +149,10 @@ import javax.annotation.concurrent.NotThreadSafe;
mStartPositionMillis = startPositionMillis;
return this;
}
+
+ public Builder audioStreamType(int audioStreamType) {
+ mAudioStreamType = audioStreamType;
+ return this;
+ }
}
}
diff --git a/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java b/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java
index 76492c1..8489dc1 100644
--- a/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java
+++ b/variablespeed/src/com/android/ex/variablespeed/MediaPlayerProxy.java
@@ -45,4 +45,5 @@ public interface MediaPlayerProxy {
boolean isPlaying();
int getCurrentPosition();
void pause();
+ void setAudioStreamType(int streamType);
}
diff --git a/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java b/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java
index 035bc0e..17692f7 100644
--- a/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java
+++ b/variablespeed/src/com/android/ex/variablespeed/SingleThreadedMediaPlayerProxy.java
@@ -102,4 +102,9 @@ public class SingleThreadedMediaPlayerProxy implements MediaPlayerProxy {
public synchronized void pause() {
mDelegate.pause();
}
+
+ @Override
+ public void setAudioStreamType(int streamType) {
+ mDelegate.setAudioStreamType(streamType);
+ }
}
diff --git a/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java b/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java
index 1f86a95..5c93d26 100644
--- a/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java
+++ b/variablespeed/src/com/android/ex/variablespeed/VariableSpeed.java
@@ -64,6 +64,7 @@ public class VariableSpeed implements MediaPlayerProxy {
@GuardedBy("lock") private float mCurrentPlaybackRate = 1.0f;
@GuardedBy("lock") private int mDuration;
@GuardedBy("lock") private MediaPlayer.OnCompletionListener mCompletionListener;
+ @GuardedBy("lock") private int mAudioStreamType;
private VariableSpeed(Executor executor) throws UnsupportedOperationException {
Preconditions.checkNotNull(executor);
@@ -213,15 +214,18 @@ public class VariableSpeed implements MediaPlayerProxy {
@Override
public void prepare() throws IOException {
MediaPlayerDataSource dataSource;
+ int audioStreamType;
synchronized (lock) {
check(!mHasBeenReleased, "has been released, reset before use");
check(mDataSource != null, "must setDataSource before you prepare");
check(!mIsPrepared, "cannot prepare more than once");
mIsPrepared = true;
dataSource = mDataSource;
+ audioStreamType = mAudioStreamType;
}
// NYI This should become another executable that we can wait on.
MediaPlayer mediaPlayer = new MediaPlayer();
+ mediaPlayer.setAudioStreamType(audioStreamType);
dataSource.setAsSourceFor(mediaPlayer);
mediaPlayer.prepare();
synchronized (lock) {
@@ -286,7 +290,9 @@ public class VariableSpeed implements MediaPlayerProxy {
mHasStartedPlayback = true;
EngineParameters engineParameters = new EngineParameters.Builder()
.initialRate(mCurrentPlaybackRate)
- .startPositionMillis(mStartPosition).build();
+ .startPositionMillis(mStartPosition)
+ .audioStreamType(mAudioStreamType)
+ .build();
VariableSpeedNative.initializeEngine(engineParameters);
VariableSpeedNative.startPlayback();
mEngineInitializedLatch.countDown();
@@ -387,4 +393,11 @@ public class VariableSpeed implements MediaPlayerProxy {
throw new IllegalArgumentException(argumentName + " must not be null");
}
}
+
+ @Override
+ public void setAudioStreamType(int audioStreamType) {
+ synchronized (lock) {
+ mAudioStreamType = audioStreamType;
+ }
+ }
}
diff --git a/variablespeed/src/com/android/ex/variablespeed/VariableSpeedNative.java b/variablespeed/src/com/android/ex/variablespeed/VariableSpeedNative.java
index ed7e80b..07195db 100644
--- a/variablespeed/src/com/android/ex/variablespeed/VariableSpeedNative.java
+++ b/variablespeed/src/com/android/ex/variablespeed/VariableSpeedNative.java
@@ -82,11 +82,11 @@ import java.lang.reflect.Field;
params.getWindowDuration(), params.getWindowOverlapDuration(),
params.getMaxPlayBufferCount(), params.getInitialRate(),
params.getDecodeBufferInitialSize(), params.getDecodeBufferMaxSize(),
- params.getStartPositionMillis());
+ params.getStartPositionMillis(), params.getAudioStreamType());
}
private static native void initializeEngine(int targetFrames,
float windowDuration, float windowOverlapDuration, int maxPlayBufferCount,
float initialRate, int decodeBufferInitialSize, int decodeBufferMaxSize,
- int startPositionMillis);
+ int startPositionMillis, int audioStreamType);
}