Loading media/libmedia/IDataSource.cpp +10 −2 Original line number Original line Diff line number Diff line Loading @@ -50,8 +50,16 @@ struct BpDataSource : public BpInterface<IDataSource> { data.writeInterfaceToken(IDataSource::getInterfaceDescriptor()); data.writeInterfaceToken(IDataSource::getInterfaceDescriptor()); data.writeInt64(offset); data.writeInt64(offset); data.writeInt64(size); data.writeInt64(size); remote()->transact(READ_AT, data, &reply); status_t err = remote()->transact(READ_AT, data, &reply); return reply.readInt64(); if (err != OK) { return err; } int64_t value = 0; err = reply.readInt64(&value); if (err != OK) { return err; } return (ssize_t)value; } } virtual status_t getSize(off64_t* size) { virtual status_t getSize(off64_t* size) { Loading media/libstagefright/MPEG4Extractor.cpp +59 −8 Original line number Original line Diff line number Diff line Loading @@ -67,6 +67,7 @@ public: Vector<SidxEntry> &sidx, Vector<SidxEntry> &sidx, const Trex *trex, const Trex *trex, off64_t firstMoofOffset); off64_t firstMoofOffset); virtual status_t init(); virtual status_t start(MetaData *params = NULL); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); virtual status_t stop(); Loading Loading @@ -2016,7 +2017,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { *offset += chunk_size; *offset += chunk_size; if (underQTMetaPath(mPath, 3)) { if (underQTMetaPath(mPath, 3)) { parseQTMetaKey(data_offset, chunk_data_size); status_t err = parseQTMetaKey(data_offset, chunk_data_size); if (err != OK) { return err; } } } break; break; } } Loading Loading @@ -2160,7 +2164,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 'i', 'd', 'x'): case FOURCC('s', 'i', 'd', 'x'): { { parseSegmentIndex(data_offset, chunk_data_size); status_t err = parseSegmentIndex(data_offset, chunk_data_size); if (err != OK) { return err; } *offset += chunk_size; *offset += chunk_size; return UNKNOWN_ERROR; // stop parsing after sidx return UNKNOWN_ERROR; // stop parsing after sidx } } Loading @@ -2170,7 +2177,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { // check if we're parsing 'ilst' for meta keys // check if we're parsing 'ilst' for meta keys // if so, treat type as a number (key-id). // if so, treat type as a number (key-id). if (underQTMetaPath(mPath, 3)) { if (underQTMetaPath(mPath, 3)) { parseQTMetaVal(chunk_type, data_offset, chunk_data_size); status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size); if (err != OK) { return err; } } } *offset += chunk_size; *offset += chunk_size; Loading Loading @@ -2919,9 +2929,13 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { ALOGV("getTrack called, pssh: %zu", mPssh.size()); ALOGV("getTrack called, pssh: %zu", mPssh.size()); return new MPEG4Source(this, sp<MPEG4Source> source = new MPEG4Source(this, track->meta, mDataSource, track->timescale, track->sampleTable, track->meta, mDataSource, track->timescale, track->sampleTable, mSidxEntries, trex, mMoofOffset); mSidxEntries, trex, mMoofOffset); if (source->init() != OK) { return NULL; } return source; } } // static // static Loading Loading @@ -3318,6 +3332,7 @@ MPEG4Source::MPEG4Source( mTrex(trex), mTrex(trex), mFirstMoofOffset(firstMoofOffset), mFirstMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), mNextMoofOffset(-1), mCurrentTime(0), mCurrentTime(0), mCurrentSampleInfoAllocSize(0), mCurrentSampleInfoAllocSize(0), mCurrentSampleInfoSizes(NULL), mCurrentSampleInfoSizes(NULL), Loading Loading @@ -3382,10 +3397,14 @@ MPEG4Source::MPEG4Source( CHECK(format->findInt32(kKeyTrackID, &mTrackId)); CHECK(format->findInt32(kKeyTrackID, &mTrackId)); } status_t MPEG4Source::init() { if (mFirstMoofOffset != 0) { if (mFirstMoofOffset != 0) { off64_t offset = mFirstMoofOffset; off64_t offset = mFirstMoofOffset; parseChunk(&offset); return parseChunk(&offset); } } return OK; } } MPEG4Source::~MPEG4Source() { MPEG4Source::~MPEG4Source() { Loading Loading @@ -3509,9 +3528,30 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { } } chunk_size = ntohl(hdr[0]); chunk_size = ntohl(hdr[0]); chunk_type = ntohl(hdr[1]); chunk_type = ntohl(hdr[1]); if (chunk_size == 1) { // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box // which is defined in 4.2 Object Structure. // When chunk_size==1, 8 bytes follows as "largesize". if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { return ERROR_IO; } chunk_size = ntoh64(chunk_size); if (chunk_size < 16) { // The smallest valid chunk is 16 bytes long in this case. return ERROR_MALFORMED; } } else if (chunk_size == 0) { // next box extends to end of file. } else if (chunk_size < 8) { // The smallest valid chunk is 8 bytes long in this case. return ERROR_MALFORMED; } if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { mNextMoofOffset = *offset; mNextMoofOffset = *offset; break; break; } else if (chunk_size == 0) { break; } } *offset += chunk_size; *offset += chunk_size; } } Loading Loading @@ -4376,17 +4416,25 @@ status_t MPEG4Source::fragmentedRead( totalOffset += se->mSize; totalOffset += se->mSize; } } mCurrentMoofOffset = totalOffset; mCurrentMoofOffset = totalOffset; mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSamples.clear(); mCurrentSampleIndex = 0; mCurrentSampleIndex = 0; parseChunk(&totalOffset); status_t err = parseChunk(&totalOffset); if (err != OK) { return err; } mCurrentTime = totalTime * mTimescale / 1000000ll; mCurrentTime = totalTime * mTimescale / 1000000ll; } else { } else { // without sidx boxes, we can only seek to 0 // without sidx boxes, we can only seek to 0 mCurrentMoofOffset = mFirstMoofOffset; mCurrentMoofOffset = mFirstMoofOffset; mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSamples.clear(); mCurrentSampleIndex = 0; mCurrentSampleIndex = 0; off64_t tmp = mCurrentMoofOffset; off64_t tmp = mCurrentMoofOffset; parseChunk(&tmp); status_t err = parseChunk(&tmp); if (err != OK) { return err; } mCurrentTime = 0; mCurrentTime = 0; } } Loading Loading @@ -4415,7 +4463,10 @@ status_t MPEG4Source::fragmentedRead( mCurrentMoofOffset = nextMoof; mCurrentMoofOffset = nextMoof; mCurrentSamples.clear(); mCurrentSamples.clear(); mCurrentSampleIndex = 0; mCurrentSampleIndex = 0; parseChunk(&nextMoof); status_t err = parseChunk(&nextMoof); if (err != OK) { return err; } if (mCurrentSampleIndex >= mCurrentSamples.size()) { if (mCurrentSampleIndex >= mCurrentSamples.size()) { return ERROR_END_OF_STREAM; return ERROR_END_OF_STREAM; } } Loading Loading
media/libmedia/IDataSource.cpp +10 −2 Original line number Original line Diff line number Diff line Loading @@ -50,8 +50,16 @@ struct BpDataSource : public BpInterface<IDataSource> { data.writeInterfaceToken(IDataSource::getInterfaceDescriptor()); data.writeInterfaceToken(IDataSource::getInterfaceDescriptor()); data.writeInt64(offset); data.writeInt64(offset); data.writeInt64(size); data.writeInt64(size); remote()->transact(READ_AT, data, &reply); status_t err = remote()->transact(READ_AT, data, &reply); return reply.readInt64(); if (err != OK) { return err; } int64_t value = 0; err = reply.readInt64(&value); if (err != OK) { return err; } return (ssize_t)value; } } virtual status_t getSize(off64_t* size) { virtual status_t getSize(off64_t* size) { Loading
media/libstagefright/MPEG4Extractor.cpp +59 −8 Original line number Original line Diff line number Diff line Loading @@ -67,6 +67,7 @@ public: Vector<SidxEntry> &sidx, Vector<SidxEntry> &sidx, const Trex *trex, const Trex *trex, off64_t firstMoofOffset); off64_t firstMoofOffset); virtual status_t init(); virtual status_t start(MetaData *params = NULL); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); virtual status_t stop(); Loading Loading @@ -2016,7 +2017,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { *offset += chunk_size; *offset += chunk_size; if (underQTMetaPath(mPath, 3)) { if (underQTMetaPath(mPath, 3)) { parseQTMetaKey(data_offset, chunk_data_size); status_t err = parseQTMetaKey(data_offset, chunk_data_size); if (err != OK) { return err; } } } break; break; } } Loading Loading @@ -2160,7 +2164,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('s', 'i', 'd', 'x'): case FOURCC('s', 'i', 'd', 'x'): { { parseSegmentIndex(data_offset, chunk_data_size); status_t err = parseSegmentIndex(data_offset, chunk_data_size); if (err != OK) { return err; } *offset += chunk_size; *offset += chunk_size; return UNKNOWN_ERROR; // stop parsing after sidx return UNKNOWN_ERROR; // stop parsing after sidx } } Loading @@ -2170,7 +2177,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { // check if we're parsing 'ilst' for meta keys // check if we're parsing 'ilst' for meta keys // if so, treat type as a number (key-id). // if so, treat type as a number (key-id). if (underQTMetaPath(mPath, 3)) { if (underQTMetaPath(mPath, 3)) { parseQTMetaVal(chunk_type, data_offset, chunk_data_size); status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size); if (err != OK) { return err; } } } *offset += chunk_size; *offset += chunk_size; Loading Loading @@ -2919,9 +2929,13 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { ALOGV("getTrack called, pssh: %zu", mPssh.size()); ALOGV("getTrack called, pssh: %zu", mPssh.size()); return new MPEG4Source(this, sp<MPEG4Source> source = new MPEG4Source(this, track->meta, mDataSource, track->timescale, track->sampleTable, track->meta, mDataSource, track->timescale, track->sampleTable, mSidxEntries, trex, mMoofOffset); mSidxEntries, trex, mMoofOffset); if (source->init() != OK) { return NULL; } return source; } } // static // static Loading Loading @@ -3318,6 +3332,7 @@ MPEG4Source::MPEG4Source( mTrex(trex), mTrex(trex), mFirstMoofOffset(firstMoofOffset), mFirstMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), mCurrentMoofOffset(firstMoofOffset), mNextMoofOffset(-1), mCurrentTime(0), mCurrentTime(0), mCurrentSampleInfoAllocSize(0), mCurrentSampleInfoAllocSize(0), mCurrentSampleInfoSizes(NULL), mCurrentSampleInfoSizes(NULL), Loading Loading @@ -3382,10 +3397,14 @@ MPEG4Source::MPEG4Source( CHECK(format->findInt32(kKeyTrackID, &mTrackId)); CHECK(format->findInt32(kKeyTrackID, &mTrackId)); } status_t MPEG4Source::init() { if (mFirstMoofOffset != 0) { if (mFirstMoofOffset != 0) { off64_t offset = mFirstMoofOffset; off64_t offset = mFirstMoofOffset; parseChunk(&offset); return parseChunk(&offset); } } return OK; } } MPEG4Source::~MPEG4Source() { MPEG4Source::~MPEG4Source() { Loading Loading @@ -3509,9 +3528,30 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { } } chunk_size = ntohl(hdr[0]); chunk_size = ntohl(hdr[0]); chunk_type = ntohl(hdr[1]); chunk_type = ntohl(hdr[1]); if (chunk_size == 1) { // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box // which is defined in 4.2 Object Structure. // When chunk_size==1, 8 bytes follows as "largesize". if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { return ERROR_IO; } chunk_size = ntoh64(chunk_size); if (chunk_size < 16) { // The smallest valid chunk is 16 bytes long in this case. return ERROR_MALFORMED; } } else if (chunk_size == 0) { // next box extends to end of file. } else if (chunk_size < 8) { // The smallest valid chunk is 8 bytes long in this case. return ERROR_MALFORMED; } if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { mNextMoofOffset = *offset; mNextMoofOffset = *offset; break; break; } else if (chunk_size == 0) { break; } } *offset += chunk_size; *offset += chunk_size; } } Loading Loading @@ -4376,17 +4416,25 @@ status_t MPEG4Source::fragmentedRead( totalOffset += se->mSize; totalOffset += se->mSize; } } mCurrentMoofOffset = totalOffset; mCurrentMoofOffset = totalOffset; mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSamples.clear(); mCurrentSampleIndex = 0; mCurrentSampleIndex = 0; parseChunk(&totalOffset); status_t err = parseChunk(&totalOffset); if (err != OK) { return err; } mCurrentTime = totalTime * mTimescale / 1000000ll; mCurrentTime = totalTime * mTimescale / 1000000ll; } else { } else { // without sidx boxes, we can only seek to 0 // without sidx boxes, we can only seek to 0 mCurrentMoofOffset = mFirstMoofOffset; mCurrentMoofOffset = mFirstMoofOffset; mNextMoofOffset = -1; mCurrentSamples.clear(); mCurrentSamples.clear(); mCurrentSampleIndex = 0; mCurrentSampleIndex = 0; off64_t tmp = mCurrentMoofOffset; off64_t tmp = mCurrentMoofOffset; parseChunk(&tmp); status_t err = parseChunk(&tmp); if (err != OK) { return err; } mCurrentTime = 0; mCurrentTime = 0; } } Loading Loading @@ -4415,7 +4463,10 @@ status_t MPEG4Source::fragmentedRead( mCurrentMoofOffset = nextMoof; mCurrentMoofOffset = nextMoof; mCurrentSamples.clear(); mCurrentSamples.clear(); mCurrentSampleIndex = 0; mCurrentSampleIndex = 0; parseChunk(&nextMoof); status_t err = parseChunk(&nextMoof); if (err != OK) { return err; } if (mCurrentSampleIndex >= mCurrentSamples.size()) { if (mCurrentSampleIndex >= mCurrentSamples.size()) { return ERROR_END_OF_STREAM; return ERROR_END_OF_STREAM; } } Loading