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