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);