am 46e63b34: Merge "Better file size estimate" into gingerbread
Merge commit '46e63b346770efa14451b8e67b7f7636c4e5a76c' into gingerbread-plus-aosp * commit '46e63b346770efa14451b8e67b7f7636c4e5a76c': Better file size estimate
This commit is contained in:
@@ -144,6 +144,7 @@ private:
|
|||||||
|
|
||||||
inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream);
|
inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream);
|
||||||
bool exceedsFileSizeLimit();
|
bool exceedsFileSizeLimit();
|
||||||
|
bool use32BitFileOffset() const;
|
||||||
bool exceedsFileDurationLimit();
|
bool exceedsFileDurationLimit();
|
||||||
void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
|
void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
static const int64_t kMax32BitFileSize = 0x007fffffffLL;
|
||||||
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
|
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
|
||||||
static const uint8_t kNalUnitTypePicParamSet = 0x08;
|
static const uint8_t kNalUnitTypePicParamSet = 0x08;
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ public:
|
|||||||
bool isAvc() const { return mIsAvc; }
|
bool isAvc() const { return mIsAvc; }
|
||||||
bool isAudio() const { return mIsAudio; }
|
bool isAudio() const { return mIsAudio; }
|
||||||
bool isMPEG4() const { return mIsMPEG4; }
|
bool isMPEG4() const { return mIsMPEG4; }
|
||||||
void addChunkOffset(off_t offset) { mChunkOffsets.push_back(offset); }
|
void addChunkOffset(off_t offset);
|
||||||
status_t dump(int fd, const Vector<String16>& args) const;
|
status_t dump(int fd, const Vector<String16>& args) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -79,7 +80,7 @@ private:
|
|||||||
bool mIsRealTimeRecording;
|
bool mIsRealTimeRecording;
|
||||||
int64_t mMaxTimeStampUs;
|
int64_t mMaxTimeStampUs;
|
||||||
int64_t mEstimatedTrackSizeBytes;
|
int64_t mEstimatedTrackSizeBytes;
|
||||||
int64_t mMaxWriteTimeUs;
|
int64_t mMdatSizeBytes;
|
||||||
int32_t mTimeScale;
|
int32_t mTimeScale;
|
||||||
|
|
||||||
pthread_t mThread;
|
pthread_t mThread;
|
||||||
@@ -92,8 +93,11 @@ private:
|
|||||||
bool mSamplesHaveSameSize;
|
bool mSamplesHaveSameSize;
|
||||||
|
|
||||||
List<MediaBuffer *> mChunkSamples;
|
List<MediaBuffer *> mChunkSamples;
|
||||||
|
|
||||||
|
size_t mNumStcoTableEntries;
|
||||||
List<off_t> mChunkOffsets;
|
List<off_t> mChunkOffsets;
|
||||||
|
|
||||||
|
size_t mNumStscTableEntries;
|
||||||
struct StscTableEntry {
|
struct StscTableEntry {
|
||||||
|
|
||||||
StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id)
|
StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id)
|
||||||
@@ -107,9 +111,11 @@ private:
|
|||||||
};
|
};
|
||||||
List<StscTableEntry> mStscTableEntries;
|
List<StscTableEntry> mStscTableEntries;
|
||||||
|
|
||||||
|
size_t mNumStssTableEntries;
|
||||||
List<int32_t> mStssTableEntries;
|
List<int32_t> mStssTableEntries;
|
||||||
List<int64_t> mChunkDurations;
|
List<int64_t> mChunkDurations;
|
||||||
|
|
||||||
|
size_t mNumSttsTableEntries;
|
||||||
struct SttsTableEntry {
|
struct SttsTableEntry {
|
||||||
|
|
||||||
SttsTableEntry(uint32_t count, uint32_t durationUs)
|
SttsTableEntry(uint32_t count, uint32_t durationUs)
|
||||||
@@ -178,6 +184,11 @@ private:
|
|||||||
// Simple validation on the codec specific data
|
// Simple validation on the codec specific data
|
||||||
status_t checkCodecSpecificData() const;
|
status_t checkCodecSpecificData() const;
|
||||||
|
|
||||||
|
void updateTrackSizeEstimate();
|
||||||
|
void addOneStscTableEntry(size_t chunkId, size_t sampleId);
|
||||||
|
void addOneStssTableEntry(size_t sampleId);
|
||||||
|
void addOneSttsTableEntry(size_t sampleCount, int64_t durationUs);
|
||||||
|
|
||||||
Track(const Track &);
|
Track(const Track &);
|
||||||
Track &operator=(const Track &);
|
Track &operator=(const Track &);
|
||||||
};
|
};
|
||||||
@@ -211,9 +222,11 @@ MPEG4Writer::MPEG4Writer(int fd)
|
|||||||
MPEG4Writer::~MPEG4Writer() {
|
MPEG4Writer::~MPEG4Writer() {
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
for (List<Track *>::iterator it = mTracks.begin();
|
while (!mTracks.empty()) {
|
||||||
it != mTracks.end(); ++it) {
|
List<Track *>::iterator it = mTracks.begin();
|
||||||
delete *it;
|
delete *it;
|
||||||
|
(*it) = NULL;
|
||||||
|
mTracks.erase(it);
|
||||||
}
|
}
|
||||||
mTracks.clear();
|
mTracks.clear();
|
||||||
}
|
}
|
||||||
@@ -332,6 +345,21 @@ status_t MPEG4Writer::start(MetaData *param) {
|
|||||||
mUse32BitOffset = false;
|
mUse32BitOffset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mUse32BitOffset) {
|
||||||
|
// Implicit 32 bit file size limit
|
||||||
|
if (mMaxFileSizeLimitBytes == 0) {
|
||||||
|
mMaxFileSizeLimitBytes = kMax32BitFileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If file size is set to be larger than the 32 bit file
|
||||||
|
// size limit, treat it as an error.
|
||||||
|
if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
|
||||||
|
LOGE("32-bit file size limit too big: %lld bytes",
|
||||||
|
mMaxFileSizeLimitBytes);
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// System property can overwrite the file offset bits parameter
|
// System property can overwrite the file offset bits parameter
|
||||||
char value[PROPERTY_VALUE_MAX];
|
char value[PROPERTY_VALUE_MAX];
|
||||||
if (property_get("media.stagefright.record-64bits", value, NULL)
|
if (property_get("media.stagefright.record-64bits", value, NULL)
|
||||||
@@ -413,6 +441,10 @@ status_t MPEG4Writer::start(MetaData *param) {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MPEG4Writer::use32BitFileOffset() const {
|
||||||
|
return mUse32BitOffset;
|
||||||
|
}
|
||||||
|
|
||||||
status_t MPEG4Writer::pause() {
|
status_t MPEG4Writer::pause() {
|
||||||
if (mFile == NULL) {
|
if (mFile == NULL) {
|
||||||
return OK;
|
return OK;
|
||||||
@@ -739,7 +771,8 @@ bool MPEG4Writer::exceedsFileSizeLimit() {
|
|||||||
it != mTracks.end(); ++it) {
|
it != mTracks.end(); ++it) {
|
||||||
nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
|
nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
|
||||||
}
|
}
|
||||||
return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes);
|
|
||||||
|
return (nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MPEG4Writer::exceedsFileDurationLimit() {
|
bool MPEG4Writer::exceedsFileDurationLimit() {
|
||||||
@@ -819,6 +852,48 @@ MPEG4Writer::Track::Track(
|
|||||||
setTimeScale();
|
setTimeScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::Track::updateTrackSizeEstimate() {
|
||||||
|
|
||||||
|
int64_t stcoBoxSizeBytes = mOwner->use32BitFileOffset()
|
||||||
|
? mNumStcoTableEntries * 4
|
||||||
|
: mNumStcoTableEntries * 8;
|
||||||
|
|
||||||
|
int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mNumSamples * 4);
|
||||||
|
|
||||||
|
mEstimatedTrackSizeBytes = mMdatSizeBytes + // media data size
|
||||||
|
mNumStscTableEntries * 12 + // stsc box size
|
||||||
|
mNumStssTableEntries * 4 + // stss box size
|
||||||
|
mNumSttsTableEntries * 8 + // stts box size
|
||||||
|
stcoBoxSizeBytes + // stco box size
|
||||||
|
stszBoxSizeBytes; // stsz box size
|
||||||
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::Track::addOneStscTableEntry(
|
||||||
|
size_t chunkId, size_t sampleId) {
|
||||||
|
|
||||||
|
StscTableEntry stscEntry(chunkId, sampleId, 1);
|
||||||
|
mStscTableEntries.push_back(stscEntry);
|
||||||
|
++mNumStscTableEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) {
|
||||||
|
mStssTableEntries.push_back(sampleId);
|
||||||
|
++mNumStssTableEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::Track::addOneSttsTableEntry(
|
||||||
|
size_t sampleCount, int64_t durationUs) {
|
||||||
|
|
||||||
|
SttsTableEntry sttsEntry(sampleCount, durationUs);
|
||||||
|
mSttsTableEntries.push_back(sttsEntry);
|
||||||
|
++mNumSttsTableEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MPEG4Writer::Track::addChunkOffset(off_t offset) {
|
||||||
|
++mNumStcoTableEntries;
|
||||||
|
mChunkOffsets.push_back(offset);
|
||||||
|
}
|
||||||
|
|
||||||
void MPEG4Writer::Track::setTimeScale() {
|
void MPEG4Writer::Track::setTimeScale() {
|
||||||
LOGV("setTimeScale");
|
LOGV("setTimeScale");
|
||||||
// Default time scale
|
// Default time scale
|
||||||
@@ -1039,6 +1114,7 @@ status_t MPEG4Writer::startWriterThread() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t MPEG4Writer::Track::start(MetaData *params) {
|
status_t MPEG4Writer::Track::start(MetaData *params) {
|
||||||
if (!mDone && mPaused) {
|
if (!mDone && mPaused) {
|
||||||
mPaused = false;
|
mPaused = false;
|
||||||
@@ -1077,6 +1153,11 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
|
|||||||
mTrackDurationUs = 0;
|
mTrackDurationUs = 0;
|
||||||
mReachedEOS = false;
|
mReachedEOS = false;
|
||||||
mEstimatedTrackSizeBytes = 0;
|
mEstimatedTrackSizeBytes = 0;
|
||||||
|
mNumStcoTableEntries = 0;
|
||||||
|
mNumStssTableEntries = 0;
|
||||||
|
mNumStscTableEntries = 0;
|
||||||
|
mNumSttsTableEntries = 0;
|
||||||
|
mMdatSizeBytes = 0;
|
||||||
|
|
||||||
pthread_create(&mThread, &attr, ThreadWrapper, this);
|
pthread_create(&mThread, &attr, ThreadWrapper, this);
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
@@ -1434,7 +1515,6 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
bool collectStats = collectStatisticalData();
|
bool collectStats = collectStatisticalData();
|
||||||
|
|
||||||
mNumSamples = 0;
|
mNumSamples = 0;
|
||||||
mMaxWriteTimeUs = 0;
|
|
||||||
status_t err = OK;
|
status_t err = OK;
|
||||||
MediaBuffer *buffer;
|
MediaBuffer *buffer;
|
||||||
while (!mDone && (err = mSource->read(&buffer)) == OK) {
|
while (!mDone && (err = mSource->read(&buffer)) == OK) {
|
||||||
@@ -1505,7 +1585,9 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
: copy->range_length();
|
: copy->range_length();
|
||||||
|
|
||||||
// Max file size or duration handling
|
// Max file size or duration handling
|
||||||
mEstimatedTrackSizeBytes += sampleSize;
|
mMdatSizeBytes += sampleSize;
|
||||||
|
updateTrackSizeEstimate();
|
||||||
|
|
||||||
if (mOwner->exceedsFileSizeLimit()) {
|
if (mOwner->exceedsFileSizeLimit()) {
|
||||||
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
|
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
|
||||||
break;
|
break;
|
||||||
@@ -1587,8 +1669,7 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
|
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
|
||||||
|
|
||||||
if (currDurationTicks != lastDurationTicks) {
|
if (currDurationTicks != lastDurationTicks) {
|
||||||
SttsTableEntry sttsEntry(sampleCount, lastDurationUs);
|
addOneSttsTableEntry(sampleCount, lastDurationUs);
|
||||||
mSttsTableEntries.push_back(sttsEntry);
|
|
||||||
sampleCount = 1;
|
sampleCount = 1;
|
||||||
} else {
|
} else {
|
||||||
++sampleCount;
|
++sampleCount;
|
||||||
@@ -1611,7 +1692,7 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isSync != 0) {
|
if (isSync != 0) {
|
||||||
mStssTableEntries.push_back(mNumSamples);
|
addOneStssTableEntry(mNumSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrackingProgressStatus) {
|
if (mTrackingProgressStatus) {
|
||||||
@@ -1624,7 +1705,7 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
off_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
|
off_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
|
||||||
: mOwner->addSample_l(copy);
|
: mOwner->addSample_l(copy);
|
||||||
if (mChunkOffsets.empty()) {
|
if (mChunkOffsets.empty()) {
|
||||||
mChunkOffsets.push_back(offset);
|
addChunkOffset(offset);
|
||||||
}
|
}
|
||||||
copy->release();
|
copy->release();
|
||||||
copy = NULL;
|
copy = NULL;
|
||||||
@@ -1633,8 +1714,7 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
|
|
||||||
mChunkSamples.push_back(copy);
|
mChunkSamples.push_back(copy);
|
||||||
if (interleaveDurationUs == 0) {
|
if (interleaveDurationUs == 0) {
|
||||||
StscTableEntry stscEntry(++nChunks, 1, 1);
|
addOneStscTableEntry(++nChunks, 1);
|
||||||
mStscTableEntries.push_back(stscEntry);
|
|
||||||
bufferChunk(timestampUs);
|
bufferChunk(timestampUs);
|
||||||
} else {
|
} else {
|
||||||
if (chunkTimestampUs == 0) {
|
if (chunkTimestampUs == 0) {
|
||||||
@@ -1648,9 +1728,7 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
if (nChunks == 1 || // First chunk
|
if (nChunks == 1 || // First chunk
|
||||||
(--(mStscTableEntries.end()))->samplesPerChunk !=
|
(--(mStscTableEntries.end()))->samplesPerChunk !=
|
||||||
mChunkSamples.size()) {
|
mChunkSamples.size()) {
|
||||||
StscTableEntry stscEntry(nChunks,
|
addOneStscTableEntry(nChunks, mChunkSamples.size());
|
||||||
mChunkSamples.size(), 1);
|
|
||||||
mStscTableEntries.push_back(stscEntry);
|
|
||||||
}
|
}
|
||||||
bufferChunk(timestampUs);
|
bufferChunk(timestampUs);
|
||||||
chunkTimestampUs = timestampUs;
|
chunkTimestampUs = timestampUs;
|
||||||
@@ -1669,12 +1747,9 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
|
|
||||||
// Last chunk
|
// Last chunk
|
||||||
if (mOwner->numTracks() == 1) {
|
if (mOwner->numTracks() == 1) {
|
||||||
StscTableEntry stscEntry(1, mNumSamples, 1);
|
addOneStscTableEntry(1, mNumSamples);
|
||||||
mStscTableEntries.push_back(stscEntry);
|
|
||||||
} else if (!mChunkSamples.empty()) {
|
} else if (!mChunkSamples.empty()) {
|
||||||
++nChunks;
|
addOneStscTableEntry(++nChunks, mChunkSamples.size());
|
||||||
StscTableEntry stscEntry(nChunks, mChunkSamples.size(), 1);
|
|
||||||
mStscTableEntries.push_back(stscEntry);
|
|
||||||
bufferChunk(timestampUs);
|
bufferChunk(timestampUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1686,12 +1761,11 @@ status_t MPEG4Writer::Track::threadEntry() {
|
|||||||
} else {
|
} else {
|
||||||
++sampleCount; // Count for the last sample
|
++sampleCount; // Count for the last sample
|
||||||
}
|
}
|
||||||
SttsTableEntry sttsEntry(sampleCount, lastDurationUs);
|
addOneSttsTableEntry(sampleCount, lastDurationUs);
|
||||||
mSttsTableEntries.push_back(sttsEntry);
|
|
||||||
mTrackDurationUs += lastDurationUs;
|
mTrackDurationUs += lastDurationUs;
|
||||||
mReachedEOS = true;
|
mReachedEOS = true;
|
||||||
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. Max write time: %lld us - %s",
|
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
|
||||||
count, nZeroLengthFrames, mNumSamples, mMaxWriteTimeUs, mIsAudio? "audio": "video");
|
count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video");
|
||||||
|
|
||||||
logStatisticalData(mIsAudio);
|
logStatisticalData(mIsAudio);
|
||||||
if (err == ERROR_END_OF_STREAM) {
|
if (err == ERROR_END_OF_STREAM) {
|
||||||
@@ -1855,14 +1929,9 @@ int64_t MPEG4Writer::getDriftTimeUs() {
|
|||||||
void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
|
void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
|
||||||
LOGV("bufferChunk");
|
LOGV("bufferChunk");
|
||||||
|
|
||||||
int64_t startTimeUs = systemTime() / 1000;
|
|
||||||
Chunk chunk(this, timestampUs, mChunkSamples);
|
Chunk chunk(this, timestampUs, mChunkSamples);
|
||||||
mOwner->bufferChunk(chunk);
|
mOwner->bufferChunk(chunk);
|
||||||
mChunkSamples.clear();
|
mChunkSamples.clear();
|
||||||
int64_t endTimeUs = systemTime() / 1000;
|
|
||||||
if (mMaxWriteTimeUs < endTimeUs - startTimeUs) {
|
|
||||||
mMaxWriteTimeUs = endTimeUs - startTimeUs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t MPEG4Writer::Track::getDurationUs() const {
|
int64_t MPEG4Writer::Track::getDurationUs() const {
|
||||||
@@ -2215,7 +2284,7 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
|
|
||||||
mOwner->beginBox("stts");
|
mOwner->beginBox("stts");
|
||||||
mOwner->writeInt32(0); // version=0, flags=0
|
mOwner->writeInt32(0); // version=0, flags=0
|
||||||
mOwner->writeInt32(mSttsTableEntries.size());
|
mOwner->writeInt32(mNumSttsTableEntries);
|
||||||
int64_t prevTimestampUs = 0;
|
int64_t prevTimestampUs = 0;
|
||||||
for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
|
for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
|
||||||
it != mSttsTableEntries.end(); ++it) {
|
it != mSttsTableEntries.end(); ++it) {
|
||||||
@@ -2235,7 +2304,7 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
if (!mIsAudio) {
|
if (!mIsAudio) {
|
||||||
mOwner->beginBox("stss");
|
mOwner->beginBox("stss");
|
||||||
mOwner->writeInt32(0); // version=0, flags=0
|
mOwner->writeInt32(0); // version=0, flags=0
|
||||||
mOwner->writeInt32(mStssTableEntries.size()); // number of sync frames
|
mOwner->writeInt32(mNumStssTableEntries); // number of sync frames
|
||||||
for (List<int32_t>::iterator it = mStssTableEntries.begin();
|
for (List<int32_t>::iterator it = mStssTableEntries.begin();
|
||||||
it != mStssTableEntries.end(); ++it) {
|
it != mStssTableEntries.end(); ++it) {
|
||||||
mOwner->writeInt32(*it);
|
mOwner->writeInt32(*it);
|
||||||
@@ -2262,7 +2331,7 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
|
|
||||||
mOwner->beginBox("stsc");
|
mOwner->beginBox("stsc");
|
||||||
mOwner->writeInt32(0); // version=0, flags=0
|
mOwner->writeInt32(0); // version=0, flags=0
|
||||||
mOwner->writeInt32(mStscTableEntries.size());
|
mOwner->writeInt32(mNumStscTableEntries);
|
||||||
for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
|
for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
|
||||||
it != mStscTableEntries.end(); ++it) {
|
it != mStscTableEntries.end(); ++it) {
|
||||||
mOwner->writeInt32(it->firstChunk);
|
mOwner->writeInt32(it->firstChunk);
|
||||||
@@ -2272,7 +2341,7 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
mOwner->endBox(); // stsc
|
mOwner->endBox(); // stsc
|
||||||
mOwner->beginBox(use32BitOffset? "stco": "co64");
|
mOwner->beginBox(use32BitOffset? "stco": "co64");
|
||||||
mOwner->writeInt32(0); // version=0, flags=0
|
mOwner->writeInt32(0); // version=0, flags=0
|
||||||
mOwner->writeInt32(mChunkOffsets.size());
|
mOwner->writeInt32(mNumStcoTableEntries);
|
||||||
for (List<off_t>::iterator it = mChunkOffsets.begin();
|
for (List<off_t>::iterator it = mChunkOffsets.begin();
|
||||||
it != mChunkOffsets.end(); ++it) {
|
it != mChunkOffsets.end(); ++it) {
|
||||||
if (use32BitOffset) {
|
if (use32BitOffset) {
|
||||||
|
|||||||
Reference in New Issue
Block a user