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:
Gerald Squelart 2016-07-26 09:36:55 +10:00
parent 374f22a566
commit 2a787d2521
3 changed files with 52 additions and 8 deletions

View File

@ -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;
}
}
};

View File

@ -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()
{

View File

@ -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