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

Commit 023f2a52 authored by Lajos Molnar's avatar Lajos Molnar Committed by android-build-merger
Browse files

stagefright: fill in profile/level when reassembling AVCC

am: 47d88911

* commit '47d88911':
  stagefright: fill in profile/level when reassembling AVCC

Change-Id: I7f14c4b0c320d76f3d87a2cee8474b9060ac36da
parents 013ce69d 47d88911
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -48,6 +48,11 @@ status_t convertMetaDataToMessage(
void convertMessageToMetaData(
        const sp<AMessage> &format, sp<MetaData> &meta);

// Returns a pointer to the next NAL start code in buffer of size |length| starting at |data|, or
// a pointer to the end of the buffer if the start code is not found.
// TODO: combine this with avc_utils::getNextNALUnit
const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length);

AString MakeUserAgent();

// Convert a MIME type to a AudioSystem::audio_format
+2 −21
Original line number Diff line number Diff line
@@ -1929,22 +1929,6 @@ static void getNalUnitType(uint8_t byte, uint8_t* type) {
    *type = (byte & 0x1F);
}

static const uint8_t *findNextStartCode(
        const uint8_t *data, size_t length) {

    ALOGV("findNextStartCode: %p %zu", data, length);

    size_t bytesLeft = length;
    while (bytesLeft > 4  &&
            memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) {
        --bytesLeft;
    }
    if (bytesLeft <= 4) {
        bytesLeft = 0; // Last parameter set
    }
    return &data[length - bytesLeft];
}

const uint8_t *MPEG4Writer::Track::parseParamSet(
        const uint8_t *data, size_t length, int type, size_t *paramSetLen) {

@@ -1952,7 +1936,7 @@ const uint8_t *MPEG4Writer::Track::parseParamSet(
    CHECK(type == kNalUnitTypeSeqParamSet ||
          type == kNalUnitTypePicParamSet);

    const uint8_t *nextStartCode = findNextStartCode(data, length);
    const uint8_t *nextStartCode = findNextNalStartCode(data, length);
    *paramSetLen = nextStartCode - data;
    if (*paramSetLen == 0) {
        ALOGE("Param set is malformed, since its length is 0");
@@ -2198,10 +2182,7 @@ status_t MPEG4Writer::Track::parseHEVCCodecSpecificData(
    const uint8_t *nextStartCode = data;
    size_t bytesLeft = size;
    while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
        nextStartCode = findNextStartCode(tmp + 4, bytesLeft - 4);
        if (nextStartCode == NULL) {
            return ERROR_MALFORMED;
        }
        nextStartCode = findNextNalStartCode(tmp + 4, bytesLeft - 4);
        status_t err = paramSets.addNalUnit(tmp + 4, (nextStartCode - tmp) - 4);
        if (err != OK) {
            return ERROR_MALFORMED;
+40 −37
Original line number Diff line number Diff line
@@ -568,6 +568,15 @@ status_t convertMetaDataToMessage(
    return OK;
}

const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
    uint8_t *res = NULL;
    if (length > 4) {
        // minus 1 as to not match NAL start code at end
        res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
    }
    return res != NULL && res < data + length - 4 ? res : &data[length];
}

static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
    avcc[0] = 1;        // version
    avcc[1] = 0x64;     // profile (default to high)
@@ -580,26 +589,28 @@ static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, ch
    int lastparamoffset = 0;
    int avccidx = 6;
    do {
        if (i >= csd0->size() - 4 ||
                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
            if (i >= csd0->size() - 4) {
                // there can't be another param here, so use all the rest
                i = csd0->size();
            }
        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
        ALOGV("block at %zu, last was %d", i, lastparamoffset);
        if (lastparamoffset > 0) {
            const uint8_t *lastparam = csd0->data() + lastparamoffset;
            int size = i - lastparamoffset;
            if (size > 3) {
                if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
                    ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
                            avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
                } else if (!numparams) {
                    // fill in profile, constraints and level
                    memcpy(avcc + 1, lastparam + 1, 3);
                }
            }
            avcc[avccidx++] = size >> 8;
            avcc[avccidx++] = size & 0xff;
                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
            memcpy(avcc+avccidx, lastparam, size);
            avccidx += size;
            numparams++;
        }
        i += 4;
        lastparamoffset = i;
        } else {
            i++;
        }
    } while(i < csd0->size());
    ALOGV("csd0 contains %d params", numparams);

@@ -611,12 +622,7 @@ static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, ch
    int numpicparamsoffset = avccidx;
    avccidx++;
    do {
        if (i >= csd1->size() - 4 ||
                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
            if (i >= csd1->size() - 4) {
                // there can't be another param here, so use all the rest
                i = csd1->size();
            }
        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
        ALOGV("block at %zu, last was %d", i, lastparamoffset);
        if (lastparamoffset > 0) {
            int size = i - lastparamoffset;
@@ -628,9 +634,6 @@ static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, ch
        }
        i += 4;
        lastparamoffset = i;
        } else {
            i++;
        }
    } while(i < csd1->size());
    avcc[numpicparamsoffset] = numparams;
    return avccidx;