summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_media_AudioTrack.cpp33
-rw-r--r--include/media/IMediaPlayerService.h7
-rw-r--r--include/media/mediaplayer.h3
-rw-r--r--media/java/android/media/AudioTrack.java70
-rw-r--r--media/java/android/media/MediaPlayer.java44
-rw-r--r--media/jni/android_media_MediaPlayer.cpp27
-rw-r--r--media/libmedia/AudioTrack.cpp6
-rw-r--r--media/libmedia/IMediaPlayerService.cpp19
-rw-r--r--media/libmedia/mediaplayer.cpp26
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp42
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h13
11 files changed, 252 insertions, 38 deletions
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 65c0435..ce43e73 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -166,7 +166,7 @@ static void audioCallback(int event, void* user, void *info) {
static int
android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint streamType, jint sampleRateInHertz, jint channels,
- jint audioFormat, jint buffSizeInBytes, jint memoryMode)
+ jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession)
{
LOGV("sampleRate=%d, audioFormat(from Java)=%d, channels=%x, buffSize=%d",
sampleRateInHertz, audioFormat, channels, buffSizeInBytes);
@@ -253,6 +253,20 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
lpJniStorage->mStreamType = atStreamType;
+ jint* nSession = NULL;
+ if (jSession) {
+ nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
+ if (nSession == NULL) {
+ LOGE("Error creating AudioTrack: Error retrieving session id pointer");
+ delete lpJniStorage;
+ return AUDIOTRACK_ERROR;
+ }
+ } else {
+ LOGE("Error creating AudioTrack: invalid session ID pointer");
+ delete lpJniStorage;
+ return AUDIOTRACK_ERROR;
+ }
+
// create the native AudioTrack object
AudioTrack* lpTrack = new AudioTrack();
if (lpTrack == NULL) {
@@ -273,7 +287,8 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
0,// shared mem
- true);// thread can call Java
+ true,// thread can call Java
+ nSession[0]);// audio session ID
} else if (memoryMode == javaAudioTrackFields.MODE_STATIC) {
// AudioTrack is using shared memory
@@ -293,7 +308,8 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
lpJniStorage->mMemBase,// shared mem
- true);// thread can call Java
+ true,// thread can call Java
+ nSession[0]);// audio session ID
}
if (lpTrack->initCheck() != NO_ERROR) {
@@ -301,6 +317,12 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
goto native_init_failure;
}
+ // read the audio session ID back from AudioTrack in case we create a new session
+ nSession[0] = lpTrack->getSessionId();
+
+ env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+ nSession = NULL;
+
// save our newly created C++ AudioTrack in the "nativeTrackInJavaObj" field
// of the Java object (in mNativeTrackInJavaObj)
env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, (int)lpTrack);
@@ -317,6 +339,9 @@ native_init_failure:
env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, 0);
native_track_failure:
+ if (nSession != NULL) {
+ env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+ }
env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_class);
env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_ref);
delete lpJniStorage;
@@ -785,7 +810,7 @@ static JNINativeMethod gMethods[] = {
{"native_stop", "()V", (void *)android_media_AudioTrack_stop},
{"native_pause", "()V", (void *)android_media_AudioTrack_pause},
{"native_flush", "()V", (void *)android_media_AudioTrack_flush},
- {"native_setup", "(Ljava/lang/Object;IIIIII)I",
+ {"native_setup", "(Ljava/lang/Object;IIIIII[I)I",
(void *)android_media_AudioTrack_native_setup},
{"native_finalize", "()V", (void *)android_media_AudioTrack_native_finalize},
{"native_release", "()V", (void *)android_media_AudioTrack_native_release},
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 31c0991..e892875 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -40,8 +40,11 @@ public:
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers = NULL) = 0;
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
+ const char* url, const KeyedVector<String8, String8> *headers = NULL,
+ int audioSessionId = 0) = 0;
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
+ int fd, int64_t offset, int64_t length, int audioSessionId) = 0;
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IOMX> getOMX() = 0;
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index dc783ce..62a4e50 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -172,6 +172,8 @@ public:
status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
status_t suspend();
status_t resume();
+ status_t setAudioSessionId(int sessionId);
+ int getAudioSessionId();
private:
void clear_l();
status_t seekTo_l(int msec);
@@ -198,6 +200,7 @@ private:
float mRightVolume;
int mVideoWidth;
int mVideoHeight;
+ int mAudioSessionId;
};
}; // namespace android
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1e8d72f..079c41f 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -210,6 +210,10 @@ public class AudioTrack
* @see AudioFormat#ENCODING_PCM_16BIT
*/
private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+ /**
+ * Audio session ID
+ */
+ private int mSessionId = 0;
//--------------------------------
@@ -258,6 +262,48 @@ public class AudioTrack
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode)
throws IllegalArgumentException {
+ this(streamType, sampleRateInHz, channelConfig, audioFormat,
+ bufferSizeInBytes, mode, 0);
+ }
+
+ /**
+ * Class constructor with audio session. Use this constructor when the AudioTrack must be
+ * attached to a particular audio session. The primary use of the audio session ID is to
+ * associate audio effects to a particular instance of AudioTrack: if an audio session ID
+ * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
+ * and media players in the same session and not to the output mix.
+ * When an AudioTrack is created without specifying a session, it will create its own session
+ * which can be retreived by calling the {@link #getAudioSessionId()} method.
+ * If a session ID is provided, this AudioTrack will share effects attached to this session
+ * with all other media players or audio tracks in the same session.
+ * @param streamType the type of the audio stream. See
+ * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+ * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and
+ * {@link AudioManager#STREAM_ALARM}
+ * @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but
+ * not limited to) 44100, 22050 and 11025.
+ * @param channelConfig describes the configuration of the audio channels.
+ * See {@link AudioFormat#CHANNEL_OUT_MONO} and
+ * {@link AudioFormat#CHANNEL_OUT_STEREO}
+ * @param audioFormat the format in which the audio data is represented.
+ * See {@link AudioFormat#ENCODING_PCM_16BIT} and
+ * {@link AudioFormat#ENCODING_PCM_8BIT}
+ * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
+ * from for playback. If using the AudioTrack in streaming mode, you can write data into
+ * this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
+ * this is the maximum size of the sound that will be played for this instance.
+ * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
+ * for the successful creation of an AudioTrack instance in streaming mode. Using values
+ * smaller than getMinBufferSize() will result in an initialization failure.
+ * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
+ * @param sessionId Id of audio session the AudioTrack must be attached to
+ * @throws java.lang.IllegalArgumentException
+ // FIXME: unhide.
+ * @hide
+ */
+ public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
+ int bufferSizeInBytes, int mode, int sessionId)
+ throws IllegalArgumentException {
mState = STATE_UNINITIALIZED;
// remember which looper is associated with the AudioTrack instanciation
@@ -269,15 +315,23 @@ public class AudioTrack
audioBuffSizeCheck(bufferSizeInBytes);
+ if (sessionId < 0) {
+ throw (new IllegalArgumentException("Invalid audio session ID: "+sessionId));
+ }
+
+ int[] session = new int[1];
+ session[0] = sessionId;
// native initialization
int initResult = native_setup(new WeakReference<AudioTrack>(this),
mStreamType, mSampleRate, mChannels, mAudioFormat,
- mNativeBufferSizeInBytes, mDataLoadMode);
+ mNativeBufferSizeInBytes, mDataLoadMode, session);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing AudioTrack.");
return; // with mState == STATE_UNINITIALIZED
}
+ mSessionId = session[0];
+
if (mDataLoadMode == MODE_STATIC) {
mState = STATE_NO_STATIC_DATA;
} else {
@@ -590,6 +644,17 @@ public class AudioTrack
}
}
+ /**
+ * Returns the audio session ID.
+ *
+ * @return the ID of the audio session this AudioTrack belongs to.
+ // FIXME: unhide.
+ // FIXME: link to AudioEffect class when public.
+ * @hide
+ */
+ public int getAudioSessionId() {
+ return mSessionId;
+ }
//--------------------------------------------------------------------------
// Initialization / configuration
@@ -1012,7 +1077,7 @@ public class AudioTrack
private native final int native_setup(Object audiotrack_this,
int streamType, int sampleRate, int nbChannels, int audioFormat,
- int buffSizeInBytes, int mode);
+ int buffSizeInBytes, int mode, int[] sessionId);
private native final void native_finalize();
@@ -1056,6 +1121,7 @@ public class AudioTrack
static private native final int native_get_min_buff_size(
int sampleRateInHz, int channelConfig, int audioFormat);
+ private native final int native_get_session_id();
//---------------------------------------------------------
// Utility methods
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index c9d4650..8caa07a 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -423,6 +423,18 @@ import java.lang.ref.WeakReference;
* <td>Successful invoke of this method in a valid state transfers the
* object to the <em>Stopped</em> state. Calling this method in an
* invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>setAudioSessionId </p></td>
+ * <td>{Idle} </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ * Error} </p></td>
+ * <td>This method must be called in idle state as the audio session ID must be known before
+ * calling setDataSource. Calling it does not change the object state. </p></td></tr>
+ * <tr><td>getAudioSessionId </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>
+ *
* </table>
*
* <a name="Permissions"></a>
@@ -1159,6 +1171,38 @@ public class MediaPlayer
public native Bitmap getFrameAt(int msec) throws IllegalStateException;
/**
+ * Sets the audio session ID.
+ *
+ * @param sessionId: the audio session ID.
+ * The audio session ID is a system wide unique identifier for the audio stream played by
+ * this MediaPlayer instance.
+ * The primary use of the audio session ID is to associate audio effects to a particular
+ * instance of MediaPlayer: if an audio session ID is provided when creating an audio effect,
+ * this effect will be applied only to the audio content of media players within the same
+ * audio session and not to the output mix.
+ * When created, a MediaPlayer instance automatically generates its own audio session ID.
+ * However, it is possible to force this player to be part of an already existing audio session
+ * by calling this method.
+ * This method must be called before one of the overloaded <code> setDataSource </code> methods.
+ * @throws IllegalStateException if it is called in an invalid state
+ *
+ // FIXME: unhide.
+ // FIXME: link to AudioEffect class when public.
+ * @hide
+ */
+ public native void setAudioSessionId(int sessionId) throws IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Returns the audio session ID.
+ *
+ * @return the audio session ID. {@see #setAudioSessionId(int)}.
+ * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer was contructed.
+ // FIXME: unhide.
+ * @hide
+ */
+ public native int getAudioSessionId();
+
+ /**
* @param request Parcel destinated to the media player. The
* Interface token must be set to the IMediaPlayer
* one to be routed correctly through the system.
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 60ff264..c5250d7 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -292,7 +292,7 @@ static void setVideoSurface(const sp<MediaPlayer>& mp, JNIEnv *env, jobject thiz
if (surface != NULL) {
const sp<Surface> native_surface = get_surface(env, surface);
LOGV("prepare: surface=%p (id=%d)",
- native_surface.get(), native_surface->ID());
+ native_surface.get(), native_surface->getIdentity());
mp->setVideoSurface(native_surface);
}
}
@@ -332,7 +332,7 @@ android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
if (surface != NULL) {
const sp<Surface> native_surface = get_surface(env, surface);
LOGV("prepareAsync: surface=%p (id=%d)",
- native_surface.get(), native_surface->ID());
+ native_surface.get(), native_surface->getIdentity());
mp->setVideoSurface(native_surface);
}
process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
@@ -705,6 +705,27 @@ android_media_MediaPlayer_native_suspend_resume(
return isSuspend ? mp->suspend() : mp->resume();
}
+static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env, jobject thiz, jint sessionId) {
+ LOGV("set_session_id(): %d", sessionId);
+ sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+ if (mp == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+ process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
+}
+
+static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject thiz) {
+ LOGV("get_session_id()");
+ sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+ if (mp == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return 0;
+ }
+
+ return mp->getAudioSessionId();
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -738,6 +759,8 @@ static JNINativeMethod gMethods[] = {
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
{"snoop", "([SI)I", (void *)android_media_MediaPlayer_snoop},
{"native_suspend_resume", "(Z)I", (void *)android_media_MediaPlayer_native_suspend_resume},
+ {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
+ {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
};
static const char* const kClassPathName = "android/media/MediaPlayer";
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 2118f8f..0f2093a 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -92,7 +92,8 @@ AudioTrack::AudioTrack(
: mStatus(NO_INIT)
{
mStatus = set(streamType, sampleRate, format, channels,
- frameCount, flags, cbf, user, notificationFrames, 0);
+ frameCount, flags, cbf, user, notificationFrames,
+ 0, false, sessionId);
}
AudioTrack::AudioTrack(
@@ -109,7 +110,8 @@ AudioTrack::AudioTrack(
: mStatus(NO_INIT)
{
mStatus = set(streamType, sampleRate, format, channels,
- 0, flags, cbf, user, notificationFrames, sharedBuffer);
+ 0, flags, cbf, user, notificationFrames,
+ sharedBuffer, false, sessionId);
}
AudioTrack::~AudioTrack()
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 71c5f86..1ae222e 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -58,7 +58,7 @@ public:
virtual sp<IMediaPlayer> create(
pid_t pid, const sp<IMediaPlayerClient>& client,
- const char* url, const KeyedVector<String8, String8> *headers) {
+ const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
data.writeInt32(pid);
@@ -75,8 +75,10 @@ public:
data.writeString8(headers->valueAt(i));
}
}
+ data.writeInt32(audioSessionId);
remote()->transact(CREATE_URL, data, &reply);
+
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
}
@@ -89,7 +91,8 @@ public:
return interface_cast<IMediaRecorder>(reply.readStrongBinder());
}
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length)
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd,
+ int64_t offset, int64_t length, int audioSessionId)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
@@ -98,8 +101,11 @@ public:
data.writeFileDescriptor(fd);
data.writeInt64(offset);
data.writeInt64(length);
+ data.writeInt32(audioSessionId);
+
remote()->transact(CREATE_FD, data, &reply);
- return interface_cast<IMediaPlayer>(reply.readStrongBinder());
+
+ return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
}
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
@@ -166,9 +172,10 @@ status_t BnMediaPlayerService::onTransact(
String8 value = data.readString8();
headers.add(key, value);
}
+ int audioSessionId = data.readInt32();
sp<IMediaPlayer> player = create(
- pid, client, url, numHeaders > 0 ? &headers : NULL);
+ pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId);
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
@@ -180,7 +187,9 @@ status_t BnMediaPlayerService::onTransact(
int fd = dup(data.readFileDescriptor());
int64_t offset = data.readInt64();
int64_t length = data.readInt64();
- sp<IMediaPlayer> player = create(pid, client, fd, offset, length);
+ int audioSessionId = data.readInt32();
+
+ sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId);
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index c6bbbcc..d5a3c13 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -55,6 +55,7 @@ MediaPlayer::MediaPlayer()
mLeftVolume = mRightVolume = 1.0;
mVideoWidth = mVideoHeight = 0;
mLockThreadId = 0;
+ mAudioSessionId = AudioSystem::newAudioSessionId();
}
MediaPlayer::~MediaPlayer()
@@ -137,7 +138,7 @@ status_t MediaPlayer::setDataSource(
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(
- service->create(getpid(), this, url, headers));
+ service->create(getpid(), this, url, headers, mAudioSessionId));
err = setDataSource(player);
}
}
@@ -150,7 +151,7 @@ status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
status_t err = UNKNOWN_ERROR;
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
- sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length));
+ sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length, mAudioSessionId));
err = setDataSource(player);
}
return err;
@@ -501,6 +502,27 @@ status_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
return OK;
}
+status_t MediaPlayer::setAudioSessionId(int sessionId)
+{
+ LOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
+ Mutex::Autolock _l(mLock);
+ if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
+ LOGE("setAudioSessionId called in state %d", mCurrentState);
+ return INVALID_OPERATION;
+ }
+ if (sessionId < 0) {
+ return BAD_VALUE;
+ }
+ mAudioSessionId = sessionId;
+ return NO_ERROR;
+}
+
+int MediaPlayer::getAudioSessionId()
+{
+ Mutex::Autolock _l(mLock);
+ return mAudioSessionId;
+}
+
void MediaPlayer::notify(int msg, int ext1, int ext2)
{
LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index d7ca635..d45c17b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -252,11 +252,12 @@ sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pi
sp<IMediaPlayer> MediaPlayerService::create(
pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
- const KeyedVector<String8, String8> *headers)
+ const KeyedVector<String8, String8> *headers, int audioSessionId)
{
int32_t connId = android_atomic_inc(&mNextConnId);
- sp<Client> c = new Client(this, pid, connId, client);
- LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
+ sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+ LOGV("Create new client(%d) from pid %d, url=%s, connId=%d, audioSessionId=%d",
+ connId, pid, url, connId, audioSessionId);
if (NO_ERROR != c->setDataSource(url, headers))
{
c.clear();
@@ -269,12 +270,12 @@ sp<IMediaPlayer> MediaPlayerService::create(
}
sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
- int fd, int64_t offset, int64_t length)
+ int fd, int64_t offset, int64_t length, int audioSessionId)
{
int32_t connId = android_atomic_inc(&mNextConnId);
- sp<Client> c = new Client(this, pid, connId, client);
- LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld",
- connId, pid, fd, offset, length);
+ sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+ LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld, audioSessionId=%d",
+ connId, pid, fd, offset, length, audioSessionId);
if (NO_ERROR != c->setDataSource(fd, offset, length)) {
c.clear();
} else {
@@ -609,7 +610,7 @@ void MediaPlayerService::removeClient(wp<Client> client)
}
MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
- int32_t connId, const sp<IMediaPlayerClient>& client)
+ int32_t connId, const sp<IMediaPlayerClient>& client, int audioSessionId)
{
LOGV("Client(%d) constructor", connId);
mPid = pid;
@@ -618,6 +619,8 @@ MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t
mClient = client;
mLoop = false;
mStatus = NO_INIT;
+ mAudioSessionId = audioSessionId;
+
#if CALLBACK_ANTAGONIZER
LOGD("create Antagonizer");
mAntagonizer = new Antagonizer(notify, this);
@@ -871,7 +874,7 @@ status_t MediaPlayerService::Client::setDataSource(
if (p == NULL) return NO_INIT;
if (!p->hardwareOutput()) {
- mAudioOutput = new AudioOutput();
+ mAudioOutput = new AudioOutput(mAudioSessionId);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
}
@@ -921,7 +924,7 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64
if (p == NULL) return NO_INIT;
if (!p->hardwareOutput()) {
- mAudioOutput = new AudioOutput();
+ mAudioOutput = new AudioOutput(mAudioSessionId);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
}
@@ -1412,9 +1415,11 @@ sp<IMemory> MediaPlayerService::snoop()
#undef LOG_TAG
#define LOG_TAG "AudioSink"
-MediaPlayerService::AudioOutput::AudioOutput()
+MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
: mCallback(NULL),
- mCallbackCookie(NULL) {
+ mCallbackCookie(NULL),
+ mSessionId(sessionId) {
+ LOGV("AudioOutput(%d)", sessionId);
mTrack = 0;
mStreamType = AudioSystem::MUSIC;
mLeftVolume = 1.0;
@@ -1504,7 +1509,7 @@ status_t MediaPlayerService::AudioOutput::open(
bufferCount = mMinBufferCount;
}
- LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
+ LOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId);
if (mTrack) close();
int afSampleRate;
int afFrameCount;
@@ -1529,14 +1534,21 @@ status_t MediaPlayerService::AudioOutput::open(
frameCount,
0 /* flags */,
CallbackWrapper,
- this);
+ this,
+ 0,
+ mSessionId);
} else {
t = new AudioTrack(
mStreamType,
sampleRate,
format,
(channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
- frameCount);
+ frameCount,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ mSessionId);
}
if ((t == 0) || (t->initCheck() != NO_ERROR)) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 2408c62..60b91c6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -65,7 +65,7 @@ class MediaPlayerService : public BnMediaPlayerService
class AudioOutput : public MediaPlayerBase::AudioSink
{
public:
- AudioOutput();
+ AudioOutput(int sessionId);
virtual ~AudioOutput();
virtual bool ready() const { return mTrack != NULL; }
@@ -108,6 +108,7 @@ class MediaPlayerService : public BnMediaPlayerService
float mRightVolume;
float mMsecsPerFrame;
uint32_t mLatency;
+ int mSessionId;
static bool mIsOnEmulator;
static int mMinBufferCount; // 12 for emulator; otherwise 4
@@ -185,9 +186,9 @@ public:
// House keeping for media player clients
virtual sp<IMediaPlayer> create(
pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
- const KeyedVector<String8, String8> *headers);
+ const KeyedVector<String8, String8> *headers, int audioSessionId);
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length, int audioSessionId);
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> snoop();
@@ -237,12 +238,15 @@ private:
pid_t pid() const { return mPid; }
virtual status_t dump(int fd, const Vector<String16>& args) const;
+ int getAudioSessionId() { return mAudioSessionId; }
+
private:
friend class MediaPlayerService;
Client( const sp<MediaPlayerService>& service,
pid_t pid,
int32_t connId,
- const sp<IMediaPlayerClient>& client);
+ const sp<IMediaPlayerClient>& client,
+ int audioSessionId);
Client();
virtual ~Client();
@@ -271,6 +275,7 @@ private:
status_t mStatus;
bool mLoop;
int32_t mConnId;
+ int mAudioSessionId;
// Metadata filters.
media::Metadata::Filter mMetadataAllow; // protected by mLock