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

Commit e314c678 authored by Jinsuk Kim's avatar Jinsuk Kim
Browse files

DO NOT MERGE: Prevent crash at erroneous MPEG2TS bitstream

Used new RCHECK_ macros for drop-in replacements for CHECK_
to avoid crashing at bit errors encountered while parsing
MPEG2 transport packets.

Also removed CHECK_ macros in PSI table processing as errors
would have been already filtered out by CRC check.

Bug: 20274977
Change-Id: I5ca810df3c4295142610bbd1d586d7529bb9f303
(cherry picked from commit e84ab89a)
parent 1e2a0e6a
Loading
Loading
Loading
Loading
+124 −62
Original line number Diff line number Diff line
@@ -302,9 +302,13 @@ bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
                // The two checks below shouldn't happen,
                // we already checked above the stream count matches
                ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
                CHECK(index >= 0);
                if (index < 0) {
                    return false;
                }
                Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
                CHECK(newPIDs.size() > 0);
                if (newPIDs.isEmpty()) {
                    return false;
                }

                // get the next PID for temp[i]->type() in the new PID map
                Vector<int32_t>::iterator it = newPIDs.begin();
@@ -335,13 +339,11 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
        return ERROR_MALFORMED;
    }

    CHECK_EQ(br->getBits(1), 0u);
    br->skipBits(1);  // '0'
    MY_LOGV("  reserved = %u", br->getBits(2));

    unsigned section_length = br->getBits(12);
    ALOGV("  section_length = %u", section_length);
    CHECK_EQ(section_length & 0xc00, 0u);
    CHECK_LE(section_length, 1021u);

    MY_LOGV("  program_number = %u", br->getBits(16));
    MY_LOGV("  reserved = %u", br->getBits(2));
