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,
5172aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        int64_t range_offset, int64_t range_length) {
518a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    *out = NULL;
519a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
520a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<DataSource> source;
521a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
522a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (!strncasecmp(url, "file://", 7)) {
523a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        source = new FileSource(url + 7);
5248cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber    } else if (strncasecmp(url, "http://", 7)
5258cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber            && strncasecmp(url, "https://", 8)) {
526df42f949c8bd05b81d94633767514fff88f52062Andreas Huber        return ERROR_UNSUPPORTED;
527a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else {
5282aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        KeyedVector<String8, String8> headers = mExtraHeaders;
5292aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        if (range_offset > 0 || range_length >= 0) {
5302aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            headers.add(
5312aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                    String8("Range"),
5322aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                    String8(
5332aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                        StringPrintf(
5342aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                            "bytes=%lld-%s",
5352aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                            range_offset,
5362aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                            range_length < 0
5372aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                                ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str()));
5382aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        }
5392aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        status_t err = mHTTPDataSource->connect(url, &headers);
540a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
541a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (err != OK) {
542a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            return err;
543a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
544a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
545a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        source = mHTTPDataSource;
546a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
547a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
548a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    off64_t size;
549a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    status_t err = source->getSize(&size);
550a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
551a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (err != OK) {
552a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        size = 65536;
553a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
554a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
555a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<ABuffer> buffer = new ABuffer(size);
556a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    buffer->setRange(0, 0);
557a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
558a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    for (;;) {
559a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        size_t bufferRemaining = buffer->capacity() - buffer->size();
560a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
561a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (bufferRemaining == 0) {
562a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            bufferRemaining = 32768;
563a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
5643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("increasing download buffer to %d bytes",
565a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                 buffer->size() + bufferRemaining);
566a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
567a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
568a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            memcpy(copy->data(), buffer->data(), buffer->size());
569a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            copy->setRange(0, buffer->size());
570a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
571a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            buffer = copy;
572a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
573a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
5742aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        size_t maxBytesToRead = bufferRemaining;
5752aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        if (range_length >= 0) {
5762aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            int64_t bytesLeftInRange = range_length - buffer->size();
5772aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            if (bytesLeftInRange < maxBytesToRead) {
5782aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                maxBytesToRead = bytesLeftInRange;
5792aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber
5802aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                if (bytesLeftInRange == 0) {
5812aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                    break;
5822aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                }
5832aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber            }
5842aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber        }
5852aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber
586a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        ssize_t n = source->readAt(
587a44153c1a57202fb538659eb50706e60454d6273Andreas Huber                buffer->size(), buffer->data() + buffer->size(),
5882aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber                maxBytesToRead);
589a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
590a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (n < 0) {
59120ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber            return n;
592a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
593a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
594a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (n == 0) {
595a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            break;
596a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
597a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
598a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        buffer->setRange(0, buffer->size() + (size_t)n);
599a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
600a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
601a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    *out = buffer;
602a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
603a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return OK;
604a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
605a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
60614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist(
60714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        const char *url, uint8_t *curPlaylistHash, bool *unchanged) {
608b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    ALOGV("fetchPlaylist '%s'", url);
609b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
6107e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    *unchanged = false;
6117e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
612a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<ABuffer> buffer;
613a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    status_t err = fetchFile(url, &buffer);
614a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
615a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (err != OK) {
616a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return NULL;
617a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
618a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
6197e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    // MD5 functionality is not available on the simulator, treat all
6207e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    // playlists as changed.
6217e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6227e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS)
6237e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    uint8_t hash[16];
6247e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6257e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_CTX m;
6267e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_Init(&m);
6277e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_Update(&m, buffer->data(), buffer->size());
6287e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6297e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    MD5_Final(hash, &m);
6307e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
63114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) {
6327e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber        // playlist unchanged
6337e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber        *unchanged = true;
6347e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Playlist unchanged, refresh state is now %d",
6367e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber             (int)mRefreshState);
6377e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
6387e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber        return NULL;
6397e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    }
6407e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
64114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (curPlaylistHash != NULL) {
64214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        memcpy(curPlaylistHash, hash, sizeof(hash));
64314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
6447e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif
6457e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
646a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    sp<M3UParser> playlist =
647a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        new M3UParser(url, buffer->data(), buffer->size());
648a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
649a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (playlist->initCheck() != OK) {
65029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("failed to parse .m3u8 playlist");
6519067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber
652a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return NULL;
653a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
654a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
655a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return playlist;
656a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
657a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
658a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() {
659a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return (double)rand() / RAND_MAX;
660a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
661a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
662a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() {
663a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mBandwidthItems.size() == 0) {
664a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        return 0;
665a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
666a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
667a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1
668a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    char value[PROPERTY_VALUE_MAX];
669673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber    ssize_t index = -1;
67014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (property_get("media.httplive.bw-index", value, NULL)) {
671a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        char *end;
67214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = strtol(value, &end, 10);
67314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(end > value && *end == '\0');
67414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
67514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (index >= 0 && (size_t)index >= mBandwidthItems.size()) {
67614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            index = mBandwidthItems.size() - 1;
677a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
678a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
679a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
68014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (index < 0) {
68114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        int32_t bandwidthBps;
68214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (mHTTPDataSource != NULL
68314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) {
68414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f);
68514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        } else {
68614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            ALOGV("no bandwidth estimate.");
68714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            return 0;  // Pick the lowest bandwidth stream by default.
68814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
689a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
69014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        char value[PROPERTY_VALUE_MAX];
69114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (property_get("media.httplive.max-bw", value, NULL)) {
69214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            char *end;
69314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            long maxBw = strtoul(value, &end, 10);
69414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (end > value && *end == '\0') {
69514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                if (maxBw > 0 && bandwidthBps > maxBw) {
69614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    ALOGV("bandwidth capped to %ld bps", maxBw);
69714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    bandwidthBps = maxBw;
69814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                }
69914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            }
70014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
701a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
70214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // Consider only 80% of the available bandwidth usable.
70314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        bandwidthBps = (bandwidthBps * 8) / 10;
70414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
70514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // Pick the highest bandwidth stream below or equal to estimated bandwidth.
70614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
70714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = mBandwidthItems.size() - 1;
70814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth
70914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                > (size_t)bandwidthBps) {
71014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            --index;
71114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
712a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
713a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0
714a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // Change bandwidth at random()
715a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index = uniformRand() * mBandwidthItems.size();
716a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0
717a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // There's a 50% chance to stay on the current bandwidth and
718a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // a 50% chance to switch to the next higher bandwidth (wrapping around
719a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // to lowest)
720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    const size_t kMinIndex = 0;
721a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
72214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    static ssize_t mPrevBandwidthIndex = -1;
72314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
724a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index;
725a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    if (mPrevBandwidthIndex < 0) {
726a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        index = kMinIndex;
727a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else if (uniformRand() < 0.5) {
728a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        index = (size_t)mPrevBandwidthIndex;
729a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    } else {
730a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        index = mPrevBandwidthIndex + 1;
731a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        if (index == mBandwidthItems.size()) {
732a44153c1a57202fb538659eb50706e60454d6273Andreas Huber            index = kMinIndex;
733a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
734a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
73514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPrevBandwidthIndex = index;
736a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0
737a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec
738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
739a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index = mBandwidthItems.size() - 1;
740a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) {
741a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        --index;
742a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
74314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1
74414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    char value[PROPERTY_VALUE_MAX];
74514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    size_t index;
74614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (property_get("media.httplive.bw-index", value, NULL)) {
74714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        char *end;
74814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = strtoul(value, &end, 10);
74914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(end > value && *end == '\0');
75014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
75114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (index >= mBandwidthItems.size()) {
75214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            index = mBandwidthItems.size() - 1;
75314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
75414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else {
75514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        index = 0;
75614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
757a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else
758a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    size_t index = mBandwidthItems.size() - 1;  // Highest bandwidth stream
759a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif
760a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
76114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK_GE(index, 0);
76214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
763a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    return index;
764a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
765a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
76614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) {
76714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t timeUs;
76814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
7697e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
77014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (!mReconfigurationInProgress) {
77114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changeConfiguration(timeUs, getBandwidthIndex());
7727e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber    }
7737e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
77414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return OK;
7757e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber}
7767e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber
77714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const {
77814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t maxDurationUs = 0ll;
77914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
78014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs;
781b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
78214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (fetcherDurationUs >= 0ll && fetcherDurationUs > maxDurationUs) {
78314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            maxDurationUs = fetcherDurationUs;
784a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
785a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
786a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
78714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    *durationUs = maxDurationUs;
788a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
78914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return OK;
79014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
7910f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber
79214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const {
79314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t durationUs;
79414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return getDuration(&durationUs) == OK && durationUs >= 0;
79514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
7960f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber
79714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const {
79814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    return false;
79914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
8000f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber
801dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::getTrackInfo(Parcel *reply) const {
802dcb89b3b505522efde173c105a851c412f947178Chong Zhang    return mPlaylist->getTrackInfo(reply);
803dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
804dcb89b3b505522efde173c105a851c412f947178Chong Zhang
805dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) {
806dcb89b3b505522efde173c105a851c412f947178Chong Zhang    status_t err = mPlaylist->selectTrack(index, select);
807dcb89b3b505522efde173c105a851c412f947178Chong Zhang    if (err == OK) {
808dcb89b3b505522efde173c105a851c412f947178Chong Zhang        (new AMessage(kWhatChangeConfiguration, id()))->post();
809dcb89b3b505522efde173c105a851c412f947178Chong Zhang    }
810dcb89b3b505522efde173c105a851c412f947178Chong Zhang    return err;
811dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
812dcb89b3b505522efde173c105a851c412f947178Chong Zhang
813dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration(
814dcb89b3b505522efde173c105a851c412f947178Chong Zhang        int64_t timeUs, size_t bandwidthIndex, bool pickTrack) {
81514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(!mReconfigurationInProgress);
81614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mReconfigurationInProgress = true;
817a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
81814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mPrevBandwidthIndex = bandwidthIndex;
81943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
820dcb89b3b505522efde173c105a851c412f947178Chong Zhang    ALOGV("changeConfiguration => timeUs:%lld us, bwIndex:%d, pickTrack:%d",
821dcb89b3b505522efde173c105a851c412f947178Chong Zhang          timeUs, bandwidthIndex, pickTrack);
82243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
823dcb89b3b505522efde173c105a851c412f947178Chong Zhang    if (pickTrack) {
824dcb89b3b505522efde173c105a851c412f947178Chong Zhang        mPlaylist->pickRandomMediaItems();
825dcb89b3b505522efde173c105a851c412f947178Chong Zhang    }
82643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
82714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK_LT(bandwidthIndex, mBandwidthItems.size());
82814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex);
829a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
83014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t streamMask = 0;
831a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
83214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString audioURI;
83314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->getAudioURI(item.mPlaylistIndex, &audioURI)) {
83414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask |= STREAMTYPE_AUDIO;
835a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
836a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
83714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString videoURI;
83814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->getVideoURI(item.mPlaylistIndex, &videoURI)) {
83914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask |= STREAMTYPE_VIDEO;
840a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
841a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
84214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString subtitleURI;
84314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPlaylist->getSubtitleURI(item.mPlaylistIndex, &subtitleURI)) {
84414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask |= STREAMTYPE_SUBTITLES;
84514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
846aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber
84714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Step 1, stop and discard fetchers that are no longer needed.
84814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Pause those that we'll reuse.
84914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
85014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        const AString &uri = mFetcherInfos.keyAt(i);
851aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber
85214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        bool discardFetcher = true;
853aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber
85414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // If we're seeking all current fetchers are discarded.
85514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (timeUs < 0ll) {
85614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            if (((streamMask & STREAMTYPE_AUDIO) && uri == audioURI)
85714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    || ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI)
85814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    || ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI)) {
85914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                discardFetcher = false;
8606801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber            }
86114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
862a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
86314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if (discardFetcher) {
86414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            mFetcherInfos.valueAt(i).mFetcher->stopAsync();
8656801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber        } else {
86614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            mFetcherInfos.valueAt(i).mFetcher->pauseAsync();
8676801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber        }
868a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
869a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
87014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatChangeConfiguration2, id());
87114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setInt32("streamMask", streamMask);
87214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setInt64("timeUs", timeUs);
87314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_AUDIO) {
87414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->setString("audioURI", audioURI.c_str());
875a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
87614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_VIDEO) {
87714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->setString("videoURI", videoURI.c_str());
8782aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber    }
87914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_SUBTITLES) {
88014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->setString("subtitleURI", subtitleURI.c_str());
8816e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber    }
882a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
88314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Every time a fetcher acknowledges the stopAsync or pauseAsync request
88414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // we'll decrement mContinuationCounter, once it reaches zero, i.e. all
88514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // fetchers have completed their asynchronous operation, we'll post
88614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // mContinuation, which then is handled below in onChangeConfiguration2.
88714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuationCounter = mFetcherInfos.size();
88814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuation = msg;
88988b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber
89014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mContinuationCounter == 0) {
89114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        msg->post();
89288b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber    }
89314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
894a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
895dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) {
896dcb89b3b505522efde173c105a851c412f947178Chong Zhang    if (!mReconfigurationInProgress) {
897dcb89b3b505522efde173c105a851c412f947178Chong Zhang        changeConfiguration(-1ll /* timeUs */, getBandwidthIndex());
898dcb89b3b505522efde173c105a851c412f947178Chong Zhang    } else {
899dcb89b3b505522efde173c105a851c412f947178Chong Zhang        msg->post(1000000ll); // retry in 1 sec
900dcb89b3b505522efde173c105a851c412f947178Chong Zhang    }
901dcb89b3b505522efde173c105a851c412f947178Chong Zhang}
902dcb89b3b505522efde173c105a851c412f947178Chong Zhang
90314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
90414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mContinuation.clear();
905bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
90614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // All fetchers are either suspended or have been removed now.
907bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
90814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t streamMask;
90914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
910bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
91114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString audioURI, videoURI, subtitleURI;
91214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_AUDIO) {
91314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("audioURI", &audioURI));
91414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("audioURI = '%s'", audioURI.c_str());
915a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
91614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_VIDEO) {
91714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("videoURI", &videoURI));
91814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("videoURI = '%s'", videoURI.c_str());
91922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    }
92014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_SUBTITLES) {
92114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("subtitleURI", &subtitleURI));
92214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("subtitleURI = '%s'", subtitleURI.c_str());
92322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    }
9243831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
92514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Determine which decoders to shutdown on the player side,
92614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // a decoder has to be shutdown if either
92714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // 1) its streamtype was active before but now longer isn't.
92814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // or
92914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // 2) its streamtype was already active and still is but the URI
93014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    //    has changed.
93114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t changedMask = 0;
93214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (((mStreamMask & streamMask & STREAMTYPE_AUDIO)
93314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                && !(audioURI == mAudioURI))
93414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        || (mStreamMask & ~streamMask & STREAMTYPE_AUDIO)) {
93514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changedMask |= STREAMTYPE_AUDIO;
93614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
93714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (((mStreamMask & streamMask & STREAMTYPE_VIDEO)
93814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                && !(videoURI == mVideoURI))
93914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        || (mStreamMask & ~streamMask & STREAMTYPE_VIDEO)) {
94014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changedMask |= STREAMTYPE_VIDEO;
941b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    }
942b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
94314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (changedMask == 0) {
94414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // If nothing changed as far as the audio/video decoders
94514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        // are concerned we can proceed.
94614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        onChangeConfiguration3(msg);
94714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return;
94814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
94943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
95014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Something changed, inform the player which will shutdown the
95114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // corresponding decoders and will post the reply once that's done.
95214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Handling the reply will continue executing below in
95314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // onChangeConfiguration3.
95414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> notify = mNotify->dup();
95514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setInt32("what", kWhatStreamsChanged);
95614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setInt32("changedMask", changedMask);
95720f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber
95814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setWhat(kWhatChangeConfiguration3);
95914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setTarget(id());
960b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
96114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->setMessage("reply", msg);
96214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->post();
96314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
964b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
96514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
96614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // All remaining fetchers are still suspended, the player has shutdown
96714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // any decoders that needed it.
968b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
96914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t streamMask;
97014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
971a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
97214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString audioURI, videoURI, subtitleURI;
97314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_AUDIO) {
97414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("audioURI", &audioURI));
97514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
97614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_VIDEO) {
97714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("videoURI", &videoURI));
97814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
97914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask & STREAMTYPE_SUBTITLES) {
98014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(msg->findString("subtitleURI", &subtitleURI));
981a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
982a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
98314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t timeUs;
98414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
985a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
98614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (timeUs < 0ll) {
98714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        timeUs = mLastDequeuedTimeUs;
98814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
989dcb89b3b505522efde173c105a851c412f947178Chong Zhang    mRealTimeBaseUs = ALooper::GetNowUs() - timeUs;
990a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
99114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mStreamMask = streamMask;
99214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mAudioURI = audioURI;
99314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mVideoURI = videoURI;
99414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mSubtitleURI = subtitleURI;
995a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
99614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Resume all existing fetchers and assign them packet sources.
99714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
99814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        const AString &uri = mFetcherInfos.keyAt(i);
9990df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
100014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        uint32_t resumeMask = 0;
10010df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
100214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> audioSource;
100314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
100414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
100514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            resumeMask |= STREAMTYPE_AUDIO;
10060df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber        }
10070df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
100814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> videoSource;
100914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
101014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
101114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            resumeMask |= STREAMTYPE_VIDEO;
10120df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber        }
10130df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber
101414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> subtitleSource;
101514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
101614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
101714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            resumeMask |= STREAMTYPE_SUBTITLES;
101814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        }
1019a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
102014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK_NE(resumeMask, 0u);
1021a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
102214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("resuming fetchers for mask 0x%08x", resumeMask);
1023a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
102414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        streamMask &= ~resumeMask;
1025a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
102614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        mFetcherInfos.valueAt(i).mFetcher->startAsync(
102714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                audioSource, videoSource, subtitleSource);
1028a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
1029a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // streamMask now only contains the types that need a new fetcher created.
1031a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (streamMask != 0) {
103314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        ALOGV("creating new fetchers for mask 0x%08x", streamMask);
1034a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
1035a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
103614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    while (streamMask != 0) {
103714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        StreamType streamType = (StreamType)(streamMask & ~(streamMask - 1));
10381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
103914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        AString uri;
104014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        switch (streamType) {
104114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            case STREAMTYPE_AUDIO:
104214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                uri = audioURI;
104314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
104414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            case STREAMTYPE_VIDEO:
104514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                uri = videoURI;
104614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
104714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            case STREAMTYPE_SUBTITLES:
104814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                uri = subtitleURI;
104914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                break;
105014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            default:
105114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                TRESPASS();
10529b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        }
10539b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
105414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str());
105514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        CHECK(fetcher != NULL);
1056a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
105714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> audioSource;
105814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
105914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
106014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            audioSource->clear();
1061a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
106214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamMask &= ~STREAMTYPE_AUDIO;
1063a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
1064a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
106514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> videoSource;
106614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
106714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
106814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            videoSource->clear();
1069a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
107014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamMask &= ~STREAMTYPE_VIDEO;
1071a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
1072a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
107314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        sp<AnotherPacketSource> subtitleSource;
107414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
107514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
107614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            subtitleSource->clear();
1077a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
107814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            streamMask &= ~STREAMTYPE_SUBTITLES;
1079a44153c1a57202fb538659eb50706e60454d6273Andreas Huber        }
108014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
108114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        fetcher->startAsync(audioSource, videoSource, subtitleSource, timeUs);
1082a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
1083a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
108414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // All fetchers have now been started, the configuration change
108514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // has completed.
1086a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
108714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    scheduleCheckBandwidthEvent();
1088a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
108914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ALOGV("XXX configuration change completed.");
1090a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mReconfigurationInProgress = false;
1092a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mDisconnectReplyID != 0) {
109414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        finishDisconnect();
1095a44153c1a57202fb538659eb50706e60454d6273Andreas Huber    }
109614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}
1097a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
109814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() {
109914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id());
110014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->setInt32("generation", mCheckBandwidthGeneration);
110114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    msg->post(10000000ll);
1102a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
1103a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
110414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() {
110514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    ++mCheckBandwidthGeneration;
1106a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
1107a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
110814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onCheckBandwidth() {
110914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mReconfigurationInProgress) {
111014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        scheduleCheckBandwidthEvent();
111114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        return;
111214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
111314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
111414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    size_t bandwidthIndex = getBandwidthIndex();
111514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (mPrevBandwidthIndex < 0
111614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            || bandwidthIndex != (size_t)mPrevBandwidthIndex) {
111714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        changeConfiguration(-1ll /* timeUs */, bandwidthIndex);
111814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
1119a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
112014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Handling the kWhatCheckBandwidth even here does _not_ automatically
112114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // schedule another one on return, only an explicit call to
112214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // scheduleCheckBandwidthEvent will do that.
112314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // This ensures that only one configuration change is ongoing at any
112414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // one time, once that completes it'll schedule another check bandwidth
112514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // event.
1126a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}
1127a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) {
112914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    CHECK(mInPreparationPhase);
1130a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
113114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> notify = mNotify->dup();
113214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    if (err == OK || err == ERROR_END_OF_STREAM) {
113314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        notify->setInt32("what", kWhatPrepared);
113414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    } else {
113514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        notify->setInt32("what", kWhatPreparationFailed);
113614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        notify->setInt32("err", err);
113714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    }
1138a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
113914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    notify->post();
1140a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
114114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    mInPreparationPhase = false;
1142b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber}
1143b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
1144a44153c1a57202fb538659eb50706e60454d6273Andreas Huber}  // namespace android
1145a44153c1a57202fb538659eb50706e60454d6273Andreas Huber
1146