C API for extractor plugins
Define a C extractor plugin API, along with some helpers
so extractors can still be implemented in C++ if desired.
Bug: 111407253
Test: build, boot, play some files
Change-Id: Iba947381441769d77929b4235cdb4a4cd5d4f606
diff --git a/include/media/MediaExtractorPluginApi.h b/include/media/MediaExtractorPluginApi.h
new file mode 100644
index 0000000..30c2b05
--- /dev/null
+++ b/include/media/MediaExtractorPluginApi.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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 MEDIA_EXTRACTOR_PLUGIN_API_H_
+#define MEDIA_EXTRACTOR_PLUGIN_API_H_
+
+#include <utils/Errors.h> // for status_t
+
+namespace android {
+
+struct MediaTrack;
+class MetaDataBase;
+class DataSourceBase;
+
+extern "C" {
+
+struct CMediaExtractor {
+ void *data;
+
+ void (*free)(void *data);
+ size_t (*countTracks)(void *data);
+ MediaTrack* (*getTrack)(void *data, size_t index);
+ status_t (*getTrackMetaData)(
+ void *data,
+ MetaDataBase& meta,
+ size_t index, uint32_t flags);
+
+ status_t (*getMetaData)(void *data, MetaDataBase& meta);
+ uint32_t (*flags)(void *data);
+ status_t (*setMediaCas)(void *data, const uint8_t* casToken, size_t size);
+ const char * (*name)(void *data);
+};
+
+typedef CMediaExtractor* (*CreatorFunc)(DataSourceBase *source, void *meta);
+typedef void (*FreeMetaFunc)(void *meta);
+
+// The sniffer can optionally fill in an opaque object, "meta", that helps
+// the corresponding extractor initialize its state without duplicating
+// effort already exerted by the sniffer. If "freeMeta" is given, it will be
+// called against the opaque object when it is no longer used.
+typedef CreatorFunc (*SnifferFunc)(
+ DataSourceBase *source, float *confidence,
+ void **meta, FreeMetaFunc *freeMeta);
+
+typedef struct {
+ const uint8_t b[16];
+} media_uuid_t;
+
+typedef struct {
+ // version number of this structure
+ const uint32_t def_version;
+
+ // A unique identifier for this extractor.
+ // See below for a convenience macro to create this from a string.
+ media_uuid_t extractor_uuid;
+
+ // Version number of this extractor. When two extractors with the same
+ // uuid are encountered, the one with the largest version number will
+ // be used.
+ const uint32_t extractor_version;
+
+ // a human readable name
+ const char *extractor_name;
+
+ // the sniffer function
+ const SnifferFunc sniff;
+} ExtractorDef;
+
+const uint32_t EXTRACTORDEF_VERSION = 1;
+
+// each plugin library exports one function of this type
+typedef ExtractorDef (*GetExtractorDef)();
+
+} // extern "C"
+
+} // namespace android
+
+#endif // MEDIA_EXTRACTOR_PLUGIN_API_H_
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
new file mode 100644
index 0000000..465f76a
--- /dev/null
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2018 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 MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
+
+#define MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
+
+#include <stdio.h>
+#include <vector>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <media/MediaExtractorPluginApi.h>
+
+namespace android {
+
+class DataSourceBase;
+class MetaDataBase;
+struct MediaTrack;
+
+// extractor plugins can derive from this class which looks remarkably
+// like MediaExtractor and can be easily wrapped in the required C API
+class MediaExtractorPluginHelper
+{
+public:
+ virtual ~MediaExtractorPluginHelper() {}
+ virtual size_t countTracks() = 0;
+ virtual MediaTrack *getTrack(size_t index) = 0;
+
+ enum GetTrackMetaDataFlags {
+ kIncludeExtensiveMetaData = 1
+ };
+ virtual status_t getTrackMetaData(
+ MetaDataBase& meta,
+ size_t index, uint32_t flags = 0) = 0;
+
+ // Return container specific meta-data. The default implementation
+ // returns an empty metadata object.
+ virtual status_t getMetaData(MetaDataBase& meta) = 0;
+
+ enum Flags {
+ CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
+ CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
+ CAN_PAUSE = 4,
+ CAN_SEEK = 8, // the "seek bar"
+ };
+
+ // If subclasses do _not_ override this, the default is
+ // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+ virtual uint32_t flags() const {
+ return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE;
+ };
+
+ virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
+ return INVALID_OPERATION;
+ }
+
+ virtual const char * name() { return "<unspecified>"; }
+
+protected:
+ MediaExtractorPluginHelper() {}
+
+private:
+ MediaExtractorPluginHelper(const MediaExtractorPluginHelper &);
+ MediaExtractorPluginHelper &operator=(const MediaExtractorPluginHelper &);
+};
+
+inline CMediaExtractor *wrap(MediaExtractorPluginHelper *extractor) {
+ CMediaExtractor *wrapper = (CMediaExtractor*) malloc(sizeof(CMediaExtractor));
+ wrapper->data = extractor;
+ wrapper->free = [](void *data) -> void {
+ delete (MediaExtractorPluginHelper*)(data);
+ };
+ wrapper->countTracks = [](void *data) -> size_t {
+ return ((MediaExtractorPluginHelper*)data)->countTracks();
+ };
+ wrapper->getTrack = [](void *data, size_t index) -> MediaTrack* {
+ return ((MediaExtractorPluginHelper*)data)->getTrack(index);
+ };
+ wrapper->getTrackMetaData = [](
+ void *data,
+ MetaDataBase& meta,
+ size_t index, uint32_t flags) -> status_t {
+ return ((MediaExtractorPluginHelper*)data)->getTrackMetaData(meta, index, flags);
+ };
+ wrapper->getMetaData = [](
+ void *data,
+ MetaDataBase& meta) -> status_t {
+ return ((MediaExtractorPluginHelper*)data)->getMetaData(meta);
+ };
+ wrapper->flags = [](
+ void *data) -> uint32_t {
+ return ((MediaExtractorPluginHelper*)data)->flags();
+ };
+ wrapper->setMediaCas = [](
+ void *data, const uint8_t *casToken, size_t size) -> status_t {
+ return ((MediaExtractorPluginHelper*)data)->setMediaCas(casToken, size);
+ };
+ wrapper->name = [](
+ void *data) -> const char * {
+ return ((MediaExtractorPluginHelper*)data)->name();
+ };
+ return wrapper;
+}
+
+// helpers to create a media_uuid_t from a string literal
+
+// purposely not defined anywhere so that this will fail to link if
+// expressions below are not evaluated at compile time
+int invalid_uuid_string(const char *);
+
+template <typename T, size_t N>
+constexpr uint8_t _digitAt_(const T (&s)[N], const size_t n) {
+ return s[n] >= '0' && s[n] <= '9' ? s[n] - '0'
+ : s[n] >= 'a' && s[n] <= 'f' ? s[n] - 'a' + 10
+ : s[n] >= 'A' && s[n] <= 'F' ? s[n] - 'A' + 10
+ : invalid_uuid_string("uuid: bad digits");
+}
+
+template <typename T, size_t N>
+constexpr uint8_t _hexByteAt_(const T (&s)[N], size_t n) {
+ return (_digitAt_(s, n) << 4) + _digitAt_(s, n + 1);
+}
+
+constexpr bool _assertIsDash_(char c) {
+ return c == '-' ? true : invalid_uuid_string("Wrong format");
+}
+
+template <size_t N>
+constexpr media_uuid_t constUUID(const char (&s) [N]) {
+ static_assert(N == 37, "uuid: wrong length");
+ return
+ _assertIsDash_(s[8]),
+ _assertIsDash_(s[13]),
+ _assertIsDash_(s[18]),
+ _assertIsDash_(s[23]),
+ media_uuid_t {{
+ _hexByteAt_(s, 0),
+ _hexByteAt_(s, 2),
+ _hexByteAt_(s, 4),
+ _hexByteAt_(s, 6),
+ _hexByteAt_(s, 9),
+ _hexByteAt_(s, 11),
+ _hexByteAt_(s, 14),
+ _hexByteAt_(s, 16),
+ _hexByteAt_(s, 19),
+ _hexByteAt_(s, 21),
+ _hexByteAt_(s, 24),
+ _hexByteAt_(s, 26),
+ _hexByteAt_(s, 28),
+ _hexByteAt_(s, 30),
+ _hexByteAt_(s, 32),
+ _hexByteAt_(s, 34),
+ }};
+}
+// Convenience macro to create a media_uuid_t from a string literal, which should
+// be formatted as "12345678-1234-1234-1234-123456789abc", as generated by
+// e.g. https://www.uuidgenerator.net/ or the 'uuidgen' linux command.
+// Hex digits may be upper or lower case.
+//
+// The macro call is otherwise equivalent to specifying the structure directly
+// (e.g. UUID("7d613858-5837-4a38-84c5-332d1cddee27") is the same as
+// {{0x7d, 0x61, 0x38, 0x58, 0x58, 0x37, 0x4a, 0x38,
+// 0x84, 0xc5, 0x33, 0x2d, 0x1c, 0xdd, 0xee, 0x27}})
+
+#define UUID(str) []{ constexpr media_uuid_t uuid = constUUID(str); return uuid; }()
+
+} // namespace android
+
+#endif // MEDIA_EXTRACTOR_PLUGIN_HELPER_H_
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 9fc5a76..7b9da47 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -323,16 +323,16 @@
////////////////////////////////////////////////////////////////////////////////
-static MediaExtractor* CreateExtractor(
+static CMediaExtractor* CreateExtractor(
DataSourceBase *source,
void *meta) {
off64_t offset = *static_cast<off64_t*>(meta);
- return new AACExtractor(source, offset);
+ return wrap(new AACExtractor(source, offset));
}
-static MediaExtractor::CreatorFunc Sniff(
+static CreatorFunc Sniff(
DataSourceBase *source, float *confidence, void **meta,
- MediaExtractor::FreeMetaFunc *freeMeta) {
+ FreeMetaFunc *freeMeta) {
off64_t pos = 0;
for (;;) {
@@ -387,9 +387,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("4fd80eae-03d2-4d72-9eb9-48fa6bb54613"),
1, // version
"AAC Extractor",
diff --git a/media/extractors/aac/AACExtractor.h b/media/extractors/aac/AACExtractor.h
index 9dadbed..a48de5c 100644
--- a/media/extractors/aac/AACExtractor.h
+++ b/media/extractors/aac/AACExtractor.h
@@ -18,7 +18,8 @@
#define AAC_EXTRACTOR_H_
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
#include <utils/Vector.h>
@@ -28,7 +29,7 @@
struct AMessage;
class String8;
-class AACExtractor : public MediaExtractor {
+class AACExtractor : public MediaExtractorPluginHelper {
public:
AACExtractor(DataSourceBase *source, off64_t offset);
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index f56d5ef..f1143c4 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -365,9 +365,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("c86639c9-2f31-40ac-a715-fa01b4493aaf"),
1,
"AMR Extractor",
@@ -375,12 +375,12 @@
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
+ FreeMetaFunc *) -> CreatorFunc {
if (SniffAMR(source, nullptr, confidence)) {
return [](
DataSourceBase *source,
- void *) -> MediaExtractor* {
- return new AMRExtractor(source);};
+ void *) -> CMediaExtractor* {
+ return wrap(new AMRExtractor(source));};
}
return NULL;
}
diff --git a/media/extractors/amr/AMRExtractor.h b/media/extractors/amr/AMRExtractor.h
index c90b325..1099dbf 100644
--- a/media/extractors/amr/AMRExtractor.h
+++ b/media/extractors/amr/AMRExtractor.h
@@ -19,7 +19,8 @@
#define AMR_EXTRACTOR_H_
#include <utils/Errors.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
namespace android {
@@ -28,7 +29,7 @@
class String8;
#define OFFSET_TABLE_LEN 300
-class AMRExtractor : public MediaExtractor {
+class AMRExtractor : public MediaExtractorPluginHelper {
public:
explicit AMRExtractor(DataSourceBase *source);
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index a721b65..ba4e5ac 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -859,9 +859,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("1364b048-cc45-4fda-9934-327d0ebf9829"),
1,
"FLAC Extractor",
@@ -869,12 +869,12 @@
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
+ FreeMetaFunc *) -> CreatorFunc {
if (SniffFLAC(source, confidence)) {
return [](
DataSourceBase *source,
- void *) -> MediaExtractor* {
- return new FLACExtractor(source);};
+ void *) -> CMediaExtractor* {
+ return wrap(new FLACExtractor(source));};
}
return NULL;
}
diff --git a/media/extractors/flac/FLACExtractor.h b/media/extractors/flac/FLACExtractor.h
index 7fb6ec6..70ba9ac 100644
--- a/media/extractors/flac/FLACExtractor.h
+++ b/media/extractors/flac/FLACExtractor.h
@@ -18,7 +18,8 @@
#define FLAC_EXTRACTOR_H_
#include <media/DataSourceBase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
#include <utils/String8.h>
@@ -26,7 +27,7 @@
class FLACParser;
-class FLACExtractor : public MediaExtractor {
+class FLACExtractor : public MediaExtractorPluginHelper {
public:
explicit FLACExtractor(DataSourceBase *source);
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index a30b6f8..1b9cd5e 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -326,9 +326,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("ef6cca0a-f8a2-43e6-ba5f-dfcd7c9a7ef2"),
1,
"MIDI Extractor",
@@ -336,12 +336,12 @@
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
+ FreeMetaFunc *) -> CreatorFunc {
if (SniffMidi(source, confidence)) {
return [](
DataSourceBase *source,
- void *) -> MediaExtractor* {
- return new MidiExtractor(source);};
+ void *) -> CMediaExtractor* {
+ return wrap(new MidiExtractor(source));};
}
return NULL;
}
diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h
index 244dd0f..6ea8781 100644
--- a/media/extractors/midi/MidiExtractor.h
+++ b/media/extractors/midi/MidiExtractor.h
@@ -18,7 +18,8 @@
#define MIDI_EXTRACTOR_H_
#include <media/DataSourceBase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MediaBufferBase.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MetaDataBase.h>
@@ -50,7 +51,7 @@
bool mIsInitialized;
};
-class MidiExtractor : public MediaExtractor {
+class MidiExtractor : public MediaExtractorPluginHelper {
public:
explicit MidiExtractor(DataSourceBase *source);
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index d657582..3f703e5 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -1638,9 +1638,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"),
1,
"Matroska Extractor",
@@ -1648,12 +1648,12 @@
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
+ FreeMetaFunc *) -> CreatorFunc {
if (SniffMatroska(source, confidence)) {
return [](
DataSourceBase *source,
- void *) -> MediaExtractor* {
- return new MatroskaExtractor(source);};
+ void *) -> CMediaExtractor* {
+ return wrap(new MatroskaExtractor(source));};
}
return NULL;
}
diff --git a/media/extractors/mkv/MatroskaExtractor.h b/media/extractors/mkv/MatroskaExtractor.h
index 3568ea1..6d62044 100644
--- a/media/extractors/mkv/MatroskaExtractor.h
+++ b/media/extractors/mkv/MatroskaExtractor.h
@@ -20,7 +20,8 @@
#include "mkvparser/mkvparser.h"
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
#include <utils/Vector.h>
#include <utils/threads.h>
@@ -34,7 +35,7 @@
struct DataSourceBaseReader;
struct MatroskaSource;
-struct MatroskaExtractor : public MediaExtractor {
+struct MatroskaExtractor : public MediaExtractorPluginHelper {
explicit MatroskaExtractor(DataSourceBase *source);
virtual size_t countTracks();
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/extractors/mp3/MP3Extractor.cpp
index 33cff96..c86212c 100644
--- a/media/extractors/mp3/MP3Extractor.cpp
+++ b/media/extractors/mp3/MP3Extractor.cpp
@@ -669,16 +669,16 @@
return OK;
}
-static MediaExtractor* CreateExtractor(
+static CMediaExtractor* CreateExtractor(
DataSourceBase *source,
void *meta) {
Mp3Meta *metaData = static_cast<Mp3Meta *>(meta);
- return new MP3Extractor(source, metaData);
+ return wrap(new MP3Extractor(source, metaData));
}
-static MediaExtractor::CreatorFunc Sniff(
+static CreatorFunc Sniff(
DataSourceBase *source, float *confidence, void **meta,
- MediaExtractor::FreeMetaFunc *freeMeta) {
+ FreeMetaFunc *freeMeta) {
off64_t pos = 0;
off64_t post_id3_pos;
uint32_t header;
@@ -710,9 +710,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("812a3f6c-c8cf-46de-b529-3774b14103d4"),
1, // version
"MP3 Extractor",
diff --git a/media/extractors/mp3/MP3Extractor.h b/media/extractors/mp3/MP3Extractor.h
index 485b0ca..8957302 100644
--- a/media/extractors/mp3/MP3Extractor.h
+++ b/media/extractors/mp3/MP3Extractor.h
@@ -19,7 +19,8 @@
#define MP3_EXTRACTOR_H_
#include <utils/Errors.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
namespace android {
@@ -30,7 +31,7 @@
class String8;
struct Mp3Meta;
-class MP3Extractor : public MediaExtractor {
+class MP3Extractor : public MediaExtractorPluginHelper {
public:
MP3Extractor(DataSourceBase *source, Mp3Meta *meta);
~MP3Extractor();
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 251a4cd..0cb4e6b 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -5944,13 +5944,13 @@
return true;
}
-static MediaExtractor* CreateExtractor(DataSourceBase *source, void *) {
- return new MPEG4Extractor(source);
+static CMediaExtractor* CreateExtractor(DataSourceBase *source, void *) {
+ return wrap(new MPEG4Extractor(source));
}
-static MediaExtractor::CreatorFunc Sniff(
+static CreatorFunc Sniff(
DataSourceBase *source, float *confidence, void **,
- MediaExtractor::FreeMetaFunc *) {
+ FreeMetaFunc *) {
if (BetterSniffMPEG4(source, confidence)) {
return CreateExtractor;
}
@@ -5966,9 +5966,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("27575c67-4417-4c54-8d3d-8e626985a164"),
1, // version
"MP4 Extractor",
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index a4a5684..561b567 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -21,7 +21,8 @@
#include <arpa/inet.h>
#include <media/DataSourceBase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
#include <media/stagefright/foundation/AString.h>
#include <utils/KeyedVector.h>
@@ -53,7 +54,7 @@
uint32_t default_sample_flags;
};
-class MPEG4Extractor : public MediaExtractor {
+class MPEG4Extractor : public MediaExtractorPluginHelper {
public:
explicit MPEG4Extractor(DataSourceBase *source, const char *mime = NULL);
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index 8a0fa03..3045aa9 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -27,9 +27,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("3d1dcfeb-e40a-436d-a574-c2438a555e5f"),
1,
"MPEG2-PS/TS Extractor",
@@ -37,17 +37,17 @@
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
+ FreeMetaFunc *) -> CreatorFunc {
if (SniffMPEG2TS(source, confidence)) {
return [](
DataSourceBase *source,
- void *) -> MediaExtractor* {
- return new MPEG2TSExtractor(source);};
+ void *) -> CMediaExtractor* {
+ return wrap(new MPEG2TSExtractor(source));};
} else if (SniffMPEG2PS(source, confidence)) {
return [](
DataSourceBase *source,
- void *) -> MediaExtractor* {
- return new MPEG2PSExtractor(source);};
+ void *) -> CMediaExtractor* {
+ return wrap(new MPEG2PSExtractor(source));};
}
return NULL;
}
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.h b/media/extractors/mpeg2/MPEG2PSExtractor.h
index 8b9dad9..93827fa 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.h
@@ -19,7 +19,8 @@
#define MPEG2_PS_EXTRACTOR_H_
#include <media/stagefright/foundation/ABase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
#include <utils/threads.h>
#include <utils/KeyedVector.h>
@@ -31,7 +32,7 @@
struct Track;
class String8;
-struct MPEG2PSExtractor : public MediaExtractor {
+struct MPEG2PSExtractor : public MediaExtractorPluginHelper {
explicit MPEG2PSExtractor(DataSourceBase *source);
virtual size_t countTracks();
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index cbdd3cb..05e57c5 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -20,7 +20,8 @@
#define MPEG2_TS_EXTRACTOR_H_
#include <media/stagefright/foundation/ABase.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/MediaTrack.h>
#include <media/stagefright/MetaDataBase.h>
#include <utils/threads.h>
@@ -38,7 +39,7 @@
struct MPEG2TSSource;
class String8;
-struct MPEG2TSExtractor : public MediaExtractor {
+struct MPEG2TSExtractor : public MediaExtractorPluginHelper {
explicit MPEG2TSExtractor(DataSourceBase *source);
virtual size_t countTracks();
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index b2fe69c..efacfb3 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -1248,17 +1248,17 @@
return mImpl->getFileMetaData(meta);
}
-static MediaExtractor* CreateExtractor(
+static CMediaExtractor* CreateExtractor(
DataSourceBase *source,
void *) {
- return new OggExtractor(source);
+ return wrap(new OggExtractor(source));
}
-static MediaExtractor::CreatorFunc Sniff(
+static CreatorFunc Sniff(
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) {
+ FreeMetaFunc *) {
char tmp[4];
if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) {
return NULL;
@@ -1272,9 +1272,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"),
1, // version
"Ogg Extractor",
diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h
index 9fe2944..94f857a 100644
--- a/media/extractors/ogg/OggExtractor.h
+++ b/media/extractors/ogg/OggExtractor.h
@@ -19,7 +19,8 @@
#define OGG_EXTRACTOR_H_
#include <utils/Errors.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
namespace android {
@@ -30,7 +31,7 @@
struct MyOggExtractor;
struct OggSource;
-struct OggExtractor : public MediaExtractor {
+struct OggExtractor : public MediaExtractorPluginHelper {
explicit OggExtractor(DataSourceBase *source);
virtual size_t countTracks();
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index f5a1b01..903de52 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -544,17 +544,17 @@
////////////////////////////////////////////////////////////////////////////////
-static MediaExtractor* CreateExtractor(
+static CMediaExtractor* CreateExtractor(
DataSourceBase *source,
void *) {
- return new WAVExtractor(source);
+ return wrap(new WAVExtractor(source));
}
-static MediaExtractor::CreatorFunc Sniff(
+static CreatorFunc Sniff(
DataSourceBase *source,
float *confidence,
void **,
- MediaExtractor::FreeMetaFunc *) {
+ FreeMetaFunc *) {
char header[12];
if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
return NULL;
@@ -564,7 +564,7 @@
return NULL;
}
- MediaExtractor *extractor = new WAVExtractor(source);
+ WAVExtractor *extractor = new WAVExtractor(source);
int numTracks = extractor->countTracks();
delete extractor;
if (numTracks == 0) {
@@ -579,9 +579,9 @@
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
-MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
+ExtractorDef GETEXTRACTORDEF() {
return {
- MediaExtractor::EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION,
UUID("7d613858-5837-4a38-84c5-332d1cddee27"),
1, // version
"WAV Extractor",
diff --git a/media/extractors/wav/WAVExtractor.h b/media/extractors/wav/WAVExtractor.h
index 467d0b7..519a730 100644
--- a/media/extractors/wav/WAVExtractor.h
+++ b/media/extractors/wav/WAVExtractor.h
@@ -19,7 +19,8 @@
#define WAV_EXTRACTOR_H_
#include <utils/Errors.h>
-#include <media/MediaExtractor.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MetaDataBase.h>
namespace android {
@@ -28,7 +29,7 @@
class DataSourceBase;
class String8;
-class WAVExtractor : public MediaExtractor {
+class WAVExtractor : public MediaExtractorPluginHelper {
public:
explicit WAVExtractor(DataSourceBase *source);
diff --git a/media/libmediaextractor/MediaExtractor.cpp b/media/libmediaextractor/MediaExtractor.cpp
index a6b3dc9..8bf44c8 100644
--- a/media/libmediaextractor/MediaExtractor.cpp
+++ b/media/libmediaextractor/MediaExtractor.cpp
@@ -39,4 +39,43 @@
return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
}
+// --------------------------------------------------------------------------------
+MediaExtractorCUnwrapper::MediaExtractorCUnwrapper(CMediaExtractor *wrapper) {
+ this->wrapper = wrapper;
+}
+
+MediaExtractorCUnwrapper::~MediaExtractorCUnwrapper() {
+ wrapper->free(wrapper->data);
+ free(wrapper);
+}
+
+size_t MediaExtractorCUnwrapper::countTracks() {
+ return wrapper->countTracks(wrapper->data);
+}
+
+MediaTrack *MediaExtractorCUnwrapper::getTrack(size_t index) {
+ return wrapper->getTrack(wrapper->data, index);
+}
+
+status_t MediaExtractorCUnwrapper::getTrackMetaData(
+ MetaDataBase& meta, size_t index, uint32_t flags) {
+ return wrapper->getTrackMetaData(wrapper->data, meta, index, flags);
+}
+
+status_t MediaExtractorCUnwrapper::getMetaData(MetaDataBase& meta) {
+ return wrapper->getMetaData(wrapper->data, meta);
+}
+
+const char * MediaExtractorCUnwrapper::name() {
+ return wrapper->name(wrapper->data);
+}
+
+uint32_t MediaExtractorCUnwrapper::flags() const {
+ return wrapper->flags(wrapper->data);
+}
+
+status_t MediaExtractorCUnwrapper::setMediaCas(const uint8_t* casToken, size_t size) {
+ return wrapper->setMediaCas(wrapper->data, casToken, size);
+}
+
} // namespace android
diff --git a/media/libmediaextractor/include/media/MediaExtractor.h b/media/libmediaextractor/include/media/MediaExtractor.h
index 4ba98da..d9456ab 100644
--- a/media/libmediaextractor/include/media/MediaExtractor.h
+++ b/media/libmediaextractor/include/media/MediaExtractor.h
@@ -24,6 +24,8 @@
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/MediaExtractorPluginHelper.h>
namespace android {
@@ -42,7 +44,6 @@
}
};
-
class MediaExtractor
// : public ExtractorAllocTracker
{
@@ -79,46 +80,6 @@
virtual const char * name() { return "<unspecified>"; }
- typedef MediaExtractor* (*CreatorFunc)(
- DataSourceBase *source, void *meta);
- typedef void (*FreeMetaFunc)(void *meta);
-
- // The sniffer can optionally fill in an opaque object, "meta", that helps
- // the corresponding extractor initialize its state without duplicating
- // effort already exerted by the sniffer. If "freeMeta" is given, it will be
- // called against the opaque object when it is no longer used.
- typedef CreatorFunc (*SnifferFunc)(
- DataSourceBase *source, float *confidence,
- void **meta, FreeMetaFunc *freeMeta);
-
- typedef struct {
- const uint8_t b[16];
- } uuid_t;
-
- typedef struct {
- // version number of this structure
- const uint32_t def_version;
-
- // A unique identifier for this extractor.
- // See below for a convenience macro to create this from a string.
- uuid_t extractor_uuid;
-
- // Version number of this extractor. When two extractors with the same
- // uuid are encountered, the one with the largest version number will
- // be used.
- const uint32_t extractor_version;
-
- // a human readable name
- const char *extractor_name;
-
- // the sniffer function
- const SnifferFunc sniff;
- } ExtractorDef;
-
- static const uint32_t EXTRACTORDEF_VERSION = 1;
-
- typedef ExtractorDef (*GetExtractorDef)();
-
protected:
MediaExtractor();
@@ -127,66 +88,21 @@
MediaExtractor &operator=(const MediaExtractor &);
};
-// purposely not defined anywhere so that this will fail to link if
-// expressions below are not evaluated at compile time
-int invalid_uuid_string(const char *);
-
-template <typename T, size_t N>
-constexpr uint8_t _digitAt_(const T (&s)[N], const size_t n) {
- return s[n] >= '0' && s[n] <= '9' ? s[n] - '0'
- : s[n] >= 'a' && s[n] <= 'f' ? s[n] - 'a' + 10
- : s[n] >= 'A' && s[n] <= 'F' ? s[n] - 'A' + 10
- : invalid_uuid_string("uuid: bad digits");
-}
-
-template <typename T, size_t N>
-constexpr uint8_t _hexByteAt_(const T (&s)[N], size_t n) {
- return (_digitAt_(s, n) << 4) + _digitAt_(s, n + 1);
-}
-
-constexpr bool _assertIsDash_(char c) {
- return c == '-' ? true : invalid_uuid_string("Wrong format");
-}
-
-template <size_t N>
-constexpr MediaExtractor::uuid_t constUUID(const char (&s) [N]) {
- static_assert(N == 37, "uuid: wrong length");
- return
- _assertIsDash_(s[8]),
- _assertIsDash_(s[13]),
- _assertIsDash_(s[18]),
- _assertIsDash_(s[23]),
- MediaExtractor::uuid_t {{
- _hexByteAt_(s, 0),
- _hexByteAt_(s, 2),
- _hexByteAt_(s, 4),
- _hexByteAt_(s, 6),
- _hexByteAt_(s, 9),
- _hexByteAt_(s, 11),
- _hexByteAt_(s, 14),
- _hexByteAt_(s, 16),
- _hexByteAt_(s, 19),
- _hexByteAt_(s, 21),
- _hexByteAt_(s, 24),
- _hexByteAt_(s, 26),
- _hexByteAt_(s, 28),
- _hexByteAt_(s, 30),
- _hexByteAt_(s, 32),
- _hexByteAt_(s, 34),
- }};
-}
-// Convenience macro to create a uuid_t from a string literal, which should
-// be formatted as "12345678-1234-1234-1234-123456789abc", as generated by
-// e.g. https://www.uuidgenerator.net/ or the 'uuidgen' linux command.
-// Hex digits may be upper or lower case.
-//
-// The macro call is otherwise equivalent to specifying the structure directly
-// (e.g. UUID("7d613858-5837-4a38-84c5-332d1cddee27") is the same as
-// {{0x7d, 0x61, 0x38, 0x58, 0x58, 0x37, 0x4a, 0x38,
-// 0x84, 0xc5, 0x33, 0x2d, 0x1c, 0xdd, 0xee, 0x27}})
-
-#define UUID(str) []{ constexpr MediaExtractor::uuid_t uuid = constUUID(str); return uuid; }()
-
+class MediaExtractorCUnwrapper : public MediaExtractor {
+public:
+ explicit MediaExtractorCUnwrapper(CMediaExtractor *wrapper);
+ virtual size_t countTracks();
+ virtual MediaTrack *getTrack(size_t index);
+ virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags = 0);
+ virtual status_t getMetaData(MetaDataBase& meta);
+ virtual const char * name();
+ virtual uint32_t flags() const;
+ virtual status_t setMediaCas(const uint8_t* casToken, size_t size);
+protected:
+ virtual ~MediaExtractorCUnwrapper();
+private:
+ CMediaExtractor *wrapper;
+};
} // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 2d4bd39..dd98fc0 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -74,8 +74,8 @@
source->DrmInitialization(nullptr /* mime */);
void *meta = nullptr;
- MediaExtractor::CreatorFunc creator = NULL;
- MediaExtractor::FreeMetaFunc freeMeta = nullptr;
+ CreatorFunc creator = NULL;
+ FreeMetaFunc freeMeta = nullptr;
float confidence;
sp<ExtractorPlugin> plugin;
creator = sniff(source.get(), &confidence, &meta, &freeMeta, plugin);
@@ -84,15 +84,16 @@
return NULL;
}
- MediaExtractor *ret = creator(source.get(), meta);
+ CMediaExtractor *ret = creator(source.get(), meta);
if (meta != nullptr && freeMeta != nullptr) {
freeMeta(meta);
}
+ MediaExtractor *ex = ret != nullptr ? new MediaExtractorCUnwrapper(ret) : nullptr;
ALOGV("Created an extractor '%s' with confidence %.2f",
- ret != nullptr ? ret->name() : "<null>", confidence);
+ ex != nullptr ? ex->name() : "<null>", confidence);
- return CreateIMediaExtractorFromMediaExtractor(ret, source, plugin);
+ return CreateIMediaExtractorFromMediaExtractor(ex, source, plugin);
}
//static
@@ -103,14 +104,14 @@
}
struct ExtractorPlugin : public RefBase {
- MediaExtractor::ExtractorDef def;
+ ExtractorDef def;
void *libHandle;
String8 libPath;
String8 uuidString;
- ExtractorPlugin(MediaExtractor::ExtractorDef definition, void *handle, String8 &path)
+ ExtractorPlugin(ExtractorDef definition, void *handle, String8 &path)
: def(definition), libHandle(handle), libPath(path) {
- for (size_t i = 0; i < sizeof MediaExtractor::ExtractorDef::extractor_uuid; i++) {
+ for (size_t i = 0; i < sizeof ExtractorDef::extractor_uuid; i++) {
uuidString.appendFormat("%02x", def.extractor_uuid.b[i]);
}
}
@@ -127,9 +128,9 @@
bool MediaExtractorFactory::gPluginsRegistered = false;
// static
-MediaExtractor::CreatorFunc MediaExtractorFactory::sniff(
+CreatorFunc MediaExtractorFactory::sniff(
DataSourceBase *source, float *confidence, void **meta,
- MediaExtractor::FreeMetaFunc *freeMeta, sp<ExtractorPlugin> &plugin) {
+ FreeMetaFunc *freeMeta, sp<ExtractorPlugin> &plugin) {
*confidence = 0.0f;
*meta = nullptr;
@@ -142,13 +143,13 @@
plugins = gPlugins;
}
- MediaExtractor::CreatorFunc curCreator = NULL;
- MediaExtractor::CreatorFunc bestCreator = NULL;
+ CreatorFunc curCreator = NULL;
+ CreatorFunc bestCreator = NULL;
for (auto it = plugins->begin(); it != plugins->end(); ++it) {
ALOGV("sniffing %s", (*it)->def.extractor_name);
float newConfidence;
void *newMeta = nullptr;
- MediaExtractor::FreeMetaFunc newFreeMeta = nullptr;
+ FreeMetaFunc newFreeMeta = nullptr;
if ((curCreator = (*it)->def.sniff(source, &newConfidence, &newMeta, &newFreeMeta))) {
if (newConfidence > *confidence) {
*confidence = newConfidence;
@@ -175,7 +176,7 @@
std::list<sp<ExtractorPlugin>> &pluginList) {
// sanity check check struct version, uuid, name
if (plugin->def.def_version == 0
- || plugin->def.def_version > MediaExtractor::EXTRACTORDEF_VERSION) {
+ || plugin->def.def_version > EXTRACTORDEF_VERSION) {
ALOGE("don't understand extractor format %u, ignoring.", plugin->def.def_version);
return;
}
@@ -236,8 +237,8 @@
// within the apk instead of system libraries already loaded.
void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
if (libHandle) {
- MediaExtractor::GetExtractorDef getDef =
- (MediaExtractor::GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
+ GetExtractorDef getDef =
+ (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
if (getDef) {
ALOGV("registering sniffer for %s", libPath.string());
RegisterExtractor(
@@ -271,8 +272,8 @@
String8 libPath = String8(libDirPath) + "/" + libEntry->d_name;
void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
if (libHandle) {
- MediaExtractor::GetExtractorDef getDef =
- (MediaExtractor::GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
+ GetExtractorDef getDef =
+ (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
if (getDef) {
ALOGV("registering sniffer for %s", libPath.string());
RegisterExtractor(
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index d5f4b35..3920ccc 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -49,8 +49,8 @@
static void RegisterExtractor(
const sp<ExtractorPlugin> &plugin, std::list<sp<ExtractorPlugin>> &pluginList);
- static MediaExtractor::CreatorFunc sniff(DataSourceBase *source,
- float *confidence, void **meta, MediaExtractor::FreeMetaFunc *freeMeta,
+ static CreatorFunc sniff(DataSourceBase *source,
+ float *confidence, void **meta, FreeMetaFunc *freeMeta,
sp<ExtractorPlugin> &plugin);
static void UpdateExtractors(const char *newUpdateApkPath);