Convert Ogg and Flac extractors to use AMediaFormat
Bug: 111407253
Test: manual, CTS
Change-Id: I8aeb44ceeb831bb558cac1123f0aaade8163abf8
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 6282793..eda7b61 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -10,11 +10,14 @@
shared_libs: [
"liblog",
"libmediaextractor",
+ "libmediandk",
],
static_libs: [
"libFLAC",
"libstagefright_foundation",
+ "libstagefright_metadatautils",
+ "libutils",
],
name: "libflacextractor",
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index 3a646d5..fcfdaff 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -25,7 +25,7 @@
#include "FLAC/stream_decoder.h"
#include <media/MediaExtractorPluginApi.h>
-#include <media/VorbisComment.h>
+#include <media/NdkMediaFormat.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/base64.h>
@@ -33,24 +33,25 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MetaDataUtils.h>
#include <media/stagefright/MediaBufferBase.h>
namespace android {
class FLACParser;
-class FLACSource : public MediaTrackHelper {
+class FLACSource : public MediaTrackHelperV2 {
public:
FLACSource(
DataSourceHelper *dataSource,
- MetaDataBase &meta);
+ AMediaFormat *meta);
- virtual status_t start();
- virtual status_t stop();
- virtual status_t getFormat(MetaDataBase &meta);
+ virtual media_status_t start();
+ virtual media_status_t stop();
+ virtual media_status_t getFormat(AMediaFormat *meta);
- virtual status_t read(
+ virtual media_status_t read(
MediaBufferBase **buffer, const ReadOptions *options = NULL);
protected:
@@ -58,7 +59,7 @@
private:
DataSourceHelper *mDataSource;
- MetaDataBase mTrackMetadata;
+ AMediaFormat *mTrackMetadata;
FLACParser *mParser;
bool mInitCheck;
bool mStarted;
@@ -81,8 +82,8 @@
explicit FLACParser(
DataSourceHelper *dataSource,
// If metadata pointers aren't provided, we don't fill them
- MetaDataBase *fileMetadata = 0,
- MetaDataBase *trackMetadata = 0);
+ AMediaFormat *fileMetadata = 0,
+ AMediaFormat *trackMetadata = 0);
virtual ~FLACParser();
@@ -119,8 +120,8 @@
private:
DataSourceHelper *mDataSource;
- MetaDataBase *mFileMetadata;
- MetaDataBase *mTrackMetadata;
+ AMediaFormat *mFileMetadata;
+ AMediaFormat *mTrackMetadata;
bool mInitCheck;
// media buffers
@@ -364,8 +365,8 @@
case FLAC__METADATA_TYPE_PICTURE:
if (mFileMetadata != 0) {
const FLAC__StreamMetadata_Picture *p = &metadata->data.picture;
- mFileMetadata->setData(kKeyAlbumArt,
- MetaData::TYPE_NONE, p->data, p->data_length);
+ AMediaFormat_setBuffer(mFileMetadata, AMEDIAFORMAT_KEY_ALBUMART,
+ p->data, p->data_length);
}
break;
default:
@@ -487,8 +488,8 @@
FLACParser::FLACParser(
DataSourceHelper *dataSource,
- MetaDataBase *fileMetadata,
- MetaDataBase *trackMetadata)
+ AMediaFormat *fileMetadata,
+ AMediaFormat *trackMetadata)
: mDataSource(dataSource),
mFileMetadata(fileMetadata),
mTrackMetadata(trackMetadata),
@@ -614,20 +615,25 @@
}
// populate track metadata
if (mTrackMetadata != 0) {
- mTrackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- mTrackMetadata->setInt32(kKeyChannelCount, getChannels());
- mTrackMetadata->setInt32(kKeySampleRate, getSampleRate());
- mTrackMetadata->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
+ AMediaFormat_setString(mTrackMetadata,
+ AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
+ AMediaFormat_setInt32(mTrackMetadata,
+ AMEDIAFORMAT_KEY_CHANNEL_COUNT, getChannels());
+ AMediaFormat_setInt32(mTrackMetadata,
+ AMEDIAFORMAT_KEY_SAMPLE_RATE, getSampleRate());
+ AMediaFormat_setInt32(mTrackMetadata,
+ AMEDIAFORMAT_KEY_PCM_ENCODING, kAudioEncodingPcm16bit);
// sample rate is non-zero, so division by zero not possible
- mTrackMetadata->setInt64(kKeyDuration,
- (getTotalSamples() * 1000000LL) / getSampleRate());
+ AMediaFormat_setInt64(mTrackMetadata,
+ AMEDIAFORMAT_KEY_DURATION, (getTotalSamples() * 1000000LL) / getSampleRate());
}
} else {
ALOGE("missing STREAMINFO");
return NO_INIT;
}
if (mFileMetadata != 0) {
- mFileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC);
+ AMediaFormat_setString(mFileMetadata,
+ AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
}
return OK;
}
@@ -708,7 +714,7 @@
FLACSource::FLACSource(
DataSourceHelper *dataSource,
- MetaDataBase &trackMetadata)
+ AMediaFormat *trackMetadata)
: mDataSource(dataSource),
mTrackMetadata(trackMetadata),
mParser(0),
@@ -730,7 +736,7 @@
delete mParser;
}
-status_t FLACSource::start()
+media_status_t FLACSource::start()
{
ALOGV("FLACSource::start");
@@ -738,10 +744,10 @@
mParser->allocateBuffers();
mStarted = true;
- return OK;
+ return AMEDIA_OK;
}
-status_t FLACSource::stop()
+media_status_t FLACSource::stop()
{
ALOGV("FLACSource::stop");
@@ -749,16 +755,15 @@
mParser->releaseBuffers();
mStarted = false;
- return OK;
+ return AMEDIA_OK;
}
-status_t FLACSource::getFormat(MetaDataBase &meta)
+media_status_t FLACSource::getFormat(AMediaFormat *meta)
{
- meta = mTrackMetadata;
- return OK;
+ return AMediaFormat_copy(meta, mTrackMetadata);
}
-status_t FLACSource::read(
+media_status_t FLACSource::read(
MediaBufferBase **outBuffer, const ReadOptions *options)
{
MediaBufferBase *buffer;
@@ -782,7 +787,7 @@
buffer = mParser->readBuffer();
}
*outBuffer = buffer;
- return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM;
+ return buffer != NULL ? AMEDIA_OK : AMEDIA_ERROR_END_OF_STREAM;
}
// FLACExtractor
@@ -795,7 +800,9 @@
{
ALOGV("FLACExtractor::FLACExtractor");
// FLACParser will fill in the metadata for us
- mParser = new FLACParser(mDataSource, &mFileMetadata, &mTrackMetadata);
+ mFileMetadata = AMediaFormat_new();
+ mTrackMetadata = AMediaFormat_new();
+ mParser = new FLACParser(mDataSource, mFileMetadata, mTrackMetadata);
mInitCheck = mParser->initCheck();
}
@@ -804,6 +811,8 @@
ALOGV("~FLACExtractor::FLACExtractor");
delete mParser;
delete mDataSource;
+ AMediaFormat_delete(mFileMetadata);
+ AMediaFormat_delete(mTrackMetadata);
}
size_t FLACExtractor::countTracks()
@@ -811,7 +820,7 @@
return mInitCheck == OK ? 1 : 0;
}
-MediaTrackHelper *FLACExtractor::getTrack(size_t index)
+MediaTrackHelperV2 *FLACExtractor::getTrack(size_t index)
{
if (mInitCheck != OK || index > 0) {
return NULL;
@@ -819,20 +828,18 @@
return new FLACSource(mDataSource, mTrackMetadata);
}
-status_t FLACExtractor::getTrackMetaData(
- MetaDataBase &meta,
+media_status_t FLACExtractor::getTrackMetaData(
+ AMediaFormat *meta,
size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index > 0) {
- return UNKNOWN_ERROR;
+ return AMEDIA_ERROR_UNKNOWN;
}
- meta = mTrackMetadata;
- return OK;
+ return AMediaFormat_copy(meta, mTrackMetadata);
}
-status_t FLACExtractor::getMetaData(MetaDataBase &meta)
+media_status_t FLACExtractor::getMetaData(AMediaFormat *meta)
{
- meta = mFileMetadata;
- return OK;
+ return AMediaFormat_copy(meta, mFileMetadata);
}
// Sniffer
@@ -861,22 +868,22 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION_CURRENT,
UUID("1364b048-cc45-4fda-9934-327d0ebf9829"),
1,
"FLAC Extractor",
{
- [](
+ .v2 = [](
CDataSource *source,
float *confidence,
void **,
- FreeMetaFunc *) -> CreatorFunc {
+ FreeMetaFunc *) -> CreatorFuncV2 {
DataSourceHelper helper(source);
if (SniffFLAC(&helper, confidence)) {
return [](
CDataSource *source,
- void *) -> CMediaExtractor* {
- return wrap(new FLACExtractor(new DataSourceHelper(source)));};
+ void *) -> CMediaExtractorV2* {
+ return wrapV2(new FLACExtractor(new DataSourceHelper(source)));};
}
return NULL;
}
diff --git a/media/extractors/flac/FLACExtractor.h b/media/extractors/flac/FLACExtractor.h
index 829f661..323307b 100644
--- a/media/extractors/flac/FLACExtractor.h
+++ b/media/extractors/flac/FLACExtractor.h
@@ -20,23 +20,23 @@
#include <media/DataSourceBase.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/MediaExtractorPluginHelper.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/NdkMediaFormat.h>
#include <utils/String8.h>
namespace android {
class FLACParser;
-class FLACExtractor : public MediaExtractorPluginHelper {
+class FLACExtractor : public MediaExtractorPluginHelperV2 {
public:
explicit FLACExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelper *getTrack(size_t index);
- virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+ virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
- virtual status_t getMetaData(MetaDataBase& meta);
+ virtual media_status_t getMetaData(AMediaFormat *meta);
virtual const char * name() { return "FLACExtractor"; }
protected:
@@ -46,10 +46,10 @@
DataSourceHelper *mDataSource;
FLACParser *mParser;
status_t mInitCheck;
- MetaDataBase mFileMetadata;
+ AMediaFormat *mFileMetadata;
// There is only one track
- MetaDataBase mTrackMetadata;
+ AMediaFormat *mTrackMetadata;
FLACExtractor(const FLACExtractor &);
FLACExtractor &operator=(const FLACExtractor &);
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index 7c6fc75..c6deb18 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -10,10 +10,12 @@
shared_libs: [
"liblog",
"libmediaextractor",
+ "libmediandk",
],
static_libs: [
"libstagefright_foundation",
+ "libstagefright_metadatautils",
"libutils",
"libvorbisidec",
],
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 123ac91..1b4fe27 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -24,7 +24,6 @@
#include <utils/Vector.h>
#include <media/DataSourceBase.h>
#include <media/ExtractorUtils.h>
-#include <media/VorbisComment.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/base64.h>
@@ -34,6 +33,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaDataBase.h>
+#include <media/stagefright/MetaDataUtils.h>
#include <utils/String8.h>
extern "C" {
@@ -47,15 +47,15 @@
namespace android {
-struct OggSource : public MediaTrackHelper {
+struct OggSource : public MediaTrackHelperV2 {
explicit OggSource(OggExtractor *extractor);
- virtual status_t getFormat(MetaDataBase &);
+ virtual media_status_t getFormat(AMediaFormat *);
- virtual status_t start();
- virtual status_t stop();
+ virtual media_status_t start();
+ virtual media_status_t stop();
- virtual status_t read(
+ virtual media_status_t read(
MediaBufferBase **buffer, const ReadOptions *options = NULL);
protected:
@@ -77,7 +77,7 @@
int64_t seekPreRollUs);
virtual ~MyOggExtractor();
- status_t getFormat(MetaDataBase &) const;
+ media_status_t getFormat(AMediaFormat *) const;
// Returns an approximate bitrate in bits per second.
virtual uint64_t approxBitrate() const = 0;
@@ -88,9 +88,8 @@
status_t init();
- status_t getFileMetaData(MetaDataBase &meta) {
- meta = mFileMeta;
- return OK;
+ media_status_t getFileMetaData(AMediaFormat *meta) {
+ return AMediaFormat_copy(meta, mFileMeta);
}
protected:
@@ -129,8 +128,8 @@
vorbis_info mVi;
vorbis_comment mVc;
- MetaDataBase mMeta;
- MetaDataBase mFileMeta;
+ AMediaFormat *mMeta;
+ AMediaFormat *mFileMeta;
Vector<TOCEntry> mTableOfContents;
@@ -237,27 +236,27 @@
}
}
-status_t OggSource::getFormat(MetaDataBase &meta) {
+media_status_t OggSource::getFormat(AMediaFormat *meta) {
return mExtractor->mImpl->getFormat(meta);
}
-status_t OggSource::start() {
+media_status_t OggSource::start() {
if (mStarted) {
- return INVALID_OPERATION;
+ return AMEDIA_ERROR_INVALID_OPERATION;
}
mStarted = true;
- return OK;
+ return AMEDIA_OK;
}
-status_t OggSource::stop() {
+media_status_t OggSource::stop() {
mStarted = false;
- return OK;
+ return AMEDIA_OK;
}
-status_t OggSource::read(
+media_status_t OggSource::read(
MediaBufferBase **out, const ReadOptions *options) {
*out = NULL;
@@ -266,7 +265,7 @@
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
status_t err = mExtractor->mImpl->seekToTime(seekTimeUs);
if (err != OK) {
- return err;
+ return AMEDIA_ERROR_UNKNOWN;
}
}
@@ -274,7 +273,7 @@
status_t err = mExtractor->mImpl->readNextPacket(&packet);
if (err != OK) {
- return err;
+ return AMEDIA_ERROR_UNKNOWN;
}
#if 0
@@ -290,7 +289,7 @@
*out = packet;
- return OK;
+ return AMEDIA_OK;
}
////////////////////////////////////////////////////////////////////////////////
@@ -316,16 +315,19 @@
vorbis_info_init(&mVi);
vorbis_comment_init(&mVc);
+ mMeta = AMediaFormat_new();
+ mFileMeta = AMediaFormat_new();
}
MyOggExtractor::~MyOggExtractor() {
+ AMediaFormat_delete(mFileMeta);
+ AMediaFormat_delete(mMeta);
vorbis_comment_clear(&mVc);
vorbis_info_clear(&mVi);
}
-status_t MyOggExtractor::getFormat(MetaDataBase &meta) const {
- meta = mMeta;
- return OK;
+media_status_t MyOggExtractor::getFormat(AMediaFormat *meta) const {
+ return AMediaFormat_copy(meta, mMeta);
}
status_t MyOggExtractor::findNextPage(
@@ -832,7 +834,7 @@
}
status_t MyOggExtractor::init() {
- mMeta.setCString(kKeyMIMEType, mMimeType);
+ AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType);
status_t err;
MediaBufferBase *packet;
@@ -865,7 +867,7 @@
int64_t durationUs = getTimeUsOfGranule(lastGranulePosition);
- mMeta.setInt64(kKeyDuration, durationUs);
+ AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, durationUs);
buildTableOfContents();
}
@@ -981,11 +983,14 @@
mChannelCount = data[9];
mCodecDelay = U16LE_AT(&data[10]);
- mMeta.setData(kKeyOpusHeader, 0, data, size);
- mMeta.setInt32(kKeySampleRate, kOpusSampleRate);
- mMeta.setInt32(kKeyChannelCount, mChannelCount);
- mMeta.setInt64(kKeyOpusSeekPreRoll /* ns */, kOpusSeekPreRollUs * 1000 /* = 80 ms*/);
- mMeta.setInt64(kKeyOpusCodecDelay /* ns */,
+ // kKeyOpusHeader is csd-0
+ AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_0, data, size);
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, kOpusSampleRate);
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mChannelCount);
+ // are these actually used anywhere?
+ // (they are kKeyOpusSeekPreRoll and kKeyOpusCodecDelay respectively)
+ AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_CSD_2, kOpusSeekPreRollUs * 1000 /* = 80 ms*/);
+ AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_CSD_1,
mCodecDelay /* sample/s */ * 1000000000ll / kOpusSampleRate);
return OK;
@@ -1122,10 +1127,10 @@
return ERROR_MALFORMED;
}
- mMeta.setData(kKeyVorbisInfo, 0, data, size);
- mMeta.setInt32(kKeySampleRate, mVi.rate);
- mMeta.setInt32(kKeyChannelCount, mVi.channels);
- mMeta.setInt32(kKeyBitRate, mVi.bitrate_nominal);
+ AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_0, data, size);
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, mVi.rate);
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mVi.channels);
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_BIT_RATE, mVi.bitrate_nominal);
ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
@@ -1140,7 +1145,7 @@
if (mSource->getSize(&size) == OK) {
uint64_t bps = approxBitrate();
if (bps != 0) {
- mMeta.setInt64(kKeyDuration, size * 8000000ll / bps);
+ AMediaFormat_setInt64(mMeta, AMEDIAFORMAT_KEY_DURATION, size * 8000000ll / bps);
}
}
break;
@@ -1162,7 +1167,7 @@
return ERROR_MALFORMED;
}
- mMeta.setData(kKeyVorbisBooks, 0, data, size);
+ AMediaFormat_setBuffer(mMeta, AMEDIAFORMAT_KEY_CSD_1, data, size);
break;
}
}
@@ -1180,12 +1185,12 @@
void MyOggExtractor::parseFileMetaData() {
- mFileMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);
+ AMediaFormat_setString(mFileMeta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_OGG);
for (int i = 0; i < mVc.comments; ++i) {
const char *comment = mVc.user_comments[i];
size_t commentLength = mVc.comment_lengths[i];
- parseVorbisComment(&mFileMeta, comment, commentLength);
+ parseVorbisComment(mFileMeta, comment, commentLength);
//ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
}
}
@@ -1227,7 +1232,7 @@
return mInitCheck != OK ? 0 : 1;
}
-MediaTrackHelper *OggExtractor::getTrack(size_t index) {
+MediaTrackHelperV2 *OggExtractor::getTrack(size_t index) {
if (index >= 1) {
return NULL;
}
@@ -1235,27 +1240,27 @@
return new OggSource(this);
}
-status_t OggExtractor::getTrackMetaData(
- MetaDataBase &meta,
+media_status_t OggExtractor::getTrackMetaData(
+ AMediaFormat *meta,
size_t index, uint32_t /* flags */) {
if (index >= 1) {
- return UNKNOWN_ERROR;
+ return AMEDIA_ERROR_UNKNOWN;
}
return mImpl->getFormat(meta);
}
-status_t OggExtractor::getMetaData(MetaDataBase &meta) {
+media_status_t OggExtractor::getMetaData(AMediaFormat *meta) {
return mImpl->getFileMetaData(meta);
}
-static CMediaExtractor* CreateExtractor(
+static CMediaExtractorV2* CreateExtractor(
CDataSource *source,
void *) {
- return wrap(new OggExtractor(new DataSourceHelper(source)));
+ return wrapV2(new OggExtractor(new DataSourceHelper(source)));
}
-static CreatorFunc Sniff(
+static CreatorFuncV2 Sniff(
CDataSource *source,
float *confidence,
void **,
@@ -1276,11 +1281,11 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION_CURRENT,
UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"),
1, // version
"Ogg Extractor",
- { Sniff }
+ { .v2 = Sniff }
};
}
diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h
index c70f832..cd674f3 100644
--- a/media/extractors/ogg/OggExtractor.h
+++ b/media/extractors/ogg/OggExtractor.h
@@ -21,6 +21,7 @@
#include <utils/Errors.h>
#include <media/MediaExtractorPluginApi.h>
#include <media/MediaExtractorPluginHelper.h>
+#include <media/NdkMediaFormat.h>
namespace android {
@@ -30,14 +31,14 @@
struct MyOggExtractor;
struct OggSource;
-struct OggExtractor : public MediaExtractorPluginHelper {
+struct OggExtractor : public MediaExtractorPluginHelperV2 {
explicit OggExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelper *getTrack(size_t index);
- virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+ virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
- virtual status_t getMetaData(MetaDataBase& meta);
+ virtual media_status_t getMetaData(AMediaFormat *meta);
virtual const char * name() { return "OggExtractor"; }
protected:
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
index 4ffbb69..0871d60 100644
--- a/media/libmediaextractor/Android.bp
+++ b/media/libmediaextractor/Android.bp
@@ -38,7 +38,6 @@
"MediaSource.cpp",
"MetaData.cpp",
"MetaDataBase.cpp",
- "VorbisComment.cpp",
],
clang: true,
diff --git a/media/libmediaextractor/VorbisComment.cpp b/media/libmediaextractor/VorbisComment.cpp
deleted file mode 100644
index 6d16385..0000000
--- a/media/libmediaextractor/VorbisComment.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "VorbisComment"
-#include <utils/Log.h>
-
-#include "media/VorbisComment.h"
-
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MetaDataBase.h>
-
-namespace android {
-
-static void extractAlbumArt(
- MetaDataBase *fileMeta, const void *data, size_t size) {
- ALOGV("extractAlbumArt from '%s'", (const char *)data);
-
- sp<ABuffer> flacBuffer = decodeBase64(AString((const char *)data, size));
- if (flacBuffer == NULL) {
- ALOGE("malformed base64 encoded data.");
- return;
- }
-
- size_t flacSize = flacBuffer->size();
- uint8_t *flac = flacBuffer->data();
- ALOGV("got flac of size %zu", flacSize);
-
- uint32_t picType;
- uint32_t typeLen;
- uint32_t descLen;
- uint32_t dataLen;
- char type[128];
-
- if (flacSize < 8) {
- return;
- }
-
- picType = U32_AT(flac);
-
- if (picType != 3) {
- // This is not a front cover.
- return;
- }
-
- typeLen = U32_AT(&flac[4]);
- if (typeLen > sizeof(type) - 1) {
- return;
- }
-
- // we've already checked above that flacSize >= 8
- if (flacSize - 8 < typeLen) {
- return;
- }
-
- memcpy(type, &flac[8], typeLen);
- type[typeLen] = '\0';
-
- ALOGV("picType = %d, type = '%s'", picType, type);
-
- if (!strcmp(type, "-->")) {
- // This is not inline cover art, but an external url instead.
- return;
- }
-
- if (flacSize < 32 || flacSize - 32 < typeLen) {
- return;
- }
-
- descLen = U32_AT(&flac[8 + typeLen]);
- if (flacSize - 32 - typeLen < descLen) {
- return;
- }
-
- dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
-
- // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
- if (flacSize - 32 - typeLen - descLen < dataLen) {
- return;
- }
-
- ALOGV("got image data, %zu trailing bytes",
- flacSize - 32 - typeLen - descLen - dataLen);
-
- fileMeta->setData(
- kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen);
-}
-
-void parseVorbisComment(
- MetaDataBase *fileMeta, const char *comment, size_t commentLength)
-{
- struct {
- const char *const mTag;
- uint32_t mKey;
- } kMap[] = {
- { "TITLE", kKeyTitle },
- { "ARTIST", kKeyArtist },
- { "ALBUMARTIST", kKeyAlbumArtist },
- { "ALBUM ARTIST", kKeyAlbumArtist },
- { "COMPILATION", kKeyCompilation },
- { "ALBUM", kKeyAlbum },
- { "COMPOSER", kKeyComposer },
- { "GENRE", kKeyGenre },
- { "AUTHOR", kKeyAuthor },
- { "TRACKNUMBER", kKeyCDTrackNumber },
- { "DISCNUMBER", kKeyDiscNumber },
- { "DATE", kKeyDate },
- { "YEAR", kKeyYear },
- { "LYRICIST", kKeyWriter },
- { "METADATA_BLOCK_PICTURE", kKeyAlbumArt },
- { "ANDROID_LOOP", kKeyAutoLoop },
- };
-
- for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
- size_t tagLen = strlen(kMap[j].mTag);
- if (!strncasecmp(kMap[j].mTag, comment, tagLen)
- && comment[tagLen] == '=') {
- if (kMap[j].mKey == kKeyAlbumArt) {
- extractAlbumArt(
- fileMeta,
- &comment[tagLen + 1],
- commentLength - tagLen - 1);
- } else if (kMap[j].mKey == kKeyAutoLoop) {
- if (!strcasecmp(&comment[tagLen + 1], "true")) {
- fileMeta->setInt32(kKeyAutoLoop, true);
- }
- } else {
- fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]);
- }
- }
- }
-
-}
-
-} // namespace android
diff --git a/media/libmediaextractor/include/media/VorbisComment.h b/media/libmediaextractor/include/media/VorbisComment.h
deleted file mode 100644
index 8ba3295..0000000
--- a/media/libmediaextractor/include/media/VorbisComment.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 VORBIS_COMMENT_H_
-#define VORBIS_COMMENT_H_
-
-namespace android {
-
-class MetaDataBase;
-
-void parseVorbisComment(
- MetaDataBase *fileMeta, const char *comment, size_t commentLength);
-
-} // namespace android
-
-#endif // VORBIS_COMMENT_H_
diff --git a/media/libstagefright/MetaDataUtils.cpp b/media/libstagefright/MetaDataUtils.cpp
index 5672145..2cf79c3 100644
--- a/media/libstagefright/MetaDataUtils.cpp
+++ b/media/libstagefright/MetaDataUtils.cpp
@@ -19,8 +19,10 @@
#include <utils/Log.h>
#include <media/stagefright/foundation/avc_utils.h>
+#include <media/stagefright/foundation/base64.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaDataUtils.h>
#include <media/stagefright/Utils.h>
@@ -192,4 +194,135 @@
return true;
}
+
+static void extractAlbumArt(
+ AMediaFormat *fileMeta, const void *data, size_t size) {
+ ALOGV("extractAlbumArt from '%s'", (const char *)data);
+
+ size_t inLen = strnlen((const char *)data, size);
+ size_t flacSize = inLen / 4 * 3;
+ uint8_t *flac = new uint8_t[flacSize];
+ if (!decodeBase64(flac, &flacSize, (const char*)data)) {
+ ALOGE("malformed base64 encoded data.");
+ delete[] flac;
+ return;
+ }
+
+ ALOGV("got flac of size %zu", flacSize);
+
+ uint32_t picType;
+ uint32_t typeLen;
+ uint32_t descLen;
+ uint32_t dataLen;
+ char type[128];
+
+ if (flacSize < 8) {
+ delete[] flac;
+ return;
+ }
+
+ picType = U32_AT(flac);
+
+ if (picType != 3) {
+ // This is not a front cover.
+ delete[] flac;
+ return;
+ }
+
+ typeLen = U32_AT(&flac[4]);
+ if (typeLen > sizeof(type) - 1) {
+ delete[] flac;
+ return;
+ }
+
+ // we've already checked above that flacSize >= 8
+ if (flacSize - 8 < typeLen) {
+ delete[] flac;
+ return;
+ }
+
+ memcpy(type, &flac[8], typeLen);
+ type[typeLen] = '\0';
+
+ ALOGV("picType = %d, type = '%s'", picType, type);
+
+ if (!strcmp(type, "-->")) {
+ // This is not inline cover art, but an external url instead.
+ delete[] flac;
+ return;
+ }
+
+ if (flacSize < 32 || flacSize - 32 < typeLen) {
+ delete[] flac;
+ return;
+ }
+
+ descLen = U32_AT(&flac[8 + typeLen]);
+ if (flacSize - 32 - typeLen < descLen) {
+ delete[] flac;
+ return;
+ }
+
+ dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
+
+ // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
+ if (flacSize - 32 - typeLen - descLen < dataLen) {
+ delete[] flac;
+ return;
+ }
+
+ ALOGV("got image data, %zu trailing bytes",
+ flacSize - 32 - typeLen - descLen - dataLen);
+
+ AMediaFormat_setBuffer(fileMeta, AMEDIAFORMAT_KEY_ALBUMART,
+ &flac[8 + typeLen + 4 + descLen + 20], dataLen);
+
+ delete[] flac;
+}
+
+void parseVorbisComment(
+ AMediaFormat *fileMeta, const char *comment, size_t commentLength) {
+ struct {
+ const char *const mTag;
+ const char *mKey;
+ } kMap[] = {
+ { "TITLE", AMEDIAFORMAT_KEY_TITLE },
+ { "ARTIST", AMEDIAFORMAT_KEY_ARTIST },
+ { "ALBUMARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
+ { "ALBUM ARTIST", AMEDIAFORMAT_KEY_ALBUMARTIST },
+ { "COMPILATION", AMEDIAFORMAT_KEY_COMPILATION },
+ { "ALBUM", AMEDIAFORMAT_KEY_ALBUM },
+ { "COMPOSER", AMEDIAFORMAT_KEY_COMPOSER },
+ { "GENRE", AMEDIAFORMAT_KEY_GENRE },
+ { "AUTHOR", AMEDIAFORMAT_KEY_AUTHOR },
+ { "TRACKNUMBER", AMEDIAFORMAT_KEY_CDTRACKNUMBER },
+ { "DISCNUMBER", AMEDIAFORMAT_KEY_DISCNUMBER },
+ { "DATE", AMEDIAFORMAT_KEY_DATE },
+ { "YEAR", AMEDIAFORMAT_KEY_YEAR },
+ { "LYRICIST", AMEDIAFORMAT_KEY_LYRICIST },
+ { "METADATA_BLOCK_PICTURE", AMEDIAFORMAT_KEY_ALBUMART },
+ { "ANDROID_LOOP", AMEDIAFORMAT_KEY_LOOP },
+ };
+
+ for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
+ size_t tagLen = strlen(kMap[j].mTag);
+ if (!strncasecmp(kMap[j].mTag, comment, tagLen)
+ && comment[tagLen] == '=') {
+ if (kMap[j].mKey == AMEDIAFORMAT_KEY_ALBUMART) {
+ extractAlbumArt(
+ fileMeta,
+ &comment[tagLen + 1],
+ commentLength - tagLen - 1);
+ } else if (kMap[j].mKey == AMEDIAFORMAT_KEY_LOOP) {
+ if (!strcasecmp(&comment[tagLen + 1], "true")) {
+ AMediaFormat_setInt32(fileMeta, AMEDIAFORMAT_KEY_LOOP, 1);
+ }
+ } else {
+ AMediaFormat_setString(fileMeta, kMap[j].mKey, &comment[tagLen + 1]);
+ }
+ }
+ }
+
+}
+
} // namespace android
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index a17b648..456e2e3 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -578,8 +578,10 @@
{ "cdtracknum", kKeyCDTrackNumber },
{ "compilation", kKeyCompilation },
{ "composer", kKeyComposer },
+ { "date", kKeyDate },
{ "discnum", kKeyDiscNumber },
{ "genre", kKeyGenre },
+ { "lyricist", kKeyWriter },
{ "title", kKeyTitle },
{ "year", kKeyYear },
}
@@ -596,6 +598,11 @@
if (msg->findBuffer("albumart", &buf)) {
meta->setData(kKeyAlbumArt, MetaDataBase::Type::TYPE_NONE, buf->data(), buf->size());
}
+
+ int32_t loop;
+ if (msg->findInt32("loop", &loop)) {
+ meta->setInt32(kKeyAutoLoop, loop);
+ }
}
void convertMetaDataToMessageTags(const MetaDataBase *meta, sp<AMessage> format) {
@@ -612,6 +619,10 @@
sp<ABuffer> buf = ABuffer::CreateAsCopy(data, size);
format->setBuffer("albumart", buf);
}
+ int32_t loop;
+ if (meta->findInt32(kKeyAutoLoop, &loop)) {
+ format->setInt32("loop", loop);
+ }
}
status_t convertMetaDataToMessage(
diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp
index 8f32582..834b88f 100644
--- a/media/libstagefright/foundation/base64.cpp
+++ b/media/libstagefright/foundation/base64.cpp
@@ -28,14 +28,31 @@
return NULL;
}
+ size_t bufSize = n / 4 * 3;
+ sp<ABuffer> buf = new ABuffer(bufSize);
+
+ if (decodeBase64(buf->data(), &bufSize, s.c_str())) {
+ buf->setRange(0, bufSize);
+ return buf;
+ }
+ return NULL;
+}
+
+bool decodeBase64(uint8_t *out, size_t *inOutBufSize, const char* s) {
+ size_t n = strlen(s);
+
+ if ((n % 4) != 0) {
+ return false;
+ }
+
size_t padding = 0;
- if (n >= 1 && s.c_str()[n - 1] == '=') {
+ if (n >= 1 && s[n - 1] == '=') {
padding = 1;
- if (n >= 2 && s.c_str()[n - 2] == '=') {
+ if (n >= 2 && s[n - 2] == '=') {
padding = 2;
- if (n >= 3 && s.c_str()[n - 3] == '=') {
+ if (n >= 3 && s[n - 3] == '=') {
padding = 3;
}
}
@@ -45,15 +62,13 @@
// already made sure that n % 4 == 0.
size_t outLen = (n / 4) * 3 - padding;
- sp<ABuffer> buffer = new ABuffer(outLen);
- uint8_t *out = buffer->data();
- if (out == NULL || buffer->size() < outLen) {
- return NULL;
+ if (out == NULL || *inOutBufSize < outLen) {
+ return false;
}
size_t j = 0;
uint32_t accum = 0;
for (size_t i = 0; i < n; ++i) {
- char c = s.c_str()[i];
+ char c = s[i];
unsigned value;
if (c >= 'A' && c <= 'Z') {
value = c - 'A';
@@ -66,10 +81,10 @@
} else if (c == '/' || c == '_') {
value = 63;
} else if (c != '=') {
- return NULL;
+ return false;
} else {
if (i < n - padding) {
- return NULL;
+ return false;
}
value = 0;
@@ -86,7 +101,8 @@
}
}
- return buffer;
+ *inOutBufSize = j;
+ return true;
}
static char encode6Bit(unsigned x) {
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h b/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
index abc95e0..60fb9ff 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
@@ -26,6 +26,9 @@
struct AString;
sp<ABuffer> decodeBase64(const AString &s);
+
+bool decodeBase64(uint8_t *out, size_t *inOutBufSize, const char* s);
+
void encodeBase64(const void *data, size_t size, AString *out);
void encodeBase64Url(const void *data, size_t size, AString *out);
diff --git a/media/libstagefright/include/media/stagefright/MetaDataUtils.h b/media/libstagefright/include/media/stagefright/MetaDataUtils.h
index fd79a9e..e87c7f9 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataUtils.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataUtils.h
@@ -34,6 +34,9 @@
bool MakeAACCodecSpecificData(AMediaFormat *meta, unsigned profile, unsigned sampling_freq_index,
unsigned channel_configuration);
+void parseVorbisComment(
+ AMediaFormat *fileMeta, const char *comment, size_t commentLength);
+
} // namespace android
#endif // META_DATA_UTILS_H_
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index a55067e..22fbb42 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -291,6 +291,7 @@
EXPORT const char* AMEDIAFORMAT_KEY_CSD_0 = "csd-0";
EXPORT const char* AMEDIAFORMAT_KEY_CSD_1 = "csd-1";
EXPORT const char* AMEDIAFORMAT_KEY_CSD_2 = "csd-2";
+EXPORT const char* AMEDIAFORMAT_KEY_DATE = "date";
EXPORT const char* AMEDIAFORMAT_KEY_DISCNUMBER = "discnum";
EXPORT const char* AMEDIAFORMAT_KEY_DISPLAY_CROP = "crop";
EXPORT const char* AMEDIAFORMAT_KEY_DISPLAY_HEIGHT = "display-height";
@@ -314,6 +315,8 @@
EXPORT const char* AMEDIAFORMAT_KEY_LANGUAGE = "language";
EXPORT const char* AMEDIAFORMAT_KEY_LATENCY = "latency";
EXPORT const char* AMEDIAFORMAT_KEY_LEVEL = "level";
+EXPORT const char* AMEDIAFORMAT_KEY_LOOP = "loop";
+EXPORT const char* AMEDIAFORMAT_KEY_LYRICIST = "lyricist";
EXPORT const char* AMEDIAFORMAT_KEY_MAX_HEIGHT = "max-height";
EXPORT const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE = "max-input-size";
EXPORT const char* AMEDIAFORMAT_KEY_MAX_WIDTH = "max-width";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 2bdc5e3..3fc28f3 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -184,10 +184,13 @@
extern const char* AMEDIAFORMAT_KEY_CDTRACKNUMBER __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_COMPILATION __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_COMPOSER __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_DATE __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_DISCNUMBER __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_ENCODER_DELAY __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_ENCODER_PADDING __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_GENRE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_LOOP __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_LYRICIST __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_TITLE __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_YEAR __INTRODUCED_IN(29);