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

Commit 2008b88e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ia03716ca,If3d6c8fd into nyc-dev

* changes:
  stagefright: do not fail on bad bitstreams in HevcParameterSets
  stagefright: add safe versions of parseUE and parseSE
parents 29d7654d 05b849ec
Loading
Loading
Loading
Loading
+29 −25
Original line number Original line Diff line number Diff line
@@ -149,6 +149,7 @@ status_t HevcParameterSets::parseVps(const uint8_t* data, size_t size) {
    // Skip reserved
    // Skip reserved
    reader.skipBits(16);
    reader.skipBits(16);


    if (reader.atLeastNumBitsLeft(96)) {
        mParams.add(kGeneralProfileSpace, reader.getBits(2));
        mParams.add(kGeneralProfileSpace, reader.getBits(2));
        mParams.add(kGeneralTierFlag, reader.getBits(1));
        mParams.add(kGeneralTierFlag, reader.getBits(1));
        mParams.add(kGeneralProfileIdc, reader.getBits(5));
        mParams.add(kGeneralProfileIdc, reader.getBits(5));
@@ -158,8 +159,11 @@ status_t HevcParameterSets::parseVps(const uint8_t* data, size_t size) {
                ((uint64_t)reader.getBits(16) << 32) | reader.getBits(32));
                ((uint64_t)reader.getBits(16) << 32) | reader.getBits(32));
        mParams.add(kGeneralLevelIdc, reader.getBits(8));
        mParams.add(kGeneralLevelIdc, reader.getBits(8));
        // 96 bits total for general profile.
        // 96 bits total for general profile.
    } else {
        reader.skipBits(96);
    }


    return OK;
    return reader.overRead() ? ERROR_MALFORMED : OK;
}
}


status_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) {
status_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) {
@@ -167,7 +171,7 @@ status_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) {
    NALBitReader reader(data, size);
    NALBitReader reader(data, size);
    // Skip sps_video_parameter_set_id
    // Skip sps_video_parameter_set_id
    reader.skipBits(4);
    reader.skipBits(4);
    uint8_t maxSubLayersMinus1 = reader.getBits(3);
    uint8_t maxSubLayersMinus1 = reader.getBitsWithFallback(3, 0);
    // Skip sps_temporal_id_nesting_flag;
    // Skip sps_temporal_id_nesting_flag;
    reader.skipBits(1);
    reader.skipBits(1);
    // Skip general profile
    // Skip general profile
@@ -176,8 +180,8 @@ status_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) {
        bool subLayerProfilePresentFlag[8];
        bool subLayerProfilePresentFlag[8];
        bool subLayerLevelPresentFlag[8];
        bool subLayerLevelPresentFlag[8];
        for (int i = 0; i < maxSubLayersMinus1; ++i) {
        for (int i = 0; i < maxSubLayersMinus1; ++i) {
            subLayerProfilePresentFlag[i] = reader.getBits(1);
            subLayerProfilePresentFlag[i] = reader.getBitsWithFallback(1, 0);
            subLayerLevelPresentFlag[i] = reader.getBits(1);
            subLayerLevelPresentFlag[i] = reader.getBitsWithFallback(1, 0);
        }
        }
        // Skip reserved
        // Skip reserved
        reader.skipBits(2 * (8 - maxSubLayersMinus1));
        reader.skipBits(2 * (8 - maxSubLayersMinus1));
@@ -193,31 +197,31 @@ status_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) {
        }
        }
    }
    }
    // Skip sps_seq_parameter_set_id
    // Skip sps_seq_parameter_set_id
    parseUE(&reader);
    skipUE(&reader);
    uint8_t chromaFormatIdc = parseUE(&reader);
    uint8_t chromaFormatIdc = parseUEWithFallback(&reader, 0);
    mParams.add(kChromaFormatIdc, chromaFormatIdc);
    mParams.add(kChromaFormatIdc, chromaFormatIdc);
    if (chromaFormatIdc == 3) {
    if (chromaFormatIdc == 3) {
        // Skip separate_colour_plane_flag
        // Skip separate_colour_plane_flag
        reader.skipBits(1);
        reader.skipBits(1);
    }
    }
    // Skip pic_width_in_luma_samples
    // Skip pic_width_in_luma_samples
    parseUE(&reader);
    skipUE(&reader);
    // Skip pic_height_in_luma_samples
    // Skip pic_height_in_luma_samples
    parseUE(&reader);
    skipUE(&reader);
    if (reader.getBits(1) /* i.e. conformance_window_flag */) {
    if (reader.getBitsWithFallback(1, 0) /* i.e. conformance_window_flag */) {
        // Skip conf_win_left_offset
        // Skip conf_win_left_offset
        parseUE(&reader);
        skipUE(&reader);
        // Skip conf_win_right_offset
        // Skip conf_win_right_offset
        parseUE(&reader);
        skipUE(&reader);
        // Skip conf_win_top_offset
        // Skip conf_win_top_offset
        parseUE(&reader);
        skipUE(&reader);
        // Skip conf_win_bottom_offset
        // Skip conf_win_bottom_offset
        parseUE(&reader);
        skipUE(&reader);
    }
    }
    mParams.add(kBitDepthLumaMinus8, parseUE(&reader));
    mParams.add(kBitDepthLumaMinus8, parseUEWithFallback(&reader, 0));
    mParams.add(kBitDepthChromaMinus8, parseUE(&reader));
    mParams.add(kBitDepthChromaMinus8, parseUEWithFallback(&reader, 0));


    return OK;
    return reader.overRead() ? ERROR_MALFORMED : OK;
}
}


