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

Commit fe5f0aae authored by Andreas Huber's avatar Andreas Huber
Browse files

Properly decode ADTS files with ID3 headers.

Change-Id: I55247e79ac9cc9547e3e0f6fe048bcbdc9b639d1
parent 688ff9a7
Loading
Loading
Loading
Loading
+58 −10
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "include/avc_utils.h"

#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
@@ -131,18 +132,28 @@ static size_t getAdtsFrameLength(const sp<DataSource> &source, off64_t offset, s
    return frameSize;
}

AACExtractor::AACExtractor(const sp<DataSource> &source)
AACExtractor::AACExtractor(
        const sp<DataSource> &source, const sp<AMessage> &_meta)
    : mDataSource(source),
      mInitCheck(NO_INIT),
      mFrameDurationUs(0) {
    sp<AMessage> meta = _meta;

    if (meta == NULL) {
        String8 mimeType;
        float confidence;
    if (!SniffAAC(mDataSource, &mimeType, &confidence, NULL)) {
        sp<AMessage> _meta;

        if (!SniffAAC(mDataSource, &mimeType, &confidence, &meta)) {
            return;
        }
    }

    int64_t offset;
    CHECK(meta->findInt64("offset", &offset));

    uint8_t profile, sf_index, channel, header[2];
    if (mDataSource->readAt(2, &header, 2) < 2) {
    if (mDataSource->readAt(offset + 2, &header, 2) < 2) {
        return;
    }

@@ -156,7 +167,6 @@ AACExtractor::AACExtractor(const sp<DataSource> &source)

    mMeta = MakeAACCodecSpecificData(profile, sf_index, channel);

    off64_t offset = 0;
    off64_t streamSize, numFrames = 0;
    size_t frameSize = 0;
    int64_t duration = 0;
@@ -245,7 +255,12 @@ AACSource::~AACSource() {
status_t AACSource::start(MetaData *params) {
    CHECK(!mStarted);

    if (mOffsetVector.empty()) {
        mOffset = 0;
    } else {
        mOffset = mOffsetVector.itemAt(0);
    }

    mCurrentTimeUs = 0;
    mGroup = new MediaBufferGroup;
    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
@@ -318,10 +333,39 @@ status_t AACSource::read(

bool SniffAAC(
        const sp<DataSource> &source, String8 *mimeType, float *confidence,
        sp<AMessage> *) {
        sp<AMessage> *meta) {
    off64_t pos = 0;

    for (;;) {
        uint8_t id3header[10];
        if (source->readAt(pos, id3header, sizeof(id3header))
                < (ssize_t)sizeof(id3header)) {
            return false;
        }

        if (memcmp("ID3", id3header, 3)) {
            break;
        }

        // Skip the ID3v2 header.

        size_t len =
            ((id3header[6] & 0x7f) << 21)
            | ((id3header[7] & 0x7f) << 14)
            | ((id3header[8] & 0x7f) << 7)
            | (id3header[9] & 0x7f);

        len += 10;

        pos += len;

        ALOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)",
             pos, pos);
    }

    uint8_t header[2];

    if (source->readAt(0, &header, 2) != 2) {
    if (source->readAt(pos, &header, 2) != 2) {
        return false;
    }

@@ -329,6 +373,10 @@ bool SniffAAC(
    if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) {
        *mimeType = MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
        *confidence = 0.2;

        *meta = new AMessage;
        (*meta)->setInt64("offset", pos);

        return true;
    }

+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ sp<MediaExtractor> MediaExtractor::Create(
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
        ret = new WVMExtractor(source);
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
        ret = new AACExtractor(source);
        ret = new AACExtractor(source, meta);
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
        ret = new MPEG2PSExtractor(source);
    }
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ class String8;

class AACExtractor : public MediaExtractor {
public:
    AACExtractor(const sp<DataSource> &source);
    AACExtractor(const sp<DataSource> &source, const sp<AMessage> &meta);

    virtual size_t countTracks();
    virtual sp<MediaSource> getTrack(size_t index);