Loading media/libstagefright/MPEG4Extractor.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -3284,7 +3284,7 @@ status_t MPEG4Source::read( uint32_t sampleIndex; uint32_t sampleIndex; status_t err = mSampleTable->findSampleAtTime( status_t err = mSampleTable->findSampleAtTime( seekTimeUs * mTimescale / 1000000, seekTimeUs, 1000000, mTimescale, &sampleIndex, findFlags); &sampleIndex, findFlags); if (mode == ReadOptions::SEEK_CLOSEST) { if (mode == ReadOptions::SEEK_CLOSEST) { Loading media/libstagefright/OggExtractor.cpp +9 −5 Original line number Original line Diff line number Diff line Loading @@ -320,22 +320,26 @@ status_t MyVorbisExtractor::seekToTime(int64_t timeUs) { } } size_t left = 0; size_t left = 0; size_t right = mTableOfContents.size(); size_t right_plus_one = mTableOfContents.size(); while (left < right) { while (left < right_plus_one) { size_t center = left / 2 + right / 2 + (left & right & 1); size_t center = left + (right_plus_one - left) / 2; const TOCEntry &entry = mTableOfContents.itemAt(center); const TOCEntry &entry = mTableOfContents.itemAt(center); if (timeUs < entry.mTimeUs) { if (timeUs < entry.mTimeUs) { right = center; right_plus_one = center; } else if (timeUs > entry.mTimeUs) { } else if (timeUs > entry.mTimeUs) { left = center + 1; left = center + 1; } else { } else { left = right = center; left = center; break; break; } } } } if (left == mTableOfContents.size()) { --left; } const TOCEntry &entry = mTableOfContents.itemAt(left); const TOCEntry &entry = mTableOfContents.itemAt(left); ALOGV("seeking to entry %d / %d at offset %lld", ALOGV("seeking to entry %d / %d at offset %lld", Loading media/libstagefright/SampleTable.cpp +78 −113 Original line number Original line Diff line number Diff line Loading @@ -520,83 +520,72 @@ void SampleTable::buildSampleEntriesTable() { } } status_t SampleTable::findSampleAtTime( status_t SampleTable::findSampleAtTime( uint32_t req_time, uint32_t *sample_index, uint32_t flags) { uint64_t req_time, uint64_t scale_num, uint64_t scale_den, uint32_t *sample_index, uint32_t flags) { buildSampleEntriesTable(); buildSampleEntriesTable(); uint32_t left = 0; uint32_t left = 0; uint32_t right = mNumSampleSizes; uint32_t right_plus_one = mNumSampleSizes; while (left < right) { while (left < right_plus_one) { uint32_t center = (left + right) / 2; uint32_t center = left + (right_plus_one - left) / 2; uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime; uint64_t centerTime = getSampleTime(center, scale_num, scale_den); if (req_time < centerTime) { if (req_time < centerTime) { right = center; right_plus_one = center; } else if (req_time > centerTime) { } else if (req_time > centerTime) { left = center + 1; left = center + 1; } else { } else { left = center; *sample_index = mSampleTimeEntries[center].mSampleIndex; break; return OK; } } } } if (left == mNumSampleSizes) { uint32_t closestIndex = left; if (closestIndex == mNumSampleSizes) { if (flags == kFlagAfter) { if (flags == kFlagAfter) { return ERROR_OUT_OF_RANGE; return ERROR_OUT_OF_RANGE; } } flags = kFlagBefore; --left; } else if (closestIndex == 0) { if (flags == kFlagBefore) { // normally we should return out of range, but that is // treated as end-of-stream. instead return first sample // // return ERROR_OUT_OF_RANGE; } flags = kFlagAfter; } } uint32_t closestIndex = left; switch (flags) { switch (flags) { case kFlagBefore: case kFlagBefore: { { while (closestIndex > 0 && mSampleTimeEntries[closestIndex].mCompositionTime > req_time) { --closestIndex; --closestIndex; } break; break; } } case kFlagAfter: case kFlagAfter: { { while (closestIndex + 1 < mNumSampleSizes // nothing to do && mSampleTimeEntries[closestIndex].mCompositionTime < req_time) { ++closestIndex; } break; break; } } default: default: { { CHECK(flags == kFlagClosest); CHECK(flags == kFlagClosest); // pick closest based on timestamp. use abs_difference for safety if (closestIndex > 0) { if (abs_difference( // Check left neighbour and pick closest. getSampleTime(closestIndex, scale_num, scale_den), req_time) > uint32_t absdiff1 = abs_difference( mSampleTimeEntries[closestIndex].mCompositionTime, req_time); uint32_t absdiff2 = abs_difference( abs_difference( mSampleTimeEntries[closestIndex - 1].mCompositionTime, req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { req_time); --closestIndex; if (absdiff1 > absdiff2) { closestIndex = closestIndex - 1; } } } break; break; } } } } *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; return OK; return OK; } } Loading @@ -618,109 +607,85 @@ status_t SampleTable::findSyncSampleNear( } } uint32_t left = 0; uint32_t left = 0; uint32_t right = mNumSyncSamples; uint32_t right_plus_one = mNumSyncSamples; while (left < right) { while (left < right_plus_one) { uint32_t center = left + (right - left) / 2; uint32_t center = left + (right_plus_one - left) / 2; uint32_t x = mSyncSamples[center]; uint32_t x = mSyncSamples[center]; if (start_sample_index < x) { if (start_sample_index < x) { right = center; right_plus_one = center; } else if (start_sample_index > x) { } else if (start_sample_index > x) { left = center + 1; left = center + 1; } else { } else { left = center; *sample_index = x; break; return OK; } } } } if (left == mNumSyncSamples) { if (left == mNumSyncSamples) { if (flags == kFlagAfter) { if (flags == kFlagAfter) { ALOGE("tried to find a sync frame after the last one: %d", left); ALOGE("tried to find a sync frame after the last one: %d", left); return ERROR_OUT_OF_RANGE; return ERROR_OUT_OF_RANGE; } } left = left - 1; flags = kFlagBefore; } } else if (left == 0) { if (flags == kFlagBefore) { ALOGE("tried to find a sync frame before the first one: %d", left); // Now ssi[left] is the sync sample index just before (or at) // normally we should return out of range, but that is // start_sample_index. // treated as end-of-stream. instead seek to first sync // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples. // // return ERROR_OUT_OF_RANGE; uint32_t x = mSyncSamples[left]; } flags = kFlagAfter; if (left + 1 < mNumSyncSamples) { } uint32_t y = mSyncSamples[left + 1]; // our sample lies between sync samples x and y. // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] switch (flags) { case kFlagBefore: { --left; break; } case kFlagAfter: { // nothing to do break; } default: { // this route is not used, but implement it nonetheless CHECK(flags == kFlagClosest); status_t err = mSampleIterator->seekTo(start_sample_index); status_t err = mSampleIterator->seekTo(start_sample_index); if (err != OK) { if (err != OK) { return err; return err; } } uint32_t sample_time = mSampleIterator->getSampleTime(); uint32_t sample_time = mSampleIterator->getSampleTime(); err = mSampleIterator->seekTo(x); err = mSampleIterator->seekTo(mSyncSamples[left]); if (err != OK) { if (err != OK) { return err; return err; } } uint32_t x_time = mSampleIterator->getSampleTime(); uint32_t upper_time = mSampleIterator->getSampleTime(); err = mSampleIterator->seekTo(y); err = mSampleIterator->seekTo(mSyncSamples[left - 1]); if (err != OK) { if (err != OK) { return err; return err; } } uint32_t lower_time = mSampleIterator->getSampleTime(); uint32_t y_time = mSampleIterator->getSampleTime(); // use abs_difference for safety if (abs_difference(upper_time, sample_time) > if (abs_difference(x_time, sample_time) abs_difference(sample_time, lower_time)) { > abs_difference(y_time, sample_time)) { --left; // Pick the sync sample closest (timewise) to the start-sample. x = y; ++left; } } switch (flags) { case kFlagBefore: { if (x > start_sample_index) { CHECK(left > 0); x = mSyncSamples[left - 1]; if (x > start_sample_index) { // The table of sync sample indices was not sorted // properly. return ERROR_MALFORMED; } } break; } case kFlagAfter: { if (x < start_sample_index) { if (left + 1 >= mNumSyncSamples) { return ERROR_OUT_OF_RANGE; } x = mSyncSamples[left + 1]; if (x < start_sample_index) { // The table of sync sample indices was not sorted // properly. return ERROR_MALFORMED; } } } break; break; } } default: break; } } *sample_index = x; *sample_index = mSyncSamples[left]; return OK; return OK; } } Loading media/libstagefright/include/SampleTable.h +9 −1 Original line number Original line Diff line number Diff line Loading @@ -74,7 +74,8 @@ public: kFlagClosest kFlagClosest }; }; status_t findSampleAtTime( status_t findSampleAtTime( uint32_t req_time, uint32_t *sample_index, uint32_t flags); uint64_t req_time, uint64_t scale_num, uint64_t scale_den, uint32_t *sample_index, uint32_t flags); status_t findSyncSampleNear( status_t findSyncSampleNear( uint32_t start_sample_index, uint32_t *sample_index, uint32_t start_sample_index, uint32_t *sample_index, Loading Loading @@ -137,6 +138,13 @@ private: friend struct SampleIterator; friend struct SampleIterator; // normally we don't round inline uint64_t getSampleTime( size_t sample_index, uint64_t scale_num, uint64_t scale_den) const { return (mSampleTimeEntries[sample_index].mCompositionTime * scale_num) / scale_den; } status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size); status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size); uint32_t getCompositionTimeOffset(uint32_t sampleIndex); uint32_t getCompositionTimeOffset(uint32_t sampleIndex); Loading Loading
media/libstagefright/MPEG4Extractor.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -3284,7 +3284,7 @@ status_t MPEG4Source::read( uint32_t sampleIndex; uint32_t sampleIndex; status_t err = mSampleTable->findSampleAtTime( status_t err = mSampleTable->findSampleAtTime( seekTimeUs * mTimescale / 1000000, seekTimeUs, 1000000, mTimescale, &sampleIndex, findFlags); &sampleIndex, findFlags); if (mode == ReadOptions::SEEK_CLOSEST) { if (mode == ReadOptions::SEEK_CLOSEST) { Loading
media/libstagefright/OggExtractor.cpp +9 −5 Original line number Original line Diff line number Diff line Loading @@ -320,22 +320,26 @@ status_t MyVorbisExtractor::seekToTime(int64_t timeUs) { } } size_t left = 0; size_t left = 0; size_t right = mTableOfContents.size(); size_t right_plus_one = mTableOfContents.size(); while (left < right) { while (left < right_plus_one) { size_t center = left / 2 + right / 2 + (left & right & 1); size_t center = left + (right_plus_one - left) / 2; const TOCEntry &entry = mTableOfContents.itemAt(center); const TOCEntry &entry = mTableOfContents.itemAt(center); if (timeUs < entry.mTimeUs) { if (timeUs < entry.mTimeUs) { right = center; right_plus_one = center; } else if (timeUs > entry.mTimeUs) { } else if (timeUs > entry.mTimeUs) { left = center + 1; left = center + 1; } else { } else { left = right = center; left = center; break; break; } } } } if (left == mTableOfContents.size()) { --left; } const TOCEntry &entry = mTableOfContents.itemAt(left); const TOCEntry &entry = mTableOfContents.itemAt(left); ALOGV("seeking to entry %d / %d at offset %lld", ALOGV("seeking to entry %d / %d at offset %lld", Loading
media/libstagefright/SampleTable.cpp +78 −113 Original line number Original line Diff line number Diff line Loading @@ -520,83 +520,72 @@ void SampleTable::buildSampleEntriesTable() { } } status_t SampleTable::findSampleAtTime( status_t SampleTable::findSampleAtTime( uint32_t req_time, uint32_t *sample_index, uint32_t flags) { uint64_t req_time, uint64_t scale_num, uint64_t scale_den, uint32_t *sample_index, uint32_t flags) { buildSampleEntriesTable(); buildSampleEntriesTable(); uint32_t left = 0; uint32_t left = 0; uint32_t right = mNumSampleSizes; uint32_t right_plus_one = mNumSampleSizes; while (left < right) { while (left < right_plus_one) { uint32_t center = (left + right) / 2; uint32_t center = left + (right_plus_one - left) / 2; uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime; uint64_t centerTime = getSampleTime(center, scale_num, scale_den); if (req_time < centerTime) { if (req_time < centerTime) { right = center; right_plus_one = center; } else if (req_time > centerTime) { } else if (req_time > centerTime) { left = center + 1; left = center + 1; } else { } else { left = center; *sample_index = mSampleTimeEntries[center].mSampleIndex; break; return OK; } } } } if (left == mNumSampleSizes) { uint32_t closestIndex = left; if (closestIndex == mNumSampleSizes) { if (flags == kFlagAfter) { if (flags == kFlagAfter) { return ERROR_OUT_OF_RANGE; return ERROR_OUT_OF_RANGE; } } flags = kFlagBefore; --left; } else if (closestIndex == 0) { if (flags == kFlagBefore) { // normally we should return out of range, but that is // treated as end-of-stream. instead return first sample // // return ERROR_OUT_OF_RANGE; } flags = kFlagAfter; } } uint32_t closestIndex = left; switch (flags) { switch (flags) { case kFlagBefore: case kFlagBefore: { { while (closestIndex > 0 && mSampleTimeEntries[closestIndex].mCompositionTime > req_time) { --closestIndex; --closestIndex; } break; break; } } case kFlagAfter: case kFlagAfter: { { while (closestIndex + 1 < mNumSampleSizes // nothing to do && mSampleTimeEntries[closestIndex].mCompositionTime < req_time) { ++closestIndex; } break; break; } } default: default: { { CHECK(flags == kFlagClosest); CHECK(flags == kFlagClosest); // pick closest based on timestamp. use abs_difference for safety if (closestIndex > 0) { if (abs_difference( // Check left neighbour and pick closest. getSampleTime(closestIndex, scale_num, scale_den), req_time) > uint32_t absdiff1 = abs_difference( mSampleTimeEntries[closestIndex].mCompositionTime, req_time); uint32_t absdiff2 = abs_difference( abs_difference( mSampleTimeEntries[closestIndex - 1].mCompositionTime, req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { req_time); --closestIndex; if (absdiff1 > absdiff2) { closestIndex = closestIndex - 1; } } } break; break; } } } } *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; return OK; return OK; } } Loading @@ -618,109 +607,85 @@ status_t SampleTable::findSyncSampleNear( } } uint32_t left = 0; uint32_t left = 0; uint32_t right = mNumSyncSamples; uint32_t right_plus_one = mNumSyncSamples; while (left < right) { while (left < right_plus_one) { uint32_t center = left + (right - left) / 2; uint32_t center = left + (right_plus_one - left) / 2; uint32_t x = mSyncSamples[center]; uint32_t x = mSyncSamples[center]; if (start_sample_index < x) { if (start_sample_index < x) { right = center; right_plus_one = center; } else if (start_sample_index > x) { } else if (start_sample_index > x) { left = center + 1; left = center + 1; } else { } else { left = center; *sample_index = x; break; return OK; } } } } if (left == mNumSyncSamples) { if (left == mNumSyncSamples) { if (flags == kFlagAfter) { if (flags == kFlagAfter) { ALOGE("tried to find a sync frame after the last one: %d", left); ALOGE("tried to find a sync frame after the last one: %d", left); return ERROR_OUT_OF_RANGE; return ERROR_OUT_OF_RANGE; } } left = left - 1; flags = kFlagBefore; } } else if (left == 0) { if (flags == kFlagBefore) { ALOGE("tried to find a sync frame before the first one: %d", left); // Now ssi[left] is the sync sample index just before (or at) // normally we should return out of range, but that is // start_sample_index. // treated as end-of-stream. instead seek to first sync // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples. // // return ERROR_OUT_OF_RANGE; uint32_t x = mSyncSamples[left]; } flags = kFlagAfter; if (left + 1 < mNumSyncSamples) { } uint32_t y = mSyncSamples[left + 1]; // our sample lies between sync samples x and y. // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] switch (flags) { case kFlagBefore: { --left; break; } case kFlagAfter: { // nothing to do break; } default: { // this route is not used, but implement it nonetheless CHECK(flags == kFlagClosest); status_t err = mSampleIterator->seekTo(start_sample_index); status_t err = mSampleIterator->seekTo(start_sample_index); if (err != OK) { if (err != OK) { return err; return err; } } uint32_t sample_time = mSampleIterator->getSampleTime(); uint32_t sample_time = mSampleIterator->getSampleTime(); err = mSampleIterator->seekTo(x); err = mSampleIterator->seekTo(mSyncSamples[left]); if (err != OK) { if (err != OK) { return err; return err; } } uint32_t x_time = mSampleIterator->getSampleTime(); uint32_t upper_time = mSampleIterator->getSampleTime(); err = mSampleIterator->seekTo(y); err = mSampleIterator->seekTo(mSyncSamples[left - 1]); if (err != OK) { if (err != OK) { return err; return err; } } uint32_t lower_time = mSampleIterator->getSampleTime(); uint32_t y_time = mSampleIterator->getSampleTime(); // use abs_difference for safety if (abs_difference(upper_time, sample_time) > if (abs_difference(x_time, sample_time) abs_difference(sample_time, lower_time)) { > abs_difference(y_time, sample_time)) { --left; // Pick the sync sample closest (timewise) to the start-sample. x = y; ++left; } } switch (flags) { case kFlagBefore: { if (x > start_sample_index) { CHECK(left > 0); x = mSyncSamples[left - 1]; if (x > start_sample_index) { // The table of sync sample indices was not sorted // properly. return ERROR_MALFORMED; } } break; } case kFlagAfter: { if (x < start_sample_index) { if (left + 1 >= mNumSyncSamples) { return ERROR_OUT_OF_RANGE; } x = mSyncSamples[left + 1]; if (x < start_sample_index) { // The table of sync sample indices was not sorted // properly. return ERROR_MALFORMED; } } } break; break; } } default: break; } } *sample_index = x; *sample_index = mSyncSamples[left]; return OK; return OK; } } Loading
media/libstagefright/include/SampleTable.h +9 −1 Original line number Original line Diff line number Diff line Loading @@ -74,7 +74,8 @@ public: kFlagClosest kFlagClosest }; }; status_t findSampleAtTime( status_t findSampleAtTime( uint32_t req_time, uint32_t *sample_index, uint32_t flags); uint64_t req_time, uint64_t scale_num, uint64_t scale_den, uint32_t *sample_index, uint32_t flags); status_t findSyncSampleNear( status_t findSyncSampleNear( uint32_t start_sample_index, uint32_t *sample_index, uint32_t start_sample_index, uint32_t *sample_index, Loading Loading @@ -137,6 +138,13 @@ private: friend struct SampleIterator; friend struct SampleIterator; // normally we don't round inline uint64_t getSampleTime( size_t sample_index, uint64_t scale_num, uint64_t scale_den) const { return (mSampleTimeEntries[sample_index].mCompositionTime * scale_num) / scale_den; } status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size); status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size); uint32_t getCompositionTimeOffset(uint32_t sampleIndex); uint32_t getCompositionTimeOffset(uint32_t sampleIndex); Loading