Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07a017d3 authored by Marco Nelissen's avatar Marco Nelissen Committed by Gerrit Code Review
Browse files

Merge "Added support for ID3v2 meta data in 3gp files"

parents 4cc47940 328abde6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -215,6 +215,8 @@ public:
    bool findData(uint32_t key, uint32_t *type,
                  const void **data, size_t *size) const;

    bool hasData(uint32_t key) const;

    void dumpToLog() const;

protected:
+70 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <utils/String8.h>

#include <byteswap.h>
#include "include/ID3.h"

namespace android {

@@ -1787,6 +1788,18 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            break;
        }

        case FOURCC('I', 'D', '3', '2'):
        {
            if (chunk_data_size < 6) {
                return ERROR_MALFORMED;
            }

            parseID3v2MetaData(data_offset + 6);

            *offset += chunk_size;
            break;
        }

        case FOURCC('-', '-', '-', '-'):
        {
            mLastCommentMean.clear();
@@ -2167,7 +2180,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
            break;
    }

    if (size >= 8 && metadataKey) {
    if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
        if (metadataKey == kKeyAlbumArt) {
            mFileMetaData->setData(
                    kKeyAlbumArt, MetaData::TYPE_NONE,
@@ -2316,6 +2329,62 @@ status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int dept
    return OK;
}

void MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
    ID3 id3(mDataSource, true /* ignorev1 */, offset);

    if (id3.isValid()) {
        struct Map {
            int key;
            const char *tag1;
            const char *tag2;
        };
        static const Map kMap[] = {
            { kKeyAlbum, "TALB", "TAL" },
            { kKeyArtist, "TPE1", "TP1" },
            { kKeyAlbumArtist, "TPE2", "TP2" },
            { kKeyComposer, "TCOM", "TCM" },
            { kKeyGenre, "TCON", "TCO" },
            { kKeyTitle, "TIT2", "TT2" },
            { kKeyYear, "TYE", "TYER" },
            { kKeyAuthor, "TXT", "TEXT" },
            { kKeyCDTrackNumber, "TRK", "TRCK" },
            { kKeyDiscNumber, "TPA", "TPOS" },
            { kKeyCompilation, "TCP", "TCMP" },
        };
        static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);

        for (size_t i = 0; i < kNumMapEntries; ++i) {
            if (!mFileMetaData->hasData(kMap[i].key)) {
                ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
                if (it->done()) {
                    delete it;
                    it = new ID3::Iterator(id3, kMap[i].tag2);
                }

                if (it->done()) {
                    delete it;
                    continue;
                }

                String8 s;
                it->getString(&s);
                delete it;

                mFileMetaData->setCString(kMap[i].key, s);
            }
        }

        size_t dataSize;
        String8 mime;
        const void *data = id3.getAlbumArt(&dataSize, &mime);

        if (data) {
            mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
            mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
        }
    }
}

sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
    status_t err;
    if ((err = readMetaData()) != OK) {
+10 −0
Original line number Diff line number Diff line
@@ -221,6 +221,16 @@ bool MetaData::findData(uint32_t key, uint32_t *type,
    return true;
}

bool MetaData::hasData(uint32_t key) const {
    ssize_t i = mItems.indexOfKey(key);

    if (i < 0) {
        return false;
    }

    return true;
}

MetaData::typed_data::typed_data()
    : mType(0),
      mSize(0) {
+6 −6
Original line number Diff line number Diff line
@@ -56,14 +56,14 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(MemorySource);
};

ID3::ID3(const sp<DataSource> &source, bool ignoreV1)
ID3::ID3(const sp<DataSource> &source, bool ignoreV1, off64_t offset)
    : mIsValid(false),
      mData(NULL),
      mSize(0),
      mFirstFrameOffset(0),
      mVersion(ID3_UNKNOWN),
      mRawSize(0) {
    mIsValid = parseV2(source);
    mIsValid = parseV2(source, offset);

    if (!mIsValid && !ignoreV1) {
        mIsValid = parseV1(source);
@@ -79,7 +79,7 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1)
      mRawSize(0) {
    sp<MemorySource> source = new MemorySource(data, size);

    mIsValid = parseV2(source);
    mIsValid = parseV2(source, 0);

    if (!mIsValid && !ignoreV1) {
        mIsValid = parseV1(source);
@@ -115,7 +115,7 @@ bool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) {
    return true;
}

bool ID3::parseV2(const sp<DataSource> &source) {
bool ID3::parseV2(const sp<DataSource> &source, off64_t offset) {
struct id3_header {
    char id[3];
    uint8_t version_major;
@@ -126,7 +126,7 @@ struct id3_header {

    id3_header header;
    if (source->readAt(
                0, &header, sizeof(header)) != (ssize_t)sizeof(header)) {
                offset, &header, sizeof(header)) != (ssize_t)sizeof(header)) {
        return false;
    }

@@ -185,7 +185,7 @@ struct id3_header {
    mSize = size;
    mRawSize = mSize + sizeof(header);

    if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) {
    if (source->readAt(offset + sizeof(header), mData, mSize) != (ssize_t)mSize) {
        free(mData);
        mData = NULL;

+2 −2
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ struct ID3 {
        ID3_V2_4,
    };

    ID3(const sp<DataSource> &source, bool ignoreV1 = false);
    ID3(const sp<DataSource> &source, bool ignoreV1 = false, off64_t offset = 0);
    ID3(const uint8_t *data, size_t size, bool ignoreV1 = false);
    ~ID3();

@@ -86,7 +86,7 @@ private:
    size_t mRawSize;

    bool parseV1(const sp<DataSource> &source);
    bool parseV2(const sp<DataSource> &source);
    bool parseV2(const sp<DataSource> &source, off64_t offset);
    void removeUnsynchronization();
    bool removeUnsynchronizationV2_4(bool iTunesHack);

Loading