RemoteDataSource.h revision 009ff0dd59732f0c389d172edb26942c35422e3a
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/IDataSource.h>
23#include <media/stagefright/DataSource.h>
24
25namespace android {
26
27// Originally in MediaExtractor.cpp
28class RemoteDataSource : public BnDataSource {
29public:
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
40    virtual ~RemoteDataSource() {
41        close();
42    }
43    virtual sp<IMemory> getIMemory() {
44        return mMemory;
45    }
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    }
53    virtual status_t getSize(off64_t *size) {
54        return mSource->getSize(size);
55    }
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    }
63    virtual uint32_t getFlags() {
64        return mSource->flags();
65    }
66    virtual String8 toString()  {
67        return mName;
68    }
69    virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
70        return mSource->DrmInitialization(mime);
71    }
72
73private:
74    enum {
75        kBufferSize = 64 * 1024,
76    };
77
78    sp<IMemory> mMemory;
79    sp<DataSource> mSource;
80    String8 mName;
81    Mutex mCloseLock;
82
83    explicit RemoteDataSource(const sp<DataSource> &source) {
84        mSource = source;
85        sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource");
86        mMemory = memoryDealer->allocate(kBufferSize);
87        if (mMemory.get() == nullptr) {
88            ALOGE("Failed to allocate memory!");
89        }
90        mName = String8::format("RemoteDataSource(%s)", mSource->toString().string());
91    }
92
93    DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
94};
95
96}  // namespace android
97
98#endif  // REMOTE_DATA_SOURCE_H_
99