1 /* 2 * Copyright 2016, 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 #ifndef REMOTE_DATA_SOURCE_H_ 18 #define REMOTE_DATA_SOURCE_H_ 19 20 #include <binder/IMemory.h> 21 #include <binder/MemoryDealer.h> 22 #include <media/DataSource.h> 23 #include <media/IDataSource.h> 24 25 namespace android { 26 27 // Originally in MediaExtractor.cpp 28 class RemoteDataSource : public BnDataSource { 29 public: wrap(const sp<DataSource> & source)30 static sp<IDataSource> wrap(const sp<DataSource> &source) { 31 if (source.get() == nullptr) { 32 return nullptr; 33 } 34 if (source->getIDataSource().get() != nullptr) { 35 return source->getIDataSource(); 36 } 37 return new RemoteDataSource(source); 38 } 39 ~RemoteDataSource()40 virtual ~RemoteDataSource() { 41 close(); 42 } getIMemory()43 virtual sp<IMemory> getIMemory() { 44 return mMemory; 45 } readAt(off64_t offset,size_t size)46 virtual ssize_t readAt(off64_t offset, size_t size) { 47 ALOGV("readAt(%lld, %zu)", (long long)offset, size); 48 if (size > kBufferSize) { 49 size = kBufferSize; 50 } 51 return mSource->readAt(offset, mMemory->pointer(), size); 52 } getSize(off64_t * size)53 virtual status_t getSize(off64_t *size) { 54 return mSource->getSize(size); 55 } close()56 virtual void close() { 57 // Protect strong pointer assignments. This also can be called from the binder 58 // clean-up procedure which is running on a separate thread. 59 Mutex::Autolock lock(mCloseLock); 60 mSource = nullptr; 61 mMemory = nullptr; 62 } getFlags()63 virtual uint32_t getFlags() { 64 return mSource->flags(); 65 } toString()66 virtual String8 toString() { 67 return mName; 68 } 69 70 private: 71 enum { 72 kBufferSize = 64 * 1024, 73 }; 74 75 sp<IMemory> mMemory; 76 sp<DataSource> mSource; 77 String8 mName; 78 Mutex mCloseLock; 79 RemoteDataSource(const sp<DataSource> & source)80 explicit RemoteDataSource(const sp<DataSource> &source) { 81 mSource = source; 82 sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource"); 83 mMemory = memoryDealer->allocate(kBufferSize); 84 if (mMemory.get() == nullptr) { 85 ALOGE("Failed to allocate memory!"); 86 } 87 mName = String8::format("RemoteDataSource(%s)", mSource->toString().string()); 88 } 89 90 DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource); 91 }; 92 93 } // namespace android 94 95 #endif // REMOTE_DATA_SOURCE_H_ 96