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

Commit 403484d6 authored by Marco Nelissen's avatar Marco Nelissen
Browse files

Allow for larger codec private data

This change adds support for multibyte sizes in the ESDS. Previously the
Matroska extractor only supported single byte sizes, so codec private data
had to be less than 108 bytes, and would crash if it was bigger.
b/12584090

Change-Id: I9edfc2f687187d1e98bcfd2fe56576312435df3e
parent cc09c59e
Loading
Loading
Loading
Loading
+50 −30
Original line number Original line Diff line number Diff line
@@ -716,41 +716,61 @@ bool MatroskaExtractor::isLiveStreaming() const {
    return mIsLiveStreaming;
    return mIsLiveStreaming;
}
}


static int bytesForSize(size_t size) {
    // use at most 28 bits (4 times 7)
    CHECK(size <= 0xfffffff);

    if (size > 0x1fffff) {
        return 4;
    } else if (size > 0x3fff) {
        return 3;
    } else if (size > 0x7f) {
        return 2;
    }
    return 1;
}

static void storeSize(uint8_t *data, size_t &idx, size_t size) {
    int numBytes = bytesForSize(size);
    idx += numBytes;

    data += idx;
    size_t next = 0;
    while (numBytes--) {
        *--data = (size & 0x7f) | next;
        size >>= 7;
        next = 0x80;
    }
}

static void addESDSFromCodecPrivate(
static void addESDSFromCodecPrivate(
        const sp<MetaData> &meta,
        const sp<MetaData> &meta,
        bool isAudio, const void *priv, size_t privSize) {
        bool isAudio, const void *priv, size_t privSize) {
    static const uint8_t kStaticESDS[] = {
        0x03, 22,
        0x00, 0x00,     // ES_ID
        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag

        0x04, 17,
        0x40,           // ObjectTypeIndication
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,

        0x05,
        // CodecSpecificInfo (with size prefix) follows
    };


    // Make sure all sizes can be coded in a single byte.
    int privSizeBytesRequired = bytesForSize(privSize);
    CHECK(privSize + 22 - 2 < 128);
    int esdsSize2 = 14 + privSizeBytesRequired + privSize;
    size_t esdsSize = sizeof(kStaticESDS) + privSize + 1;
    int esdsSize2BytesRequired = bytesForSize(esdsSize2);
    int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2;
    int esdsSize1BytesRequired = bytesForSize(esdsSize1);
    size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1;
    uint8_t *esds = new uint8_t[esdsSize];
    uint8_t *esds = new uint8_t[esdsSize];
    memcpy(esds, kStaticESDS, sizeof(kStaticESDS));

    uint8_t *ptr = esds + sizeof(kStaticESDS);
    size_t idx = 0;
    *ptr++ = privSize;
    esds[idx++] = 0x03;
    memcpy(ptr, priv, privSize);
    storeSize(esds, idx, esdsSize1);

    esds[idx++] = 0x00; // ES_ID
    // Increment by codecPrivateSize less 2 bytes that are accounted for
    esds[idx++] = 0x00; // ES_ID
    // already in lengths of 22/17
    esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
    esds[1] += privSize - 2;
    esds[idx++] = 0x04;
    esds[6] += privSize - 2;
    storeSize(esds, idx, esdsSize2);

    esds[idx++] = isAudio ? 0x40   // Audio ISO/IEC 14496-3
    // Set ObjectTypeIndication.
    esds[7] = isAudio ? 0x40   // Audio ISO/IEC 14496-3
                          : 0x20;  // Visual ISO/IEC 14496-2
                          : 0x20;  // Visual ISO/IEC 14496-2
    for (int i = 0; i < 12; i++) {
        esds[idx++] = 0x00;
    }
    esds[idx++] = 0x05;
    storeSize(esds, idx, privSize);
    memcpy(esds + idx, priv, privSize);


    meta->setData(kKeyESDS, 0, esds, esdsSize);
    meta->setData(kKeyESDS, 0, esds, esdsSize);