NuCachedSource2.cpp revision a045cb0e77097120e86e367e1cab5494ce2a5d5e
15994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber/* 25994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Copyright (C) 2010 The Android Open Source Project 35994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * 45994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 55994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * you may not use this file except in compliance with the License. 65994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * You may obtain a copy of the License at 75994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * 85994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 95994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * 105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * Unless required by applicable law or agreed to in writing, software 115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * See the License for the specific language governing permissions and 145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber * limitations under the License. 155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber */ 165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 17ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber//#define LOG_NDEBUG 0 185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#define LOG_TAG "NuCachedSource2" 195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <utils/Log.h> 205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include "include/NuCachedSource2.h" 225b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong#include "include/HTTPBase.h" 235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 24a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber#include <cutils/properties.h> 255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/ADebug.h> 265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/AMessage.h> 275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/MediaErrors.h> 285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 295994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubernamespace android { 305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct PageCache { 325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache(size_t pageSize); 335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ~PageCache(); 345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber struct Page { 365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *mData; 375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mSize; 385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber }; 395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *acquirePage(); 415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void releasePage(Page *page); 425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void appendPage(Page *page); 445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t releaseFromStart(size_t maxBytes); 455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize() const { 475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mTotalSize; 485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void copy(size_t from, void *data, size_t size); 515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberprivate: 535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mPageSize; 545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mTotalSize; 555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mActivePages; 575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mFreePages; 585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void freePages(List<Page *> *list); 605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(PageCache); 625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber}; 635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 645994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::PageCache(size_t pageSize) 655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mPageSize(pageSize), 665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize(0) { 675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 695994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::~PageCache() { 705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mActivePages); 715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mFreePages); 725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 745994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::freePages(List<Page *> *list) { 755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = list->begin(); 765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (it != list->end()) { 775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber free(page->mData); 805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete page; 815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page = NULL; 825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 875994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::Page *PageCache::acquirePage() { 885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (!mFreePages.empty()) { 895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mFreePages.begin(); 905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.erase(it); 925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = new Page; 975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mData = malloc(mPageSize); 985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 1015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1035994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::releasePage(Page *page) { 1045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 1055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.push_back(page); 1065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1085994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::appendPage(Page *page) { 1095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize += page->mSize; 1105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.push_back(page); 1115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1135994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t PageCache::releaseFromStart(size_t maxBytes) { 1145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t bytesReleased = 0; 1155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (maxBytes > 0 && !mActivePages.empty()) { 1175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 1205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (maxBytes < page->mSize) { 1225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 1235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.erase(it); 1265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber maxBytes -= page->mSize; 1285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber bytesReleased += page->mSize; 1295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber releasePage(page); 1315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize -= bytesReleased; 1345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return bytesReleased; 1355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1375994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::copy(size_t from, void *data, size_t size) { 1386e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("copy from %d size %d", from, size); 1395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 140310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber if (size == 0) { 141310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber return; 142310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber } 143310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber 1445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_LE(from + size, mTotalSize); 1455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t offset = 0; 1475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (from >= offset + (*it)->mSize) { 1495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber offset += (*it)->mSize; 1505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = from - offset; 1545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t avail = (*it)->mSize - delta; 1555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (avail >= size) { 1575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, size); 1585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 1595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, avail); 1625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + avail; 1645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= avail; 1655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (size > 0) { 1675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t copy = (*it)->mSize; 1685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (copy > size) { 1695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber copy = size; 1705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (*it)->mData, copy); 1725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + copy; 1735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= copy; 1745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1805994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::NuCachedSource2(const sp<DataSource> &source) 1815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mSource(source), 1825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mReflector(new AHandlerReflector<NuCachedSource2>(this)), 1835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper(new ALooper), 1845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache(new PageCache(kPageSize)), 1855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset(0), 1865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus(OK), 1875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos(0), 188a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mFetching(true), 1890683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mLastFetchTimeUs(-1), 190a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mNumRetriesLeft(kMaxNumRetries), 191a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes(kDefaultHighWaterThreshold), 192a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes(kDefaultLowWaterThreshold), 193a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) { 194a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromSystemProperty(); 195a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 196a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mLooper->setName("NuCachedSource2"); 1975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->registerHandler(mReflector); 1985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->start(); 1995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 2015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(); 2025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2045994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::~NuCachedSource2() { 2055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->stop(); 2065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->unregisterHandler(mReflector->id()); 2075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete mCache; 2095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache = NULL; 2105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2125b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) { 213b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 214b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase* source = static_cast<HTTPBase *>(mSource.get()); 215b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->getEstimatedBandwidthKbps(kbps); 216b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 217b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2185b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2195b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2205b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::setCacheStatCollectFreq(int32_t freqMs) { 221b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 222b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase *source = static_cast<HTTPBase *>(mSource.get()); 223b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->setBandwidthStatCollectFreq(freqMs); 224b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 225b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2265b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2275b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstatus_t NuCachedSource2::initCheck() const { 2295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->initCheck(); 2305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 232c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::getSize(off64_t *size) { 2335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->getSize(size); 2345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberuint32_t NuCachedSource2::flags() { 237b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong // Remove HTTP related flags since NuCachedSource2 is not HTTP-based. 238b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong uint32_t flags = mSource->flags() & ~(kWantsPrefetching | kIsHTTPBasedSource); 239b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return (flags | kIsCachingDataSource); 2405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2425994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) { 2435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber switch (msg->what()) { 2445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatFetchMore: 2455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onFetch(); 2475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatRead: 2515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onRead(msg); 2535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber default: 2575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber TRESPASS(); 2585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2615994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::fetchInternal() { 2626e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("fetchInternal"); 2635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2640683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber { 2650683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber Mutex::Autolock autoLock(mLock); 2660683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber CHECK(mFinalStatus == OK || mNumRetriesLeft > 0); 2670683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2680683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 2690683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber --mNumRetriesLeft; 2700683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2710683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber status_t err = 2720683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize()); 2730683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2740683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (err == ERROR_UNSUPPORTED) { 2750683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = 0; 2760683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber return; 2770683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else if (err != OK) { 2780683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber LOGI("The attempt to reconnect failed, %d retries remaining", 2790683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft); 2800683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2810683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber return; 2820683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 2830683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 2840683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 2855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache::Page *page = mCache->acquirePage(); 2875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t n = mSource->readAt( 2895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset + mCache->totalSize(), page->mData, kPageSize); 2905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 2925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (n < 0) { 2940683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber LOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft); 2955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = n; 2965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 2975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else if (n == 0) { 2986e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("ERROR_END_OF_STREAM"); 2990683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3000683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = 0; 3015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = ERROR_END_OF_STREAM; 3020683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 3045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else { 3050683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 3060683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber LOGI("retrying a previously failed read succeeded."); 3070683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3080683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = kMaxNumRetries; 3090683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mFinalStatus = OK; 3100683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = n; 3125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->appendPage(page); 3135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3165994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onFetch() { 3176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("onFetch"); 3185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3190683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft == 0) { 3206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("EOS reached, done prefetching for now"); 3215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 3225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 324a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber bool keepAlive = 325a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber !mFetching 326a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber && mFinalStatus == OK 327a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && mKeepAliveIntervalUs > 0 328a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber && ALooper::GetNowUs() >= mLastFetchTimeUs + mKeepAliveIntervalUs; 329a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 330a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (mFetching || keepAlive) { 331a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (keepAlive) { 3326e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("Keep alive"); 333a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber } 334a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 3355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber fetchInternal(); 3365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 337a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mLastFetchTimeUs = ALooper::GetNowUs(); 338a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 339a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) { 3406e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("Cache full, done prefetching for now"); 3415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 3425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 343a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 344d17875a226491e3de60fa32d764a4cc92de7f949Andreas Huber Mutex::Autolock autoLock(mLock); 3455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber restartPrefetcherIfNecessary_l(); 3465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3480683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber int64_t delayUs; 3490683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching) { 3500683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 3510683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // We failed this time and will try again in 3 seconds. 3520683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 3000000ll; 3530683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 3540683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 0; 3550683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3560683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 3570683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 100000ll; 3580683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3590683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3600683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs); 3615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3635994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onRead(const sp<AMessage> &msg) { 3646e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("onRead"); 3655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int64_t offset; 3675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findInt64("offset", &offset)); 3685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *data; 3705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findPointer("data", &data)); 3715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t size; 3735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findSize("size", &size)); 3745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t result = readInternal(offset, data, size); 3765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result == -EAGAIN) { 3785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(50000); 3795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 3805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 3835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 3855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult = new AMessage; 3875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult->setInt32("result", result); 3885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.signal(); 3905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 39234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::restartPrefetcherIfNecessary_l( 3937bf8413f91fc072452f315a91618aeef2574d420Andreas Huber bool ignoreLowWaterThreshold, bool force) { 3946ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const size_t kGrayArea = 1024 * 1024; 3955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3960683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) { 3975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 3985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4007bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!ignoreLowWaterThreshold && !force 40134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber && mCacheOffset + mCache->totalSize() - mLastAccessPos 402a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber >= mLowwaterThresholdBytes) { 4035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 4045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t maxBytes = mLastAccessPos - mCacheOffset; 4075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4087bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!force) { 4097bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (maxBytes < kGrayArea) { 4107bf8413f91fc072452f315a91618aeef2574d420Andreas Huber return; 4117bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4127bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 4137bf8413f91fc072452f315a91618aeef2574d420Andreas Huber maxBytes -= kGrayArea; 4147bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t actualBytes = mCache->releaseFromStart(maxBytes); 4175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset += actualBytes; 4185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("restarting prefetcher, totalSize = %d", mCache->totalSize()); 4205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 4215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 423c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) { 4245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoSerializer(mSerializer); 4255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 426145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber LOGV("readAt offset %lld, size %d", offset, size); 4275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // If the request can be completely satisfied from the cache, do so. 4315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 4335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber && offset + size <= mCacheOffset + mCache->totalSize()) { 4345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 4355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 4365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + size; 4385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 4405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber sp<AMessage> msg = new AMessage(kWhatRead, mReflector->id()); 4435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setInt64("offset", offset); 4445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setPointer("data", data); 4455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setSize("size", size); 4465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(); 4495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (mAsyncResult == NULL) { 4515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.wait(mLock); 4525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int32_t result; 4555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult->findInt32("result", &result)); 4565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult.clear(); 4585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result > 0) { 4605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + result; 4615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return (ssize_t)result; 4645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4665994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t NuCachedSource2::cachedSize() { 4675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mCacheOffset + mCache->totalSize(); 4695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4711bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinneysize_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) { 4725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4731bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney return approxDataRemaining_l(finalStatus); 4745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4761bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinneysize_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) { 4771bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney *finalStatus = mFinalStatus; 4780683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 4790683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 4800683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // Pretend that everything is fine until we're out of retries. 4810683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber *finalStatus = OK; 4820683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4830683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 484c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t lastBytePosCached = mCacheOffset + mCache->totalSize(); 4855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mLastAccessPos < lastBytePosCached) { 4865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return lastBytePosCached - mLastAccessPos; 4875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return 0; 4895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 491c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) { 492a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber CHECK_LE(size, (size_t)mHighwaterThresholdBytes); 4937bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 494145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber LOGV("readInternal offset %lld size %d", offset, size); 4955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4987bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!mFetching) { 4997bf8413f91fc072452f315a91618aeef2574d420Andreas Huber mLastAccessPos = offset; 5007bf8413f91fc072452f315a91618aeef2574d420Andreas Huber restartPrefetcherIfNecessary_l( 5017bf8413f91fc072452f315a91618aeef2574d420Andreas Huber false, // ignoreLowWaterThreshold 5027bf8413f91fc072452f315a91618aeef2574d420Andreas Huber true); // force 5037bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 5047bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 5055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset < mCacheOffset 506c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong || offset >= (off64_t)(mCacheOffset + mCache->totalSize())) { 5076ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const off64_t kPadding = 256 * 1024; 5085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // In the presence of multiple decoded streams, once of them will 5105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // trigger this seek request, the other one will request data "nearby" 5115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // soon, adjust the seek position so that that subsequent request 5125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // does not trigger another seek. 513c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t seekOffset = (offset > kPadding) ? offset - kPadding : 0; 5145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber seekInternal_l(seekOffset); 5165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 5195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mFinalStatus != OK) { 5215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (delta >= mCache->totalSize()) { 5225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mFinalStatus; 5235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5256f5aae1bcba130d5b8092a19fca3627aa565df56Andreas Huber size_t avail = mCache->totalSize() - delta; 52667802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 52767802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber if (avail > size) { 52867802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber avail = size; 52967802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber } 53067802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 5315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, avail); 5325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return avail; 5345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset + size <= mCacheOffset + mCache->totalSize()) { 5375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 5385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 5405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5426e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("deferring read"); 5435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return -EAGAIN; 5455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 547c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::seekInternal_l(off64_t offset) { 5485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset; 5495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 551c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong && offset <= (off64_t)(mCacheOffset + mCache->totalSize())) { 5525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 5535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5557fe4ed1207fa587c65231f9a32374ae4b618d6c0Andreas Huber LOGI("new range: offset= %lld", offset); 5565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset = offset; 5585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize = mCache->totalSize(); 5605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize); 5615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = OK; 5635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 5645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 5665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 56834ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::resumeFetchingIfNecessary() { 56934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber Mutex::Autolock autoLock(mLock); 57034ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 57134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber restartPrefetcherIfNecessary_l(true /* ignore low water threshold */); 57234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber} 57334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 574b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangsp<DecryptHandle> NuCachedSource2::DrmInitialization() { 575889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang return mSource->DrmInitialization(); 576b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 577b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 578b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangvoid NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) { 579b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang mSource->getDrmInfo(handle, client); 580b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 581b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 582771b85d9245a24273497792a2515d88d31c99e1eGloria WangString8 NuCachedSource2::getUri() { 583771b85d9245a24273497792a2515d88d31c99e1eGloria Wang return mSource->getUri(); 584771b85d9245a24273497792a2515d88d31c99e1eGloria Wang} 585ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber 5866511c9755c3a3360ba869772600c7aae048a7ffcAndreas HuberString8 NuCachedSource2::getMIMEType() const { 5876511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber return mSource->getMIMEType(); 5886511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber} 5896511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber 590a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromSystemProperty() { 591a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber char value[PROPERTY_VALUE_MAX]; 592a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (!property_get("media.stagefright.cache-params", value, NULL)) { 593a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 594a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 595a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 596a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber updateCacheParamsFromString(value); 597a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 598a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 599a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Hubervoid NuCachedSource2::updateCacheParamsFromString(const char *s) { 600a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber ssize_t lowwaterMarkKb, highwaterMarkKb; 601a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber unsigned keepAliveSecs; 602a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 603a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (sscanf(s, "%ld/%ld/%u", 604a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber &lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3 605a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber || lowwaterMarkKb >= highwaterMarkKb) { 606a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber LOGE("Failed to parse cache parameters from '%s'.", s); 607a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber return; 608a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 609a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 610a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (lowwaterMarkKb >= 0) { 611a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = lowwaterMarkKb * 1024; 612a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 613a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes = kDefaultLowWaterThreshold; 614a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 615a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 616a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber if (highwaterMarkKb >= 0) { 617a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = highwaterMarkKb * 1024; 618a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } else { 619a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes = kDefaultHighWaterThreshold; 620a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber } 621a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 622a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mKeepAliveIntervalUs = keepAliveSecs * 1000000ll; 623a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 624a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber LOGV("lowwater = %d bytes, highwater = %d bytes, keepalive = %lld us", 625a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mLowwaterThresholdBytes, 626a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mHighwaterThresholdBytes, 627a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber mKeepAliveIntervalUs); 628a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber} 629a045cb0e77097120e86e367e1cab5494ce2a5d5eAndreas Huber 6305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} // namespace android 631