Bug 1128410: Lazily allocate the MP4 parser buffer. r=kentuckyfriedtakahe

This buffer is unsused for fragmented MP4. So we don't need to unecessarily
allocate it and block a chunk of 3MB data. Also, this removes the restriction
of playing YouTube video > 1080p
This commit is contained in:
Jean-Yves Avenard 2015-02-02 21:36:48 +11:00
parent 9aba60f615
commit 63be8f20a5

View File

@ -103,6 +103,7 @@ private:
bool mWantsNALFragments;
uint8_t *mSrcBuffer;
int32_t mSrcBufferSize;
size_t parseNALSize(const uint8_t *data) const;
status_t parseChunk(off64_t *offset);
@ -163,6 +164,8 @@ private:
MPEG4Source(const MPEG4Source &);
MPEG4Source &operator=(const MPEG4Source &);
bool ensureSrcBufferAllocated();
};
// This custom data source wraps an existing one and satisfies requests
@ -723,6 +726,13 @@ static void convertTimeToDate(int64_t time_1904, String8 *s) {
s->setTo(tmp);
}
static bool ValidInputSize(int32_t size) {
// Reject compressed samples larger than an uncompressed UHD
// frame. This is a reasonable cut-off for a lossy codec,
// combined with the current Firefox limit to 5k video.
return (size > 0 && size <= 4 * (1920 * 1080) * 3 / 2);
}
status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
ALOGV("entering parseChunk %lld/%d", *offset, depth);
uint32_t hdr[2];
@ -2502,6 +2512,7 @@ MPEG4Source::MPEG4Source(
mBuffer(NULL),
mWantsNALFragments(false),
mSrcBuffer(NULL),
mSrcBufferSize(0),
mTrackExtends(trackExtends) {
mFormat->findInt32(kKeyCryptoMode, &mCryptoMode);
@ -2548,13 +2559,6 @@ MPEG4Source::~MPEG4Source() {
free(mCurrentSampleInfoOffsets);
}
static bool ValidInputSize(int32_t size) {
// Reject compressed samples larger than an uncompressed UHD
// frame. This is a reasonable cut-off for a lossy codec,
// combined with the current Firefox limit to 5k video.
return (size > 0 && size <= 4 * (1920 * 1080) * 3 / 2);
}
status_t MPEG4Source::start(MetaData *params) {
Mutex::Autolock autoLock(mLock);
@ -2568,14 +2572,7 @@ status_t MPEG4Source::start(MetaData *params) {
mWantsNALFragments = false;
}
int32_t max_size;
CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
if (!ValidInputSize(max_size)) {
ALOGE("Invalid max input size %d", max_size);
return ERROR_MALFORMED;
}
mSrcBuffer = new uint8_t[max_size];
CHECK(mFormat->findInt32(kKeyMaxInputSize, &mSrcBufferSize));
mStarted = true;
@ -3269,6 +3266,17 @@ status_t MPEG4Source::lookForMoof() {
}
}
bool MPEG4Source::ensureSrcBufferAllocated() {
if (mSrcBuffer) {
return true;
}
if (!ValidInputSize(mSrcBufferSize)) {
ALOGE("Invalid max input size %d", mSrcBufferSize);
return false;
}
mSrcBuffer = new uint8_t[mSrcBufferSize];
return true;
}
status_t MPEG4Source::read(
MediaBuffer **out, const ReadOptions *options) {
@ -3514,6 +3522,9 @@ status_t MPEG4Source::read(
num_bytes_read =
mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
} else {
if (!ensureSrcBufferAllocated()) {
return ERROR_MALFORMED;
}
num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
}
@ -3866,6 +3877,9 @@ status_t MPEG4Source::fragmentedRead(
num_bytes_read =
mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
} else {
if (!ensureSrcBufferAllocated()) {
return ERROR_MALFORMED;
}
num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
}