1/*
2 * Copyright (C) 2009 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 MEDIA_EXTRACTOR_H_
18
19#define MEDIA_EXTRACTOR_H_
20
21#include <stdio.h>
22#include <vector>
23
24#include <utils/Errors.h>
25#include <utils/Log.h>
26#include <utils/RefBase.h>
27
28namespace android {
29
30class DataSourceBase;
31class MetaDataBase;
32struct MediaTrack;
33
34
35class ExtractorAllocTracker {
36public:
37    ExtractorAllocTracker() {
38        ALOGD("extractor allocated: %p", this);
39    }
40    virtual ~ExtractorAllocTracker() {
41        ALOGD("extractor freed: %p", this);
42    }
43};
44
45
46class MediaExtractor
47// : public ExtractorAllocTracker
48{
49public:
50    virtual ~MediaExtractor();
51    virtual size_t countTracks() = 0;
52    virtual MediaTrack *getTrack(size_t index) = 0;
53
54    enum GetTrackMetaDataFlags {
55        kIncludeExtensiveMetaData = 1
56    };
57    virtual status_t getTrackMetaData(
58            MetaDataBase& meta,
59            size_t index, uint32_t flags = 0) = 0;
60
61    // Return container specific meta-data. The default implementation
62    // returns an empty metadata object.
63    virtual status_t getMetaData(MetaDataBase& meta) = 0;
64
65    enum Flags {
66        CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
67        CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
68        CAN_PAUSE          = 4,
69        CAN_SEEK           = 8,  // the "seek bar"
70    };
71
72    // If subclasses do _not_ override this, the default is
73    // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
74    virtual uint32_t flags() const;
75
76    virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
77        return INVALID_OPERATION;
78    }
79
80    virtual const char * name() { return "<unspecified>"; }
81
82    typedef MediaExtractor* (*CreatorFunc)(
83            DataSourceBase *source, void *meta);
84    typedef void (*FreeMetaFunc)(void *meta);
85
86    // The sniffer can optionally fill in an opaque object, "meta", that helps
87    // the corresponding extractor initialize its state without duplicating
88    // effort already exerted by the sniffer. If "freeMeta" is given, it will be
89    // called against the opaque object when it is no longer used.
90    typedef CreatorFunc (*SnifferFunc)(
91            DataSourceBase *source, float *confidence,
92            void **meta, FreeMetaFunc *freeMeta);
93
94    typedef struct {
95        const uint8_t b[16];
96    } uuid_t;
97
98    typedef struct {
99        // version number of this structure
100        const uint32_t def_version;
101
102        // A unique identifier for this extractor.
103        // See below for a convenience macro to create this from a string.
104        uuid_t extractor_uuid;
105
106        // Version number of this extractor. When two extractors with the same
107        // uuid are encountered, the one with the largest version number will
108        // be used.
109        const uint32_t extractor_version;
110
111        // a human readable name
112        const char *extractor_name;
113
114        // the sniffer function
115        const SnifferFunc sniff;
116    } ExtractorDef;
117
118    static const uint32_t EXTRACTORDEF_VERSION = 1;
119
120    typedef ExtractorDef (*GetExtractorDef)();
121
122protected:
123    MediaExtractor();
124
125private:
126    MediaExtractor(const MediaExtractor &);
127    MediaExtractor &operator=(const MediaExtractor &);
128};
129
130// purposely not defined anywhere so that this will fail to link if
131// expressions below are not evaluated at compile time
132int invalid_uuid_string(const char *);
133
134template <typename T, size_t N>
135constexpr uint8_t _digitAt_(const T (&s)[N], const size_t n) {
136    return s[n] >= '0' && s[n] <= '9' ? s[n] - '0'
137            : s[n] >= 'a' && s[n] <= 'f' ? s[n] - 'a' + 10
138                    : s[n] >= 'A' && s[n] <= 'F' ? s[n] - 'A' + 10
139                            : invalid_uuid_string("uuid: bad digits");
140}
141
142template <typename T, size_t N>
143constexpr uint8_t _hexByteAt_(const T (&s)[N], size_t n) {
144    return (_digitAt_(s, n) << 4) + _digitAt_(s, n + 1);
145}
146
147constexpr bool _assertIsDash_(char c) {
148    return c == '-' ? true : invalid_uuid_string("Wrong format");
149}
150
151template <size_t N>
152constexpr MediaExtractor::uuid_t constUUID(const char (&s) [N]) {
153    static_assert(N == 37, "uuid: wrong length");
154    return
155            _assertIsDash_(s[8]),
156            _assertIsDash_(s[13]),
157            _assertIsDash_(s[18]),
158            _assertIsDash_(s[23]),
159            MediaExtractor::uuid_t {{
160                _hexByteAt_(s, 0),
161                _hexByteAt_(s, 2),
162                _hexByteAt_(s, 4),
163                _hexByteAt_(s, 6),
164                _hexByteAt_(s, 9),
165                _hexByteAt_(s, 11),
166                _hexByteAt_(s, 14),
167                _hexByteAt_(s, 16),
168                _hexByteAt_(s, 19),
169                _hexByteAt_(s, 21),
170                _hexByteAt_(s, 24),
171                _hexByteAt_(s, 26),
172                _hexByteAt_(s, 28),
173                _hexByteAt_(s, 30),
174                _hexByteAt_(s, 32),
175                _hexByteAt_(s, 34),
176            }};
177}
178// Convenience macro to create a uuid_t from a string literal, which should
179// be formatted as "12345678-1234-1234-1234-123456789abc", as generated by
180// e.g. https://www.uuidgenerator.net/ or the 'uuidgen' linux command.
181// Hex digits may be upper or lower case.
182//
183// The macro call is otherwise equivalent to specifying the structure directly
184// (e.g. UUID("7d613858-5837-4a38-84c5-332d1cddee27") is the same as
185//       {{0x7d, 0x61, 0x38, 0x58, 0x58, 0x37, 0x4a, 0x38,
186//         0x84, 0xc5, 0x33, 0x2d, 0x1c, 0xdd, 0xee, 0x27}})
187
188#define UUID(str) []{ constexpr MediaExtractor::uuid_t uuid = constUUID(str); return uuid; }()
189
190
191
192}  // namespace android
193
194#endif  // MEDIA_EXTRACTOR_H_
195