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

Commit 54fa7254 authored by Marco Nelissen's avatar Marco Nelissen Committed by Android (Google) Code Review
Browse files

Merge "Parse mp3 encoder padding/delay"

parents b2e822fc 2ed77701
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ enum {
    kKeyThumbnailTime     = 'thbT',  // int64_t (usecs)
    kKeyTrackID           = 'trID',
    kKeyIsDRM             = 'idrm',  // int32_t (bool)
    kKeyEncoderDelay      = 'encd',  // int32_t (frames)
    kKeyEncoderPadding    = 'encp',  // int32_t (frames)

    kKeyAlbum             = 'albu',  // cstring
    kKeyArtist            = 'arti',  // cstring
+37 −2
Original line number Diff line number Diff line
@@ -311,10 +311,18 @@ MP3Extractor::MP3Extractor(
    mMeta->setInt32(kKeyBitRate, bitrate * 1000);
    mMeta->setInt32(kKeyChannelCount, num_channels);

    mSeeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
    sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);

    if (mSeeker == NULL) {
    if (seeker == NULL) {
        mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
    } else {
        mSeeker = seeker;
        int encd = seeker->getEncoderDelay();
        int encp = seeker->getEncoderPadding();
        if (encd != 0 || encp != 0) {
            mMeta->setInt32(kKeyEncoderDelay, encd);
            mMeta->setInt32(kKeyEncoderPadding, encp);
        }
    }

    if (mSeeker != NULL) {
@@ -547,6 +555,33 @@ sp<MetaData> MP3Extractor::getMetaData() {
        return meta;
    }

    ID3::Iterator *com = new ID3::Iterator(id3, "COM");
    if (com->done()) {
        delete com;
        com = new ID3::Iterator(id3, "COMM");
    }
    while(!com->done()) {
        String8 commentdesc;
        String8 commentvalue;
        com->getString(&commentdesc, &commentvalue);
        const char * desc = commentdesc.string();
        const char * value = commentvalue.string();

        // first 3 characters are the language, which we don't care about
        if(strlen(desc) > 3 && strcmp(desc + 3, "iTunSMPB") == 0) {

            int32_t delay, padding;
            if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) {
                mMeta->setInt32(kKeyEncoderDelay, delay);
                mMeta->setInt32(kKeyEncoderPadding, padding);
            }
            break;
        }
        com->next();
    }
    delete com;
    com = NULL;

    struct Map {
        int key;
        const char *tag1;
+29 −3
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
 * limitations under the License.
 */

#define LOG_TAG "XINGSEEKER"
#include <utils/Log.h>

#include "include/XINGSeeker.h"
#include "include/avc_utils.h"

@@ -24,7 +27,9 @@ namespace android {

XINGSeeker::XINGSeeker()
    : mDurationUs(-1),
      mSizeBytes(0) {
      mSizeBytes(0),
      mEncoderDelay(0),
      mEncoderPadding(0) {
}

bool XINGSeeker::getDuration(int64_t *durationUs) {
@@ -76,8 +81,6 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(

    seeker->mFirstFramePos = first_frame_pos;

    ALOGI("xingseeker first frame pos: %lld", first_frame_pos);

    seeker->mSizeBytes = 0;
    seeker->mTOCValid = false;
    seeker->mDurationUs = 0;
@@ -111,6 +114,8 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(
        else offset += 9;
    }

    int xingbase = offset;

    if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID
        return NULL;
    }
@@ -161,10 +166,31 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(
        // do something with the quality indicator
        offset += 4;
    }

    if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags
        return false;
    }

    ALOGV("nogap preceding: %s, nogap continued in next: %s",
              (buffer[0] & 0x80) ? "true" : "false",
              (buffer[0] & 0x40) ? "true" : "false");
#endif

    if (source->readAt(xingbase + 0xb1 - 0x24, &buffer, 3) == 3) {
        seeker->mEncoderDelay = (buffer[0] << 4) + (buffer[1] >> 4);
        seeker->mEncoderPadding = ((buffer[1] & 0xf) << 8) + buffer[2];
    }

    return seeker;
}

int32_t XINGSeeker::getEncoderDelay() {
    return mEncoderDelay;
}

int32_t XINGSeeker::getEncoderPadding() {
    return mEncoderPadding;
}

}  // namespace android
+36 −11
Original line number Diff line number Diff line
@@ -463,40 +463,65 @@ static void convertISO8859ToString8(
    tmp = NULL;
}

void ID3::Iterator::getString(String8 *id) const {
// the 2nd argument is used to get the data following the \0 in a comment field
void ID3::Iterator::getString(String8 *id, String8 *comment) const {
    getstring(id, false);
    if (comment != NULL) {
        getstring(comment, true);
    }
}

// comment fields (COM/COMM) contain an initial short descriptor, followed by \0,
// followed by more data. The data following the \0 can be retrieved by setting
// "otherdata" to true.
void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
    id->setTo("");

    if (mFrameData == NULL) {
    const uint8_t *frameData = mFrameData;
    if (frameData == NULL) {
        return;
    }

    uint8_t encoding = *frameData;

    if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) {
        if (mOffset == 126 || mOffset == 127) {
            // Special treatment for the track number and genre.
            char tmp[16];
            sprintf(tmp, "%d", (int)*mFrameData);
            sprintf(tmp, "%d", (int)*frameData);

            id->setTo(tmp);
            return;
        }

        convertISO8859ToString8(mFrameData, mFrameSize, id);
        convertISO8859ToString8(frameData, mFrameSize, id);
        return;
    }

    size_t n = mFrameSize - getHeaderLength() - 1;
    if (otherdata) {
        // skip past the encoding, language, and the 0 separator
        frameData += 4;
        int32_t i = n - 4;
        while(--i >= 0 && *++frameData != 0) ;
        int skipped = (frameData - mFrameData);
        if (skipped >= n) {
            return;
        }
        n -= skipped;
    }

    if (*mFrameData == 0x00) {
    if (encoding == 0x00) {
        // ISO 8859-1
        convertISO8859ToString8(mFrameData + 1, n, id);
    } else if (*mFrameData == 0x03) {
        convertISO8859ToString8(frameData + 1, n, id);
    } else if (encoding == 0x03) {
        // UTF-8
        id->setTo((const char *)(mFrameData + 1), n);
    } else if (*mFrameData == 0x02) {
        id->setTo((const char *)(frameData + 1), n);
    } else if (encoding == 0x02) {
        // UTF-16 BE, no byte order mark.
        // API wants number of characters, not number of bytes...
        int len = n / 2;
        const char16_t *framedata = (const char16_t *) (mFrameData + 1);
        const char16_t *framedata = (const char16_t *) (frameData + 1);
        char16_t *framedatacopy = NULL;
#if BYTE_ORDER == LITTLE_ENDIAN
        framedatacopy = new char16_t[len];
@@ -513,7 +538,7 @@ void ID3::Iterator::getString(String8 *id) const {
        // UCS-2
        // API wants number of characters, not number of bytes...
        int len = n / 2;
        const char16_t *framedata = (const char16_t *) (mFrameData + 1);
        const char16_t *framedata = (const char16_t *) (frameData + 1);
        char16_t *framedatacopy = NULL;
        if (*framedata == 0xfffe) {
            // endianness marker doesn't match host endianness, convert
+2 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ struct ID3 {

        bool done() const;
        void getID(String8 *id) const;
        void getString(String8 *s) const;
        void getString(String8 *s, String8 *ss = NULL) const;
        const uint8_t *getData(size_t *length) const;
        void next();

@@ -65,6 +65,7 @@ struct ID3 {
        void findFrame();

        size_t getHeaderLength() const;
        void getstring(String8 *s, bool secondhalf) const;

        Iterator(const Iterator &);
        Iterator &operator=(const Iterator &);
Loading