Support for communicating if a buffer read from the _extractor_ is a sync sample or not.

Change-Id: Ie71506224d937cfff1fa1273bfac31c47db8845f
related-to-bug: 2900534
This commit is contained in:
Andreas Huber
2010-08-06 14:13:10 -07:00
parent 261aaa16a2
commit ad98d383a0
8 changed files with 65 additions and 33 deletions

View File

@@ -263,6 +263,7 @@ status_t AMRSource::read(
buffer->set_range(0, frameSize); buffer->set_range(0, frameSize);
buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
mOffset += frameSize; mOffset += frameSize;
mCurrentTimeUs += 20000; // Each frame is 20ms mCurrentTimeUs += 20000; // Each frame is 20ms

View File

@@ -683,6 +683,7 @@ status_t MP3Source::read(
buffer->set_range(0, frame_size); buffer->set_range(0, frame_size);
buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
mCurrentPos += frame_size; mCurrentPos += frame_size;
mCurrentTimeUs += frame_size * 8000ll / bitrate; mCurrentTimeUs += frame_size * 8000ll / bitrate;

View File

@@ -1551,13 +1551,14 @@ status_t MPEG4Source::read(
off_t offset; off_t offset;
size_t size; size_t size;
uint32_t dts; uint32_t dts;
bool isSyncSample;
bool newBuffer = false; bool newBuffer = false;
if (mBuffer == NULL) { if (mBuffer == NULL) {
newBuffer = true; newBuffer = true;
status_t err = status_t err =
mSampleTable->getMetaDataForSample( mSampleTable->getMetaDataForSample(
mCurrentSampleIndex, &offset, &size, &dts); mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample);
if (err != OK) { if (err != OK) {
return err; return err;
@@ -1594,6 +1595,10 @@ status_t MPEG4Source::read(
kKeyTargetTime, targetSampleTimeUs); kKeyTargetTime, targetSampleTimeUs);
} }
if (isSyncSample) {
mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
}
++mCurrentSampleIndex; ++mCurrentSampleIndex;
} }
@@ -1696,6 +1701,10 @@ status_t MPEG4Source::read(
kKeyTargetTime, targetSampleTimeUs); kKeyTargetTime, targetSampleTimeUs);
} }
if (isSyncSample) {
mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
}
++mCurrentSampleIndex; ++mCurrentSampleIndex;
*out = mBuffer; *out = mBuffer;

View File

@@ -181,6 +181,8 @@ status_t OggSource::read(
} }
#endif #endif
packet->meta_data()->setInt32(kKeyIsSyncFrame, 1);
*out = packet; *out = packet;
return OK; return OK;

View File

