LiveSession.cpp revision a1df816c0677185534babba6ffc29970b048e52e
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> 46b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h> 47a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <openssl/aes.h> 487e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#include <openssl/md5.h> 49a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 50a44153c1a57202fb538659eb50706e60454d6273Andreas Hubernamespace android { 51a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 520df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas HuberLiveSession::LiveSession( 531b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<AMessage> ¬ify, uint32_t flags, 5481e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber const sp<IMediaHTTPService> &httpService) 550df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber : mNotify(notify), 560df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber mFlags(flags), 571b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPService(httpService), 580df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber mInPreparationPhase(true), 591b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPDataSource(new MediaHTTP(mHTTPService->makeHTTPConnection())), 60a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mPrevBandwidthIndex(-1), 6114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mStreamMask(0), 621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mNewStreamMask(0), 631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask(0), 6414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mCheckBandwidthGeneration(0), 651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration(0), 6614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mLastDequeuedTimeUs(0ll), 67dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs(0ll), 6814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress(false), 691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress(false), 705ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mDisconnectReplyID(0), 715ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReplyID(0) { 7214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 738ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kAudioIndex] = StreamItem("audio"); 748ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kVideoIndex] = StreamItem("video"); 75e4f25c280a8f1655c31a745978e0fcbc61f91deeRobert Shih mStreams[kSubtitleIndex] = StreamItem("subtitles"); 7614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 778ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 788ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 808ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 81a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 82a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 83a44153c1a57202fb538659eb50706e60454d6273Andreas HuberLiveSession::~LiveSession() { 84a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 85a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihsp<ABuffer> LiveSession::createFormatChangeBuffer(bool swap) { 871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ABuffer *discontinuity = new ABuffer(0); 881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("discontinuity", ATSParser::DISCONTINUITY_FORMATCHANGE); 891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("swapPacketSource", swap); 901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("switchGeneration", mSwitchGeneration); 911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt64("timeUs", -1); 921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return discontinuity; 931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::swapPacketSource(StreamType stream) { 961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps = mPacketSources.editValueFor(stream); 971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps2 = mPacketSources2.editValueFor(stream); 981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> tmp = aps; 991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps = aps2; 1001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2 = tmp; 1011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2->clear(); 1021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 1031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 10414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::dequeueAccessUnit( 10514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber StreamType stream, sp<ABuffer> *accessUnit) { 10614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 1071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // return -EWOULDBLOCK to avoid halting the decoder 1081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // when switching between audio/video and audio only. 1091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return -EWOULDBLOCK; 11014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 11114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 11314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t finalResult; 11514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!packetSource->hasBufferAvailable(&finalResult)) { 11614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return finalResult == OK ? -EAGAIN : finalResult; 11714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 11814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 11914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = packetSource->dequeueAccessUnit(accessUnit); 12014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 12114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *streamStr; 12214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (stream) { 12314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_AUDIO: 12414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "audio"; 12514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 12614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_VIDEO: 12714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "video"; 12814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 12914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_SUBTITLES: 13014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "subs"; 13114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 13214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 13314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 13414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 13514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 13614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == INFO_DISCONTINUITY) { 13714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t type; 13814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK((*accessUnit)->meta()->findInt32("discontinuity", &type)); 13914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 14014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> extra; 14114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(*accessUnit)->meta()->findMessage("extra", &extra)) { 14214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra.clear(); 14314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 14414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 14514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] read discontinuity of type %d, extra = %s", 14614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr, 14714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber type, 14814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra == NULL ? "NULL" : extra->debugString().c_str()); 1491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t swap; 1511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (type == ATSParser::DISCONTINUITY_FORMATCHANGE 1521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih && (*accessUnit)->meta()->findInt32("swapPacketSource", &swap) 1531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih && swap) { 1541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 1561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK((*accessUnit)->meta()->findInt32("switchGeneration", &switchGeneration)); 1571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 1581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 1591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration == mSwitchGeneration) { 1601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(stream); 1611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg = new AMessage(kWhatSwapped, id()); 1621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("stream", stream); 1631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("switchGeneration", switchGeneration); 1641543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->post(); 1651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1671543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else if (err == OK) { 169dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) { 170dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs; 171dcb89b3b505522efde173c105a851c412f947178Chong Zhang CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); 172b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("[%s] read buffer at time %" PRId64 " us", streamStr, timeUs); 173dcb89b3b505522efde173c105a851c412f947178Chong Zhang 174dcb89b3b505522efde173c105a851c412f947178Chong Zhang mLastDequeuedTimeUs = timeUs; 175dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 176dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else if (stream == STREAMTYPE_SUBTITLES) { 177dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt32( 178dcb89b3b505522efde173c105a851c412f947178Chong Zhang "trackIndex", mPlaylist->getSelectedIndex()); 179dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs); 180dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 18114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 18214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] encountered error %d", streamStr, err); 18314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 18414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 18514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 18614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 18714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 18814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) { 1891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // No swapPacketSource race condition; called from the same thread as dequeueAccessUnit. 19014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 19114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return UNKNOWN_ERROR; 19214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 19314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 19414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 19514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 19614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MetaData> meta = packetSource->getFormat(); 19714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 19814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (meta == NULL) { 19914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return -EAGAIN; 20014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 20114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 20214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return convertMetaDataToMessage(meta, format); 203a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 204a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 20514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::connectAsync( 206ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 207a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatConnect, id()); 208a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setString("url", url); 209ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 210ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (headers != NULL) { 211ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber msg->setPointer( 212ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber "headers", 213ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber new KeyedVector<String8, String8>(*headers)); 214ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 215ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 216a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(); 217a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 218a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 21914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::disconnect() { 22014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatDisconnect, id()); 221ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 22214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 22314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 224ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 22514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 226a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 227a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 22814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::seekTo(int64_t timeUs) { 229a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatSeek, id()); 230a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setInt64("timeUs", timeUs); 231a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 23214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 23314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 23414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 2355ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih uint32_t replyID; 2365ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(response == mSeekReply && 0 != mSeekReplyID); 2375ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply.clear(); 2385ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReplyID = 0; 23914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 240a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 241a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 242a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMessageReceived(const sp<AMessage> &msg) { 243a44153c1a57202fb538659eb50706e60454d6273Andreas Huber switch (msg->what()) { 244a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatConnect: 24514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 246a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onConnect(msg); 247a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 24814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 249a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 250a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatDisconnect: 25114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 25214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->senderAwaitsResponse(&mDisconnectReplyID)); 25314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 25414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mReconfigurationInProgress) { 25514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 25614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 25714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 25814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 259a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 26014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 261a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 26214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatSeek: 26314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 2645ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(msg->senderAwaitsResponse(&mSeekReplyID)); 26514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 26614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = onSeek(msg); 26714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 2685ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply = new AMessage; 2695ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->setInt32("err", err); 27014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 27114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 27214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 27314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFetcherNotify: 27414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 27514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t what; 27614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("what", &what)); 27714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 27814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (what) { 27914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStarted: 28014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 28114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatPaused: 28214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStopped: 28314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 28414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (what == PlaylistFetcher::kWhatStopped) { 28514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 28614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 2871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.removeItem(uri) < 0) { 2881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // ignore duplicated kWhatStopped messages. 2891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 2901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 2911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 2921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 29314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 29414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 29514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuation != NULL) { 29614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GT(mContinuationCounter, 0); 29714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (--mContinuationCounter == 0) { 29814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation->post(); 2995ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 3005ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 3015ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 3025ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 3035ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 30414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 30514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 30614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 30714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 30814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 30914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatDurationUpdate: 31014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 31114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 31214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 31314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 31514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("durationUs", &durationUs)); 31614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 31814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mDurationUs = durationUs; 31914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 32014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 32114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 32214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatError: 32314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 32414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err; 32514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("err", &err)); 32614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 32714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGE("XXX Received error %d from PlaylistFetcher.", err); 32814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 32914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 33014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(err); 33114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 33214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 3331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 3341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 33514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(err); 33614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(err); 33814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 34014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(err); 34114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 34314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatError); 34414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 34514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 34614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 34714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 34814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatTemporarilyDoneFetching: 35014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 35114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 35214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 35314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 35414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 35514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mIsPrepared = true; 35614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 35714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 35814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool allFetchersPrepared = true; 35914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 36014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mFetcherInfos.valueAt(i).mIsPrepared) { 36114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber allFetchersPrepared = false; 36214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 36314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 36414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 36514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 36614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (allFetchersPrepared) { 36714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(OK); 36814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 36914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 37014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 37114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 37214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 3731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case PlaylistFetcher::kWhatStartedAt: 3741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 3751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 3761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 3771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 3781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 3791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 3801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 3821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Resume fetcher for the original variant; the resumed fetcher should 3831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // continue until the timestamps found in msg, which is stored by the 3841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // new fetcher to indicate where the new variant has started buffering. 3851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); i++) { 3861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih const FetcherInfo info = mFetcherInfos.valueAt(i); 3871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (info.mToBeRemoved) { 3881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->resumeUntilAsync(msg); 3891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 3921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 3931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 39414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 39514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 39614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 39714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 39914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 40014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 40114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatCheckBandwidth: 402a44153c1a57202fb538659eb50706e60454d6273Andreas Huber { 403a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t generation; 404a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findInt32("generation", &generation)); 405a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 40614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (generation != mCheckBandwidthGeneration) { 407a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 408a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 409a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 41014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onCheckBandwidth(); 411a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 412a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 413a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 414dcb89b3b505522efde173c105a851c412f947178Chong Zhang case kWhatChangeConfiguration: 415dcb89b3b505522efde173c105a851c412f947178Chong Zhang { 416dcb89b3b505522efde173c105a851c412f947178Chong Zhang onChangeConfiguration(msg); 417dcb89b3b505522efde173c105a851c412f947178Chong Zhang break; 418dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 419dcb89b3b505522efde173c105a851c412f947178Chong Zhang 42014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration2: 42114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 42214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration2(msg); 42314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 42414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 42514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 42614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration3: 42714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 42814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 42914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 43014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 43114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 43214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFinishDisconnect2: 43314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 43414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onFinishDisconnect2(); 435a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 43614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 437a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 4381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case kWhatSwapped: 4391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 4401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih onSwapped(msg); 4411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 4421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 443a44153c1a57202fb538659eb50706e60454d6273Andreas Huber default: 444a44153c1a57202fb538659eb50706e60454d6273Andreas Huber TRESPASS(); 445a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 446a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 447a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 448a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 449a44153c1a57202fb538659eb50706e60454d6273Andreas Huber// static 450a44153c1a57202fb538659eb50706e60454d6273Andreas Huberint LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b) { 451a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (a->mBandwidth < b->mBandwidth) { 452a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return -1; 453a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (a->mBandwidth == b->mBandwidth) { 454a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 455a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 456a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 457a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 1; 458a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 459a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 4608ca002eedc747dd854b61cbe364b52c06869273fRobert Shih// static 4618ca002eedc747dd854b61cbe364b52c06869273fRobert ShihLiveSession::StreamType LiveSession::indexToType(int idx) { 4628ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(idx >= 0 && idx < kMaxStreams); 4638ca002eedc747dd854b61cbe364b52c06869273fRobert Shih return (StreamType)(1 << idx); 4648ca002eedc747dd854b61cbe364b52c06869273fRobert Shih} 4658ca002eedc747dd854b61cbe364b52c06869273fRobert Shih 466a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onConnect(const sp<AMessage> &msg) { 467a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString url; 468a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findString("url", &url)); 469a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 470ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber KeyedVector<String8, String8> *headers = NULL; 471ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (!msg->findPointer("headers", (void **)&headers)) { 472ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders.clear(); 473ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } else { 474ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders = *headers; 475ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 476ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber delete headers; 477ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber headers = NULL; 478ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 479ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 480a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // TODO currently we don't know if we are coming here from incognito mode 481a1df816c0677185534babba6ffc29970b048e52eLajos Molnar ALOGI("onConnect %s", uriDebugString(url).c_str()); 482a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 483a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mMasterURL = url; 484a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 4857e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber bool dummy; 48614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist = fetchPlaylist(url.c_str(), NULL /* curPlaylistHash */, &dummy); 487ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 48814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist == NULL) { 489a1df816c0677185534babba6ffc29970b048e52eLajos Molnar ALOGE("unable to fetch master playlist %s.", uriDebugString(url).c_str()); 490ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 49114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(ERROR_IO); 492ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber return; 493ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 494a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 49514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // We trust the content provider to make a reasonable choice of preferred 49614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // initial bandwidth by listing it first in the variant playlist. 49714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // At startup we really don't have a good estimate on the available 49814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // network bandwidth since we haven't tranferred any data yet. Once 49914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we have we can make a better informed choice. 50014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidth = 0; 50114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidthIndex = 0; 50214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 50314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist->isVariantPlaylist()) { 50414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mPlaylist->size(); ++i) { 505a44153c1a57202fb538659eb50706e60454d6273Andreas Huber BandwidthItem item; 506a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 50714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = i; 50814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 509a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> meta; 51014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 51114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist->itemAt(i, &uri, &meta); 512a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 513a44153c1a57202fb538659eb50706e60454d6273Andreas Huber unsigned long bandwidth; 514a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth)); 515a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 51614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (initialBandwidth == 0) { 51714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidth = item.mBandwidth; 51814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 520a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.push(item); 521a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 522a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 523a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(mBandwidthItems.size(), 0u); 524a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 525a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.sort(SortByBandwidth); 52614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 52714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mBandwidthItems.size(); ++i) { 52814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mBandwidthItems.itemAt(i).mBandwidth == initialBandwidth) { 52914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidthIndex = i; 53014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 53114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 53214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 53314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 53414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // dummy item. 53514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber BandwidthItem item; 53614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = 0; 53714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mBandwidth = 0; 53814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mBandwidthItems.push(item); 539a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 540a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 541dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration( 542dcb89b3b505522efde173c105a851c412f947178Chong Zhang 0ll /* timeUs */, initialBandwidthIndex, true /* pickTrack */); 543a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 544a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 54514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::finishDisconnect() { 54614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // No reconfiguration is currently pending, make sure none will trigger 54714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // during disconnection either. 54814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber cancelCheckBandwidthEvent(); 54914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through disconnect. 5511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (finishDisconnect, onFinishDisconnect2) 5521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 5531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 55414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 55514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 55614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 55714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 55814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id()); 559a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 56014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 56114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 562ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 56314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 56414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 56514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 56614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 56714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 56814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onFinishDisconnect2() { 56914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 57014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(ERROR_END_OF_STREAM); 57214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(ERROR_END_OF_STREAM); 57314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 57514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(ERROR_END_OF_STREAM); 57614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response = new AMessage; 57814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->setInt32("err", OK); 57914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 58014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->postReply(mDisconnectReplyID); 58114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mDisconnectReplyID = 0; 58214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 58314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 58414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { 58514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ssize_t index = mFetcherInfos.indexOfKey(uri); 58614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 58714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0) { 58814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return NULL; 58914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 59014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 59114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id()); 59214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setString("uri", uri); 5931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih notify->setInt32("switchGeneration", mSwitchGeneration); 59414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 59514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo info; 59614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mFetcher = new PlaylistFetcher(notify, this, uri); 59714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mDurationUs = -1ll; 59814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mIsPrepared = false; 5991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = false; 60014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber looper()->registerHandler(info.mFetcher); 60114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 60214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.add(uri, info); 60314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 60414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return info.mFetcher; 605a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 606a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6078dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih/* 6088dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Illustration of parameters: 6098dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 6108dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 0 `range_offset` 6118dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * +------------+-------------------------------------------------------+--+--+ 6128dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | | next block to fetch | | | 6138dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | `source` handle => `out` buffer | | | | 6148dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | 6158dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | |<----------- `range_length` / buffer capacity ----------->| | 6168dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * |<------------------------------ file_size ------------------------------->| 6178dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 6188dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Special parameter values: 6198dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - range_length == -1 means entire file 6208dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - block_size == 0 means entire range 6218dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 6228dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih */ 62343ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shihssize_t LiveSession::fetchFile( 6242aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber const char *url, sp<ABuffer> *out, 6258dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih int64_t range_offset, int64_t range_length, 6268dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih uint32_t block_size, /* download block size */ 62797194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen sp<DataSource> *source, /* to return and reuse source */ 628784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 *actualUrl) { 6298dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih off64_t size; 6308dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<DataSource> temp_source; 6318dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (source == NULL) { 6328dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih source = &temp_source; 6338dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 634a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6358dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*source == NULL) { 6368dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (!strncasecmp(url, "file://", 7)) { 6378dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = new FileSource(url + 7); 6388dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else if (strncasecmp(url, "http://", 7) 6398dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih && strncasecmp(url, "https://", 8)) { 6408dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return ERROR_UNSUPPORTED; 6418dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else { 6428dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih KeyedVector<String8, String8> headers = mExtraHeaders; 6438dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (range_offset > 0 || range_length >= 0) { 6448dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih headers.add( 6458dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8("Range"), 6468dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8( 6478dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih StringPrintf( 6488dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih "bytes=%lld-%s", 6498dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset, 6508dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length < 0 6518dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ? "" : StringPrintf("%lld", 6528dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset + range_length - 1).c_str()).c_str())); 6538dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 6548dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t err = mHTTPDataSource->connect(url, &headers); 655a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6568dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (err != OK) { 6578dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return err; 6588dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 659a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6608dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = mHTTPDataSource; 661a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 662a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 663a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6648dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t getSizeErr = (*source)->getSize(&size); 6658dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (getSizeErr != OK) { 666a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size = 65536; 667a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 668a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6698dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); 6708dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*out == NULL) { 6718dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih buffer->setRange(0, 0); 6728dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 673a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 67443ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t bytesRead = 0; 6758dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // adjust range_length if only reading partial block 676b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (block_size > 0 && (range_length == -1 || (int64_t)(buffer->size() + block_size) < range_length)) { 6778dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length = buffer->size() + block_size; 6788dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 679a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (;;) { 6808dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // Only resize when we don't know the size. 681a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bufferRemaining = buffer->capacity() - buffer->size(); 6828dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (bufferRemaining == 0 && getSizeErr != OK) { 683a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bufferRemaining = 32768; 684a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 685b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("increasing download buffer to %zu bytes", 686a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size() + bufferRemaining); 687a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 688a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining); 689a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memcpy(copy->data(), buffer->data(), buffer->size()); 690a44153c1a57202fb538659eb50706e60454d6273Andreas Huber copy->setRange(0, buffer->size()); 691a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 692a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer = copy; 693a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 694a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6952aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber size_t maxBytesToRead = bufferRemaining; 6962aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (range_length >= 0) { 6972aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber int64_t bytesLeftInRange = range_length - buffer->size(); 698b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (bytesLeftInRange < (int64_t)maxBytesToRead) { 6992aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead = bytesLeftInRange; 7002aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 7012aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (bytesLeftInRange == 0) { 7022aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber break; 7032aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 7042aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 7052aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 7062aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 7078dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) 7088dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // to help us break out of the loop. 7098dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ssize_t n = (*source)->readAt( 710a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size(), buffer->data() + buffer->size(), 7112aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead); 712a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 713a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n < 0) { 71420ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber return n; 715a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 716a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 717a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n == 0) { 718a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 719a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 721a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, buffer->size() + (size_t)n); 72243ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih bytesRead += n; 723a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 724a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 725a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = buffer; 726784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl != NULL) { 72797194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen *actualUrl = (*source)->getUri(); 728784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl->isEmpty()) { 729784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo *actualUrl = url; 730784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 731784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 732a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 73343ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih return bytesRead; 734a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 735a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 73614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist( 73714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *url, uint8_t *curPlaylistHash, bool *unchanged) { 738b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ALOGV("fetchPlaylist '%s'", url); 739b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 7407e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = false; 7417e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 742a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 743784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 actualUrl; 74443ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t err = fetchFile(url, &buffer, 0, -1, 0, NULL, &actualUrl); 745a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 74643ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih if (err <= 0) { 747a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 748a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 749a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 7507e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // MD5 functionality is not available on the simulator, treat all 7517e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlists as changed. 7527e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7537e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS) 7547e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber uint8_t hash[16]; 7557e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7567e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_CTX m; 7577e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Init(&m); 7587e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Update(&m, buffer->data(), buffer->size()); 7597e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7607e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Final(hash, &m); 7617e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 76214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) { 7637e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlist unchanged 7647e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = true; 7657e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 7667e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber return NULL; 7677e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 7687e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 76914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL) { 77014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber memcpy(curPlaylistHash, hash, sizeof(hash)); 77114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 7727e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif 7737e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 774a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = 775784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo new M3UParser(actualUrl.string(), buffer->data(), buffer->size()); 776a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 777a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->initCheck() != OK) { 77829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to parse .m3u8 playlist"); 7799067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber 780a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 781a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 782a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 783a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return playlist; 784a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 785a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 786a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() { 787a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return (double)rand() / RAND_MAX; 788a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 789a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 790a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() { 791a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() == 0) { 792a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 793a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 794a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 795a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1 796a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char value[PROPERTY_VALUE_MAX]; 797673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber ssize_t index = -1; 79814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 799a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char *end; 80014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtol(value, &end, 10); 80114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 80214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 80314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0 && (size_t)index >= mBandwidthItems.size()) { 80414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 805a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 806a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 807a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 80814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index < 0) { 80914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t bandwidthBps; 81014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mHTTPDataSource != NULL 81114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) { 81214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); 81314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 81414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("no bandwidth estimate."); 81514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return 0; // Pick the lowest bandwidth stream by default. 81614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 817a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 81814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 81914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.max-bw", value, NULL)) { 82014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 82114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber long maxBw = strtoul(value, &end, 10); 82214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (end > value && *end == '\0') { 82314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (maxBw > 0 && bandwidthBps > maxBw) { 82414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth capped to %ld bps", maxBw); 82514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = maxBw; 82614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 82714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 82814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 829a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 83014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Consider only 80% of the available bandwidth usable. 83114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = (bandwidthBps * 8) / 10; 83214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 83314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pick the highest bandwidth stream below or equal to estimated bandwidth. 83414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 83514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 83614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth 83714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber > (size_t)bandwidthBps) { 83814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber --index; 83914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 840a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 841a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 842a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Change bandwidth at random() 843a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = uniformRand() * mBandwidthItems.size(); 844a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 845a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // There's a 50% chance to stay on the current bandwidth and 846a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // a 50% chance to switch to the next higher bandwidth (wrapping around 847a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // to lowest) 848a44153c1a57202fb538659eb50706e60454d6273Andreas Huber const size_t kMinIndex = 0; 849a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 85014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber static ssize_t mPrevBandwidthIndex = -1; 85114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 852a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index; 853a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mPrevBandwidthIndex < 0) { 854a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 855a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (uniformRand() < 0.5) { 856a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = (size_t)mPrevBandwidthIndex; 857a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 858a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = mPrevBandwidthIndex + 1; 859a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index == mBandwidthItems.size()) { 860a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 861a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 862a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 86314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPrevBandwidthIndex = index; 864a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 865a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec 866a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 867a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 868a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) { 869a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 870a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 87114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1 87214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 87314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t index; 87414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 87514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 87614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtoul(value, &end, 10); 87714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 87814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 87914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= mBandwidthItems.size()) { 88014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 88114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 88214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 88314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = 0; 88414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 885a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else 886a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream 887a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif 888a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 88914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GE(index, 0); 89014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 891a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return index; 892a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 893a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 89414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) { 89514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 89614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 8977e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 89814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mReconfigurationInProgress) { 89914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(timeUs, getBandwidthIndex()); 9007e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 9017e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 90214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 9037e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber} 9047e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 90514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const { 90614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t maxDurationUs = 0ll; 90714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 90814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs; 909b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 91014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (fetcherDurationUs >= 0ll && fetcherDurationUs > maxDurationUs) { 91114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber maxDurationUs = fetcherDurationUs; 912a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 913a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 914a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *durationUs = maxDurationUs; 916a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 91814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 9190f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 92014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const { 92114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 92214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return getDuration(&durationUs) == OK && durationUs >= 0; 92314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 9240f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 92514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const { 92614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return false; 92714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 9280f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 929dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::getTrackInfo(Parcel *reply) const { 930dcb89b3b505522efde173c105a851c412f947178Chong Zhang return mPlaylist->getTrackInfo(reply); 931dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 932dcb89b3b505522efde173c105a851c412f947178Chong Zhang 933dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) { 934dcb89b3b505522efde173c105a851c412f947178Chong Zhang status_t err = mPlaylist->selectTrack(index, select); 935dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (err == OK) { 936dcb89b3b505522efde173c105a851c412f947178Chong Zhang (new AMessage(kWhatChangeConfiguration, id()))->post(); 937dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 938dcb89b3b505522efde173c105a851c412f947178Chong Zhang return err; 939dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 940dcb89b3b505522efde173c105a851c412f947178Chong Zhang 9411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchUp() { 9421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds. 9431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih status_t err = OK; 9441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mPacketSources.size(); ++i) { 9451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> source = mPacketSources.valueAt(i); 9461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t dur = source->getBufferedDurationUs(&err); 9471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (err == OK && dur > 10000000) { 9481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 9491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 9501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 9511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 9521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 9531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 954dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration( 955dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs, size_t bandwidthIndex, bool pickTrack) { 9561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through reconfiguration. 9571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (changeConfiguration, onChangeConfiguration2, onChangeConfiguration3). 9581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 9591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 96014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(!mReconfigurationInProgress); 96114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = true; 962a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 96314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPrevBandwidthIndex = bandwidthIndex; 96443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 965b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("changeConfiguration => timeUs:%" PRId64 " us, bwIndex:%zu, pickTrack:%d", 966dcb89b3b505522efde173c105a851c412f947178Chong Zhang timeUs, bandwidthIndex, pickTrack); 96743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 968dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (pickTrack) { 969dcb89b3b505522efde173c105a851c412f947178Chong Zhang mPlaylist->pickRandomMediaItems(); 970dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 97143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 97214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_LT(bandwidthIndex, mBandwidthItems.size()); 97314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex); 974a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask = 0; // streams that should be fetched by the new fetcher 9761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t resumeMask = 0; // streams that should be fetched by the original fetcher 977a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9788ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 9798ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 9808ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) { 9818ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask |= indexToType(i); 9828ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 98314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 984aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 98514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Step 1, stop and discard fetchers that are no longer needed. 98614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pause those that we'll reuse. 98714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 98814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 989aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 99014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool discardFetcher = true; 991aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 99214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If we're seeking all current fetchers are discarded. 99314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 9941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // delay fetcher removal 9951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discardFetcher = false; 9961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 9978ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 9981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType type = indexToType(j); 9991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((streamMask & type) && uri == URIs[j]) { 10001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih resumeMask |= type; 10011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih streamMask &= ~type; 10028ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 10036801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 100414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1005a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 100614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (discardFetcher) { 100714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 10086801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } else { 100914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->pauseAsync(); 10106801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 1011a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1012a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 10131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg; 10141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (timeUs < 0ll) { 10151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // skip onChangeConfiguration2 (decoder destruction) if switching. 10161543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration3, id()); 10171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 10181543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration2, id()); 10191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 102014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("streamMask", streamMask); 10211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("resumeMask", resumeMask); 102214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt64("timeUs", timeUs); 10238ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 10248ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 10258ca002eedc747dd854b61cbe364b52c06869273fRobert Shih msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str()); 10268ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 10276e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 1028a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 102914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Every time a fetcher acknowledges the stopAsync or pauseAsync request 103014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we'll decrement mContinuationCounter, once it reaches zero, i.e. all 103114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // fetchers have completed their asynchronous operation, we'll post 103214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // mContinuation, which then is handled below in onChangeConfiguration2. 103314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 103414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 103588b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 103614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 103714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 10385ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 10395ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 10405ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 10415ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 10425ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 104388b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber } 104414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1045a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1046dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) { 1047dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (!mReconfigurationInProgress) { 1048dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration(-1ll /* timeUs */, getBandwidthIndex()); 1049dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else { 1050dcb89b3b505522efde173c105a851c412f947178Chong Zhang msg->post(1000000ll); // retry in 1 sec 1051dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1052dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1053dcb89b3b505522efde173c105a851c412f947178Chong Zhang 105414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { 105514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 1056bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 105714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers are either suspended or have been removed now. 1058bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 105914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t streamMask; 106014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 1061bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 10628ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 10638ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 10648ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 10658ca002eedc747dd854b61cbe364b52c06869273fRobert Shih const AString &uriKey = mStreams[i].uriKey(); 10668ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(uriKey.c_str(), &URIs[i])); 10678ca002eedc747dd854b61cbe364b52c06869273fRobert Shih ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str()); 10688ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 106922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 10703831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 107114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Determine which decoders to shutdown on the player side, 107214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // a decoder has to be shutdown if either 107314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 1) its streamtype was active before but now longer isn't. 107414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // or 107514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 2) its streamtype was already active and still is but the URI 107614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has changed. 107714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t changedMask = 0; 10788ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) { 10798ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (((mStreamMask & streamMask & indexToType(i)) 10808ca002eedc747dd854b61cbe364b52c06869273fRobert Shih && !(URIs[i] == mStreams[i].mUri)) 10818ca002eedc747dd854b61cbe364b52c06869273fRobert Shih || (mStreamMask & ~streamMask & indexToType(i))) { 10828ca002eedc747dd854b61cbe364b52c06869273fRobert Shih changedMask |= indexToType(i); 10838ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1084b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } 1085b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 108614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (changedMask == 0) { 108714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If nothing changed as far as the audio/video decoders 108814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // are concerned we can proceed. 108914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 109014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return; 109114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 109243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 109314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Something changed, inform the player which will shutdown the 109414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // corresponding decoders and will post the reply once that's done. 109514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the reply will continue executing below in 109614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // onChangeConfiguration3. 109714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 109814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatStreamsChanged); 109914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("changedMask", changedMask); 110020f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber 110114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setWhat(kWhatChangeConfiguration3); 110214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setTarget(id()); 1103b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 110414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setMessage("reply", msg); 110514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 110614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1107b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 110814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { 11091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mContinuation.clear(); 111014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All remaining fetchers are still suspended, the player has shutdown 111114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // any decoders that needed it. 1112b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 11131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask, resumeMask; 111414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 11151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1116a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11178ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 11188ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 11198ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri)); 11208ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1121a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1122a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 11241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool switching = false; 112514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 1126a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber timeUs = mLastDequeuedTimeUs; 11291543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih switching = true; 113014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1131dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 1132a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mNewStreamMask = streamMask; 1134a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Of all existing fetchers: 11361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Resume fetchers that are still needed and assign them original packet sources. 11371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Mark otherwise unneeded fetchers for removal. 11381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ALOGV("resuming fetchers for mask 0x%08x", resumeMask); 113914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 114014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 11410df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber 11428ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 1143dc793ce8c0ead27ab43e40ce09f27fe338323502Robert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 11441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) { 11458ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 11468ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 114714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1148a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih FetcherInfo &info = mFetcherInfos.editValueAt(i); 11501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL 11511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih || sources[kSubtitleIndex] != NULL) { 11521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->startAsync( 11531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]); 11541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 11551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = true; 11561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1157a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1158a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 115914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // streamMask now only contains the types that need a new fetcher created. 1160a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 116114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (streamMask != 0) { 116214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("creating new fetchers for mask 0x%08x", streamMask); 1163a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1164a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Find out when the original fetchers have buffered up to and start the new fetchers 11661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // at a later timestamp. 11678ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; i++) { 11688ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (!(indexToType(i) & streamMask)) { 11698ca002eedc747dd854b61cbe364b52c06869273fRobert Shih continue; 11708ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 11711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 117214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 11738ca002eedc747dd854b61cbe364b52c06869273fRobert Shih uri = mStreams[i].mUri; 11749b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 117514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str()); 117614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(fetcher != NULL); 1177a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t latestSeq = -1; 11791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t latestTimeUs = 0ll; 11808ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 11811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11828ca002eedc747dd854b61cbe364b52c06869273fRobert Shih // TRICKY: looping from i as earlier streams are already removed from streamMask 11838ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = i; j < kMaxStreams; ++j) { 11848ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if ((streamMask & indexToType(j)) && uri == mStreams[j].mUri) { 11858ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 11861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (!switching) { 11881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 11891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 11901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t type, seq; 11911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t srcTimeUs; 11921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> meta = sources[j]->getLatestMeta(); 11931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (meta != NULL && !meta->findInt32("discontinuity", &type)) { 11951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(meta->findInt32("seq", &seq)); 11961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (seq > latestSeq) { 11971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestSeq = seq; 11981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(meta->findInt64("timeUs", &srcTimeUs)); 12001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (srcTimeUs > latestTimeUs) { 12011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestTimeUs = srcTimeUs; 12021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j] = mPacketSources2.valueFor(indexToType(j)); 12061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 12071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 12081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (extraStreams & indexToType(j)) { 12091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->queueAccessUnit(createFormatChangeBuffer(/* swap = */ false)); 12101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1212a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12138ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask &= ~indexToType(j); 12148ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1215a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 121614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 12178ca002eedc747dd854b61cbe364b52c06869273fRobert Shih fetcher->startAsync( 12188ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kAudioIndex], 12198ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kVideoIndex], 12208ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kSubtitleIndex], 12211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih timeUs, 12221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestTimeUs /* min start time(us) */, 12231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih latestSeq >= 0 ? latestSeq + 1 : -1 /* starting sequence number hint */ ); 1224a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1225a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 122614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers have now been started, the configuration change 122714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has completed. 1228a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 122914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber scheduleCheckBandwidthEvent(); 1230a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 123114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("XXX configuration change completed."); 123214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = false; 12331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switching) { 12341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = true; 12351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 12361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 12371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1238a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 123914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mDisconnectReplyID != 0) { 124014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 1241a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 124214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1243a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onSwapped(const sp<AMessage> &msg) { 12451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 12461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 12471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 12481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 12491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t stream; 12521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("stream", &stream)); 12531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask |= stream; 12541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mSwapMask != mStreamMask) { 12551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 12561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Check if new variant contains extra streams. 12591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 12601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih while (extraStreams) { 12611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType extraStream = (StreamType) (extraStreams & ~(extraStreams - 1)); 12621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(extraStream); 12631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih extraStreams &= ~extraStream; 12641543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 12671543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 12681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// Mark switch done when: 12701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// 1. all old buffers are swapped out, AND 12711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// 2. all old fetchers are removed. 12721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::tryToFinishBandwidthSwitch() { 12731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool needToRemoveFetchers = false; 12741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 12751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.valueAt(i).mToBeRemoved) { 12761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih needToRemoveFetchers = true; 12771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 12781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (!needToRemoveFetchers && mSwapMask == mStreamMask) { 12811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 12821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 12831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 12841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 12861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 128714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() { 128814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id()); 128914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("generation", mCheckBandwidthGeneration); 129014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(10000000ll); 1291a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1292a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 129314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() { 129414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ++mCheckBandwidthGeneration; 1295a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1296a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::cancelBandwidthSwitch() { 12981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 12991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration++; 13001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 13011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 13021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 13031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 13041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) { 13051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress) { 13061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 13071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 13081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 13091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mPrevBandwidthIndex < 0) { 13101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 131114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 131214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 13131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (bandwidthIndex == (size_t)mPrevBandwidthIndex) { 13141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 13151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else if (bandwidthIndex > (size_t)mPrevBandwidthIndex) { 13161543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return canSwitchUp(); 13171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 13181543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 13191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 13201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 13211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 13221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onCheckBandwidth() { 132314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t bandwidthIndex = getBandwidthIndex(); 13241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (canSwitchBandwidthTo(bandwidthIndex)) { 132514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(-1ll /* timeUs */, bandwidthIndex); 13261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 13271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih scheduleCheckBandwidthEvent(); 132814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1329a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 133014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the kWhatCheckBandwidth even here does _not_ automatically 133114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // schedule another one on return, only an explicit call to 133214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // scheduleCheckBandwidthEvent will do that. 133314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // This ensures that only one configuration change is ongoing at any 133414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // one time, once that completes it'll schedule another check bandwidth 133514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // event. 1336a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1337a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 133814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) { 133914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(mInPreparationPhase); 1340a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 134114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 134214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == OK || err == ERROR_END_OF_STREAM) { 134314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPrepared); 134414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 134514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPreparationFailed); 134614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 134714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1348a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 134914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 1350a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 135114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mInPreparationPhase = false; 1352b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber} 1353b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1354a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} // namespace android 1355a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1356