Loading include/media/stagefright/MPEG4Writer.h +5 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ private: class Track; FILE *mFile; bool mUse4ByteNalLength; bool mUse32BitOffset; bool mPaused; bool mStarted; Loading Loading @@ -135,6 +136,10 @@ private: void setDriftTimeUs(int64_t driftTimeUs); int64_t getDriftTimeUs(); // Return whether the nal length is 4 bytes or 2 bytes // Only makes sense for H.264/AVC bool useNalLengthFour(); void lock(); void unlock(); Loading include/media/stagefright/MetaData.h +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ enum { // Set this key to enable authoring files in 64-bit offset kKey64BitFileOffset = 'fobt', // int32_t (bool) kKey2ByteNalLength = '2NAL', // int32_t (bool) // Identify the file output format for authoring // Please see <media/mediarecorder.h> for the supported Loading media/libstagefright/MPEG4Writer.cpp +47 −204 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ #include <media/stagefright/MediaSource.h> #include <media/stagefright/Utils.h> #include <media/mediarecorder.h> #include <cutils/properties.h> #include "include/ESDS.h" Loading Loading @@ -113,7 +112,6 @@ private: size_t mNumStssTableEntries; List<int32_t> mStssTableEntries; List<int64_t> mChunkDurations; size_t mNumSttsTableEntries; struct SttsTableEntry { Loading Loading @@ -167,12 +165,6 @@ private: void trackProgressStatus(int64_t timeUs, status_t err = OK); void initTrackingProgressStatus(MetaData *params); // Utilities for collecting statistical data void logStatisticalData(bool isAudio); void findMinAvgMaxSampleDurationMs( int32_t *min, int32_t *avg, int32_t *max); void findMinMaxChunkDurations(int64_t *min, int64_t *max); void getCodecSpecificDataFromInputFormatIfPossible(); // Determine the track time scale Loading @@ -193,10 +185,9 @@ private: Track &operator=(const Track &); }; #define USE_NALLEN_FOUR 1 MPEG4Writer::MPEG4Writer(const char *filename) : mFile(fopen(filename, "wb")), mUse4ByteNalLength(true), mUse32BitOffset(true), mPaused(false), mStarted(false), Loading @@ -209,6 +200,7 @@ MPEG4Writer::MPEG4Writer(const char *filename) MPEG4Writer::MPEG4Writer(int fd) : mFile(fdopen(fd, "wb")), mUse4ByteNalLength(true), mUse32BitOffset(true), mPaused(false), mStarted(false), Loading Loading @@ -360,11 +352,11 @@ status_t MPEG4Writer::start(MetaData *param) { } } // System property can overwrite the file offset bits parameter char value[PROPERTY_VALUE_MAX]; if (property_get("media.stagefright.record-64bits", value, NULL) && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { mUse32BitOffset = false; int32_t use2ByteNalLength; if (param && param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) && use2ByteNalLength) { mUse4ByteNalLength = false; } mStartTimestampUs = -1; Loading Loading @@ -639,7 +631,7 @@ off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { size_t length = buffer->range_length(); #if USE_NALLEN_FOUR if (mUse4ByteNalLength) { uint8_t x = length >> 24; fwrite(&x, 1, 1, mFile); x = (length >> 16) & 0xff; Loading @@ -648,23 +640,21 @@ off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { fwrite(&x, 1, 1, mFile); x = length & 0xff; fwrite(&x, 1, 1, mFile); #else fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 1, length, mFile); mOffset += length + 4; } else { CHECK(length < 65536); uint8_t x = length >> 8; fwrite(&x, 1, 1, mFile); x = length & 0xff; fwrite(&x, 1, 1, mFile); #endif fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 1, length, mFile); #if USE_NALLEN_FOUR mOffset += length + 4; #else mOffset += length + 2; #endif } return old_offset; } Loading Loading @@ -1204,46 +1194,6 @@ void *MPEG4Writer::Track::ThreadWrapper(void *me) { return (void *) err; } #include <ctype.h> static void hexdump(const void *_data, size_t size) { const uint8_t *data = (const uint8_t *)_data; size_t offset = 0; while (offset < size) { printf("0x%04x ", offset); size_t n = size - offset; if (n > 16) { n = 16; } for (size_t i = 0; i < 16; ++i) { if (i == 8) { printf(" "); } if (offset + i < size) { printf("%02x ", data[offset + i]); } else { printf(" "); } } printf(" "); for (size_t i = 0; i < n; ++i) { if (isprint(data[offset + i])) { printf("%c", data[offset + i]); } else { printf("."); } } printf("\n"); offset += 16; } } static void getNalUnitType(uint8_t byte, uint8_t* type) { LOGV("getNalUnitType: %d", byte); Loading Loading @@ -1415,7 +1365,6 @@ status_t MPEG4Writer::Track::parseAVCCodecSpecificData( status_t MPEG4Writer::Track::makeAVCCodecSpecificData( const uint8_t *data, size_t size) { // hexdump(data, size); if (mCodecSpecificData != NULL) { LOGE("Already have codec specific data"); Loading Loading @@ -1446,11 +1395,11 @@ status_t MPEG4Writer::Track::makeAVCCodecSpecificData( header[3] = mLevelIdc; // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne #if USE_NALLEN_FOUR if (mOwner->useNalLengthFour()) { header[4] = 0xfc | 3; // length size == 4 bytes #else } else { header[4] = 0xfc | 1; // length size == 2 bytes #endif } // 3-bit '111' followed by 5-bit numSequenceParameterSets int nSequenceParamSets = mSeqParamSets.size(); Loading Loading @@ -1487,15 +1436,6 @@ 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; } status_t MPEG4Writer::Track::threadEntry() { int32_t count = 0; const int64_t interleaveDurationUs = mOwner->interleaveDuration(); Loading @@ -1512,7 +1452,6 @@ status_t MPEG4Writer::Track::threadEntry() { int64_t timestampUs; sp<MetaData> meta_data; bool collectStats = collectStatisticalData(); mNumSamples = 0; status_t err = OK; Loading Loading @@ -1575,14 +1514,14 @@ status_t MPEG4Writer::Track::threadEntry() { if (mIsAvc) StripStartcode(copy); size_t sampleSize; sampleSize = mIsAvc #if USE_NALLEN_FOUR ? copy->range_length() + 4 #else ? copy->range_length() + 2 #endif : copy->range_length(); size_t sampleSize = copy->range_length(); if (mIsAvc) { if (mOwner->useNalLengthFour()) { sampleSize += 4; } else { sampleSize += 2; } } // Max file size or duration handling mMdatSizeBytes += sampleSize; Loading Loading @@ -1722,9 +1661,6 @@ status_t MPEG4Writer::Track::threadEntry() { } else { if (timestampUs - chunkTimestampUs > interleaveDurationUs) { ++nChunks; if (collectStats) { mChunkDurations.push_back(timestampUs - chunkTimestampUs); } if (nChunks == 1 || // First chunk (--(mStscTableEntries.end()))->samplesPerChunk != mChunkSamples.size()) { Loading Loading @@ -1767,7 +1703,6 @@ status_t MPEG4Writer::Track::threadEntry() { LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s", count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video"); logStatisticalData(mIsAudio); if (err == ERROR_END_OF_STREAM) { return OK; } Loading @@ -1792,17 +1727,6 @@ void MPEG4Writer::trackProgressStatus( CHECK(nTracks < 64); // Arbitrary number int32_t trackNum = 0; #if 0 // In the worst case, we can put the trackNum // along with MEDIA_RECORDER_INFO_COMPLETION_STATUS // to report the progress. for (List<Track *>::iterator it = mTracks.begin(); it != mTracks.end(); ++it, ++trackNum) { if (track == (*it)) { break; } } #endif CHECK(trackNum < nTracks); trackNum <<= 16; Loading @@ -1829,91 +1753,6 @@ void MPEG4Writer::trackProgressStatus( } } void MPEG4Writer::Track::findMinAvgMaxSampleDurationMs( int32_t *min, int32_t *avg, int32_t *max) { CHECK(!mSampleSizes.empty()); int32_t avgSampleDurationMs = mTrackDurationUs / 1000 / mNumSamples; int32_t minSampleDurationMs = 0x7FFFFFFF; int32_t maxSampleDurationMs = 0; for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); it != mSttsTableEntries.end(); ++it) { int32_t sampleDurationMs = (static_cast<int32_t>(it->sampleDurationUs) + 500) / 1000; if (sampleDurationMs > maxSampleDurationMs) { maxSampleDurationMs = sampleDurationMs; } else if (sampleDurationMs < minSampleDurationMs) { minSampleDurationMs = sampleDurationMs; } LOGI("sample duration: %d ms", sampleDurationMs); } CHECK(minSampleDurationMs != 0); CHECK(avgSampleDurationMs != 0); CHECK(maxSampleDurationMs != 0); *min = minSampleDurationMs; *avg = avgSampleDurationMs; *max = maxSampleDurationMs; } // Don't count the last duration void MPEG4Writer::Track::findMinMaxChunkDurations(int64_t *min, int64_t *max) { int64_t duration = mOwner->interleaveDuration(); int64_t minChunkDuration = duration; int64_t maxChunkDuration = duration; if (mChunkDurations.size() > 1) { for (List<int64_t>::iterator it = mChunkDurations.begin(); it != --mChunkDurations.end(); ++it) { if (minChunkDuration > (*it)) { minChunkDuration = (*it); } else if (maxChunkDuration < (*it)) { maxChunkDuration = (*it); } } } *min = minChunkDuration; *max = maxChunkDuration; } void MPEG4Writer::Track::logStatisticalData(bool isAudio) { if (mTrackDurationUs <= 0 || mSampleSizes.empty()) { LOGI("nothing is recorded"); return; } bool collectStats = collectStatisticalData(); if (collectStats) { LOGI("%s track - duration %lld us, total %d frames", isAudio? "audio": "video", mTrackDurationUs, mNumSamples); int32_t min, avg, max; findMinAvgMaxSampleDurationMs(&min, &avg, &max); LOGI("min/avg/max sample duration (ms): %d/%d/%d", min, avg, max); if (!isAudio) { float avgFps = 1000.0 / avg; float minFps = 1000.0 / max; float maxFps = 1000.0 / min; LOGI("min/avg/max frame rate (fps): %.2f/%.2f/%.2f", minFps, avgFps, maxFps); } int64_t totalBytes = 0; for (List<size_t>::iterator it = mSampleSizes.begin(); it != mSampleSizes.end(); ++it) { totalBytes += (*it); } float bitRate = (totalBytes * 8000000.0) / mTrackDurationUs; LOGI("avg bit rate (bps): %.2f", bitRate); int64_t duration = mOwner->interleaveDuration(); if (duration != 0) { // If interleaving is enabled int64_t minChunk, maxChunk; findMinMaxChunkDurations(&minChunk, &maxChunk); LOGI("min/avg/max chunk duration (ms): %lld/%lld/%lld", minChunk, duration, maxChunk); } } } void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) { LOGV("setDriftTimeUs: %lld us", driftTimeUs); Mutex::Autolock autolock(mLock); Loading @@ -1926,6 +1765,10 @@ int64_t MPEG4Writer::getDriftTimeUs() { return mDriftTimeUs; } bool MPEG4Writer::useNalLengthFour() { return mUse4ByteNalLength; } void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) { LOGV("bufferChunk"); Loading Loading
include/media/stagefright/MPEG4Writer.h +5 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ private: class Track; FILE *mFile; bool mUse4ByteNalLength; bool mUse32BitOffset; bool mPaused; bool mStarted; Loading Loading @@ -135,6 +136,10 @@ private: void setDriftTimeUs(int64_t driftTimeUs); int64_t getDriftTimeUs(); // Return whether the nal length is 4 bytes or 2 bytes // Only makes sense for H.264/AVC bool useNalLengthFour(); void lock(); void unlock(); Loading
include/media/stagefright/MetaData.h +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ enum { // Set this key to enable authoring files in 64-bit offset kKey64BitFileOffset = 'fobt', // int32_t (bool) kKey2ByteNalLength = '2NAL', // int32_t (bool) // Identify the file output format for authoring // Please see <media/mediarecorder.h> for the supported Loading
media/libstagefright/MPEG4Writer.cpp +47 −204 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ #include <media/stagefright/MediaSource.h> #include <media/stagefright/Utils.h> #include <media/mediarecorder.h> #include <cutils/properties.h> #include "include/ESDS.h" Loading Loading @@ -113,7 +112,6 @@ private: size_t mNumStssTableEntries; List<int32_t> mStssTableEntries; List<int64_t> mChunkDurations; size_t mNumSttsTableEntries; struct SttsTableEntry { Loading Loading @@ -167,12 +165,6 @@ private: void trackProgressStatus(int64_t timeUs, status_t err = OK); void initTrackingProgressStatus(MetaData *params); // Utilities for collecting statistical data void logStatisticalData(bool isAudio); void findMinAvgMaxSampleDurationMs( int32_t *min, int32_t *avg, int32_t *max); void findMinMaxChunkDurations(int64_t *min, int64_t *max); void getCodecSpecificDataFromInputFormatIfPossible(); // Determine the track time scale Loading @@ -193,10 +185,9 @@ private: Track &operator=(const Track &); }; #define USE_NALLEN_FOUR 1 MPEG4Writer::MPEG4Writer(const char *filename) : mFile(fopen(filename, "wb")), mUse4ByteNalLength(true), mUse32BitOffset(true), mPaused(false), mStarted(false), Loading @@ -209,6 +200,7 @@ MPEG4Writer::MPEG4Writer(const char *filename) MPEG4Writer::MPEG4Writer(int fd) : mFile(fdopen(fd, "wb")), mUse4ByteNalLength(true), mUse32BitOffset(true), mPaused(false), mStarted(false), Loading Loading @@ -360,11 +352,11 @@ status_t MPEG4Writer::start(MetaData *param) { } } // System property can overwrite the file offset bits parameter char value[PROPERTY_VALUE_MAX]; if (property_get("media.stagefright.record-64bits", value, NULL) && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { mUse32BitOffset = false; int32_t use2ByteNalLength; if (param && param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) && use2ByteNalLength) { mUse4ByteNalLength = false; } mStartTimestampUs = -1; Loading Loading @@ -639,7 +631,7 @@ off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { size_t length = buffer->range_length(); #if USE_NALLEN_FOUR if (mUse4ByteNalLength) { uint8_t x = length >> 24; fwrite(&x, 1, 1, mFile); x = (length >> 16) & 0xff; Loading @@ -648,23 +640,21 @@ off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { fwrite(&x, 1, 1, mFile); x = length & 0xff; fwrite(&x, 1, 1, mFile); #else fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 1, length, mFile); mOffset += length + 4; } else { CHECK(length < 65536); uint8_t x = length >> 8; fwrite(&x, 1, 1, mFile); x = length & 0xff; fwrite(&x, 1, 1, mFile); #endif fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 1, length, mFile); #if USE_NALLEN_FOUR mOffset += length + 4; #else mOffset += length + 2; #endif } return old_offset; } Loading Loading @@ -1204,46 +1194,6 @@ void *MPEG4Writer::Track::ThreadWrapper(void *me) { return (void *) err; } #include <ctype.h> static void hexdump(const void *_data, size_t size) { const uint8_t *data = (const uint8_t *)_data; size_t offset = 0; while (offset < size) { printf("0x%04x ", offset); size_t n = size - offset; if (n > 16) { n = 16; } for (size_t i = 0; i < 16; ++i) { if (i == 8) { printf(" "); } if (offset + i < size) { printf("%02x ", data[offset + i]); } else { printf(" "); } } printf(" "); for (size_t i = 0; i < n; ++i) { if (isprint(data[offset + i])) { printf("%c", data[offset + i]); } else { printf("."); } } printf("\n"); offset += 16; } } static void getNalUnitType(uint8_t byte, uint8_t* type) { LOGV("getNalUnitType: %d", byte); Loading Loading @@ -1415,7 +1365,6 @@ status_t MPEG4Writer::Track::parseAVCCodecSpecificData( status_t MPEG4Writer::Track::makeAVCCodecSpecificData( const uint8_t *data, size_t size) { // hexdump(data, size); if (mCodecSpecificData != NULL) { LOGE("Already have codec specific data"); Loading Loading @@ -1446,11 +1395,11 @@ status_t MPEG4Writer::Track::makeAVCCodecSpecificData( header[3] = mLevelIdc; // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne #if USE_NALLEN_FOUR if (mOwner->useNalLengthFour()) { header[4] = 0xfc | 3; // length size == 4 bytes #else } else { header[4] = 0xfc | 1; // length size == 2 bytes #endif } // 3-bit '111' followed by 5-bit numSequenceParameterSets int nSequenceParamSets = mSeqParamSets.size(); Loading Loading @@ -1487,15 +1436,6 @@ 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; } status_t MPEG4Writer::Track::threadEntry() { int32_t count = 0; const int64_t interleaveDurationUs = mOwner->interleaveDuration(); Loading @@ -1512,7 +1452,6 @@ status_t MPEG4Writer::Track::threadEntry() { int64_t timestampUs; sp<MetaData> meta_data; bool collectStats = collectStatisticalData(); mNumSamples = 0; status_t err = OK; Loading Loading @@ -1575,14 +1514,14 @@ status_t MPEG4Writer::Track::threadEntry() { if (mIsAvc) StripStartcode(copy); size_t sampleSize; sampleSize = mIsAvc #if USE_NALLEN_FOUR ? copy->range_length() + 4 #else ? copy->range_length() + 2 #endif : copy->range_length(); size_t sampleSize = copy->range_length(); if (mIsAvc) { if (mOwner->useNalLengthFour()) { sampleSize += 4; } else { sampleSize += 2; } } // Max file size or duration handling mMdatSizeBytes += sampleSize; Loading Loading @@ -1722,9 +1661,6 @@ status_t MPEG4Writer::Track::threadEntry() { } else { if (timestampUs - chunkTimestampUs > interleaveDurationUs) { ++nChunks; if (collectStats) { mChunkDurations.push_back(timestampUs - chunkTimestampUs); } if (nChunks == 1 || // First chunk (--(mStscTableEntries.end()))->samplesPerChunk != mChunkSamples.size()) { Loading Loading @@ -1767,7 +1703,6 @@ status_t MPEG4Writer::Track::threadEntry() { LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s", count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video"); logStatisticalData(mIsAudio); if (err == ERROR_END_OF_STREAM) { return OK; } Loading @@ -1792,17 +1727,6 @@ void MPEG4Writer::trackProgressStatus( CHECK(nTracks < 64); // Arbitrary number int32_t trackNum = 0; #if 0 // In the worst case, we can put the trackNum // along with MEDIA_RECORDER_INFO_COMPLETION_STATUS // to report the progress. for (List<Track *>::iterator it = mTracks.begin(); it != mTracks.end(); ++it, ++trackNum) { if (track == (*it)) { break; } } #endif CHECK(trackNum < nTracks); trackNum <<= 16; Loading @@ -1829,91 +1753,6 @@ void MPEG4Writer::trackProgressStatus( } } void MPEG4Writer::Track::findMinAvgMaxSampleDurationMs( int32_t *min, int32_t *avg, int32_t *max) { CHECK(!mSampleSizes.empty()); int32_t avgSampleDurationMs = mTrackDurationUs / 1000 / mNumSamples; int32_t minSampleDurationMs = 0x7FFFFFFF; int32_t maxSampleDurationMs = 0; for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); it != mSttsTableEntries.end(); ++it) { int32_t sampleDurationMs = (static_cast<int32_t>(it->sampleDurationUs) + 500) / 1000; if (sampleDurationMs > maxSampleDurationMs) { maxSampleDurationMs = sampleDurationMs; } else if (sampleDurationMs < minSampleDurationMs) { minSampleDurationMs = sampleDurationMs; } LOGI("sample duration: %d ms", sampleDurationMs); } CHECK(minSampleDurationMs != 0); CHECK(avgSampleDurationMs != 0); CHECK(maxSampleDurationMs != 0); *min = minSampleDurationMs; *avg = avgSampleDurationMs; *max = maxSampleDurationMs; } // Don't count the last duration void MPEG4Writer::Track::findMinMaxChunkDurations(int64_t *min, int64_t *max) { int64_t duration = mOwner->interleaveDuration(); int64_t minChunkDuration = duration; int64_t maxChunkDuration = duration; if (mChunkDurations.size() > 1) { for (List<int64_t>::iterator it = mChunkDurations.begin(); it != --mChunkDurations.end(); ++it) { if (minChunkDuration > (*it)) { minChunkDuration = (*it); } else if (maxChunkDuration < (*it)) { maxChunkDuration = (*it); } } } *min = minChunkDuration; *max = maxChunkDuration; } void MPEG4Writer::Track::logStatisticalData(bool isAudio) { if (mTrackDurationUs <= 0 || mSampleSizes.empty()) { LOGI("nothing is recorded"); return; } bool collectStats = collectStatisticalData(); if (collectStats) { LOGI("%s track - duration %lld us, total %d frames", isAudio? "audio": "video", mTrackDurationUs, mNumSamples); int32_t min, avg, max; findMinAvgMaxSampleDurationMs(&min, &avg, &max); LOGI("min/avg/max sample duration (ms): %d/%d/%d", min, avg, max); if (!isAudio) { float avgFps = 1000.0 / avg; float minFps = 1000.0 / max; float maxFps = 1000.0 / min; LOGI("min/avg/max frame rate (fps): %.2f/%.2f/%.2f", minFps, avgFps, maxFps); } int64_t totalBytes = 0; for (List<size_t>::iterator it = mSampleSizes.begin(); it != mSampleSizes.end(); ++it) { totalBytes += (*it); } float bitRate = (totalBytes * 8000000.0) / mTrackDurationUs; LOGI("avg bit rate (bps): %.2f", bitRate); int64_t duration = mOwner->interleaveDuration(); if (duration != 0) { // If interleaving is enabled int64_t minChunk, maxChunk; findMinMaxChunkDurations(&minChunk, &maxChunk); LOGI("min/avg/max chunk duration (ms): %lld/%lld/%lld", minChunk, duration, maxChunk); } } } void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) { LOGV("setDriftTimeUs: %lld us", driftTimeUs); Mutex::Autolock autolock(mLock); Loading @@ -1926,6 +1765,10 @@ int64_t MPEG4Writer::getDriftTimeUs() { return mDriftTimeUs; } bool MPEG4Writer::useNalLengthFour() { return mUse4ByteNalLength; } void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) { LOGV("bufferChunk"); Loading