@@ -358,7 +360,6 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {

    unsigned program_info_length = br->getBits(12);
    ALOGV("  program_info_length = %u", program_info_length);
    CHECK_EQ(program_info_length & 0xc00, 0u);

    br->skipBits(program_info_length * 8);  // skip descriptors

@@ -369,8 +370,7 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
    // final CRC.
    size_t infoBytesRemaining = section_length - 9 - program_info_length - 4;

    while (infoBytesRemaining > 0) {
        CHECK_GE(infoBytesRemaining, 5u);
    while (infoBytesRemaining >= 5) {

        unsigned streamType = br->getBits(8);
        ALOGV("    stream_type = 0x%02x", streamType);
@@ -384,9 +384,6 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {

        unsigned ES_info_length = br->getBits(12);
        ALOGV("    ES_info_length = %u", ES_info_length);
        CHECK_EQ(ES_info_length & 0xc00, 0u);

        CHECK_GE(infoBytesRemaining - 5, ES_info_length);

#if 0
        br->skipBits(ES_info_length * 8);  // skip descriptors
@@ -398,13 +395,13 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
            unsigned descLength = br->getBits(8);
            ALOGV("      len = %u", descLength);

            CHECK_GE(info_bytes_remaining, 2 + descLength);

            if (info_bytes_remaining < descLength) {
                return ERROR_MALFORMED;
            }
            br->skipBits(descLength * 8);

            info_bytes_remaining -= descLength + 2;
        }
        CHECK_EQ(info_bytes_remaining, 0u);
#endif

        StreamInfo info;
@@ -415,7 +412,9 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
        infoBytesRemaining -= 5 + ES_info_length;
    }

    CHECK_EQ(infoBytesRemaining, 0u);
    if (infoBytesRemaining != 0) {
        ALOGW("Section data remains unconsumed");
    }
    MY_LOGV("  CRC = 0x%08x", br->getBits(32));

    bool PIDsChanged = false;
@@ -680,7 +679,10 @@ status_t ATSParser::Stream::parse(
    }

    size_t payloadSizeBits = br->numBitsLeft();
    CHECK_EQ(payloadSizeBits % 8, 0u);
    if (payloadSizeBits % 8 != 0u) {
        ALOGE("Wrong value");
        return BAD_VALUE;
    }

    size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
    if (mBuffer->capacity() < neededSize) {
@@ -797,8 +799,6 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
        return ERROR_MALFORMED;
    }

    CHECK_EQ(packet_startcode_prefix, 0x000001u);

    unsigned stream_id = br->getBits(8);
    ALOGV("stream_id = 0x%02x", stream_id);

@@ -813,7 +813,9 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
            && stream_id != 0xff  // program_stream_directory
            && stream_id != 0xf2  // DSMCC
            && stream_id != 0xf8) {  // H.222.1 type E
        CHECK_EQ(br->getBits(2), 2u);
        if (br->getBits(2) != 2u) {
            return ERROR_MALFORMED;
        }

        MY_LOGV("PES_scrambling_control = %u", br->getBits(2));
        MY_LOGV("PES_priority = %u", br->getBits(1));
@@ -847,34 +849,51 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
        uint64_t PTS = 0, DTS = 0;

        if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
            CHECK_GE(optional_bytes_remaining, 5u);
            if (optional_bytes_remaining < 5u) {
                return ERROR_MALFORMED;
            }

            if (br->getBits(4) != PTS_DTS_flags) {
                ALOGE("PES data Error!");
                return ERROR_MALFORMED;
            }
            PTS = ((uint64_t)br->getBits(3)) << 30;
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            PTS |= ((uint64_t)br->getBits(15)) << 15;
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            PTS |= br->getBits(15);
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);

            optional_bytes_remaining -= 5;

            if (PTS_DTS_flags == 3) {
                CHECK_GE(optional_bytes_remaining, 5u);
                if (optional_bytes_remaining < 5u) {
                    return ERROR_MALFORMED;
                }

                CHECK_EQ(br->getBits(4), 1u);
                if (br->getBits(4) != 1u) {
                    return ERROR_MALFORMED;
                }

                DTS = ((uint64_t)br->getBits(3)) << 30;
                CHECK_EQ(br->getBits(1), 1u);
                if (br->getBits(1) != 1u) {
                    return ERROR_MALFORMED;
                }
                DTS |= ((uint64_t)br->getBits(15)) << 15;
                CHECK_EQ(br->getBits(1), 1u);
                if (br->getBits(1) != 1u) {
                    return ERROR_MALFORMED;
                }
                DTS |= br->getBits(15);
                CHECK_EQ(br->getBits(1), 1u);
                if (br->getBits(1) != 1u) {
                    return ERROR_MALFORMED;
                }

                ALOGV("DTS = %" PRIu64, DTS);

@@ -883,31 +902,47 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
        }

        if (ESCR_flag) {
            CHECK_GE(optional_bytes_remaining, 6u);
            if (optional_bytes_remaining < 6u) {
                return ERROR_MALFORMED;
            }

            br->getBits(2);

            uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            ESCR |= ((uint64_t)br->getBits(15)) << 15;
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            ESCR |= br->getBits(15);
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            ALOGV("ESCR = %" PRIu64, ESCR);
            MY_LOGV("ESCR_extension = %u", br->getBits(9));

            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            optional_bytes_remaining -= 6;
        }

        if (ES_rate_flag) {
            CHECK_GE(optional_bytes_remaining, 3u);
            if (optional_bytes_remaining < 3u) {
                return ERROR_MALFORMED;
            }

            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            MY_LOGV("ES_rate = %u", br->getBits(22));
            CHECK_EQ(br->getBits(1), 1u);
            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            optional_bytes_remaining -= 3;
        }
@@ -917,7 +952,9 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
        // ES data follows.

        if (PES_packet_length != 0) {
            CHECK_GE(PES_packet_length, PES_header_data_length + 3);
            if (PES_packet_length < PES_header_data_length + 3) {
                return ERROR_MALFORMED;
            }

            unsigned dataLength =
                PES_packet_length - 3 - PES_header_data_length;
@@ -930,7 +967,9 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
                return ERROR_MALFORMED;
            }

            CHECK_GE(br->numBitsLeft(), dataLength * 8);
            if (br->numBitsLeft() < dataLength * 8) {
                return ERROR_MALFORMED;
            }

            onPayloadData(
                    PTS_DTS_flags, PTS, DTS, br->data(), dataLength);
@@ -942,15 +981,21 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
                    br->data(), br->numBitsLeft() / 8);

            size_t payloadSizeBits = br->numBitsLeft();
            CHECK_EQ(payloadSizeBits % 8, 0u);
            if (payloadSizeBits % 8 != 0u) {
                return ERROR_MALFORMED;
            }

            ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8);
        }
    } else if (stream_id == 0xbe) {  // padding_stream
        CHECK_NE(PES_packet_length, 0u);
        if (PES_packet_length == 0u) {
            return ERROR_MALFORMED;
        }
        br->skipBits(PES_packet_length * 8);
    } else {
        CHECK_NE(PES_packet_length, 0u);
        if (PES_packet_length == 0u) {
            return ERROR_MALFORMED;
        }
        br->skipBits(PES_packet_length * 8);
    }

