Loading include/media/stagefright/MetaData.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ enum { kKeyIsSyncFrame = 'sync', // int32_t (bool) kKeyIsCodecConfig = 'conf', // int32_t (bool) kKeyTime = 'time', // int64_t (usecs) kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs) kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) kKeyTargetTime = 'tarT', // int64_t (usecs) kKeyDriftTime = 'dftT', // int64_t (usecs) Loading include/media/stagefright/OMXCodec.h +6 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,10 @@ private: bool mOnlySubmitOneBufferAtOneTime; bool mEnableGrallocUsageProtected; // Used to record the decoding time for an output picture from // a video encoder. List<int64_t> mDecodingTimeList; OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, bool isEncoder, const char *mime, const char *componentName, const sp<MediaSource> &source, Loading Loading @@ -317,6 +321,8 @@ private: status_t applyRotation(); int64_t retrieveDecodingTimeUs(bool isCodecSpecific); OMXCodec(const OMXCodec &); OMXCodec &operator=(const OMXCodec &); }; Loading media/libstagefright/MPEG4Writer.cpp +118 −9 Original line number Diff line number Diff line Loading @@ -128,7 +128,6 @@ private: size_t mNumStssTableEntries; List<int32_t> mStssTableEntries; size_t mNumSttsTableEntries; struct SttsTableEntry { SttsTableEntry(uint32_t count, uint32_t duration) Loading @@ -137,8 +136,20 @@ private: uint32_t sampleCount; uint32_t sampleDuration; // time scale based }; size_t mNumSttsTableEntries; List<SttsTableEntry> mSttsTableEntries; struct CttsTableEntry { CttsTableEntry(uint32_t count, int32_t timescaledDur) : sampleCount(count), sampleDuration(timescaledDur) {} uint32_t sampleCount; int32_t sampleDuration; // time scale based }; bool mHasNegativeCttsDeltaDuration; size_t mNumCttsTableEntries; List<CttsTableEntry> mCttsTableEntries; // Sequence parameter set or picture parameter set struct AVCParamSet { AVCParamSet(uint16_t length, const uint8_t *data) Loading Loading @@ -219,6 +230,7 @@ private: // Duration is time scale based void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur); void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur); void sendTrackSummary(bool hasMultipleTracks); // Write the boxes Loading @@ -227,6 +239,7 @@ private: void writeStszBox(); void writeStssBox(); void writeSttsBox(); void writeCttsBox(); void writeD263Box(); void writePaspBox(); void writeAvccBox(); Loading Loading @@ -1147,6 +1160,7 @@ void MPEG4Writer::Track::updateTrackSizeEstimate() { mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 + // stsc box size mNumStssTableEntries * 4 + // stss box size mNumSttsTableEntries * 8 + // stts box size mNumCttsTableEntries * 8 + // ctts box size stcoBoxSizeBytes + // stco box size stszBoxSizeBytes; // stsz box size } Loading @@ -1173,6 +1187,20 @@ void MPEG4Writer::Track::addOneSttsTableEntry( ++mNumSttsTableEntries; } void MPEG4Writer::Track::addOneCttsTableEntry( size_t sampleCount, int32_t duration) { if (mIsAudio) { return; } if (duration < 0 && !mHasNegativeCttsDeltaDuration) { mHasNegativeCttsDeltaDuration = true; } CttsTableEntry cttsEntry(sampleCount, duration); mCttsTableEntries.push_back(cttsEntry); ++mNumCttsTableEntries; } void MPEG4Writer::Track::addChunkOffset(off64_t offset) { ++mNumStcoTableEntries; mChunkOffsets.push_back(offset); Loading Loading @@ -1483,6 +1511,7 @@ status_t MPEG4Writer::Track::start(MetaData *params) { mNumStssTableEntries = 0; mNumStscTableEntries = 0; mNumSttsTableEntries = 0; mNumCttsTableEntries = 0; mMdatSizeBytes = 0; mIsMediaTimeAdjustmentOn = false; mPrevMediaTimeAdjustTimestampUs = 0; Loading @@ -1491,6 +1520,7 @@ status_t MPEG4Writer::Track::start(MetaData *params) { mTotalDriftTimeToAdjustUs = 0; mPrevTotalAccumDriftTimeUs = 0; mMaxChunkDurationUs = 0; mHasNegativeCttsDeltaDuration = false; pthread_create(&mThread, &attr, ThreadWrapper, this); pthread_attr_destroy(&attr); Loading Loading @@ -1932,14 +1962,19 @@ status_t MPEG4Writer::Track::threadEntry() { int64_t chunkTimestampUs = 0; int32_t nChunks = 0; int32_t nZeroLengthFrames = 0; int64_t lastTimestampUs = 0; // Previous sample time stamp in ms int64_t lastDurationUs = 0; // Between the previous two samples in ms int64_t lastTimestampUs = 0; // Previous sample time stamp int64_t lastCttsTimeUs = 0; // Previous sample time stamp int64_t lastDurationUs = 0; // Between the previous two samples int64_t currDurationTicks = 0; // Timescale based ticks int64_t lastDurationTicks = 0; // Timescale based ticks int32_t sampleCount = 1; // Sample count in the current stts table entry int64_t currCttsDurTicks = 0; // Timescale based ticks int64_t lastCttsDurTicks = 0; // Timescale based ticks int32_t cttsSampleCount = 1; // Sample count in the current ctts table entry uint32_t previousSampleSize = 0; // Size of the previous sample int64_t previousPausedDurationUs = 0; int64_t timestampUs; int64_t timestampUs = 0; int64_t cttsDeltaTimeUs = 0; if (mIsAudio) { prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); Loading Loading @@ -2063,7 +2098,6 @@ status_t MPEG4Writer::Track::threadEntry() { * */ CHECK(meta_data->findInt64(kKeyTime, ×tampUs)); LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs); //////////////////////////////////////////////////////////////////////////////// if (mNumSamples == 0) { Loading @@ -2084,6 +2118,24 @@ status_t MPEG4Writer::Track::threadEntry() { timestampUs -= previousPausedDurationUs; CHECK(timestampUs >= 0); if (!mIsAudio) { /* * Composition time: timestampUs * Decoding time: decodingTimeUs * Composition time delta = composition time - decoding time * * We save picture decoding time stamp delta in stts table entries, * and composition time delta duration in ctts table entries. */ int64_t decodingTimeUs; CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs)); decodingTimeUs -= previousPausedDurationUs; int64_t timeUs = decodingTimeUs; cttsDeltaTimeUs = timestampUs - decodingTimeUs; timestampUs = decodingTimeUs; LOGV("decoding time: %lld and ctts delta time: %lld", timestampUs, cttsDeltaTimeUs); } // Media time adjustment for real-time applications if (mIsRealTimeRecording) { Loading Loading @@ -2139,6 +2191,18 @@ status_t MPEG4Writer::Track::threadEntry() { } else { ++sampleCount; } if (!mIsAudio) { currCttsDurTicks = ((cttsDeltaTimeUs * mTimeScale + 500000LL) / 1000000LL - (lastCttsTimeUs * mTimeScale + 500000LL) / 1000000LL); if (currCttsDurTicks != lastCttsDurTicks) { addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks); cttsSampleCount = 1; } else { ++cttsSampleCount; } } } if (mSamplesHaveSameSize) { if (mNumSamples >= 2 && previousSampleSize != sampleSize) { Loading @@ -2152,6 +2216,11 @@ status_t MPEG4Writer::Track::threadEntry() { lastDurationTicks = currDurationTicks; lastTimestampUs = timestampUs; if (!mIsAudio) { lastCttsDurTicks = currCttsDurTicks; lastCttsTimeUs = cttsDeltaTimeUs; } if (isSync != 0) { addOneStssTableEntry(mNumSamples); } Loading Loading @@ -2221,8 +2290,10 @@ status_t MPEG4Writer::Track::threadEntry() { if (mNumSamples == 1) { lastDurationUs = 0; // A single sample's duration lastDurationTicks = 0; lastCttsDurTicks = 0; } else { ++sampleCount; // Count for the last sample ++cttsSampleCount; } if (mNumSamples <= 2) { Loading @@ -2234,6 +2305,7 @@ status_t MPEG4Writer::Track::threadEntry() { addOneSttsTableEntry(sampleCount, lastDurationTicks); } addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks); mTrackDurationUs += lastDurationUs; mReachedEOS = true; Loading Loading @@ -2432,6 +2504,7 @@ void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) { } mOwner->endBox(); // stsd writeSttsBox(); writeCttsBox(); if (!mIsAudio) { writeStssBox(); } Loading Loading @@ -2782,13 +2855,49 @@ void MPEG4Writer::Track::writeSttsBox() { int32_t dur = (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL; mOwner->writeInt32(dur + it->sampleDuration); int64_t totalCount = 1; while (++it != mSttsTableEntries.end()) { mOwner->writeInt32(it->sampleCount); mOwner->writeInt32(it->sampleDuration); totalCount += it->sampleCount; } CHECK(totalCount == mNumSamples); mOwner->endBox(); // stts } void MPEG4Writer::Track::writeCttsBox() { if (mIsAudio) { // ctts is not for audio return; } // Do not write ctts box when there is no need to have it. if ((mNumCttsTableEntries == 1 && mCttsTableEntries.begin()->sampleDuration == 0) || mNumCttsTableEntries == 0) { return; } LOGV("ctts box has %d entries", mNumCttsTableEntries); mOwner->beginBox("ctts"); if (mHasNegativeCttsDeltaDuration) { mOwner->writeInt32(0x00010000); // version=1, flags=0 } else { mOwner->writeInt32(0); // version=0, flags=0 } mOwner->writeInt32(mNumCttsTableEntries); int64_t totalCount = 0; for (List<CttsTableEntry>::iterator it = mCttsTableEntries.begin(); it != mCttsTableEntries.end(); ++it) { mOwner->writeInt32(it->sampleCount); mOwner->writeInt32(it->sampleDuration); totalCount += it->sampleCount; } CHECK(totalCount == mNumSamples); mOwner->endBox(); // ctts } void MPEG4Writer::Track::writeStssBox() { mOwner->beginBox("stss"); mOwner->writeInt32(0); // version=0, flags=0 Loading media/libstagefright/OMXCodec.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -1981,6 +1981,20 @@ OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() { return bufInfo; } int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) { CHECK(mIsEncoder); CHECK(!mDecodingTimeList.empty()); List<int64_t>::iterator it = mDecodingTimeList.begin(); int64_t timeUs = *it; // If the output buffer is codec specific configuration, // do not remove the decoding time from the list. if (!isCodecSpecific) { mDecodingTimeList.erase(it); } return timeUs; } void OMXCodec::on_message(const omx_message &msg) { if (mState == ERROR) { LOGW("Dropping OMX message - we're in ERROR state."); Loading Loading @@ -2128,14 +2142,21 @@ void OMXCodec::on_message(const omx_message &msg) { if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); } bool isCodecSpecific = false; if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); isCodecSpecific = true; } if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) { buffer->meta_data()->setInt32(kKeyIsUnreadable, true); } if (mIsEncoder) { int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific); buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); } buffer->meta_data()->setPointer( kKeyPlatformPrivate, msg.u.extended_buffer_data.platform_private); Loading Loading @@ -2938,6 +2959,9 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { int64_t lastBufferTimeUs; CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); CHECK(lastBufferTimeUs >= 0); if (mIsEncoder) { mDecodingTimeList.push_back(lastBufferTimeUs); } if (offset == 0) { timestampUs = lastBufferTimeUs; Loading Loading
include/media/stagefright/MetaData.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ enum { kKeyIsSyncFrame = 'sync', // int32_t (bool) kKeyIsCodecConfig = 'conf', // int32_t (bool) kKeyTime = 'time', // int64_t (usecs) kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs) kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) kKeyTargetTime = 'tarT', // int64_t (usecs) kKeyDriftTime = 'dftT', // int64_t (usecs) Loading
include/media/stagefright/OMXCodec.h +6 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,10 @@ private: bool mOnlySubmitOneBufferAtOneTime; bool mEnableGrallocUsageProtected; // Used to record the decoding time for an output picture from // a video encoder. List<int64_t> mDecodingTimeList; OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, bool isEncoder, const char *mime, const char *componentName, const sp<MediaSource> &source, Loading Loading @@ -317,6 +321,8 @@ private: status_t applyRotation(); int64_t retrieveDecodingTimeUs(bool isCodecSpecific); OMXCodec(const OMXCodec &); OMXCodec &operator=(const OMXCodec &); }; Loading
media/libstagefright/MPEG4Writer.cpp +118 −9 Original line number Diff line number Diff line Loading @@ -128,7 +128,6 @@ private: size_t mNumStssTableEntries; List<int32_t> mStssTableEntries; size_t mNumSttsTableEntries; struct SttsTableEntry { SttsTableEntry(uint32_t count, uint32_t duration) Loading @@ -137,8 +136,20 @@ private: uint32_t sampleCount; uint32_t sampleDuration; // time scale based }; size_t mNumSttsTableEntries; List<SttsTableEntry> mSttsTableEntries; struct CttsTableEntry { CttsTableEntry(uint32_t count, int32_t timescaledDur) : sampleCount(count), sampleDuration(timescaledDur) {} uint32_t sampleCount; int32_t sampleDuration; // time scale based }; bool mHasNegativeCttsDeltaDuration; size_t mNumCttsTableEntries; List<CttsTableEntry> mCttsTableEntries; // Sequence parameter set or picture parameter set struct AVCParamSet { AVCParamSet(uint16_t length, const uint8_t *data) Loading Loading @@ -219,6 +230,7 @@ private: // Duration is time scale based void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur); void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur); void sendTrackSummary(bool hasMultipleTracks); // Write the boxes Loading @@ -227,6 +239,7 @@ private: void writeStszBox(); void writeStssBox(); void writeSttsBox(); void writeCttsBox(); void writeD263Box(); void writePaspBox(); void writeAvccBox(); Loading Loading @@ -1147,6 +1160,7 @@ void MPEG4Writer::Track::updateTrackSizeEstimate() { mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 + // stsc box size mNumStssTableEntries * 4 + // stss box size mNumSttsTableEntries * 8 + // stts box size mNumCttsTableEntries * 8 + // ctts box size stcoBoxSizeBytes + // stco box size stszBoxSizeBytes; // stsz box size } Loading @@ -1173,6 +1187,20 @@ void MPEG4Writer::Track::addOneSttsTableEntry( ++mNumSttsTableEntries; } void MPEG4Writer::Track::addOneCttsTableEntry( size_t sampleCount, int32_t duration) { if (mIsAudio) { return; } if (duration < 0 && !mHasNegativeCttsDeltaDuration) { mHasNegativeCttsDeltaDuration = true; } CttsTableEntry cttsEntry(sampleCount, duration); mCttsTableEntries.push_back(cttsEntry); ++mNumCttsTableEntries; } void MPEG4Writer::Track::addChunkOffset(off64_t offset) { ++mNumStcoTableEntries; mChunkOffsets.push_back(offset); Loading Loading @@ -1483,6 +1511,7 @@ status_t MPEG4Writer::Track::start(MetaData *params) { mNumStssTableEntries = 0; mNumStscTableEntries = 0; mNumSttsTableEntries = 0; mNumCttsTableEntries = 0; mMdatSizeBytes = 0; mIsMediaTimeAdjustmentOn = false; mPrevMediaTimeAdjustTimestampUs = 0; Loading @@ -1491,6 +1520,7 @@ status_t MPEG4Writer::Track::start(MetaData *params) { mTotalDriftTimeToAdjustUs = 0; mPrevTotalAccumDriftTimeUs = 0; mMaxChunkDurationUs = 0; mHasNegativeCttsDeltaDuration = false; pthread_create(&mThread, &attr, ThreadWrapper, this); pthread_attr_destroy(&attr); Loading Loading @@ -1932,14 +1962,19 @@ status_t MPEG4Writer::Track::threadEntry() { int64_t chunkTimestampUs = 0; int32_t nChunks = 0; int32_t nZeroLengthFrames = 0; int64_t lastTimestampUs = 0; // Previous sample time stamp in ms int64_t lastDurationUs = 0; // Between the previous two samples in ms int64_t lastTimestampUs = 0; // Previous sample time stamp int64_t lastCttsTimeUs = 0; // Previous sample time stamp int64_t lastDurationUs = 0; // Between the previous two samples int64_t currDurationTicks = 0; // Timescale based ticks int64_t lastDurationTicks = 0; // Timescale based ticks int32_t sampleCount = 1; // Sample count in the current stts table entry int64_t currCttsDurTicks = 0; // Timescale based ticks int64_t lastCttsDurTicks = 0; // Timescale based ticks int32_t cttsSampleCount = 1; // Sample count in the current ctts table entry uint32_t previousSampleSize = 0; // Size of the previous sample int64_t previousPausedDurationUs = 0; int64_t timestampUs; int64_t timestampUs = 0; int64_t cttsDeltaTimeUs = 0; if (mIsAudio) { prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); Loading Loading @@ -2063,7 +2098,6 @@ status_t MPEG4Writer::Track::threadEntry() { * */ CHECK(meta_data->findInt64(kKeyTime, ×tampUs)); LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs); //////////////////////////////////////////////////////////////////////////////// if (mNumSamples == 0) { Loading @@ -2084,6 +2118,24 @@ status_t MPEG4Writer::Track::threadEntry() { timestampUs -= previousPausedDurationUs; CHECK(timestampUs >= 0); if (!mIsAudio) { /* * Composition time: timestampUs * Decoding time: decodingTimeUs * Composition time delta = composition time - decoding time * * We save picture decoding time stamp delta in stts table entries, * and composition time delta duration in ctts table entries. */ int64_t decodingTimeUs; CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs)); decodingTimeUs -= previousPausedDurationUs; int64_t timeUs = decodingTimeUs; cttsDeltaTimeUs = timestampUs - decodingTimeUs; timestampUs = decodingTimeUs; LOGV("decoding time: %lld and ctts delta time: %lld", timestampUs, cttsDeltaTimeUs); } // Media time adjustment for real-time applications if (mIsRealTimeRecording) { Loading Loading @@ -2139,6 +2191,18 @@ status_t MPEG4Writer::Track::threadEntry() { } else { ++sampleCount; } if (!mIsAudio) { currCttsDurTicks = ((cttsDeltaTimeUs * mTimeScale + 500000LL) / 1000000LL - (lastCttsTimeUs * mTimeScale + 500000LL) / 1000000LL); if (currCttsDurTicks != lastCttsDurTicks) { addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks); cttsSampleCount = 1; } else { ++cttsSampleCount; } } } if (mSamplesHaveSameSize) { if (mNumSamples >= 2 && previousSampleSize != sampleSize) { Loading @@ -2152,6 +2216,11 @@ status_t MPEG4Writer::Track::threadEntry() { lastDurationTicks = currDurationTicks; lastTimestampUs = timestampUs; if (!mIsAudio) { lastCttsDurTicks = currCttsDurTicks; lastCttsTimeUs = cttsDeltaTimeUs; } if (isSync != 0) { addOneStssTableEntry(mNumSamples); } Loading Loading @@ -2221,8 +2290,10 @@ status_t MPEG4Writer::Track::threadEntry() { if (mNumSamples == 1) { lastDurationUs = 0; // A single sample's duration lastDurationTicks = 0; lastCttsDurTicks = 0; } else { ++sampleCount; // Count for the last sample ++cttsSampleCount; } if (mNumSamples <= 2) { Loading @@ -2234,6 +2305,7 @@ status_t MPEG4Writer::Track::threadEntry() { addOneSttsTableEntry(sampleCount, lastDurationTicks); } addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks); mTrackDurationUs += lastDurationUs; mReachedEOS = true; Loading Loading @@ -2432,6 +2504,7 @@ void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) { } mOwner->endBox(); // stsd writeSttsBox(); writeCttsBox(); if (!mIsAudio) { writeStssBox(); } Loading Loading @@ -2782,13 +2855,49 @@ void MPEG4Writer::Track::writeSttsBox() { int32_t dur = (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL; mOwner->writeInt32(dur + it->sampleDuration); int64_t totalCount = 1; while (++it != mSttsTableEntries.end()) { mOwner->writeInt32(it->sampleCount); mOwner->writeInt32(it->sampleDuration); totalCount += it->sampleCount; } CHECK(totalCount == mNumSamples); mOwner->endBox(); // stts } void MPEG4Writer::Track::writeCttsBox() { if (mIsAudio) { // ctts is not for audio return; } // Do not write ctts box when there is no need to have it. if ((mNumCttsTableEntries == 1 && mCttsTableEntries.begin()->sampleDuration == 0) || mNumCttsTableEntries == 0) { return; } LOGV("ctts box has %d entries", mNumCttsTableEntries); mOwner->beginBox("ctts"); if (mHasNegativeCttsDeltaDuration) { mOwner->writeInt32(0x00010000); // version=1, flags=0 } else { mOwner->writeInt32(0); // version=0, flags=0 } mOwner->writeInt32(mNumCttsTableEntries); int64_t totalCount = 0; for (List<CttsTableEntry>::iterator it = mCttsTableEntries.begin(); it != mCttsTableEntries.end(); ++it) { mOwner->writeInt32(it->sampleCount); mOwner->writeInt32(it->sampleDuration); totalCount += it->sampleCount; } CHECK(totalCount == mNumSamples); mOwner->endBox(); // ctts } void MPEG4Writer::Track::writeStssBox() { mOwner->beginBox("stss"); mOwner->writeInt32(0); // version=0, flags=0 Loading
media/libstagefright/OMXCodec.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -1981,6 +1981,20 @@ OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() { return bufInfo; } int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) { CHECK(mIsEncoder); CHECK(!mDecodingTimeList.empty()); List<int64_t>::iterator it = mDecodingTimeList.begin(); int64_t timeUs = *it; // If the output buffer is codec specific configuration, // do not remove the decoding time from the list. if (!isCodecSpecific) { mDecodingTimeList.erase(it); } return timeUs; } void OMXCodec::on_message(const omx_message &msg) { if (mState == ERROR) { LOGW("Dropping OMX message - we're in ERROR state."); Loading Loading @@ -2128,14 +2142,21 @@ void OMXCodec::on_message(const omx_message &msg) { if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) { buffer->meta_data()->setInt32(kKeyIsSyncFrame, true); } bool isCodecSpecific = false; if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) { buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); isCodecSpecific = true; } if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) { buffer->meta_data()->setInt32(kKeyIsUnreadable, true); } if (mIsEncoder) { int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific); buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); } buffer->meta_data()->setPointer( kKeyPlatformPrivate, msg.u.extended_buffer_data.platform_private); Loading Loading @@ -2938,6 +2959,9 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { int64_t lastBufferTimeUs; CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); CHECK(lastBufferTimeUs >= 0); if (mIsEncoder) { mDecodingTimeList.push_back(lastBufferTimeUs); } if (offset == 0) { timestampUs = lastBufferTimeUs; Loading