LiveSession.cpp revision b3f9759c8c9437c45b9a34519ce2ea38a8314d4e
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())), 60309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex(-1), 6114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mStreamMask(0), 621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mNewStreamMask(0), 631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask(0), 6414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mCheckBandwidthGeneration(0), 651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration(0), 66b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih mSubtitleGeneration(0), 6714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mLastDequeuedTimeUs(0ll), 68dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs(0ll), 6914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress(false), 701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress(false), 715ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mDisconnectReplyID(0), 72309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mSeekReplyID(0), 73309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mFirstTimeUsValid(false), 74309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mFirstTimeUs(0), 75309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mLastSeekTimeUs(0) { 7614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 778ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kAudioIndex] = StreamItem("audio"); 788ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kVideoIndex] = StreamItem("video"); 79e4f25c280a8f1655c31a745978e0fcbc61f91deeRobert Shih mStreams[kSubtitleIndex] = StreamItem("subtitles"); 8014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 818ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 82309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuities.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 838ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 85f69c996864844e8f669308af8412cede043062a2Robert Shih mBuffering[i] = false; 868ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 87a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 88a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 89a44153c1a57202fb538659eb50706e60454d6273Andreas HuberLiveSession::~LiveSession() { 90a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 91a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihsp<ABuffer> LiveSession::createFormatChangeBuffer(bool swap) { 931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ABuffer *discontinuity = new ABuffer(0); 941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("discontinuity", ATSParser::DISCONTINUITY_FORMATCHANGE); 951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("swapPacketSource", swap); 961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("switchGeneration", mSwitchGeneration); 971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt64("timeUs", -1); 981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return discontinuity; 991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 1001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::swapPacketSource(StreamType stream) { 1021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps = mPacketSources.editValueFor(stream); 1031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps2 = mPacketSources2.editValueFor(stream); 1041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> tmp = aps; 1051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps = aps2; 1061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2 = tmp; 1071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2->clear(); 1081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 1091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 11014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::dequeueAccessUnit( 11114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber StreamType stream, sp<ABuffer> *accessUnit) { 11214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 1131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // return -EWOULDBLOCK to avoid halting the decoder 1141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // when switching between audio/video and audio only. 1151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return -EWOULDBLOCK; 11614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 11714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 118309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih status_t finalResult; 119309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue = mDiscontinuities.valueFor(stream); 120309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (discontinuityQueue->hasBufferAvailable(&finalResult)) { 121309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->dequeueAccessUnit(accessUnit); 122309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // seeking, track switching 123309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> extra; 124309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t timeUs; 125309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((*accessUnit)->meta()->findMessage("extra", &extra) 126309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih && extra != NULL 127309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih && extra->findInt64("timeUs", &timeUs)) { 128309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // seeking only 129309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mLastSeekTimeUs = timeUs; 130309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityOffsetTimesUs.clear(); 131309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityAbsStartTimesUs.clear(); 132309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 133309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return INFO_DISCONTINUITY; 134309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 135309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 13614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 13714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 138f69c996864844e8f669308af8412cede043062a2Robert Shih ssize_t idx = typeToIndex(stream); 13914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!packetSource->hasBufferAvailable(&finalResult)) { 140f69c996864844e8f669308af8412cede043062a2Robert Shih if (finalResult == OK) { 141f69c996864844e8f669308af8412cede043062a2Robert Shih mBuffering[idx] = true; 142f69c996864844e8f669308af8412cede043062a2Robert Shih return -EAGAIN; 143f69c996864844e8f669308af8412cede043062a2Robert Shih } else { 144f69c996864844e8f669308af8412cede043062a2Robert Shih return finalResult; 145f69c996864844e8f669308af8412cede043062a2Robert Shih } 146f69c996864844e8f669308af8412cede043062a2Robert Shih } 147f69c996864844e8f669308af8412cede043062a2Robert Shih 148f69c996864844e8f669308af8412cede043062a2Robert Shih if (mBuffering[idx]) { 149f69c996864844e8f669308af8412cede043062a2Robert Shih if (mSwitchInProgress 150f69c996864844e8f669308af8412cede043062a2Robert Shih || packetSource->isFinished(0) 151f69c996864844e8f669308af8412cede043062a2Robert Shih || packetSource->getEstimatedDurationUs() > 10000000ll) { 152f69c996864844e8f669308af8412cede043062a2Robert Shih mBuffering[idx] = false; 153f69c996864844e8f669308af8412cede043062a2Robert Shih } 154f69c996864844e8f669308af8412cede043062a2Robert Shih } 155f69c996864844e8f669308af8412cede043062a2Robert Shih 156f69c996864844e8f669308af8412cede043062a2Robert Shih if (mBuffering[idx]) { 157f69c996864844e8f669308af8412cede043062a2Robert Shih return -EAGAIN; 15814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 15914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 160309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // wait for counterpart 161309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> otherSource; 16273d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih uint32_t mask = mNewStreamMask & mStreamMask; 16373d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih uint32_t fetchersMask = 0; 16473d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 16573d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih uint32_t fetcherMask = mFetcherInfos.valueAt(i).mFetcher->getStreamTypeMask(); 16673d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih fetchersMask |= fetcherMask; 16773d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih } 16873d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih mask &= fetchersMask; 16973d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih if (stream == STREAMTYPE_AUDIO && (mask & STREAMTYPE_VIDEO)) { 170309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih otherSource = mPacketSources.valueFor(STREAMTYPE_VIDEO); 17173d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih } else if (stream == STREAMTYPE_VIDEO && (mask & STREAMTYPE_AUDIO)) { 172309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih otherSource = mPacketSources.valueFor(STREAMTYPE_AUDIO); 173309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 174309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (otherSource != NULL && !otherSource->hasBufferAvailable(&finalResult)) { 175309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return finalResult == OK ? -EAGAIN : finalResult; 176309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 177309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 17814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = packetSource->dequeueAccessUnit(accessUnit); 17914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 180309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih size_t streamIdx; 18114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *streamStr; 18214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (stream) { 18314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_AUDIO: 184309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamIdx = kAudioIndex; 18514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "audio"; 18614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 18714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_VIDEO: 188309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamIdx = kVideoIndex; 18914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "video"; 19014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 19114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_SUBTITLES: 192309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamIdx = kSubtitleIndex; 19314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "subs"; 19414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 19514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 19614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 19714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 19814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 199309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih StreamItem& strm = mStreams[streamIdx]; 20014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == INFO_DISCONTINUITY) { 201309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adaptive streaming, discontinuities in the playlist 20214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t type; 20314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK((*accessUnit)->meta()->findInt32("discontinuity", &type)); 20414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 20514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> extra; 20614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(*accessUnit)->meta()->findMessage("extra", &extra)) { 20714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra.clear(); 20814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 20914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 21014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] read discontinuity of type %d, extra = %s", 21114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr, 21214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber type, 21314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra == NULL ? "NULL" : extra->debugString().c_str()); 2141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 2151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t swap; 216309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((*accessUnit)->meta()->findInt32("swapPacketSource", &swap) && swap) { 2171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 2181543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK((*accessUnit)->meta()->findInt32("switchGeneration", &switchGeneration)); 2191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 2201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 2211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration == mSwitchGeneration) { 2221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(stream); 2231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg = new AMessage(kWhatSwapped, id()); 2241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("stream", stream); 2251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("switchGeneration", switchGeneration); 2261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->post(); 2271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 2281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 229309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 230309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih size_t seq = strm.mCurDiscontinuitySeq; 231309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t offsetTimeUs; 232309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityOffsetTimesUs.indexOfKey(seq) >= 0) { 233309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs = mDiscontinuityOffsetTimesUs.valueFor(seq); 234309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 235309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs = 0; 236309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 237309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 238309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih seq += 1; 239309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityAbsStartTimesUs.indexOfKey(strm.mCurDiscontinuitySeq) >= 0) { 240309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t firstTimeUs; 241309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = mDiscontinuityAbsStartTimesUs.valueFor(strm.mCurDiscontinuitySeq); 242309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs += strm.mLastDequeuedTimeUs - firstTimeUs; 243309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs += strm.mLastSampleDurationUs; 244309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 245309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs += strm.mLastSampleDurationUs; 246309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 247309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 248309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityOffsetTimesUs.add(seq, offsetTimeUs); 2491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 25014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else if (err == OK) { 251309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 252dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) { 253dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs; 254309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discontinuitySeq = 0; 255dcb89b3b505522efde173c105a851c412f947178Chong Zhang CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); 256309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih (*accessUnit)->meta()->findInt32("discontinuitySeq", &discontinuitySeq); 257309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih strm.mCurDiscontinuitySeq = discontinuitySeq; 258309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 259309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discard = 0; 260309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t firstTimeUs; 261309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityAbsStartTimesUs.indexOfKey(strm.mCurDiscontinuitySeq) >= 0) { 262309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t durUs; // approximate sample duration 263309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs > strm.mLastDequeuedTimeUs) { 264309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih durUs = timeUs - strm.mLastDequeuedTimeUs; 265309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 266309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih durUs = strm.mLastDequeuedTimeUs - timeUs; 267309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 268309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih strm.mLastSampleDurationUs = durUs; 269309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = mDiscontinuityAbsStartTimesUs.valueFor(strm.mCurDiscontinuitySeq); 270309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else if ((*accessUnit)->meta()->findInt32("discard", &discard) && discard) { 271309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = timeUs; 272309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 273309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityAbsStartTimesUs.add(strm.mCurDiscontinuitySeq, timeUs); 274309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = timeUs; 275309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 276309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 277309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih strm.mLastDequeuedTimeUs = timeUs; 278309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs >= firstTimeUs) { 279309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs -= firstTimeUs; 280309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 281309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs = 0; 282309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 283309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs += mLastSeekTimeUs; 284309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityOffsetTimesUs.indexOfKey(discontinuitySeq) >= 0) { 285309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs += mDiscontinuityOffsetTimesUs.valueFor(discontinuitySeq); 286309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 287dcb89b3b505522efde173c105a851c412f947178Chong Zhang 288309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGV("[%s] read buffer at time %" PRId64 " us", streamStr, timeUs); 289309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih (*accessUnit)->meta()->setInt64("timeUs", timeUs); 290dcb89b3b505522efde173c105a851c412f947178Chong Zhang mLastDequeuedTimeUs = timeUs; 291dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 292dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else if (stream == STREAMTYPE_SUBTITLES) { 293b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih int32_t subtitleGeneration; 294b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if ((*accessUnit)->meta()->findInt32("subtitleGeneration", &subtitleGeneration) 295b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih && subtitleGeneration != mSubtitleGeneration) { 296b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return -EAGAIN; 297b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih }; 298dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt32( 299dcb89b3b505522efde173c105a851c412f947178Chong Zhang "trackIndex", mPlaylist->getSelectedIndex()); 300dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs); 301dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 30214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 30314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] encountered error %d", streamStr, err); 30414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 30514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 30614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 30714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 30814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 30914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) { 3101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // No swapPacketSource race condition; called from the same thread as dequeueAccessUnit. 31114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 31214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return UNKNOWN_ERROR; 31314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 31414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 31614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MetaData> meta = packetSource->getFormat(); 31814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 31914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (meta == NULL) { 32014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return -EAGAIN; 32114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 32214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 32314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return convertMetaDataToMessage(meta, format); 324a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 325a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 32614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::connectAsync( 327ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 328a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatConnect, id()); 329a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setString("url", url); 330ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 331ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (headers != NULL) { 332ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber msg->setPointer( 333ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber "headers", 334ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber new KeyedVector<String8, String8>(*headers)); 335ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 336ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 337a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(); 338a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 339a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 34014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::disconnect() { 34114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatDisconnect, id()); 342ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 34314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 34414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 345ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 34614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 347a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 348a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 34914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::seekTo(int64_t timeUs) { 350a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatSeek, id()); 351a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setInt64("timeUs", timeUs); 352a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 35314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 35414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 35514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 35614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 357a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 358a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 359a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMessageReceived(const sp<AMessage> &msg) { 360a44153c1a57202fb538659eb50706e60454d6273Andreas Huber switch (msg->what()) { 361a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatConnect: 36214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 363a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onConnect(msg); 364a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 36514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 366a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 367a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatDisconnect: 36814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 36914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->senderAwaitsResponse(&mDisconnectReplyID)); 37014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 37114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mReconfigurationInProgress) { 37214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 37314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 37414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 37514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 376a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 37714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 378a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 37914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatSeek: 38014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 381800599cdd50737de1cde483a34b39923750b0658Robert Shih uint32_t seekReplyID; 382800599cdd50737de1cde483a34b39923750b0658Robert Shih CHECK(msg->senderAwaitsResponse(&seekReplyID)); 383800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = seekReplyID; 384800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply = new AMessage; 38514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 38614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = onSeek(msg); 38714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 388800599cdd50737de1cde483a34b39923750b0658Robert Shih if (err != OK) { 389800599cdd50737de1cde483a34b39923750b0658Robert Shih msg->post(50000); 390800599cdd50737de1cde483a34b39923750b0658Robert Shih } 39114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 39214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 39314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFetcherNotify: 39514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 39614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t what; 39714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("what", &what)); 39814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (what) { 40014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStarted: 40114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 40214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatPaused: 40314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStopped: 40414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 40514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (what == PlaylistFetcher::kWhatStopped) { 40614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 40714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 4081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.removeItem(uri) < 0) { 4091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // ignore duplicated kWhatStopped messages. 4101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 4111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 4121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 413309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mSwitchInProgress) { 414309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih tryToFinishBandwidthSwitch(); 415309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 41614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 41714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 41814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuation != NULL) { 41914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GT(mContinuationCounter, 0); 42014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (--mContinuationCounter == 0) { 42114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation->post(); 4225ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 4235ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 4245ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 425800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply->setInt32("err", OK); 4265ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 427800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = 0; 428800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply.clear(); 4295ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 43014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 43114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 43214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 43314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 43414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 43514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatDurationUpdate: 43614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 43714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 43814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 43914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 44014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 44114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("durationUs", &durationUs)); 44214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 44314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 44414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mDurationUs = durationUs; 44514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 44614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 44714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 44814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatError: 44914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 45014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err; 45114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("err", &err)); 45214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 45314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGE("XXX Received error %d from PlaylistFetcher.", err); 45414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 45515f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih // handle EOS on subtitle tracks independently 45615f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih AString uri; 45715f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (err == ERROR_END_OF_STREAM && msg->findString("uri", &uri)) { 45815f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih ssize_t i = mFetcherInfos.indexOfKey(uri); 45915f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (i >= 0) { 46015f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih const sp<PlaylistFetcher> &fetcher = mFetcherInfos.valueAt(i).mFetcher; 46115f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (fetcher != NULL) { 46215f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih uint32_t type = fetcher->getStreamTypeMask(); 46315f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (type == STREAMTYPE_SUBTITLES) { 46415f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih mPacketSources.valueFor( 46515f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih STREAMTYPE_SUBTITLES)->signalEOS(err);; 46615f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih break; 46715f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 46815f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 46915f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 47015f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 47115f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih 47214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 47314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(err); 47414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 47514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 4761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 4771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 47814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(err); 47914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 48014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(err); 48114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 48214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 48314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(err); 48414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 48514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 48614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatError); 48714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 48814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 48914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 49014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 49114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 49214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatTemporarilyDoneFetching: 49314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 49414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 49514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 49614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 4976300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen if (mFetcherInfos.indexOfKey(uri) < 0) { 4986300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen ALOGE("couldn't find uri"); 4996300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen break; 5006300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen } 50114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 50214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mIsPrepared = true; 50314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 50414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 50514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool allFetchersPrepared = true; 50614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 50714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mFetcherInfos.valueAt(i).mIsPrepared) { 50814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber allFetchersPrepared = false; 50914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 51014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 51314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (allFetchersPrepared) { 51414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(OK); 51514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 51814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case PlaylistFetcher::kWhatStartedAt: 5211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 5221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 5231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 5241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 5251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 5261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 5271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 5291543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Resume fetcher for the original variant; the resumed fetcher should 5301543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // continue until the timestamps found in msg, which is stored by the 5311543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // new fetcher to indicate where the new variant has started buffering. 5321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); i++) { 5331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih const FetcherInfo info = mFetcherInfos.valueAt(i); 5341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (info.mToBeRemoved) { 5351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->resumeUntilAsync(msg); 5361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 5391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 54114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 54214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 54314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 54414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 54514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 54614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 54714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 54814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatCheckBandwidth: 549a44153c1a57202fb538659eb50706e60454d6273Andreas Huber { 550a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t generation; 551a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findInt32("generation", &generation)); 552a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 55314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (generation != mCheckBandwidthGeneration) { 554a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 555a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 556a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 55700598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih onCheckBandwidth(msg); 558a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 559a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 560a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 561dcb89b3b505522efde173c105a851c412f947178Chong Zhang case kWhatChangeConfiguration: 562dcb89b3b505522efde173c105a851c412f947178Chong Zhang { 563dcb89b3b505522efde173c105a851c412f947178Chong Zhang onChangeConfiguration(msg); 564dcb89b3b505522efde173c105a851c412f947178Chong Zhang break; 565dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 566dcb89b3b505522efde173c105a851c412f947178Chong Zhang 56714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration2: 56814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 56914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration2(msg); 57014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 57114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 57214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration3: 57414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 57514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 57614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 57714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 57814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFinishDisconnect2: 58014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 58114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onFinishDisconnect2(); 582a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 58314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 584a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 5851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case kWhatSwapped: 5861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 5871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih onSwapped(msg); 5881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 5891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5900ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 5910ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih case kWhatCheckSwitchDown: 5920ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih { 5930ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih onCheckSwitchDown(); 5940ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 5950ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 5960ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 5970ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih case kWhatSwitchDown: 5980ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih { 5990ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih onSwitchDown(); 6000ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 6010ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 6020ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 603a44153c1a57202fb538659eb50706e60454d6273Andreas Huber default: 604a44153c1a57202fb538659eb50706e60454d6273Andreas Huber TRESPASS(); 605a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 606a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 607a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 608a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 609a44153c1a57202fb538659eb50706e60454d6273Andreas Huber// static 610a44153c1a57202fb538659eb50706e60454d6273Andreas Huberint LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b) { 611a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (a->mBandwidth < b->mBandwidth) { 612a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return -1; 613a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (a->mBandwidth == b->mBandwidth) { 614a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 615a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 616a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 617a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 1; 618a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 619a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6208ca002eedc747dd854b61cbe364b52c06869273fRobert Shih// static 6218ca002eedc747dd854b61cbe364b52c06869273fRobert ShihLiveSession::StreamType LiveSession::indexToType(int idx) { 6228ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(idx >= 0 && idx < kMaxStreams); 6238ca002eedc747dd854b61cbe364b52c06869273fRobert Shih return (StreamType)(1 << idx); 6248ca002eedc747dd854b61cbe364b52c06869273fRobert Shih} 6258ca002eedc747dd854b61cbe364b52c06869273fRobert Shih 626f69c996864844e8f669308af8412cede043062a2Robert Shih// static 627f69c996864844e8f669308af8412cede043062a2Robert Shihssize_t LiveSession::typeToIndex(int32_t type) { 628f69c996864844e8f669308af8412cede043062a2Robert Shih switch (type) { 629f69c996864844e8f669308af8412cede043062a2Robert Shih case STREAMTYPE_AUDIO: 630f69c996864844e8f669308af8412cede043062a2Robert Shih return 0; 631f69c996864844e8f669308af8412cede043062a2Robert Shih case STREAMTYPE_VIDEO: 632f69c996864844e8f669308af8412cede043062a2Robert Shih return 1; 633f69c996864844e8f669308af8412cede043062a2Robert Shih case STREAMTYPE_SUBTITLES: 634f69c996864844e8f669308af8412cede043062a2Robert Shih return 2; 635f69c996864844e8f669308af8412cede043062a2Robert Shih default: 636f69c996864844e8f669308af8412cede043062a2Robert Shih return -1; 637f69c996864844e8f669308af8412cede043062a2Robert Shih }; 638f69c996864844e8f669308af8412cede043062a2Robert Shih return -1; 639f69c996864844e8f669308af8412cede043062a2Robert Shih} 640f69c996864844e8f669308af8412cede043062a2Robert Shih 641a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onConnect(const sp<AMessage> &msg) { 642a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString url; 643a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findString("url", &url)); 644a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 645ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber KeyedVector<String8, String8> *headers = NULL; 646ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (!msg->findPointer("headers", (void **)&headers)) { 647ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders.clear(); 648ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } else { 649ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders = *headers; 650ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 651ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber delete headers; 652ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber headers = NULL; 653ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 654ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 655a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // TODO currently we don't know if we are coming here from incognito mode 656a1df816c0677185534babba6ffc29970b048e52eLajos Molnar ALOGI("onConnect %s", uriDebugString(url).c_str()); 657a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 658a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mMasterURL = url; 659a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6607e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber bool dummy; 66114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist = fetchPlaylist(url.c_str(), NULL /* curPlaylistHash */, &dummy); 662ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 66314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist == NULL) { 664a1df816c0677185534babba6ffc29970b048e52eLajos Molnar ALOGE("unable to fetch master playlist %s.", uriDebugString(url).c_str()); 665ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 66614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(ERROR_IO); 667ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber return; 668ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 669a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 67014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // We trust the content provider to make a reasonable choice of preferred 67114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // initial bandwidth by listing it first in the variant playlist. 67214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // At startup we really don't have a good estimate on the available 67314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // network bandwidth since we haven't tranferred any data yet. Once 67414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we have we can make a better informed choice. 67514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidth = 0; 67614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidthIndex = 0; 67714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 67814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist->isVariantPlaylist()) { 67914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mPlaylist->size(); ++i) { 680a44153c1a57202fb538659eb50706e60454d6273Andreas Huber BandwidthItem item; 681a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 68214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = i; 68314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 684a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> meta; 68514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 68614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist->itemAt(i, &uri, &meta); 687a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 688a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth)); 689a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 69014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (initialBandwidth == 0) { 69114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidth = item.mBandwidth; 69214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 69314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 694a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.push(item); 695a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 696a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 697a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(mBandwidthItems.size(), 0u); 698a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 699a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.sort(SortByBandwidth); 70014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 70114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mBandwidthItems.size(); ++i) { 70214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mBandwidthItems.itemAt(i).mBandwidth == initialBandwidth) { 70314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidthIndex = i; 70414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 70514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 70614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 70714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 70814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // dummy item. 70914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber BandwidthItem item; 71014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = 0; 71114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mBandwidth = 0; 71214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mBandwidthItems.push(item); 713a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 714a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 715309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mPlaylist->pickRandomMediaItems(); 716dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration( 717309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 0ll /* timeUs */, initialBandwidthIndex, false /* pickTrack */); 718a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 719a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 72014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::finishDisconnect() { 72114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // No reconfiguration is currently pending, make sure none will trigger 72214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // during disconnection either. 72314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber cancelCheckBandwidthEvent(); 72414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 7251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through disconnect. 7261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (finishDisconnect, onFinishDisconnect2) 7271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 7281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 7290ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih // cancel switch down monitor 7300ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor.clear(); 7310ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 73214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 73314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 73414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 73514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 73614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id()); 737a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 73814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 73914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 740ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 74114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 74214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 74314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 74414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 74514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 74614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onFinishDisconnect2() { 74714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 74814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 74914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(ERROR_END_OF_STREAM); 75014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(ERROR_END_OF_STREAM); 75114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 75314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(ERROR_END_OF_STREAM); 75414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response = new AMessage; 75614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->setInt32("err", OK); 75714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->postReply(mDisconnectReplyID); 75914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mDisconnectReplyID = 0; 76014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 76114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 76214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { 76314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ssize_t index = mFetcherInfos.indexOfKey(uri); 76414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 76514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0) { 76614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return NULL; 76714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 76814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 76914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id()); 77014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setString("uri", uri); 7711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih notify->setInt32("switchGeneration", mSwitchGeneration); 77214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 77314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo info; 774b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih info.mFetcher = new PlaylistFetcher(notify, this, uri, mSubtitleGeneration); 77514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mDurationUs = -1ll; 77614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mIsPrepared = false; 7771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = false; 77814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber looper()->registerHandler(info.mFetcher); 77914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.add(uri, info); 78114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return info.mFetcher; 783a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 784a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 7858dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih/* 7868dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Illustration of parameters: 7878dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 7888dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 0 `range_offset` 7898dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * +------------+-------------------------------------------------------+--+--+ 7908dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | | next block to fetch | | | 7918dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | `source` handle => `out` buffer | | | | 7928dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | 7938dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | |<----------- `range_length` / buffer capacity ----------->| | 7948dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * |<------------------------------ file_size ------------------------------->| 7958dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 7968dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Special parameter values: 7978dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - range_length == -1 means entire file 7988dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - block_size == 0 means entire range 7998dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 8008dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih */ 80143ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shihssize_t LiveSession::fetchFile( 8022aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber const char *url, sp<ABuffer> *out, 8038dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih int64_t range_offset, int64_t range_length, 8048dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih uint32_t block_size, /* download block size */ 80597194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen sp<DataSource> *source, /* to return and reuse source */ 806784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 *actualUrl) { 8078dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih off64_t size; 8088dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<DataSource> temp_source; 8098dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (source == NULL) { 8108dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih source = &temp_source; 8118dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 812a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8138dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*source == NULL) { 8148dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (!strncasecmp(url, "file://", 7)) { 8158dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = new FileSource(url + 7); 8168dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else if (strncasecmp(url, "http://", 7) 8178dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih && strncasecmp(url, "https://", 8)) { 8188dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return ERROR_UNSUPPORTED; 8198dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else { 8208dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih KeyedVector<String8, String8> headers = mExtraHeaders; 8218dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (range_offset > 0 || range_length >= 0) { 8228dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih headers.add( 8238dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8("Range"), 8248dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8( 8258dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih StringPrintf( 8268dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih "bytes=%lld-%s", 8278dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset, 8288dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length < 0 8298dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ? "" : StringPrintf("%lld", 8308dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset + range_length - 1).c_str()).c_str())); 8318dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 8328dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t err = mHTTPDataSource->connect(url, &headers); 833a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8348dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (err != OK) { 8358dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return err; 8368dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 837a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8388dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = mHTTPDataSource; 839a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 840a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 841a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8428dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t getSizeErr = (*source)->getSize(&size); 8438dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (getSizeErr != OK) { 844a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size = 65536; 845a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 846a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8478dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); 8488dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*out == NULL) { 8498dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih buffer->setRange(0, 0); 8508dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 851a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 85243ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t bytesRead = 0; 8538dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // adjust range_length if only reading partial block 854b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (block_size > 0 && (range_length == -1 || (int64_t)(buffer->size() + block_size) < range_length)) { 8558dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length = buffer->size() + block_size; 8568dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 857a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (;;) { 8588dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // Only resize when we don't know the size. 859a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bufferRemaining = buffer->capacity() - buffer->size(); 8608dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (bufferRemaining == 0 && getSizeErr != OK) { 861a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bufferRemaining = 32768; 862a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 863b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("increasing download buffer to %zu bytes", 864a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size() + bufferRemaining); 865a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 866a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining); 867a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memcpy(copy->data(), buffer->data(), buffer->size()); 868a44153c1a57202fb538659eb50706e60454d6273Andreas Huber copy->setRange(0, buffer->size()); 869a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 870a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer = copy; 871a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 872a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8732aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber size_t maxBytesToRead = bufferRemaining; 8742aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (range_length >= 0) { 8752aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber int64_t bytesLeftInRange = range_length - buffer->size(); 876b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (bytesLeftInRange < (int64_t)maxBytesToRead) { 8772aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead = bytesLeftInRange; 8782aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 8792aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (bytesLeftInRange == 0) { 8802aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber break; 8812aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 8822aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 8832aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 8842aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 8858dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) 8868dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // to help us break out of the loop. 8878dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ssize_t n = (*source)->readAt( 888a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size(), buffer->data() + buffer->size(), 8892aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead); 890a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 891a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n < 0) { 89220ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber return n; 893a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 894a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 895a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n == 0) { 896a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 897a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 898a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 899a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, buffer->size() + (size_t)n); 90043ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih bytesRead += n; 901a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 902a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 903a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = buffer; 904784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl != NULL) { 90597194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen *actualUrl = (*source)->getUri(); 906784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl->isEmpty()) { 907784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo *actualUrl = url; 908784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 909784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 910a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91143ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih return bytesRead; 912a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 913a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist( 91514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *url, uint8_t *curPlaylistHash, bool *unchanged) { 916b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ALOGV("fetchPlaylist '%s'", url); 917b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 9187e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = false; 9197e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 920a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 921784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 actualUrl; 92243ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t err = fetchFile(url, &buffer, 0, -1, 0, NULL, &actualUrl); 923a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 92443ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih if (err <= 0) { 925a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 926a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 927a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9287e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // MD5 functionality is not available on the simulator, treat all 9297e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlists as changed. 9307e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9317e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS) 9327e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber uint8_t hash[16]; 9337e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9347e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_CTX m; 9357e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Init(&m); 9367e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Update(&m, buffer->data(), buffer->size()); 9377e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9387e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Final(hash, &m); 9397e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 94014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) { 9417e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlist unchanged 9427e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = true; 9437e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9447e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber return NULL; 9457e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 9467e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 94714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL) { 94814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber memcpy(curPlaylistHash, hash, sizeof(hash)); 94914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 9507e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif 9517e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 952a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = 953784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo new M3UParser(actualUrl.string(), buffer->data(), buffer->size()); 954a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 955a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->initCheck() != OK) { 95629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to parse .m3u8 playlist"); 9579067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber 958a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 959a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 960a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 961a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return playlist; 962a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 963a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 964b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe#if 0 965a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() { 966a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return (double)rand() / RAND_MAX; 967a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 968b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe#endif 969a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 970a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() { 971a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() == 0) { 972a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 973a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 974a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 975a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1 976a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char value[PROPERTY_VALUE_MAX]; 977673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber ssize_t index = -1; 97814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 979a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char *end; 98014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtol(value, &end, 10); 98114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 98214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 98314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0 && (size_t)index >= mBandwidthItems.size()) { 98414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 985a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 986a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 987a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 98814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index < 0) { 98914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t bandwidthBps; 99014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mHTTPDataSource != NULL 99114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) { 99214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); 99314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 99414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("no bandwidth estimate."); 99514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return 0; // Pick the lowest bandwidth stream by default. 99614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 997a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 99814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 99914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.max-bw", value, NULL)) { 100014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 100114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber long maxBw = strtoul(value, &end, 10); 100214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (end > value && *end == '\0') { 100314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (maxBw > 0 && bandwidthBps > maxBw) { 100414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth capped to %ld bps", maxBw); 100514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = maxBw; 100614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 100714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 100814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1009a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 101014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pick the highest bandwidth stream below or equal to estimated bandwidth. 101114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 101214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 101300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih while (index > 0) { 101400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // consider only 80% of the available bandwidth, but if we are switching up, 101500598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // be even more conservative (70%) to avoid overestimating and immediately 101600598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // switching back. 101700598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih size_t adjustedBandwidthBps = bandwidthBps; 101800598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih if (index > mCurBandwidthIndex) { 101900598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih adjustedBandwidthBps = adjustedBandwidthBps * 7 / 10; 102000598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } else { 102100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih adjustedBandwidthBps = adjustedBandwidthBps * 8 / 10; 102200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } 102300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih if (mBandwidthItems.itemAt(index).mBandwidth <= adjustedBandwidthBps) { 102400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih break; 102500598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } 102614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber --index; 102714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1028a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1029a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1030a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Change bandwidth at random() 1031a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = uniformRand() * mBandwidthItems.size(); 1032a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1033a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // There's a 50% chance to stay on the current bandwidth and 1034a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // a 50% chance to switch to the next higher bandwidth (wrapping around 1035a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // to lowest) 1036a44153c1a57202fb538659eb50706e60454d6273Andreas Huber const size_t kMinIndex = 0; 1037a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1038309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih static ssize_t mCurBandwidthIndex = -1; 103914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1040a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index; 1041309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mCurBandwidthIndex < 0) { 1042a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 1043a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (uniformRand() < 0.5) { 1044309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih index = (size_t)mCurBandwidthIndex; 1045a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 1046309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih index = mCurBandwidthIndex + 1; 1047a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index == mBandwidthItems.size()) { 1048a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 1049a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1050a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1051309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex = index; 1052a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1053a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec 1054a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1055a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 1056a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) { 1057a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 1058a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 105914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1 106014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 106114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t index; 106214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 106314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 106414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtoul(value, &end, 10); 106514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 106614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 106714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= mBandwidthItems.size()) { 106814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 106914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 107014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 107114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = 0; 107214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1073a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else 1074a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream 1075a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif 1076a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 107714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GE(index, 0); 107814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1079a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return index; 1080a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1081a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1082b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shihint64_t LiveSession::latestMediaSegmentStartTimeUs() { 1083b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih sp<AMessage> audioMeta = mPacketSources.valueFor(STREAMTYPE_AUDIO)->getLatestDequeuedMeta(); 1084b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih int64_t minSegmentStartTimeUs = -1, videoSegmentStartTimeUs = -1; 1085b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (audioMeta != NULL) { 1086b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih audioMeta->findInt64("segmentStartTimeUs", &minSegmentStartTimeUs); 1087b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1088b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1089b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih sp<AMessage> videoMeta = mPacketSources.valueFor(STREAMTYPE_VIDEO)->getLatestDequeuedMeta(); 1090b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (videoMeta != NULL 1091b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih && videoMeta->findInt64("segmentStartTimeUs", &videoSegmentStartTimeUs)) { 1092b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (minSegmentStartTimeUs < 0 || videoSegmentStartTimeUs < minSegmentStartTimeUs) { 1093b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih minSegmentStartTimeUs = videoSegmentStartTimeUs; 1094b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1095b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1096b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1097b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return minSegmentStartTimeUs; 1098b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih} 1099b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 110014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) { 110114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 110214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 11037e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 110414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mReconfigurationInProgress) { 1105800599cdd50737de1cde483a34b39923750b0658Robert Shih changeConfiguration(timeUs, mCurBandwidthIndex); 1106800599cdd50737de1cde483a34b39923750b0658Robert Shih return OK; 1107800599cdd50737de1cde483a34b39923750b0658Robert Shih } else { 1108800599cdd50737de1cde483a34b39923750b0658Robert Shih return -EWOULDBLOCK; 11097e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 11107e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber} 11117e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 111214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const { 111314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t maxDurationUs = 0ll; 111414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 111514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs; 1116b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 111714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (fetcherDurationUs >= 0ll && fetcherDurationUs > maxDurationUs) { 111814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber maxDurationUs = fetcherDurationUs; 1119a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1120a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1121a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *durationUs = maxDurationUs; 1123a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 112514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11260f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 112714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const { 112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 112914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return getDuration(&durationUs) == OK && durationUs >= 0; 113014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11310f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 113214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const { 113314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return false; 113414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11350f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 1136404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangsize_t LiveSession::getTrackCount() const { 11379d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih if (mPlaylist == NULL) { 11389d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return 0; 11399d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } else { 11409d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return mPlaylist->getTrackCount(); 11419d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } 1142404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang} 1143404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang 1144404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangsp<AMessage> LiveSession::getTrackInfo(size_t trackIndex) const { 11459d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih if (mPlaylist == NULL) { 11469d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return NULL; 11479d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } else { 11489d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return mPlaylist->getTrackInfo(trackIndex); 11499d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } 1150dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1151dcb89b3b505522efde173c105a851c412f947178Chong Zhang 1152dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) { 1153b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (mPlaylist == NULL) { 1154b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return INVALID_OPERATION; 1155b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1156b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1157b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih ++mSubtitleGeneration; 1158dcb89b3b505522efde173c105a851c412f947178Chong Zhang status_t err = mPlaylist->selectTrack(index, select); 1159dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (err == OK) { 1160309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> msg = new AMessage(kWhatChangeConfiguration, id()); 1161309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("bandwidthIndex", mCurBandwidthIndex); 1162309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("pickTrack", select); 1163309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->post(); 1164dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1165dcb89b3b505522efde173c105a851c412f947178Chong Zhang return err; 1166dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1167dcb89b3b505522efde173c105a851c412f947178Chong Zhang 11681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchUp() { 11691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds. 11701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih status_t err = OK; 11711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mPacketSources.size(); ++i) { 11721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> source = mPacketSources.valueAt(i); 11731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t dur = source->getBufferedDurationUs(&err); 11741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (err == OK && dur > 10000000) { 11751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 11761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 11791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 11801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1181dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration( 1182dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs, size_t bandwidthIndex, bool pickTrack) { 11831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through reconfiguration. 11841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (changeConfiguration, onChangeConfiguration2, onChangeConfiguration3). 11851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 11861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 118714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(!mReconfigurationInProgress); 118814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = true; 1189a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1190309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex = bandwidthIndex; 119143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1192b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("changeConfiguration => timeUs:%" PRId64 " us, bwIndex:%zu, pickTrack:%d", 1193dcb89b3b505522efde173c105a851c412f947178Chong Zhang timeUs, bandwidthIndex, pickTrack); 119443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 119514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_LT(bandwidthIndex, mBandwidthItems.size()); 119614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex); 1197a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 11981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask = 0; // streams that should be fetched by the new fetcher 11991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t resumeMask = 0; // streams that should be fetched by the original fetcher 1200a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12018ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 12028ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 12038ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) { 12048ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask |= indexToType(i); 12058ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 120614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1207aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 120814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Step 1, stop and discard fetchers that are no longer needed. 120914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pause those that we'll reuse. 121014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 121114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 1212aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 121314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool discardFetcher = true; 1214aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 121514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If we're seeking all current fetchers are discarded. 121614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 1217309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // delay fetcher removal if not picking tracks 1218309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discardFetcher = pickTrack; 12191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12208ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 12211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType type = indexToType(j); 12221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((streamMask & type) && uri == URIs[j]) { 12231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih resumeMask |= type; 12241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih streamMask &= ~type; 1225309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discardFetcher = false; 12268ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 12276801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 122814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1229a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 123014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (discardFetcher) { 123114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 12326801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } else { 123314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->pauseAsync(); 12346801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 1235a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1236a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg; 12381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (timeUs < 0ll) { 1239309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // skip onChangeConfiguration2 (decoder destruction) if not seeking. 12401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration3, id()); 12411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 12421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration2, id()); 12431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 124414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("streamMask", streamMask); 12451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("resumeMask", resumeMask); 1246309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("pickTrack", pickTrack); 124714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt64("timeUs", timeUs); 12488ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1249309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((streamMask | resumeMask) & indexToType(i)) { 12508ca002eedc747dd854b61cbe364b52c06869273fRobert Shih msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str()); 12518ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 12526e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 1253a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 125414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Every time a fetcher acknowledges the stopAsync or pauseAsync request 125514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we'll decrement mContinuationCounter, once it reaches zero, i.e. all 125614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // fetchers have completed their asynchronous operation, we'll post 125714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // mContinuation, which then is handled below in onChangeConfiguration2. 125814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 125914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 126088b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 126114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 126214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 12635ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 12645ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 12655ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 1266800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply->setInt32("err", OK); 12675ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 1268800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = 0; 1269800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply.clear(); 12705ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 127188b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber } 127214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1273a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1274dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) { 1275dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (!mReconfigurationInProgress) { 1276309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t pickTrack = 0, bandwidthIndex = mCurBandwidthIndex; 1277309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->findInt32("pickTrack", &pickTrack); 1278309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->findInt32("bandwidthIndex", &bandwidthIndex); 1279309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih changeConfiguration(-1ll /* timeUs */, bandwidthIndex, pickTrack); 1280dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else { 1281dcb89b3b505522efde173c105a851c412f947178Chong Zhang msg->post(1000000ll); // retry in 1 sec 1282dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1283dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1284dcb89b3b505522efde173c105a851c412f947178Chong Zhang 128514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { 128614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 1287bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 128814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers are either suspended or have been removed now. 1289bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 1290309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih uint32_t streamMask, resumeMask; 129114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 1292309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1293309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1294309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // currently onChangeConfiguration2 is only called for seeking; 1295309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // remove the following CHECK if using it else where. 1296309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK_EQ(resumeMask, 0); 1297309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamMask |= resumeMask; 1298bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 12998ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 13008ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 13018ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 13028ca002eedc747dd854b61cbe364b52c06869273fRobert Shih const AString &uriKey = mStreams[i].uriKey(); 13038ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(uriKey.c_str(), &URIs[i])); 13048ca002eedc747dd854b61cbe364b52c06869273fRobert Shih ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str()); 13058ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 130622fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 13073831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 130814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Determine which decoders to shutdown on the player side, 130914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // a decoder has to be shutdown if either 131014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 1) its streamtype was active before but now longer isn't. 131114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // or 131214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 2) its streamtype was already active and still is but the URI 131314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has changed. 131414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t changedMask = 0; 13158ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) { 13168ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (((mStreamMask & streamMask & indexToType(i)) 13178ca002eedc747dd854b61cbe364b52c06869273fRobert Shih && !(URIs[i] == mStreams[i].mUri)) 13188ca002eedc747dd854b61cbe364b52c06869273fRobert Shih || (mStreamMask & ~streamMask & indexToType(i))) { 13198ca002eedc747dd854b61cbe364b52c06869273fRobert Shih changedMask |= indexToType(i); 13208ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1321b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } 1322b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 132314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (changedMask == 0) { 132414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If nothing changed as far as the audio/video decoders 132514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // are concerned we can proceed. 132614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 132714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return; 132814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 132943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 133014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Something changed, inform the player which will shutdown the 133114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // corresponding decoders and will post the reply once that's done. 133214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the reply will continue executing below in 133314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // onChangeConfiguration3. 133414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 133514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatStreamsChanged); 133614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("changedMask", changedMask); 133720f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber 133814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setWhat(kWhatChangeConfiguration3); 133914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setTarget(id()); 1340b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 134114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setMessage("reply", msg); 134214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 134314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1344b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 134514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { 13461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mContinuation.clear(); 134714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All remaining fetchers are still suspended, the player has shutdown 134814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // any decoders that needed it. 1349b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 13501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask, resumeMask; 135114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 13521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1353a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 135414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 1355309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t pickTrack; 13561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool switching = false; 135714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 1358309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(msg->findInt32("pickTrack", &pickTrack)); 1359a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 136014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 1361309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!pickTrack) { 1362309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih switching = true; 1363309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1364309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mRealTimeBaseUs = ALooper::GetNowUs() - mLastDequeuedTimeUs; 1365309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1366309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 136714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1368a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1369f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1370f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (streamMask & indexToType(i)) { 1371f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (switching) { 1372f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mNewUri)); 1373f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } else { 1374f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri)); 1375f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1376f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1377f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1378f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1379309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mNewStreamMask = streamMask | resumeMask; 1380f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (switching) { 1381f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mSwapMask = mStreamMask & ~resumeMask; 1382f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1383a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 13841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Of all existing fetchers: 13851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Resume fetchers that are still needed and assign them original packet sources. 13861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Mark otherwise unneeded fetchers for removal. 13871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ALOGV("resuming fetchers for mask 0x%08x", resumeMask); 138814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 138914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 13900df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber 13918ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 1392dc793ce8c0ead27ab43e40ce09f27fe338323502Robert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 13931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) { 13948ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 1395309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1396309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (j != kSubtitleIndex) { 1397309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGV("queueing dummy discontinuity for stream type %d", indexToType(j)); 1398309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1399309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1400309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1401309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_NONE, 1402309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih NULL, 1403309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih true); 1404309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 14058ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 140614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1407a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih FetcherInfo &info = mFetcherInfos.editValueAt(i); 14091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL 14101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih || sources[kSubtitleIndex] != NULL) { 14111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->startAsync( 14121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]); 14131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 14141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = true; 14151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1416a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1417a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 141814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // streamMask now only contains the types that need a new fetcher created. 1419a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 142014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (streamMask != 0) { 142114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("creating new fetchers for mask 0x%08x", streamMask); 1422a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1423a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Find out when the original fetchers have buffered up to and start the new fetchers 14251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // at a later timestamp. 14268ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; i++) { 14278ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (!(indexToType(i) & streamMask)) { 14288ca002eedc747dd854b61cbe364b52c06869273fRobert Shih continue; 14298ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 14301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 143114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 1432f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih uri = switching ? mStreams[i].mNewUri : mStreams[i].mUri; 14339b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 143414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str()); 143514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(fetcher != NULL); 1436a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1437309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t startTimeUs = -1; 1438309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t segmentStartTimeUs = -1ll; 1439309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discontinuitySeq = -1; 14408ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 14411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1442b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (i == kSubtitleIndex) { 1443b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih segmentStartTimeUs = latestMediaSegmentStartTimeUs(); 1444b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1445b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 14468ca002eedc747dd854b61cbe364b52c06869273fRobert Shih // TRICKY: looping from i as earlier streams are already removed from streamMask 14478ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = i; j < kMaxStreams; ++j) { 1448f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih const AString &streamUri = switching ? mStreams[j].mNewUri : mStreams[j].mUri; 1449f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if ((streamMask & indexToType(j)) && uri == streamUri) { 14508ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 14511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1452309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs >= 0) { 14531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 1454309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs = timeUs; 1455309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1456309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1457309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> extra = new AMessage; 1458309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih extra->setInt64("timeUs", timeUs); 1459309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1460309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1461309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_SEEK, extra, true); 14621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 1463309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t type; 1464309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> meta; 1465309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (pickTrack) { 1466309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // selecting 1467309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih meta = sources[j]->getLatestDequeuedMeta(); 1468309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1469309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adapting 1470309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih meta = sources[j]->getLatestEnqueuedMeta(); 1471309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 14721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 14731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (meta != NULL && !meta->findInt32("discontinuity", &type)) { 1474309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t tmpUs; 1475309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt64("timeUs", &tmpUs)); 1476309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (startTimeUs < 0 || tmpUs < startTimeUs) { 1477309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs = tmpUs; 1478309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1479309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1480309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt64("segmentStartTimeUs", &tmpUs)); 1481309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (segmentStartTimeUs < 0 || tmpUs < segmentStartTimeUs) { 1482309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih segmentStartTimeUs = tmpUs; 14831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1484309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1485309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t seq; 1486309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt32("discontinuitySeq", &seq)); 1487309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (discontinuitySeq < 0 || seq < discontinuitySeq) { 1488309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuitySeq = seq; 14891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 14901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 14911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1492309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (pickTrack) { 1493309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // selecting track, queue discontinuities before content 1494309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->clear(); 1495309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (j == kSubtitleIndex) { 1496309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih break; 1497309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1498309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1499309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1500309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1501309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true); 1502309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1503309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adapting, queue discontinuities after resume 1504309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j] = mPacketSources2.valueFor(indexToType(j)); 1505309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->clear(); 1506309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 1507309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (extraStreams & indexToType(j)) { 1508309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->queueAccessUnit(createFormatChangeBuffer(/*swap*/ false)); 1509309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 15101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1512a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 15138ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask &= ~indexToType(j); 15148ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1515a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 151614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 15178ca002eedc747dd854b61cbe364b52c06869273fRobert Shih fetcher->startAsync( 15188ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kAudioIndex], 15198ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kVideoIndex], 15208ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kSubtitleIndex], 1521309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs < 0 ? mLastSeekTimeUs : startTimeUs, 1522309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih segmentStartTimeUs, 1523309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuitySeq, 1524309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih switching); 1525a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1526a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 152714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers have now been started, the configuration change 152814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has completed. 1529a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 153000598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih cancelCheckBandwidthEvent(); 153114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber scheduleCheckBandwidthEvent(); 1532a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 153314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("XXX configuration change completed."); 153414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = false; 15351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switching) { 15361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = true; 15371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 15381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 15391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1540a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 154114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mDisconnectReplyID != 0) { 154214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 1543a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 154414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1545a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 15461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onSwapped(const sp<AMessage> &msg) { 15471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 15481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 15491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 15501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 15511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t stream; 15541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("stream", &stream)); 1555f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1556f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ssize_t idx = typeToIndex(stream); 1557f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(idx >= 0); 1558f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if ((mNewStreamMask & stream) && mStreams[idx].mNewUri.empty()) { 1559f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ALOGW("swapping stream type %d %s to empty stream", stream, mStreams[idx].mUri.c_str()); 1560f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1561f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mUri = mStreams[idx].mNewUri; 1562f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mNewUri.clear(); 1563f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1564309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mSwapMask &= ~stream; 1565309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mSwapMask != 0) { 15661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 15671543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Check if new variant contains extra streams. 15701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 15711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih while (extraStreams) { 15721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType extraStream = (StreamType) (extraStreams & ~(extraStreams - 1)); 15731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(extraStream); 15741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih extraStreams &= ~extraStream; 1575f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1576f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih idx = typeToIndex(extraStream); 1577f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(idx >= 0); 1578f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (mStreams[idx].mNewUri.empty()) { 1579f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ALOGW("swapping extra stream type %d %s to empty stream", 1580f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih extraStream, mStreams[idx].mUri.c_str()); 1581f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1582f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mUri = mStreams[idx].mNewUri; 1583f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mNewUri.clear(); 15841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 15871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 15881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15890ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shihvoid LiveSession::onCheckSwitchDown() { 15900ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (mSwitchDownMonitor == NULL) { 15910ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 15920ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 15930ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 15940ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 15950ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int32_t targetDuration; 15960ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(indexToType(i)); 15970ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih sp<AMessage> meta = packetSource->getLatestDequeuedMeta(); 15980ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 15990ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (meta != NULL && meta->findInt32("targetDuration", &targetDuration) ) { 16000ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int64_t bufferedDurationUs = packetSource->getEstimatedDurationUs(); 16010ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int64_t targetDurationUs = targetDuration * 1000000ll; 16020ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16030ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (bufferedDurationUs < targetDurationUs / 3) { 16040ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih (new AMessage(kWhatSwitchDown, id()))->post(); 16050ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 16060ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16070ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16080ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16090ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16100ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor->post(1000000ll); 16110ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih} 16120ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16130ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shihvoid LiveSession::onSwitchDown() { 16140ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress || mCurBandwidthIndex == 0) { 16150ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16160ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16170ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16180ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih ssize_t bandwidthIndex = getBandwidthIndex(); 16190ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (bandwidthIndex < mCurBandwidthIndex) { 16200ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih changeConfiguration(-1, bandwidthIndex, false); 16210ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16220ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16230ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16240ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih changeConfiguration(-1, mCurBandwidthIndex - 1, false); 16250ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih} 16260ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// Mark switch done when: 1628309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih// 1. all old buffers are swapped out 16291543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::tryToFinishBandwidthSwitch() { 1630309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!mSwitchInProgress) { 1631309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return; 1632309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1633309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 16341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool needToRemoveFetchers = false; 16351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 16361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.valueAt(i).mToBeRemoved) { 16371543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih needToRemoveFetchers = true; 16381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 16391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1641309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1642309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!needToRemoveFetchers && mSwapMask == 0) { 1643309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGI("mSwitchInProgress = false"); 16441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 16451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 16461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 16481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 164914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() { 165014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id()); 165114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("generation", mCheckBandwidthGeneration); 165214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(10000000ll); 1653a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1654a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 165514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() { 165614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ++mCheckBandwidthGeneration; 1657a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1658a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 16591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::cancelBandwidthSwitch() { 16601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 16611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration++; 16621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 16631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 1664f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1665f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 1666f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih FetcherInfo& info = mFetcherInfos.editValueAt(i); 1667f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (info.mToBeRemoved) { 1668f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih info.mToBeRemoved = false; 1669f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1670f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1671f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1672f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1673f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (!mStreams[i].mNewUri.empty()) { 1674f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ssize_t j = mFetcherInfos.indexOfKey(mStreams[i].mNewUri); 1675f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (j < 0) { 1676f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[i].mNewUri.clear(); 1677f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih continue; 1678f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1679f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1680f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih const FetcherInfo &info = mFetcherInfos.valueAt(j); 1681f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih info.mFetcher->stopAsync(); 1682f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mFetcherInfos.removeItemsAt(j); 1683f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[i].mNewUri.clear(); 1684f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1685f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 16861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 16871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 16881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) { 16891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress) { 16901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 16911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1693309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mCurBandwidthIndex < 0) { 16941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 169514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 169614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1697309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (bandwidthIndex == (size_t)mCurBandwidthIndex) { 16981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 1699309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else if (bandwidthIndex > (size_t)mCurBandwidthIndex) { 17001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return canSwitchUp(); 17011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 17021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 17031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 17041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 17051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 170600598ec0b15426197494aaf9e5ec0bc88507c762Robert Shihvoid LiveSession::onCheckBandwidth(const sp<AMessage> &msg) { 170714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t bandwidthIndex = getBandwidthIndex(); 17081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (canSwitchBandwidthTo(bandwidthIndex)) { 170914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(-1ll /* timeUs */, bandwidthIndex); 17101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 171100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // Come back and check again 10 seconds later in case there is nothing to do now. 171200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // If we DO change configuration, once that completes it'll schedule a new 171300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // check bandwidth event with an incremented mCheckBandwidthGeneration. 171400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih msg->post(10000000ll); 171514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1716a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1717a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 171814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) { 171914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(mInPreparationPhase); 1720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 172114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 172214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == OK || err == ERROR_END_OF_STREAM) { 172314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPrepared); 172414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 172514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPreparationFailed); 172614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 172714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1728a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 172914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 1730a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 173114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mInPreparationPhase = false; 17320ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 17330ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor = new AMessage(kWhatCheckSwitchDown, id()); 17340ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor->post(); 1735b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber} 1736b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1737a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} // namespace android 1738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1739