am 4000e06e: Merge "Metadata construction optimization" into kraken

This commit is contained in:
James Dong
2010-05-10 11:34:49 -07:00
committed by Android Git Automerger

View File

@@ -60,6 +60,8 @@ private:
int64_t timestamp; int64_t timestamp;
}; };
List<SampleInfo> mSampleInfos; List<SampleInfo> mSampleInfos;
bool mSamplesHaveSameSize;
List<MediaBuffer *> mChunkSamples; List<MediaBuffer *> mChunkSamples;
List<off_t> mChunkOffsets; List<off_t> mChunkOffsets;
@@ -78,6 +80,16 @@ private:
List<int32_t> mStssTableEntries; List<int32_t> mStssTableEntries;
struct SttsTableEntry {
SttsTableEntry(uint32_t count, uint32_t duration)
: sampleCount(count), sampleDuration(duration) {}
uint32_t sampleCount;
uint32_t sampleDuration;
};
List<SttsTableEntry> mSttsTableEntries;
void *mCodecSpecificData; void *mCodecSpecificData;
size_t mCodecSpecificDataSize; size_t mCodecSpecificDataSize;
bool mGotAllCodecSpecificData; bool mGotAllCodecSpecificData;
@@ -389,6 +401,7 @@ MPEG4Writer::Track::Track(
mSource(source), mSource(source),
mDone(false), mDone(false),
mMaxTimeStampUs(0), mMaxTimeStampUs(0),
mSamplesHaveSameSize(true),
mCodecSpecificData(NULL), mCodecSpecificData(NULL),
mCodecSpecificDataSize(0), mCodecSpecificDataSize(0),
mGotAllCodecSpecificData(false), mGotAllCodecSpecificData(false),
@@ -562,6 +575,10 @@ void MPEG4Writer::Track::threadEntry() {
int64_t chunkTimestampUs = 0; int64_t chunkTimestampUs = 0;
int32_t nChunks = 0; int32_t nChunks = 0;
int32_t nZeroLengthFrames = 0; int32_t nZeroLengthFrames = 0;
int64_t lastTimestamp = 0; // Timestamp of the previous sample
int64_t lastDuration = 0; // Time spacing between the previous two samples
int32_t sampleCount = 1; // Sample count in the current stts table entry
uint32_t previousSampleSize = 0; // Size of the previous sample
MediaBuffer *buffer; MediaBuffer *buffer;
while (!mDone && mSource->read(&buffer) == OK) { while (!mDone && mSource->read(&buffer) == OK) {
@@ -584,11 +601,7 @@ void MPEG4Writer::Track::threadEntry() {
(const uint8_t *)buffer->data() (const uint8_t *)buffer->data()
+ buffer->range_offset(), + buffer->range_offset(),
buffer->range_length()); buffer->range_length());
CHECK_EQ(OK, err);
if (err != OK) {
LOGE("failed to parse avc codec specific data.");
break;
}
} else if (is_mpeg4) { } else if (is_mpeg4) {
mCodecSpecificDataSize = buffer->range_length(); mCodecSpecificDataSize = buffer->range_length();
mCodecSpecificData = malloc(mCodecSpecificDataSize); mCodecSpecificData = malloc(mCodecSpecificDataSize);
@@ -676,14 +689,9 @@ void MPEG4Writer::Track::threadEntry() {
status_t err = makeAVCCodecSpecificData( status_t err = makeAVCCodecSpecificData(
(const uint8_t *)tmp, size); (const uint8_t *)tmp, size);
free(tmp); free(tmp);
tmp = NULL; tmp = NULL;
CHECK_EQ(OK, err);
if (err != OK) {
LOGE("failed to parse avc codec specific data.");
break;
}
mGotAllCodecSpecificData = true; mGotAllCodecSpecificData = true;
} }
@@ -712,6 +720,23 @@ void MPEG4Writer::Track::threadEntry() {
// Our timestamp is in ms. // Our timestamp is in ms.
info.timestamp = (timestampUs + 500) / 1000; info.timestamp = (timestampUs + 500) / 1000;
mSampleInfos.push_back(info); mSampleInfos.push_back(info);
if (mSampleInfos.size() > 2) {
if (lastDuration != info.timestamp - lastTimestamp) {
SttsTableEntry sttsEntry(sampleCount, lastDuration);
mSttsTableEntries.push_back(sttsEntry);
sampleCount = 1;
} else {
++sampleCount;
}
}
if (mSamplesHaveSameSize) {
if (mSampleInfos.size() >= 2 && previousSampleSize != info.size) {
mSamplesHaveSameSize = false;
}
previousSampleSize = info.size;
}
lastDuration = info.timestamp - lastTimestamp;
lastTimestamp = info.timestamp;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Make a deep copy of the MediaBuffer less Metadata // Make a deep copy of the MediaBuffer less Metadata
@@ -749,11 +774,13 @@ void MPEG4Writer::Track::threadEntry() {
isSync != 0) { isSync != 0) {
mStssTableEntries.push_back(mSampleInfos.size()); mStssTableEntries.push_back(mSampleInfos.size());
} }
// Our timestamp is in ms.
buffer->release(); buffer->release();
buffer = NULL; buffer = NULL;
} }
CHECK(!mSampleInfos.empty());
// Last chunk // Last chunk
if (!mChunkSamples.empty()) { if (!mChunkSamples.empty()) {
++nChunks; ++nChunks;
@@ -762,6 +789,16 @@ void MPEG4Writer::Track::threadEntry() {
writeOneChunk(is_avc); writeOneChunk(is_avc);
} }
// We don't really know how long the last frame lasts, since
// there is no frame time after it, just repeat the previous
// frame's duration.
if (mSampleInfos.size() == 1) {
lastDuration = 0; // A single sample's duration
} else {
++sampleCount; // Count for the last sample
}
SttsTableEntry sttsEntry(sampleCount, lastDuration);
mSttsTableEntries.push_back(sttsEntry);
mReachedEOS = true; mReachedEOS = true;
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames", LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames",
count, nZeroLengthFrames, mSampleInfos.size()); count, nZeroLengthFrames, mSampleInfos.size());
@@ -1054,29 +1091,12 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
mOwner->beginBox("stts"); mOwner->beginBox("stts");
mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt32(mSampleInfos.size()); mOwner->writeInt32(mSttsTableEntries.size());
for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
List<SampleInfo>::iterator it = mSampleInfos.begin(); it != mSttsTableEntries.end(); ++it) {
int64_t last = (*it).timestamp; mOwner->writeInt32(it->sampleCount);
int64_t lastDuration = 1; mOwner->writeInt32(it->sampleDuration);
++it;
while (it != mSampleInfos.end()) {
mOwner->writeInt32(1);
lastDuration = (*it).timestamp - last;
mOwner->writeInt32(lastDuration);
last = (*it).timestamp;
++it;
} }
// We don't really know how long the last frame lasts, since
// there is no frame time after it, just repeat the previous
// frame's duration.
mOwner->writeInt32(1);
mOwner->writeInt32(lastDuration);
mOwner->endBox(); // stts mOwner->endBox(); // stts
if (!is_audio) { if (!is_audio) {
@@ -1092,11 +1112,18 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
mOwner->beginBox("stsz"); mOwner->beginBox("stsz");
mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt32(0); // default sample size if (mSamplesHaveSameSize) {
List<SampleInfo>::iterator it = mSampleInfos.begin();
mOwner->writeInt32(it->size); // default sample size
} else {
mOwner->writeInt32(0);
}
mOwner->writeInt32(mSampleInfos.size()); mOwner->writeInt32(mSampleInfos.size());
for (List<SampleInfo>::iterator it = mSampleInfos.begin(); if (!mSamplesHaveSameSize) {
it != mSampleInfos.end(); ++it) { for (List<SampleInfo>::iterator it = mSampleInfos.begin();
mOwner->writeInt32((*it).size); it != mSampleInfos.end(); ++it) {
mOwner->writeInt32((*it).size);
}
} }
mOwner->endBox(); // stsz mOwner->endBox(); // stsz