LiveSession.cpp revision 1543d3c735a5ba4ddfcf8ab644575df13c7e30a9
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> 301b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPConnection.h> 311b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 32a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/hexdump.h> 33a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 34a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/ADebug.h> 35a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/AMessage.h> 36a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/DataSource.h> 37a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/FileSource.h> 38a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/MediaErrors.h> 391b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/MediaHTTP.h> 4014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include <media/stagefright/MetaData.h> 4114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include <media/stagefright/Utils.h> 42a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih#include <utils/Mutex.h> 441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 45a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <ctype.h> 46a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <openssl/aes.h> 477e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#include <openssl/md5.h> 48a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 49a44153c1a57202fb538659eb50706e60454d6273Andreas Hubernamespace android { 50a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 510df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas HuberLiveSession::LiveSession( 521b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<AMessage> ¬ify, uint32_t flags, 5381e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber const sp<IMediaHTTPService> &httpService) 540df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber : mNotify(notify), 550df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber mFlags(flags), 561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPService(httpService), 570df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber mInPreparationPhase(true), 581b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPDataSource(new MediaHTTP(mHTTPService->makeHTTPConnection())), 59a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mPrevBandwidthIndex(-1), 6014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mStreamMask(0), 611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mNewStreamMask(0), 621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask(0), 6314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mCheckBandwidthGeneration(0), 641543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration(0), 6514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mLastDequeuedTimeUs(0ll), 66dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs(0ll), 6714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress(false), 681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress(false), 6914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mDisconnectReplyID(0) { 7014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 718ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kAudioIndex] = StreamItem("audio"); 728ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kVideoIndex] = StreamItem("video"); 738ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kSubtitleIndex] = StreamItem("subtitle"); 7414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 758ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 768ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 788ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 79a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 80a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 81a44153c1a57202fb538659eb50706e60454d6273Andreas HuberLiveSession::~LiveSession() { 82a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 83a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihsp<ABuffer> LiveSession::createFormatChangeBuffer(bool swap) { 851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ABuffer *discontinuity = new ABuffer(0); 861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("discontinuity", ATSParser::DISCONTINUITY_FORMATCHANGE); 871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("swapPacketSource", swap); 881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("switchGeneration", mSwitchGeneration); 891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt64("timeUs", -1); 901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return discontinuity; 911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::swapPacketSource(StreamType stream) { 941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps = mPacketSources.editValueFor(stream); 951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps2 = mPacketSources2.editValueFor(stream); 961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> tmp = aps; 971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps = aps2; 981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2 = tmp; 991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2->clear(); 1001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 1011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 10214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::dequeueAccessUnit( 10314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber StreamType stream, sp<ABuffer> *accessUnit) { 10414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 1051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // return -EWOULDBLOCK to avoid halting the decoder 1061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // when switching between audio/video and audio only. 1071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return -EWOULDBLOCK; 10814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 10914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 11114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t finalResult; 11314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!packetSource->hasBufferAvailable(&finalResult)) { 11414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return finalResult == OK ? -EAGAIN : finalResult; 11514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 11614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = packetSource->dequeueAccessUnit(accessUnit); 11814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *streamStr; 12014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (stream) { 12114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_AUDIO: 12214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "audio"; 12314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 12414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_VIDEO: 12514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "video"; 12614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 12714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_SUBTITLES: 12814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "subs"; 12914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 13014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 13114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 13214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 13314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 13414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == INFO_DISCONTINUITY) { 13514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t type; 13614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK((*accessUnit)->meta()->findInt32("discontinuity", &type)); 13714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 13814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> extra; 13914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(*accessUnit)->meta()->findMessage("extra", &extra)) { 14014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra.clear(); 14114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 14214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 14314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] read discontinuity of type %d, extra = %s", 14414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr, 14514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber type, 14614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra == NULL ? "NULL" : extra->debugString().c_str()); 1471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t swap; 1491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (type == ATSParser::DISCONTINUITY_FORMATCHANGE 1501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih && (*accessUnit)->meta()->findInt32("swapPacketSource", &swap) 1511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih && swap) { 1521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 1541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK((*accessUnit)->meta()->findInt32("switchGeneration", &switchGeneration)); 1551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 1561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 1571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration == mSwitchGeneration) { 1581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(stream); 1591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg = new AMessage(kWhatSwapped, id()); 1601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("stream", stream); 1611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("switchGeneration", switchGeneration); 1621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->post(); 1631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1641543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else if (err == OK) { 167dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) { 168dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs; 169dcb89b3b505522efde173c105a851c412f947178Chong Zhang CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); 170dcb89b3b505522efde173c105a851c412f947178Chong Zhang ALOGV("[%s] read buffer at time %lld us", streamStr, timeUs); 171dcb89b3b505522efde173c105a851c412f947178Chong Zhang 172dcb89b3b505522efde173c105a851c412f947178Chong Zhang mLastDequeuedTimeUs = timeUs; 173dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 174dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else if (stream == STREAMTYPE_SUBTITLES) { 175dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt32( 176dcb89b3b505522efde173c105a851c412f947178Chong Zhang "trackIndex", mPlaylist->getSelectedIndex()); 177dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs); 178dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 17914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 18014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] encountered error %d", streamStr, err); 18114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 18214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 18314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 18414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 18514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 18614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) { 1871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // No swapPacketSource race condition; called from the same thread as dequeueAccessUnit. 18814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 18914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return UNKNOWN_ERROR; 19014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 19114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 19214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 19314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 19414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MetaData> meta = packetSource->getFormat(); 19514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 19614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (meta == NULL) { 19714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return -EAGAIN; 19814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 19914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 20014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return convertMetaDataToMessage(meta, format); 201a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 202a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 20314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::connectAsync( 204ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 205a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatConnect, id()); 206a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setString("url", url); 207ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 208ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (headers != NULL) { 209ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber msg->setPointer( 210ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber "headers", 211ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber new KeyedVector<String8, String8>(*headers)); 212ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 213ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 214a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(); 215a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 216a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 21714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::disconnect() { 21814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatDisconnect, id()); 219ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 22014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 22114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 222ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 22314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 224a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 225a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 22614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::seekTo(int64_t timeUs) { 227a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatSeek, id()); 228a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setInt64("timeUs", timeUs); 229a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 23014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 23114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 23214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 23314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 234a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 235a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 236a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMessageReceived(const sp<AMessage> &msg) { 237a44153c1a57202fb538659eb50706e60454d6273Andreas Huber switch (msg->what()) { 238a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatConnect: 23914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 240a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onConnect(msg); 241a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 24214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 243a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 244a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatDisconnect: 24514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 24614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->senderAwaitsResponse(&mDisconnectReplyID)); 24714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 24814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mReconfigurationInProgress) { 24914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 25014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 25114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 25214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 253a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 25414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 255a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 25614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatSeek: 25714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 25814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t replyID; 25914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 26014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 26114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = onSeek(msg); 26214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 26314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response = new AMessage; 26414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->setInt32("err", err); 26514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 26614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->postReply(replyID); 26714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 26814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 26914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 27014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFetcherNotify: 27114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 27214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t what; 27314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("what", &what)); 27414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 27514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (what) { 27614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStarted: 27714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 27814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatPaused: 27914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStopped: 28014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 28114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (what == PlaylistFetcher::kWhatStopped) { 28214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 28314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 2841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.removeItem(uri) < 0) { 2851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // ignore duplicated kWhatStopped messages. 2861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 2871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 2881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 2891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 29014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 29114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 29214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuation != NULL) { 29314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GT(mContinuationCounter, 0); 29414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (--mContinuationCounter == 0) { 29514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation->post(); 29614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 29714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 29814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 29914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 30014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 30114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatDurationUpdate: 30214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 30314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 30414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 30514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 30614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 30714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("durationUs", &durationUs)); 30814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 30914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 31014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mDurationUs = durationUs; 31114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 31214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 31314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatError: 31514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 31614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err; 31714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("err", &err)); 31814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGE("XXX Received error %d from PlaylistFetcher.", err); 32014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 32114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 32214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(err); 32314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 32414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 3251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 3261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 32714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(err); 32814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 32914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(err); 33014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 33214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(err); 33314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 33514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatError); 33614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 33714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 33814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 33914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 34014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatTemporarilyDoneFetching: 34214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 34314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 34414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 34514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 34714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mIsPrepared = true; 34814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 35014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool allFetchersPrepared = true; 35114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 35214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mFetcherInfos.valueAt(i).mIsPrepared) { 35314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber allFetchersPrepared = false; 35414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 35514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 35614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 35714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 35814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (allFetchersPrepared) { 35914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(OK); 36014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 36114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 36214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 36314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 36414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 3651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case PlaylistFetcher::kWhatStartedAt: 3661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 3671543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 3681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 3691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 3701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 3711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 3721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 3741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Resume fetcher for the original variant; the resumed fetcher should 3751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // continue until the timestamps found in msg, which is stored by the 3761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // new fetcher to indicate where the new variant has started buffering. 3771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); i++) { 3781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih const FetcherInfo info = mFetcherInfos.valueAt(i); 3791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (info.mToBeRemoved) { 3801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->resumeUntilAsync(msg); 3811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 3841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 38614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 38714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 38814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 38914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 39114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 39214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatCheckBandwidth: 394a44153c1a57202fb538659eb50706e60454d6273Andreas Huber { 395a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t generation; 396a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findInt32("generation", &generation)); 397a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 39814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (generation != mCheckBandwidthGeneration) { 399a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 400a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 401a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 40214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onCheckBandwidth(); 403a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 404a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 405a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 406dcb89b3b505522efde173c105a851c412f947178Chong Zhang case kWhatChangeConfiguration: 407dcb89b3b505522efde173c105a851c412f947178Chong Zhang { 408dcb89b3b505522efde173c105a851c412f947178Chong Zhang onChangeConfiguration(msg); 409dcb89b3b505522efde173c105a851c412f947178Chong Zhang break; 410dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 411dcb89b3b505522efde173c105a851c412f947178Chong Zhang 41214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration2: 41314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 41414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration2(msg); 41514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 41614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 41714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 41814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration3: 41914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 42014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 42114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 42214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 42314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 42414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFinishDisconnect2: 42514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 42614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onFinishDisconnect2(); 427a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 42814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 429a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 4301543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case kWhatSwapped: 4311543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 4321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih onSwapped(msg); 4331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 4341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 435a44153c1a57202fb538659eb50706e60454d6273Andreas Huber default: 436a44153c1a57202fb538659eb50706e60454d6273Andreas Huber TRESPASS(); 437a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 438a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 439a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 440a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 441a44153c1a57202fb538659eb50706e60454d6273Andreas Huber// static 442a44153c1a57202fb538659eb50706e60454d6273Andreas Huberint LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b) { 443a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (a->mBandwidth < b->mBandwidth) { 444a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return -1; 445a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (a->mBandwidth == b->mBandwidth) { 446a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 447a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 448a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 449a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 1; 450a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 451a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 4528ca002eedc747dd854b61cbe364b52c06869273fRobert Shih// static 4538ca002eedc747dd854b61cbe364b52c06869273fRobert ShihLiveSession::StreamType LiveSession::indexToType(int idx) { 4548ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(idx >= 0 && idx < kMaxStreams); 4558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih return (StreamType)(1 << idx); 4568ca002eedc747dd854b61cbe364b52c06869273fRobert Shih} 4578ca002eedc747dd854b61cbe364b52c06869273fRobert Shih 458a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onConnect(const sp<AMessage> &msg) { 459a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString url; 460a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findString("url", &url)); 461a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 462ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber KeyedVector<String8, String8> *headers = NULL; 463ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (!msg->findPointer("headers", (void **)&headers)) { 464ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders.clear(); 465ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } else { 466ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders = *headers; 467ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 468ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber delete headers; 469ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber headers = NULL; 470ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 471ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 47214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#if 1 47353ae1640ffbfc690962f7f94694b02680c6f66cbJames Dong ALOGI("onConnect <URL suppressed>"); 47414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#else 47514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("onConnect %s", url.c_str()); 47614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#endif 477a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 478a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mMasterURL = url; 479a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 4807e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber bool dummy; 48114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist = fetchPlaylist(url.c_str(), NULL /* curPlaylistHash */, &dummy); 482ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 48314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist == NULL) { 48429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("unable to fetch master playlist '%s'.", url.c_str()); 485ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 48614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(ERROR_IO); 487ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber return; 488ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 489a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 49014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // We trust the content provider to make a reasonable choice of preferred 49114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // initial bandwidth by listing it first in the variant playlist. 49214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // At startup we really don't have a good estimate on the available 49314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // network bandwidth since we haven't tranferred any data yet. Once 49414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we have we can make a better informed choice. 49514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidth = 0; 49614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidthIndex = 0; 49714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 49814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist->isVariantPlaylist()) { 49914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mPlaylist->size(); ++i) { 500a44153c1a57202fb538659eb50706e60454d6273Andreas Huber BandwidthItem item; 501a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 50214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = i; 50314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 504a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> meta; 50514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 50614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist->itemAt(i, &uri, &meta); 507a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 508a44153c1a57202fb538659eb50706e60454d6273Andreas Huber unsigned long bandwidth; 509a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth)); 510a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 51114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (initialBandwidth == 0) { 51214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidth = item.mBandwidth; 51314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 515a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.push(item); 516a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 517a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 518a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(mBandwidthItems.size(), 0u); 519a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 520a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.sort(SortByBandwidth); 52114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 52214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mBandwidthItems.size(); ++i) { 52314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mBandwidthItems.itemAt(i).mBandwidth == initialBandwidth) { 52414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidthIndex = i; 52514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 52614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 52714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 52814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 52914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // dummy item. 53014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber BandwidthItem item; 53114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = 0; 53214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mBandwidth = 0; 53314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mBandwidthItems.push(item); 534a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 535a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 536dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration( 537dcb89b3b505522efde173c105a851c412f947178Chong Zhang 0ll /* timeUs */, initialBandwidthIndex, true /* pickTrack */); 538a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 539a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 54014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::finishDisconnect() { 54114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // No reconfiguration is currently pending, make sure none will trigger 54214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // during disconnection either. 54314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber cancelCheckBandwidthEvent(); 54414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through disconnect. 5461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (finishDisconnect, onFinishDisconnect2) 5471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 5481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 54914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 55014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 55114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 55214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 55314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id()); 554a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 55514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 55614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 557ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 55814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 55914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 56014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 56114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 56214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 56314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onFinishDisconnect2() { 56414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 56514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 56614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(ERROR_END_OF_STREAM); 56714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(ERROR_END_OF_STREAM); 56814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 56914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 57014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(ERROR_END_OF_STREAM); 57114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response = new AMessage; 57314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->setInt32("err", OK); 57414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->postReply(mDisconnectReplyID); 57614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mDisconnectReplyID = 0; 57714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 57814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { 58014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ssize_t index = mFetcherInfos.indexOfKey(uri); 58114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 58214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0) { 58314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return NULL; 58414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 58514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 58614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id()); 58714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setString("uri", uri); 5881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih notify->setInt32("switchGeneration", mSwitchGeneration); 58914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 59014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo info; 59114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mFetcher = new PlaylistFetcher(notify, this, uri); 59214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mDurationUs = -1ll; 59314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mIsPrepared = false; 5941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = false; 59514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber looper()->registerHandler(info.mFetcher); 59614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 59714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.add(uri, info); 59814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 59914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return info.mFetcher; 600a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 601a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6028dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih/* 6038dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Illustration of parameters: 6048dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 6058dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 0 `range_offset` 6068dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * +------------+-------------------------------------------------------+--+--+ 6078dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | | next block to fetch | | | 6088dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | `source` handle => `out` buffer | | | | 6098dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | 6108dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | |<----------- `range_length` / buffer capacity ----------->| | 6118dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * |<------------------------------ file_size ------------------------------->| 6128dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 6138dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Special parameter values: 6148dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - range_length == -1 means entire file 6158dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - block_size == 0 means entire range 6168dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 6178dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih */ 6182aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huberstatus_t LiveSession::fetchFile( 6192aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber const char *url, sp<ABuffer> *out, 6208dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih int64_t range_offset, int64_t range_length, 6218dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih uint32_t block_size, /* download block size */ 62297194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen sp<DataSource> *source, /* to return and reuse source */ 623784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 *actualUrl) { 6248dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih off64_t size; 6258dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<DataSource> temp_source; 6268dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (source == NULL) { 6278dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih source = &temp_source; 6288dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 629a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6308dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*source == NULL) { 6318dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (!strncasecmp(url, "file://", 7)) { 6328dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = new FileSource(url + 7); 6338dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else if (strncasecmp(url, "http://", 7) 6348dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih && strncasecmp(url, "https://", 8)) { 6358dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return ERROR_UNSUPPORTED; 6368dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else { 6378dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih KeyedVector<String8, String8> headers = mExtraHeaders; 6388dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (range_offset > 0 || range_length >= 0) { 6398dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih headers.add( 6408dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8("Range"), 6418dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8( 6428dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih StringPrintf( 6438dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih "bytes=%lld-%s", 6448dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset, 6458dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length < 0 6468dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ? "" : StringPrintf("%lld", 6478dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset + range_length - 1).c_str()).c_str())); 6488dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 6498dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t err = mHTTPDataSource->connect(url, &headers); 650a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6518dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (err != OK) { 6528dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return err; 6538dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 654a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6558dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = mHTTPDataSource; 656a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 657a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 658a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6598dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t getSizeErr = (*source)->getSize(&size); 6608dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (getSizeErr != OK) { 661a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size = 65536; 662a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 663a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6648dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); 6658dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*out == NULL) { 6668dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih buffer->setRange(0, 0); 6678dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 668a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6698dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // adjust range_length if only reading partial block 6708dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (block_size > 0 && (range_length == -1 || buffer->size() + block_size < range_length)) { 6718dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length = buffer->size() + block_size; 6728dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 673a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (;;) { 6748dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // Only resize when we don't know the size. 675a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bufferRemaining = buffer->capacity() - buffer->size(); 6768dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (bufferRemaining == 0 && getSizeErr != OK) { 677a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bufferRemaining = 32768; 678a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("increasing download buffer to %d bytes", 680a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size() + bufferRemaining); 681a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 682a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining); 683a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memcpy(copy->data(), buffer->data(), buffer->size()); 684a44153c1a57202fb538659eb50706e60454d6273Andreas Huber copy->setRange(0, buffer->size()); 685a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 686a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer = copy; 687a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 688a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6892aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber size_t maxBytesToRead = bufferRemaining; 6902aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (range_length >= 0) { 6912aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber int64_t bytesLeftInRange = range_length - buffer->size(); 6922aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (bytesLeftInRange < maxBytesToRead) { 6932aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead = bytesLeftInRange; 6942aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 6952aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (bytesLeftInRange == 0) { 6962aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber break; 6972aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 6982aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 6992aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 7002aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 7018dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) 7028dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // to help us break out of the loop. 7038dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ssize_t n = (*source)->readAt( 704a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size(), buffer->data() + buffer->size(), 7052aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead); 706a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 707a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n < 0) { 70820ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber return n; 709a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 710a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 711a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n == 0) { 712a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 713a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 714a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 715a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, buffer->size() + (size_t)n); 716a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 717a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 718a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = buffer; 719784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl != NULL) { 72097194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen *actualUrl = (*source)->getUri(); 721784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl->isEmpty()) { 722784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo *actualUrl = url; 723784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 724784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 725a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 726a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return OK; 727a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 728a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 72914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist( 73014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *url, uint8_t *curPlaylistHash, bool *unchanged) { 731b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ALOGV("fetchPlaylist '%s'", url); 732b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 7337e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = false; 7347e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 735a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 736784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 actualUrl; 73797194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen status_t err = fetchFile(url, &buffer, 0, -1, 0, NULL, &actualUrl); 738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 739a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (err != OK) { 740a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 741a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 742a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 7437e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // MD5 functionality is not available on the simulator, treat all 7447e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlists as changed. 7457e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7467e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS) 7477e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber uint8_t hash[16]; 7487e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7497e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_CTX m; 7507e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Init(&m); 7517e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Update(&m, buffer->data(), buffer->size()); 7527e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7537e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Final(hash, &m); 7547e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 75514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) { 7567e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlist unchanged 7577e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = true; 7587e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7597e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber return NULL; 7607e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 7617e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 76214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL) { 76314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber memcpy(curPlaylistHash, hash, sizeof(hash)); 76414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 7657e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif 7667e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 767a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = 768784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo new M3UParser(actualUrl.string(), buffer->data(), buffer->size()); 769a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 770a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->initCheck() != OK) { 77129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to parse .m3u8 playlist"); 7729067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber 773a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 774a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 775a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 776a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return playlist; 777a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 778a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 779a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() { 780a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return (double)rand() / RAND_MAX; 781a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 782a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 783a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() { 784a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() == 0) { 785a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 786a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 787a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 788a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1 789a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char value[PROPERTY_VALUE_MAX]; 790673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber ssize_t index = -1; 79114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 792a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char *end; 79314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtol(value, &end, 10); 79414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 79514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 79614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0 && (size_t)index >= mBandwidthItems.size()) { 79714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 798a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 799a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 800a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 80114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index < 0) { 80214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t bandwidthBps; 80314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mHTTPDataSource != NULL 80414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) { 80514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); 80614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 80714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("no bandwidth estimate."); 80814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return 0; // Pick the lowest bandwidth stream by default. 80914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 810a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 81114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 81214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.max-bw", value, NULL)) { 81314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 81414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber long maxBw = strtoul(value, &end, 10); 81514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (end > value && *end == '\0') { 81614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (maxBw > 0 && bandwidthBps > maxBw) { 81714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth capped to %ld bps", maxBw); 81814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = maxBw; 81914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 82014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 82114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 822a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 82314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Consider only 80% of the available bandwidth usable. 82414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = (bandwidthBps * 8) / 10; 82514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 82614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pick the highest bandwidth stream below or equal to estimated bandwidth. 82714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 82814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 82914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth 83014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber > (size_t)bandwidthBps) { 83114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber --index; 83214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 833a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 834a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 835a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Change bandwidth at random() 836a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = uniformRand() * mBandwidthItems.size(); 837a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 838a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // There's a 50% chance to stay on the current bandwidth and 839a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // a 50% chance to switch to the next higher bandwidth (wrapping around 840a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // to lowest) 841a44153c1a57202fb538659eb50706e60454d6273Andreas Huber const size_t kMinIndex = 0; 842a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 84314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber static ssize_t mPrevBandwidthIndex = -1; 84414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 845a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index; 846a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mPrevBandwidthIndex < 0) { 847a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 848a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (uniformRand() < 0.5) { 849a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = (size_t)mPrevBandwidthIndex; 850a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 851a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = mPrevBandwidthIndex + 1; 852a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index == mBandwidthItems.size()) { 853a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 854a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 855a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 85614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPrevBandwidthIndex = index; 857a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 858a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec 859a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 860a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 861a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) { 862a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 863a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 86414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1 86514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 86614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t index; 86714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 86814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 86914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtoul(value, &end, 10); 87014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 87114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 87214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= mBandwidthItems.size()) { 87314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 87414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 87514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 87614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = 0; 87714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 878a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else 879a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream 880a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif 881a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 88214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GE(index, 0); 88314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 884a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return index; 885a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 886a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 88714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) { 88814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 88914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 8907e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 89114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mReconfigurationInProgress) { 89214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(timeUs, getBandwidthIndex()); 8937e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 8947e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 89514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 8967e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber} 8977e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 89814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const { 89914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t maxDurationUs = 0ll; 90014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 90114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs; 902b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 90314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (fetcherDurationUs >= 0ll && fetcherDurationUs > maxDurationUs) { 90414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber maxDurationUs = fetcherDurationUs; 905a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 906a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 907a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 90814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *durationUs = maxDurationUs; 909a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 91114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 9120f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 91314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const { 91414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 91514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return getDuration(&durationUs) == OK && durationUs >= 0; 91614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 9170f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 91814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const { 91914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return false; 92014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 9210f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 922dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::getTrackInfo(Parcel *reply) const { 923dcb89b3b505522efde173c105a851c412f947178Chong Zhang return mPlaylist->getTrackInfo(reply); 924dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 925dcb89b3b505522efde173c105a851c412f947178Chong Zhang 926dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) { 927dcb89b3b505522efde173c105a851c412f947178Chong Zhang status_t err = mPlaylist->selectTrack(index, select); 928dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (err == OK) { 929dcb89b3b505522efde173c105a851c412f947178Chong Zhang (new AMessage(kWhatChangeConfiguration, id()))->post(); 930dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 931dcb89b3b505522efde173c105a851c412f947178Chong Zhang return err; 932dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 933dcb89b3b505522efde173c105a851c412f947178Chong Zhang 9341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchUp() { 9351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds. 9361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih status_t err = OK; 9371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mPacketSources.size(); ++i) { 9381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> source = mPacketSources.valueAt(i); 9391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t dur = source->getBufferedDurationUs(&err); 9401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (err == OK && dur > 10000000) { 9411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 9421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 9431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 9441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 9451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 9461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 947dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration( 948dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs, size_t bandwidthIndex, bool pickTrack) { 9491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through reconfiguration. 9501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (changeConfiguration, onChangeConfiguration2, onChangeConfiguration3). 9511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 9521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 95314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(!mReconfigurationInProgress); 95414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = true; 955a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 95614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPrevBandwidthIndex = bandwidthIndex; 95743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 958dcb89b3b505522efde173c105a851c412f947178Chong Zhang ALOGV("changeConfiguration => timeUs:%lld us, bwIndex:%d, pickTrack:%d", 959dcb89b3b505522efde173c105a851c412f947178Chong Zhang timeUs, bandwidthIndex, pickTrack); 96043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 961dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (pickTrack) { 962dcb89b3b505522efde173c105a851c412f947178Chong Zhang mPlaylist->pickRandomMediaItems(); 963dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 96443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 96514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_LT(bandwidthIndex, mBandwidthItems.size()); 96614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex); 967a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask = 0; // streams that should be fetched by the new fetcher 9691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t resumeMask = 0; // streams that should be fetched by the original fetcher 970a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9718ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 9728ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 9738ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) { 9748ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask |= indexToType(i); 9758ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 97614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 977aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 97814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Step 1, stop and discard fetchers that are no longer needed. 97914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pause those that we'll reuse. 98014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 98114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 982aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 98314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool discardFetcher = true; 984aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 98514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If we're seeking all current fetchers are discarded. 98614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 9871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // delay fetcher removal 9881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discardFetcher = false; 9891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 9908ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 9911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType type = indexToType(j); 9921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((streamMask & type) && uri == URIs[j]) { 9931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih resumeMask |= type; 9941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih streamMask &= ~type; 9958ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 9966801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 99714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 998a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 99914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (discardFetcher) { 100014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 10016801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } else { 100214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->pauseAsync(); 10036801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 1004a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1005a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 10061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg; 10071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (timeUs < 0ll) { 10081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // skip onChangeConfiguration2 (decoder destruction) if switching. 10091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration3, id()); 10101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 10111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration2, id()); 10121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 101314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("streamMask", streamMask); 10141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("resumeMask", resumeMask); 101514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt64("timeUs", timeUs); 10168ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 10178ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 10188ca002eedc747dd854b61cbe364b52c06869273fRobert Shih msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str()); 10198ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 10206e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 1021a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 102214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Every time a fetcher acknowledges the stopAsync or pauseAsync request 102314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we'll decrement mContinuationCounter, once it reaches zero, i.e. all 102414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // fetchers have completed their asynchronous operation, we'll post 102514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // mContinuation, which then is handled below in onChangeConfiguration2. 102614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 102714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 102888b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 102914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 103014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 103188b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber } 103214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1033a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1034dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) { 1035dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (!mReconfigurationInProgress) { 1036dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration(-1ll /* timeUs */, getBandwidthIndex()); 1037dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else { 1038dcb89b3b505522efde173c105a851c412f947178Chong Zhang msg->post(1000000ll); // retry in 1 sec 1039dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1040dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1041dcb89b3b505522efde173c105a851c412f947178Chong Zhang 104214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { 104314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 1044bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 104514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers are either suspended or have been removed now. 1046bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 104714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t streamMask; 104814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 1049bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 10508ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 10518ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 10528ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 10538ca002eedc747dd854b61cbe364b52c06869273fRobert Shih const AString &uriKey = mStreams[i].uriKey(); 10548ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(uriKey.c_str(), &URIs[i])); 10558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str()); 10568ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 105722fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 10583831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 105914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Determine which decoders to shutdown on the player side, 106014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // a decoder has to be shutdown if either 106114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 1) its streamtype was active before but now longer isn't. 106214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // or 106314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 2) its streamtype was already active and still is but the URI 106414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has changed. 106514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t changedMask = 0; 10668ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) { 10678ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (((mStreamMask & streamMask & indexToType(i)) 10688ca002eedc747dd854b61cbe364b52c06869273fRobert Shih && !(URIs[i] == mStreams[i].mUri)) 10698ca002eedc747dd854b61cbe364b52c06869273fRobert Shih || (mStreamMask & ~streamMask & indexToType(i))) { 10708ca002eedc747dd854b61cbe364b52c06869273fRobert Shih changedMask |= indexToType(i); 10718ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1072b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } 1073b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 107414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (changedMask == 0) { 107514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If nothing changed as far as the audio/video decoders 107614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // are concerned we can proceed. 107714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 107814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return; 107914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 108043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 108114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Something changed, inform the player which will shutdown the 108214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // corresponding decoders and will post the reply once that's done. 108314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the reply will continue executing below in 108414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // onChangeConfiguration3. 108514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 108614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatStreamsChanged); 108714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("changedMask", changedMask); 108820f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber 108914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setWhat(kWhatChangeConfiguration3); 109014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setTarget(id()); 1091b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 109214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setMessage("reply", msg); 109314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 109414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1095b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 109614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { 10971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mContinuation.clear(); 109814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All remaining fetchers are still suspended, the player has shutdown 109914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // any decoders that needed it. 1100b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 11011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask, resumeMask; 110214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 11031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1104a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11058ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 11068ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 11078ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri)); 11088ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1109a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1110a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 111114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 11121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool switching = false; 111314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 1114a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 111514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 111614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber timeUs = mLastDequeuedTimeUs; 11171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih switching = true; 111814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1119dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 1120a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mNewStreamMask = streamMask; 1122a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Of all existing fetchers: 11241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Resume fetchers that are still needed and assign them original packet sources. 11251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Mark otherwise unneeded fetchers for removal. 11261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ALOGV("resuming fetchers for mask 0x%08x", resumeMask); 112714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 11290df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber 11308ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 1131dc793ce8c0ead27ab43e40ce09f27fe338323502Robert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 11321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) { 11338ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 11348ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 113514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1136a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih FetcherInfo &info = mFetcherInfos.editValueAt(i); 11381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL 11391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih || sources[kSubtitleIndex] != NULL) { 11401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->startAsync( 11411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]); 11421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 11431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = true; 11441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1145a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1146a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 114714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // streamMask now only contains the types that need a new fetcher created. 1148a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 114914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (streamMask != 0) { 115014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("creating new fetchers for mask 0x%08x", streamMask); 1151a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1152a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Find out when the original fetchers have buffered up to and start the new fetchers 11541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // at a later timestamp. 11558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; i++) { 11568ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (!(indexToType(i) & streamMask)) { 11578ca002eedc747dd854b61cbe364b52c06869273fRobert Shih continue; 11588ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 11591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 116014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 11618ca002eedc747dd854b61cbe364b52c06869273fRobert Shih uri = mStreams[i].mUri; 11629b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 116314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str()); 116414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(fetcher != NULL); 1165a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t latestSeq = -1; 11671543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t latestTimeUs = 0ll; 11688ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 11691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11708ca002eedc747dd854b61cbe364b52c06869273fRobert Shih // TRICKY: looping from i as earlier streams are already removed from streamMask 11718ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = i; j < kMaxStreams; ++j) { 11728ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if ((streamMask & indexToType(j)) && uri == mStreams[j].mUri) { 11738ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 11741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (!switching) { 11761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 11771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 11781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t type, seq; 11791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t srcTimeUs; 11801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> meta = sources[j]->getLatestMeta(); 11811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (meta != NULL && !meta->findInt32("discontinuity", &type)) { 11831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(meta->findInt32("seq", &seq)); 11841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (seq > latestSeq) { 11851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestSeq = seq; 11861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(meta->findInt64("timeUs", &srcTimeUs)); 11881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (srcTimeUs > latestTimeUs) { 11891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestTimeUs = srcTimeUs; 11901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j] = mPacketSources2.valueFor(indexToType(j)); 11941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 11951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 11961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (extraStreams & indexToType(j)) { 11971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->queueAccessUnit(createFormatChangeBuffer(/* swap = */ false)); 11981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1200a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12018ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask &= ~indexToType(j); 12028ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1203a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 120414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 12058ca002eedc747dd854b61cbe364b52c06869273fRobert Shih fetcher->startAsync( 12068ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kAudioIndex], 12078ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kVideoIndex], 12088ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kSubtitleIndex], 12091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih timeUs, 12101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestTimeUs /* min start time(us) */, 12111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestSeq >= 0 ? latestSeq + 1 : -1 /* starting sequence number hint */ ); 1212a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1213a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 121414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers have now been started, the configuration change 121514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has completed. 1216a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 121714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber scheduleCheckBandwidthEvent(); 1218a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 121914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("XXX configuration change completed."); 122014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = false; 12211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switching) { 12221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = true; 12231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 12241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 12251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1226a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 122714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mDisconnectReplyID != 0) { 122814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 1229a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 123014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1231a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onSwapped(const sp<AMessage> &msg) { 12331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 12341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 12351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 12361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 12371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t stream; 12401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("stream", &stream)); 12411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask |= stream; 12421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mSwapMask != mStreamMask) { 12431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 12441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Check if new variant contains extra streams. 12471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 12481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih while (extraStreams) { 12491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType extraStream = (StreamType) (extraStreams & ~(extraStreams - 1)); 12501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(extraStream); 12511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih extraStreams &= ~extraStream; 12521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 12551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 12561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// Mark switch done when: 12581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// 1. all old buffers are swapped out, AND 12591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// 2. all old fetchers are removed. 12601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::tryToFinishBandwidthSwitch() { 12611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool needToRemoveFetchers = false; 12621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 12631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.valueAt(i).mToBeRemoved) { 12641543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih needToRemoveFetchers = true; 12651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 12661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12671543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (!needToRemoveFetchers && mSwapMask == mStreamMask) { 12691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 12701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 12711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 12721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 12741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 127514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() { 127614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id()); 127714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("generation", mCheckBandwidthGeneration); 127814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(10000000ll); 1279a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1280a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 128114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() { 128214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ++mCheckBandwidthGeneration; 1283a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1284a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::cancelBandwidthSwitch() { 12861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 12871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration++; 12881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 12891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 12901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 12911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) { 12931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress) { 12941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 12951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mPrevBandwidthIndex < 0) { 12981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 129914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 130014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 13011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (bandwidthIndex == (size_t)mPrevBandwidthIndex) { 13021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 13031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else if (bandwidthIndex > (size_t)mPrevBandwidthIndex) { 13041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return canSwitchUp(); 13051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 13061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 13071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 13081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 13091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 13101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onCheckBandwidth() { 131114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t bandwidthIndex = getBandwidthIndex(); 13121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (canSwitchBandwidthTo(bandwidthIndex)) { 131314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(-1ll /* timeUs */, bandwidthIndex); 13141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 13151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih scheduleCheckBandwidthEvent(); 131614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1317a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 131814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the kWhatCheckBandwidth even here does _not_ automatically 131914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // schedule another one on return, only an explicit call to 132014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // scheduleCheckBandwidthEvent will do that. 132114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // This ensures that only one configuration change is ongoing at any 132214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // one time, once that completes it'll schedule another check bandwidth 132314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // event. 1324a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1325a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 132614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) { 132714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(mInPreparationPhase); 1328a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 132914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 133014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == OK || err == ERROR_END_OF_STREAM) { 133114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPrepared); 133214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 133314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPreparationFailed); 133414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 133514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1336a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 133714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 1338a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 133914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mInPreparationPhase = false; 1340b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber} 1341b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1342a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} // namespace android 1343a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1344