@@ -55,6 +55,8 @@ SampleTable::SampleTable(const sp<DataSource> &source)
mTimeToSample(NULL), mTimeToSample(NULL),
mSyncSampleOffset(-1), mSyncSampleOffset(-1),
mNumSyncSamples(0), mNumSyncSamples(0),
mSyncSamples(NULL),
mLastSyncSampleIndex(0),
mSampleToChunkEntries(NULL) { mSampleToChunkEntries(NULL) {
mSampleIterator = new SampleIterator(this); mSampleIterator = new SampleIterator(this);
} }
@@ -63,6 +65,9 @@ SampleTable::~SampleTable() {
delete[] mSampleToChunkEntries; delete[] mSampleToChunkEntries;
mSampleToChunkEntries = NULL; mSampleToChunkEntries = NULL;
delete[] mSyncSamples;
mSyncSamples = NULL;
delete[] mTimeToSample; delete[] mTimeToSample;
mTimeToSample = NULL; mTimeToSample = NULL;
@@ -278,6 +283,18 @@ status_t SampleTable::setSyncSampleParams(off_t data_offset, size_t data_size) {
if (mNumSyncSamples < 2) { if (mNumSyncSamples < 2) {
LOGW("Table of sync samples is empty or has only a single entry!"); LOGW("Table of sync samples is empty or has only a single entry!");
} }
mSyncSamples = new uint32_t[mNumSyncSamples];
size_t size = mNumSyncSamples * sizeof(uint32_t);
if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
!= (ssize_t)size) {
return ERROR_IO;
}
for (size_t i = 0; i < mNumSyncSamples; ++i) {
mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
}
return OK; return OK;
} }
@@ -394,14 +411,7 @@ status_t SampleTable::findSyncSampleNear(
uint32_t left = 0; uint32_t left = 0;
while (left < mNumSyncSamples) { while (left < mNumSyncSamples) {
uint32_t x; uint32_t x = mSyncSamples[left];
if (mDataSource->readAt(
mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) {
return ERROR_IO;
}
x = ntohl(x);
--x;
if (x >= start_sample_index) { if (x >= start_sample_index) {
break; break;
@@ -421,14 +431,7 @@ status_t SampleTable::findSyncSampleNear(
--x; --x;
if (left + 1 < mNumSyncSamples) { if (left + 1 < mNumSyncSamples) {
uint32_t y; uint32_t y = mSyncSamples[left + 1];
if (mDataSource->readAt(
mSyncSampleOffset + 8 + (left + 1) * 4, &y, 4) != 4) {
return ERROR_IO;
}
y = ntohl(y);
--y;
// our sample lies between sync samples x and y. // our sample lies between sync samples x and y.
@@ -486,13 +489,7 @@ status_t SampleTable::findSyncSampleNear(
return ERROR_OUT_OF_RANGE; return ERROR_OUT_OF_RANGE;
} }
if (mDataSource->readAt( x = mSyncSamples[left + 1];
mSyncSampleOffset + 8 + (left + 1) * 4, &x, 4) != 4) {
return ERROR_IO;
}
x = ntohl(x);
--x;
CHECK(x >= start_sample_index); CHECK(x >= start_sample_index);
} }
@@ -532,13 +529,7 @@ status_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
} }
for (size_t i = 0; i < numSamplesToScan; ++i) { for (size_t i = 0; i < numSamplesToScan; ++i) {
uint32_t x; uint32_t x = mSyncSamples[i];
if (mDataSource->readAt(
mSyncSampleOffset + 8 + i * 4, &x, 4) != 4) {
return ERROR_IO;
}
x = ntohl(x);
--x;
// Now x is a sample index. // Now x is a sample index.
size_t sampleSize; size_t sampleSize;
@@ -568,7 +559,8 @@ status_t SampleTable::getMetaDataForSample(
uint32_t sampleIndex, uint32_t sampleIndex,
off_t *offset, off_t *offset,
size_t *size, size_t *size,
uint32_t *decodingTime) { uint32_t *decodingTime,
bool *isSyncSample) {
Mutex::Autolock autoLock(mLock); Mutex::Autolock autoLock(mLock);
status_t err; status_t err;
@@ -588,6 +580,28 @@ status_t SampleTable::getMetaDataForSample(
*decodingTime = mSampleIterator->getSampleTime(); *decodingTime = mSampleIterator->getSampleTime();
} }
if (isSyncSample) {
*isSyncSample = false;
if (mSyncSampleOffset < 0) {
// Every sample is a sync sample.
*isSyncSample = true;
} else {
size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
&& (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
? mLastSyncSampleIndex : 0;
while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
++i;
}
if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
*isSyncSample = true;
}
mLastSyncSampleIndex = i;
}
}
return OK; return OK;
} }

View File

@@ -358,6 +358,7 @@ status_t WAVSource::read(
1000000LL * (mCurrentPos - mOffset) 1000000LL * (mCurrentPos - mOffset)
/ (mNumChannels * bytesPerSample) / mSampleRate); / (mNumChannels * bytesPerSample) / mSampleRate);
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
*out = buffer; *out = buffer;

View File

@@ -60,7 +60,8 @@ public:
uint32_t sampleIndex, uint32_t sampleIndex,
off_t *offset, off_t *offset,
size_t *size, size_t *size,
uint32_t *decodingTime); uint32_t *decodingTime,
bool *isSyncSample = NULL);
enum { enum {
kFlagBefore, kFlagBefore,
@@ -105,6 +106,8 @@ private:
off_t mSyncSampleOffset; off_t mSyncSampleOffset;
uint32_t mNumSyncSamples; uint32_t mNumSyncSamples;
uint32_t *mSyncSamples;
size_t mLastSyncSampleIndex;
SampleIterator *mSampleIterator; SampleIterator *mSampleIterator;

View File

@@ -296,6 +296,7 @@ status_t MatroskaSource::read(
MediaBuffer *buffer = new MediaBuffer(size + 2); MediaBuffer *buffer = new MediaBuffer(size + 2);
buffer->meta_data()->setInt64(kKeyTime, timeUs); buffer->meta_data()->setInt64(kKeyTime, timeUs);
buffer->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
long res = block->Read( long res = block->Read(
mExtractor->mReader, (unsigned char *)buffer->data() + 2); mExtractor->mReader, (unsigned char *)buffer->data() + 2);