LiveSession.cpp revision 678bcdc852dd8f801f5c46fdc85db587b721d83d
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 52a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd// Number of recently-read bytes to use for bandwidth estimation 53a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowdconst size_t LiveSession::kBandwidthHistoryBytes = 200 * 1024; 54a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd 550df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas HuberLiveSession::LiveSession( 561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<AMessage> ¬ify, uint32_t flags, 5781e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber const sp<IMediaHTTPService> &httpService) 580df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber : mNotify(notify), 590df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber mFlags(flags), 601b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPService(httpService), 610df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber mInPreparationPhase(true), 621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPDataSource(new MediaHTTP(mHTTPService->makeHTTPConnection())), 63309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex(-1), 6414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mStreamMask(0), 651543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mNewStreamMask(0), 661543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask(0), 6714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mCheckBandwidthGeneration(0), 681543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration(0), 69b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih mSubtitleGeneration(0), 7014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mLastDequeuedTimeUs(0ll), 71dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs(0ll), 7214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress(false), 731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress(false), 745ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mDisconnectReplyID(0), 75309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mSeekReplyID(0), 76309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mFirstTimeUsValid(false), 77309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mFirstTimeUs(0), 78309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mLastSeekTimeUs(0) { 7914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 808ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kAudioIndex] = StreamItem("audio"); 818ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mStreams[kVideoIndex] = StreamItem("video"); 82e4f25c280a8f1655c31a745978e0fcbc61f91deeRobert Shih mStreams[kSubtitleIndex] = StreamItem("subtitles"); 8314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 848ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 85309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuities.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 868ca002eedc747dd854b61cbe364b52c06869273fRobert Shih mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */)); 88f69c996864844e8f669308af8412cede043062a2Robert Shih mBuffering[i] = false; 898ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 90a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd 91a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd size_t numHistoryItems = kBandwidthHistoryBytes / 92a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd PlaylistFetcher::kDownloadBlockSize + 1; 93a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd if (numHistoryItems < 5) { 94a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd numHistoryItems = 5; 95a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd } 96a93fd2be99d21629bed504b9b7df035fc2f54562Leena Winterrowd mHTTPDataSource->setBandwidthHistorySize(numHistoryItems); 97a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 98a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 99a44153c1a57202fb538659eb50706e60454d6273Andreas HuberLiveSession::~LiveSession() { 100a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 101a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihsp<ABuffer> LiveSession::createFormatChangeBuffer(bool swap) { 1031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ABuffer *discontinuity = new ABuffer(0); 1041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("discontinuity", ATSParser::DISCONTINUITY_FORMATCHANGE); 1051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("swapPacketSource", swap); 1061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt32("switchGeneration", mSwitchGeneration); 1071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih discontinuity->meta()->setInt64("timeUs", -1); 1081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return discontinuity; 1091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 1101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::swapPacketSource(StreamType stream) { 1121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps = mPacketSources.editValueFor(stream); 1131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> &aps2 = mPacketSources2.editValueFor(stream); 1141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> tmp = aps; 1151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps = aps2; 1161543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2 = tmp; 1171543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih aps2->clear(); 1181543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 1191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::dequeueAccessUnit( 12114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber StreamType stream, sp<ABuffer> *accessUnit) { 12214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 1231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // return -EWOULDBLOCK to avoid halting the decoder 1241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // when switching between audio/video and audio only. 1251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return -EWOULDBLOCK; 12614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 12714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 128309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih status_t finalResult; 129309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue = mDiscontinuities.valueFor(stream); 130309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (discontinuityQueue->hasBufferAvailable(&finalResult)) { 131309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->dequeueAccessUnit(accessUnit); 132309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // seeking, track switching 133309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> extra; 134309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t timeUs; 135309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((*accessUnit)->meta()->findMessage("extra", &extra) 136309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih && extra != NULL 137309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih && extra->findInt64("timeUs", &timeUs)) { 138309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // seeking only 139309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mLastSeekTimeUs = timeUs; 140309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityOffsetTimesUs.clear(); 141309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityAbsStartTimesUs.clear(); 142309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 143309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return INFO_DISCONTINUITY; 144309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 145309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 14614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 14714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 148f69c996864844e8f669308af8412cede043062a2Robert Shih ssize_t idx = typeToIndex(stream); 14914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!packetSource->hasBufferAvailable(&finalResult)) { 150f69c996864844e8f669308af8412cede043062a2Robert Shih if (finalResult == OK) { 151f69c996864844e8f669308af8412cede043062a2Robert Shih mBuffering[idx] = true; 152f69c996864844e8f669308af8412cede043062a2Robert Shih return -EAGAIN; 153f69c996864844e8f669308af8412cede043062a2Robert Shih } else { 154f69c996864844e8f669308af8412cede043062a2Robert Shih return finalResult; 155f69c996864844e8f669308af8412cede043062a2Robert Shih } 156f69c996864844e8f669308af8412cede043062a2Robert Shih } 157f69c996864844e8f669308af8412cede043062a2Robert Shih 158174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd int32_t targetDuration = 0; 159174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd sp<AMessage> meta = packetSource->getLatestEnqueuedMeta(); 160174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd if (meta != NULL) { 161174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd meta->findInt32("targetDuration", &targetDuration); 162174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd } 163174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd 164174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd int64_t targetDurationUs = targetDuration * 1000000ll; 165174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd if (targetDurationUs == 0 || 166174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd targetDurationUs > PlaylistFetcher::kMinBufferedDurationUs) { 167174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd // Fetchers limit buffering to 168174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd // min(3 * targetDuration, kMinBufferedDurationUs) 169174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd targetDurationUs = PlaylistFetcher::kMinBufferedDurationUs; 170174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd } 171174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd 172f69c996864844e8f669308af8412cede043062a2Robert Shih if (mBuffering[idx]) { 173f69c996864844e8f669308af8412cede043062a2Robert Shih if (mSwitchInProgress 174f69c996864844e8f669308af8412cede043062a2Robert Shih || packetSource->isFinished(0) 175174609765fb9c8cbd6aeb61f489746c3570bfee2Leena Winterrowd || packetSource->getEstimatedDurationUs() > targetDurationUs) { 176f69c996864844e8f669308af8412cede043062a2Robert Shih mBuffering[idx] = false; 177f69c996864844e8f669308af8412cede043062a2Robert Shih } 178f69c996864844e8f669308af8412cede043062a2Robert Shih } 179f69c996864844e8f669308af8412cede043062a2Robert Shih 180f69c996864844e8f669308af8412cede043062a2Robert Shih if (mBuffering[idx]) { 181f69c996864844e8f669308af8412cede043062a2Robert Shih return -EAGAIN; 18214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 18314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 184309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // wait for counterpart 185309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> otherSource; 18673d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih uint32_t mask = mNewStreamMask & mStreamMask; 18773d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih uint32_t fetchersMask = 0; 18873d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 18973d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih uint32_t fetcherMask = mFetcherInfos.valueAt(i).mFetcher->getStreamTypeMask(); 19073d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih fetchersMask |= fetcherMask; 19173d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih } 19273d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih mask &= fetchersMask; 19373d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih if (stream == STREAMTYPE_AUDIO && (mask & STREAMTYPE_VIDEO)) { 194309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih otherSource = mPacketSources.valueFor(STREAMTYPE_VIDEO); 19573d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7Robert Shih } else if (stream == STREAMTYPE_VIDEO && (mask & STREAMTYPE_AUDIO)) { 196309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih otherSource = mPacketSources.valueFor(STREAMTYPE_AUDIO); 197309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 198309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (otherSource != NULL && !otherSource->hasBufferAvailable(&finalResult)) { 199309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return finalResult == OK ? -EAGAIN : finalResult; 200309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 201309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 20214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = packetSource->dequeueAccessUnit(accessUnit); 20314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 204309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih size_t streamIdx; 20514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *streamStr; 20614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (stream) { 20714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_AUDIO: 208309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamIdx = kAudioIndex; 20914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "audio"; 21014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 21114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_VIDEO: 212309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamIdx = kVideoIndex; 21314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "video"; 21414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 21514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case STREAMTYPE_SUBTITLES: 216309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamIdx = kSubtitleIndex; 21714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr = "subs"; 21814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 21914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 22014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 22114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 22214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 223309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih StreamItem& strm = mStreams[streamIdx]; 22414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == INFO_DISCONTINUITY) { 225309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adaptive streaming, discontinuities in the playlist 22614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t type; 22714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK((*accessUnit)->meta()->findInt32("discontinuity", &type)); 22814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 22914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> extra; 23014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(*accessUnit)->meta()->findMessage("extra", &extra)) { 23114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra.clear(); 23214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 23314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 23414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] read discontinuity of type %d, extra = %s", 23514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber streamStr, 23614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber type, 23714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber extra == NULL ? "NULL" : extra->debugString().c_str()); 2381543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 2391543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t swap; 240309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((*accessUnit)->meta()->findInt32("swapPacketSource", &swap) && swap) { 2411543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 2421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK((*accessUnit)->meta()->findInt32("switchGeneration", &switchGeneration)); 2431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 2441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 2451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration == mSwitchGeneration) { 2461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(stream); 2471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg = new AMessage(kWhatSwapped, id()); 2481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("stream", stream); 2491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("switchGeneration", switchGeneration); 2501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->post(); 2511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 2521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 253309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 254309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih size_t seq = strm.mCurDiscontinuitySeq; 255309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t offsetTimeUs; 256309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityOffsetTimesUs.indexOfKey(seq) >= 0) { 257309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs = mDiscontinuityOffsetTimesUs.valueFor(seq); 258309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 259309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs = 0; 260309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 261309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 262309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih seq += 1; 263309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityAbsStartTimesUs.indexOfKey(strm.mCurDiscontinuitySeq) >= 0) { 264309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t firstTimeUs; 265309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = mDiscontinuityAbsStartTimesUs.valueFor(strm.mCurDiscontinuitySeq); 266309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs += strm.mLastDequeuedTimeUs - firstTimeUs; 267309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs += strm.mLastSampleDurationUs; 268309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 269309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih offsetTimeUs += strm.mLastSampleDurationUs; 270309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 271309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 272309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityOffsetTimesUs.add(seq, offsetTimeUs); 2731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 27414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else if (err == OK) { 275309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 276dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) { 277dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs; 278309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discontinuitySeq = 0; 279dcb89b3b505522efde173c105a851c412f947178Chong Zhang CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); 280309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih (*accessUnit)->meta()->findInt32("discontinuitySeq", &discontinuitySeq); 281309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih strm.mCurDiscontinuitySeq = discontinuitySeq; 282309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 283309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discard = 0; 284309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t firstTimeUs; 285309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityAbsStartTimesUs.indexOfKey(strm.mCurDiscontinuitySeq) >= 0) { 286309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t durUs; // approximate sample duration 287309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs > strm.mLastDequeuedTimeUs) { 288309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih durUs = timeUs - strm.mLastDequeuedTimeUs; 289309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 290309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih durUs = strm.mLastDequeuedTimeUs - timeUs; 291309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 292309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih strm.mLastSampleDurationUs = durUs; 293309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = mDiscontinuityAbsStartTimesUs.valueFor(strm.mCurDiscontinuitySeq); 294309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else if ((*accessUnit)->meta()->findInt32("discard", &discard) && discard) { 295309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = timeUs; 296309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 297309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mDiscontinuityAbsStartTimesUs.add(strm.mCurDiscontinuitySeq, timeUs); 298309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih firstTimeUs = timeUs; 299309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 300309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 301309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih strm.mLastDequeuedTimeUs = timeUs; 302309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs >= firstTimeUs) { 303309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs -= firstTimeUs; 304309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 305309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs = 0; 306309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 307309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs += mLastSeekTimeUs; 308309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mDiscontinuityOffsetTimesUs.indexOfKey(discontinuitySeq) >= 0) { 309309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih timeUs += mDiscontinuityOffsetTimesUs.valueFor(discontinuitySeq); 310309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 311dcb89b3b505522efde173c105a851c412f947178Chong Zhang 312309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGV("[%s] read buffer at time %" PRId64 " us", streamStr, timeUs); 313309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih (*accessUnit)->meta()->setInt64("timeUs", timeUs); 314dcb89b3b505522efde173c105a851c412f947178Chong Zhang mLastDequeuedTimeUs = timeUs; 315dcb89b3b505522efde173c105a851c412f947178Chong Zhang mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 316dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else if (stream == STREAMTYPE_SUBTITLES) { 317b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih int32_t subtitleGeneration; 318b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if ((*accessUnit)->meta()->findInt32("subtitleGeneration", &subtitleGeneration) 319b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih && subtitleGeneration != mSubtitleGeneration) { 320b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return -EAGAIN; 321b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih }; 322dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt32( 323dcb89b3b505522efde173c105a851c412f947178Chong Zhang "trackIndex", mPlaylist->getSelectedIndex()); 324dcb89b3b505522efde173c105a851c412f947178Chong Zhang (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs); 325dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 32614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 32714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGI("[%s] encountered error %d", streamStr, err); 32814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 32914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 33114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 33214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) { 3341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // No swapPacketSource race condition; called from the same thread as dequeueAccessUnit. 33514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!(mStreamMask & stream)) { 33614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return UNKNOWN_ERROR; 33714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 33814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 33914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream); 34014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MetaData> meta = packetSource->getFormat(); 34214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (meta == NULL) { 34414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return -EAGAIN; 34514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 34614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 34714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return convertMetaDataToMessage(meta, format); 348a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 349a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 35014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::connectAsync( 351ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 352a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatConnect, id()); 353a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setString("url", url); 354ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 355ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (headers != NULL) { 356ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber msg->setPointer( 357ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber "headers", 358ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber new KeyedVector<String8, String8>(*headers)); 359ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 360ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 361a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(); 362a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 363a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 36414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::disconnect() { 36514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatDisconnect, id()); 366ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 36714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 36814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 369ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 37014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 371a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 372a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 37314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::seekTo(int64_t timeUs) { 374a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatSeek, id()); 375a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setInt64("timeUs", timeUs); 376a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 37714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response; 37814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 37914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 38014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return err; 381a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 382a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 383a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMessageReceived(const sp<AMessage> &msg) { 384a44153c1a57202fb538659eb50706e60454d6273Andreas Huber switch (msg->what()) { 385a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatConnect: 38614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 387a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onConnect(msg); 388a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 38914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 390a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 391a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatDisconnect: 39214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 39314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->senderAwaitsResponse(&mDisconnectReplyID)); 39414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mReconfigurationInProgress) { 39614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 39714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 39814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 39914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 400a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 40114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 402a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 40314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatSeek: 40414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 405800599cdd50737de1cde483a34b39923750b0658Robert Shih uint32_t seekReplyID; 406800599cdd50737de1cde483a34b39923750b0658Robert Shih CHECK(msg->senderAwaitsResponse(&seekReplyID)); 407800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = seekReplyID; 408800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply = new AMessage; 40914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 41014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err = onSeek(msg); 41114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 412800599cdd50737de1cde483a34b39923750b0658Robert Shih if (err != OK) { 413800599cdd50737de1cde483a34b39923750b0658Robert Shih msg->post(50000); 414800599cdd50737de1cde483a34b39923750b0658Robert Shih } 41514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 41614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 41714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 41814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFetcherNotify: 41914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 42014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t what; 42114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("what", &what)); 42214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 42314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber switch (what) { 42414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStarted: 42514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 42614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatPaused: 42714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatStopped: 42814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 42914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (what == PlaylistFetcher::kWhatStopped) { 43014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 43114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 4321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.removeItem(uri) < 0) { 4331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // ignore duplicated kWhatStopped messages. 4341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 4351543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 4361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 437309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mSwitchInProgress) { 438309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih tryToFinishBandwidthSwitch(); 439309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 44014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 44114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 44214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuation != NULL) { 44314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GT(mContinuationCounter, 0); 44414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (--mContinuationCounter == 0) { 44514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation->post(); 4465ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 4475ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 4485ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 449800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply->setInt32("err", OK); 4505ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 451800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = 0; 452800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply.clear(); 4535ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 45414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 45514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 45614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 45714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 45814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 45914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatDurationUpdate: 46014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 46114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 46214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 46314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 46414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 46514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("durationUs", &durationUs)); 46614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 46714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 46814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mDurationUs = durationUs; 46914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 47014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 47114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 47214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatError: 47314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 47414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber status_t err; 47514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("err", &err)); 47614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 47714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGE("XXX Received error %d from PlaylistFetcher.", err); 47814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 47915f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih // handle EOS on subtitle tracks independently 48015f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih AString uri; 48115f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (err == ERROR_END_OF_STREAM && msg->findString("uri", &uri)) { 48215f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih ssize_t i = mFetcherInfos.indexOfKey(uri); 48315f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (i >= 0) { 48415f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih const sp<PlaylistFetcher> &fetcher = mFetcherInfos.valueAt(i).mFetcher; 48515f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (fetcher != NULL) { 48615f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih uint32_t type = fetcher->getStreamTypeMask(); 48715f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih if (type == STREAMTYPE_SUBTITLES) { 48815f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih mPacketSources.valueFor( 48915f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih STREAMTYPE_SUBTITLES)->signalEOS(err);; 49015f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih break; 49115f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 49215f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 49315f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 49415f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih } 49515f8ecfa23b650b3efa8fe841d2be6bd0c9523fbRobert Shih 49614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 49714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(err); 49814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 49914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5001543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 5011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 50214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(err); 50314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 50414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(err); 50514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 50614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 50714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(err); 50814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 50914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 51014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatError); 51114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 51214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 51314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 51414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 51514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 51614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case PlaylistFetcher::kWhatTemporarilyDoneFetching: 51714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 51814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 51914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findString("uri", &uri)); 52014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5216300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen if (mFetcherInfos.indexOfKey(uri) < 0) { 5226300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen ALOGE("couldn't find uri"); 5236300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen break; 5246300cbe99899da0103c910ba6a35c785261ce433Marco Nelissen } 52514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo *info = &mFetcherInfos.editValueFor(uri); 52614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info->mIsPrepared = true; 52714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 52814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mInPreparationPhase) { 52914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool allFetchersPrepared = true; 53014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 53114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mFetcherInfos.valueAt(i).mIsPrepared) { 53214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber allFetchersPrepared = false; 53314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 53414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 53514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 53614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 53714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (allFetchersPrepared) { 53814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(OK); 53914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 54014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 54114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 54214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 54314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case PlaylistFetcher::kWhatStartedAt: 5451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 5461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 5471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 5481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 5491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 5501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 5511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 5531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Resume fetcher for the original variant; the resumed fetcher should 5541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // continue until the timestamps found in msg, which is stored by the 5551543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // new fetcher to indicate where the new variant has started buffering. 5561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); i++) { 5571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih const FetcherInfo info = mFetcherInfos.valueAt(i); 5581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (info.mToBeRemoved) { 5591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->resumeUntilAsync(msg); 5601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5611543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5621543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 5631543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 5641543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 56514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 56614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber TRESPASS(); 56714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 56814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 56914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 57014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 57114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 57214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatCheckBandwidth: 573a44153c1a57202fb538659eb50706e60454d6273Andreas Huber { 574a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t generation; 575a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findInt32("generation", &generation)); 576a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 57714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (generation != mCheckBandwidthGeneration) { 578a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 579a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 580a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 58100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih onCheckBandwidth(msg); 582a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 583a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 584a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 585dcb89b3b505522efde173c105a851c412f947178Chong Zhang case kWhatChangeConfiguration: 586dcb89b3b505522efde173c105a851c412f947178Chong Zhang { 587dcb89b3b505522efde173c105a851c412f947178Chong Zhang onChangeConfiguration(msg); 588dcb89b3b505522efde173c105a851c412f947178Chong Zhang break; 589dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 590dcb89b3b505522efde173c105a851c412f947178Chong Zhang 59114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration2: 59214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 59314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration2(msg); 59414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 59514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 59614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 59714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatChangeConfiguration3: 59814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 59914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 60014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 60114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 60214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 60314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber case kWhatFinishDisconnect2: 60414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber { 60514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onFinishDisconnect2(); 606a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 60714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 608a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih case kWhatSwapped: 6101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih { 6111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih onSwapped(msg); 6121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 6131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 6140ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 6150ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih case kWhatCheckSwitchDown: 6160ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih { 6170ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih onCheckSwitchDown(); 6180ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 6190ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 6200ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 6210ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih case kWhatSwitchDown: 6220ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih { 6230ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih onSwitchDown(); 6240ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 6250ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 6260ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 627a44153c1a57202fb538659eb50706e60454d6273Andreas Huber default: 628a44153c1a57202fb538659eb50706e60454d6273Andreas Huber TRESPASS(); 629a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 630a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 631a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 632a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 633a44153c1a57202fb538659eb50706e60454d6273Andreas Huber// static 634a44153c1a57202fb538659eb50706e60454d6273Andreas Huberint LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b) { 635a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (a->mBandwidth < b->mBandwidth) { 636a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return -1; 637a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (a->mBandwidth == b->mBandwidth) { 638a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 639a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 640a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 641a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 1; 642a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 643a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6448ca002eedc747dd854b61cbe364b52c06869273fRobert Shih// static 6458ca002eedc747dd854b61cbe364b52c06869273fRobert ShihLiveSession::StreamType LiveSession::indexToType(int idx) { 6468ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(idx >= 0 && idx < kMaxStreams); 6478ca002eedc747dd854b61cbe364b52c06869273fRobert Shih return (StreamType)(1 << idx); 6488ca002eedc747dd854b61cbe364b52c06869273fRobert Shih} 6498ca002eedc747dd854b61cbe364b52c06869273fRobert Shih 650f69c996864844e8f669308af8412cede043062a2Robert Shih// static 651f69c996864844e8f669308af8412cede043062a2Robert Shihssize_t LiveSession::typeToIndex(int32_t type) { 652f69c996864844e8f669308af8412cede043062a2Robert Shih switch (type) { 653f69c996864844e8f669308af8412cede043062a2Robert Shih case STREAMTYPE_AUDIO: 654f69c996864844e8f669308af8412cede043062a2Robert Shih return 0; 655f69c996864844e8f669308af8412cede043062a2Robert Shih case STREAMTYPE_VIDEO: 656f69c996864844e8f669308af8412cede043062a2Robert Shih return 1; 657f69c996864844e8f669308af8412cede043062a2Robert Shih case STREAMTYPE_SUBTITLES: 658f69c996864844e8f669308af8412cede043062a2Robert Shih return 2; 659f69c996864844e8f669308af8412cede043062a2Robert Shih default: 660f69c996864844e8f669308af8412cede043062a2Robert Shih return -1; 661f69c996864844e8f669308af8412cede043062a2Robert Shih }; 662f69c996864844e8f669308af8412cede043062a2Robert Shih return -1; 663f69c996864844e8f669308af8412cede043062a2Robert Shih} 664f69c996864844e8f669308af8412cede043062a2Robert Shih 665a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onConnect(const sp<AMessage> &msg) { 666a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString url; 667a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findString("url", &url)); 668a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 669ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber KeyedVector<String8, String8> *headers = NULL; 670ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (!msg->findPointer("headers", (void **)&headers)) { 671ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders.clear(); 672ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } else { 673ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders = *headers; 674ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 675ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber delete headers; 676ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber headers = NULL; 677ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 678ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 679a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // TODO currently we don't know if we are coming here from incognito mode 680a1df816c0677185534babba6ffc29970b048e52eLajos Molnar ALOGI("onConnect %s", uriDebugString(url).c_str()); 681a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 682a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mMasterURL = url; 683a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6847e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber bool dummy; 68514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist = fetchPlaylist(url.c_str(), NULL /* curPlaylistHash */, &dummy); 686ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 68714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist == NULL) { 688a1df816c0677185534babba6ffc29970b048e52eLajos Molnar ALOGE("unable to fetch master playlist %s.", uriDebugString(url).c_str()); 689ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 69014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber postPrepared(ERROR_IO); 691ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber return; 692ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 693a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 69414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // We trust the content provider to make a reasonable choice of preferred 69514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // initial bandwidth by listing it first in the variant playlist. 69614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // At startup we really don't have a good estimate on the available 69714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // network bandwidth since we haven't tranferred any data yet. Once 69814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we have we can make a better informed choice. 69914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidth = 0; 70014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t initialBandwidthIndex = 0; 70114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 70214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mPlaylist->isVariantPlaylist()) { 70314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mPlaylist->size(); ++i) { 704a44153c1a57202fb538659eb50706e60454d6273Andreas Huber BandwidthItem item; 705a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 70614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = i; 70714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 708a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> meta; 70914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 71014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPlaylist->itemAt(i, &uri, &meta); 711a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 712a44153c1a57202fb538659eb50706e60454d6273Andreas Huber unsigned long bandwidth; 713a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth)); 714a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 71514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (initialBandwidth == 0) { 71614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidth = item.mBandwidth; 71714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 71814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 719a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.push(item); 720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 721a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 722a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(mBandwidthItems.size(), 0u); 723a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 724a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.sort(SortByBandwidth); 72514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 72614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mBandwidthItems.size(); ++i) { 72714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mBandwidthItems.itemAt(i).mBandwidth == initialBandwidth) { 72814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber initialBandwidthIndex = i; 72914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber break; 73014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 73114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 73214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 73314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // dummy item. 73414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber BandwidthItem item; 73514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mPlaylistIndex = 0; 73614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber item.mBandwidth = 0; 73714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mBandwidthItems.push(item); 738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 739a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 740309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mPlaylist->pickRandomMediaItems(); 741dcb89b3b505522efde173c105a851c412f947178Chong Zhang changeConfiguration( 742309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 0ll /* timeUs */, initialBandwidthIndex, false /* pickTrack */); 743a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 744a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 74514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::finishDisconnect() { 74614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // No reconfiguration is currently pending, make sure none will trigger 74714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // during disconnection either. 74814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber cancelCheckBandwidthEvent(); 74914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 7501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through disconnect. 7511543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (finishDisconnect, onFinishDisconnect2) 7521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 7531543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 7540ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih // cancel switch down monitor 7550ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor.clear(); 7560ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 75714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 75814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 75914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 76014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 76114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id()); 762a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 76314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 76414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 765ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 76614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 76714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 76814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 76914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 77014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 77114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onFinishDisconnect2() { 77214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 77314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 77414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(ERROR_END_OF_STREAM); 77514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(ERROR_END_OF_STREAM); 77614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 77714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mPacketSources.valueFor( 77814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber STREAMTYPE_SUBTITLES)->signalEOS(ERROR_END_OF_STREAM); 77914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> response = new AMessage; 78114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->setInt32("err", OK); 78214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber response->postReply(mDisconnectReplyID); 78414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mDisconnectReplyID = 0; 78514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 78614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 78714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { 78814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ssize_t index = mFetcherInfos.indexOfKey(uri); 78914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 79014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0) { 79114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return NULL; 79214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 79314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 79414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id()); 79514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setString("uri", uri); 7961543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih notify->setInt32("switchGeneration", mSwitchGeneration); 79714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 79814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber FetcherInfo info; 799b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih info.mFetcher = new PlaylistFetcher(notify, this, uri, mSubtitleGeneration); 80014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mDurationUs = -1ll; 80114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber info.mIsPrepared = false; 8021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = false; 80314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber looper()->registerHandler(info.mFetcher); 80414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 80514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.add(uri, info); 80614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 80714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return info.mFetcher; 808a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 809a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8108dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih/* 8118dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Illustration of parameters: 8128dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 8138dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 0 `range_offset` 8148dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * +------------+-------------------------------------------------------+--+--+ 8158dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | | next block to fetch | | | 8168dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | | `source` handle => `out` buffer | | | | 8178dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | 8188dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * | |<----------- `range_length` / buffer capacity ----------->| | 8198dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * |<------------------------------ file_size ------------------------------->| 8208dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 8218dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * Special parameter values: 8228dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - range_length == -1 means entire file 8238dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * - block_size == 0 means entire range 8248dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih * 8258dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih */ 82643ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shihssize_t LiveSession::fetchFile( 8272aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber const char *url, sp<ABuffer> *out, 8288dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih int64_t range_offset, int64_t range_length, 8298dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih uint32_t block_size, /* download block size */ 83097194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen sp<DataSource> *source, /* to return and reuse source */ 831784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 *actualUrl) { 8328dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih off64_t size; 8338dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<DataSource> temp_source; 8348dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (source == NULL) { 8358dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih source = &temp_source; 8368dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 837a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8388dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*source == NULL) { 8398dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (!strncasecmp(url, "file://", 7)) { 8408dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = new FileSource(url + 7); 8418dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else if (strncasecmp(url, "http://", 7) 8428dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih && strncasecmp(url, "https://", 8)) { 8438dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return ERROR_UNSUPPORTED; 8448dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } else { 8458dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih KeyedVector<String8, String8> headers = mExtraHeaders; 8468dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (range_offset > 0 || range_length >= 0) { 8478dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih headers.add( 8488dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8("Range"), 8498dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih String8( 8508dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih StringPrintf( 8518dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih "bytes=%lld-%s", 8528dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset, 8538dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length < 0 8548dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ? "" : StringPrintf("%lld", 8558dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_offset + range_length - 1).c_str()).c_str())); 8568dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 8578dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t err = mHTTPDataSource->connect(url, &headers); 858a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8598dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (err != OK) { 8608dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih return err; 8618dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 862a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8638dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih *source = mHTTPDataSource; 864a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 865a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 866a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8678dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih status_t getSizeErr = (*source)->getSize(&size); 8688dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (getSizeErr != OK) { 869a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size = 65536; 870a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 871a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 8728dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); 8738dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (*out == NULL) { 8748dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih buffer->setRange(0, 0); 8758dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 876a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 87743ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t bytesRead = 0; 8788dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // adjust range_length if only reading partial block 879b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (block_size > 0 && (range_length == -1 || (int64_t)(buffer->size() + block_size) < range_length)) { 8808dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih range_length = buffer->size() + block_size; 8818dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih } 882a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (;;) { 8838dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // Only resize when we don't know the size. 884a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bufferRemaining = buffer->capacity() - buffer->size(); 8858dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih if (bufferRemaining == 0 && getSizeErr != OK) { 8869aff25fb41f516ac26f9d1983a25402909f1e77aLeena Winterrowd size_t bufferIncrement = buffer->size() / 2; 8879aff25fb41f516ac26f9d1983a25402909f1e77aLeena Winterrowd if (bufferIncrement < 32768) { 8889aff25fb41f516ac26f9d1983a25402909f1e77aLeena Winterrowd bufferIncrement = 32768; 8899aff25fb41f516ac26f9d1983a25402909f1e77aLeena Winterrowd } 8909aff25fb41f516ac26f9d1983a25402909f1e77aLeena Winterrowd bufferRemaining = bufferIncrement; 891a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 892b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("increasing download buffer to %zu bytes", 893a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size() + bufferRemaining); 894a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 895a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining); 896a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memcpy(copy->data(), buffer->data(), buffer->size()); 897a44153c1a57202fb538659eb50706e60454d6273Andreas Huber copy->setRange(0, buffer->size()); 898a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 899a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer = copy; 900a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 901a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9022aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber size_t maxBytesToRead = bufferRemaining; 9032aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (range_length >= 0) { 9042aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber int64_t bytesLeftInRange = range_length - buffer->size(); 905b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross if (bytesLeftInRange < (int64_t)maxBytesToRead) { 9062aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead = bytesLeftInRange; 9072aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 9082aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber if (bytesLeftInRange == 0) { 9092aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber break; 9102aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 9112aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 9122aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber } 9132aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber 9148dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) 9158dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih // to help us break out of the loop. 9168dd1c202aea703ed8beacaaa0dad5ae9c76a0863Robert Shih ssize_t n = (*source)->readAt( 917a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size(), buffer->data() + buffer->size(), 9182aa4cc04154d82f6658fb86f394f13bb488b0468Andreas Huber maxBytesToRead); 919a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 920a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n < 0) { 92120ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber return n; 922a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 923a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 924a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n == 0) { 925a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 926a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 927a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 928a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, buffer->size() + (size_t)n); 92943ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih bytesRead += n; 930a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 931a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 932a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = buffer; 933784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl != NULL) { 93497194cdf8d67f362ef8c6dfdf607298c7e102b3bMarco Nelissen *actualUrl = (*source)->getUri(); 935784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo if (actualUrl->isEmpty()) { 936784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo *actualUrl = url; 937784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 938784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo } 939a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 94043ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih return bytesRead; 941a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 942a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 94314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist( 94414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *url, uint8_t *curPlaylistHash, bool *unchanged) { 945b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ALOGV("fetchPlaylist '%s'", url); 946b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 9477e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = false; 9487e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 949a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 950784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo String8 actualUrl; 95143ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih ssize_t err = fetchFile(url, &buffer, 0, -1, 0, NULL, &actualUrl); 952a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 95343ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih if (err <= 0) { 954a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 955a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 956a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 9577e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // MD5 functionality is not available on the simulator, treat all 9587e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlists as changed. 9597e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9607e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#if defined(HAVE_ANDROID_OS) 9617e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber uint8_t hash[16]; 9627e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9637e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_CTX m; 9647e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Init(&m); 9657e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Update(&m, buffer->data(), buffer->size()); 9667e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9677e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber MD5_Final(hash, &m); 9687e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 96914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL && !memcmp(hash, curPlaylistHash, 16)) { 9707e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber // playlist unchanged 9717e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber *unchanged = true; 9727e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 9737e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber return NULL; 9747e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 9757e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 97614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (curPlaylistHash != NULL) { 97714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber memcpy(curPlaylistHash, hash, sizeof(hash)); 97814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 9797e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber#endif 9807e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 981a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = 982784faaf1d76902be6b36d3af01fb5325f0d45a04Martin Storsjo new M3UParser(actualUrl.string(), buffer->data(), buffer->size()); 983a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 984a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->initCheck() != OK) { 98529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to parse .m3u8 playlist"); 9869067e30b3ccb3a07e41b61af22c036378053a9a3Andreas Huber 987a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 988a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 989a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 990a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return playlist; 991a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 992a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 993a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() { 994a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return (double)rand() / RAND_MAX; 995a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 996a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 997a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() { 998a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() == 0) { 999a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 1000a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1001a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1002a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1 1003a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char value[PROPERTY_VALUE_MAX]; 1004673158582c9589cee1d5e4d7c79622609938b8f8Andreas Huber ssize_t index = -1; 100514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 1006a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char *end; 100714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtol(value, &end, 10); 100814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 100914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 101014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= 0 && (size_t)index >= mBandwidthItems.size()) { 101114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 1012a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1013a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1014a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 101514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index < 0) { 101614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int32_t bandwidthBps; 101714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mHTTPDataSource != NULL 101814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) { 101914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); 102014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 102114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("no bandwidth estimate."); 102214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return 0; // Pick the lowest bandwidth stream by default. 102314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1024a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 102514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 102614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.max-bw", value, NULL)) { 102714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 102814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber long maxBw = strtoul(value, &end, 10); 102914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (end > value && *end == '\0') { 103014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (maxBw > 0 && bandwidthBps > maxBw) { 103114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("bandwidth capped to %ld bps", maxBw); 103214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bandwidthBps = maxBw; 103314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 103414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 103514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1036a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 103714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pick the highest bandwidth stream below or equal to estimated bandwidth. 103814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 103914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 104000598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih while (index > 0) { 104100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // consider only 80% of the available bandwidth, but if we are switching up, 104200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // be even more conservative (70%) to avoid overestimating and immediately 104300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // switching back. 104400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih size_t adjustedBandwidthBps = bandwidthBps; 104500598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih if (index > mCurBandwidthIndex) { 104600598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih adjustedBandwidthBps = adjustedBandwidthBps * 7 / 10; 104700598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } else { 104800598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih adjustedBandwidthBps = adjustedBandwidthBps * 8 / 10; 104900598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } 105000598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih if (mBandwidthItems.itemAt(index).mBandwidth <= adjustedBandwidthBps) { 105100598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih break; 105200598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih } 105314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber --index; 105414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1055a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1056a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1057a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Change bandwidth at random() 1058a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = uniformRand() * mBandwidthItems.size(); 1059a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1060a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // There's a 50% chance to stay on the current bandwidth and 1061a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // a 50% chance to switch to the next higher bandwidth (wrapping around 1062a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // to lowest) 1063a44153c1a57202fb538659eb50706e60454d6273Andreas Huber const size_t kMinIndex = 0; 1064a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1065309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih static ssize_t mCurBandwidthIndex = -1; 106614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1067a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index; 1068309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mCurBandwidthIndex < 0) { 1069a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 1070a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (uniformRand() < 0.5) { 1071309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih index = (size_t)mCurBandwidthIndex; 1072a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 1073309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih index = mCurBandwidthIndex + 1; 1074a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index == mBandwidthItems.size()) { 1075a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 1076a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1077a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1078309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex = index; 1079a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 1080a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec 1081a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1082a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 1083a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) { 1084a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 1085a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 108614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#elif 1 108714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char value[PROPERTY_VALUE_MAX]; 108814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t index; 108914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (property_get("media.httplive.bw-index", value, NULL)) { 109014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber char *end; 109114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = strtoul(value, &end, 10); 109214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(end > value && *end == '\0'); 109314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 109414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (index >= mBandwidthItems.size()) { 109514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = mBandwidthItems.size() - 1; 109614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 109714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 109814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber index = 0; 109914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1100a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else 1101a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream 1102a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif 1103a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 110414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_GE(index, 0); 110514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1106a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return index; 1107a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1108a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1109b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shihint64_t LiveSession::latestMediaSegmentStartTimeUs() { 1110b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih sp<AMessage> audioMeta = mPacketSources.valueFor(STREAMTYPE_AUDIO)->getLatestDequeuedMeta(); 1111b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih int64_t minSegmentStartTimeUs = -1, videoSegmentStartTimeUs = -1; 1112b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (audioMeta != NULL) { 1113b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih audioMeta->findInt64("segmentStartTimeUs", &minSegmentStartTimeUs); 1114b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1115b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1116b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih sp<AMessage> videoMeta = mPacketSources.valueFor(STREAMTYPE_VIDEO)->getLatestDequeuedMeta(); 1117b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (videoMeta != NULL 1118b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih && videoMeta->findInt64("segmentStartTimeUs", &videoSegmentStartTimeUs)) { 1119b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (minSegmentStartTimeUs < 0 || videoSegmentStartTimeUs < minSegmentStartTimeUs) { 1120b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih minSegmentStartTimeUs = videoSegmentStartTimeUs; 1121b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1122b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1123b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1124b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return minSegmentStartTimeUs; 1125b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih} 1126b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 112714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::onSeek(const sp<AMessage> &msg) { 112814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 112914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 11307e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 113114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mReconfigurationInProgress) { 1132800599cdd50737de1cde483a34b39923750b0658Robert Shih changeConfiguration(timeUs, mCurBandwidthIndex); 1133800599cdd50737de1cde483a34b39923750b0658Robert Shih return OK; 1134800599cdd50737de1cde483a34b39923750b0658Robert Shih } else { 1135800599cdd50737de1cde483a34b39923750b0658Robert Shih return -EWOULDBLOCK; 11367e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber } 11377e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber} 11387e43a5a2dcfa9bc64ef477472a33c87a84695c09Andreas Huber 113914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) const { 1140895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia int64_t maxDurationUs = -1ll; 114114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 114214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs; 1143b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1144895651b07fec30b0f9b0d2499599a179d95c9be4Wei Jia if (fetcherDurationUs > maxDurationUs) { 114514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber maxDurationUs = fetcherDurationUs; 1146a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1147a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1148a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 114914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *durationUs = maxDurationUs; 1150a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 115114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 115214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11530f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 115414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::isSeekable() const { 115514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t durationUs; 115614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return getDuration(&durationUs) == OK && durationUs >= 0; 115714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11580f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 115914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberbool LiveSession::hasDynamicDuration() const { 116014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return false; 116114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 11620f30bd90272c818aa37c0bb22d22eaa7d3689879Andreas Huber 1163404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangsize_t LiveSession::getTrackCount() const { 11649d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih if (mPlaylist == NULL) { 11659d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return 0; 11669d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } else { 11679d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return mPlaylist->getTrackCount(); 11689d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } 1169404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang} 1170404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhang 1171404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangsp<AMessage> LiveSession::getTrackInfo(size_t trackIndex) const { 11729d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih if (mPlaylist == NULL) { 11739d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return NULL; 11749d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } else { 11759d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih return mPlaylist->getTrackInfo(trackIndex); 11769d7fc5c5fab0c7c967a625d22fffda046f9d5c29Robert Shih } 1177dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1178dcb89b3b505522efde173c105a851c412f947178Chong Zhang 1179dcb89b3b505522efde173c105a851c412f947178Chong Zhangstatus_t LiveSession::selectTrack(size_t index, bool select) { 1180b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (mPlaylist == NULL) { 1181b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih return INVALID_OPERATION; 1182b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1183b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 1184b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih ++mSubtitleGeneration; 1185dcb89b3b505522efde173c105a851c412f947178Chong Zhang status_t err = mPlaylist->selectTrack(index, select); 1186dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (err == OK) { 1187309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> msg = new AMessage(kWhatChangeConfiguration, id()); 1188309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("bandwidthIndex", mCurBandwidthIndex); 1189309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("pickTrack", select); 1190309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->post(); 1191dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1192dcb89b3b505522efde173c105a851c412f947178Chong Zhang return err; 1193dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1194dcb89b3b505522efde173c105a851c412f947178Chong Zhang 119589bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shihssize_t LiveSession::getSelectedTrack(media_track_type type) const { 119689bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih if (mPlaylist == NULL) { 119789bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih return -1; 119889bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih } else { 119989bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih return mPlaylist->getSelectedTrack(type); 120089bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih } 120189bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih} 120289bf2525c5b57f17260de5b00c5f3f78ac4b881eRobert Shih 12031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchUp() { 12041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds. 12051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih status_t err = OK; 12061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mPacketSources.size(); ++i) { 12071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AnotherPacketSource> source = mPacketSources.valueAt(i); 12081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int64_t dur = source->getBufferedDurationUs(&err); 12091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (err == OK && dur > 10000000) { 12101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 12111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12121543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 12131543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 12141543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 12151543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1216dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::changeConfiguration( 1217dcb89b3b505522efde173c105a851c412f947178Chong Zhang int64_t timeUs, size_t bandwidthIndex, bool pickTrack) { 12181543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Protect mPacketSources from a swapPacketSource race condition through reconfiguration. 12191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // (changeConfiguration, onChangeConfiguration2, onChangeConfiguration3). 12201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih cancelBandwidthSwitch(); 12211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 122214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(!mReconfigurationInProgress); 122314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = true; 1224a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1225309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mCurBandwidthIndex = bandwidthIndex; 122643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1227b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("changeConfiguration => timeUs:%" PRId64 " us, bwIndex:%zu, pickTrack:%d", 1228dcb89b3b505522efde173c105a851c412f947178Chong Zhang timeUs, bandwidthIndex, pickTrack); 122943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 123014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK_LT(bandwidthIndex, mBandwidthItems.size()); 123114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex); 1232a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask = 0; // streams that should be fetched by the new fetcher 12341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t resumeMask = 0; // streams that should be fetched by the original fetcher 1235a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12368ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 12378ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 12388ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) { 12398ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask |= indexToType(i); 12408ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 124114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1242aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 124314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Step 1, stop and discard fetchers that are no longer needed. 124414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Pause those that we'll reuse. 124514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 124614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 1247aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 124814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber bool discardFetcher = true; 1249aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 125014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If we're seeking all current fetchers are discarded. 125114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 1252309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // delay fetcher removal if not picking tracks 1253309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discardFetcher = pickTrack; 12541543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 12558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 12561543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType type = indexToType(j); 12571543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((streamMask & type) && uri == URIs[j]) { 12581543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih resumeMask |= type; 12591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih streamMask &= ~type; 1260309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discardFetcher = false; 12618ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 12626801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 126314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1264a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 126514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (discardFetcher) { 126614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->stopAsync(); 12676801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } else { 126814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFetcherInfos.valueAt(i).mFetcher->pauseAsync(); 12696801b4dbd00b485ecdcd31b517ed885a8fa21c63Andreas Huber } 1270a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1271a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 12721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sp<AMessage> msg; 12731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (timeUs < 0ll) { 1274309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // skip onChangeConfiguration2 (decoder destruction) if not seeking. 12751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration3, id()); 12761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 12771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg = new AMessage(kWhatChangeConfiguration2, id()); 12781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 127914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("streamMask", streamMask); 12801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih msg->setInt32("resumeMask", resumeMask); 1281309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->setInt32("pickTrack", pickTrack); 128214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt64("timeUs", timeUs); 12838ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1284309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if ((streamMask | resumeMask) & indexToType(i)) { 12858ca002eedc747dd854b61cbe364b52c06869273fRobert Shih msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str()); 12868ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 12876e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 1288a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 128914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Every time a fetcher acknowledges the stopAsync or pauseAsync request 129014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // we'll decrement mContinuationCounter, once it reaches zero, i.e. all 129114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // fetchers have completed their asynchronous operation, we'll post 129214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // mContinuation, which then is handled below in onChangeConfiguration2. 129314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuationCounter = mFetcherInfos.size(); 129414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation = msg; 129588b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 129614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mContinuationCounter == 0) { 129714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(); 12985ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih 12995ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih if (mSeekReplyID != 0) { 13005ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih CHECK(mSeekReply != NULL); 1301800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply->setInt32("err", OK); 13025ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih mSeekReply->postReply(mSeekReplyID); 1303800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReplyID = 0; 1304800599cdd50737de1cde483a34b39923750b0658Robert Shih mSeekReply.clear(); 13055ce50c1931e1e3d8f113394bbe2c9f99354f4c5fRobert Shih } 130688b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber } 130714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1308a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1309dcb89b3b505522efde173c105a851c412f947178Chong Zhangvoid LiveSession::onChangeConfiguration(const sp<AMessage> &msg) { 1310dcb89b3b505522efde173c105a851c412f947178Chong Zhang if (!mReconfigurationInProgress) { 1311309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t pickTrack = 0, bandwidthIndex = mCurBandwidthIndex; 1312309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->findInt32("pickTrack", &pickTrack); 1313309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih msg->findInt32("bandwidthIndex", &bandwidthIndex); 1314309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih changeConfiguration(-1ll /* timeUs */, bandwidthIndex, pickTrack); 1315dcb89b3b505522efde173c105a851c412f947178Chong Zhang } else { 1316dcb89b3b505522efde173c105a851c412f947178Chong Zhang msg->post(1000000ll); // retry in 1 sec 1317dcb89b3b505522efde173c105a851c412f947178Chong Zhang } 1318dcb89b3b505522efde173c105a851c412f947178Chong Zhang} 1319dcb89b3b505522efde173c105a851c412f947178Chong Zhang 132014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { 132114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mContinuation.clear(); 1322bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 132314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers are either suspended or have been removed now. 1324bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 1325309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih uint32_t streamMask, resumeMask; 132614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 1327309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1328309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1329309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // currently onChangeConfiguration2 is only called for seeking; 1330309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // remove the following CHECK if using it else where. 1331309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK_EQ(resumeMask, 0); 1332309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih streamMask |= resumeMask; 1333bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 13348ca002eedc747dd854b61cbe364b52c06869273fRobert Shih AString URIs[kMaxStreams]; 13358ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 13368ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (streamMask & indexToType(i)) { 13378ca002eedc747dd854b61cbe364b52c06869273fRobert Shih const AString &uriKey = mStreams[i].uriKey(); 13388ca002eedc747dd854b61cbe364b52c06869273fRobert Shih CHECK(msg->findString(uriKey.c_str(), &URIs[i])); 13398ca002eedc747dd854b61cbe364b52c06869273fRobert Shih ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str()); 13408ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 134122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 13423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 134314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Determine which decoders to shutdown on the player side, 134414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // a decoder has to be shutdown if either 134514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 1) its streamtype was active before but now longer isn't. 134614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // or 134714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // 2) its streamtype was already active and still is but the URI 134814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has changed. 134914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber uint32_t changedMask = 0; 13508ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) { 13518ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (((mStreamMask & streamMask & indexToType(i)) 13528ca002eedc747dd854b61cbe364b52c06869273fRobert Shih && !(URIs[i] == mStreams[i].mUri)) 13538ca002eedc747dd854b61cbe364b52c06869273fRobert Shih || (mStreamMask & ~streamMask & indexToType(i))) { 13548ca002eedc747dd854b61cbe364b52c06869273fRobert Shih changedMask |= indexToType(i); 13558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1356b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } 1357b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 135814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (changedMask == 0) { 135914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // If nothing changed as far as the audio/video decoders 136014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // are concerned we can proceed. 136114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber onChangeConfiguration3(msg); 136214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return; 136314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 136443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 136514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Something changed, inform the player which will shutdown the 136614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // corresponding decoders and will post the reply once that's done. 136714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // Handling the reply will continue executing below in 136814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // onChangeConfiguration3. 136914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 137014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatStreamsChanged); 137114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("changedMask", changedMask); 137220f725ebcef13ded1b4b85c61c8a4b37cd030656Andreas Huber 137314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setWhat(kWhatChangeConfiguration3); 137414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setTarget(id()); 1375b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 137614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setMessage("reply", msg); 137714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 137814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1379b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 138014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { 13811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mContinuation.clear(); 138214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All remaining fetchers are still suspended, the player has shutdown 138314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // any decoders that needed it. 1384b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 13851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t streamMask, resumeMask; 138614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask)); 13871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask)); 1388a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 138914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber int64_t timeUs; 1390309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t pickTrack; 13911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool switching = false; 139214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 1393309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(msg->findInt32("pickTrack", &pickTrack)); 1394a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 139514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (timeUs < 0ll) { 1396309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!pickTrack) { 1397309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih switching = true; 1398309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1399309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mRealTimeBaseUs = ALooper::GetNowUs() - mLastDequeuedTimeUs; 1400309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1401309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mRealTimeBaseUs = ALooper::GetNowUs() - timeUs; 140214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1403a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1404f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1405f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (streamMask & indexToType(i)) { 1406f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (switching) { 1407f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mNewUri)); 1408f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } else { 1409f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri)); 1410f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1411f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1412f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1413f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1414309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mNewStreamMask = streamMask | resumeMask; 1415f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (switching) { 1416f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mSwapMask = mStreamMask & ~resumeMask; 1417f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1418a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14191543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Of all existing fetchers: 14201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Resume fetchers that are still needed and assign them original packet sources. 14211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // * Mark otherwise unneeded fetchers for removal. 14221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih ALOGV("resuming fetchers for mask 0x%08x", resumeMask); 142314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 142414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const AString &uri = mFetcherInfos.keyAt(i); 14250df36ec3303c2c6bf9b42c07945ac8bd234153f3Andreas Huber 14268ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 1427dc793ce8c0ead27ab43e40ce09f27fe338323502Robert Shih for (size_t j = 0; j < kMaxStreams; ++j) { 14281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) { 14298ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 1430309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1431309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (j != kSubtitleIndex) { 1432309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGV("queueing dummy discontinuity for stream type %d", indexToType(j)); 1433309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1434309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1435309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1436309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_NONE, 1437309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih NULL, 1438309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih true); 1439309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 14408ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 144114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1442a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih FetcherInfo &info = mFetcherInfos.editValueAt(i); 14441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL 14451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih || sources[kSubtitleIndex] != NULL) { 14461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mFetcher->startAsync( 14471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]); 14481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 14491543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih info.mToBeRemoved = true; 14501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1451a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1452a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 145314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // streamMask now only contains the types that need a new fetcher created. 1454a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 145514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (streamMask != 0) { 145614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("creating new fetchers for mask 0x%08x", streamMask); 1457a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1458a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14591543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Find out when the original fetchers have buffered up to and start the new fetchers 14601543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // at a later timestamp. 14618ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t i = 0; i < kMaxStreams; i++) { 14628ca002eedc747dd854b61cbe364b52c06869273fRobert Shih if (!(indexToType(i) & streamMask)) { 14638ca002eedc747dd854b61cbe364b52c06869273fRobert Shih continue; 14648ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 14651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 146614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber AString uri; 1467f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih uri = switching ? mStreams[i].mNewUri : mStreams[i].mUri; 14689b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 146914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str()); 147014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(fetcher != NULL); 1471a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 14721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t latestSeq = -1; 1473309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t startTimeUs = -1; 1474309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t segmentStartTimeUs = -1ll; 1475309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t discontinuitySeq = -1; 14768ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sp<AnotherPacketSource> sources[kMaxStreams]; 14771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1478b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih if (i == kSubtitleIndex) { 1479b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih segmentStartTimeUs = latestMediaSegmentStartTimeUs(); 1480b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih } 1481b44ce2f84691559672cfaf6bb8fd3a9ac43904f2Robert Shih 14828ca002eedc747dd854b61cbe364b52c06869273fRobert Shih // TRICKY: looping from i as earlier streams are already removed from streamMask 14838ca002eedc747dd854b61cbe364b52c06869273fRobert Shih for (size_t j = i; j < kMaxStreams; ++j) { 1484f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih const AString &streamUri = switching ? mStreams[j].mNewUri : mStreams[j].mUri; 1485f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if ((streamMask & indexToType(j)) && uri == streamUri) { 14868ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[j] = mPacketSources.valueFor(indexToType(j)); 14871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1488309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (timeUs >= 0) { 14891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih sources[j]->clear(); 1490309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs = timeUs; 1491309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1492309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1493309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> extra = new AMessage; 1494309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih extra->setInt64("timeUs", timeUs); 1495309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1496309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1497fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia ATSParser::DISCONTINUITY_TIME, extra, true); 14981543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 1499309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t type; 1500309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t srcSegmentStartTimeUs; 1501309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AMessage> meta; 1502309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (pickTrack) { 1503309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // selecting 1504309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih meta = sources[j]->getLatestDequeuedMeta(); 1505309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1506309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adapting 1507309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih meta = sources[j]->getLatestEnqueuedMeta(); 1508309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 15091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (meta != NULL && !meta->findInt32("discontinuity", &type)) { 1511309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int64_t tmpUs; 1512309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt64("timeUs", &tmpUs)); 1513309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (startTimeUs < 0 || tmpUs < startTimeUs) { 1514309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs = tmpUs; 1515309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1516309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1517309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt64("segmentStartTimeUs", &tmpUs)); 1518309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (segmentStartTimeUs < 0 || tmpUs < segmentStartTimeUs) { 1519309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih segmentStartTimeUs = tmpUs; 15201543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1521309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1522309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih int32_t seq; 1523309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih CHECK(meta->findInt32("discontinuitySeq", &seq)); 1524309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (discontinuitySeq < 0 || seq < discontinuitySeq) { 1525309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuitySeq = seq; 15261543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15271543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1529309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (pickTrack) { 1530309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // selecting track, queue discontinuities before content 1531309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->clear(); 1532309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (j == kSubtitleIndex) { 1533309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih break; 1534309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1535309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sp<AnotherPacketSource> discontinuityQueue; 1536309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue = mDiscontinuities.valueFor(indexToType(j)); 1537309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuityQueue->queueDiscontinuity( 1538309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true); 1539309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else { 1540309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih // adapting, queue discontinuities after resume 1541309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j] = mPacketSources2.valueFor(indexToType(j)); 1542309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->clear(); 1543309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 1544309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (extraStreams & indexToType(j)) { 1545309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih sources[j]->queueAccessUnit(createFormatChangeBuffer(/*swap*/ false)); 1546309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 15471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15481543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1549a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 15508ca002eedc747dd854b61cbe364b52c06869273fRobert Shih streamMask &= ~indexToType(j); 15518ca002eedc747dd854b61cbe364b52c06869273fRobert Shih } 1552a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 155314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 15548ca002eedc747dd854b61cbe364b52c06869273fRobert Shih fetcher->startAsync( 15558ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kAudioIndex], 15568ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kVideoIndex], 15578ca002eedc747dd854b61cbe364b52c06869273fRobert Shih sources[kSubtitleIndex], 1558309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih startTimeUs < 0 ? mLastSeekTimeUs : startTimeUs, 1559309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih segmentStartTimeUs, 1560309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih discontinuitySeq, 1561309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih switching); 1562a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 1563a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 156414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // All fetchers have now been started, the configuration change 156514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber // has completed. 1566a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 156700598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih cancelCheckBandwidthEvent(); 156814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber scheduleCheckBandwidthEvent(); 1569a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 157014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ALOGV("XXX configuration change completed."); 157114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mReconfigurationInProgress = false; 15721543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switching) { 15731543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = true; 15741543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 15751543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 15761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1577a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 157814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (mDisconnectReplyID != 0) { 157914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber finishDisconnect(); 1580a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 158114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 1582a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 15831543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::onSwapped(const sp<AMessage> &msg) { 15841543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t switchGeneration; 15851543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("switchGeneration", &switchGeneration)); 15861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (switchGeneration != mSwitchGeneration) { 15871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 15881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 15891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 15901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih int32_t stream; 15911543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih CHECK(msg->findInt32("stream", &stream)); 1592f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1593f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ssize_t idx = typeToIndex(stream); 1594f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(idx >= 0); 1595f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if ((mNewStreamMask & stream) && mStreams[idx].mNewUri.empty()) { 1596f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ALOGW("swapping stream type %d %s to empty stream", stream, mStreams[idx].mUri.c_str()); 1597f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1598f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mUri = mStreams[idx].mNewUri; 1599f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mNewUri.clear(); 1600f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1601309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih mSwapMask &= ~stream; 1602309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mSwapMask != 0) { 16031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return; 16041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 16061543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih // Check if new variant contains extra streams. 16071543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih uint32_t extraStreams = mNewStreamMask & (~mStreamMask); 16081543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih while (extraStreams) { 16091543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih StreamType extraStream = (StreamType) (extraStreams & ~(extraStreams - 1)); 16101543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih swapPacketSource(extraStream); 16111543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih extraStreams &= ~extraStream; 1612f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1613f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih idx = typeToIndex(extraStream); 1614f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih CHECK(idx >= 0); 1615f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (mStreams[idx].mNewUri.empty()) { 1616f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ALOGW("swapping extra stream type %d %s to empty stream", 1617f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih extraStream, mStreams[idx].mUri.c_str()); 1618f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1619f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mUri = mStreams[idx].mNewUri; 1620f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[idx].mNewUri.clear(); 16211543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16221543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 16231543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih tryToFinishBandwidthSwitch(); 16241543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 16251543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 16260ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shihvoid LiveSession::onCheckSwitchDown() { 16270ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (mSwitchDownMonitor == NULL) { 16280ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16290ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16300ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 1631678bcdc852dd8f801f5c46fdc85db587b721d83dApurupa Pattapu if (mSwitchInProgress || mReconfigurationInProgress) { 1632678bcdc852dd8f801f5c46fdc85db587b721d83dApurupa Pattapu ALOGV("Switch/Reconfig in progress, defer switch down"); 1633678bcdc852dd8f801f5c46fdc85db587b721d83dApurupa Pattapu mSwitchDownMonitor->post(1000000ll); 1634678bcdc852dd8f801f5c46fdc85db587b721d83dApurupa Pattapu return; 1635678bcdc852dd8f801f5c46fdc85db587b721d83dApurupa Pattapu } 1636678bcdc852dd8f801f5c46fdc85db587b721d83dApurupa Pattapu 16370ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 16380ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int32_t targetDuration; 16390ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(indexToType(i)); 16400ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih sp<AMessage> meta = packetSource->getLatestDequeuedMeta(); 16410ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16420ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (meta != NULL && meta->findInt32("targetDuration", &targetDuration) ) { 16430ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int64_t bufferedDurationUs = packetSource->getEstimatedDurationUs(); 16440ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih int64_t targetDurationUs = targetDuration * 1000000ll; 16450ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16460ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (bufferedDurationUs < targetDurationUs / 3) { 16470ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih (new AMessage(kWhatSwitchDown, id()))->post(); 16480ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih break; 16490ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16500ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16510ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16520ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16530ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor->post(1000000ll); 16540ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih} 16550ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16560ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shihvoid LiveSession::onSwitchDown() { 16570ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress || mCurBandwidthIndex == 0) { 16580ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16590ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16600ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16610ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih ssize_t bandwidthIndex = getBandwidthIndex(); 16620ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih if (bandwidthIndex < mCurBandwidthIndex) { 16630ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih changeConfiguration(-1, bandwidthIndex, false); 16640ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih return; 16650ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih } 16660ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16670ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih} 16680ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 16691543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih// Mark switch done when: 1670309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih// 1. all old buffers are swapped out 16711543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::tryToFinishBandwidthSwitch() { 1672309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!mSwitchInProgress) { 1673309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih return; 1674309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 1675309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 16761543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih bool needToRemoveFetchers = false; 16771543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 16781543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mFetcherInfos.valueAt(i).mToBeRemoved) { 16791543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih needToRemoveFetchers = true; 16801543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih break; 16811543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16821543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 1683309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih 1684309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (!needToRemoveFetchers && mSwapMask == 0) { 1685309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih ALOGI("mSwitchInProgress = false"); 16861543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mStreamMask = mNewStreamMask; 16871543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 16881543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 16891543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 16901543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 169114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::scheduleCheckBandwidthEvent() { 169214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id()); 169314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->setInt32("generation", mCheckBandwidthGeneration); 169414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber msg->post(10000000ll); 1695a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1696a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 169714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::cancelCheckBandwidthEvent() { 169814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber ++mCheckBandwidthGeneration; 1699a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1700a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 17011543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihvoid LiveSession::cancelBandwidthSwitch() { 17021543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih Mutex::Autolock lock(mSwapMutex); 17031543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchGeneration++; 17041543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwitchInProgress = false; 17051543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih mSwapMask = 0; 1706f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1707f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < mFetcherInfos.size(); ++i) { 1708f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih FetcherInfo& info = mFetcherInfos.editValueAt(i); 1709f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (info.mToBeRemoved) { 1710f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih info.mToBeRemoved = false; 1711f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1712f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1713f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1714f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih for (size_t i = 0; i < kMaxStreams; ++i) { 1715f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (!mStreams[i].mNewUri.empty()) { 1716f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih ssize_t j = mFetcherInfos.indexOfKey(mStreams[i].mNewUri); 1717f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih if (j < 0) { 1718f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[i].mNewUri.clear(); 1719f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih continue; 1720f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1721f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih 1722f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih const FetcherInfo &info = mFetcherInfos.valueAt(j); 1723f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih info.mFetcher->stopAsync(); 1724f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mFetcherInfos.removeItemsAt(j); 1725f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih mStreams[i].mNewUri.clear(); 1726f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 1727f4a48dfa8570d6a4708a868b8b15d1236f7ca54bRobert Shih } 17281543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 17291543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 17301543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shihbool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) { 17311543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (mReconfigurationInProgress || mSwitchInProgress) { 17321543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 17331543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 17341543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 1735309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (mCurBandwidthIndex < 0) { 17361543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 173714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 173814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 1739309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (bandwidthIndex == (size_t)mCurBandwidthIndex) { 17401543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return false; 1741309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } else if (bandwidthIndex > (size_t)mCurBandwidthIndex) { 17421543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return canSwitchUp(); 17431543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 17441543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih return true; 17451543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } 17461543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih} 17471543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih 174800598ec0b15426197494aaf9e5ec0bc88507c762Robert Shihvoid LiveSession::onCheckBandwidth(const sp<AMessage> &msg) { 174914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t bandwidthIndex = getBandwidthIndex(); 17501543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih if (canSwitchBandwidthTo(bandwidthIndex)) { 175114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber changeConfiguration(-1ll /* timeUs */, bandwidthIndex); 17521543d3c735a5ba4ddfcf8ab644575df13c7e30a9Robert Shih } else { 175300598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // Come back and check again 10 seconds later in case there is nothing to do now. 175400598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // If we DO change configuration, once that completes it'll schedule a new 175500598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih // check bandwidth event with an incremented mCheckBandwidthGeneration. 175600598ec0b15426197494aaf9e5ec0bc88507c762Robert Shih msg->post(10000000ll); 175714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1758a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 1759a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 176014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubervoid LiveSession::postPrepared(status_t err) { 176114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(mInPreparationPhase); 1762a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 176314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<AMessage> notify = mNotify->dup(); 176414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (err == OK || err == ERROR_END_OF_STREAM) { 176514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPrepared); 176614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } else { 176714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("what", kWhatPreparationFailed); 176814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->setInt32("err", err); 176914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 1770a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 177114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber notify->post(); 1772a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 177314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mInPreparationPhase = false; 17740ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih 17750ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor = new AMessage(kWhatCheckSwitchDown, id()); 17760ad776d2e4c6b4968d9dcd9bf34b962366b312a9Robert Shih mSwitchDownMonitor->post(); 1777b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber} 1778b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 1779a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} // namespace android 1780a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 1781