summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2012-02-09 11:53:57 -0800
committerJames Dong <jdong@google.com>2012-02-09 15:02:08 -0800
commit43089daaf82bd2b8e5f9a29b80af5abaae4657b3 (patch)
treef02db6abff1cd9d35151468dee35fc0b741e80d3
parent5ec58d925520e6913fba3fc54413881af751c610 (diff)
downloadframeworks_av-43089daaf82bd2b8e5f9a29b80af5abaae4657b3.zip
frameworks_av-43089daaf82bd2b8e5f9a29b80af5abaae4657b3.tar.gz
frameworks_av-43089daaf82bd2b8e5f9a29b80af5abaae4657b3.tar.bz2
Finish up B frame support in MPEG4Writer
o optimize to reduce the size of the size of the ctts box o change the type for the time offset field in ctts table entry from int32_t to uint32_t according to the mp4 file spec o also moved away from MediaDebug and used ADebug instead. o related-to-bug: 4232183 Change-Id: I19364303728da64359c63169eec7487508c1d0f8
-rwxr-xr-xmedia/libstagefright/MPEG4Writer.cpp86
1 files changed, 50 insertions, 36 deletions
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index c7a8b32..7ebbe1d 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -23,10 +23,10 @@
#include <pthread.h>
#include <sys/prctl.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
@@ -141,7 +141,7 @@ private:
: sampleCount(count), sampleDuration(timescaledDur) {}
uint32_t sampleCount;
- int32_t sampleDuration; // time scale based
+ uint32_t sampleDuration; // time scale based
};
size_t mNumCttsTableEntries;
List<CttsTableEntry> mCttsTableEntries;
@@ -478,7 +478,7 @@ status_t MPEG4Writer::start(MetaData *param) {
!param->findInt32(kKeyTimeScale, &mTimeScale)) {
mTimeScale = 1000;
}
- CHECK(mTimeScale > 0);
+ CHECK_GT(mTimeScale, 0);
ALOGV("movie time scale: %d", mTimeScale);
mStreamableFile = true;
@@ -497,7 +497,7 @@ status_t MPEG4Writer::start(MetaData *param) {
}
mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
}
- CHECK(mEstimatedMoovBoxSize >= 8);
+ CHECK_GE(mEstimatedMoovBoxSize, 8);
lseek64(mFd, mFreeBoxOffset, SEEK_SET);
writeInt32(mEstimatedMoovBoxSize);
write("free", 4);
@@ -691,7 +691,7 @@ status_t MPEG4Writer::reset() {
mWriteMoovBoxToMemory = false;
if (mStreamableFile) {
- CHECK(mMoovBoxBufferOffset + 8 <= mEstimatedMoovBoxSize);
+ CHECK_LE(mMoovBoxBufferOffset + 8, mEstimatedMoovBoxSize);
// Moov box
lseek64(mFd, mFreeBoxOffset, SEEK_SET);
@@ -863,7 +863,7 @@ off64_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
mOffset += length + 4;
} else {
- CHECK(length < 65536);
+ CHECK_LT(length, 65536);
uint8_t x = length >> 8;
::write(mFd, &x, 1);
@@ -1092,7 +1092,7 @@ bool MPEG4Writer::reachedEOS() {
void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
ALOGI("setStartTimestampUs: %lld", timeUs);
- CHECK(timeUs >= 0);
+ CHECK_GE(timeUs, 0ll);
Mutex::Autolock autoLock(mLock);
if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
mStartTimestampUs = timeUs;
@@ -1222,7 +1222,7 @@ void MPEG4Writer::Track::setTimeScale() {
mTimeScale = timeScale;
}
- CHECK(mTimeScale > 0);
+ CHECK_GT(mTimeScale, 0);
}
void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
@@ -1303,7 +1303,7 @@ void MPEG4Writer::bufferChunk(const Chunk& chunk) {
}
}
- CHECK("Received a chunk for a unknown track" == 0);
+ CHECK(!"Received a chunk for a unknown track");
}
void MPEG4Writer::writeChunkToFile(Chunk* chunk) {
@@ -1846,7 +1846,7 @@ status_t MPEG4Writer::Track::threadEntry() {
int64_t cttsOffsetTimeUs = 0;
int64_t currCttsOffsetTimeTicks = 0; // Timescale based ticks
int64_t lastCttsOffsetTimeTicks = -1; // Timescale based ticks
- int32_t cttsSampleCount = 1; // Sample count in the current ctts table entry
+ int32_t cttsSampleCount = 0; // Sample count in the current ctts table entry
if (mIsAudio) {
prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
@@ -1889,7 +1889,7 @@ status_t MPEG4Writer::Track::threadEntry() {
(const uint8_t *)buffer->data()
+ buffer->range_offset(),
buffer->range_length());
- CHECK_EQ(OK, err);
+ CHECK_EQ((status_t)OK, err);
} else if (mIsMPEG4) {
mCodecSpecificDataSize = buffer->range_length();
mCodecSpecificData = malloc(mCodecSpecificDataSize);
@@ -1955,15 +1955,15 @@ status_t MPEG4Writer::Track::threadEntry() {
if (mResumed) {
int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
- CHECK(durExcludingEarlierPausesUs >= 0);
+ CHECK_GE(durExcludingEarlierPausesUs, 0ll);
int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
- CHECK(pausedDurationUs >= lastDurationUs);
+ CHECK_GE(pausedDurationUs, lastDurationUs);
previousPausedDurationUs += pausedDurationUs - lastDurationUs;
mResumed = false;
}
timestampUs -= previousPausedDurationUs;
- CHECK(timestampUs >= 0);
+ CHECK_GE(timestampUs, 0ll);
if (!mIsAudio) {
/*
* Composition time: timestampUs
@@ -1975,7 +1975,7 @@ status_t MPEG4Writer::Track::threadEntry() {
decodingTimeUs -= previousPausedDurationUs;
cttsOffsetTimeUs =
timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
- CHECK(cttsOffsetTimeUs >= 0);
+ CHECK_GE(cttsOffsetTimeUs, 0ll);
timestampUs = decodingTimeUs;
ALOGV("decoding time: %lld and ctts offset time: %lld",
timestampUs, cttsOffsetTimeUs);
@@ -1983,16 +1983,23 @@ status_t MPEG4Writer::Track::threadEntry() {
// Update ctts box table if necessary
currCttsOffsetTimeTicks =
(cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL;
- CHECK(currCttsOffsetTimeTicks <= 0x7FFFFFFFLL);
-#if 0
- // FIXME:
- // Optimize to reduce the number of ctts table entries.
- // Also, make sure that the very first ctts table entry contains
- // only a single sample.
-#else
- addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
-#endif
- lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
+ CHECK_LE(currCttsOffsetTimeTicks, 0x0FFFFFFFFLL);
+ if (mNumSamples == 0) {
+ // Force the first ctts table entry to have one single entry
+ // so that we can do adjustment for the initial track start
+ // time offset easily in writeCttsBox().
+ lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
+ addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
+ cttsSampleCount = 0; // No sample in ctts box is pending
+ } else {
+ if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
+ addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
+ lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
+ cttsSampleCount = 1; // One sample in ctts box is pending
+ } else {
+ ++cttsSampleCount;
+ }
+ }
// Update ctts time offset range
if (mNumSamples == 0) {
@@ -2014,7 +2021,7 @@ status_t MPEG4Writer::Track::threadEntry() {
}
}
- CHECK(timestampUs >= 0);
+ CHECK_GE(timestampUs, 0ll);
ALOGV("%s media time stamp: %lld and previous paused duration %lld",
mIsAudio? "Audio": "Video", timestampUs, previousPausedDurationUs);
if (timestampUs > mTrackDurationUs) {
@@ -2029,7 +2036,7 @@ status_t MPEG4Writer::Track::threadEntry() {
currDurationTicks =
((timestampUs * mTimeScale + 500000LL) / 1000000LL -
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
- CHECK(currDurationTicks >= 0);
+ CHECK_GE(currDurationTicks, 0ll);
mSampleSizes.push_back(sampleSize);
++mNumSamples;
@@ -2127,7 +2134,6 @@ status_t MPEG4Writer::Track::threadEntry() {
lastDurationTicks = 0;
} else {
++sampleCount; // Count for the last sample
- ++cttsSampleCount;
}
if (mNumSamples <= 2) {
@@ -2139,6 +2145,14 @@ status_t MPEG4Writer::Track::threadEntry() {
addOneSttsTableEntry(sampleCount, lastDurationTicks);
}
+ // The last ctts box may not have been written yet, and this
+ // is to make sure that we write out the last ctts box.
+ if (currCttsOffsetTimeTicks == lastCttsOffsetTimeTicks) {
+ if (cttsSampleCount > 0) {
+ addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
+ }
+ }
+
mTrackDurationUs += lastDurationUs;
mReachedEOS = true;
@@ -2404,7 +2418,7 @@ void MPEG4Writer::Track::writeVideoFourCCBox() {
mOwner->writeInt16(0x18); // depth
mOwner->writeInt16(-1); // predefined
- CHECK(23 + mCodecSpecificDataSize < 128);
+ CHECK_LT(23 + mCodecSpecificDataSize, 128);
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
writeMp4vEsdsBox();
@@ -2463,10 +2477,10 @@ void MPEG4Writer::Track::writeAudioFourCCBox() {
void MPEG4Writer::Track::writeMp4aEsdsBox() {
mOwner->beginBox("esds");
CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize > 0);
+ CHECK_GT(mCodecSpecificDataSize, 0);
// Make sure all sizes encode to a single byte.
- CHECK(mCodecSpecificDataSize + 23 < 128);
+ CHECK_LT(mCodecSpecificDataSize + 23, 128);
mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt8(0x03); // ES_DescrTag
@@ -2500,7 +2514,7 @@ void MPEG4Writer::Track::writeMp4aEsdsBox() {
void MPEG4Writer::Track::writeMp4vEsdsBox() {
CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize > 0);
+ CHECK_GT(mCodecSpecificDataSize, 0);
mOwner->beginBox("esds");
mOwner->writeInt32(0); // version=0, flags=0
@@ -2660,7 +2674,7 @@ void MPEG4Writer::Track::writeDinfBox() {
void MPEG4Writer::Track::writeAvccBox() {
CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize >= 5);
+ CHECK_GE(mCodecSpecificDataSize, 5);
// Patch avcc's lengthSize field to match the number
// of bytes we use to indicate the size of a nal unit.
@@ -2692,7 +2706,7 @@ int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const {
int64_t trackStartTimeOffsetUs = 0;
int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
if (mStartTimestampUs != moovStartTimeUs) {
- CHECK(mStartTimestampUs > moovStartTimeUs);
+ CHECK_GT(mStartTimestampUs, moovStartTimeUs);
trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
}
return (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL;
@@ -2715,7 +2729,7 @@ void MPEG4Writer::Track::writeSttsBox() {
mOwner->writeInt32(it->sampleDuration);
totalCount += it->sampleCount;
}
- CHECK(totalCount == mNumSamples);
+ CHECK_EQ(totalCount, mNumSamples);
mOwner->endBox(); // stts
}
@@ -2758,7 +2772,7 @@ void MPEG4Writer::Track::writeCttsBox() {
mOwner->writeInt32(it->sampleDuration - mMinCttsOffsetTimeUs);
totalCount += it->sampleCount;
}
- CHECK(totalCount == mNumSamples);
+ CHECK_EQ(totalCount, mNumSamples);
mOwner->endBox(); // ctts
}