@@ -1082,7 +1127,10 @@ ATSParser::~ATSParser() {
}

status_t ATSParser::feedTSPacket(const void *data, size_t size) {
    CHECK_EQ(size, kTSPacketSize);
    if (size != kTSPacketSize) {
        ALOGE("Wrong TS packet size");
        return BAD_VALUE;
    }

    ABitReader br((const uint8_t *)data, kTSPacketSize);
    return parseTS(&br);
@@ -1108,14 +1156,23 @@ void ATSParser::signalDiscontinuity(
        }
    } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
        int64_t timeUs;
        CHECK(extra->findInt64("timeUs", &timeUs));
        if (!extra->findInt64("timeUs", &timeUs)) {
            ALOGE("timeUs not found");
            return;
        }

        CHECK(mPrograms.empty());
        if (!mPrograms.empty()) {
            ALOGE("mPrograms is not empty");
            return;
        }
        mAbsoluteTimeAnchorUs = timeUs;
        return;
    } else if (type == DISCONTINUITY_TIME_OFFSET) {
        int64_t offset;
        CHECK(extra->findInt64("offset", &offset));
        if (!extra->findInt64("offset", &offset)) {
            ALOGE("offset not found");
            return;
        }

        mTimeOffsetValid = true;
        mTimeOffsetUs = offset;
@@ -1128,7 +1185,10 @@ void ATSParser::signalDiscontinuity(
}

void ATSParser::signalEOS(status_t finalResult) {
    CHECK_NE(finalResult, (status_t)OK);
    if (finalResult == (status_t) OK) {
        ALOGE("finalResult not OK");
        return;
    }

    for (size_t i = 0; i < mPrograms.size(); ++i) {
        mPrograms.editItemAt(i)->signalEOS(finalResult);
@@ -1144,14 +1204,12 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) {
    }
    unsigned section_syntax_indictor = br->getBits(1);
    ALOGV("  section_syntax_indictor = %u", section_syntax_indictor);
    CHECK_EQ(section_syntax_indictor, 1u);

    CHECK_EQ(br->getBits(1), 0u);
    br->skipBits(1);  // '0'
    MY_LOGV("  reserved = %u", br->getBits(2));

    unsigned section_length = br->getBits(12);
    ALOGV("  section_length = %u", section_length);
    CHECK_EQ(section_length & 0xc00, 0u);

    MY_LOGV("  transport_stream_id = %u", br->getBits(16));
    MY_LOGV("  reserved = %u", br->getBits(2));
@@ -1161,7 +1219,6 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) {
    MY_LOGV("  last_section_number = %u", br->getBits(8));

    size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
    CHECK_EQ((numProgramBytes % 4), 0u);

    for (size_t i = 0; i < numProgramBytes / 4; ++i) {
        unsigned program_number = br->getBits(16);
@@ -1221,7 +1278,9 @@ status_t ATSParser::parsePID(
            br->skipBits(skip * 8);
        }

        CHECK((br->numBitsLeft() % 8) == 0);
        if (br->numBitsLeft() % 8 != 0) {
            return ERROR_MALFORMED;
        }
        status_t err = section->append(br->data(), br->numBitsLeft() / 8);

        if (err != OK) {
@@ -1291,7 +1350,7 @@ status_t ATSParser::parsePID(
    return OK;
}

void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
status_t ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
    unsigned adaptation_field_length = br->getBits(8);

    if (adaptation_field_length > 0) {
@@ -1307,6 +1366,9 @@ void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
        size_t numBitsRead = 4;

        if (PCR_flag) {
            if (adaptation_field_length * 8 < 52) {
                return ERROR_MALFORMED;
            }
            br->skipBits(4);
            uint64_t PCR_base = br->getBits(32);
            PCR_base = (PCR_base << 1) | br->getBits(1);
@@ -1337,10 +1399,9 @@ void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
            numBitsRead += 52;
        }

        CHECK_GE(adaptation_field_length * 8, numBitsRead);

        br->skipBits(adaptation_field_length * 8 - numBitsRead);
    }
    return OK;
}

status_t ATSParser::parseTS(ABitReader *br) {
@@ -1375,16 +1436,17 @@ status_t ATSParser::parseTS(ABitReader *br) {

    // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);

    if (adaptation_field_control == 2 || adaptation_field_control == 3) {
        parseAdaptationField(br, PID);
    }

    status_t err = OK;

    if (adaptation_field_control == 2 || adaptation_field_control == 3) {
        err = parseAdaptationField(br, PID);
    }
    if (err == OK) {
        if (adaptation_field_control == 1 || adaptation_field_control == 3) {
            err = parsePID(
                    br, PID, continuity_counter, payload_unit_start_indicator);
        }
    }

    ++mNumTSPacketsParsed;

+1 −1
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ private:
        unsigned continuity_counter,
        unsigned payload_unit_start_indicator);

    void parseAdaptationField(ABitReader *br, unsigned PID);
    status_t parseAdaptationField(ABitReader *br, unsigned PID);
    status_t parseTS(ABitReader *br);

    void updatePCR(unsigned PID, uint64_t PCR, size_t byteOffsetFromStart);
+116 −35
Original line number Diff line number Diff line
@@ -421,8 +421,8 @@ status_t ElementaryStreamQueue::appendData(
            }

            default:
                TRESPASS();
                break;
                ALOGE("Unknown mode: %d", mMode);
                return ERROR_MALFORMED;
        }
    }

@@ -503,7 +503,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
        case METADATA:
            return dequeueAccessUnitMetadata();
        default:
            CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
            if (mMode != MPEG_AUDIO) {
                ALOGE("Unknown mode");
                return NULL;
            }
            return dequeueAccessUnitMPEGAudio();
    }
}
@@ -540,7 +543,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAC3() {
    memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);

    int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
    CHECK_GE(timeUs, 0ll);
    if (timeUs < 0ll) {
        ALOGE("negative timeUs");
        return NULL;
    }
    accessUnit->meta()->setInt64("timeUs", timeUs);
    accessUnit->meta()->setInt32("isSync", 1);

