diff options
author | James Dong <jdong@google.com> | 2010-07-28 12:19:33 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-07-28 12:19:33 -0700 |
commit | 84665f6dc2d0b5dfa6a46463677c51f2b670e511 (patch) | |
tree | b3f8dc6ed88e18ed2c463851451a36434ed03d05 /media | |
parent | cb51115cca81ba47d00aa344f6ed16d1056b056b (diff) | |
parent | 7e397842d53a4242a019daa4b234910273121c30 (diff) | |
download | frameworks_base-84665f6dc2d0b5dfa6a46463677c51f2b670e511.zip frameworks_base-84665f6dc2d0b5dfa6a46463677c51f2b670e511.tar.gz frameworks_base-84665f6dc2d0b5dfa6a46463677c51f2b670e511.tar.bz2 |
am 7e397842: 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
Merge commit '7e397842d53a4242a019daa4b234910273121c30' into gingerbread-plus-aosp
* commit '7e397842d53a4242a019daa4b234910273121c30':
Reduce memory usage by the MP4 file writer
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/MPEG4Writer.cpp | 86 |
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, ×tampUs)); //////////////////////////////////////////////////////////////////////////////// - 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 |