mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 12:20:56 +00:00
Bug 1289668 - Record inter-keyframe statistics - r=kamidphish
FrameStatisticsData can now store inter-keyframe information, which is provided by the MediaFormatReader (based on live decoding). MozReview-Commit-ID: HhBy6pgT6ZX --HG-- extra : rebase_source : 6a072623e8a5b0f23b81307e8ea4b19a3e21b252
This commit is contained in:
parent
374f22a566
commit
2a787d2521
@ -29,6 +29,15 @@ struct FrameStatisticsData
|
||||
// composition deadline.
|
||||
uint64_t mDroppedFrames = 0;
|
||||
|
||||
// Sum of all inter-keyframe segment durations, in microseconds.
|
||||
// Dividing by count will give the average inter-keyframe time.
|
||||
uint64_t mInterKeyframeSum_us = 0;
|
||||
// Number of inter-keyframe segments summed so far.
|
||||
size_t mInterKeyframeCount = 0;
|
||||
|
||||
// Maximum inter-keyframe segment duration, in microseconds.
|
||||
uint64_t mInterKeyFrameMax_us = 0;
|
||||
|
||||
FrameStatisticsData() = default;
|
||||
FrameStatisticsData(uint64_t aParsed, uint64_t aDecoded, uint64_t aDropped)
|
||||
: mParsedFrames(aParsed)
|
||||
@ -43,6 +52,12 @@ struct FrameStatisticsData
|
||||
mDecodedFrames += aStats.mDecodedFrames;
|
||||
mPresentedFrames += aStats.mPresentedFrames;
|
||||
mDroppedFrames += aStats.mDroppedFrames;
|
||||
mInterKeyframeSum_us += aStats.mInterKeyframeSum_us;
|
||||
mInterKeyframeCount += aStats.mInterKeyframeCount;
|
||||
// It doesn't make sense to add max numbers, instead keep the bigger one.
|
||||
if (mInterKeyFrameMax_us < aStats.mInterKeyFrameMax_us) {
|
||||
mInterKeyFrameMax_us = aStats.mInterKeyFrameMax_us;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -67,6 +67,7 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder,
|
||||
, mDemuxer(aDemuxer)
|
||||
, mDemuxerInitDone(false)
|
||||
, mLastReportedNumDecodedFrames(0)
|
||||
, mPreviousDecodedKeyframeTime_us(sNoPreviousDecodedKeyframe)
|
||||
, mLayersBackendType(aLayersBackend)
|
||||
, mInitDone(false)
|
||||
, mIsEncrypted(false)
|
||||
@ -1159,6 +1160,8 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
if (time >= target.Time()) {
|
||||
// We have reached our internal seek target.
|
||||
decoder.mTimeThreshold.reset();
|
||||
// We might have dropped some keyframes.
|
||||
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
|
||||
}
|
||||
if (time < target.Time() || (target.mDropTarget && target.Contains(time))) {
|
||||
LOGV("Internal Seeking: Dropping %s frame time:%f wanted:%f (kf:%d)",
|
||||
@ -1194,6 +1197,18 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
decoder.mNumSamplesOutputTotal - mLastReportedNumDecodedFrames;
|
||||
a.mStats.mDecodedFrames = static_cast<uint32_t>(delta);
|
||||
mLastReportedNumDecodedFrames = decoder.mNumSamplesOutputTotal;
|
||||
if (output->mKeyframe) {
|
||||
if (mPreviousDecodedKeyframeTime_us < output->mTime) {
|
||||
// There is a previous keyframe -> Record inter-keyframe stats.
|
||||
uint64_t segment_us = output->mTime - mPreviousDecodedKeyframeTime_us;
|
||||
a.mStats.mInterKeyframeSum_us += segment_us;
|
||||
a.mStats.mInterKeyframeCount += 1;
|
||||
if (a.mStats.mInterKeyFrameMax_us < segment_us) {
|
||||
a.mStats.mInterKeyFrameMax_us = segment_us;
|
||||
}
|
||||
}
|
||||
mPreviousDecodedKeyframeTime_us = output->mTime;
|
||||
}
|
||||
nsCString error;
|
||||
mVideo.mIsHardwareAccelerated =
|
||||
mVideo.mDecoder && mVideo.mDecoder->IsHardwareAccelerated(error);
|
||||
@ -1757,6 +1772,8 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
|
||||
LOGV("Video seeked to %lld", aTime.ToMicroseconds());
|
||||
mVideo.mSeekRequest.Complete();
|
||||
|
||||
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
|
||||
|
||||
SetVideoDecodeThreshold();
|
||||
|
||||
if (HasAudio() && !mOriginalSeekTarget.IsVideoOnly()) {
|
||||
@ -1773,6 +1790,13 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnVideoSeekFailed(DemuxerFailureReason aFailure)
|
||||
{
|
||||
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
|
||||
OnSeekFailed(TrackType::kVideoTrack, aFailure);
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::SetVideoDecodeThreshold()
|
||||
{
|
||||
@ -1833,6 +1857,12 @@ MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
|
||||
mSeekPromise.Resolve(aTime, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::OnAudioSeekFailed(DemuxerFailureReason aFailure)
|
||||
{
|
||||
OnSeekFailed(TrackType::kAudioTrack, aFailure);
|
||||
}
|
||||
|
||||
media::TimeIntervals
|
||||
MediaFormatReader::GetBuffered()
|
||||
{
|
||||
|
@ -515,6 +515,11 @@ private:
|
||||
// delta there.
|
||||
uint64_t mLastReportedNumDecodedFrames;
|
||||
|
||||
// Timestamp of the previous decoded keyframe, in microseconds.
|
||||
int64_t mPreviousDecodedKeyframeTime_us;
|
||||
// Default mLastDecodedKeyframeTime_us value, must be bigger than anything.
|
||||
static const int64_t sNoPreviousDecodedKeyframe = INT64_MAX;
|
||||
|
||||
layers::LayersBackend mLayersBackendType;
|
||||
|
||||
// Metadata objects
|
||||
@ -546,18 +551,12 @@ private:
|
||||
void OnSeekFailed(TrackType aTrack, DemuxerFailureReason aFailure);
|
||||
void DoVideoSeek();
|
||||
void OnVideoSeekCompleted(media::TimeUnit aTime);
|
||||
void OnVideoSeekFailed(DemuxerFailureReason aFailure)
|
||||
{
|
||||
OnSeekFailed(TrackType::kVideoTrack, aFailure);
|
||||
}
|
||||
void OnVideoSeekFailed(DemuxerFailureReason aFailure);
|
||||
bool mSeekScheduled;
|
||||
|
||||
void DoAudioSeek();
|
||||
void OnAudioSeekCompleted(media::TimeUnit aTime);
|
||||
void OnAudioSeekFailed(DemuxerFailureReason aFailure)
|
||||
{
|
||||
OnSeekFailed(TrackType::kAudioTrack, aFailure);
|
||||
}
|
||||
void OnAudioSeekFailed(DemuxerFailureReason aFailure);
|
||||
// The SeekTarget that was last given to Seek()
|
||||
SeekTarget mOriginalSeekTarget;
|
||||
// Temporary seek information while we wait for the data
|
||||
|
Loading…
x
Reference in New Issue
Block a user