LiveSession.cpp revision ad0d9c9c39a24b7fbd94e935a5855c9025341929
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 21a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include "include/LiveSession.h" 22a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 23a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include "LiveDataSource.h" 24a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 25a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include "include/M3UParser.h" 261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "include/HTTPBase.h" 27a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 28a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <cutils/properties.h> 29a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/hexdump.h> 30a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 31a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/ADebug.h> 32a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/foundation/AMessage.h> 33a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/DataSource.h> 34a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/FileSource.h> 35a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <media/stagefright/MediaErrors.h> 36a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 37a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <ctype.h> 38a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include <openssl/aes.h> 39a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 40a44153c1a57202fb538659eb50706e60454d6273Andreas Hubernamespace android { 41a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 42a44153c1a57202fb538659eb50706e60454d6273Andreas Huberconst int64_t LiveSession::kMaxPlaylistAgeUs = 15000000ll; 43a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 447314fa17093d514199fedcb55ac41136a1b31cb3Andreas HuberLiveSession::LiveSession(uint32_t flags) 457314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber : mFlags(flags), 467314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber mDataSource(new LiveDataSource), 477314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber mHTTPDataSource( 481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber HTTPBase::Create( 497314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber (mFlags & kFlagIncognito) 501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber ? HTTPBase::kFlagIncognito 517314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber : 0)), 52a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mPrevBandwidthIndex(-1), 53a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mLastPlaylistFetchTimeUs(-1), 54a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeqNumber(-1), 55a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeekTimeUs(-1), 56a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mNumRetries(0), 57a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDurationUs(-1), 58a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeekDone(false), 59ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber mDisconnectPending(false), 60a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mMonitorQueueGeneration(0) { 61a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 62a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 63a44153c1a57202fb538659eb50706e60454d6273Andreas HuberLiveSession::~LiveSession() { 64a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 65a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 66a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersp<DataSource> LiveSession::getDataSource() { 67a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return mDataSource; 68a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 69a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 70ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Hubervoid LiveSession::connect( 71ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 72a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatConnect, id()); 73a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setString("url", url); 74ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 75ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (headers != NULL) { 76ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber msg->setPointer( 77ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber "headers", 78ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber new KeyedVector<String8, String8>(*headers)); 79ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 80ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 81a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(); 82a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 83a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 84a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::disconnect() { 85ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber Mutex::Autolock autoLock(mLock); 86ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber mDisconnectPending = true; 87ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 88ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber mHTTPDataSource->disconnect(); 89ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 90a44153c1a57202fb538659eb50706e60454d6273Andreas Huber (new AMessage(kWhatDisconnect, id()))->post(); 91a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 92a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 93a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::seekTo(int64_t timeUs) { 94a44153c1a57202fb538659eb50706e60454d6273Andreas Huber Mutex::Autolock autoLock(mLock); 95a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeekDone = false; 96a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 97a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatSeek, id()); 98a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setInt64("timeUs", timeUs); 99a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(); 100a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 101a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (!mSeekDone) { 102a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mCondition.wait(mLock); 103a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 104a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 105a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 106a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMessageReceived(const sp<AMessage> &msg) { 107a44153c1a57202fb538659eb50706e60454d6273Andreas Huber switch (msg->what()) { 108a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatConnect: 109a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onConnect(msg); 110a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 111a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 112a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatDisconnect: 113a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onDisconnect(); 114a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 115a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 116a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatMonitorQueue: 117a44153c1a57202fb538659eb50706e60454d6273Andreas Huber { 118a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t generation; 119a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findInt32("generation", &generation)); 120a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 121a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (generation != mMonitorQueueGeneration) { 122a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Stale event 123a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 124a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 125a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 126a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onMonitorQueue(); 127a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 128a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 129a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 130a44153c1a57202fb538659eb50706e60454d6273Andreas Huber case kWhatSeek: 131a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onSeek(msg); 132a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 133a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 134a44153c1a57202fb538659eb50706e60454d6273Andreas Huber default: 135a44153c1a57202fb538659eb50706e60454d6273Andreas Huber TRESPASS(); 136a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 137a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 138a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 139a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 140a44153c1a57202fb538659eb50706e60454d6273Andreas Huber// static 141a44153c1a57202fb538659eb50706e60454d6273Andreas Huberint LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b) { 142a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (a->mBandwidth < b->mBandwidth) { 143a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return -1; 144a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (a->mBandwidth == b->mBandwidth) { 145a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 146a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 147a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 148a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 1; 149a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 150a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 151a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onConnect(const sp<AMessage> &msg) { 152a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString url; 153a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findString("url", &url)); 154a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 155ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber KeyedVector<String8, String8> *headers = NULL; 156ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber if (!msg->findPointer("headers", (void **)&headers)) { 157ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders.clear(); 158ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } else { 159ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber mExtraHeaders = *headers; 160ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 161ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber delete headers; 162ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber headers = NULL; 163ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber } 164ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber 1657314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber if (!(mFlags & kFlagIncognito)) { 1667314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber LOGI("onConnect '%s'", url.c_str()); 1677314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber } else { 1687314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber LOGI("onConnect <URL suppressed>"); 1697314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber } 170a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 171a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mMasterURL = url; 172a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 173a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = fetchPlaylist(url.c_str()); 174ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 175ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber if (playlist == NULL) { 176ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber LOGE("unable to fetch master playlist '%s'.", url.c_str()); 177ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 178ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber mDataSource->queueEOS(ERROR_IO); 179ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber return; 180ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 181a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 182a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->isVariantPlaylist()) { 183a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (size_t i = 0; i < playlist->size(); ++i) { 184a44153c1a57202fb538659eb50706e60454d6273Andreas Huber BandwidthItem item; 185a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 186a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> meta; 187a44153c1a57202fb538659eb50706e60454d6273Andreas Huber playlist->itemAt(i, &item.mURI, &meta); 188a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 189a44153c1a57202fb538659eb50706e60454d6273Andreas Huber unsigned long bandwidth; 190a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(meta->findInt32("bandwidth", (int32_t *)&item.mBandwidth)); 191a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 192a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.push(item); 193a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 194a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 195a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(mBandwidthItems.size(), 0u); 196a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 197a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mBandwidthItems.sort(SortByBandwidth); 198a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 199a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 200a44153c1a57202fb538659eb50706e60454d6273Andreas Huber postMonitorQueue(); 201a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 202a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 203a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onDisconnect() { 204a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGI("onDisconnect"); 205a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 206a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDataSource->queueEOS(ERROR_END_OF_STREAM); 207ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 208ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber Mutex::Autolock autoLock(mLock); 209ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber mDisconnectPending = false; 210a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 211a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 212a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatus_t LiveSession::fetchFile(const char *url, sp<ABuffer> *out) { 213a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = NULL; 214a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 215a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<DataSource> source; 216a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 217a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (!strncasecmp(url, "file://", 7)) { 218a44153c1a57202fb538659eb50706e60454d6273Andreas Huber source = new FileSource(url + 7); 2198cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber } else if (strncasecmp(url, "http://", 7) 2208cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber && strncasecmp(url, "https://", 8)) { 221df42f949c8bd05b81d94633767514fff88f52062Andreas Huber return ERROR_UNSUPPORTED; 222a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 223ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber { 224ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber Mutex::Autolock autoLock(mLock); 225ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 226ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber if (mDisconnectPending) { 227ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber return ERROR_IO; 228ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 229ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber } 230ab8a0badb8fb1e294dacf2eb6a891439f348aff9Andreas Huber 231ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber status_t err = mHTTPDataSource->connect( 232ad0d9c9c39a24b7fbd94e935a5855c9025341929Andreas Huber url, mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); 233a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 234a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (err != OK) { 235a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return err; 236a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 237a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 238a44153c1a57202fb538659eb50706e60454d6273Andreas Huber source = mHTTPDataSource; 239a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 240a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 241a44153c1a57202fb538659eb50706e60454d6273Andreas Huber off64_t size; 242a44153c1a57202fb538659eb50706e60454d6273Andreas Huber status_t err = source->getSize(&size); 243a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 244a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (err != OK) { 245a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size = 65536; 246a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 247a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 248a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 249a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, 0); 250a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 251a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (;;) { 252a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bufferRemaining = buffer->capacity() - buffer->size(); 253a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 254a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (bufferRemaining == 0) { 255a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bufferRemaining = 32768; 256a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 257a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGV("increasing download buffer to %d bytes", 258a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size() + bufferRemaining); 259a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 260a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining); 261a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memcpy(copy->data(), buffer->data(), buffer->size()); 262a44153c1a57202fb538659eb50706e60454d6273Andreas Huber copy->setRange(0, buffer->size()); 263a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 264a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer = copy; 265a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 266a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 267a44153c1a57202fb538659eb50706e60454d6273Andreas Huber ssize_t n = source->readAt( 268a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->size(), buffer->data() + buffer->size(), 269a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bufferRemaining); 270a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 271a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n < 0) { 27220ad3a341a96e7746015ccb7369fa567897e11f6Andreas Huber return n; 273a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 274a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 275a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n == 0) { 276a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 277a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 278a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 279a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(0, buffer->size() + (size_t)n); 280a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 281a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 282a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *out = buffer; 283a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 284a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return OK; 285a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 286a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 287a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersp<M3UParser> LiveSession::fetchPlaylist(const char *url) { 288a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 289a44153c1a57202fb538659eb50706e60454d6273Andreas Huber status_t err = fetchFile(url, &buffer); 290a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 291a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (err != OK) { 292a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 293a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 294a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 295a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<M3UParser> playlist = 296a44153c1a57202fb538659eb50706e60454d6273Andreas Huber new M3UParser(url, buffer->data(), buffer->size()); 297a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 298a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (playlist->initCheck() != OK) { 299a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return NULL; 300a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 301a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 302a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return playlist; 303a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 304a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 305a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatic double uniformRand() { 306a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return (double)rand() / RAND_MAX; 307a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 308a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 309a44153c1a57202fb538659eb50706e60454d6273Andreas Hubersize_t LiveSession::getBandwidthIndex() { 310a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() == 0) { 311a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; 312a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 313a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 314a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#if 1 315a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t bandwidthBps; 316a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mHTTPDataSource != NULL 317a44153c1a57202fb538659eb50706e60454d6273Andreas Huber && mHTTPDataSource->estimateBandwidth(&bandwidthBps)) { 318a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); 319a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 320a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGV("no bandwidth estimate."); 321a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return 0; // Pick the lowest bandwidth stream by default. 322a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 323a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 324a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char value[PROPERTY_VALUE_MAX]; 325a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (property_get("media.httplive.max-bw", value, NULL)) { 326a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char *end; 327a44153c1a57202fb538659eb50706e60454d6273Andreas Huber long maxBw = strtoul(value, &end, 10); 328a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (end > value && *end == '\0') { 329a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (maxBw > 0 && bandwidthBps > maxBw) { 330a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGV("bandwidth capped to %ld bps", maxBw); 331a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bandwidthBps = maxBw; 332a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 333a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 334a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 335a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 336a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Consider only 80% of the available bandwidth usable. 337a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bandwidthBps = (bandwidthBps * 8) / 10; 338a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 339a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to estimated bandwidth. 340a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 341a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 342a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth 343a44153c1a57202fb538659eb50706e60454d6273Andreas Huber > (size_t)bandwidthBps) { 344a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 345a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 346a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 347a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Change bandwidth at random() 348a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = uniformRand() * mBandwidthItems.size(); 349a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 350a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // There's a 50% chance to stay on the current bandwidth and 351a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // a 50% chance to switch to the next higher bandwidth (wrapping around 352a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // to lowest) 353a44153c1a57202fb538659eb50706e60454d6273Andreas Huber const size_t kMinIndex = 0; 354a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 355a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index; 356a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mPrevBandwidthIndex < 0) { 357a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 358a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (uniformRand() < 0.5) { 359a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = (size_t)mPrevBandwidthIndex; 360a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 361a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = mPrevBandwidthIndex + 1; 362a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index == mBandwidthItems.size()) { 363a44153c1a57202fb538659eb50706e60454d6273Andreas Huber index = kMinIndex; 364a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 365a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 366a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#elif 0 367a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Pick the highest bandwidth stream below or equal to 1.2 Mbit/sec 368a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 369a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; 370a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (index > 0 && mBandwidthItems.itemAt(index).mBandwidth > 1200000) { 371a44153c1a57202fb538659eb50706e60454d6273Andreas Huber --index; 372a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 373a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#else 374a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream 375a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#endif 376a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 377a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return index; 378a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 379a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 380a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onDownloadNext() { 381a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t bandwidthIndex = getBandwidthIndex(); 382a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 383aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huberrinse_repeat: 384a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 385a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 386a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mLastPlaylistFetchTimeUs < 0 387a44153c1a57202fb538659eb50706e60454d6273Andreas Huber || (ssize_t)bandwidthIndex != mPrevBandwidthIndex 388a44153c1a57202fb538659eb50706e60454d6273Andreas Huber || (!mPlaylist->isComplete() 389a44153c1a57202fb538659eb50706e60454d6273Andreas Huber && mLastPlaylistFetchTimeUs + kMaxPlaylistAgeUs <= nowUs)) { 390a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString url; 391a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mBandwidthItems.size() > 0) { 392a44153c1a57202fb538659eb50706e60454d6273Andreas Huber url = mBandwidthItems.editItemAt(bandwidthIndex).mURI; 393a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 394a44153c1a57202fb538659eb50706e60454d6273Andreas Huber url = mMasterURL; 395a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 396a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 397a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bool firstTime = (mPlaylist == NULL); 398a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 399a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mPlaylist = fetchPlaylist(url.c_str()); 4006e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber if (mPlaylist == NULL) { 4016e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber LOGE("failed to load playlist at url '%s'", url.c_str()); 4026e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber mDataSource->queueEOS(ERROR_IO); 4036e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber return; 4046e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 405a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 406a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (firstTime) { 407a44153c1a57202fb538659eb50706e60454d6273Andreas Huber Mutex::Autolock autoLock(mLock); 408a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 409a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t targetDuration; 410a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (!mPlaylist->isComplete() 411a44153c1a57202fb538659eb50706e60454d6273Andreas Huber || !mPlaylist->meta()->findInt32( 412a44153c1a57202fb538659eb50706e60454d6273Andreas Huber "target-duration", &targetDuration)) { 413a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDurationUs = -1; 414a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 415a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDurationUs = 1000000ll * targetDuration * mPlaylist->size(); 416a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 417a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 418a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 419a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mLastPlaylistFetchTimeUs = ALooper::GetNowUs(); 420a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 421a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 422a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t firstSeqNumberInPlaylist; 423a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( 424a44153c1a57202fb538659eb50706e60454d6273Andreas Huber "media-sequence", &firstSeqNumberInPlaylist)) { 425a44153c1a57202fb538659eb50706e60454d6273Andreas Huber firstSeqNumberInPlaylist = 0; 426a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 427a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 428a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bool explicitDiscontinuity = false; 42922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber bool bandwidthChanged = false; 430a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 431a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mSeekTimeUs >= 0) { 432a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t targetDuration; 433a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mPlaylist->isComplete() && 434a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mPlaylist->meta()->findInt32( 435a44153c1a57202fb538659eb50706e60454d6273Andreas Huber "target-duration", &targetDuration)) { 436a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int64_t seekTimeSecs = (mSeekTimeUs + 500000ll) / 1000000ll; 437a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int64_t index = seekTimeSecs / targetDuration; 438a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 439a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index >= 0 && index < mPlaylist->size()) { 44043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int32_t newSeqNumber = firstSeqNumberInPlaylist + index; 441a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 44243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (newSeqNumber != mSeqNumber) { 44343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber LOGI("seeking to seq no %d", newSeqNumber); 44443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 44543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mSeqNumber = newSeqNumber; 44643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 44743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mDataSource->reset(); 44843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 44922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // reseting the data source will have had the 45022fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // side effect of discarding any previously queued 45122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // bandwidth change discontinuity. 45222fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // Therefore we'll need to treat these explicit 45322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // discontinuities as involving a bandwidth change 45422fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // even if they aren't directly. 45543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber explicitDiscontinuity = true; 45622fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber bandwidthChanged = true; 45743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 458a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 459a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 460a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 461a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeekTimeUs = -1; 462a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 463a44153c1a57202fb538659eb50706e60454d6273Andreas Huber Mutex::Autolock autoLock(mLock); 464a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeekDone = true; 465a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mCondition.broadcast(); 466a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 467a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 468a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mSeqNumber < 0) { 469a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mPlaylist->isComplete()) { 470a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeqNumber = firstSeqNumberInPlaylist; 471a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 472a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeqNumber = firstSeqNumberInPlaylist + mPlaylist->size() / 2; 473a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 474a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 475a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 476a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t lastSeqNumberInPlaylist = 477a44153c1a57202fb538659eb50706e60454d6273Andreas Huber firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; 478a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 479a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mSeqNumber < firstSeqNumberInPlaylist 480a44153c1a57202fb538659eb50706e60454d6273Andreas Huber || mSeqNumber > lastSeqNumberInPlaylist) { 48188b7ad413c4b6d08697069b18488641d6ce31fd3Andreas Huber if (mPrevBandwidthIndex != (ssize_t)bandwidthIndex) { 482aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber // Go back to the previous bandwidth. 483aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 484aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber LOGI("new bandwidth does not have the sequence number " 485aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber "we're looking for, switching back to previous bandwidth"); 486aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 487aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber mLastPlaylistFetchTimeUs = -1; 488aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber bandwidthIndex = mPrevBandwidthIndex; 489aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber goto rinse_repeat; 490aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber } 491aea5aff45a1af14e249ac311f0a128a621a7d13eAndreas Huber 492a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (!mPlaylist->isComplete() 493a44153c1a57202fb538659eb50706e60454d6273Andreas Huber && mSeqNumber > lastSeqNumberInPlaylist 494a44153c1a57202fb538659eb50706e60454d6273Andreas Huber && mNumRetries < kMaxNumRetries) { 495a44153c1a57202fb538659eb50706e60454d6273Andreas Huber ++mNumRetries; 496a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 497a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mLastPlaylistFetchTimeUs = -1; 4985bc087c573c70c84c6a39946457590b42d392a33Andreas Huber postMonitorQueue(3000000ll); 499a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return; 500a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 501a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 502a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("Cannot find sequence number %d in playlist " 503a44153c1a57202fb538659eb50706e60454d6273Andreas Huber "(contains %d - %d)", 504a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeqNumber, firstSeqNumberInPlaylist, 505a44153c1a57202fb538659eb50706e60454d6273Andreas Huber firstSeqNumberInPlaylist + mPlaylist->size() - 1); 506a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 507a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDataSource->queueEOS(ERROR_END_OF_STREAM); 508a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return; 509a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 510a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 511a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mNumRetries = 0; 512a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 513a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString uri; 514a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> itemMeta; 515a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(mPlaylist->itemAt( 516a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeqNumber - firstSeqNumberInPlaylist, 517a44153c1a57202fb538659eb50706e60454d6273Andreas Huber &uri, 518a44153c1a57202fb538659eb50706e60454d6273Andreas Huber &itemMeta)); 519a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 520a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int32_t val; 521a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (itemMeta->findInt32("discontinuity", &val) && val != 0) { 522a44153c1a57202fb538659eb50706e60454d6273Andreas Huber explicitDiscontinuity = true; 523a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 524a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 525a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> buffer; 526a44153c1a57202fb538659eb50706e60454d6273Andreas Huber status_t err = fetchFile(uri.c_str(), &buffer); 5276e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber if (err != OK) { 5286e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber LOGE("failed to fetch .ts segment at url '%s'", uri.c_str()); 5296e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber mDataSource->queueEOS(err); 5306e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber return; 5316e6b1cae2bac1b78205cefab8e4e9e9538982965Andreas Huber } 532a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 53343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber CHECK(buffer != NULL); 53443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 53588b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer); 53688b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 53788b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber if (err != OK) { 53888b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber LOGE("decryptBuffer failed w/ error %d", err); 53988b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber 54088b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber mDataSource->queueEOS(err); 54188b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber return; 54288b348910a607ae399bcd693dd42a231d98da2c9Andreas Huber } 543a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 544a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (buffer->size() == 0 || buffer->data()[0] != 0x47) { 545a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Not a transport stream??? 546a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 547a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("This doesn't look like a transport stream..."); 548a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 549bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mBandwidthItems.removeAt(bandwidthIndex); 550bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 551bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber if (mBandwidthItems.isEmpty()) { 552bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mDataSource->queueEOS(ERROR_UNSUPPORTED); 553bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber return; 554bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 555bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 556bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber LOGI("Retrying with a different bandwidth stream."); 557bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 558bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mLastPlaylistFetchTimeUs = -1; 559bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber bandwidthIndex = getBandwidthIndex(); 560bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mPrevBandwidthIndex = bandwidthIndex; 561bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mSeqNumber = -1; 562bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 563bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber goto rinse_repeat; 564a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 565a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 56622fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber if ((size_t)mPrevBandwidthIndex != bandwidthIndex) { 56722fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber bandwidthChanged = true; 56822fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 56922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber 57022fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber if (mPrevBandwidthIndex < 0) { 57122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // Don't signal a bandwidth change at the very beginning of 57222fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber // playback. 57322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber bandwidthChanged = false; 57422fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } 5753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 5763831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (explicitDiscontinuity || bandwidthChanged) { 577a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // Signal discontinuity. 578a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 57943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber LOGI("queueing discontinuity (explicit=%d, bandwidthChanged=%d)", 58043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber explicitDiscontinuity, bandwidthChanged); 58143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 582a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> tmp = new ABuffer(188); 583a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memset(tmp->data(), 0, tmp->size()); 5843831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber tmp->data()[1] = bandwidthChanged; 585a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 586a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDataSource->queueBuffer(tmp); 587a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 588a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 589a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mDataSource->queueBuffer(buffer); 590a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 591a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mPrevBandwidthIndex = bandwidthIndex; 592a44153c1a57202fb538659eb50706e60454d6273Andreas Huber ++mSeqNumber; 593a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 594a44153c1a57202fb538659eb50706e60454d6273Andreas Huber postMonitorQueue(); 595a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 596a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 597a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onMonitorQueue() { 598a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (mSeekTimeUs >= 0 599a44153c1a57202fb538659eb50706e60454d6273Andreas Huber || mDataSource->countQueuedBuffers() < kMaxNumQueuedFragments) { 600a44153c1a57202fb538659eb50706e60454d6273Andreas Huber onDownloadNext(); 601a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 602a44153c1a57202fb538659eb50706e60454d6273Andreas Huber postMonitorQueue(1000000ll); 603a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 604a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 605a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 606a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatus_t LiveSession::decryptBuffer( 607a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t playlistIndex, const sp<ABuffer> &buffer) { 608a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> itemMeta; 609a44153c1a57202fb538659eb50706e60454d6273Andreas Huber bool found = false; 610a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString method; 611a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 612a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (ssize_t i = playlistIndex; i >= 0; --i) { 613a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString uri; 614a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(mPlaylist->itemAt(i, &uri, &itemMeta)); 615a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 616a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (itemMeta->findString("cipher-method", &method)) { 617a44153c1a57202fb538659eb50706e60454d6273Andreas Huber found = true; 618a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 619a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 620a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 621a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 622a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (!found) { 623a44153c1a57202fb538659eb50706e60454d6273Andreas Huber method = "NONE"; 624a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 625a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 626a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (method == "NONE") { 627a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return OK; 628a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else if (!(method == "AES-128")) { 629a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("Unsupported cipher method '%s'", method.c_str()); 630a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return ERROR_UNSUPPORTED; 631a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 632a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 633a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString keyURI; 634a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (!itemMeta->findString("cipher-uri", &keyURI)) { 635a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("Missing key uri"); 636a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return ERROR_MALFORMED; 637a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 638a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 639a44153c1a57202fb538659eb50706e60454d6273Andreas Huber ssize_t index = mAESKeyForURI.indexOfKey(keyURI); 640a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 641a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<ABuffer> key; 642a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (index >= 0) { 643a44153c1a57202fb538659eb50706e60454d6273Andreas Huber key = mAESKeyForURI.valueAt(index); 644a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 645a44153c1a57202fb538659eb50706e60454d6273Andreas Huber key = new ABuffer(16); 646a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 6471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber sp<HTTPBase> keySource = 6481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber HTTPBase::Create( 6491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber (mFlags & kFlagIncognito) 6501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber ? HTTPBase::kFlagIncognito 6511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber : 0); 6521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber 653a44153c1a57202fb538659eb50706e60454d6273Andreas Huber status_t err = keySource->connect(keyURI.c_str()); 654a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 655a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (err == OK) { 656a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t offset = 0; 657a44153c1a57202fb538659eb50706e60454d6273Andreas Huber while (offset < 16) { 658a44153c1a57202fb538659eb50706e60454d6273Andreas Huber ssize_t n = keySource->readAt( 659a44153c1a57202fb538659eb50706e60454d6273Andreas Huber offset, key->data() + offset, 16 - offset); 660a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (n <= 0) { 661a44153c1a57202fb538659eb50706e60454d6273Andreas Huber err = ERROR_IO; 662a44153c1a57202fb538659eb50706e60454d6273Andreas Huber break; 663a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 664a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 665a44153c1a57202fb538659eb50706e60454d6273Andreas Huber offset += n; 666a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 667a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 668a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 669a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (err != OK) { 670a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("failed to fetch cipher key from '%s'.", keyURI.c_str()); 671a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return ERROR_IO; 672a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 673a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 674a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mAESKeyForURI.add(keyURI, key); 675a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 676a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 677a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AES_KEY aes_key; 678a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (AES_set_decrypt_key(key->data(), 128, &aes_key) != 0) { 679a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("failed to set AES decryption key."); 680a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return UNKNOWN_ERROR; 681a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 682a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 683a44153c1a57202fb538659eb50706e60454d6273Andreas Huber unsigned char aes_ivec[16]; 684a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 685a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AString iv; 686a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (itemMeta->findString("cipher-iv", &iv)) { 687a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if ((!iv.startsWith("0x") && !iv.startsWith("0X")) 688a44153c1a57202fb538659eb50706e60454d6273Andreas Huber || iv.size() != 16 * 2 + 2) { 689a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("malformed cipher IV '%s'.", iv.c_str()); 690a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return ERROR_MALFORMED; 691a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 692a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 693a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memset(aes_ivec, 0, sizeof(aes_ivec)); 694a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (size_t i = 0; i < 16; ++i) { 695a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char c1 = tolower(iv.c_str()[2 + 2 * i]); 696a44153c1a57202fb538659eb50706e60454d6273Andreas Huber char c2 = tolower(iv.c_str()[3 + 2 * i]); 697a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (!isxdigit(c1) || !isxdigit(c2)) { 698a44153c1a57202fb538659eb50706e60454d6273Andreas Huber LOGE("malformed cipher IV '%s'.", iv.c_str()); 699a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return ERROR_MALFORMED; 700a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 701a44153c1a57202fb538659eb50706e60454d6273Andreas Huber uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10; 702a44153c1a57202fb538659eb50706e60454d6273Andreas Huber uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10; 703a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 704a44153c1a57202fb538659eb50706e60454d6273Andreas Huber aes_ivec[i] = nibble1 << 4 | nibble2; 705a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 706a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 707a44153c1a57202fb538659eb50706e60454d6273Andreas Huber memset(aes_ivec, 0, sizeof(aes_ivec)); 708a44153c1a57202fb538659eb50706e60454d6273Andreas Huber aes_ivec[15] = mSeqNumber & 0xff; 709a44153c1a57202fb538659eb50706e60454d6273Andreas Huber aes_ivec[14] = (mSeqNumber >> 8) & 0xff; 710a44153c1a57202fb538659eb50706e60454d6273Andreas Huber aes_ivec[13] = (mSeqNumber >> 16) & 0xff; 711a44153c1a57202fb538659eb50706e60454d6273Andreas Huber aes_ivec[12] = (mSeqNumber >> 24) & 0xff; 712a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 713a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 714a44153c1a57202fb538659eb50706e60454d6273Andreas Huber AES_cbc_encrypt( 715a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->data(), buffer->data(), buffer->size(), 716a44153c1a57202fb538659eb50706e60454d6273Andreas Huber &aes_key, aes_ivec, AES_DECRYPT); 717a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 718a44153c1a57202fb538659eb50706e60454d6273Andreas Huber // hexdump(buffer->data(), buffer->size()); 719a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 720a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t n = buffer->size(); 721a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(n, 0u); 722a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 723a44153c1a57202fb538659eb50706e60454d6273Andreas Huber size_t pad = buffer->data()[n - 1]; 724a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 725a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GT(pad, 0u); 726a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_LE(pad, 16u); 727a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_GE((size_t)n, pad); 728a44153c1a57202fb538659eb50706e60454d6273Andreas Huber for (size_t i = 0; i < pad; ++i) { 729a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK_EQ((unsigned)buffer->data()[n - 1 - i], pad); 730a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 731a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 732a44153c1a57202fb538659eb50706e60454d6273Andreas Huber n -= pad; 733a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 734a44153c1a57202fb538659eb50706e60454d6273Andreas Huber buffer->setRange(buffer->offset(), n); 735a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 736a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return OK; 737a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 738a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 739a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::postMonitorQueue(int64_t delayUs) { 740a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id()); 741a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->setInt32("generation", ++mMonitorQueueGeneration); 742a44153c1a57202fb538659eb50706e60454d6273Andreas Huber msg->post(delayUs); 743a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 744a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 745a44153c1a57202fb538659eb50706e60454d6273Andreas Hubervoid LiveSession::onSeek(const sp<AMessage> &msg) { 746a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int64_t timeUs; 747a44153c1a57202fb538659eb50706e60454d6273Andreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 748a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 749a44153c1a57202fb538659eb50706e60454d6273Andreas Huber mSeekTimeUs = timeUs; 750a44153c1a57202fb538659eb50706e60454d6273Andreas Huber postMonitorQueue(); 751a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 752a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 753a44153c1a57202fb538659eb50706e60454d6273Andreas Huberstatus_t LiveSession::getDuration(int64_t *durationUs) { 754a44153c1a57202fb538659eb50706e60454d6273Andreas Huber Mutex::Autolock autoLock(mLock); 755a44153c1a57202fb538659eb50706e60454d6273Andreas Huber *durationUs = mDurationUs; 756a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 757a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return OK; 758a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 759a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 760a44153c1a57202fb538659eb50706e60454d6273Andreas Huberbool LiveSession::isSeekable() { 761a44153c1a57202fb538659eb50706e60454d6273Andreas Huber int64_t durationUs; 762a44153c1a57202fb538659eb50706e60454d6273Andreas Huber return getDuration(&durationUs) == OK && durationUs >= 0; 763a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} 764a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 765a44153c1a57202fb538659eb50706e60454d6273Andreas Huber} // namespace android 766a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 767