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/libmediaextractor/MetaData.cpp b/media/libmediaextractor/MetaData.cpp
index 69beea1..1d0a607 100644
--- a/media/libmediaextractor/MetaData.cpp
+++ b/media/libmediaextractor/MetaData.cpp
@@ -31,500 +31,20 @@
 
 namespace android {
 
-struct MetaData::typed_data {
-    typed_data();
-    ~typed_data();
 
-    typed_data(const MetaData::typed_data &);
-    typed_data &operator=(const MetaData::typed_data &);
-
-    void clear();
-    void setData(uint32_t type, const void *data, size_t size);
-    void getData(uint32_t *type, const void **data, size_t *size) const;
-    // may include hexdump of binary data if verbose=true
-    String8 asString(bool verbose) const;
-
-private:
-    uint32_t mType;
-    size_t mSize;
-
-    union {
-        void *ext_data;
-        float reservoir;
-    } u;
-
-    bool usesReservoir() const {
-        return mSize <= sizeof(u.reservoir);
-    }
-
-    void *allocateStorage(size_t size);
-    void freeStorage();
-
-    void *storage() {
-        return usesReservoir() ? &u.reservoir : u.ext_data;
-    }
-
-    const void *storage() const {
-        return usesReservoir() ? &u.reservoir : u.ext_data;
-    }
-};
-
-struct MetaData::Rect {
-    int32_t mLeft, mTop, mRight, mBottom;
-};
-
-
-struct MetaData::MetaDataInternal {
-    KeyedVector<uint32_t, MetaData::typed_data> mItems;
-};
-
-
-MetaData::MetaData()
-    : mInternalData(new MetaDataInternal()) {
+MetaData::MetaData() {
 }
 
 MetaData::MetaData(const MetaData &from)
-    : RefBase(),
-      mInternalData(new MetaDataInternal()) {
-    mInternalData->mItems = from.mInternalData->mItems;
+    : MetaDataBase(from) {
+}
+MetaData::MetaData(const MetaDataBase &from)
+    : MetaDataBase(from) {
 }
 
 MetaData::~MetaData() {
-    clear();
-    delete mInternalData;
 }
 
-void MetaData::clear() {
-    mInternalData->mItems.clear();
-}
-
-bool MetaData::remove(uint32_t key) {
-    ssize_t i = mInternalData->mItems.indexOfKey(key);
-
-    if (i < 0) {
-        return false;
-    }
-
-    mInternalData->mItems.removeItemsAt(i);
-
-    return true;
-}
-
-bool MetaData::setCString(uint32_t key, const char *value) {
-    return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
-}
-
-bool MetaData::setInt32(uint32_t key, int32_t value) {
-    return setData(key, TYPE_INT32, &value, sizeof(value));
-}
-
-bool MetaData::setInt64(uint32_t key, int64_t value) {
-    return setData(key, TYPE_INT64, &value, sizeof(value));
-}
-
-bool MetaData::setFloat(uint32_t key, float value) {
-    return setData(key, TYPE_FLOAT, &value, sizeof(value));
-}
-
-bool MetaData::setPointer(uint32_t key, void *value) {
-    return setData(key, TYPE_POINTER, &value, sizeof(value));
-}
-
-bool MetaData::setRect(
-        uint32_t key,
-        int32_t left, int32_t top,
-        int32_t right, int32_t bottom) {
-    Rect r;
-    r.mLeft = left;
-    r.mTop = top;
-    r.mRight = right;
-    r.mBottom = bottom;
-
-    return setData(key, TYPE_RECT, &r, sizeof(r));
-}
-
-/**
- * Note that the returned pointer becomes invalid when additional metadata is set.
- */
-bool MetaData::findCString(uint32_t key, const char **value) const {
-    uint32_t type;
-    const void *data;
-    size_t size;
-    if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
-        return false;
-    }
-
-    *value = (const char *)data;
-
-    return true;
-}
-
-bool MetaData::findInt32(uint32_t key, int32_t *value) const {
-    uint32_t type = 0;
-    const void *data;
-    size_t size;
-    if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
-        return false;
-    }
-
-    CHECK_EQ(size, sizeof(*value));
-
-    *value = *(int32_t *)data;
-
-    return true;
-}
-
-bool MetaData::findInt64(uint32_t key, int64_t *value) const {
-    uint32_t type = 0;
-    const void *data;
-    size_t size;
-    if (!findData(key, &type, &data, &size) || type != TYPE_INT64) {
-        return false;
-    }
-
-    CHECK_EQ(size, sizeof(*value));
-
-    *value = *(int64_t *)data;
-
-    return true;
-}
-
-bool MetaData::findFloat(uint32_t key, float *value) const {
-    uint32_t type = 0;
-    const void *data;
-    size_t size;
-    if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
-        return false;
-    }
-
-    CHECK_EQ(size, sizeof(*value));
-
-    *value = *(float *)data;
-
-    return true;
-}
-
-bool MetaData::findPointer(uint32_t key, void **value) const {
-    uint32_t type = 0;
-    const void *data;
-    size_t size;
-    if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
-        return false;
-    }
-
-    CHECK_EQ(size, sizeof(*value));
-
-    *value = *(void **)data;
-
-    return true;
-}
-
-bool MetaData::findRect(
-        uint32_t key,
-        int32_t *left, int32_t *top,
-        int32_t *right, int32_t *bottom) const {
-    uint32_t type = 0;
-    const void *data;
-    size_t size;
-    if (!findData(key, &type, &data, &size) || type != TYPE_RECT) {
-        return false;
-    }
-
-    CHECK_EQ(size, sizeof(Rect));
-
-    const Rect *r = (const Rect *)data;
-    *left = r->mLeft;
-    *top = r->mTop;
-    *right = r->mRight;
-    *bottom = r->mBottom;
-
-    return true;
-}
-
-bool MetaData::setData(
-        uint32_t key, uint32_t type, const void *data, size_t size) {
-    bool overwrote_existing = true;
-
-    ssize_t i = mInternalData->mItems.indexOfKey(key);
-    if (i < 0) {
-        typed_data item;
-        i = mInternalData->mItems.add(key, item);
-
-        overwrote_existing = false;
-    }
-
-    typed_data &item = mInternalData->mItems.editValueAt(i);
-
-    item.setData(type, data, size);
-
-    return overwrote_existing;
-}
-
-bool MetaData::findData(uint32_t key, uint32_t *type,
-                        const void **data, size_t *size) const {
-    ssize_t i = mInternalData->mItems.indexOfKey(key);
-
-    if (i < 0) {
-        return false;
-    }
-
-    const typed_data &item = mInternalData->mItems.valueAt(i);
-
-    item.getData(type, data, size);
-
-    return true;
-}
-
-bool MetaData::hasData(uint32_t key) const {
-    ssize_t i = mInternalData->mItems.indexOfKey(key);
-
-    if (i < 0) {
-        return false;
-    }
-
-    return true;
-}
-
-MetaData::typed_data::typed_data()
-    : mType(0),
-      mSize(0) {
-}
-
-MetaData::typed_data::~typed_data() {
-    clear();
-}
-
-MetaData::typed_data::typed_data(const typed_data &from)
-    : mType(from.mType),
-      mSize(0) {
-
-    void *dst = allocateStorage(from.mSize);
-    if (dst) {
-        memcpy(dst, from.storage(), mSize);
-    }
-}
-
-MetaData::typed_data &MetaData::typed_data::operator=(
-        const MetaData::typed_data &from) {
-    if (this != &from) {
-        clear();
-        mType = from.mType;
-        void *dst = allocateStorage(from.mSize);
-        if (dst) {
-            memcpy(dst, from.storage(), mSize);
-        }
-    }
-
-    return *this;
-}
-
-void MetaData::typed_data::clear() {
-    freeStorage();
-
-    mType = 0;
-}
-
-void MetaData::typed_data::setData(
-        uint32_t type, const void *data, size_t size) {
-    clear();
-
-    mType = type;
-
-    void *dst = allocateStorage(size);
-    if (dst) {
-        memcpy(dst, data, size);
-    }
-}
-
-void MetaData::typed_data::getData(
-        uint32_t *type, const void **data, size_t *size) const {
-    *type = mType;
-    *size = mSize;
-    *data = storage();
-}
-
-void *MetaData::typed_data::allocateStorage(size_t size) {
-    mSize = size;
-
-    if (usesReservoir()) {
-        return &u.reservoir;
-    }
-
-    u.ext_data = malloc(mSize);
-    if (u.ext_data == NULL) {
-        ALOGE("Couldn't allocate %zu bytes for item", size);
-        mSize = 0;
-    }
-    return u.ext_data;
-}
-
-void MetaData::typed_data::freeStorage() {
-    if (!usesReservoir()) {
-        if (u.ext_data) {
-            free(u.ext_data);
-            u.ext_data = NULL;
-        }
-    }
-
-    mSize = 0;
-}
-
-String8 MetaData::typed_data::asString(bool verbose) const {
-    String8 out;
-    const void *data = storage();
-    switch(mType) {
-        case TYPE_NONE:
-            out = String8::format("no type, size %zu)", mSize);
-            break;
-        case TYPE_C_STRING:
-            out = String8::format("(char*) %s", (const char *)data);
-            break;
-        case TYPE_INT32:
-            out = String8::format("(int32_t) %d", *(int32_t *)data);
-            break;
-        case TYPE_INT64:
-            out = String8::format("(int64_t) %" PRId64, *(int64_t *)data);
-            break;
-        case TYPE_FLOAT:
-            out = String8::format("(float) %f", *(float *)data);
-            break;
-        case TYPE_POINTER:
-            out = String8::format("(void*) %p", *(void **)data);
-            break;
-        case TYPE_RECT:
-        {
-            const Rect *r = (const Rect *)data;
-            out = String8::format("Rect(%d, %d, %d, %d)",
-                                  r->mLeft, r->mTop, r->mRight, r->mBottom);
-            break;
-        }
-
-        default:
-            out = String8::format("(unknown type %d, size %zu)", mType, mSize);
-            if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it
-                AString foo;
-                hexdump(data, mSize, 0, &foo);
-                out.append("\n");
-                out.append(foo.c_str());
-            }
-            break;
-    }
-    return out;
-}
-
-static void MakeFourCCString(uint32_t x, char *s) {
-    s[0] = x >> 24;
-    s[1] = (x >> 16) & 0xff;
-    s[2] = (x >> 8) & 0xff;
-    s[3] = x & 0xff;
-    s[4] = '\0';
-}
-
-String8 MetaData::toString() const {
-    String8 s;
-    for (int i = mInternalData->mItems.size(); --i >= 0;) {
-        int32_t key = mInternalData->mItems.keyAt(i);
-        char cc[5];
-        MakeFourCCString(key, cc);
-        const typed_data &item = mInternalData->mItems.valueAt(i);
-        s.appendFormat("%s: %s", cc, item.asString(false).string());
-        if (i != 0) {
-            s.append(", ");
-        }
-    }
-    return s;
-}
-void MetaData::dumpToLog() const {
-    for (int i = mInternalData->mItems.size(); --i >= 0;) {
-        int32_t key = mInternalData->mItems.keyAt(i);
-        char cc[5];
-        MakeFourCCString(key, cc);
-        const typed_data &item = mInternalData->mItems.valueAt(i);
-        ALOGI("%s: %s", cc, item.asString(true /* verbose */).string());
-    }
-}
-
-status_t MetaData::writeToParcel(Parcel &parcel) {
-    status_t ret;
-    size_t numItems = mInternalData->mItems.size();
-    ret = parcel.writeUint32(uint32_t(numItems));
-    if (ret) {
-        return ret;
-    }
-    for (size_t i = 0; i < numItems; i++) {
-        int32_t key = mInternalData->mItems.keyAt(i);
-        const typed_data &item = mInternalData->mItems.valueAt(i);
-        uint32_t type;
-        const void *data;
-        size_t size;
-        item.getData(&type, &data, &size);
-        ret = parcel.writeInt32(key);
-        if (ret) {
-            return ret;
-        }
-        ret = parcel.writeUint32(type);
-        if (ret) {
-            return ret;
-        }
-        if (type == TYPE_NONE) {
-            android::Parcel::WritableBlob blob;
-            ret = parcel.writeUint32(static_cast<uint32_t>(size));
-            if (ret) {
-                return ret;
-            }
-            ret = parcel.writeBlob(size, false, &blob);
-            if (ret) {
-                return ret;
-            }
-            memcpy(blob.data(), data, size);
-            blob.release();
-        } else {
-            ret = parcel.writeByteArray(size, (uint8_t*)data);
-            if (ret) {
-                return ret;
-            }
-        }
-    }
-    return OK;
-}
-
-status_t MetaData::updateFromParcel(const Parcel &parcel) {
-    uint32_t numItems;
-    if (parcel.readUint32(&numItems) == OK) {
-
-        for (size_t i = 0; i < numItems; i++) {
-            int32_t key;
-            uint32_t type;
-            uint32_t size;
-            status_t ret = parcel.readInt32(&key);
-            ret |= parcel.readUint32(&type);
-            ret |= parcel.readUint32(&size);
-            if (ret != OK) {
-                break;
-            }
-            // copy data from Blob, which may be inline in Parcel storage,
-            // then advance position
-            if (type == TYPE_NONE) {
-                android::Parcel::ReadableBlob blob;
-                ret = parcel.readBlob(size, &blob);
-                if (ret != OK) {
-                    break;
-                }
-                setData(key, type, blob.data(), size);
-                blob.release();
-            } else {
-                // copy data directly from Parcel storage, then advance position
-                setData(key, type, parcel.readInplace(size), size);
-            }
-         }
-
-        return OK;
-    }
-    ALOGW("no metadata in parcel");
-    return UNKNOWN_ERROR;
-}
-
-
 /* static */
 sp<MetaData> MetaData::createFromParcel(const Parcel &parcel) {
 
@@ -533,7 +53,5 @@
     return meta;
 }
 
-
-
 }  // namespace android