LiveSession.cpp revision 895651b07fec30b0f9b0d2499599a179d95c9be4
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 unsigned long bandwidth; 689a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth)); 690a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 69114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (initialBandwidth == 0) { 69214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidth = item.mBandwidth; 69314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 69414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 695a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.push(item); 696a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 697a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 698a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(mBandwidthItems.size(), 0u); 699a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 700a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.sort(SortByBandwidth); 70114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 70214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mBandwidthItems.size(); ++i) { 70314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mBandwidthItems.itemAt(i).mBandwidth == initialBandwidth) { 70414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidthIndex = i; 70514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 70614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 70714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 70814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 70914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // dummy item. 71014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber BandwidthItem item; 71114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = 0; 71214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mBandwidth = 0; 71314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mBandwidthItems.push(item); 714a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 715a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 716309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mPlaylist->pickRandomMediaItems(); 717dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration( 718309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 0ll /* timeUs */, initialBandwidthIndex, false /* pickTrack */); 719a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 72114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::finishDisconnect() { 72214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // No reconfiguration is currently pending, make sure none will trigger 72314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // during disconnection either. 72414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber cancelCheckBandwidthEvent(); 72514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 7261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through disconnect. 7271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (finishDisconnect, onFinishDisconnect2) 7281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 7291543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 7300ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih // cancel switch down monitor 7310ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor.clear(); 7320ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 73314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 73414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 73514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 73614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 73714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id()); 738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 73914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 74014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 741ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 74214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 74314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 74414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 74514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 74614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 74714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onFinishDisconnect2() { 74814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 74914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(ERROR_END_OF_STREAM); 75114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(ERROR_END_OF_STREAM); 75214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 75414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(ERROR_END_OF_STREAM); 75514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response = new AMessage; 75714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->setInt32("err", OK); 75814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 75914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->postReply(mDisconnectReplyID); 76014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mDisconnectReplyID = 0; 76114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 76214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 76314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { 76414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ssize_t index = mFetcherInfos.indexOfKey(uri); 76514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 76614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0) { 76714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return NULL; 76814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 76914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 77014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id()); 77114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setString("uri", uri); 7721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih notify->setInt32("switchGeneration", mSwitchGeneration); 77314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 77414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo info; 775b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih info.mFetcher = new PlaylistFetcher(notify, this, uri, mSubtitleGeneration); 77614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mDurationUs = -1ll; 77714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mIsPrepared = false; 7781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = false; 77914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber looper()->registerHandler(info.mFetcher); 78014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.add(uri, info); 78214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return info.mFetcher; 784a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 785a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 7868dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih/* 7878dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Illustration of parameters: 7888dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 7898dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 0 `range_offset` 7908dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * +------------+-------------------------------------------------------+--+--+ 7918dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | | next block to fetch | | | 7928dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | `source` handle => `out` buffer | | | | 7938dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | 7948dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | |<----------- `range_length` / buffer capacity ----------->| | 7958dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * |<------------------------------ file_size ------------------------------->| 7968dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 7978dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Special parameter values: 7988dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - range_length == -1 means entire file 7998dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - block_size == 0 means entire range 8008dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 8018dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih */ 80243ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shihssize_t LiveSession::fetchFile( 8032aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber const char *url, sp<ABuffer> *out, 8048dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih int64_t range_offset, int64_t range_length, 8058dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih uint32_t block_size, /* download block size */ 80697194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen sp<DataSource> *source, /* to return and reuse source */ 807784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 *actualUrl) { 8088dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih off64_t size; 8098dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<DataSource> temp_source; 8108dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (source == NULL) { 8118dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih source = &temp_source; 8128dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 813a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8148dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*source == NULL) { 8158dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (!strncasecmp(url, "file://", 7)) { 8168dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = new FileSource(url + 7); 8178dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else if (strncasecmp(url, "http://", 7) 8188dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih && strncasecmp(url, "https://", 8)) { 8198dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return ERROR_UNSUPPORTED; 8208dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else { 8218dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih KeyedVector<String8, String8> headers = mExtraHeaders; 8228dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (range_offset > 0 || range_length >= 0) { 8238dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih headers.add( 8248dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8("Range"), 8258dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8( 8268dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih StringPrintf( 8278dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih "bytes=%lld-%s", 8288dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset, 8298dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length < 0 8308dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ? "" : StringPrintf("%lld", 8318dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset + range_length - 1).c_str()).c_str())); 8328dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 8338dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t err = mHTTPDataSource->connect(url, &headers); 834a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8358dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (err != OK) { 8368dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return err; 8378dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 838a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8398dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = mHTTPDataSource; 840a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 841a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 842a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8438dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t getSizeErr = (*source)->getSize(&size); 8448dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (getSizeErr != OK) { 845a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size = 65536; 846a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 847a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8488dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); 8498dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*out == NULL) { 8508dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih buffer->setRange(0, 0); 8518dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 852a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 85343ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t bytesRead = 0; 8548dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // adjust range_length if only reading partial block 855b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (block_size > 0 && (range_length == -1 || (int64_t)(buffer->size() + block_size) < range_length)) { 8568dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length = buffer->size() + block_size; 8578dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 858a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (;;) { 8598dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // Only resize when we don't know the size. 860a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bufferRemaining = buffer->capacity() - buffer->size(); 8618dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (bufferRemaining == 0 && getSizeErr != OK) { 862a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bufferRemaining = 32768; 863a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 864b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("increasing download buffer to %zu bytes", 865a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size() + bufferRemaining); 866a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 867a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining); 868a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memcpy(copy->data(), buffer->data(), buffer->size()); 869a44153c1a57202fb538659eb50706e60454d6273Andreas Huber copy->setRange(0, buffer->size()); 870a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 871a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer = copy; 872a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 873a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8742aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber size_t maxBytesToRead = bufferRemaining; 8752aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (range_length >= 0) { 8762aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber int64_t bytesLeftInRange = range_length - buffer->size(); 877b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (bytesLeftInRange < (int64_t)maxBytesToRead) { 8782aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead = bytesLeftInRange; 8792aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 8802aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (bytesLeftInRange == 0) { 8812aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber break; 8822aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 8832aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 8842aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 8852aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 8868dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) 8878dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // to help us break out of the loop. 8888dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ssize_t n = (*source)->readAt( 889a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size(), buffer->data() + buffer->size(), 8902aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead); 891a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 892a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n < 0) { 89320ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber return n; 894a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 895a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 896a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n == 0) { 897a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 898a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 899a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 900a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, buffer->size() + (size_t)n); 90143ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih bytesRead += n; 902a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 903a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 904a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = buffer; 905784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl != NULL) { 90697194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen *actualUrl = (*source)->getUri(); 907784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl->isEmpty()) { 908784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo *actualUrl = url; 909784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 910784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 911a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91243ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih return bytesRead; 913a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 914a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 91514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist( 91614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *url, uint8_t *curPlaylistHash, bool *unchanged) { 917b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ALOGV("fetchPlaylist '%s'", url); 918b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 9197e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = false; 9207e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 921a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 922784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 actualUrl; 92343ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t err = fetchFile(url, &buffer, 0, -1, 0, NULL, &actualUrl); 924a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 92543ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih if (err <= 0) { 926a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 927a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 928a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9297e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // MD5 functionality is not available on the simulator, treat all 9307e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlists as changed. 9317e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9327e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS) 9337e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber uint8_t hash[16]; 9347e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9357e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_CTX m; 9367e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Init(&m); 9377e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Update(&m, buffer->data(), buffer->size()); 9387e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9397e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Final(hash, &m); 9407e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 94114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) { 9427e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlist unchanged 9437e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = true; 9447e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9457e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber return NULL; 9467e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 9477e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 94814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL) { 94914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber memcpy(curPlaylistHash, hash, sizeof(hash)); 95014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 9517e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif 9527e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 953a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = 954784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo new M3UParser(actualUrl.string(), buffer->data(), buffer->size()); 955a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 956a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->initCheck() != OK) { 95729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to parse .m3u8 playlist"); 9589067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber 959a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 960a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 961a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 962a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return playlist; 963a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 964a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 965a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() { 966a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return (double)rand() / RAND_MAX; 967a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 968a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 969a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() { 970a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() == 0) { 971a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 972a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 973a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 974a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1 975a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char value[PROPERTY_VALUE_MAX]; 976673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber ssize_t index = -1; 97714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 978a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char *end; 97914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtol(value, &end, 10); 98014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 98114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 98214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0 && (size_t)index >= mBandwidthItems.size()) { 98314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 984a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 985a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 986a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 98714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index < 0) { 98814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t bandwidthBps; 98914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mHTTPDataSource != NULL 99014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) { 99114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); 99214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 99314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("no bandwidth estimate."); 99414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return 0; // Pick the lowest bandwidth stream by default. 99514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 996a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 99714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 99814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.max-bw", value, NULL)) { 99914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 100014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber long maxBw = strtoul(value, &end, 10); 100114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (end > value && *end == '\0') { 100214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (maxBw > 0 && bandwidthBps > maxBw) { 100314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth capped to %ld bps", maxBw); 100414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = maxBw; 100514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 100614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 100714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1008a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 100914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pick the highest bandwidth stream below or equal to estimated bandwidth. 101014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 101114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 101200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih while (index > 0) { 101300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // consider only 80% of the available bandwidth, but if we are switching up, 101400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // be even more conservative (70%) to avoid overestimating and immediately 101500598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // switching back. 101600598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih size_t adjustedBandwidthBps = bandwidthBps; 101700598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih if (index > mCurBandwidthIndex) { 101800598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih adjustedBandwidthBps = adjustedBandwidthBps * 7 / 10; 101900598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } else { 102000598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih adjustedBandwidthBps = adjustedBandwidthBps * 8 / 10; 102100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } 102200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih if (mBandwidthItems.itemAt(index).mBandwidth <= adjustedBandwidthBps) { 102300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih break; 102400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } 102514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber --index; 102614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1027a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1028a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1029a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Change bandwidth at random() 1030a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = uniformRand() * mBandwidthItems.size(); 1031a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1032a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // There's a 50% chance to stay on the current bandwidth and 1033a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // a 50% chance to switch to the next higher bandwidth (wrapping around 1034a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // to lowest) 1035a44153c1a57202fb538659eb50706e60454d6273Andreas Huber const size_t kMinIndex = 0; 1036a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1037309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih static ssize_t mCurBandwidthIndex = -1; 103814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1039a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index; 1040309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mCurBandwidthIndex < 0) { 1041a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 1042a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (uniformRand() < 0.5) { 1043309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih index = (size_t)mCurBandwidthIndex; 1044a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 1045309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih index = mCurBandwidthIndex + 1; 1046a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index == mBandwidthItems.size()) { 1047a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 1048a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1049a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1050309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex = index; 1051a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1052a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec 1053a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1054a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 1055a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) { 1056a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 1057a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 105814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1 105914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 106014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t index; 106114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 106214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 106314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtoul(value, &end, 10); 106414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 106514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 106614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= mBandwidthItems.size()) { 106714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 106814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 106914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 107014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = 0; 107114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1072a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else 1073a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream 1074a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif 1075a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 107614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GE(index, 0); 107714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1078a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return index; 1079a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1080a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1081b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shihint64_t LiveSession::latestMediaSegmentStartTimeUs() { 1082b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih sp<AMessage> audioMeta = mPacketSources.valueFor(STREAMTYPE_AUDIO)->getLatestDequeuedMeta(); 1083b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih int64_t minSegmentStartTimeUs = -1, videoSegmentStartTimeUs = -1; 1084b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (audioMeta != NULL) { 1085b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih audioMeta->findInt64("segmentStartTimeUs", &minSegmentStartTimeUs); 1086b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1087b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1088b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih sp<AMessage> videoMeta = mPacketSources.valueFor(STREAMTYPE_VIDEO)->getLatestDequeuedMeta(); 1089b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (videoMeta != NULL 1090b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih && videoMeta->findInt64("segmentStartTimeUs", &videoSegmentStartTimeUs)) { 1091b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (minSegmentStartTimeUs < 0 || videoSegmentStartTimeUs < minSegmentStartTimeUs) { 1092b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih minSegmentStartTimeUs = videoSegmentStartTimeUs; 1093b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1094b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1095b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1096b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return minSegmentStartTimeUs; 1097b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih} 1098b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 109914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) { 110014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 110114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 11027e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 110314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mReconfigurationInProgress) { 1104800599cdd50737de1cde483a34b39923750b0658Robert Shih changeConfiguration(timeUs, mCurBandwidthIndex); 1105800599cdd50737de1cde483a34b39923750b0658Robert Shih return OK; 1106800599cdd50737de1cde483a34b39923750b0658Robert Shih } else { 1107800599cdd50737de1cde483a34b39923750b0658Robert Shih return -EWOULDBLOCK; 11087e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 11097e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber} 11107e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 111114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const { 1112895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia int64_t maxDurationUs = -1ll; 111314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 111414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs; 1115b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1116895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia if (fetcherDurationUs > maxDurationUs) { 111714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber maxDurationUs = fetcherDurationUs; 1118a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1119a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1120a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *durationUs = maxDurationUs; 1122a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 112414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11250f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 112614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const { 112714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return getDuration(&durationUs) == OK && durationUs >= 0; 112914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11300f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 113114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const { 113214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return false; 113314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11340f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 1135404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangsize_t LiveSession::getTrackCount() const { 11369d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih if (mPlaylist == NULL) { 11379d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return 0; 11389d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } else { 11399d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return mPlaylist->getTrackCount(); 11409d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } 1141404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang} 1142404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang 1143404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangsp<AMessage> LiveSession::getTrackInfo(size_t trackIndex) const { 11449d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih if (mPlaylist == NULL) { 11459d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return NULL; 11469d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } else { 11479d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return mPlaylist->getTrackInfo(trackIndex); 11489d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } 1149dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1150dcb89b3b505522efde173c105a851c412f947178Chong Zhang 1151dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) { 1152b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (mPlaylist == NULL) { 1153b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return INVALID_OPERATION; 1154b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1155b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1156b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih ++mSubtitleGeneration; 1157dcb89b3b505522efde173c105a851c412f947178Chong Zhang status_t err = mPlaylist->selectTrack(index, select); 1158dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (err == OK) { 1159309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> msg = new AMessage(kWhatChangeConfiguration, id()); 1160309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("bandwidthIndex", mCurBandwidthIndex); 1161309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("pickTrack", select); 1162309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->post(); 1163dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1164dcb89b3b505522efde173c105a851c412f947178Chong Zhang return err; 1165dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1166dcb89b3b505522efde173c105a851c412f947178Chong Zhang 116789bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shihssize_t LiveSession::getSelectedTrack(media_track_type type) const { 116889bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih if (mPlaylist == NULL) { 116989bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih return -1; 117089bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih } else { 117189bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih return mPlaylist->getSelectedTrack(type); 117289bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih } 117389bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih} 117489bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih 11751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchUp() { 11761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds. 11771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih status_t err = OK; 11781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mPacketSources.size(); ++i) { 11791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> source = mPacketSources.valueAt(i); 11801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t dur = source->getBufferedDurationUs(&err); 11811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (err == OK && dur > 10000000) { 11821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 11831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 11851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 11861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 11871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1188dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration( 1189dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs, size_t bandwidthIndex, bool pickTrack) { 11901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through reconfiguration. 11911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (changeConfiguration, onChangeConfiguration2, onChangeConfiguration3). 11921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 11931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 119414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(!mReconfigurationInProgress); 119514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = true; 1196a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1197309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex = bandwidthIndex; 119843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1199b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("changeConfiguration => timeUs:%" PRId64 " us, bwIndex:%zu, pickTrack:%d", 1200dcb89b3b505522efde173c105a851c412f947178Chong Zhang timeUs, bandwidthIndex, pickTrack); 120143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 120214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_LT(bandwidthIndex, mBandwidthItems.size()); 120314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex); 1204a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask = 0; // streams that should be fetched by the new fetcher 12061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t resumeMask = 0; // streams that should be fetched by the original fetcher 1207a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12088ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 12098ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 12108ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) { 12118ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask |= indexToType(i); 12128ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 121314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1214aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 121514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Step 1, stop and discard fetchers that are no longer needed. 121614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pause those that we'll reuse. 121714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 121814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 1219aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 122014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool discardFetcher = true; 1221aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 122214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If we're seeking all current fetchers are discarded. 122314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 1224309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // delay fetcher removal if not picking tracks 1225309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discardFetcher = pickTrack; 12261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12278ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 12281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType type = indexToType(j); 12291543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((streamMask & type) && uri == URIs[j]) { 12301543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih resumeMask |= type; 12311543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih streamMask &= ~type; 1232309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discardFetcher = false; 12338ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 12346801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 123514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1236a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 123714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (discardFetcher) { 123814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 12396801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } else { 124014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->pauseAsync(); 12416801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 1242a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1243a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg; 12451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (timeUs < 0ll) { 1246309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // skip onChangeConfiguration2 (decoder destruction) if not seeking. 12471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration3, id()); 12481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 12491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration2, id()); 12501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 125114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("streamMask", streamMask); 12521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("resumeMask", resumeMask); 1253309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("pickTrack", pickTrack); 125414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt64("timeUs", timeUs); 12558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1256309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((streamMask | resumeMask) & indexToType(i)) { 12578ca002eedc747dd854b61cbe364b52c06869273fRobert Shih msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str()); 12588ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 12596e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 1260a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 126114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Every time a fetcher acknowledges the stopAsync or pauseAsync request 126214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we'll decrement mContinuationCounter, once it reaches zero, i.e. all 126314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // fetchers have completed their asynchronous operation, we'll post 126414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // mContinuation, which then is handled below in onChangeConfiguration2. 126514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 126614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 126788b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 126814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 126914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 12705ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 12715ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 12725ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 1273800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply->setInt32("err", OK); 12745ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 1275800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = 0; 1276800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply.clear(); 12775ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 127888b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber } 127914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1280a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1281dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) { 1282dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (!mReconfigurationInProgress) { 1283309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t pickTrack = 0, bandwidthIndex = mCurBandwidthIndex; 1284309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->findInt32("pickTrack", &pickTrack); 1285309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->findInt32("bandwidthIndex", &bandwidthIndex); 1286309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih changeConfiguration(-1ll /* timeUs */, bandwidthIndex, pickTrack); 1287dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else { 1288dcb89b3b505522efde173c105a851c412f947178Chong Zhang msg->post(1000000ll); // retry in 1 sec 1289dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1290dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1291dcb89b3b505522efde173c105a851c412f947178Chong Zhang 129214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { 129314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 1294bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 129514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers are either suspended or have been removed now. 1296bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 1297309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih uint32_t streamMask, resumeMask; 129814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 1299309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1300309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1301309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // currently onChangeConfiguration2 is only called for seeking; 1302309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // remove the following CHECK if using it else where. 1303309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK_EQ(resumeMask, 0); 1304309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamMask |= resumeMask; 1305bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 13068ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 13078ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 13088ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 13098ca002eedc747dd854b61cbe364b52c06869273fRobert Shih const AString &uriKey = mStreams[i].uriKey(); 13108ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(uriKey.c_str(), &URIs[i])); 13118ca002eedc747dd854b61cbe364b52c06869273fRobert Shih ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str()); 13128ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 131322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 13143831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 131514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Determine which decoders to shutdown on the player side, 131614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // a decoder has to be shutdown if either 131714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 1) its streamtype was active before but now longer isn't. 131814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // or 131914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 2) its streamtype was already active and still is but the URI 132014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has changed. 132114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t changedMask = 0; 13228ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) { 13238ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (((mStreamMask & streamMask & indexToType(i)) 13248ca002eedc747dd854b61cbe364b52c06869273fRobert Shih && !(URIs[i] == mStreams[i].mUri)) 13258ca002eedc747dd854b61cbe364b52c06869273fRobert Shih || (mStreamMask & ~streamMask & indexToType(i))) { 13268ca002eedc747dd854b61cbe364b52c06869273fRobert Shih changedMask |= indexToType(i); 13278ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1328b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } 1329b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 133014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (changedMask == 0) { 133114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If nothing changed as far as the audio/video decoders 133214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // are concerned we can proceed. 133314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 133414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return; 133514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 133643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 133714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Something changed, inform the player which will shutdown the 133814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // corresponding decoders and will post the reply once that's done. 133914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the reply will continue executing below in 134014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // onChangeConfiguration3. 134114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 134214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatStreamsChanged); 134314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("changedMask", changedMask); 134420f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber 134514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setWhat(kWhatChangeConfiguration3); 134614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setTarget(id()); 1347b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 134814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setMessage("reply", msg); 134914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 135014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1351b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 135214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { 13531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mContinuation.clear(); 135414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All remaining fetchers are still suspended, the player has shutdown 135514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // any decoders that needed it. 1356b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 13571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask, resumeMask; 135814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 13591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1360a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 136114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 1362309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t pickTrack; 13631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool switching = false; 136414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 1365309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(msg->findInt32("pickTrack", &pickTrack)); 1366a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 136714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 1368309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!pickTrack) { 1369309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih switching = true; 1370309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1371309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mRealTimeBaseUs = ALooper::GetNowUs() - mLastDequeuedTimeUs; 1372309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1373309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 137414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1375a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1376f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1377f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (streamMask & indexToType(i)) { 1378f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (switching) { 1379f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mNewUri)); 1380f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } else { 1381f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri)); 1382f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1383f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1384f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1385f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1386309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mNewStreamMask = streamMask | resumeMask; 1387f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (switching) { 1388f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mSwapMask = mStreamMask & ~resumeMask; 1389f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1390a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 13911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Of all existing fetchers: 13921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Resume fetchers that are still needed and assign them original packet sources. 13931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Mark otherwise unneeded fetchers for removal. 13941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ALOGV("resuming fetchers for mask 0x%08x", resumeMask); 139514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 139614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 13970df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber 13988ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 1399dc793ce8c0ead27ab43e40ce09f27fe338323502Robert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 14001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) { 14018ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 1402309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1403309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (j != kSubtitleIndex) { 1404309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGV("queueing dummy discontinuity for stream type %d", indexToType(j)); 1405309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1406309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1407309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1408309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_NONE, 1409309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih NULL, 1410309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih true); 1411309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 14128ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 141314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1414a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih FetcherInfo &info = mFetcherInfos.editValueAt(i); 14161543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL 14171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih || sources[kSubtitleIndex] != NULL) { 14181543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->startAsync( 14191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]); 14201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 14211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = true; 14221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1423a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1424a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 142514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // streamMask now only contains the types that need a new fetcher created. 1426a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 142714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (streamMask != 0) { 142814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("creating new fetchers for mask 0x%08x", streamMask); 1429a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1430a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14311543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Find out when the original fetchers have buffered up to and start the new fetchers 14321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // at a later timestamp. 14338ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; i++) { 14348ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (!(indexToType(i) & streamMask)) { 14358ca002eedc747dd854b61cbe364b52c06869273fRobert Shih continue; 14368ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 14371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 143814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 1439f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih uri = switching ? mStreams[i].mNewUri : mStreams[i].mUri; 14409b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 144114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str()); 144214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(fetcher != NULL); 1443a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t latestSeq = -1; 1445309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t startTimeUs = -1; 1446309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t segmentStartTimeUs = -1ll; 1447309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discontinuitySeq = -1; 14488ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 14491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1450b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (i == kSubtitleIndex) { 1451b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih segmentStartTimeUs = latestMediaSegmentStartTimeUs(); 1452b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1453b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 14548ca002eedc747dd854b61cbe364b52c06869273fRobert Shih // TRICKY: looping from i as earlier streams are already removed from streamMask 14558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = i; j < kMaxStreams; ++j) { 1456f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih const AString &streamUri = switching ? mStreams[j].mNewUri : mStreams[j].mUri; 1457f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if ((streamMask & indexToType(j)) && uri == streamUri) { 14588ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 14591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1460309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs >= 0) { 14611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 1462309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs = timeUs; 1463309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1464309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1465309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> extra = new AMessage; 1466309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih extra->setInt64("timeUs", timeUs); 1467309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1468309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1469fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia ATSParser::DISCONTINUITY_TIME, extra, true); 14701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 1471309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t type; 1472309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t srcSegmentStartTimeUs; 1473309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> meta; 1474309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (pickTrack) { 1475309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // selecting 1476309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih meta = sources[j]->getLatestDequeuedMeta(); 1477309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1478309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adapting 1479309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih meta = sources[j]->getLatestEnqueuedMeta(); 1480309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 14811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 14821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (meta != NULL && !meta->findInt32("discontinuity", &type)) { 1483309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t tmpUs; 1484309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt64("timeUs", &tmpUs)); 1485309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (startTimeUs < 0 || tmpUs < startTimeUs) { 1486309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs = tmpUs; 1487309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1488309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1489309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt64("segmentStartTimeUs", &tmpUs)); 1490309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (segmentStartTimeUs < 0 || tmpUs < segmentStartTimeUs) { 1491309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih segmentStartTimeUs = tmpUs; 14921543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1493309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1494309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t seq; 1495309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt32("discontinuitySeq", &seq)); 1496309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (discontinuitySeq < 0 || seq < discontinuitySeq) { 1497309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuitySeq = seq; 14981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 14991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1501309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (pickTrack) { 1502309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // selecting track, queue discontinuities before content 1503309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->clear(); 1504309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (j == kSubtitleIndex) { 1505309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih break; 1506309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1507309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1508309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1509309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1510309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true); 1511309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1512309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adapting, queue discontinuities after resume 1513309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j] = mPacketSources2.valueFor(indexToType(j)); 1514309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->clear(); 1515309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 1516309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (extraStreams & indexToType(j)) { 1517309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->queueAccessUnit(createFormatChangeBuffer(/*swap*/ false)); 1518309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 15191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1521a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 15228ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask &= ~indexToType(j); 15238ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1524a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 152514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 15268ca002eedc747dd854b61cbe364b52c06869273fRobert Shih fetcher->startAsync( 15278ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kAudioIndex], 15288ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kVideoIndex], 15298ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kSubtitleIndex], 1530309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs < 0 ? mLastSeekTimeUs : startTimeUs, 1531309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih segmentStartTimeUs, 1532309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuitySeq, 1533309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih switching); 1534a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1535a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 153614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers have now been started, the configuration change 153714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has completed. 1538a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 153900598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih cancelCheckBandwidthEvent(); 154014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber scheduleCheckBandwidthEvent(); 1541a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 154214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("XXX configuration change completed."); 154314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = false; 15441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switching) { 15451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = true; 15461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 15471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 15481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1549a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 155014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mDisconnectReplyID != 0) { 155114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 1552a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 155314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1554a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 15551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onSwapped(const sp<AMessage> &msg) { 15561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 15571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 15581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 15591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 15601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t stream; 15631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("stream", &stream)); 1564f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1565f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ssize_t idx = typeToIndex(stream); 1566f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(idx >= 0); 1567f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if ((mNewStreamMask & stream) && mStreams[idx].mNewUri.empty()) { 1568f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ALOGW("swapping stream type %d %s to empty stream", stream, mStreams[idx].mUri.c_str()); 1569f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1570f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mUri = mStreams[idx].mNewUri; 1571f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mNewUri.clear(); 1572f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1573309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mSwapMask &= ~stream; 1574309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mSwapMask != 0) { 15751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 15761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Check if new variant contains extra streams. 15791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 15801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih while (extraStreams) { 15811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType extraStream = (StreamType) (extraStreams & ~(extraStreams - 1)); 15821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(extraStream); 15831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih extraStreams &= ~extraStream; 1584f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1585f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih idx = typeToIndex(extraStream); 1586f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(idx >= 0); 1587f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (mStreams[idx].mNewUri.empty()) { 1588f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ALOGW("swapping extra stream type %d %s to empty stream", 1589f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih extraStream, mStreams[idx].mUri.c_str()); 1590f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1591f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mUri = mStreams[idx].mNewUri; 1592f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mNewUri.clear(); 15931543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15941543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 15961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 15971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15980ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shihvoid LiveSession::onCheckSwitchDown() { 15990ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (mSwitchDownMonitor == NULL) { 16000ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16010ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16020ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16030ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 16040ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int32_t targetDuration; 16050ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(indexToType(i)); 16060ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih sp<AMessage> meta = packetSource->getLatestDequeuedMeta(); 16070ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16080ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (meta != NULL && meta->findInt32("targetDuration", &targetDuration) ) { 16090ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int64_t bufferedDurationUs = packetSource->getEstimatedDurationUs(); 16100ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int64_t targetDurationUs = targetDuration * 1000000ll; 16110ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16120ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (bufferedDurationUs < targetDurationUs / 3) { 16130ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih (new AMessage(kWhatSwitchDown, id()))->post(); 16140ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 16150ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16160ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16170ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16180ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16190ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor->post(1000000ll); 16200ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih} 16210ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16220ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shihvoid LiveSession::onSwitchDown() { 16230ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress || mCurBandwidthIndex == 0) { 16240ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16250ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16260ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16270ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih ssize_t bandwidthIndex = getBandwidthIndex(); 16280ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (bandwidthIndex < mCurBandwidthIndex) { 16290ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih changeConfiguration(-1, bandwidthIndex, false); 16300ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16310ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16320ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16330ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih changeConfiguration(-1, mCurBandwidthIndex - 1, false); 16340ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih} 16350ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// Mark switch done when: 1637309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih// 1. all old buffers are swapped out 16381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::tryToFinishBandwidthSwitch() { 1639309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!mSwitchInProgress) { 1640309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return; 1641309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1642309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 16431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool needToRemoveFetchers = false; 16441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 16451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.valueAt(i).mToBeRemoved) { 16461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih needToRemoveFetchers = true; 16471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 16481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1650309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1651309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!needToRemoveFetchers && mSwapMask == 0) { 1652309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGI("mSwitchInProgress = false"); 16531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 16541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 16551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 16571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 165814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() { 165914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id()); 166014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("generation", mCheckBandwidthGeneration); 166114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(10000000ll); 1662a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1663a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 166414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() { 166514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ++mCheckBandwidthGeneration; 1666a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1667a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 16681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::cancelBandwidthSwitch() { 16691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 16701543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration++; 16711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 16721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 1673f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1674f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 1675f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih FetcherInfo& info = mFetcherInfos.editValueAt(i); 1676f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (info.mToBeRemoved) { 1677f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih info.mToBeRemoved = false; 1678f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1679f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1680f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1681f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1682f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (!mStreams[i].mNewUri.empty()) { 1683f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ssize_t j = mFetcherInfos.indexOfKey(mStreams[i].mNewUri); 1684f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (j < 0) { 1685f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[i].mNewUri.clear(); 1686f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih continue; 1687f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1688f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1689f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih const FetcherInfo &info = mFetcherInfos.valueAt(j); 1690f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih info.mFetcher->stopAsync(); 1691f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mFetcherInfos.removeItemsAt(j); 1692f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[i].mNewUri.clear(); 1693f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1694f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 16951543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 16961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 16971543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) { 16981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress) { 16991543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 17001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 17011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1702309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mCurBandwidthIndex < 0) { 17031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 170414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 170514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1706309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (bandwidthIndex == (size_t)mCurBandwidthIndex) { 17071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 1708309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else if (bandwidthIndex > (size_t)mCurBandwidthIndex) { 17091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return canSwitchUp(); 17101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 17111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 17121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 17131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 17141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 171500598ec0b15426197494aaf9e5ec0bc88507c762Robert Shihvoid LiveSession::onCheckBandwidth(const sp<AMessage> &msg) { 171614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t bandwidthIndex = getBandwidthIndex(); 17171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (canSwitchBandwidthTo(bandwidthIndex)) { 171814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(-1ll /* timeUs */, bandwidthIndex); 17191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 172000598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // Come back and check again 10 seconds later in case there is nothing to do now. 172100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // If we DO change configuration, once that completes it'll schedule a new 172200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // check bandwidth event with an incremented mCheckBandwidthGeneration. 172300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih msg->post(10000000ll); 172414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1725a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1726a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 172714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) { 172814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(mInPreparationPhase); 1729a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 173014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 173114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == OK || err == ERROR_END_OF_STREAM) { 173214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPrepared); 173314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 173414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPreparationFailed); 173514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 173614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1737a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 173814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 1739a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 174014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mInPreparationPhase = false; 17410ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 17420ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor = new AMessage(kWhatCheckSwitchDown, id()); 17430ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor->post(); 1744b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber} 1745b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1746a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} // namespace android 1747a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1748