NuCachedSource2.cpp revision 0683eba6b35c396c21f10e926709f2f8fc05f090
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 245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/ADebug.h> 255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/foundation/AMessage.h> 265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber#include <media/stagefright/MediaErrors.h> 275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 285994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubernamespace android { 295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstruct PageCache { 315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache(size_t pageSize); 325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ~PageCache(); 335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber struct Page { 355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *mData; 365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mSize; 375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber }; 385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *acquirePage(); 405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void releasePage(Page *page); 415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void appendPage(Page *page); 435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t releaseFromStart(size_t maxBytes); 445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize() const { 465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mTotalSize; 475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void copy(size_t from, void *data, size_t size); 505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberprivate: 525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mPageSize; 535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t mTotalSize; 545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mActivePages; 565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *> mFreePages; 575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void freePages(List<Page *> *list); 595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(PageCache); 615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber}; 625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 635994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::PageCache(size_t pageSize) 645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mPageSize(pageSize), 655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize(0) { 665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 685994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::~PageCache() { 695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mActivePages); 705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber freePages(&mFreePages); 715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 735994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::freePages(List<Page *> *list) { 745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = list->begin(); 755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (it != list->end()) { 765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber free(page->mData); 795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete page; 805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page = NULL; 815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 865994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberPageCache::Page *PageCache::acquirePage() { 875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (!mFreePages.empty()) { 885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mFreePages.begin(); 895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.erase(it); 915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = new Page; 965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mData = malloc(mPageSize); 975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return page; 1005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1025994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::releasePage(Page *page) { 1035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = 0; 1045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFreePages.push_back(page); 1055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1075994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::appendPage(Page *page) { 1085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize += page->mSize; 1095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.push_back(page); 1105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1125994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t PageCache::releaseFromStart(size_t maxBytes) { 1135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t bytesReleased = 0; 1145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (maxBytes > 0 && !mActivePages.empty()) { 1165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Page *page = *it; 1195994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (maxBytes < page->mSize) { 1215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 1225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mActivePages.erase(it); 1255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber maxBytes -= page->mSize; 1275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber bytesReleased += page->mSize; 1285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber releasePage(page); 1305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mTotalSize -= bytesReleased; 1335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return bytesReleased; 1345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1365994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid PageCache::copy(size_t from, void *data, size_t size) { 1376e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("copy from %d size %d", from, size); 1385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 139310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber if (size == 0) { 140310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber return; 141310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber } 142310962976d575c0a97ec7a768e9cca0b2361daeaAndreas Huber 1435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_LE(from + size, mTotalSize); 1445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t offset = 0; 1465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber List<Page *>::iterator it = mActivePages.begin(); 1475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (from >= offset + (*it)->mSize) { 1485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber offset += (*it)->mSize; 1495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = from - offset; 1535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t avail = (*it)->mSize - delta; 1545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (avail >= size) { 1565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, size); 1575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 1585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (const uint8_t *)(*it)->mData + delta, avail); 1615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + avail; 1635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= avail; 1645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (size > 0) { 1665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t copy = (*it)->mSize; 1675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (copy > size) { 1685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber copy = size; 1695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber memcpy(data, (*it)->mData, copy); 1715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber data = (uint8_t *)data + copy; 1725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size -= copy; 1735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ++it; 1745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 1755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1795994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::NuCachedSource2(const sp<DataSource> &source) 1805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber : mSource(source), 1815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mReflector(new AHandlerReflector<NuCachedSource2>(this)), 1825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper(new ALooper), 1835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache(new PageCache(kPageSize)), 1845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset(0), 1855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus(OK), 1865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos(0), 187a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mFetching(true), 1880683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mLastFetchTimeUs(-1), 1890683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft(kMaxNumRetries) { 190a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber mLooper->setName("NuCachedSource2"); 1915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->registerHandler(mReflector); 1925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->start(); 1935994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1945994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 1955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(); 1965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 1975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 1985994b4798b01f3dd340577c9ea9657f09093a770Andreas HuberNuCachedSource2::~NuCachedSource2() { 1995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->stop(); 2005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLooper->unregisterHandler(mReflector->id()); 2015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber delete mCache; 2035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache = NULL; 2045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2065b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::getEstimatedBandwidthKbps(int32_t *kbps) { 207b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 208b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase* source = static_cast<HTTPBase *>(mSource.get()); 209b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->getEstimatedBandwidthKbps(kbps); 210b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 211b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2125b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2135b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2145b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t NuCachedSource2::setCacheStatCollectFreq(int32_t freqMs) { 215b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong if (mSource->flags() & kIsHTTPBasedSource) { 216b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong HTTPBase *source = static_cast<HTTPBase *>(mSource.get()); 217b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return source->setBandwidthStatCollectFreq(freqMs); 218b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong } 219b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return ERROR_UNSUPPORTED; 2205b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong} 2215b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong 2225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberstatus_t NuCachedSource2::initCheck() const { 2235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->initCheck(); 2245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 226c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::getSize(off64_t *size) { 2275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mSource->getSize(size); 2285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huberuint32_t NuCachedSource2::flags() { 231b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong // Remove HTTP related flags since NuCachedSource2 is not HTTP-based. 232b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong uint32_t flags = mSource->flags() & ~(kWantsPrefetching | kIsHTTPBasedSource); 233b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong return (flags | kIsCachingDataSource); 2345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2365994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) { 2375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber switch (msg->what()) { 2385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatFetchMore: 2395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onFetch(); 2415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber case kWhatRead: 2455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber { 2465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber onRead(msg); 2475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber break; 2485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber default: 2515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber TRESPASS(); 2525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 2535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 2545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2555994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::fetchInternal() { 2566e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("fetchInternal"); 2575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2580683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber { 2590683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber Mutex::Autolock autoLock(mLock); 2600683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber CHECK(mFinalStatus == OK || mNumRetriesLeft > 0); 2610683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2620683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 2630683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber --mNumRetriesLeft; 2640683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2650683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber status_t err = 2660683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize()); 2670683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2680683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (err == ERROR_UNSUPPORTED) { 2690683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = 0; 2700683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber return; 2710683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else if (err != OK) { 2720683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber LOGI("The attempt to reconnect failed, %d retries remaining", 2730683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft); 2740683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2750683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber return; 2760683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 2770683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 2780683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 2795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber PageCache::Page *page = mCache->acquirePage(); 2815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t n = mSource->readAt( 2835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset + mCache->totalSize(), page->mData, kPageSize); 2845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2855994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 2865994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 2875994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (n < 0) { 2880683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber LOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft); 2895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = n; 2905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 2915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else if (n == 0) { 2926e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("ERROR_END_OF_STREAM"); 2930683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2940683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = 0; 2955994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = ERROR_END_OF_STREAM; 2960683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 2975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->releasePage(page); 2985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } else { 2990683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK) { 3000683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber LOGI("retrying a previously failed read succeeded."); 3010683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3020683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mNumRetriesLeft = kMaxNumRetries; 3030683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber mFinalStatus = OK; 3040683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber page->mSize = n; 3065994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->appendPage(page); 3075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3105994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onFetch() { 3116e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("onFetch"); 3125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3130683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft == 0) { 3146e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("EOS reached, done prefetching for now"); 3155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 3165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 318a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber bool keepAlive = 319a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber !mFetching 320a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber && mFinalStatus == OK 321a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber && ALooper::GetNowUs() >= mLastFetchTimeUs + kKeepAliveIntervalUs; 322a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 323a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (mFetching || keepAlive) { 324a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (keepAlive) { 3256e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("Keep alive"); 326a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber } 327a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 3285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber fetchInternal(); 3295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 330a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber mLastFetchTimeUs = ALooper::GetNowUs(); 331a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber 332a5273ebd1746368662a597643d6701a5046d5c7bAndreas Huber if (mFetching && mCache->totalSize() >= kHighWaterThreshold) { 3336e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("Cache full, done prefetching for now"); 3345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = false; 3355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 336a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } else { 337d17875a226491e3de60fa32d764a4cc92de7f949Andreas Huber Mutex::Autolock autoLock(mLock); 3385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber restartPrefetcherIfNecessary_l(); 3395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3410683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber int64_t delayUs; 3420683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching) { 3430683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 3440683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // We failed this time and will try again in 3 seconds. 3450683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 3000000ll; 3460683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 3470683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 0; 3480683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3490683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } else { 3500683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber delayUs = 100000ll; 3510683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 3520683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 3530683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs); 3545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3565994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubervoid NuCachedSource2::onRead(const sp<AMessage> &msg) { 3576e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("onRead"); 3585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int64_t offset; 3605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findInt64("offset", &offset)); 3615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber void *data; 3635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findPointer("data", &data)); 3645994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t size; 3665994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(msg->findSize("size", &size)); 3675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber ssize_t result = readInternal(offset, data, size); 3695994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3705994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result == -EAGAIN) { 3715994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(50000); 3725994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 3735994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3745994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3755994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 3765994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3775994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 3785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult = new AMessage; 3805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult->setInt32("result", result); 3815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.signal(); 3835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 3845994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 38534ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::restartPrefetcherIfNecessary_l( 3867bf8413f91fc072452f315a91618aeef2574d420Andreas Huber bool ignoreLowWaterThreshold, bool force) { 3876ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const size_t kGrayArea = 1024 * 1024; 3885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3890683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) { 3905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 3915994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3925994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3937bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!ignoreLowWaterThreshold && !force 39434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber && mCacheOffset + mCache->totalSize() - mLastAccessPos 39534ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber >= kLowWaterThreshold) { 3965994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return; 3975994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 3985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 3995994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t maxBytes = mLastAccessPos - mCacheOffset; 4005994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4017bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!force) { 4027bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (maxBytes < kGrayArea) { 4037bf8413f91fc072452f315a91618aeef2574d420Andreas Huber return; 4047bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4057bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 4067bf8413f91fc072452f315a91618aeef2574d420Andreas Huber maxBytes -= kGrayArea; 4077bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t actualBytes = mCache->releaseFromStart(maxBytes); 4105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset += actualBytes; 4115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4126e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGI("restarting prefetcher, totalSize = %d", mCache->totalSize()); 4135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 4145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 416c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) { 4175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoSerializer(mSerializer); 4185994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 419145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber LOGV("readAt offset %lld, size %d", offset, size); 4205994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4215994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4225994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4235994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // If the request can be completely satisfied from the cache, do so. 4245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 4265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber && offset + size <= mCacheOffset + mCache->totalSize()) { 4275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 4285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 4295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + size; 4315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 4335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4355994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber sp<AMessage> msg = new AMessage(kWhatRead, mReflector->id()); 4365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setInt64("offset", offset); 4375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setPointer("data", data); 4385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->setSize("size", size); 4395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4405994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult == NULL); 4415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber msg->post(); 4425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber while (mAsyncResult == NULL) { 4445994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCondition.wait(mLock); 4455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber int32_t result; 4485994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK(mAsyncResult->findInt32("result", &result)); 4495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mAsyncResult.clear(); 4515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (result > 0) { 4535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset + result; 4545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return (ssize_t)result; 4575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4595994b4798b01f3dd340577c9ea9657f09093a770Andreas Hubersize_t NuCachedSource2::cachedSize() { 4605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4615994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mCacheOffset + mCache->totalSize(); 4625994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4635994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4641bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinneysize_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) { 4655994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4661bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney return approxDataRemaining_l(finalStatus); 4675994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4685994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4691bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinneysize_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) { 4701bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney *finalStatus = mFinalStatus; 4710683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 4720683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber if (mFinalStatus != OK && mNumRetriesLeft > 0) { 4730683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber // Pretend that everything is fine until we're out of retries. 4740683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber *finalStatus = OK; 4750683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber } 4760683eba6b35c396c21f10e926709f2f8fc05f090Andreas Huber 477c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t lastBytePosCached = mCacheOffset + mCache->totalSize(); 4785994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mLastAccessPos < lastBytePosCached) { 4795994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return lastBytePosCached - mLastAccessPos; 4805994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 4815994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return 0; 4825994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 4835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 484c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) { 4857bf8413f91fc072452f315a91618aeef2574d420Andreas Huber CHECK_LE(size, (size_t)kHighWaterThreshold); 4867bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 487145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber LOGV("readInternal offset %lld size %d", offset, size); 4885994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4895994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber Mutex::Autolock autoLock(mLock); 4905994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 4917bf8413f91fc072452f315a91618aeef2574d420Andreas Huber if (!mFetching) { 4927bf8413f91fc072452f315a91618aeef2574d420Andreas Huber mLastAccessPos = offset; 4937bf8413f91fc072452f315a91618aeef2574d420Andreas Huber restartPrefetcherIfNecessary_l( 4947bf8413f91fc072452f315a91618aeef2574d420Andreas Huber false, // ignoreLowWaterThreshold 4957bf8413f91fc072452f315a91618aeef2574d420Andreas Huber true); // force 4967bf8413f91fc072452f315a91618aeef2574d420Andreas Huber } 4977bf8413f91fc072452f315a91618aeef2574d420Andreas Huber 4985994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset < mCacheOffset 499c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong || offset >= (off64_t)(mCacheOffset + mCache->totalSize())) { 5006ee94582e3ce7bdd9625345e7564e3176a51a2f3James Dong static const off64_t kPadding = 256 * 1024; 5015994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5025994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // In the presence of multiple decoded streams, once of them will 5035994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // trigger this seek request, the other one will request data "nearby" 5045994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // soon, adjust the seek position so that that subsequent request 5055994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber // does not trigger another seek. 506c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t seekOffset = (offset > kPadding) ? offset - kPadding : 0; 5075994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5085994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber seekInternal_l(seekOffset); 5095994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5105994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5115994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t delta = offset - mCacheOffset; 5125994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5135994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (mFinalStatus != OK) { 5145994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (delta >= mCache->totalSize()) { 5155994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return mFinalStatus; 5165994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5175994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5186f5aae1bcba130d5b8092a19fca3627aa565df56Andreas Huber size_t avail = mCache->totalSize() - delta; 51967802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 52067802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber if (avail > size) { 52167802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber avail = size; 52267802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber } 52367802977b6f0aa8d6f14f85dadcf32a3cadb9c07Andreas Huber 5245994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, avail); 5255994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5265994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return avail; 5275994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5285994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5295994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset + size <= mCacheOffset + mCache->totalSize()) { 5305994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCache->copy(delta, data, size); 5315994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5325994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return size; 5335994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5345994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5356e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber LOGV("deferring read"); 5365994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5375994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return -EAGAIN; 5385994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5395994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 540c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t NuCachedSource2::seekInternal_l(off64_t offset) { 5415994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mLastAccessPos = offset; 5425994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5435994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber if (offset >= mCacheOffset 544c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong && offset <= (off64_t)(mCacheOffset + mCache->totalSize())) { 5455994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 5465994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber } 5475994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5487fe4ed1207fa587c65231f9a32374ae4b618d6c0Andreas Huber LOGI("new range: offset= %lld", offset); 5495994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5505994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mCacheOffset = offset; 5515994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5525994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber size_t totalSize = mCache->totalSize(); 5535994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize); 5545994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5555994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFinalStatus = OK; 5565994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber mFetching = true; 5575994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 5585994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber return OK; 5595994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} 5605994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber 56134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid NuCachedSource2::resumeFetchingIfNecessary() { 56234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber Mutex::Autolock autoLock(mLock); 56334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 56434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber restartPrefetcherIfNecessary_l(true /* ignore low water threshold */); 56534ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber} 56634ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber 567b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangsp<DecryptHandle> NuCachedSource2::DrmInitialization() { 568889b340ec736a9d3e3e690256d305cc8740f0c4bGloria Wang return mSource->DrmInitialization(); 569b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 570b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 571b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wangvoid NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) { 572b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang mSource->getDrmInfo(handle, client); 573b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang} 574b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang 575771b85d9245a24273497792a2515d88d31c99e1eGloria WangString8 NuCachedSource2::getUri() { 576771b85d9245a24273497792a2515d88d31c99e1eGloria Wang return mSource->getUri(); 577771b85d9245a24273497792a2515d88d31c99e1eGloria Wang} 578ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber 5796511c9755c3a3360ba869772600c7aae048a7ffcAndreas HuberString8 NuCachedSource2::getMIMEType() const { 5806511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber return mSource->getMIMEType(); 5816511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber} 5826511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber 5835994b4798b01f3dd340577c9ea9657f09093a770Andreas Huber} // namespace android 584