status_t HevcParameterSets::parsePps(
status_t HevcParameterSets::parsePps(
+27 −0
Original line number Original line Diff line number Diff line
@@ -41,12 +41,39 @@ unsigned parseUE(ABitReader *br) {
    return x + (1u << numZeroes) - 1;
    return x + (1u << numZeroes) - 1;
}
}


unsigned parseUEWithFallback(ABitReader *br, unsigned fallback) {
    unsigned numZeroes = 0;
    while (br->getBitsWithFallback(1, 1) == 0) {
        ++numZeroes;
    }
    uint32_t x;
    if (numZeroes < 32) {
        if (br->getBitsGraceful(numZeroes, &x)) {
            return x + (1u << numZeroes) - 1;
        } else {
            return fallback;
        }
    } else {
        br->skipBits(numZeroes);
        return fallback;
    }
}

signed parseSE(ABitReader *br) {
signed parseSE(ABitReader *br) {
    unsigned codeNum = parseUE(br);
    unsigned codeNum = parseUE(br);


    return (codeNum & 1) ? (codeNum + 1) / 2 : -(codeNum / 2);
    return (codeNum & 1) ? (codeNum + 1) / 2 : -(codeNum / 2);
}
}


signed parseSEWithFallback(ABitReader *br, signed fallback) {
    // NOTE: parseUE cannot normally return ~0 as the max supported value is 0xFFFE
    unsigned codeNum = parseUEWithFallback(br, ~0U);
    if (codeNum == ~0U) {
        return fallback;
    }
    return (codeNum & 1) ? (codeNum + 1) / 2 : -(codeNum / 2);
}

static void skipScalingList(ABitReader *br, size_t sizeOfScalingList) {
static void skipScalingList(ABitReader *br, size_t sizeOfScalingList) {
    size_t lastScale = 8;
    size_t lastScale = 8;
    size_t nextScale = 8;
    size_t nextScale = 8;
+26 −0
Original line number Original line Diff line number Diff line
@@ -47,8 +47,34 @@ void FindAVCDimensions(
        int32_t *width, int32_t *height,
        int32_t *width, int32_t *height,
        int32_t *sarWidth = NULL, int32_t *sarHeight = NULL);
        int32_t *sarWidth = NULL, int32_t *sarHeight = NULL);


// Gets and returns an unsigned exp-golomb (ue) value from a bit reader |br|. Aborts if the value
// is more than 64 bits long (>=0xFFFF (!)) or the bit reader overflows.
unsigned parseUE(ABitReader *br);
unsigned parseUE(ABitReader *br);


// Gets and returns a signed exp-golomb (se) value from a bit reader |br|. Aborts if the value is
// more than 64 bits long (>0x7FFF || <-0x7FFF (!)) or the bit reader overflows.
signed parseSE(ABitReader *br);

// Gets an unsigned exp-golomb (ue) value from a bit reader |br|, and returns it if it was
// successful. Returns |fallback| if it was unsuccessful. Note: if the value was longer that 64
// bits, it reads past the value and still returns |fallback|.
unsigned parseUEWithFallback(ABitReader *br, unsigned fallback);

// Gets a signed exp-golomb (se) value from a bit reader |br|, and returns it if it was successful.
// Returns |fallback| if it was unsuccessful. Note: if the value was longer that 64 bits, it reads
// past the value and still returns |fallback|.
signed parseSEWithFallback(ABitReader *br, signed fallback);

// Skips an unsigned exp-golomb (ue) value from bit reader |br|.
inline void skipUE(ABitReader *br) {
    (void)parseUEWithFallback(br, 0U);
}

// Skips a signed exp-golomb (se) value from bit reader |br|.
inline void skipSE(ABitReader *br) {
    (void)parseSEWithFallback(br, 0);
}

status_t getNextNALUnit(
status_t getNextNALUnit(
        const uint8_t **_data, size_t *_size,
        const uint8_t **_data, size_t *_size,
        const uint8_t **nalStart, size_t *nalSize,
        const uint8_t **nalStart, size_t *nalSize,