@@ -560,15 +566,24 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
    }

    ABitReader bits(mBuffer->data(), 4);
    CHECK_EQ(bits.getBits(8), 0xa0);
    if (bits.getBits(8) != 0xa0) {
        ALOGE("Unexpected bit values");
        return NULL;
    }
    unsigned numAUs = bits.getBits(8);
    bits.skipBits(8);
    unsigned quantization_word_length __unused = bits.getBits(2);
    unsigned audio_sampling_frequency = bits.getBits(3);
    unsigned num_channels = bits.getBits(3);

    CHECK_EQ(audio_sampling_frequency, 2);  // 48kHz
    CHECK_EQ(num_channels, 1u);  // stereo!
    if (audio_sampling_frequency != 2) {
        ALOGE("Wrong sampling freq");
        return NULL;
    }
    if (num_channels != 1u) {
        ALOGE("Wrong channel #");
        return NULL;
    }

    if (mFormat == NULL) {
        mFormat = new MetaData;
@@ -590,7 +605,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
    memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);

    int64_t timeUs = fetchTimestamp(payloadSize + 4);
    CHECK_GE(timeUs, 0ll);
    if (timeUs < 0ll) {
        ALOGE("Negative timeUs");
        return NULL;
    }
    accessUnit->meta()->setInt64("timeUs", timeUs);
    accessUnit->meta()->setInt32("isSync", 1);

