Remove RefBase from the extractor API
- Add MetaDataBase base class that MetaData derives from, but which
does not derive from RefBase.
- MediaBuffer::meta_data() now returns a MetaDataBase& rather than an
sp<MetaData>
- Rename MediaSourceBase to MediaTrack.
- MediaSource no longer derives from MediaSourceBase (or MediaTrack)
- MediaTrack::getFormat(), MediaExtractor::getTrackMetaData() and
MediaExtractor::getMetaData() all take a MetaDataBase& parameter that
they fill out, rather than returning a MetaData directly (the
corresponding methods on MediaSource and RemoteMediaExtractor continue
to return MetaData)
Bug: 67908544
Test: CTS MediaPlayerTest, DecoderTest, EncodeDecodeTest, manually record video
Change-Id: Ib531ab309061290be33d40d6100c9a8127e22083
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/extractors/mp3/MP3Extractor.cpp
index 90ee653..33cff96 100644
--- a/media/extractors/mp3/MP3Extractor.cpp
+++ b/media/extractors/mp3/MP3Extractor.cpp
@@ -25,7 +25,7 @@
#include "XINGSeeker.h"
#include <media/DataSourceBase.h>
-#include <media/MediaSourceBase.h>
+#include <media/MediaTrack.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/avc_utils.h>
@@ -209,17 +209,17 @@
return valid;
}
-class MP3Source : public MediaSourceBase {
+class MP3Source : public MediaTrack {
public:
MP3Source(
- const sp<MetaData> &meta, DataSourceBase *source,
+ MetaDataBase &meta, DataSourceBase *source,
off64_t first_frame_pos, uint32_t fixed_header,
- const sp<MP3Seeker> &seeker);
+ MP3Seeker *seeker);
- virtual status_t start(MetaData *params = NULL);
+ virtual status_t start(MetaDataBase *params = NULL);
virtual status_t stop();
- virtual sp<MetaData> getFormat();
+ virtual status_t getFormat(MetaDataBase &meta);
virtual status_t read(
MediaBufferBase **buffer, const ReadOptions *options = NULL);
@@ -229,14 +229,14 @@
private:
static const size_t kMaxFrameSize;
- sp<MetaData> mMeta;
+ MetaDataBase &mMeta;
DataSourceBase *mDataSource;
off64_t mFirstFramePos;
uint32_t mFixedHeader;
off64_t mCurrentPos;
int64_t mCurrentTimeUs;
bool mStarted;
- sp<MP3Seeker> mSeeker;
+ MP3Seeker *mSeeker;
MediaBufferGroup *mGroup;
int64_t mBasisTimeUs;
@@ -246,31 +246,31 @@
MP3Source &operator=(const MP3Source &);
};
+struct Mp3Meta {
+ off64_t pos;
+ off64_t post_id3_pos;
+ uint32_t header;
+};
+
MP3Extractor::MP3Extractor(
- DataSourceBase *source, const sp<AMessage> &meta)
+ DataSourceBase *source, Mp3Meta *meta)
: mInitCheck(NO_INIT),
mDataSource(source),
mFirstFramePos(-1),
- mFixedHeader(0) {
+ mFixedHeader(0),
+ mSeeker(NULL) {
off64_t pos = 0;
off64_t post_id3_pos;
uint32_t header;
bool success;
- int64_t meta_offset;
- uint32_t meta_header;
- int64_t meta_post_id3_offset;
- if (meta != NULL
- && meta->findInt64("offset", &meta_offset)
- && meta->findInt32("header", (int32_t *)&meta_header)
- && meta->findInt64("post-id3-offset", &meta_post_id3_offset)) {
+ if (meta != NULL) {
// The sniffer has already done all the hard work for us, simply
// accept its judgement.
- pos = (off64_t)meta_offset;
- header = meta_header;
- post_id3_pos = (off64_t)meta_post_id3_offset;
-
+ pos = meta->pos;
+ header = meta->header;
+ post_id3_pos = meta->post_id3_pos;
success = true;
} else {
success = Resync(mDataSource, 0, &pos, &post_id3_pos, &header);
@@ -283,8 +283,7 @@
mFirstFramePos = pos;
mFixedHeader = header;
- mMeta = new MetaData;
- sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
+ XINGSeeker *seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
if (seeker == NULL) {
mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
@@ -293,8 +292,8 @@
int encd = seeker->getEncoderDelay();
int encp = seeker->getEncoderPadding();
if (encd != 0 || encp != 0) {
- mMeta->setInt32(kKeyEncoderDelay, encd);
- mMeta->setInt32(kKeyEncoderPadding, encp);
+ mMeta.setInt32(kKeyEncoderDelay, encd);
+ mMeta.setInt32(kKeyEncoderPadding, encp);
}
}
@@ -330,21 +329,21 @@
switch (layer) {
case 1:
- mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
+ mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
break;
case 2:
- mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
+ mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
break;
case 3:
- mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ mMeta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
break;
default:
TRESPASS();
}
- mMeta->setInt32(kKeySampleRate, sample_rate);
- mMeta->setInt32(kKeyBitRate, bitrate * 1000);
- mMeta->setInt32(kKeyChannelCount, num_channels);
+ mMeta.setInt32(kKeySampleRate, sample_rate);
+ mMeta.setInt32(kKeyBitRate, bitrate * 1000);
+ mMeta.setInt32(kKeyChannelCount, num_channels);
int64_t durationUs;
@@ -364,7 +363,7 @@
}
if (durationUs >= 0) {
- mMeta->setInt64(kKeyDuration, durationUs);
+ mMeta.setInt64(kKeyDuration, durationUs);
}
mInitCheck = OK;
@@ -391,8 +390,8 @@
int32_t delay, padding;
if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) {
- mMeta->setInt32(kKeyEncoderDelay, delay);
- mMeta->setInt32(kKeyEncoderPadding, padding);
+ mMeta.setInt32(kKeyEncoderDelay, delay);
+ mMeta.setInt32(kKeyEncoderPadding, padding);
}
break;
}
@@ -403,11 +402,15 @@
}
}
+MP3Extractor::~MP3Extractor() {
+ delete mSeeker;
+}
+
size_t MP3Extractor::countTracks() {
return mInitCheck != OK ? 0 : 1;
}
-MediaSourceBase *MP3Extractor::getTrack(size_t index) {
+MediaTrack *MP3Extractor::getTrack(size_t index) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
@@ -417,13 +420,14 @@
mSeeker);
}
-sp<MetaData> MP3Extractor::getTrackMetaData(
+status_t MP3Extractor::getTrackMetaData(
+ MetaDataBase &meta,
size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
- return NULL;
+ return UNKNOWN_ERROR;
}
-
- return mMeta;
+ meta = mMeta;
+ return OK;
}
////////////////////////////////////////////////////////////////////////////////
@@ -436,9 +440,9 @@
// Set our max frame size to the nearest power of 2 above this size (aka, 4kB)
const size_t MP3Source::kMaxFrameSize = (1 << 12); /* 4096 bytes */
MP3Source::MP3Source(
- const sp<MetaData> &meta, DataSourceBase *source,
+ MetaDataBase &meta, DataSourceBase *source,
off64_t first_frame_pos, uint32_t fixed_header,
- const sp<MP3Seeker> &seeker)
+ MP3Seeker *seeker)
: mMeta(meta),
mDataSource(source),
mFirstFramePos(first_frame_pos),
@@ -458,7 +462,7 @@
}
}
-status_t MP3Source::start(MetaData *) {
+status_t MP3Source::start(MetaDataBase *) {
CHECK(!mStarted);
mGroup = new MediaBufferGroup;
@@ -487,8 +491,9 @@
return OK;
}
-sp<MetaData> MP3Source::getFormat() {
- return mMeta;
+status_t MP3Source::getFormat(MetaDataBase &meta) {
+ meta = mMeta;
+ return OK;
}
status_t MP3Source::read(
@@ -504,7 +509,7 @@
if (mSeeker == NULL
|| !mSeeker->getOffsetForTime(&actualSeekTimeUs, &mCurrentPos)) {
int32_t bitrate;
- if (!mMeta->findInt32(kKeyBitRate, &bitrate)) {
+ if (!mMeta.findInt32(kKeyBitRate, &bitrate)) {
// bitrate is in bits/sec.
ALOGI("no bitrate");
@@ -587,8 +592,8 @@
buffer->set_range(0, frame_size);
- buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
- buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+ buffer->meta_data().setInt64(kKeyTime, mCurrentTimeUs);
+ buffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
mCurrentPos += frame_size;
@@ -600,19 +605,17 @@
return OK;
}
-sp<MetaData> MP3Extractor::getMetaData() {
- sp<MetaData> meta = new MetaData;
-
+status_t MP3Extractor::getMetaData(MetaDataBase &meta) {
+ meta.clear();
if (mInitCheck != OK) {
- return meta;
+ return UNKNOWN_ERROR;
}
-
- meta->setCString(kKeyMIMEType, "audio/mpeg");
+ meta.setCString(kKeyMIMEType, "audio/mpeg");
ID3 id3(mDataSource);
if (!id3.isValid()) {
- return meta;
+ return OK;
}
struct Map {
@@ -651,7 +654,7 @@
it->getString(&s);
delete it;
- meta->setCString(kMap[i].key, s);
+ meta.setCString(kMap[i].key, s);
}
size_t dataSize;
@@ -659,26 +662,20 @@
const void *data = id3.getAlbumArt(&dataSize, &mime);
if (data) {
- meta->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
- meta->setCString(kKeyAlbumArtMIME, mime.string());
+ meta.setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
+ meta.setCString(kKeyAlbumArtMIME, mime.string());
}
- return meta;
+ return OK;
}
static MediaExtractor* CreateExtractor(
DataSourceBase *source,
void *meta) {
- sp<AMessage> metaData = static_cast<AMessage *>(meta);
+ Mp3Meta *metaData = static_cast<Mp3Meta *>(meta);
return new MP3Extractor(source, metaData);
}
-static void FreeMeta(void *meta) {
- if (meta != nullptr) {
- static_cast<AMessage *>(meta)->decStrong(nullptr);
- }
-}
-
static MediaExtractor::CreatorFunc Sniff(
DataSourceBase *source, float *confidence, void **meta,
MediaExtractor::FreeMetaFunc *freeMeta) {
@@ -698,14 +695,12 @@
return NULL;
}
- AMessage *msg = new AMessage;
- msg->setInt64("offset", pos);
- msg->setInt32("header", header);
- msg->setInt64("post-id3-offset", post_id3_pos);
- *meta = msg;
- *freeMeta = &FreeMeta;
- // ref count will be decreased in FreeMeta.
- msg->incStrong(nullptr);
+ Mp3Meta *mp3Meta = new Mp3Meta;
+ mp3Meta->pos = pos;
+ mp3Meta->header = header;
+ mp3Meta->post_id3_pos = post_id3_pos;
+ *meta = mp3Meta;
+ *freeMeta = ::free;
*confidence = 0.2f;
diff --git a/media/extractors/mp3/MP3Extractor.h b/media/extractors/mp3/MP3Extractor.h
index 6257112..485b0ca 100644
--- a/media/extractors/mp3/MP3Extractor.h
+++ b/media/extractors/mp3/MP3Extractor.h
@@ -20,6 +20,7 @@
#include <utils/Errors.h>
#include <media/MediaExtractor.h>
+#include <media/stagefright/MetaDataBase.h>
namespace android {
@@ -27,16 +28,18 @@
class DataSourceBase;
struct MP3Seeker;
class String8;
+struct Mp3Meta;
class MP3Extractor : public MediaExtractor {
public:
- MP3Extractor(DataSourceBase *source, const sp<AMessage> &meta);
+ MP3Extractor(DataSourceBase *source, Mp3Meta *meta);
+ ~MP3Extractor();
virtual size_t countTracks();
- virtual MediaSourceBase *getTrack(size_t index);
- virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
+ virtual MediaTrack *getTrack(size_t index);
+ virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
- virtual sp<MetaData> getMetaData();
+ virtual status_t getMetaData(MetaDataBase& meta);
virtual const char * name() { return "MP3Extractor"; }
private:
@@ -44,18 +47,14 @@
DataSourceBase *mDataSource;
off64_t mFirstFramePos;
- sp<MetaData> mMeta;
+ MetaDataBase mMeta;
uint32_t mFixedHeader;
- sp<MP3Seeker> mSeeker;
+ MP3Seeker *mSeeker;
MP3Extractor(const MP3Extractor &);
MP3Extractor &operator=(const MP3Extractor &);
};
-bool SniffMP3(
- DataSourceBase *source, String8 *mimeType, float *confidence,
- sp<AMessage> *meta);
-
} // namespace android
#endif // MP3_EXTRACTOR_H_
diff --git a/media/extractors/mp3/MP3Seeker.h b/media/extractors/mp3/MP3Seeker.h
index 599542e..0e3af25 100644
--- a/media/extractors/mp3/MP3Seeker.h
+++ b/media/extractors/mp3/MP3Seeker.h
@@ -23,7 +23,7 @@
namespace android {
-struct MP3Seeker : public RefBase {
+struct MP3Seeker {
MP3Seeker() {}
virtual bool getDuration(int64_t *durationUs) = 0;
@@ -33,7 +33,6 @@
// the actual time that seekpoint represents.
virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos) = 0;
-protected:
virtual ~MP3Seeker() {}
private:
diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/extractors/mp3/VBRISeeker.cpp
index 51c5d1f..523f14c 100644
--- a/media/extractors/mp3/VBRISeeker.cpp
+++ b/media/extractors/mp3/VBRISeeker.cpp
@@ -36,7 +36,7 @@
}
// static
-sp<VBRISeeker> VBRISeeker::CreateFromSource(
+VBRISeeker *VBRISeeker::CreateFromSource(
DataSourceBase *source, off64_t post_id3_pos) {
off64_t pos = post_id3_pos;
@@ -87,7 +87,7 @@
return NULL;
}
- sp<VBRISeeker> seeker = new (std::nothrow) VBRISeeker;
+ VBRISeeker *seeker = new (std::nothrow) VBRISeeker;
if (seeker == NULL) {
ALOGW("Couldn't allocate VBRISeeker");
return NULL;
@@ -97,6 +97,7 @@
uint8_t *buffer = new (std::nothrow) uint8_t[totalEntrySize];
if (!buffer) {
ALOGW("Couldn't allocate %zu bytes", totalEntrySize);
+ delete seeker;
return NULL;
}
@@ -104,7 +105,7 @@
if (n < (ssize_t)totalEntrySize) {
delete[] buffer;
buffer = NULL;
-
+ delete seeker;
return NULL;
}
diff --git a/media/extractors/mp3/VBRISeeker.h b/media/extractors/mp3/VBRISeeker.h
index e46af36..9213f6e 100644
--- a/media/extractors/mp3/VBRISeeker.h
+++ b/media/extractors/mp3/VBRISeeker.h
@@ -27,7 +27,7 @@
class DataSourceBase;
struct VBRISeeker : public MP3Seeker {
- static sp<VBRISeeker> CreateFromSource(
+ static VBRISeeker *CreateFromSource(
DataSourceBase *source, off64_t post_id3_pos);
virtual bool getDuration(int64_t *durationUs);
diff --git a/media/extractors/mp3/XINGSeeker.cpp b/media/extractors/mp3/XINGSeeker.cpp
index adfa8d2..95ca556 100644
--- a/media/extractors/mp3/XINGSeeker.cpp
+++ b/media/extractors/mp3/XINGSeeker.cpp
@@ -76,11 +76,8 @@
}
// static
-sp<XINGSeeker> XINGSeeker::CreateFromSource(
+XINGSeeker *XINGSeeker::CreateFromSource(
DataSourceBase *source, off64_t first_frame_pos) {
- sp<XINGSeeker> seeker = new XINGSeeker;
-
- seeker->mFirstFramePos = first_frame_pos;
uint8_t buffer[4];
int offset = first_frame_pos;
@@ -98,8 +95,6 @@
NULL, &samples_per_frame)) {
return NULL;
}
- seeker->mFirstFramePos += xingframesize;
-
uint8_t version = (buffer[1] >> 3) & 3;
// determine offset of XING header
@@ -132,9 +127,13 @@
offset += 4;
uint32_t flags = U32_AT(buffer);
+ XINGSeeker *seeker = new XINGSeeker;
+ seeker->mFirstFramePos = first_frame_pos + xingframesize;
+
if (flags & 0x0001) { // Frames field is present
if (source->readAt(offset, buffer, 4) < 4) {
- return NULL;
+ delete seeker;
+ return NULL;
}
int32_t frames = U32_AT(buffer);
// only update mDurationUs if the calculated duration is valid (non zero)
@@ -148,6 +147,7 @@
}
if (flags & 0x0002) { // Bytes field is present
if (source->readAt(offset, buffer, 4) < 4) {
+ delete seeker;
return NULL;
}
seeker->mSizeBytes = U32_AT(buffer);
@@ -155,6 +155,7 @@
}
if (flags & 0x0004) { // TOC field is present
if (source->readAt(offset + 1, seeker->mTOC, 99) < 99) {
+ delete seeker;
return NULL;
}
seeker->mTOCValid = true;
@@ -164,6 +165,7 @@
#if 0
if (flags & 0x0008) { // Quality indicator field is present
if (source->readAt(offset, buffer, 4) < 4) {
+ delete seeker;
return NULL;
}
// do something with the quality indicator
@@ -171,6 +173,7 @@
}
if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags
+ delete seeker;
return false;
}
diff --git a/media/extractors/mp3/XINGSeeker.h b/media/extractors/mp3/XINGSeeker.h
index db847bc..5867eae 100644
--- a/media/extractors/mp3/XINGSeeker.h
+++ b/media/extractors/mp3/XINGSeeker.h
@@ -25,7 +25,7 @@
class DataSourceBase;
struct XINGSeeker : public MP3Seeker {
- static sp<XINGSeeker> CreateFromSource(
+ static XINGSeeker *CreateFromSource(
DataSourceBase *source, off64_t first_frame_pos);
virtual bool getDuration(int64_t *durationUs);