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, 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