@@ -614,14 +632,19 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {
        return NULL;
    }

    CHECK(!mRangeInfos.empty());
    if (mRangeInfos.empty()) {
        return NULL;
    }

    const RangeInfo &info = *mRangeInfos.begin();
    if (mBuffer->size() < info.mLength) {
        return NULL;
    }

    CHECK_GE(info.mTimestampUs, 0ll);
    if (info.mTimestampUs < 0ll) {
        ALOGE("Negative info.mTimestampUs");
        return NULL;
    }

    // The idea here is consume all AAC frames starting at offsets before
    // info.mLength so we can assign a meaningful timestamp without
@@ -638,17 +661,26 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {

        // adts_fixed_header

        CHECK_EQ(bits.getBits(12), 0xfffu);
        if (bits.getBits(12) != 0xfffu) {
            ALOGE("Wrong atds_fixed_header");
            return NULL;
        }
        bits.skipBits(3);  // ID, layer
        bool protection_absent __unused = bits.getBits(1) != 0;

        if (mFormat == NULL) {
            unsigned profile = bits.getBits(2);
            CHECK_NE(profile, 3u);
            if (profile == 3u) {
                ALOGE("profile should not be 3");
                return NULL;
            }
            unsigned sampling_freq_index = bits.getBits(4);
            bits.getBits(1);  // private_bit
            unsigned channel_configuration = bits.getBits(3);
            CHECK_NE(channel_configuration, 0u);
            if (channel_configuration == 0u) {
                ALOGE("channel_config should not be 0");
                return NULL;
            }
            bits.skipBits(2);  // original_copy, home

            mFormat = MakeAACCodecSpecificData(
@@ -658,8 +690,14 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {

            int32_t sampleRate;
            int32_t numChannels;
            CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate));
            CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels));
            if (!mFormat->findInt32(kKeySampleRate, &sampleRate)) {
                ALOGE("SampleRate not found");
                return NULL;
            }
            if (!mFormat->findInt32(kKeyChannelCount, &numChannels)) {
                ALOGE("ChannelCount not found");
                return NULL;
            }

            ALOGI("found AAC codec config (%d Hz, %d channels)",
                 sampleRate, numChannels);
