1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #ifndef MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker #define MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include <arpa/inet.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <stdio.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <map>
24*ec779b8eSAndroid Build Coastguard Worker
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/Errors.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <utils/RefBase.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaExtractorPluginApi.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/NdkMediaFormat.h>
30*ec779b8eSAndroid Build Coastguard Worker
31*ec779b8eSAndroid Build Coastguard Worker namespace android {
32*ec779b8eSAndroid Build Coastguard Worker
33*ec779b8eSAndroid Build Coastguard Worker class DataSourceBase;
34*ec779b8eSAndroid Build Coastguard Worker class MetaDataBase;
35*ec779b8eSAndroid Build Coastguard Worker struct MediaTrack;
36*ec779b8eSAndroid Build Coastguard Worker
37*ec779b8eSAndroid Build Coastguard Worker
38*ec779b8eSAndroid Build Coastguard Worker class MediaTrackHelper;
39*ec779b8eSAndroid Build Coastguard Worker
40*ec779b8eSAndroid Build Coastguard Worker class MediaBufferHelper {
41*ec779b8eSAndroid Build Coastguard Worker private:
42*ec779b8eSAndroid Build Coastguard Worker friend CMediaTrack *wrap(MediaTrackHelper *);
43*ec779b8eSAndroid Build Coastguard Worker CMediaBuffer *mBuffer;
44*ec779b8eSAndroid Build Coastguard Worker public:
MediaBufferHelper(CMediaBuffer * buf)45*ec779b8eSAndroid Build Coastguard Worker MediaBufferHelper(CMediaBuffer *buf) {
46*ec779b8eSAndroid Build Coastguard Worker mBuffer = buf;
47*ec779b8eSAndroid Build Coastguard Worker }
48*ec779b8eSAndroid Build Coastguard Worker
~MediaBufferHelper()49*ec779b8eSAndroid Build Coastguard Worker virtual ~MediaBufferHelper() {}
50*ec779b8eSAndroid Build Coastguard Worker
release()51*ec779b8eSAndroid Build Coastguard Worker virtual void release() {
52*ec779b8eSAndroid Build Coastguard Worker mBuffer->release(mBuffer->handle);
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
data()55*ec779b8eSAndroid Build Coastguard Worker virtual void* data() {
56*ec779b8eSAndroid Build Coastguard Worker return mBuffer->data(mBuffer->handle);
57*ec779b8eSAndroid Build Coastguard Worker }
58*ec779b8eSAndroid Build Coastguard Worker
size()59*ec779b8eSAndroid Build Coastguard Worker virtual size_t size() {
60*ec779b8eSAndroid Build Coastguard Worker return mBuffer->size(mBuffer->handle);
61*ec779b8eSAndroid Build Coastguard Worker }
62*ec779b8eSAndroid Build Coastguard Worker
range_offset()63*ec779b8eSAndroid Build Coastguard Worker virtual size_t range_offset() {
64*ec779b8eSAndroid Build Coastguard Worker return mBuffer->range_offset(mBuffer->handle);
65*ec779b8eSAndroid Build Coastguard Worker }
66*ec779b8eSAndroid Build Coastguard Worker
range_length()67*ec779b8eSAndroid Build Coastguard Worker virtual size_t range_length() {
68*ec779b8eSAndroid Build Coastguard Worker return mBuffer->range_length(mBuffer->handle);
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker
set_range(size_t offset,size_t length)71*ec779b8eSAndroid Build Coastguard Worker virtual void set_range(size_t offset, size_t length) {
72*ec779b8eSAndroid Build Coastguard Worker mBuffer->set_range(mBuffer->handle, offset, length);
73*ec779b8eSAndroid Build Coastguard Worker }
meta_data()74*ec779b8eSAndroid Build Coastguard Worker virtual AMediaFormat *meta_data() {
75*ec779b8eSAndroid Build Coastguard Worker return mBuffer->meta_data(mBuffer->handle);
76*ec779b8eSAndroid Build Coastguard Worker }
77*ec779b8eSAndroid Build Coastguard Worker };
78*ec779b8eSAndroid Build Coastguard Worker
79*ec779b8eSAndroid Build Coastguard Worker class MediaBufferGroupHelper {
80*ec779b8eSAndroid Build Coastguard Worker private:
81*ec779b8eSAndroid Build Coastguard Worker CMediaBufferGroup *mGroup;
82*ec779b8eSAndroid Build Coastguard Worker std::map<CMediaBuffer*, MediaBufferHelper*> mBufferHelpers;
83*ec779b8eSAndroid Build Coastguard Worker public:
MediaBufferGroupHelper(CMediaBufferGroup * group)84*ec779b8eSAndroid Build Coastguard Worker MediaBufferGroupHelper(CMediaBufferGroup *group) {
85*ec779b8eSAndroid Build Coastguard Worker mGroup = group;
86*ec779b8eSAndroid Build Coastguard Worker }
~MediaBufferGroupHelper()87*ec779b8eSAndroid Build Coastguard Worker ~MediaBufferGroupHelper() {
88*ec779b8eSAndroid Build Coastguard Worker // delete all entries in map
89*ec779b8eSAndroid Build Coastguard Worker ALOGV("buffergroup %p map has %zu entries", this, mBufferHelpers.size());
90*ec779b8eSAndroid Build Coastguard Worker for (auto it = mBufferHelpers.begin(); it != mBufferHelpers.end(); ++it) {
91*ec779b8eSAndroid Build Coastguard Worker delete it->second;
92*ec779b8eSAndroid Build Coastguard Worker }
93*ec779b8eSAndroid Build Coastguard Worker }
94*ec779b8eSAndroid Build Coastguard Worker bool init(size_t buffers, size_t buffer_size, size_t growthLimit = 0) {
95*ec779b8eSAndroid Build Coastguard Worker return mGroup->init(mGroup->handle, buffers, buffer_size, growthLimit);
96*ec779b8eSAndroid Build Coastguard Worker }
add_buffer(size_t size)97*ec779b8eSAndroid Build Coastguard Worker void add_buffer(size_t size) {
98*ec779b8eSAndroid Build Coastguard Worker mGroup->add_buffer(mGroup->handle, size);
99*ec779b8eSAndroid Build Coastguard Worker }
100*ec779b8eSAndroid Build Coastguard Worker media_status_t acquire_buffer(
101*ec779b8eSAndroid Build Coastguard Worker MediaBufferHelper **buffer, bool nonBlocking = false, size_t requestedSize = 0) {
102*ec779b8eSAndroid Build Coastguard Worker CMediaBuffer *buf = nullptr;
103*ec779b8eSAndroid Build Coastguard Worker media_status_t ret =
104*ec779b8eSAndroid Build Coastguard Worker mGroup->acquire_buffer(mGroup->handle, &buf, nonBlocking, requestedSize);
105*ec779b8eSAndroid Build Coastguard Worker if (ret == AMEDIA_OK && buf != nullptr) {
106*ec779b8eSAndroid Build Coastguard Worker auto helper = mBufferHelpers.find(buf);
107*ec779b8eSAndroid Build Coastguard Worker if (helper == mBufferHelpers.end()) {
108*ec779b8eSAndroid Build Coastguard Worker MediaBufferHelper* newHelper = new MediaBufferHelper(buf);
109*ec779b8eSAndroid Build Coastguard Worker mBufferHelpers.insert(std::make_pair(buf, newHelper));
110*ec779b8eSAndroid Build Coastguard Worker *buffer = newHelper;
111*ec779b8eSAndroid Build Coastguard Worker } else {
112*ec779b8eSAndroid Build Coastguard Worker *buffer = helper->second;
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker } else {
115*ec779b8eSAndroid Build Coastguard Worker *buffer = nullptr;
116*ec779b8eSAndroid Build Coastguard Worker }
117*ec779b8eSAndroid Build Coastguard Worker return ret;
118*ec779b8eSAndroid Build Coastguard Worker }
has_buffers()119*ec779b8eSAndroid Build Coastguard Worker bool has_buffers() {
120*ec779b8eSAndroid Build Coastguard Worker return mGroup->has_buffers(mGroup->handle);
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker };
123*ec779b8eSAndroid Build Coastguard Worker
124*ec779b8eSAndroid Build Coastguard Worker class MediaTrackHelper {
125*ec779b8eSAndroid Build Coastguard Worker public:
MediaTrackHelper()126*ec779b8eSAndroid Build Coastguard Worker MediaTrackHelper() : mBufferGroup(nullptr) {
127*ec779b8eSAndroid Build Coastguard Worker }
~MediaTrackHelper()128*ec779b8eSAndroid Build Coastguard Worker virtual ~MediaTrackHelper() {
129*ec779b8eSAndroid Build Coastguard Worker delete mBufferGroup;
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t start() = 0;
132*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t stop() = 0;
133*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t getFormat(AMediaFormat *format) = 0;
134*ec779b8eSAndroid Build Coastguard Worker
135*ec779b8eSAndroid Build Coastguard Worker class ReadOptions {
136*ec779b8eSAndroid Build Coastguard Worker public:
137*ec779b8eSAndroid Build Coastguard Worker enum SeekMode : int32_t {
138*ec779b8eSAndroid Build Coastguard Worker SEEK_PREVIOUS_SYNC,
139*ec779b8eSAndroid Build Coastguard Worker SEEK_NEXT_SYNC,
140*ec779b8eSAndroid Build Coastguard Worker SEEK_CLOSEST_SYNC,
141*ec779b8eSAndroid Build Coastguard Worker SEEK_CLOSEST,
142*ec779b8eSAndroid Build Coastguard Worker SEEK_FRAME_INDEX,
143*ec779b8eSAndroid Build Coastguard Worker };
144*ec779b8eSAndroid Build Coastguard Worker
ReadOptions(uint32_t options,int64_t seekPosUs)145*ec779b8eSAndroid Build Coastguard Worker ReadOptions(uint32_t options, int64_t seekPosUs) {
146*ec779b8eSAndroid Build Coastguard Worker mOptions = options;
147*ec779b8eSAndroid Build Coastguard Worker mSeekPosUs = seekPosUs;
148*ec779b8eSAndroid Build Coastguard Worker }
getSeekTo(int64_t * time_us,SeekMode * mode)149*ec779b8eSAndroid Build Coastguard Worker bool getSeekTo(int64_t *time_us, SeekMode *mode) const {
150*ec779b8eSAndroid Build Coastguard Worker if ((mOptions & CMediaTrackReadOptions::SEEK) == 0) {
151*ec779b8eSAndroid Build Coastguard Worker return false;
152*ec779b8eSAndroid Build Coastguard Worker }
153*ec779b8eSAndroid Build Coastguard Worker *time_us = mSeekPosUs;
154*ec779b8eSAndroid Build Coastguard Worker *mode = (SeekMode) (mOptions & 7);
155*ec779b8eSAndroid Build Coastguard Worker return true;
156*ec779b8eSAndroid Build Coastguard Worker }
getNonBlocking()157*ec779b8eSAndroid Build Coastguard Worker bool getNonBlocking() const {
158*ec779b8eSAndroid Build Coastguard Worker return mOptions & CMediaTrackReadOptions::NONBLOCKING;
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker private:
161*ec779b8eSAndroid Build Coastguard Worker uint32_t mOptions;
162*ec779b8eSAndroid Build Coastguard Worker int64_t mSeekPosUs;
163*ec779b8eSAndroid Build Coastguard Worker };
164*ec779b8eSAndroid Build Coastguard Worker
165*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t read(
166*ec779b8eSAndroid Build Coastguard Worker MediaBufferHelper **buffer, const ReadOptions *options = NULL) = 0;
supportsNonBlockingRead()167*ec779b8eSAndroid Build Coastguard Worker virtual bool supportsNonBlockingRead() { return false; }
168*ec779b8eSAndroid Build Coastguard Worker protected:
169*ec779b8eSAndroid Build Coastguard Worker friend CMediaTrack *wrap(MediaTrackHelper *track);
170*ec779b8eSAndroid Build Coastguard Worker MediaBufferGroupHelper *mBufferGroup;
171*ec779b8eSAndroid Build Coastguard Worker };
172*ec779b8eSAndroid Build Coastguard Worker
wrap(MediaTrackHelper * track)173*ec779b8eSAndroid Build Coastguard Worker inline CMediaTrack *wrap(MediaTrackHelper *track) {
174*ec779b8eSAndroid Build Coastguard Worker if (track == nullptr) {
175*ec779b8eSAndroid Build Coastguard Worker return nullptr;
176*ec779b8eSAndroid Build Coastguard Worker }
177*ec779b8eSAndroid Build Coastguard Worker CMediaTrack *wrapper = (CMediaTrack*) malloc(sizeof(CMediaTrack));
178*ec779b8eSAndroid Build Coastguard Worker wrapper->data = track;
179*ec779b8eSAndroid Build Coastguard Worker wrapper->free = [](void *data) -> void {
180*ec779b8eSAndroid Build Coastguard Worker delete (MediaTrackHelper*)(data);
181*ec779b8eSAndroid Build Coastguard Worker };
182*ec779b8eSAndroid Build Coastguard Worker wrapper->start = [](void *data, CMediaBufferGroup *bufferGroup) -> media_status_t {
183*ec779b8eSAndroid Build Coastguard Worker if (((MediaTrackHelper*)data)->mBufferGroup) {
184*ec779b8eSAndroid Build Coastguard Worker // this shouldn't happen, but handle it anyway
185*ec779b8eSAndroid Build Coastguard Worker delete ((MediaTrackHelper*)data)->mBufferGroup;
186*ec779b8eSAndroid Build Coastguard Worker }
187*ec779b8eSAndroid Build Coastguard Worker ((MediaTrackHelper*)data)->mBufferGroup = new MediaBufferGroupHelper(bufferGroup);
188*ec779b8eSAndroid Build Coastguard Worker return ((MediaTrackHelper*)data)->start();
189*ec779b8eSAndroid Build Coastguard Worker };
190*ec779b8eSAndroid Build Coastguard Worker wrapper->stop = [](void *data) -> media_status_t {
191*ec779b8eSAndroid Build Coastguard Worker return ((MediaTrackHelper*)data)->stop();
192*ec779b8eSAndroid Build Coastguard Worker };
193*ec779b8eSAndroid Build Coastguard Worker wrapper->getFormat = [](void *data, AMediaFormat *meta) -> media_status_t {
194*ec779b8eSAndroid Build Coastguard Worker return ((MediaTrackHelper*)data)->getFormat(meta);
195*ec779b8eSAndroid Build Coastguard Worker };
196*ec779b8eSAndroid Build Coastguard Worker wrapper->read = [](void *data, CMediaBuffer **buffer, uint32_t options, int64_t seekPosUs)
197*ec779b8eSAndroid Build Coastguard Worker -> media_status_t {
198*ec779b8eSAndroid Build Coastguard Worker MediaTrackHelper::ReadOptions opts(options, seekPosUs);
199*ec779b8eSAndroid Build Coastguard Worker MediaBufferHelper *buf = NULL;
200*ec779b8eSAndroid Build Coastguard Worker media_status_t ret = ((MediaTrackHelper*)data)->read(&buf, &opts);
201*ec779b8eSAndroid Build Coastguard Worker if (ret == AMEDIA_OK && buf != nullptr) {
202*ec779b8eSAndroid Build Coastguard Worker *buffer = buf->mBuffer;
203*ec779b8eSAndroid Build Coastguard Worker }
204*ec779b8eSAndroid Build Coastguard Worker return ret;
205*ec779b8eSAndroid Build Coastguard Worker };
206*ec779b8eSAndroid Build Coastguard Worker wrapper->supportsNonBlockingRead = [](void *data) -> bool {
207*ec779b8eSAndroid Build Coastguard Worker return ((MediaTrackHelper*)data)->supportsNonBlockingRead();
208*ec779b8eSAndroid Build Coastguard Worker };
209*ec779b8eSAndroid Build Coastguard Worker return wrapper;
210*ec779b8eSAndroid Build Coastguard Worker }
211*ec779b8eSAndroid Build Coastguard Worker
212*ec779b8eSAndroid Build Coastguard Worker
213*ec779b8eSAndroid Build Coastguard Worker // extractor plugins can derive from this class which looks remarkably
214*ec779b8eSAndroid Build Coastguard Worker // like MediaExtractor and can be easily wrapped in the required C API
215*ec779b8eSAndroid Build Coastguard Worker class MediaExtractorPluginHelper
216*ec779b8eSAndroid Build Coastguard Worker {
217*ec779b8eSAndroid Build Coastguard Worker public:
~MediaExtractorPluginHelper()218*ec779b8eSAndroid Build Coastguard Worker virtual ~MediaExtractorPluginHelper() {}
219*ec779b8eSAndroid Build Coastguard Worker virtual size_t countTracks() = 0;
220*ec779b8eSAndroid Build Coastguard Worker virtual MediaTrackHelper *getTrack(size_t index) = 0;
221*ec779b8eSAndroid Build Coastguard Worker
222*ec779b8eSAndroid Build Coastguard Worker enum GetTrackMetaDataFlags {
223*ec779b8eSAndroid Build Coastguard Worker kIncludeExtensiveMetaData = 1
224*ec779b8eSAndroid Build Coastguard Worker };
225*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t getTrackMetaData(
226*ec779b8eSAndroid Build Coastguard Worker AMediaFormat *meta,
227*ec779b8eSAndroid Build Coastguard Worker size_t index, uint32_t flags = 0) = 0;
228*ec779b8eSAndroid Build Coastguard Worker
229*ec779b8eSAndroid Build Coastguard Worker // Return container specific meta-data. The default implementation
230*ec779b8eSAndroid Build Coastguard Worker // returns an empty metadata object.
231*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t getMetaData(AMediaFormat *meta) = 0;
232*ec779b8eSAndroid Build Coastguard Worker
233*ec779b8eSAndroid Build Coastguard Worker enum Flags {
234*ec779b8eSAndroid Build Coastguard Worker CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
235*ec779b8eSAndroid Build Coastguard Worker CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
236*ec779b8eSAndroid Build Coastguard Worker CAN_PAUSE = 4,
237*ec779b8eSAndroid Build Coastguard Worker CAN_SEEK = 8, // the "seek bar"
238*ec779b8eSAndroid Build Coastguard Worker };
239*ec779b8eSAndroid Build Coastguard Worker
240*ec779b8eSAndroid Build Coastguard Worker // If subclasses do _not_ override this, the default is
241*ec779b8eSAndroid Build Coastguard Worker // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
flags()242*ec779b8eSAndroid Build Coastguard Worker virtual uint32_t flags() const {
243*ec779b8eSAndroid Build Coastguard Worker return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE;
244*ec779b8eSAndroid Build Coastguard Worker };
245*ec779b8eSAndroid Build Coastguard Worker
setMediaCas(const uint8_t *,size_t)246*ec779b8eSAndroid Build Coastguard Worker virtual media_status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
247*ec779b8eSAndroid Build Coastguard Worker return AMEDIA_ERROR_INVALID_OPERATION;
248*ec779b8eSAndroid Build Coastguard Worker }
249*ec779b8eSAndroid Build Coastguard Worker
name()250*ec779b8eSAndroid Build Coastguard Worker virtual const char * name() { return "<unspecified>"; }
251*ec779b8eSAndroid Build Coastguard Worker
252*ec779b8eSAndroid Build Coastguard Worker protected:
MediaExtractorPluginHelper()253*ec779b8eSAndroid Build Coastguard Worker MediaExtractorPluginHelper() {}
254*ec779b8eSAndroid Build Coastguard Worker
255*ec779b8eSAndroid Build Coastguard Worker private:
256*ec779b8eSAndroid Build Coastguard Worker MediaExtractorPluginHelper(const MediaExtractorPluginHelper &);
257*ec779b8eSAndroid Build Coastguard Worker MediaExtractorPluginHelper &operator=(const MediaExtractorPluginHelper &);
258*ec779b8eSAndroid Build Coastguard Worker };
259*ec779b8eSAndroid Build Coastguard Worker
wrap(MediaExtractorPluginHelper * extractor)260*ec779b8eSAndroid Build Coastguard Worker inline CMediaExtractor *wrap(MediaExtractorPluginHelper *extractor) {
261*ec779b8eSAndroid Build Coastguard Worker CMediaExtractor *wrapper = (CMediaExtractor*) malloc(sizeof(CMediaExtractor));
262*ec779b8eSAndroid Build Coastguard Worker wrapper->data = extractor;
263*ec779b8eSAndroid Build Coastguard Worker wrapper->free = [](void *data) -> void {
264*ec779b8eSAndroid Build Coastguard Worker delete (MediaExtractorPluginHelper*)(data);
265*ec779b8eSAndroid Build Coastguard Worker };
266*ec779b8eSAndroid Build Coastguard Worker wrapper->countTracks = [](void *data) -> size_t {
267*ec779b8eSAndroid Build Coastguard Worker return ((MediaExtractorPluginHelper*)data)->countTracks();
268*ec779b8eSAndroid Build Coastguard Worker };
269*ec779b8eSAndroid Build Coastguard Worker wrapper->getTrack = [](void *data, size_t index) -> CMediaTrack* {
270*ec779b8eSAndroid Build Coastguard Worker return wrap(((MediaExtractorPluginHelper*)data)->getTrack(index));
271*ec779b8eSAndroid Build Coastguard Worker };
272*ec779b8eSAndroid Build Coastguard Worker wrapper->getTrackMetaData = [](
273*ec779b8eSAndroid Build Coastguard Worker void *data,
274*ec779b8eSAndroid Build Coastguard Worker AMediaFormat *meta,
275*ec779b8eSAndroid Build Coastguard Worker size_t index, uint32_t flags) -> media_status_t {
276*ec779b8eSAndroid Build Coastguard Worker return ((MediaExtractorPluginHelper*)data)->getTrackMetaData(meta, index, flags);
277*ec779b8eSAndroid Build Coastguard Worker };
278*ec779b8eSAndroid Build Coastguard Worker wrapper->getMetaData = [](
279*ec779b8eSAndroid Build Coastguard Worker void *data,
280*ec779b8eSAndroid Build Coastguard Worker AMediaFormat *meta) -> media_status_t {
281*ec779b8eSAndroid Build Coastguard Worker return ((MediaExtractorPluginHelper*)data)->getMetaData(meta);
282*ec779b8eSAndroid Build Coastguard Worker };
283*ec779b8eSAndroid Build Coastguard Worker wrapper->flags = [](
284*ec779b8eSAndroid Build Coastguard Worker void *data) -> uint32_t {
285*ec779b8eSAndroid Build Coastguard Worker return ((MediaExtractorPluginHelper*)data)->flags();
286*ec779b8eSAndroid Build Coastguard Worker };
287*ec779b8eSAndroid Build Coastguard Worker wrapper->setMediaCas = [](
288*ec779b8eSAndroid Build Coastguard Worker void *data, const uint8_t *casToken, size_t size) -> media_status_t {
289*ec779b8eSAndroid Build Coastguard Worker return ((MediaExtractorPluginHelper*)data)->setMediaCas(casToken, size);
290*ec779b8eSAndroid Build Coastguard Worker };
291*ec779b8eSAndroid Build Coastguard Worker wrapper->name = [](
292*ec779b8eSAndroid Build Coastguard Worker void *data) -> const char * {
293*ec779b8eSAndroid Build Coastguard Worker return ((MediaExtractorPluginHelper*)data)->name();
294*ec779b8eSAndroid Build Coastguard Worker };
295*ec779b8eSAndroid Build Coastguard Worker return wrapper;
296*ec779b8eSAndroid Build Coastguard Worker }
297*ec779b8eSAndroid Build Coastguard Worker
298*ec779b8eSAndroid Build Coastguard Worker /* adds some convience methods */
299*ec779b8eSAndroid Build Coastguard Worker class DataSourceHelper {
300*ec779b8eSAndroid Build Coastguard Worker public:
DataSourceHelper(CDataSource * csource)301*ec779b8eSAndroid Build Coastguard Worker explicit DataSourceHelper(CDataSource *csource) {
302*ec779b8eSAndroid Build Coastguard Worker mSource = csource;
303*ec779b8eSAndroid Build Coastguard Worker }
304*ec779b8eSAndroid Build Coastguard Worker
DataSourceHelper(DataSourceHelper * source)305*ec779b8eSAndroid Build Coastguard Worker explicit DataSourceHelper(DataSourceHelper *source) {
306*ec779b8eSAndroid Build Coastguard Worker mSource = source->mSource;
307*ec779b8eSAndroid Build Coastguard Worker }
308*ec779b8eSAndroid Build Coastguard Worker
~DataSourceHelper()309*ec779b8eSAndroid Build Coastguard Worker virtual ~DataSourceHelper() {}
310*ec779b8eSAndroid Build Coastguard Worker
readAt(off64_t offset,void * data,size_t size)311*ec779b8eSAndroid Build Coastguard Worker virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
312*ec779b8eSAndroid Build Coastguard Worker return mSource->readAt(mSource->handle, offset, data, size);
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker
getSize(off64_t * size)315*ec779b8eSAndroid Build Coastguard Worker virtual status_t getSize(off64_t *size) {
316*ec779b8eSAndroid Build Coastguard Worker return mSource->getSize(mSource->handle, size);
317*ec779b8eSAndroid Build Coastguard Worker }
318*ec779b8eSAndroid Build Coastguard Worker
getUri(char * uriString,size_t bufferSize)319*ec779b8eSAndroid Build Coastguard Worker bool getUri(char *uriString, size_t bufferSize) {
320*ec779b8eSAndroid Build Coastguard Worker return mSource->getUri(mSource->handle, uriString, bufferSize);
321*ec779b8eSAndroid Build Coastguard Worker }
322*ec779b8eSAndroid Build Coastguard Worker
flags()323*ec779b8eSAndroid Build Coastguard Worker virtual uint32_t flags() {
324*ec779b8eSAndroid Build Coastguard Worker return mSource->flags(mSource->handle);
325*ec779b8eSAndroid Build Coastguard Worker }
326*ec779b8eSAndroid Build Coastguard Worker
327*ec779b8eSAndroid Build Coastguard Worker // Convenience methods:
getUInt16(off64_t offset,uint16_t * x)328*ec779b8eSAndroid Build Coastguard Worker bool getUInt16(off64_t offset, uint16_t *x) {
329*ec779b8eSAndroid Build Coastguard Worker *x = 0;
330*ec779b8eSAndroid Build Coastguard Worker
331*ec779b8eSAndroid Build Coastguard Worker uint8_t byte[2];
332*ec779b8eSAndroid Build Coastguard Worker if (readAt(offset, byte, 2) != 2) {
333*ec779b8eSAndroid Build Coastguard Worker return false;
334*ec779b8eSAndroid Build Coastguard Worker }
335*ec779b8eSAndroid Build Coastguard Worker
336*ec779b8eSAndroid Build Coastguard Worker *x = (byte[0] << 8) | byte[1];
337*ec779b8eSAndroid Build Coastguard Worker
338*ec779b8eSAndroid Build Coastguard Worker return true;
339*ec779b8eSAndroid Build Coastguard Worker }
340*ec779b8eSAndroid Build Coastguard Worker
341*ec779b8eSAndroid Build Coastguard Worker // 3 byte int, returned as a 32-bit int
getUInt24(off64_t offset,uint32_t * x)342*ec779b8eSAndroid Build Coastguard Worker bool getUInt24(off64_t offset, uint32_t *x) {
343*ec779b8eSAndroid Build Coastguard Worker *x = 0;
344*ec779b8eSAndroid Build Coastguard Worker
345*ec779b8eSAndroid Build Coastguard Worker uint8_t byte[3];
346*ec779b8eSAndroid Build Coastguard Worker if (readAt(offset, byte, 3) != 3) {
347*ec779b8eSAndroid Build Coastguard Worker return false;
348*ec779b8eSAndroid Build Coastguard Worker }
349*ec779b8eSAndroid Build Coastguard Worker
350*ec779b8eSAndroid Build Coastguard Worker *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
351*ec779b8eSAndroid Build Coastguard Worker
352*ec779b8eSAndroid Build Coastguard Worker return true;
353*ec779b8eSAndroid Build Coastguard Worker }
354*ec779b8eSAndroid Build Coastguard Worker
getUInt32(off64_t offset,uint32_t * x)355*ec779b8eSAndroid Build Coastguard Worker bool getUInt32(off64_t offset, uint32_t *x) {
356*ec779b8eSAndroid Build Coastguard Worker *x = 0;
357*ec779b8eSAndroid Build Coastguard Worker
358*ec779b8eSAndroid Build Coastguard Worker uint32_t tmp;
359*ec779b8eSAndroid Build Coastguard Worker if (readAt(offset, &tmp, 4) != 4) {
360*ec779b8eSAndroid Build Coastguard Worker return false;
361*ec779b8eSAndroid Build Coastguard Worker }
362*ec779b8eSAndroid Build Coastguard Worker
363*ec779b8eSAndroid Build Coastguard Worker *x = ntohl(tmp);
364*ec779b8eSAndroid Build Coastguard Worker
365*ec779b8eSAndroid Build Coastguard Worker return true;
366*ec779b8eSAndroid Build Coastguard Worker }
367*ec779b8eSAndroid Build Coastguard Worker
getUInt64(off64_t offset,uint64_t * x)368*ec779b8eSAndroid Build Coastguard Worker bool getUInt64(off64_t offset, uint64_t *x) {
369*ec779b8eSAndroid Build Coastguard Worker *x = 0;
370*ec779b8eSAndroid Build Coastguard Worker
371*ec779b8eSAndroid Build Coastguard Worker uint64_t tmp;
372*ec779b8eSAndroid Build Coastguard Worker if (readAt(offset, &tmp, 8) != 8) {
373*ec779b8eSAndroid Build Coastguard Worker return false;
374*ec779b8eSAndroid Build Coastguard Worker }
375*ec779b8eSAndroid Build Coastguard Worker
376*ec779b8eSAndroid Build Coastguard Worker *x = ((uint64_t)ntohl(tmp & 0xffffffff) << 32) | ntohl(tmp >> 32);
377*ec779b8eSAndroid Build Coastguard Worker
378*ec779b8eSAndroid Build Coastguard Worker return true;
379*ec779b8eSAndroid Build Coastguard Worker }
380*ec779b8eSAndroid Build Coastguard Worker
381*ec779b8eSAndroid Build Coastguard Worker // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
getUInt16Var(off64_t offset,uint16_t * x,size_t size)382*ec779b8eSAndroid Build Coastguard Worker bool getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
383*ec779b8eSAndroid Build Coastguard Worker if (size == 2) {
384*ec779b8eSAndroid Build Coastguard Worker return getUInt16(offset, x);
385*ec779b8eSAndroid Build Coastguard Worker }
386*ec779b8eSAndroid Build Coastguard Worker if (size == 1) {
387*ec779b8eSAndroid Build Coastguard Worker uint8_t tmp;
388*ec779b8eSAndroid Build Coastguard Worker if (readAt(offset, &tmp, 1) == 1) {
389*ec779b8eSAndroid Build Coastguard Worker *x = tmp;
390*ec779b8eSAndroid Build Coastguard Worker return true;
391*ec779b8eSAndroid Build Coastguard Worker }
392*ec779b8eSAndroid Build Coastguard Worker }
393*ec779b8eSAndroid Build Coastguard Worker return false;
394*ec779b8eSAndroid Build Coastguard Worker }
395*ec779b8eSAndroid Build Coastguard Worker
getUInt32Var(off64_t offset,uint32_t * x,size_t size)396*ec779b8eSAndroid Build Coastguard Worker bool getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
397*ec779b8eSAndroid Build Coastguard Worker if (size == 4) {
398*ec779b8eSAndroid Build Coastguard Worker return getUInt32(offset, x);
399*ec779b8eSAndroid Build Coastguard Worker }
400*ec779b8eSAndroid Build Coastguard Worker if (size == 2) {
401*ec779b8eSAndroid Build Coastguard Worker uint16_t tmp;
402*ec779b8eSAndroid Build Coastguard Worker if (getUInt16(offset, &tmp)) {
403*ec779b8eSAndroid Build Coastguard Worker *x = tmp;
404*ec779b8eSAndroid Build Coastguard Worker return true;
405*ec779b8eSAndroid Build Coastguard Worker }
406*ec779b8eSAndroid Build Coastguard Worker }
407*ec779b8eSAndroid Build Coastguard Worker return false;
408*ec779b8eSAndroid Build Coastguard Worker }
409*ec779b8eSAndroid Build Coastguard Worker
getUInt64Var(off64_t offset,uint64_t * x,size_t size)410*ec779b8eSAndroid Build Coastguard Worker bool getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
411*ec779b8eSAndroid Build Coastguard Worker if (size == 8) {
412*ec779b8eSAndroid Build Coastguard Worker return getUInt64(offset, x);
413*ec779b8eSAndroid Build Coastguard Worker }
414*ec779b8eSAndroid Build Coastguard Worker if (size == 4) {
415*ec779b8eSAndroid Build Coastguard Worker uint32_t tmp;
416*ec779b8eSAndroid Build Coastguard Worker if (getUInt32(offset, &tmp)) {
417*ec779b8eSAndroid Build Coastguard Worker *x = tmp;
418*ec779b8eSAndroid Build Coastguard Worker return true;
419*ec779b8eSAndroid Build Coastguard Worker }
420*ec779b8eSAndroid Build Coastguard Worker }
421*ec779b8eSAndroid Build Coastguard Worker return false;
422*ec779b8eSAndroid Build Coastguard Worker }
423*ec779b8eSAndroid Build Coastguard Worker
424*ec779b8eSAndroid Build Coastguard Worker protected:
425*ec779b8eSAndroid Build Coastguard Worker CDataSource *mSource;
426*ec779b8eSAndroid Build Coastguard Worker };
427*ec779b8eSAndroid Build Coastguard Worker
428*ec779b8eSAndroid Build Coastguard Worker
429*ec779b8eSAndroid Build Coastguard Worker
430*ec779b8eSAndroid Build Coastguard Worker // helpers to create a media_uuid_t from a string literal
431*ec779b8eSAndroid Build Coastguard Worker
432*ec779b8eSAndroid Build Coastguard Worker // purposely not defined anywhere so that this will fail to link if
433*ec779b8eSAndroid Build Coastguard Worker // expressions below are not evaluated at compile time
434*ec779b8eSAndroid Build Coastguard Worker int invalid_uuid_string(const char *);
435*ec779b8eSAndroid Build Coastguard Worker
436*ec779b8eSAndroid Build Coastguard Worker template <typename T, size_t N>
_digitAt_(const T (& s)[N],const size_t n)437*ec779b8eSAndroid Build Coastguard Worker constexpr uint8_t _digitAt_(const T (&s)[N], const size_t n) {
438*ec779b8eSAndroid Build Coastguard Worker return s[n] >= '0' && s[n] <= '9' ? s[n] - '0'
439*ec779b8eSAndroid Build Coastguard Worker : s[n] >= 'a' && s[n] <= 'f' ? s[n] - 'a' + 10
440*ec779b8eSAndroid Build Coastguard Worker : s[n] >= 'A' && s[n] <= 'F' ? s[n] - 'A' + 10
441*ec779b8eSAndroid Build Coastguard Worker : invalid_uuid_string("uuid: bad digits");
442*ec779b8eSAndroid Build Coastguard Worker }
443*ec779b8eSAndroid Build Coastguard Worker
444*ec779b8eSAndroid Build Coastguard Worker template <typename T, size_t N>
_hexByteAt_(const T (& s)[N],size_t n)445*ec779b8eSAndroid Build Coastguard Worker constexpr uint8_t _hexByteAt_(const T (&s)[N], size_t n) {
446*ec779b8eSAndroid Build Coastguard Worker return (_digitAt_(s, n) << 4) + _digitAt_(s, n + 1);
447*ec779b8eSAndroid Build Coastguard Worker }
448*ec779b8eSAndroid Build Coastguard Worker
_assertIsDash_(char c)449*ec779b8eSAndroid Build Coastguard Worker constexpr bool _assertIsDash_(char c) {
450*ec779b8eSAndroid Build Coastguard Worker return c == '-' ? true : invalid_uuid_string("Wrong format");
451*ec779b8eSAndroid Build Coastguard Worker }
452*ec779b8eSAndroid Build Coastguard Worker
453*ec779b8eSAndroid Build Coastguard Worker template <size_t N>
constUUID(const char (& s)[N])454*ec779b8eSAndroid Build Coastguard Worker constexpr media_uuid_t constUUID(const char (&s) [N]) {
455*ec779b8eSAndroid Build Coastguard Worker static_assert(N == 37, "uuid: wrong length");
456*ec779b8eSAndroid Build Coastguard Worker return
457*ec779b8eSAndroid Build Coastguard Worker _assertIsDash_(s[8]),
458*ec779b8eSAndroid Build Coastguard Worker _assertIsDash_(s[13]),
459*ec779b8eSAndroid Build Coastguard Worker _assertIsDash_(s[18]),
460*ec779b8eSAndroid Build Coastguard Worker _assertIsDash_(s[23]),
461*ec779b8eSAndroid Build Coastguard Worker media_uuid_t {{
462*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 0),
463*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 2),
464*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 4),
465*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 6),
466*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 9),
467*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 11),
468*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 14),
469*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 16),
470*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 19),
471*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 21),
472*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 24),
473*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 26),
474*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 28),
475*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 30),
476*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 32),
477*ec779b8eSAndroid Build Coastguard Worker _hexByteAt_(s, 34),
478*ec779b8eSAndroid Build Coastguard Worker }};
479*ec779b8eSAndroid Build Coastguard Worker }
480*ec779b8eSAndroid Build Coastguard Worker // Convenience macro to create a media_uuid_t from a string literal, which should
481*ec779b8eSAndroid Build Coastguard Worker // be formatted as "12345678-1234-1234-1234-123456789abc", as generated by
482*ec779b8eSAndroid Build Coastguard Worker // e.g. https://www.uuidgenerator.net/ or the 'uuidgen' linux command.
483*ec779b8eSAndroid Build Coastguard Worker // Hex digits may be upper or lower case.
484*ec779b8eSAndroid Build Coastguard Worker //
485*ec779b8eSAndroid Build Coastguard Worker // The macro call is otherwise equivalent to specifying the structure directly
486*ec779b8eSAndroid Build Coastguard Worker // (e.g. UUID("7d613858-5837-4a38-84c5-332d1cddee27") is the same as
487*ec779b8eSAndroid Build Coastguard Worker // {{0x7d, 0x61, 0x38, 0x58, 0x58, 0x37, 0x4a, 0x38,
488*ec779b8eSAndroid Build Coastguard Worker // 0x84, 0xc5, 0x33, 0x2d, 0x1c, 0xdd, 0xee, 0x27}})
489*ec779b8eSAndroid Build Coastguard Worker
490*ec779b8eSAndroid Build Coastguard Worker #define UUID(str) []{ constexpr media_uuid_t uuid = constUUID(str); return uuid; }()
491*ec779b8eSAndroid Build Coastguard Worker
492*ec779b8eSAndroid Build Coastguard Worker } // namespace android
493*ec779b8eSAndroid Build Coastguard Worker
494*ec779b8eSAndroid Build Coastguard Worker #endif // MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
495