summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MPEG4Writer.cpp
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-07-28 10:24:39 -0700
committerJames Dong <jdong@google.com>2010-07-28 12:02:57 -0700
commit8644c14618d30d9e57a69df40ed939986ebf02c4 (patch)
tree24e5c93b81a6bb707e85494d4d2c61b362af85c1 /media/libstagefright/MPEG4Writer.cpp
parent995cef30f64d4b579a76e15c0b622cd79c461dd8 (diff)
downloadframeworks_av-8644c14618d30d9e57a69df40ed939986ebf02c4.zip
frameworks_av-8644c14618d30d9e57a69df40ed939986ebf02c4.tar.gz
frameworks_av-8644c14618d30d9e57a69df40ed939986ebf02c4.tar.bz2
Reduce memory usage by the MP4 file writer
- Don't store timestamp for each output sample - Don't store timestamp for statistical data collection if the collection of statistical data is not requested TODO: 1. Reduce CPU load by elimnating the list cost associated with List.size() call. Change-Id: I590bc17176596a65952c982574b82ee3b15b7d1c
Diffstat (limited to 'media/libstagefright/MPEG4Writer.cpp')
-rw-r--r--media/libstagefright/MPEG4Writer.cpp86
1 files changed, 44 insertions, 42 deletions
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 78970b3..16b1094 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -66,11 +66,7 @@ private:
pthread_t mThread;
- struct SampleInfo {
- size_t size;
- int64_t timestampUs;
- };
- List<SampleInfo> mSampleInfos;
+ List<size_t> mSampleSizes;
bool mSamplesHaveSameSize;
List<MediaBuffer *> mChunkSamples;
@@ -916,6 +912,15 @@ status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
return OK;
}
+static bool collectStatisticalData() {
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.stagefright.record-stats", value, NULL)
+ && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
+ return true;
+ }
+ return false;
+}
+
void MPEG4Writer::Track::threadEntry() {
sp<MetaData> meta = mSource->getFormat();
const char *mime;
@@ -935,6 +940,7 @@ void MPEG4Writer::Track::threadEntry() {
uint32_t previousSampleSize = 0; // Size of the previous sample
int64_t previousPausedDurationUs = 0;
sp<MetaData> meta_data;
+ bool collectStats = collectStatisticalData();
status_t err = OK;
MediaBuffer *buffer;
@@ -1081,8 +1087,8 @@ void MPEG4Writer::Track::threadEntry() {
if (is_avc) StripStartcode(copy);
- SampleInfo info;
- info.size = is_avc
+ size_t sampleSize;
+ sampleSize = is_avc
#if USE_NALLEN_FOUR
? copy->range_length() + 4
#else
@@ -1091,7 +1097,7 @@ void MPEG4Writer::Track::threadEntry() {
: copy->range_length();
// Max file size or duration handling
- mEstimatedTrackSizeBytes += info.size;
+ mEstimatedTrackSizeBytes += sampleSize;
if (mOwner->exceedsFileSizeLimit()) {
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
break;
@@ -1109,7 +1115,7 @@ void MPEG4Writer::Track::threadEntry() {
CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
////////////////////////////////////////////////////////////////////////////////
- if (mSampleInfos.empty()) {
+ if (mSampleSizes.empty()) {
mStartTimestampUs = timestampUs;
mOwner->setStartTimestampUs(mStartTimestampUs);
}
@@ -1126,10 +1132,9 @@ void MPEG4Writer::Track::threadEntry() {
mMaxTimeStampUs = timestampUs;
}
- info.timestampUs = timestampUs;
- mSampleInfos.push_back(info);
- if (mSampleInfos.size() > 2) {
- if (lastDurationUs != info.timestampUs - lastTimestampUs) {
+ mSampleSizes.push_back(sampleSize);
+ if (mSampleSizes.size() > 2) {
+ if (lastDurationUs != timestampUs - lastTimestampUs) {
SttsTableEntry sttsEntry(sampleCount, lastDurationUs);
mSttsTableEntries.push_back(sttsEntry);
sampleCount = 1;
@@ -1138,16 +1143,16 @@ void MPEG4Writer::Track::threadEntry() {
}
}
if (mSamplesHaveSameSize) {
- if (mSampleInfos.size() >= 2 && previousSampleSize != info.size) {
+ if (mSampleSizes.size() >= 2 && previousSampleSize != sampleSize) {
mSamplesHaveSameSize = false;
}
- previousSampleSize = info.size;
+ previousSampleSize = sampleSize;
}
- lastDurationUs = info.timestampUs - lastTimestampUs;
- lastTimestampUs = info.timestampUs;
+ lastDurationUs = timestampUs - lastTimestampUs;
+ lastTimestampUs = timestampUs;
if (isSync != 0) {
- mStssTableEntries.push_back(mSampleInfos.size());
+ mStssTableEntries.push_back(mSampleSizes.size());
}
if (mTrackingProgressStatus) {
@@ -1178,7 +1183,9 @@ void MPEG4Writer::Track::threadEntry() {
} else {
if (timestampUs - chunkTimestampUs > interleaveDurationUs) {
++nChunks;
- mChunkDurations.push_back(timestampUs - chunkTimestampUs);
+ if (collectStats) {
+ mChunkDurations.push_back(timestampUs - chunkTimestampUs);
+ }
if (nChunks == 1 || // First chunk
(--(mStscTableEntries.end()))->samplesPerChunk !=
mChunkSamples.size()) {
@@ -1194,14 +1201,14 @@ void MPEG4Writer::Track::threadEntry() {
}
- if (mSampleInfos.empty()) {
+ if (mSampleSizes.empty()) {
err = UNKNOWN_ERROR;
}
mOwner->trackProgressStatus(this, -1, err);
// Last chunk
if (mOwner->numTracks() == 1) {
- StscTableEntry stscEntry(1, mSampleInfos.size(), 1);
+ StscTableEntry stscEntry(1, mSampleSizes.size(), 1);
mStscTableEntries.push_back(stscEntry);
} else if (!mChunkSamples.empty()) {
++nChunks;
@@ -1213,7 +1220,7 @@ void MPEG4Writer::Track::threadEntry() {
// 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) {
+ if (mSampleSizes.size() == 1) {
lastDurationUs = 0; // A single sample's duration
} else {
++sampleCount; // Count for the last sample
@@ -1222,7 +1229,7 @@ void MPEG4Writer::Track::threadEntry() {
mSttsTableEntries.push_back(sttsEntry);
mReachedEOS = true;
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames - %s",
- count, nZeroLengthFrames, mSampleInfos.size(), is_audio? "audio": "video");
+ count, nZeroLengthFrames, mSampleSizes.size(), is_audio? "audio": "video");
logStatisticalData(is_audio);
}
@@ -1284,8 +1291,8 @@ void MPEG4Writer::trackProgressStatus(
void MPEG4Writer::Track::findMinAvgMaxSampleDurationMs(
int32_t *min, int32_t *avg, int32_t *max) {
- CHECK(!mSampleInfos.empty());
- int32_t avgSampleDurationMs = mMaxTimeStampUs / 1000 / mSampleInfos.size();
+ CHECK(!mSampleSizes.empty());
+ int32_t avgSampleDurationMs = mMaxTimeStampUs / 1000 / mSampleSizes.size();
int32_t minSampleDurationMs = 0x7FFFFFFF;
int32_t maxSampleDurationMs = 0;
for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
@@ -1327,22 +1334,17 @@ void MPEG4Writer::Track::findMinMaxChunkDurations(int64_t *min, int64_t *max) {
}
void MPEG4Writer::Track::logStatisticalData(bool isAudio) {
- if (mMaxTimeStampUs <= 0 || mSampleInfos.empty()) {
+ if (mMaxTimeStampUs <= 0 || mSampleSizes.empty()) {
LOGI("nothing is recorded");
return;
}
- bool collectStats = false;
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.stagefright.record-stats", value, NULL)
- && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
- collectStats = true;
- }
+ bool collectStats = collectStatisticalData();
if (collectStats) {
LOGI("%s track - duration %lld us, total %d frames",
isAudio? "audio": "video", mMaxTimeStampUs,
- mSampleInfos.size());
+ mSampleSizes.size());
int32_t min, avg, max;
findMinAvgMaxSampleDurationMs(&min, &avg, &max);
LOGI("min/avg/max sample duration (ms): %d/%d/%d", min, avg, max);
@@ -1355,9 +1357,9 @@ void MPEG4Writer::Track::logStatisticalData(bool isAudio) {
}
int64_t totalBytes = 0;
- for (List<SampleInfo>::iterator it = mSampleInfos.begin();
- it != mSampleInfos.end(); ++it) {
- totalBytes += it->size;
+ for (List<size_t>::iterator it = mSampleSizes.begin();
+ it != mSampleSizes.end(); ++it) {
+ totalBytes += (*it);
}
float bitRate = (totalBytes * 8000000.0) / mMaxTimeStampUs;
LOGI("avg bit rate (bps): %.2f", bitRate);
@@ -1731,16 +1733,16 @@ void MPEG4Writer::Track::writeTrackHeader(
mOwner->beginBox("stsz");
mOwner->writeInt32(0); // version=0, flags=0
if (mSamplesHaveSameSize) {
- List<SampleInfo>::iterator it = mSampleInfos.begin();
- mOwner->writeInt32(it->size); // default sample size
+ List<size_t>::iterator it = mSampleSizes.begin();
+ mOwner->writeInt32(*it); // default sample size
} else {
mOwner->writeInt32(0);
}
- mOwner->writeInt32(mSampleInfos.size());
+ mOwner->writeInt32(mSampleSizes.size());
if (!mSamplesHaveSameSize) {
- for (List<SampleInfo>::iterator it = mSampleInfos.begin();
- it != mSampleInfos.end(); ++it) {
- mOwner->writeInt32((*it).size);
+ for (List<size_t>::iterator it = mSampleSizes.begin();
+ it != mSampleSizes.end(); ++it) {
+ mOwner->writeInt32(*it);
}
}
mOwner->endBox(); // stsz