@@ -682,7 +720,8 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {

        if (number_of_raw_data_blocks_in_frame != 0) {
            // To be implemented.
            TRESPASS();
            ALOGE("Should not reach here.");
            return NULL;
        }

        if (offset + aac_frame_length > mBuffer->size()) {
@@ -714,7 +753,9 @@ int64_t ElementaryStreamQueue::fetchTimestamp(size_t size) {
    bool first = true;

    while (size > 0) {
        CHECK(!mRangeInfos.empty());
        if (mRangeInfos.empty()) {
            return timeUs;
        }

        RangeInfo *info = &*mRangeInfos.begin();

@@ -813,7 +854,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
                unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f;

                if (nalType == 6 && pos.nalSize > 0) {
                    CHECK_LT(seiIndex, sei->size() / sizeof(NALPosition));
                    if (seiIndex >= sei->size() / sizeof(NALPosition)) {
                        ALOGE("Wrong seiIndex");
                        return NULL;
                    }
                    NALPosition &seiPos = ((NALPosition *)sei->data())[seiIndex++];
                    seiPos.nalOffset = dstOffset + 4;
                    seiPos.nalSize = pos.nalSize;
@@ -851,7 +895,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
            mBuffer->setRange(0, mBuffer->size() - nextScan);

            int64_t timeUs = fetchTimestamp(nextScan);
            CHECK_GE(timeUs, 0ll);
            if (timeUs < 0ll) {
                ALOGE("Negative timeUs");
                return NULL;
            }

            accessUnit->meta()->setInt64("timeUs", timeUs);
            if (foundIDR) {
@@ -873,7 +920,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {

        totalSize += nalSize;
    }
    CHECK_EQ(err, (status_t)-EAGAIN);
    if (err != (status_t)-EAGAIN) {
        ALOGE("Unexpeted err");
        return NULL;
    }

    return NULL;
}
@@ -890,9 +940,12 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {

    size_t frameSize;
    int samplingRate, numChannels, bitrate, numSamples;
    CHECK(GetMPEGAudioFrameSize(
    if (!GetMPEGAudioFrameSize(
                header, &frameSize, &samplingRate, &numChannels,
                &bitrate, &numSamples));
                &bitrate, &numSamples)) {
        ALOGE("Failed to get audio frame size");
        return NULL;
    }

    if (size < frameSize) {
        return NULL;
@@ -910,7 +963,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
    mBuffer->setRange(0, mBuffer->size() - frameSize);

    int64_t timeUs = fetchTimestamp(frameSize);
    CHECK_GE(timeUs, 0ll);
    if (timeUs < 0ll) {
        ALOGE("Negative timeUs");
        return NULL;
    }

    accessUnit->meta()->setInt64("timeUs", timeUs);
    accessUnit->meta()->setInt32("isSync", 1);
@@ -932,7 +988,7 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
                break;
            default:
                TRESPASS();
                return NULL;
        }

        mFormat->setInt32(kKeySampleRate, samplingRate);
@@ -943,7 +999,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() {
}

static void EncodeSize14(uint8_t **_ptr, size_t size) {
    CHECK_LE(size, 0x3fff);
    if (size > 0x3fff) {
        ALOGE("Wrong size");
        return;
    }

    uint8_t *ptr = *_ptr;

@@ -1018,7 +1077,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
            // seqHeader without/with extension

            if (mFormat == NULL) {
                CHECK_GE(size, 7u);
                if (size < 7u) {
                    ALOGE("Size too small");
                    return NULL;
                }

                unsigned width =
                    (data[4] << 4) | data[5] >> 4;
@@ -1078,7 +1140,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
                mBuffer->setRange(0, mBuffer->size() - offset);

                int64_t timeUs = fetchTimestamp(offset);
                CHECK_GE(timeUs, 0ll);
                if (timeUs < 0ll) {
                    ALOGE("Negative timeUs");
                    return NULL;
                }

                offset = 0;

@@ -1111,7 +1176,7 @@ static ssize_t getNextChunkSize(
    }

    if (memcmp(kStartCode, data, 3)) {
        TRESPASS();
        return -EAGAIN;
    }

    size_t offset = 3;
@@ -1171,25 +1236,37 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {

            case EXPECT_VISUAL_OBJECT_START:
            {
                CHECK_EQ(chunkType, 0xb5);
                if (chunkType != 0xb5) {
                    ALOGE("Unexpected chunkType");
                    return NULL;
                }
                state = EXPECT_VO_START;
                break;
            }

            case EXPECT_VO_START:
            {
                CHECK_LE(chunkType, 0x1f);
                if (chunkType > 0x1f) {
                    ALOGE("Unexpected chunkType");
                    return NULL;
                }
                state = EXPECT_VOL_START;
                break;
            }

            case EXPECT_VOL_START:
            {
                CHECK((chunkType & 0xf0) == 0x20);
                if ((chunkType & 0xf0) != 0x20) {
                    ALOGE("Wrong chunkType");
                    return NULL;
                }

                CHECK(ExtractDimensionsFromVOLHeader(
                if (!ExtractDimensionsFromVOLHeader(
                            &data[offset], chunkSize,
                            &width, &height));
                            &width, &height)) {
                    ALOGE("Failed to get dimension");
                    return NULL;
                }

                state = WAIT_FOR_VOP_START;
                break;
@@ -1242,7 +1319,10 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
                    mBuffer->setRange(0, size);

                    int64_t timeUs = fetchTimestamp(offset);
                    CHECK_GE(timeUs, 0ll);
                    if (timeUs < 0ll) {
                        ALOGE("Negative timeus");
                        return NULL;
                    }

                    offset = 0;

@@ -1266,7 +1346,8 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
            }

            default:
                TRESPASS();
                ALOGE("Unknown state: %d", state);
                return NULL;
        }

        if (discard) {
+75 −26

File changed.

Preview size limit exceeded, changes collapsed.

+4 −1
Original line number Diff line number Diff line
@@ -131,7 +131,10 @@ sp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {

    bool seekable = true;
    if (mSourceImpls.size() > 1) {
        CHECK_EQ(mSourceImpls.size(), 2u);
        if (mSourceImpls.size() != 2u) {
            ALOGE("Wrong size");
            return NULL;
        }

        sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat();
        const char *mime;