Merge "Make sure timestamps attached to encoded media are composition timestamps."

This commit is contained in:
Andreas Huber
2011-02-03 16:19:30 -08:00
committed by Android (Google) Code Review
4 changed files with 97 additions and 0 deletions

View File

@@ -1074,6 +1074,20 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
break;
}
case FOURCC('c', 't', 't', 's'):
{
status_t err =
mLastTrack->sampleTable->setCompositionTimeToSampleParams(
data_offset, chunk_data_size);
if (err != OK) {
return err;
}
*offset += chunk_size;
break;
}
case FOURCC('s', 't', 's', 's'):
{
status_t err =

View File

@@ -307,6 +307,8 @@ status_t SampleIterator::findSampleTime(
*time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
*time += mTable->getCompositionTimeOffset(sampleIndex);
return OK;
}

View File

@@ -53,6 +53,8 @@ SampleTable::SampleTable(const sp<DataSource> &source)
mNumSampleSizes(0),
mTimeToSampleCount(0),
mTimeToSample(NULL),
mCompositionTimeDeltaEntries(NULL),
mNumCompositionTimeDeltaEntries(0),
mSyncSampleOffset(-1),
mNumSyncSamples(0),
mSyncSamples(NULL),
@@ -68,6 +70,9 @@ SampleTable::~SampleTable() {
delete[] mSyncSamples;
mSyncSamples = NULL;
delete[] mCompositionTimeDeltaEntries;
mCompositionTimeDeltaEntries = NULL;
delete[] mTimeToSample;
mTimeToSample = NULL;
@@ -260,6 +265,51 @@ status_t SampleTable::setTimeToSampleParams(
return OK;
}
status_t SampleTable::setCompositionTimeToSampleParams(
off64_t data_offset, size_t data_size) {
LOGI("There are reordered frames present.");
if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
return ERROR_MALFORMED;
}
uint8_t header[8];
if (mDataSource->readAt(
data_offset, header, sizeof(header))
< (ssize_t)sizeof(header)) {
return ERROR_IO;
}
if (U32_AT(header) != 0) {
// Expected version = 0, flags = 0.
return ERROR_MALFORMED;
}
size_t numEntries = U32_AT(&header[4]);
if (data_size != (numEntries + 1) * 8) {
return ERROR_MALFORMED;
}
mNumCompositionTimeDeltaEntries = numEntries;
mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
if (mDataSource->readAt(
data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
< (ssize_t)numEntries * 8) {
delete[] mCompositionTimeDeltaEntries;
mCompositionTimeDeltaEntries = NULL;
return ERROR_IO;
}
for (size_t i = 0; i < 2 * numEntries; ++i) {
mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
}
return OK;
}
status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
if (mSyncSampleOffset >= 0 || data_size < 8) {
return ERROR_MALFORMED;
@@ -333,6 +383,8 @@ uint32_t abs_difference(uint32_t time1, uint32_t time2) {
status_t SampleTable::findSampleAtTime(
uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
// XXX this currently uses decoding time, instead of composition time.
*sample_index = 0;
Mutex::Autolock autoLock(mLock);
@@ -607,5 +659,26 @@ status_t SampleTable::getMetaDataForSample(
return OK;
}
uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const {
if (mCompositionTimeDeltaEntries == NULL) {
return 0;
}
uint32_t curSample = 0;
for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) {
uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i];
if (sampleIndex < curSample + sampleCount) {
uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1];
return sampleDelta;
}
curSample += sampleCount;
}
return 0;
}
} // namespace android

View File

@@ -46,6 +46,9 @@ public:
status_t setTimeToSampleParams(off64_t data_offset, size_t data_size);
status_t setCompositionTimeToSampleParams(
off64_t data_offset, size_t data_size);
status_t setSyncSampleParams(off64_t data_offset, size_t data_size);
////////////////////////////////////////////////////////////////////////////
@@ -104,6 +107,9 @@ private:
uint32_t mTimeToSampleCount;
uint32_t *mTimeToSample;
uint32_t *mCompositionTimeDeltaEntries;
size_t mNumCompositionTimeDeltaEntries;
off64_t mSyncSampleOffset;
uint32_t mNumSyncSamples;
uint32_t *mSyncSamples;
@@ -122,6 +128,8 @@ private:
status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;
SampleTable(const SampleTable &);
SampleTable &operator=(const SampleTable &);
};