summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/mpeg2ts
diff options
context:
space:
mode:
authorJinsuk Kim <jinsukkim@google.com>2015-04-22 11:08:28 +0900
committerJinsuk Kim <jinsukkim@google.com>2015-04-29 08:48:33 +0000
commite314c678ea0b53dd9296ba6b5c3272c702433b47 (patch)
tree584a8a385fe067ecdc2d4ced76a49f1391334a3f /media/libstagefright/mpeg2ts
parent1e2a0e6adc3d70879b00e5295c54a74209b71e1b (diff)
downloadframeworks_av-e314c678ea0b53dd9296ba6b5c3272c702433b47.zip
frameworks_av-e314c678ea0b53dd9296ba6b5c3272c702433b47.tar.gz
frameworks_av-e314c678ea0b53dd9296ba6b5c3272c702433b47.tar.bz2
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 e84ab89a2cdae1d1828225f88d895882d716f90e)
Diffstat (limited to 'media/libstagefright/mpeg2ts')
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp186
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h2
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.cpp151
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp101
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp5
5 files changed, 320 insertions, 125 deletions
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 5411821..0d071b2 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -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,15 +1436,16 @@ 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 == 1 || adaptation_field_control == 3) {
- err = parsePID(
- br, PID, continuity_counter, payload_unit_start_indicator);
+ 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;
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 87ab1a0..4def333 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -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);
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index f28a1fd..7b5b46a 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -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) {
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index 85859f7..67ffad3 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -265,7 +265,10 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
}
unsigned PES_packet_length = U16_AT(mBuffer->data() + 4);
- CHECK_NE(PES_packet_length, 0u);
+ if (PES_packet_length == 0u) {
+ ALOGE("PES_packet_length is 0");
+ return -EAGAIN;
+ }
size_t n = PES_packet_length + 6;
@@ -286,7 +289,10 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
return ERROR_MALFORMED;
}
- CHECK_EQ(packet_startcode_prefix, 0x000001u);
+ if (packet_startcode_prefix != 0x000001u) {
+ ALOGE("Wrong PES prefix");
+ return ERROR_MALFORMED;
+ }
unsigned stream_id = br.getBits(8);
ALOGV("stream_id = 0x%02x", stream_id);
@@ -366,8 +372,7 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
&& stream_id != 0xff // program_stream_directory
&& stream_id != 0xf2 // DSMCC
&& stream_id != 0xf8) { // H.222.1 type E
- CHECK_EQ(br.getBits(2), 2u);
-
+ /* unsigned PES_marker_bits = */br.getBits(2); // should be 0x2(hex)
/* unsigned PES_scrambling_control = */br.getBits(2);
/* unsigned PES_priority = */br.getBits(1);
/* unsigned data_alignment_indicator = */br.getBits(1);
@@ -400,16 +405,26 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
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;
+ }
- CHECK_EQ(br.getBits(4), PTS_DTS_flags);
+ if (br.getBits(4) != PTS_DTS_flags) {
+ 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 = %" PRIu64, PTS);
// ALOGI("PTS = %.2f secs", PTS / 90000.0f);
@@ -417,16 +432,26 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
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);
@@ -435,31 +460,47 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
}
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);
/* unsigned ESCR_extension = */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;
+ }
/* unsigned ES_rate = */br.getBits(22);
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
optional_bytes_remaining -= 3;
}
@@ -468,7 +509,9 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
// ES data follows.
- 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;
@@ -481,7 +524,9 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
return ERROR_MALFORMED;
}
- CHECK_GE(br.numBitsLeft(), dataLength * 8);
+ if (br.numBitsLeft() < dataLength * 8) {
+ return ERROR_MALFORMED;
+ }
ssize_t index = mTracks.indexOfKey(stream_id);
if (index < 0 && mScanning) {
@@ -521,10 +566,14 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
return err;
}
} 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);
}
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index 74cb5d8..f5c33cf 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -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;