diff options
-rw-r--r-- | core/jni/android_media_AudioTrack.cpp | 33 | ||||
-rw-r--r-- | include/media/IMediaPlayerService.h | 7 | ||||
-rw-r--r-- | include/media/mediaplayer.h | 3 | ||||
-rw-r--r-- | media/java/android/media/AudioTrack.java | 70 | ||||
-rw-r--r-- | media/java/android/media/MediaPlayer.java | 44 | ||||
-rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 27 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 6 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayerService.cpp | 19 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 26 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 42 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 13 |
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 |