mediaplayer.cpp revision 1243869fb29ee580fa5c179443420c06a779dbfd
199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Copyright 2006, The Android Open Source Project
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** you may not use this file except in compliance with the License.
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** You may obtain a copy of the License at
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** See the License for the specific language governing permissions and
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** limitations under the License.
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project*/
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "MediaPlayer"
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2134fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn#include <fcntl.h>
2234fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn#include <inttypes.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/stat.h>
2434fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn#include <sys/types.h>
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <unistd.h>
2634fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn
2734fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn#include <utils/Log.h>
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
297562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h>
307562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h>
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32b1e7cd156ca3e1747374e0d20cdd1ce467210453Mathias Agopian#include <gui/Surface.h>
3361c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/mediaplayer.h>
353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar#include <media/AudioResamplerPublic.h>
36a3f1fa308728976fc9ca1b4f37d26e633b32b9acGlenn Kasten#include <media/AudioSystem.h>
373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar#include <media/AVSyncSettings.h>
3899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins#include <media/IDataSource.h>
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
407562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/MemoryBase.h>
4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
422db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huber#include <utils/KeyedVector.h>
432db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huber#include <utils/String8.h>
442db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huber
4564760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
4661c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis#include <system/window.h>
47fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayer::MediaPlayer()
5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("constructor");
5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mListener = NULL;
5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCookie = NULL;
55fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mStreamType = AUDIO_STREAM_MUSIC;
56640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    mAudioAttributesParcel = NULL;
5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCurrentPosition = -1;
5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mSeekPosition = -1;
5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCurrentState = MEDIA_PLAYER_IDLE;
6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mPrepareSync = false;
6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mPrepareStatus = NO_ERROR;
6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLoop = false;
6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLeftVolume = mRightVolume = 1.0;
6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mVideoWidth = mVideoHeight = 0;
651af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    mLockThreadId = 0;
66d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten    mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
67d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen    AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
688c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent    mSendLevel = 0;
69c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpointValid = false;
7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayer::~MediaPlayer()
7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("destructor");
75640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    if (mAudioAttributesParcel != NULL) {
76640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        delete mAudioAttributesParcel;
77640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        mAudioAttributesParcel = NULL;
78640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    }
79d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen    AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    disconnect();
8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    IPCThreadState::self()->flushCommands();
8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayer::disconnect()
8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("disconnect");
8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<IMediaPlayer> p;
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    {
8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Mutex::Autolock _l(mLock);
9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p = mPlayer;
9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mPlayer.clear();
9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p != 0) {
9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p->disconnect();
9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// always call with lock held
10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayer::clear_l()
10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCurrentPosition = -1;
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mSeekPosition = -1;
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mVideoWidth = mVideoHeight = 0;
105c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpointValid = false;
10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setListener");
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mListener = listener;
11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
117d681bbb1767bed09415e050ba78975df214bcd68Dave Burkestatus_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)
11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t err = UNKNOWN_ERROR;
12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<IMediaPlayer> p;
12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    { // scope for the lock
12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Mutex::Autolock _l(mLock);
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12483ff1438d2d1d5dbf39ca5e6f2e4fa1799e7ba80Marco Nelissen        if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
12583ff1438d2d1d5dbf39ca5e6f2e4fa1799e7ba80Marco Nelissen                (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
12629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("attachNewPlayer called in state %d", mCurrentState);
12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return INVALID_OPERATION;
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        clear_l();
13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p = mPlayer;
13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mPlayer = player;
13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (player != 0) {
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_INITIALIZED;
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            err = NO_ERROR;
13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
137f65fa170b28f97503df3c309ecdaab377a042ba6Masaki Muranaka            ALOGE("Unable to create media player");
13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p != 0) {
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p->disconnect();
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return err;
14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1482db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huberstatus_t MediaPlayer::setDataSource(
1491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService,
1502db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huber        const char *url, const KeyedVector<String8, String8> *headers)
15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setDataSource(%s)", url);
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t err = BAD_VALUE;
15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (url != NULL) {
15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const sp<IMediaPlayerService>& service(getMediaPlayerService());
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (service != 0) {
157f37971f624164c3ed185d3f976404a6f60f49b9aGlenn Kasten            sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
158c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman            if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
1591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber                (NO_ERROR != player->setDataSource(httpService, url, headers))) {
1600662067b06658a4a56a8416c676f6cce8ccddb53Dave Burke                player.clear();
161d681bbb1767bed09415e050ba78975df214bcd68Dave Burke            }
1620662067b06658a4a56a8416c676f6cce8ccddb53Dave Burke            err = attachNewPlayer(player);
16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return err;
16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
17034fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn    ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t err = UNKNOWN_ERROR;
17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const sp<IMediaPlayerService>& service(getMediaPlayerService());
17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (service != 0) {
174f37971f624164c3ed185d3f976404a6f60f49b9aGlenn Kasten        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
175c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
176c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman            (NO_ERROR != player->setDataSource(fd, offset, length))) {
1770662067b06658a4a56a8416c676f6cce8ccddb53Dave Burke            player.clear();
178d681bbb1767bed09415e050ba78975df214bcd68Dave Burke        }
1790662067b06658a4a56a8416c676f6cce8ccddb53Dave Burke        err = attachNewPlayer(player);
180d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    }
181d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    return err;
182d681bbb1767bed09415e050ba78975df214bcd68Dave Burke}
183d681bbb1767bed09415e050ba78975df214bcd68Dave Burke
18499f31604136d66ae10e20669fb6b5716f342bde0Chris Watkinsstatus_t MediaPlayer::setDataSource(const sp<IDataSource> &source)
18599f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins{
18699f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    ALOGV("setDataSource(IDataSource)");
18799f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    status_t err = UNKNOWN_ERROR;
18899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    const sp<IMediaPlayerService>& service(getMediaPlayerService());
18999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    if (service != 0) {
19099f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
19199f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
19299f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins            (NO_ERROR != player->setDataSource(source))) {
19399f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins            player.clear();
19499f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins        }
19599f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins        err = attachNewPlayer(player);
19699f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    }
19799f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    return err;
19899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins}
19999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins
2001d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Cataniastatus_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
2011d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania{
2021d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania    Mutex::Autolock _l(mLock);
2034023493a827bc9751d8e40795516d0d536a53348Nicolas Catania    const bool hasBeenInitialized =
2044023493a827bc9751d8e40795516d0d536a53348Nicolas Catania            (mCurrentState != MEDIA_PLAYER_STATE_ERROR) &&
2054023493a827bc9751d8e40795516d0d536a53348Nicolas Catania            ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE);
2064023493a827bc9751d8e40795516d0d536a53348Nicolas Catania    if ((mPlayer != NULL) && hasBeenInitialized) {
20734fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn        ALOGV("invoke %zu", request.dataSize());
208e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        return  mPlayer->invoke(request, reply);
2091d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania    }
210848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia    ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
2111d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania    return INVALID_OPERATION;
2121d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania}
2131d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania
214a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniastatus_t MediaPlayer::setMetadataFilter(const Parcel& filter)
215a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania{
216b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("setMetadataFilter");
2178e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    Mutex::Autolock lock(mLock);
2188e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    if (mPlayer == NULL) {
219a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return NO_INIT;
220a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
221a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    return mPlayer->setMetadataFilter(filter);
222a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}
2231d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania
2248e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Cataniastatus_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
2258e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania{
226b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("getMetadata");
2278e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    Mutex::Autolock lock(mLock);
2288e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    if (mPlayer == NULL) {
2298e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania        return NO_INIT;
2308e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    }
2318e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    return mPlayer->getMetadata(update_only, apply_filter, metadata);
2328e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania}
2338e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania
2341173118eace0e9e347cb007f0da817cee87579edGlenn Kastenstatus_t MediaPlayer::setVideoSurfaceTexture(
235484566c410afdfbc4b6bc5aa1732aef37428a5b8Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer)
2361173118eace0e9e347cb007f0da817cee87579edGlenn Kasten{
2373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVideoSurfaceTexture");
2381173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    Mutex::Autolock _l(mLock);
2391173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (mPlayer == 0) return NO_INIT;
240484566c410afdfbc4b6bc5aa1732aef37428a5b8Andy McFadden    return mPlayer->setVideoSurfaceTexture(bufferProducer);
2411173118eace0e9e347cb007f0da817cee87579edGlenn Kasten}
2421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// must call with lock held
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::prepareAsync_l()
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
246b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten    if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
247640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        if (mAudioAttributesParcel != NULL) {
248640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi            mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel);
2494356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        } else {
2504356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent            mPlayer->setAudioStreamType(mStreamType);
251640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        }
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCurrentState = MEDIA_PLAYER_PREPARING;
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mPlayer->prepareAsync();
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
255848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia    ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return INVALID_OPERATION;
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25965e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project// TODO: In case of error, prepareAsync provides the caller with 2 error codes,
26065e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project// one defined in the Android framework and one provided by the implementation
26165e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project// that generated the error. The sync version of prepare returns only 1 error
26265e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project// code.
26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::prepare()
26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
2653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("prepare");
26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
2671af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    mLockThreadId = getThreadId();
2681af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    if (mPrepareSync) {
2691af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        mLockThreadId = 0;
2701af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        return -EALREADY;
2711af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    }
27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mPrepareSync = true;
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = prepareAsync_l();
2741af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    if (ret != NO_ERROR) {
2751af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        mLockThreadId = 0;
2761af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        return ret;
2771af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    }
27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPrepareSync) {
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mSignal.wait(mLock);  // wait for prepare done
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mPrepareSync = false;
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
2833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("prepare complete - status=%d", mPrepareStatus);
2841af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    mLockThreadId = 0;
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mPrepareStatus;
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::prepareAsync()
28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
2903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("prepareAsync");
29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return prepareAsync_l();
29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::start()
29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
2973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("start");
298d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang
299d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    status_t ret = NO_ERROR;
30089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
301d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang
302d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    mLockThreadId = getThreadId();
303d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang
304d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    if (mCurrentState & MEDIA_PLAYER_STARTED) {
305d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang        ret = NO_ERROR;
306d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mPlayer->setLooping(mLoop);
30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mPlayer->setVolume(mLeftVolume, mRightVolume);
3102beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        mPlayer->setAuxEffectSendLevel(mSendLevel);
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCurrentState = MEDIA_PLAYER_STARTED;
312d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang        ret = mPlayer->start();
31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (ret != NO_ERROR) {
31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
3173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("playback completed immediately following start()");
31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
320d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    } else {
321848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia        ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
322d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang        ret = INVALID_OPERATION;
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
324d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang
325d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    mLockThreadId = 0;
326d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang
327d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    return ret;
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::stop()
33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
3323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stop");
33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t ret = mPlayer->stop();
33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (ret != NO_ERROR) {
33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_STOPPED;
34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return ret;
34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
345848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia    ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return INVALID_OPERATION;
34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::pause()
35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
3513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("pause");
35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
353698f476590bc9e38d4d1d4155da9efdbedd357c4Marco Nelissen    if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE))
35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return NO_ERROR;
35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t ret = mPlayer->pause();
35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (ret != NO_ERROR) {
35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_PAUSED;
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return ret;
36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
364848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia    ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return INVALID_OPERATION;
36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool MediaPlayer::isPlaying()
36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0) {
37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        bool temp = false;
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mPlayer->isPlaying(&temp);
3743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("isPlaying: %d", temp);
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) {
37629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("internal/external state mismatch corrected");
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_PAUSED;
3783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        } else if ((mCurrentState & MEDIA_PLAYER_PAUSED) && temp) {
3793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            ALOGE("internal/external state mismatch corrected");
3803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            mCurrentState = MEDIA_PLAYER_STARTED;
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return temp;
38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
3843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isPlaying: no active player");
38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return false;
38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaPlayer::setPlaybackSettings(const AudioPlaybackRate& rate)
3899816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia{
3903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    ALOGV("setPlaybackSettings: %f %f %d %d",
3913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
3923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    // Negative speed and pitch does not make sense. Further validation will
3933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    // be done by the respective mediaplayers.
3943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    if (rate.mSpeed < 0.f || rate.mPitch < 0.f) {
3959816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        return BAD_VALUE;
3969816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    }
3979816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    Mutex::Autolock _l(mLock);
3983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    if (mPlayer == 0) return INVALID_OPERATION;
3993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    status_t err = mPlayer->setPlaybackSettings(rate);
4003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    if (err == OK) {
4013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) {
4023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            mCurrentState = MEDIA_PLAYER_PAUSED;
4033a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        } else if (rate.mSpeed != 0.f && mCurrentState == MEDIA_PLAYER_PAUSED) {
4043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            mCurrentState = MEDIA_PLAYER_STARTED;
4059816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        }
4069816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    }
4073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    return err;
4083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
4093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
4103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
4113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar{
4123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    Mutex::Autolock _l(mLock);
4133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    if (mPlayer == 0) return INVALID_OPERATION;
4143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    return mPlayer->getPlaybackSettings(rate);
4153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
4163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
4173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
4183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar{
4193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    ALOGV("setSyncSettings: %u %u %f %f",
4203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
4213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    Mutex::Autolock _l(mLock);
4223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    if (mPlayer == 0) return INVALID_OPERATION;
4233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    return mPlayer->setSyncSettings(sync, videoFpsHint);
4243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
4253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
4263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaPlayer::getSyncSettings(
4273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
4283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar{
4293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    Mutex::Autolock _l(mLock);
4303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    if (mPlayer == 0) return INVALID_OPERATION;
4313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    return mPlayer->getSyncSettings(sync, videoFps);
4329816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia}
4339816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia
43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::getVideoWidth(int *w)
43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getVideoWidth");
43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer == 0) return INVALID_OPERATION;
43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *w = mVideoWidth;
44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::getVideoHeight(int *h)
44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getVideoHeight");
44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer == 0) return INVALID_OPERATION;
44889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *h = mVideoHeight;
44989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
45089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::getCurrentPosition(int *msec)
45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getCurrentPosition");
45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0) {
45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mCurrentPosition >= 0) {
4583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Using cached seek position: %d", mCurrentPosition);
45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            *msec = mCurrentPosition;
46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return NO_ERROR;
46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mPlayer->getCurrentPosition(msec);
46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return INVALID_OPERATION;
46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
46689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::getDuration_l(int *msec)
46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
469a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber    ALOGV("getDuration_l");
470b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten    bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
471b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten            MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0 && isValidState) {
473a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        int durationMs;
474a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        status_t ret = mPlayer->getDuration(&durationMs);
4752070254f241f52cadb69bc2323f56df72704f1caAndreas Huber
4762070254f241f52cadb69bc2323f56df72704f1caAndreas Huber        if (ret != OK) {
4772070254f241f52cadb69bc2323f56df72704f1caAndreas Huber            // Do not enter error state just because no duration was available.
4782070254f241f52cadb69bc2323f56df72704f1caAndreas Huber            durationMs = -1;
4792070254f241f52cadb69bc2323f56df72704f1caAndreas Huber            ret = OK;
4802070254f241f52cadb69bc2323f56df72704f1caAndreas Huber        }
4812070254f241f52cadb69bc2323f56df72704f1caAndreas Huber
482a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        if (msec) {
483a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber            *msec = durationMs;
484a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        }
48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return ret;
48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
487848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia    ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
488848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia            mPlayer.get(), mCurrentState);
48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return INVALID_OPERATION;
49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::getDuration(int *msec)
49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return getDuration_l(msec);
49689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::seekTo_l(int msec)
49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("seekTo %d", msec);
501b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten    if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
502b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten            MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if ( msec < 0 ) {
5045ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("Attempt to seek to invalid position: %d", msec);
50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            msec = 0;
50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
507a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber
508a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        int durationMs;
509a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        status_t err = mPlayer->getDuration(&durationMs);
510a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber
511a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        if (err != OK) {
512a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber            ALOGW("Stream has no duration and is therefore not seekable.");
513a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber            return err;
514a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        }
515a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber
516a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        if (msec > durationMs) {
517a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber            ALOGW("Attempt to seek to past end of file: request = %d, "
518a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber                  "durationMs = %d",
519a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber                  msec,
520a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber                  durationMs);
521a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber
522a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber            msec = durationMs;
523a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber        }
524a4c5bc0f18fe272146426ab2eccad6215279c9f3Andreas Huber
52589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // cache duration
52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCurrentPosition = msec;
52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mSeekPosition < 0) {
52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mSeekPosition = msec;
52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return mPlayer->seekTo(msec);
53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        else {
5323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Seek in progress - queue up seekTo[%d]", msec);
53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return NO_ERROR;
53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
536b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten    ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(),
537b187de1ada34a9023c05d020a4592686ba761278Glenn Kasten            mCurrentState);
53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return INVALID_OPERATION;
53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::seekTo(int msec)
54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5435cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber    mLockThreadId = getThreadId();
54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
5455cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber    status_t result = seekTo_l(msec);
5465cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber    mLockThreadId = 0;
5475cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber
5485cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber    return result;
54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55161c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennisstatus_t MediaPlayer::reset_l()
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLoop = false;
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mPrepareSync = false;
55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0) {
55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t ret = mPlayer->reset();
55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (ret != NO_ERROR) {
55929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("reset() failed with return code (%d)", ret);
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
5622b95bda111444f2834e64221e3a3eb1a87d43c38Robert Shih            mPlayer->disconnect();
56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_IDLE;
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
565a1680bce73ea1b051cc92e0df651a53944b104eeJames Dong        // setDataSource has to be called again to create a
566a1680bce73ea1b051cc92e0df651a53944b104eeJames Dong        // new mediaplayer.
567a1680bce73ea1b051cc92e0df651a53944b104eeJames Dong        mPlayer = 0;
56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return ret;
56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    clear_l();
57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
574c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossmanstatus_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) {
575c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    Mutex::Autolock _l(mLock);
576c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
577c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (player == NULL) {
578c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return UNKNOWN_ERROR;
579c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
580c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
581c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (mRetransmitEndpointValid) {
582c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return player->setRetransmitEndpoint(&mRetransmitEndpoint);
583c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
584c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
585c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    return OK;
586c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman}
587c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
58861c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennisstatus_t MediaPlayer::reset()
58961c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis{
5903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("reset");
59161c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis    Mutex::Autolock _l(mLock);
59261c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis    return reset_l();
59361c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis}
59461c7ef5bde2c7ed94a078396aa65da67b47e5402Jamie Gennis
595fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t MediaPlayer::setAudioStreamType(audio_stream_type_t type)
59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::setAudioStreamType");
59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mStreamType == type) return NO_ERROR;
60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) {
60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Can't change the stream type after prepare
60329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setAudioStream called in state %d", mCurrentState);
60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return INVALID_OPERATION;
60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // cache
60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mStreamType = type;
60889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return OK;
60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
611de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlockstatus_t MediaPlayer::getAudioStreamType(audio_stream_type_t *type)
612de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock{
613de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock    ALOGV("getAudioStreamType");
614de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock    Mutex::Autolock _l(mLock);
615de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock    *type = mStreamType;
616de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock    return OK;
617de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock}
618de9453fb5cbc9cd69fd1ea45d577851e3aa3b8c9John Spurlock
61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::setLooping(int loop)
62089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
6213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::setLooping");
62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLoop = (loop != 0);
62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0) {
62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mPlayer->setLooping(loop);
62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return OK;
62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool MediaPlayer::isLooping() {
6313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isLooping");
63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0) {
63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mLoop;
63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
6363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isLooping: no active player");
63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return false;
63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
6423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume);
64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLeftVolume = leftVolume;
64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRightVolume = rightVolume;
64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mPlayer != 0) {
64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mPlayer->setVolume(leftVolume, rightVolume);
64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return OK;
65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
652d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenstatus_t MediaPlayer::setAudioSessionId(audio_session_t sessionId)
653a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent{
6543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
655a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    Mutex::Autolock _l(mLock);
656a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
65729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setAudioSessionId called in state %d", mCurrentState);
658a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent        return INVALID_OPERATION;
659a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    }
660a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    if (sessionId < 0) {
661a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent        return BAD_VALUE;
662a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    }
6633a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (sessionId != mAudioSessionId) {
664d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen        AudioSystem::acquireAudioSessionId(sessionId, -1);
665d457c970c8d08519cd77280a90b61ae1e342cfe3Marco Nelissen        AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
666e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mAudioSessionId = sessionId;
6673a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
668a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    return NO_ERROR;
669a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent}
670a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent
671d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenaudio_session_t MediaPlayer::getAudioSessionId()
672a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent{
673a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    Mutex::Autolock _l(mLock);
674a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    return mAudioSessionId;
675a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent}
676a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent
6772beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t MediaPlayer::setAuxEffectSendLevel(float level)
6782beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent{
6793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
6802beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    Mutex::Autolock _l(mLock);
6812beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    mSendLevel = level;
6822beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    if (mPlayer != 0) {
6832beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        return mPlayer->setAuxEffectSendLevel(level);
6842beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    }
6852beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return OK;
6862beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
6872beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
6882beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t MediaPlayer::attachAuxEffect(int effectId)
6892beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent{
6903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
6912beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    Mutex::Autolock _l(mLock);
6922beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    if (mPlayer == 0 ||
6932beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        (mCurrentState & MEDIA_PLAYER_IDLE) ||
6942beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
695848ebc644a1a7ef93a051186fb5f0aef826ad67eWei Jia        ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
6962beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        return INVALID_OPERATION;
6972beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    }
6982beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
6992beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return mPlayer->attachAuxEffect(effectId);
7002beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
7012beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
702d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi// always call with lock held
703d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivistatus_t MediaPlayer::checkStateForKeySet_l(int key)
704d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi{
705d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    switch(key) {
706d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    case KEY_PARAMETER_AUDIO_ATTRIBUTES:
707d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi        if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
708d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi                MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) {
709d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi            // Can't change the audio attributes after prepare
710d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi            ALOGE("trying to set audio attributes called in state %d", mCurrentState);
711d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi            return INVALID_OPERATION;
712d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi        }
713d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi        break;
714d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    default:
715d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi        // parameter doesn't require player state check
716d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi        break;
717d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    }
718d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    return OK;
719d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi}
720d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi
7214f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t MediaPlayer::setParameter(int key, const Parcel& request)
7224f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang{
7233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::setParameter(%d)", key);
7244356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent    status_t status = INVALID_OPERATION;
7254f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    Mutex::Autolock _l(mLock);
726d9d7fa0873796ac661c44a7fcd6ad5ff697ff01fJean-Michel Trivi    if (checkStateForKeySet_l(key) != OK) {
7274356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        return status;
7284f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    }
729640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    switch (key) {
730640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    case KEY_PARAMETER_AUDIO_ATTRIBUTES:
7314356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        // save the marshalled audio attributes
732640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; };
733640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        mAudioAttributesParcel = new Parcel();
734640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi        mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
7354356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        status = OK;
7364356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        break;
737640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    default:
7384356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
7394356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        break;
7404356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent    }
7414356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent
7424356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent    if (mPlayer != NULL) {
7434356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent        status = mPlayer->setParameter(key, request);
744640adb3cf89cc9b826372009fad8c9b3d120482eJean-Michel Trivi    }
7454356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent    return status;
7464f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
7474f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang
7484f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t MediaPlayer::getParameter(int key, Parcel *reply)
7494f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang{
7503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayer::getParameter(%d)", key);
7514f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    Mutex::Autolock _l(mLock);
7524f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    if (mPlayer != NULL) {
753e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        return  mPlayer->getParameter(key, reply);
7544f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    }
7553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getParameter: no active player");
7564f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    return INVALID_OPERATION;
7574f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
7584f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang
759c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossmanstatus_t MediaPlayer::setRetransmitEndpoint(const char* addrString,
760c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman                                            uint16_t port) {
761c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)",
762c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman            addrString ? addrString : "(null)", port);
763c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
764c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    Mutex::Autolock _l(mLock);
765c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE))
766c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return INVALID_OPERATION;
767c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
768c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (NULL == addrString) {
769c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mRetransmitEndpointValid = false;
770c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return OK;
771c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
772c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
773c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    struct in_addr saddr;
774c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if(!inet_aton(addrString, &saddr)) {
775c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return BAD_VALUE;
776c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
777c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
778be08f6a6688f3b1ae6914fbe800953c9bfb13c45Glenn Kasten    memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint));
779c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpoint.sin_family = AF_INET;
780c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpoint.sin_addr   = saddr;
781c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpoint.sin_port   = htons(port);
782c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpointValid       = true;
783c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
784c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    return OK;
785c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman}
786c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
787b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wangvoid MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
78889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
7893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
79089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    bool send = true;
7911af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    bool locked = false;
79289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
79389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: In the future, we might be on the same thread if the app is
79489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // running in the same process as the media server. In that case,
79589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // this will deadlock.
796660951867e959ebe98612742ef1f72d33ea7e9a3Nicolas Catania    //
797d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    // The threadId hack below works around this for the care of prepare,
798d88adb96ec867ed1b629c434f87514d2fabaf5e9Chong Zhang    // seekTo and start within the same process.
7995cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber    // FIXME: Remember, this is a hack, it's not even a hack that is applied
8005cb07aa071b43a214e4c880b3b7852714e06451bAndreas Huber    // consistently for all use-cases, this needs to be revisited.
801e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (mLockThreadId != getThreadId()) {
8021af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        mLock.lock();
8031af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        locked = true;
804660951867e959ebe98612742ef1f72d33ea7e9a3Nicolas Catania    }
8051af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams
8063b26844e60f8487388e7e62709faf0dada86e7e1Eric Laurent    // Allows calls from JNI in idle state to notify errors
8073b26844e60f8487388e7e62709faf0dada86e7e1Eric Laurent    if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {
8083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
8091af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams        if (locked) mLock.unlock();   // release the lock when done.
81089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return;
81189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
81289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
81389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    switch (msg) {
81489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_NOP: // interface test message
81589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
81689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_PREPARED:
8173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("prepared");
81889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCurrentState = MEDIA_PLAYER_PREPARED;
81989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mPrepareSync) {
8203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("signal application thread");
82189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mPrepareSync = false;
82289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mPrepareStatus = NO_ERROR;
82389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mSignal.signal();
82489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
82589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
82689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_PLAYBACK_COMPLETE:
8273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("playback complete");
8281c1503cf47c0a37a30e7acac2c5d29140fc61a5fMarco Nelissen        if (mCurrentState == MEDIA_PLAYER_IDLE) {
82929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("playback complete in idle state");
8301c1503cf47c0a37a30e7acac2c5d29140fc61a5fMarco Nelissen        }
83189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (!mLoop) {
83289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE;
83389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
83589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_ERROR:
83665e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project        // Always log errors.
83765e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project        // ext1: Media framework error code.
83865e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project        // ext2: Implementation dependant error code.
83929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("error (%d, %d)", ext1, ext2);
84089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCurrentState = MEDIA_PLAYER_STATE_ERROR;
84189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mPrepareSync)
84289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        {
8433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("signal application thread");
84489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mPrepareSync = false;
84589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mPrepareStatus = ext1;
84689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mSignal.signal();
84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            send = false;
84889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
84989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
85065e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project    case MEDIA_INFO:
85165e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project        // ext1: Media framework error code.
85265e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project        // ext2: Implementation dependant error code.
853145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
8545ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("info/warning (%d, %d)", ext1, ext2);
855145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        }
85665e731f393f704eedab6fbe0af7f8a580c8d4617The Android Open Source Project        break;
85789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_SEEK_COMPLETE:
8583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Received seek complete");
85989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mSeekPosition != mCurrentPosition) {
8603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Executing queued seekTo(%d)", mSeekPosition);
86189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mSeekPosition = -1;
86289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            seekTo_l(mCurrentPosition);
86389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
86489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        else {
8653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("All seeks complete - return to regularly scheduled program");
86689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCurrentPosition = mSeekPosition = -1;
86789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
86889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
86989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_BUFFERING_UPDATE:
8703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("buffering %d", ext1);
87189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
87289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    case MEDIA_SET_VIDEO_SIZE:
8733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("New video size %d x %d", ext1, ext2);
87489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mVideoWidth = ext1;
87589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mVideoHeight = ext2;
87689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
877b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang    case MEDIA_TIMED_TEXT:
8783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Received timed text message");
879b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang        break;
880dcb89b3b505522efde173c105a851c412f947178Chong Zhang    case MEDIA_SUBTITLE_DATA:
881dcb89b3b505522efde173c105a851c412f947178Chong Zhang        ALOGV("Received subtitle data message");
882dcb89b3b505522efde173c105a851c412f947178Chong Zhang        break;
8830852843d304006e3ab333081fddda13b07193de8Robert Shih    case MEDIA_META_DATA:
8840852843d304006e3ab333081fddda13b07193de8Robert Shih        ALOGV("Received timed metadata message");
8850852843d304006e3ab333081fddda13b07193de8Robert Shih        break;
88689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    default:
8873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
88889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
88989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
89089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
89189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerListener> listener = mListener;
8921af452f333664e8b0a61d96a9b3bb682d8b9a00fJason Sams    if (locked) mLock.unlock();
89389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
89489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // this prevents re-entrant calls into client code
89589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((listener != 0) && send) {
89689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Mutex::Autolock _l(mNotifyLock);
8973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("callback application");
898b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang        listener->notify(msg, ext1, ext2, obj);
8993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("back from callback");
90089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
90189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
90289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
903dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dongvoid MediaPlayer::died()
904dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong{
9053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("died");
906dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong    notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
907dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong}
908dd172fce75b2a1c3cb3a5d3b3bbb5020b1ae8675James Dong
9096b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissenstatus_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
9101243869fb29ee580fa5c179443420c06a779dbfdWei Jia    Mutex::Autolock _l(mLock);
9116b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    if (mPlayer == NULL) {
9126b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        return NO_INIT;
9136b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
914b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen
915b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen    if (next != NULL && !(next->mCurrentState &
916b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen            (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
917b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen        ALOGE("next player is not prepared");
918b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen        return INVALID_OPERATION;
919b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen    }
920b13820ffafcb6bcdd33b6272676535afb4dff479Marco Nelissen
9216b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
9226b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen}
9236b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen
92440bc906252974d0b389ae4a147232d0c9a97193fGlenn Kasten} // namespace android
925