blob: c91ddfcee3c317291afdef12d24ecda82b33ac81 [file] [log] [blame]
/*
* Copyright 2016, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef REMOTE_DATA_SOURCE_H_
#define REMOTE_DATA_SOURCE_H_
#include <binder/IMemory.h>
#include <binder/MemoryDealer.h>
#include <media/IDataSource.h>
#include <media/stagefright/DataSource.h>
namespace android {
// Originally in MediaExtractor.cpp
class RemoteDataSource : public BnDataSource {
public:
static sp<IDataSource> wrap(const sp<DataSource> &source) {
if (source.get() == nullptr) {
return nullptr;
}
if (source->getIDataSource().get() != nullptr) {
return source->getIDataSource();
}
return new RemoteDataSource(source);
}
virtual ~RemoteDataSource() {
close();
}
virtual sp<IMemory> getIMemory() {
return mMemory;
}
virtual ssize_t readAt(off64_t offset, size_t size) {
ALOGV("readAt(%lld, %zu)", (long long)offset, size);
if (size > kBufferSize) {
size = kBufferSize;
}
return mSource->readAt(offset, mMemory->pointer(), size);
}
virtual status_t getSize(off64_t *size) {
return mSource->getSize(size);
}
virtual void close() {
// Protect strong pointer assignments. This also can be called from the binder
// clean-up procedure which is running on a separate thread.
Mutex::Autolock lock(mCloseLock);
mSource = nullptr;
mMemory = nullptr;
}
virtual uint32_t getFlags() {
return mSource->flags();
}
virtual String8 toString() {
return mName;
}
virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
return mSource->DrmInitialization(mime);
}
private:
enum {
kBufferSize = 64 * 1024,
};
sp<IMemory> mMemory;
sp<DataSource> mSource;
String8 mName;
Mutex mCloseLock;
explicit RemoteDataSource(const sp<DataSource> &source) {
mSource = source;
sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource");
mMemory = memoryDealer->allocate(kBufferSize);
if (mMemory.get() == nullptr) {
ALOGE("Failed to allocate memory!");
}
mName = String8::format("RemoteDataSource(%s)", mSource->toString().string());
}
DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
};
} // namespace android
#endif // REMOTE_DATA_SOURCE_H_