CallbackDataSource.cpp revision da7e453e1d1c77959822cf9602ddfed1c50be445
1/* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "CallbackDataSource" 19#include <utils/Log.h> 20 21#include "include/CallbackDataSource.h" 22 23#include <binder/IMemory.h> 24#include <media/IDataSource.h> 25#include <media/stagefright/foundation/ADebug.h> 26 27#include <algorithm> 28 29namespace android { 30 31CallbackDataSource::CallbackDataSource( 32 const sp<IDataSource>& binderDataSource) 33 : mIDataSource(binderDataSource) { 34 // Set up the buffer to read into. 35 mMemory = mIDataSource->getIMemory(); 36} 37 38CallbackDataSource::~CallbackDataSource() { 39 ALOGV("~CallbackDataSource"); 40 mIDataSource->close(); 41} 42 43status_t CallbackDataSource::initCheck() const { 44 if (mMemory == NULL) { 45 return UNKNOWN_ERROR; 46 } 47 return OK; 48} 49 50ssize_t CallbackDataSource::readAt(off64_t offset, void* data, size_t size) { 51 if (mMemory == NULL) { 52 return -1; 53 } 54 55 // IDataSource can only read up to mMemory->size() bytes at a time, but this 56 // method should be able to read any number of bytes, so read in a loop. 57 size_t totalNumRead = 0; 58 size_t numLeft = size; 59 const size_t bufferSize = mMemory->size(); 60 61 while (numLeft > 0) { 62 size_t numToRead = std::min(numLeft, bufferSize); 63 ssize_t numRead = 64 mIDataSource->readAt(offset + totalNumRead, numToRead); 65 // A negative return value represents an error. Pass it on. 66 if (numRead < 0) { 67 return numRead; 68 } 69 // A zero return value signals EOS. Return the bytes read so far. 70 if (numRead == 0) { 71 return totalNumRead; 72 } 73 if ((size_t)numRead > numToRead) { 74 return ERROR_OUT_OF_RANGE; 75 } 76 CHECK(numRead >= 0 && (size_t)numRead <= bufferSize); 77 memcpy(((uint8_t*)data) + totalNumRead, mMemory->pointer(), numRead); 78 numLeft -= numRead; 79 totalNumRead += numRead; 80 } 81 82 return totalNumRead; 83} 84 85status_t CallbackDataSource::getSize(off64_t *size) { 86 status_t err = mIDataSource->getSize(size); 87 if (err != OK) { 88 return err; 89 } 90 if (*size < 0) { 91 // IDataSource will set size to -1 to indicate unknown size, but 92 // DataSource returns ERROR_UNSUPPORTED for that. 93 return ERROR_UNSUPPORTED; 94 } 95 return OK; 96} 97 98TinyCacheSource::TinyCacheSource(const sp<DataSource>& source) 99 : mSource(source), mCachedOffset(0), mCachedSize(0) { 100} 101 102status_t TinyCacheSource::initCheck() const { 103 return mSource->initCheck(); 104} 105 106ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) { 107 if (size >= kCacheSize) { 108 return mSource->readAt(offset, data, size); 109 } 110 111 // Check if the cache satisfies the read. 112 if (offset >= mCachedOffset && offset + size <= mCachedOffset + mCachedSize) { 113 memcpy(data, &mCache[offset - mCachedOffset], size); 114 return size; 115 } 116 117 // Fill the cache and copy to the caller. 118 const ssize_t numRead = mSource->readAt(offset, mCache, kCacheSize); 119 if (numRead <= 0) { 120 return numRead; 121 } 122 if ((size_t)numRead > kCacheSize) { 123 return ERROR_OUT_OF_RANGE; 124 } 125 126 mCachedSize = numRead; 127 mCachedOffset = offset; 128 CHECK(mCachedSize <= kCacheSize && mCachedOffset >= 0); 129 const size_t numToReturn = std::min(size, (size_t)numRead); 130 memcpy(data, mCache, numToReturn); 131 132 return numToReturn; 133} 134 135status_t TinyCacheSource::getSize(off64_t *size) { 136 return mSource->getSize(size); 137} 138 139uint32_t TinyCacheSource::flags() { 140 return mSource->flags(); 141} 142 143} // namespace android 144