LiveSession.cpp revision 784faaf1d76902be6b36d3af01fb5325f0d45a04
1a44153c1a57202fb538659eb50706e60454d6273Andreas Huber/*
2a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *
4a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * you may not use this file except in compliance with the License.
6a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * You may obtain a copy of the License at
7a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *
8a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *
10a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * Unless required by applicable law or agreed to in writing, software
11a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * See the License for the specific language governing permissions and
14a44153c1a57202fb538659eb50706e60454d6273Andreas Huber * limitations under the License.
15a44153c1a57202fb538659eb50706e60454d6273Andreas Huber */
16a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
17a44153c1a57202fb538659eb50706e60454d6273Andreas Huber//#define LOG_NDEBUG 0
18a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#define LOG_TAG "LiveSession"
19a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <utils/Log.h>
20a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
2114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include "LiveSession.h"
22a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
2314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include "M3UParser.h"
2414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include "PlaylistFetcher.h"
25a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "include/HTTPBase.h"
2714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include "mpeg2ts/AnotherPacketSource.h"
28a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
29a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <cutils/properties.h>
30a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/hexdump.h>
31a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
32a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/ADebug.h>
33a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/AMessage.h>
34a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/DataSource.h>
35a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/FileSource.h>
36a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/MediaErrors.h>
3714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include <media/stagefright/MetaData.h>
3814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include <media/stagefright/Utils.h>
39a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
40a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <ctype.h>
41a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <openssl/aes.h>
427e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#include <openssl/md5.h>
43a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
44a44153c1a57202fb538659eb50706e60454d6273Andreas Hubernamespace android {
45a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
460df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas HuberLiveSession::LiveSession(
470df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber        const sp<AMessage> &notify, uint32_t flags, bool uidValid, uid_t uid)
480df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber    : mNotify(notify),
490df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber      mFlags(flags),
509b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mUIDValid(uidValid),
519b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mUID(uid),
520df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber      mInPreparationPhase(true),
537314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber      mHTTPDataSource(
541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber              HTTPBase::Create(
557314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber                  (mFlags & kFlagIncognito)
561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    ? HTTPBase::kFlagIncognito
577314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber                    : 0)),
58a44153c1a57202fb538659eb50706e60454d6273Andreas Huber      mPrevBandwidthIndex(-1),
5914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber      mStreamMask(0),
6014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber      mCheckBandwidthGeneration(0),
6114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber      mLastDequeuedTimeUs(0ll),
62dcb89b3b505522efde173c105a851c412f947178Chong Zhang      mRealTimeBaseUs(0ll),
6314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber      mReconfigurationInProgress(false),
6414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber      mDisconnectReplyID(0) {
659b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    if (mUIDValid) {
669b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        mHTTPDataSource->setUID(mUID);
679b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    }
6814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
6914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPacketSources.add(
7014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            STREAMTYPE_AUDIO, new AnotherPacketSource(NULL /* meta */));
7114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
7214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPacketSources.add(
7314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            STREAMTYPE_VIDEO, new AnotherPacketSource(NULL /* meta */));
7414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
7514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPacketSources.add(
7614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            STREAMTYPE_SUBTITLES, new AnotherPacketSource(NULL /* meta */));
77a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
78a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
79a44153c1a57202fb538659eb50706e60454d6273Andreas HuberLiveSession::~LiveSession() {
80a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
81a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
8214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::dequeueAccessUnit(
8314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        StreamType stream, sp<ABuffer> *accessUnit) {
8414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (!(mStreamMask & stream)) {
8514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return UNKNOWN_ERROR;
8614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
8714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
8814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream);
8914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
9014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    status_t finalResult;
9114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (!packetSource->hasBufferAvailable(&finalResult)) {
9214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return finalResult == OK ? -EAGAIN : finalResult;
9314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
9414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
9514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    status_t err = packetSource->dequeueAccessUnit(accessUnit);
9614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
9714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    const char *streamStr;
9814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    switch (stream) {
9914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case STREAMTYPE_AUDIO:
10014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamStr = "audio";
10114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
10214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case STREAMTYPE_VIDEO:
10314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamStr = "video";
10414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
10514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case STREAMTYPE_SUBTITLES:
10614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamStr = "subs";
10714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
10814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        default:
10914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            TRESPASS();
11014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
11114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
11214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (err == INFO_DISCONTINUITY) {
11314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        int32_t type;
11414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK((*accessUnit)->meta()->findInt32("discontinuity", &type));
11514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
11614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AMessage> extra;
11714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (!(*accessUnit)->meta()->findMessage("extra", &extra)) {
11814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            extra.clear();
11914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
12014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
12114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGI("[%s] read discontinuity of type %d, extra = %s",
12214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber              streamStr,
12314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber              type,
12414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber              extra == NULL ? "NULL" : extra->debugString().c_str());
12514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else if (err == OK) {
126dcb89b3b505522efde173c105a851c412f947178Chong Zhang        if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) {
127dcb89b3b505522efde173c105a851c412f947178Chong Zhang            int64_t timeUs;
128dcb89b3b505522efde173c105a851c412f947178Chong Zhang            CHECK((*accessUnit)->meta()->findInt64("timeUs",  &timeUs));
129dcb89b3b505522efde173c105a851c412f947178Chong Zhang            ALOGV("[%s] read buffer at time %lld us", streamStr, timeUs);
130dcb89b3b505522efde173c105a851c412f947178Chong Zhang
131dcb89b3b505522efde173c105a851c412f947178Chong Zhang            mLastDequeuedTimeUs = timeUs;
132dcb89b3b505522efde173c105a851c412f947178Chong Zhang            mRealTimeBaseUs = ALooper::GetNowUs() - timeUs;
133dcb89b3b505522efde173c105a851c412f947178Chong Zhang        } else if (stream == STREAMTYPE_SUBTITLES) {
134dcb89b3b505522efde173c105a851c412f947178Chong Zhang            (*accessUnit)->meta()->setInt32(
135dcb89b3b505522efde173c105a851c412f947178Chong Zhang                    "trackIndex", mPlaylist->getSelectedIndex());
136dcb89b3b505522efde173c105a851c412f947178Chong Zhang            (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs);
137dcb89b3b505522efde173c105a851c412f947178Chong Zhang        }
13814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else {
13914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGI("[%s] encountered error %d", streamStr, err);
14014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
14114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
14214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return err;
14314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
14414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
14514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) {
14614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (!(mStreamMask & stream)) {
14714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return UNKNOWN_ERROR;
14814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
14914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
15014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream);
15114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
15214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<MetaData> meta = packetSource->getFormat();
15314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
15414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (meta == NULL) {
15514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return -EAGAIN;
15614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
15714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
15814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return convertMetaDataToMessage(meta, format);
159a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
160a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
16114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::connectAsync(
162ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber        const char *url, const KeyedVector<String8, String8> *headers) {
163a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<AMessage> msg = new AMessage(kWhatConnect, id());
164a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    msg->setString("url", url);
165ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber
166ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber    if (headers != NULL) {
167ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber        msg->setPointer(
168ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber                "headers",
169ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber                new KeyedVector<String8, String8>(*headers));
170ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber    }
171ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber
172a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    msg->post();
173a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
174a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
17514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::disconnect() {
17614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatDisconnect, id());
177ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber
17814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> response;
17914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    status_t err = msg->postAndAwaitResponse(&response);
180ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber
18114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return err;
182a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
183a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
18414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::seekTo(int64_t timeUs) {
185a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, id());
186a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    msg->setInt64("timeUs", timeUs);
187a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
18814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> response;
18914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    status_t err = msg->postAndAwaitResponse(&response);
19014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
19114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return err;
192a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
193a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
194a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMessageReceived(const sp<AMessage> &msg) {
195a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    switch (msg->what()) {
196a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        case kWhatConnect:
19714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
198a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            onConnect(msg);
199a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
20014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
201a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
202a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        case kWhatDisconnect:
20314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
20414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            CHECK(msg->senderAwaitsResponse(&mDisconnectReplyID));
20514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
20614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (mReconfigurationInProgress) {
20714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
20814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            }
20914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
21014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            finishDisconnect();
211a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
21214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
213a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
21414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case kWhatSeek:
21514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
21614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            uint32_t replyID;
21714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
21914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            status_t err = onSeek(msg);
22014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
22114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            sp<AMessage> response = new AMessage;
22214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            response->setInt32("err", err);
22314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
22414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            response->postReply(replyID);
22514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
22614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
22714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
22814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case kWhatFetcherNotify:
22914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
23014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            int32_t what;
23114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            CHECK(msg->findInt32("what", &what));
23214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
23314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            switch (what) {
23414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                case PlaylistFetcher::kWhatStarted:
23514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    break;
23614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                case PlaylistFetcher::kWhatPaused:
23714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                case PlaylistFetcher::kWhatStopped:
23814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                {
23914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    if (what == PlaylistFetcher::kWhatStopped) {
24014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        AString uri;
24114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        CHECK(msg->findString("uri", &uri));
24214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mFetcherInfos.removeItem(uri);
24314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    }
24414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
24514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    if (mContinuation != NULL) {
24614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        CHECK_GT(mContinuationCounter, 0);
24714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        if (--mContinuationCounter == 0) {
24814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                            mContinuation->post();
24914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        }
25014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    }
25114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    break;
25214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                }
25314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
25414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                case PlaylistFetcher::kWhatDurationUpdate:
25514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                {
25614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    AString uri;
25714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK(msg->findString("uri", &uri));
25814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
25914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    int64_t durationUs;
26014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK(msg->findInt64("durationUs", &durationUs));
26114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
26214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    FetcherInfo *info = &mFetcherInfos.editValueFor(uri);
26314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    info->mDurationUs = durationUs;
26414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    break;
26514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                }
26614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
26714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                case PlaylistFetcher::kWhatError:
26814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                {
26914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    status_t err;
27014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK(msg->findInt32("err", &err));
27114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
27214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    ALOGE("XXX Received error %d from PlaylistFetcher.", err);
27314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
27414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    if (mInPreparationPhase) {
27514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        postPrepared(err);
27614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    }
27714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
27814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(err);
27914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
28014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(err);
28114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
28214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    mPacketSources.valueFor(
28314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                            STREAMTYPE_SUBTITLES)->signalEOS(err);
28414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
28514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    sp<AMessage> notify = mNotify->dup();
28614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    notify->setInt32("what", kWhatError);
28714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    notify->setInt32("err", err);
28814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    notify->post();
28914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    break;
29014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                }
29114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
29214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                case PlaylistFetcher::kWhatTemporarilyDoneFetching:
29314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                {
29414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    AString uri;
29514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK(msg->findString("uri", &uri));
29614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
29714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    FetcherInfo *info = &mFetcherInfos.editValueFor(uri);
29814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    info->mIsPrepared = true;
29914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
30014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    if (mInPreparationPhase) {
30114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        bool allFetchersPrepared = true;
30214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
30314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                            if (!mFetcherInfos.valueAt(i).mIsPrepared) {
30414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                allFetchersPrepared = false;
30514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                break;
30614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                            }
30714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        }
30814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
30914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        if (allFetchersPrepared) {
31014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                            postPrepared(OK);
31114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        }
31214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    }
31314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    break;
31414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                }
31514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
31614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                default:
31714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    TRESPASS();
31814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            }
31914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
32014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
32114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
32214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
32314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case kWhatCheckBandwidth:
324a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        {
325a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            int32_t generation;
326a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            CHECK(msg->findInt32("generation", &generation));
327a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
32814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (generation != mCheckBandwidthGeneration) {
329a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                break;
330a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            }
331a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
33214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            onCheckBandwidth();
333a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
334a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
335a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
336dcb89b3b505522efde173c105a851c412f947178Chong Zhang        case kWhatChangeConfiguration:
337dcb89b3b505522efde173c105a851c412f947178Chong Zhang        {
338dcb89b3b505522efde173c105a851c412f947178Chong Zhang            onChangeConfiguration(msg);
339dcb89b3b505522efde173c105a851c412f947178Chong Zhang            break;
340dcb89b3b505522efde173c105a851c412f947178Chong Zhang        }
341dcb89b3b505522efde173c105a851c412f947178Chong Zhang
34214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case kWhatChangeConfiguration2:
34314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
34414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            onChangeConfiguration2(msg);
34514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
34614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
34714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
34814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case kWhatChangeConfiguration3:
34914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
35014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            onChangeConfiguration3(msg);
35114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            break;
35214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
35314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
35414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        case kWhatFinishDisconnect2:
35514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        {
35614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            onFinishDisconnect2();
357a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
35814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
359a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
360a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        default:
361a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            TRESPASS();
362a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
363a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
364a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
365a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
366a44153c1a57202fb538659eb50706e60454d6273Andreas Huber// static
367a44153c1a57202fb538659eb50706e60454d6273Andreas Huberint LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b) {
368a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (a->mBandwidth < b->mBandwidth) {
369a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return -1;
370a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else if (a->mBandwidth == b->mBandwidth) {
371a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return 0;
372a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
373a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
374a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return 1;
375a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
376a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
377a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onConnect(const sp<AMessage> &msg) {
378a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    AString url;
379a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    CHECK(msg->findString("url", &url));
380a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
381ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber    KeyedVector<String8, String8> *headers = NULL;
382ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber    if (!msg->findPointer("headers", (void **)&headers)) {
383ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber        mExtraHeaders.clear();
384ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber    } else {
385ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber        mExtraHeaders = *headers;
386ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber
387ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber        delete headers;
388ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber        headers = NULL;
389ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber    }
390ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber
39114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#if 1
39253ae1640ffbfc690962f7f94694b02680c6f66cbJames Dong    ALOGI("onConnect <URL suppressed>");
39314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#else
39414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ALOGI("onConnect %s", url.c_str());
39514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#endif
396a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
397a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    mMasterURL = url;
398a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
3997e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    bool dummy;
40014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPlaylist = fetchPlaylist(url.c_str(), NULL /* curPlaylistHash */, &dummy);
401ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber
40214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist == NULL) {
40329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("unable to fetch master playlist '%s'.", url.c_str());
404ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber
40514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        postPrepared(ERROR_IO);
406ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber        return;
407ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber    }
408a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
40914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // We trust the content provider to make a reasonable choice of preferred
41014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // initial bandwidth by listing it first in the variant playlist.
41114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // At startup we really don't have a good estimate on the available
41214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // network bandwidth since we haven't tranferred any data yet. Once
41314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // we have we can make a better informed choice.
41414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    size_t initialBandwidth = 0;
41514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    size_t initialBandwidthIndex = 0;
41614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
41714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->isVariantPlaylist()) {
41814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        for (size_t i = 0; i < mPlaylist->size(); ++i) {
419a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            BandwidthItem item;
420a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
42114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            item.mPlaylistIndex = i;
42214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
423a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            sp<AMessage> meta;
42414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            AString uri;
42514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            mPlaylist->itemAt(i, &uri, &meta);
426a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
427a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            unsigned long bandwidth;
428a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth));
429a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
43014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (initialBandwidth == 0) {
43114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                initialBandwidth = item.mBandwidth;
43214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            }
43314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
434a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            mBandwidthItems.push(item);
435a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
436a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
437a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        CHECK_GT(mBandwidthItems.size(), 0u);
438a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
439a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        mBandwidthItems.sort(SortByBandwidth);
44014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
44114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        for (size_t i = 0; i < mBandwidthItems.size(); ++i) {
44214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (mBandwidthItems.itemAt(i).mBandwidth == initialBandwidth) {
44314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                initialBandwidthIndex = i;
44414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
44514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            }
44614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
44714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else {
44814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // dummy item.
44914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        BandwidthItem item;
45014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        item.mPlaylistIndex = 0;
45114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        item.mBandwidth = 0;
45214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        mBandwidthItems.push(item);
453a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
454a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
455dcb89b3b505522efde173c105a851c412f947178Chong Zhang    changeConfiguration(
456dcb89b3b505522efde173c105a851c412f947178Chong Zhang            0ll /* timeUs */, initialBandwidthIndex, true /* pickTrack */);
457a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
458a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
45914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::finishDisconnect() {
46014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // No reconfiguration is currently pending, make sure none will trigger
46114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // during disconnection either.
46214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    cancelCheckBandwidthEvent();
46314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
46414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
46514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        mFetcherInfos.valueAt(i).mFetcher->stopAsync();
46614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
46714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
46814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id());
469a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
47014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuationCounter = mFetcherInfos.size();
47114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuation = msg;
472ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber
47314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mContinuationCounter == 0) {
47414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->post();
47514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
47614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
47714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
47814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onFinishDisconnect2() {
47914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuation.clear();
48014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
48114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(ERROR_END_OF_STREAM);
48214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(ERROR_END_OF_STREAM);
48314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
48414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPacketSources.valueFor(
48514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            STREAMTYPE_SUBTITLES)->signalEOS(ERROR_END_OF_STREAM);
48614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
48714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> response = new AMessage;
48814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    response->setInt32("err", OK);
48914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
49014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    response->postReply(mDisconnectReplyID);
49114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mDisconnectReplyID = 0;
49214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
49314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
49414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) {
49514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ssize_t index = mFetcherInfos.indexOfKey(uri);
49614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
49714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (index >= 0) {
49814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return NULL;
49914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
50014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
50114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id());
50214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setString("uri", uri);
50314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
50414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    FetcherInfo info;
50514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    info.mFetcher = new PlaylistFetcher(notify, this, uri);
50614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    info.mDurationUs = -1ll;
50714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    info.mIsPrepared = false;
50814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    looper()->registerHandler(info.mFetcher);
50914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
51014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mFetcherInfos.add(uri, info);
51114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
51214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return info.mFetcher;
513a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
514a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
5152aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huberstatus_t LiveSession::fetchFile(
5162aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        const char *url, sp<ABuffer> *out,
517784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo        int64_t range_offset, int64_t range_length,
518784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo        String8 *actualUrl) {
519a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    *out = NULL;
520a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
521a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<DataSource> source;
522a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
523a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (!strncasecmp(url, "file://", 7)) {
524a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        source = new FileSource(url + 7);
5258cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber    } else if (strncasecmp(url, "http://", 7)
5268cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber            && strncasecmp(url, "https://", 8)) {
527df42f949c8bd05b81d94633767514fff88f52062Andreas Huber        return ERROR_UNSUPPORTED;
528a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else {
5292aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        KeyedVector<String8, String8> headers = mExtraHeaders;
5302aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        if (range_offset > 0 || range_length >= 0) {
5312aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            headers.add(
5322aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                    String8("Range"),
5332aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                    String8(
5342aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                        StringPrintf(
5352aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                            "bytes=%lld-%s",
5362aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                            range_offset,
5372aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                            range_length < 0
5382aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                                ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str()));
5392aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        }
5402aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        status_t err = mHTTPDataSource->connect(url, &headers);
541a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
542a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (err != OK) {
543a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            return err;
544a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
545a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
546a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        source = mHTTPDataSource;
547a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
548a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
549a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    off64_t size;
550a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    status_t err = source->getSize(&size);
551a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
552a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (err != OK) {
553a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        size = 65536;
554a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
555a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
556a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<ABuffer> buffer = new ABuffer(size);
557a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    buffer->setRange(0, 0);
558a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
559a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    for (;;) {
560a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        size_t bufferRemaining = buffer->capacity() - buffer->size();
561a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
562a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (bufferRemaining == 0) {
563a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            bufferRemaining = 32768;
564a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
5653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("increasing download buffer to %d bytes",
566a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                 buffer->size() + bufferRemaining);
567a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
568a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
569a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            memcpy(copy->data(), buffer->data(), buffer->size());
570a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            copy->setRange(0, buffer->size());
571a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
572a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            buffer = copy;
573a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
574a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
5752aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        size_t maxBytesToRead = bufferRemaining;
5762aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        if (range_length >= 0) {
5772aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            int64_t bytesLeftInRange = range_length - buffer->size();
5782aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            if (bytesLeftInRange < maxBytesToRead) {
5792aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                maxBytesToRead = bytesLeftInRange;
5802aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber
5812aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                if (bytesLeftInRange == 0) {
5822aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                    break;
5832aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                }
5842aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            }
5852aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        }
5862aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber
587a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        ssize_t n = source->readAt(
588a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                buffer->size(), buffer->data() + buffer->size(),
5892aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                maxBytesToRead);
590a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
591a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (n < 0) {
59220ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber            return n;
593a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
594a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
595a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (n == 0) {
596a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
597a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
598a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
599a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        buffer->setRange(0, buffer->size() + (size_t)n);
600a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
601a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
602a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    *out = buffer;
603784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo    if (actualUrl != NULL) {
604784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo        *actualUrl = source->getUri();
605784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo        if (actualUrl->isEmpty()) {
606784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo            *actualUrl = url;
607784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo        }
608784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo    }
609a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
610a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return OK;
611a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
612a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
61314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist(
61414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        const char *url, uint8_t *curPlaylistHash, bool *unchanged) {
615b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    ALOGV("fetchPlaylist '%s'", url);
616b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
6177e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    *unchanged = false;
6187e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
619a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<ABuffer> buffer;
620784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo    String8 actualUrl;
621784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo    status_t err = fetchFile(url, &buffer, 0, -1, &actualUrl);
622a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
623a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (err != OK) {
624a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return NULL;
625a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
626a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
6277e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    // MD5 functionality is not available on the simulator, treat all
6287e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    // playlists as changed.
6297e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6307e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS)
6317e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    uint8_t hash[16];
6327e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6337e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_CTX m;
6347e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_Init(&m);
6357e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_Update(&m, buffer->data(), buffer->size());
6367e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6377e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_Final(hash, &m);
6387e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
63914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) {
6407e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber        // playlist unchanged
6417e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber        *unchanged = true;
6427e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Playlist unchanged, refresh state is now %d",
6447e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber             (int)mRefreshState);
6457e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6467e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber        return NULL;
6477e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    }
6487e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
64914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (curPlaylistHash != NULL) {
65014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        memcpy(curPlaylistHash, hash, sizeof(hash));
65114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
6527e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif
6537e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
654a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<M3UParser> playlist =
655784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo        new M3UParser(actualUrl.string(), buffer->data(), buffer->size());
656a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
657a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (playlist->initCheck() != OK) {
65829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("failed to parse .m3u8 playlist");
6599067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber
660a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return NULL;
661a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
662a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
663a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return playlist;
664a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
665a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
666a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() {
667a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return (double)rand() / RAND_MAX;
668a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
669a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
670a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() {
671a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mBandwidthItems.size() == 0) {
672a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return 0;
673a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
674a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
675a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1
676a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    char value[PROPERTY_VALUE_MAX];
677673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber    ssize_t index = -1;
67814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (property_get("media.httplive.bw-index", value, NULL)) {
679a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        char *end;
68014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = strtol(value, &end, 10);
68114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(end > value && *end == '\0');
68214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
68314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (index >= 0 && (size_t)index >= mBandwidthItems.size()) {
68414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            index = mBandwidthItems.size() - 1;
685a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
686a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
687a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
68814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (index < 0) {
68914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        int32_t bandwidthBps;
69014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (mHTTPDataSource != NULL
69114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) {
69214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f);
69314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        } else {
69414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            ALOGV("no bandwidth estimate.");
69514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            return 0;  // Pick the lowest bandwidth stream by default.
69614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
697a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
69814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        char value[PROPERTY_VALUE_MAX];
69914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (property_get("media.httplive.max-bw", value, NULL)) {
70014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            char *end;
70114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            long maxBw = strtoul(value, &end, 10);
70214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (end > value && *end == '\0') {
70314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                if (maxBw > 0 && bandwidthBps > maxBw) {
70414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    ALOGV("bandwidth capped to %ld bps", maxBw);
70514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    bandwidthBps = maxBw;
70614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                }
70714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            }
70814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
709a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
71014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // Consider only 80% of the available bandwidth usable.
71114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        bandwidthBps = (bandwidthBps * 8) / 10;
71214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
71314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // Pick the highest bandwidth stream below or equal to estimated bandwidth.
71414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
71514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = mBandwidthItems.size() - 1;
71614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth
71714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                > (size_t)bandwidthBps) {
71814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            --index;
71914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
721a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0
722a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // Change bandwidth at random()
723a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index = uniformRand() * mBandwidthItems.size();
724a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0
725a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // There's a 50% chance to stay on the current bandwidth and
726a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // a 50% chance to switch to the next higher bandwidth (wrapping around
727a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // to lowest)
728a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    const size_t kMinIndex = 0;
729a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
73014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    static ssize_t mPrevBandwidthIndex = -1;
73114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
732a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index;
733a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mPrevBandwidthIndex < 0) {
734a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        index = kMinIndex;
735a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else if (uniformRand() < 0.5) {
736a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        index = (size_t)mPrevBandwidthIndex;
737a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else {
738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        index = mPrevBandwidthIndex + 1;
739a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (index == mBandwidthItems.size()) {
740a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            index = kMinIndex;
741a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
742a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
74314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPrevBandwidthIndex = index;
744a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0
745a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec
746a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
747a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index = mBandwidthItems.size() - 1;
748a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) {
749a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        --index;
750a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
75114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1
75214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    char value[PROPERTY_VALUE_MAX];
75314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    size_t index;
75414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (property_get("media.httplive.bw-index", value, NULL)) {
75514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        char *end;
75614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = strtoul(value, &end, 10);
75714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(end > value && *end == '\0');
75814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
75914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (index >= mBandwidthItems.size()) {
76014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            index = mBandwidthItems.size() - 1;
76114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
76214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else {
76314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = 0;
76414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
765a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else
766a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index = mBandwidthItems.size() - 1;  // Highest bandwidth stream
767a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif
768a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
76914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK_GE(index, 0);
77014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
771a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return index;
772a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
773a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
77414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) {
77514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t timeUs;
77614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
7777e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
77814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (!mReconfigurationInProgress) {
77914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changeConfiguration(timeUs, getBandwidthIndex());
7807e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    }
7817e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
78214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return OK;
7837e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber}
7847e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
78514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const {
78614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t maxDurationUs = 0ll;
78714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
78814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs;
789b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
79014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (fetcherDurationUs >= 0ll && fetcherDurationUs > maxDurationUs) {
79114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            maxDurationUs = fetcherDurationUs;
792a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
793a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
794a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
79514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    *durationUs = maxDurationUs;
796a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
79714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return OK;
79814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
7990f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber
80014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const {
80114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t durationUs;
80214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return getDuration(&durationUs) == OK && durationUs >= 0;
80314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
8040f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber
80514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const {
80614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return false;
80714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
8080f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber
809dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::getTrackInfo(Parcel *reply) const {
810dcb89b3b505522efde173c105a851c412f947178Chong Zhang    return mPlaylist->getTrackInfo(reply);
811dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
812dcb89b3b505522efde173c105a851c412f947178Chong Zhang
813dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) {
814dcb89b3b505522efde173c105a851c412f947178Chong Zhang    status_t err = mPlaylist->selectTrack(index, select);
815dcb89b3b505522efde173c105a851c412f947178Chong Zhang    if (err == OK) {
816dcb89b3b505522efde173c105a851c412f947178Chong Zhang        (new AMessage(kWhatChangeConfiguration, id()))->post();
817dcb89b3b505522efde173c105a851c412f947178Chong Zhang    }
818dcb89b3b505522efde173c105a851c412f947178Chong Zhang    return err;
819dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
820dcb89b3b505522efde173c105a851c412f947178Chong Zhang
821dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration(
822dcb89b3b505522efde173c105a851c412f947178Chong Zhang        int64_t timeUs, size_t bandwidthIndex, bool pickTrack) {
82314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(!mReconfigurationInProgress);
82414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mReconfigurationInProgress = true;
825a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
82614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPrevBandwidthIndex = bandwidthIndex;
82743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
828dcb89b3b505522efde173c105a851c412f947178Chong Zhang    ALOGV("changeConfiguration => timeUs:%lld us, bwIndex:%d, pickTrack:%d",
829dcb89b3b505522efde173c105a851c412f947178Chong Zhang          timeUs, bandwidthIndex, pickTrack);
83043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
831dcb89b3b505522efde173c105a851c412f947178Chong Zhang    if (pickTrack) {
832dcb89b3b505522efde173c105a851c412f947178Chong Zhang        mPlaylist->pickRandomMediaItems();
833dcb89b3b505522efde173c105a851c412f947178Chong Zhang    }
83443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
83514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK_LT(bandwidthIndex, mBandwidthItems.size());
83614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex);
837a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
83814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t streamMask = 0;
839a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
84014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString audioURI;
84114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->getAudioURI(item.mPlaylistIndex, &audioURI)) {
84214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask |= STREAMTYPE_AUDIO;
843a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
844a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
84514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString videoURI;
84614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->getVideoURI(item.mPlaylistIndex, &videoURI)) {
84714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask |= STREAMTYPE_VIDEO;
848a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
849a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
85014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString subtitleURI;
85114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->getSubtitleURI(item.mPlaylistIndex, &subtitleURI)) {
85214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask |= STREAMTYPE_SUBTITLES;
85314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
854aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber
85514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Step 1, stop and discard fetchers that are no longer needed.
85614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Pause those that we'll reuse.
85714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
85814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        const AString &uri = mFetcherInfos.keyAt(i);
859aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber
86014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        bool discardFetcher = true;
861aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber
86214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // If we're seeking all current fetchers are discarded.
86314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (timeUs < 0ll) {
86414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (((streamMask & STREAMTYPE_AUDIO) && uri == audioURI)
86514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    || ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI)
86614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    || ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI)) {
86714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                discardFetcher = false;
8686801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber            }
86914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
870a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
87114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (discardFetcher) {
87214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            mFetcherInfos.valueAt(i).mFetcher->stopAsync();
8736801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber        } else {
87414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            mFetcherInfos.valueAt(i).mFetcher->pauseAsync();
8756801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber        }
876a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
877a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
87814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatChangeConfiguration2, id());
87914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setInt32("streamMask", streamMask);
88014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setInt64("timeUs", timeUs);
88114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_AUDIO) {
88214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->setString("audioURI", audioURI.c_str());
883a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
88414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_VIDEO) {
88514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->setString("videoURI", videoURI.c_str());
8862aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber    }
88714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_SUBTITLES) {
88814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->setString("subtitleURI", subtitleURI.c_str());
8896e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber    }
890a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
89114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Every time a fetcher acknowledges the stopAsync or pauseAsync request
89214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // we'll decrement mContinuationCounter, once it reaches zero, i.e. all
89314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // fetchers have completed their asynchronous operation, we'll post
89414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // mContinuation, which then is handled below in onChangeConfiguration2.
89514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuationCounter = mFetcherInfos.size();
89614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuation = msg;
89788b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber
89814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mContinuationCounter == 0) {
89914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->post();
90088b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber    }
90114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
902a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
903dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) {
904dcb89b3b505522efde173c105a851c412f947178Chong Zhang    if (!mReconfigurationInProgress) {
905dcb89b3b505522efde173c105a851c412f947178Chong Zhang        changeConfiguration(-1ll /* timeUs */, getBandwidthIndex());
906dcb89b3b505522efde173c105a851c412f947178Chong Zhang    } else {
907dcb89b3b505522efde173c105a851c412f947178Chong Zhang        msg->post(1000000ll); // retry in 1 sec
908dcb89b3b505522efde173c105a851c412f947178Chong Zhang    }
909dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
910dcb89b3b505522efde173c105a851c412f947178Chong Zhang
91114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
91214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuation.clear();
913bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
91414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // All fetchers are either suspended or have been removed now.
915bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
91614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t streamMask;
91714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
918bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
91914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString audioURI, videoURI, subtitleURI;
92014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_AUDIO) {
92114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("audioURI", &audioURI));
92214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("audioURI = '%s'", audioURI.c_str());
923a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
92414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_VIDEO) {
92514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("videoURI", &videoURI));
92614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("videoURI = '%s'", videoURI.c_str());
92722fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    }
92814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_SUBTITLES) {
92914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("subtitleURI", &subtitleURI));
93014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("subtitleURI = '%s'", subtitleURI.c_str());
93122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    }
9323831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
93314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Determine which decoders to shutdown on the player side,
93414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // a decoder has to be shutdown if either
93514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // 1) its streamtype was active before but now longer isn't.
93614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // or
93714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // 2) its streamtype was already active and still is but the URI
93814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    //    has changed.
93914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t changedMask = 0;
94014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (((mStreamMask & streamMask & STREAMTYPE_AUDIO)
94114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                && !(audioURI == mAudioURI))
94214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        || (mStreamMask & ~streamMask & STREAMTYPE_AUDIO)) {
94314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changedMask |= STREAMTYPE_AUDIO;
94414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
94514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (((mStreamMask & streamMask & STREAMTYPE_VIDEO)
94614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                && !(videoURI == mVideoURI))
94714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        || (mStreamMask & ~streamMask & STREAMTYPE_VIDEO)) {
94814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changedMask |= STREAMTYPE_VIDEO;
949b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    }
950b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
95114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (changedMask == 0) {
95214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // If nothing changed as far as the audio/video decoders
95314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // are concerned we can proceed.
95414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        onChangeConfiguration3(msg);
95514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return;
95614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
95743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
95814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Something changed, inform the player which will shutdown the
95914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // corresponding decoders and will post the reply once that's done.
96014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Handling the reply will continue executing below in
96114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // onChangeConfiguration3.
96214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> notify = mNotify->dup();
96314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setInt32("what", kWhatStreamsChanged);
96414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setInt32("changedMask", changedMask);
96520f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber
96614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setWhat(kWhatChangeConfiguration3);
96714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setTarget(id());
968b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
96914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setMessage("reply", msg);
97014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->post();
97114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
972b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
97314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
97414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // All remaining fetchers are still suspended, the player has shutdown
97514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // any decoders that needed it.
976b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
97714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t streamMask;
97814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
979a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
98014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString audioURI, videoURI, subtitleURI;
98114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_AUDIO) {
98214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("audioURI", &audioURI));
98314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
98414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_VIDEO) {
98514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("videoURI", &videoURI));
98614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
98714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_SUBTITLES) {
98814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("subtitleURI", &subtitleURI));
989a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
990a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
99114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t timeUs;
99214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
993a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
99414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (timeUs < 0ll) {
99514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        timeUs = mLastDequeuedTimeUs;
99614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
997dcb89b3b505522efde173c105a851c412f947178Chong Zhang    mRealTimeBaseUs = ALooper::GetNowUs() - timeUs;
998a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
99914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mStreamMask = streamMask;
100014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mAudioURI = audioURI;
100114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mVideoURI = videoURI;
100214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mSubtitleURI = subtitleURI;
1003a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
100414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Resume all existing fetchers and assign them packet sources.
100514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
100614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        const AString &uri = mFetcherInfos.keyAt(i);
10070df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
100814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        uint32_t resumeMask = 0;
10090df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
101014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> audioSource;
101114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
101214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
101314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            resumeMask |= STREAMTYPE_AUDIO;
10140df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber        }
10150df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
101614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> videoSource;
101714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
101814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
101914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            resumeMask |= STREAMTYPE_VIDEO;
10200df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber        }
10210df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
102214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> subtitleSource;
102314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
102414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
102514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            resumeMask |= STREAMTYPE_SUBTITLES;
102614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
1027a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
102814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK_NE(resumeMask, 0u);
1029a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("resuming fetchers for mask 0x%08x", resumeMask);
1031a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask &= ~resumeMask;
1033a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        mFetcherInfos.valueAt(i).mFetcher->startAsync(
103514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                audioSource, videoSource, subtitleSource);
1036a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
1037a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // streamMask now only contains the types that need a new fetcher created.
1039a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
104014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask != 0) {
104114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("creating new fetchers for mask 0x%08x", streamMask);
1042a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
1043a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
104414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    while (streamMask != 0) {
104514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        StreamType streamType = (StreamType)(streamMask & ~(streamMask - 1));
10461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
104714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        AString uri;
104814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        switch (streamType) {
104914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            case STREAMTYPE_AUDIO:
105014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                uri = audioURI;
105114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
105214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            case STREAMTYPE_VIDEO:
105314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                uri = videoURI;
105414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
105514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            case STREAMTYPE_SUBTITLES:
105614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                uri = subtitleURI;
105714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
105814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            default:
105914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                TRESPASS();
10609b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        }
10619b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
106214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str());
106314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(fetcher != NULL);
1064a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
106514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> audioSource;
106614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
106714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
106814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            audioSource->clear();
1069a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
107014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamMask &= ~STREAMTYPE_AUDIO;
1071a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
1072a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
107314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> videoSource;
107414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
107514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
107614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            videoSource->clear();
1077a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
107814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamMask &= ~STREAMTYPE_VIDEO;
1079a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
1080a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
108114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> subtitleSource;
108214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
108314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
108414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            subtitleSource->clear();
1085a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
108614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamMask &= ~STREAMTYPE_SUBTITLES;
1087a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
108814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
108914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        fetcher->startAsync(audioSource, videoSource, subtitleSource, timeUs);
1090a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
1091a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // All fetchers have now been started, the configuration change
109314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // has completed.
1094a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    scheduleCheckBandwidthEvent();
1096a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ALOGV("XXX configuration change completed.");
1098a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mReconfigurationInProgress = false;
1100a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
110114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mDisconnectReplyID != 0) {
110214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        finishDisconnect();
1103a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
110414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
1105a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
110614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() {
110714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id());
110814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setInt32("generation", mCheckBandwidthGeneration);
110914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->post(10000000ll);
1110a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
1111a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
111214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() {
111314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ++mCheckBandwidthGeneration;
1114a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
1115a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
111614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onCheckBandwidth() {
111714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mReconfigurationInProgress) {
111814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        scheduleCheckBandwidthEvent();
111914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return;
112014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
112114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
112214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    size_t bandwidthIndex = getBandwidthIndex();
112314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPrevBandwidthIndex < 0
112414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            || bandwidthIndex != (size_t)mPrevBandwidthIndex) {
112514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changeConfiguration(-1ll /* timeUs */, bandwidthIndex);
112614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
1127a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Handling the kWhatCheckBandwidth even here does _not_ automatically
112914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // schedule another one on return, only an explicit call to
113014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // scheduleCheckBandwidthEvent will do that.
113114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // This ensures that only one configuration change is ongoing at any
113214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // one time, once that completes it'll schedule another check bandwidth
113314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // event.
1134a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
1135a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
113614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) {
113714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(mInPreparationPhase);
1138a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
113914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> notify = mNotify->dup();
114014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (err == OK || err == ERROR_END_OF_STREAM) {
114114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        notify->setInt32("what", kWhatPrepared);
114214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else {
114314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        notify->setInt32("what", kWhatPreparationFailed);
114414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        notify->setInt32("err", err);
114514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
1146a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
114714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->post();
1148a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
114914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mInPreparationPhase = false;
1150b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1151b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1152a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}  // namespace android
1153a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
1154