Skip to content

Commit

Permalink
Bug 1138253 - Count dropped frames directly; r=cpearce
Browse files Browse the repository at this point in the history
  • Loading branch information
Anthony Jones committed Mar 3, 2015
1 parent c4f6a5c commit 69c0b09
Show file tree
Hide file tree
Showing 14 changed files with 49 additions and 25 deletions.
4 changes: 2 additions & 2 deletions dom/html/HTMLVideoElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ HTMLVideoElement::GetVideoPlaybackQuality()
if (mDecoder) {
MediaDecoder::FrameStatistics& stats = mDecoder->GetFrameStatistics();
totalFrames = stats.GetParsedFrames();
droppedFrames = totalFrames - stats.GetPresentedFrames();
corruptedFrames = totalFrames - stats.GetDecodedFrames();
droppedFrames = stats.GetDroppedFrames();
corruptedFrames = 0;
}
}

Expand Down
11 changes: 7 additions & 4 deletions dom/media/AbstractMediaDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ class AbstractMediaDecoder : public nsISupports
// from the resource.
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) = 0;

// Increments the parsed and decoded frame counters by the passed in counts.
// Increments the parsed, decoded and dropped frame counters by the passed in
// counts.
// Can be called on any thread.
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) = 0;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped) = 0;

// Return the duration of the media in microseconds.
virtual int64_t GetMediaDuration() = 0;
Expand Down Expand Up @@ -138,14 +140,15 @@ class AbstractMediaDecoder : public nsISupports
class AutoNotifyDecoded {
public:
explicit AutoNotifyDecoded(AbstractMediaDecoder* aDecoder)
: mParsed(0), mDecoded(0), mDecoder(aDecoder) {}
: mParsed(0), mDecoded(0), mDropped(0), mDecoder(aDecoder) {}
~AutoNotifyDecoded() {
if (mDecoder) {
mDecoder->NotifyDecodedFrames(mParsed, mDecoded);
mDecoder->NotifyDecodedFrames(mParsed, mDecoded, mDropped);
}
}
uint32_t mParsed;
uint32_t mDecoded;
uint32_t mDropped;

private:
AbstractMediaDecoder* mDecoder;
Expand Down
22 changes: 17 additions & 5 deletions dom/media/MediaDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,8 @@ class MediaDecoder : public nsIObserver,
mReentrantMonitor("MediaDecoder::FrameStats"),
mParsedFrames(0),
mDecodedFrames(0),
mPresentedFrames(0) {}
mPresentedFrames(0),
mDroppedFrames(0) {}

// Returns number of frames which have been parsed from the media.
// Can be called on any thread.
Expand All @@ -961,14 +962,22 @@ class MediaDecoder : public nsIObserver,
return mPresentedFrames;
}

// Number of frames that have been skipped because they have missed their
// compoisition deadline.
uint32_t GetDroppedFrames() {
return mDroppedFrames;
}

// Increments the parsed and decoded frame counters by the passed in counts.
// Can be called on any thread.
void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) {
if (aParsed == 0 && aDecoded == 0)
void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped) {
if (aParsed == 0 && aDecoded == 0 && aDropped == 0)
return;
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mParsedFrames += aParsed;
mDecodedFrames += aDecoded;
mDroppedFrames += aDropped;
}

// Increments the presented frame counters.
Expand All @@ -994,16 +1003,19 @@ class MediaDecoder : public nsIObserver,
// Number of decoded frames which were actually sent down the rendering
// pipeline to be painted ("presented"). Access protected by mReentrantMonitor.
uint32_t mPresentedFrames;

uint32_t mDroppedFrames;
};

// Return the frame decode/paint related statistics.
FrameStatistics& GetFrameStatistics() { return mFrameStats; }

// Increments the parsed and decoded frame counters by the passed in counts.
// Can be called on any thread.
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_OVERRIDE
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped) MOZ_OVERRIDE
{
GetFrameStatistics().NotifyDecodedFrames(aParsed, aDecoded);
GetFrameStatistics().NotifyDecodedFrames(aParsed, aDecoded, aDropped);
}

protected:
Expand Down
5 changes: 3 additions & 2 deletions dom/media/MediaDecoderStateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3155,12 +3155,13 @@ void MediaDecoderStateMachine::AdvanceFrame()
#endif
while (IsRealTime() || clock_time >= frame->mTime) {
mVideoFrameEndTime = frame->GetEndTime();
#ifdef PR_LOGGING
if (currentFrame) {
mDecoder->NotifyDecodedFrames(0, 0, 1);
#ifdef PR_LOGGING
VERBOSE_LOG("discarding video frame mTime=%lld clock_time=%lld (%d so far)",
currentFrame->mTime, clock_time, ++droppedFrames);
}
#endif
}
currentFrame = frame;
nsRefPtr<VideoData> releaseMe = VideoQueue().PopFront();
// Notify the decode thread that the video queue's buffers may have
Expand Down
3 changes: 2 additions & 1 deletion dom/media/android/AndroidMediaReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ bool AndroidMediaReader::DecodeVideoFrame(bool &aKeyframeSkip,
#if 0
if (!frame.mKeyFrame) {
++a.mParsed;
++a.mDropped;
continue;
}
#endif
Expand Down Expand Up @@ -251,7 +252,7 @@ bool AndroidMediaReader::DecodeVideoFrame(bool &aKeyframeSkip,
}
a.mParsed++;
a.mDecoded++;
NS_ASSERTION(decoded <= parsed, "Expect to decode fewer frames than parsed in AndroidMedia...");
NS_ASSERTION(a.mDecoded <= a.mParsed, "Expect to decode fewer frames than parsed in AndroidMedia...");

// Since MPAPI doesn't give us the end time of frames, we keep one frame
// buffered in AndroidMediaReader and push it into the queue as soon
Expand Down
2 changes: 1 addition & 1 deletion dom/media/fmp4/MP4Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ MP4Reader::RequestVideoData(bool aSkipToNextKeyframe,
if (!eos && NS_FAILED(mVideo.mDecoder->Flush())) {
NS_WARNING("Failed to skip/flush video when skipping-to-next-keyframe.");
}
mDecoder->NotifyDecodedFrames(parsed, 0);
mDecoder->NotifyDecodedFrames(parsed, 0, parsed);
}

MonitorAutoLock lock(mVideo.mMonitor);
Expand Down
5 changes: 3 additions & 2 deletions dom/media/gstreamer/GStreamerReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
}
}

mDecoder->NotifyDecodedFrames(0, 1);
mDecoder->NotifyDecodedFrames(0, 1, 0);

#if GST_VERSION_MAJOR >= 1
GstSample *sample = gst_app_sink_pull_sample(mVideoAppSink);
Expand All @@ -771,6 +771,7 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,

bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
if ((aKeyFrameSkip && !isKeyframe)) {
mDecoder->NotifyDecodedFrames(0, 0, 1);
gst_buffer_unref(buffer);
return true;
}
Expand Down Expand Up @@ -1150,7 +1151,7 @@ void GStreamerReader::NewVideoBuffer()
* and notify the decode thread potentially blocked in DecodeVideoFrame
*/

mDecoder->NotifyDecodedFrames(1, 0);
mDecoder->NotifyDecodedFrames(1, 0, 0);
mVideoSinkBufferCount++;
mon.NotifyAll();
}
Expand Down
5 changes: 3 additions & 2 deletions dom/media/mediasource/SourceBufferDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,10 @@ SourceBufferDecoder::GetResource() const
}

void
SourceBufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded)
SourceBufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped)
{
return mParentDecoder->NotifyDecodedFrames(aParsed, aDecoded);
return mParentDecoder->NotifyDecodedFrames(aParsed, aDecoded, aDropped);
}

void
Expand Down
2 changes: 1 addition & 1 deletion dom/media/mediasource/SourceBufferDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class SourceBufferDecoder MOZ_FINAL : public AbstractMediaDecoder
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo, bool aRestoredFromDormant) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded, uint32_t aDropped) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyWaitingForResourcesStatusChanged() MOZ_FINAL MOZ_OVERRIDE;
virtual void OnReadMetadataCompleted() MOZ_FINAL MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) MOZ_FINAL MOZ_OVERRIDE;
Expand Down
4 changes: 2 additions & 2 deletions dom/media/omx/MediaOmxReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
continue;
}

parsed++;
a.mParsed++;
if (frame.mShouldSkip && mSkipCount < MAX_DROPPED_FRAMES) {
mSkipCount++;
continue;
Expand Down Expand Up @@ -473,7 +473,7 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
}

a.mDecoded++;
NS_ASSERTION(decoded <= parsed, "Expect to decode fewer frames than parsed in OMX decoder...");
NS_ASSERTION(a.mDecoded <= a.mParsed, "Expect to decode fewer frames than parsed in OMX decoder...");

mVideoQueue.Push(v);

Expand Down
3 changes: 2 additions & 1 deletion dom/media/webaudio/BufferDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ BufferDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
}

void
BufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded)
BufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped)
{
// ignore
}
Expand Down
3 changes: 2 additions & 1 deletion dom/media/webaudio/BufferDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class BufferDecoder : public AbstractMediaDecoder

virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;

virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped) MOZ_FINAL MOZ_OVERRIDE;

virtual int64_t GetMediaDuration() MOZ_FINAL MOZ_OVERRIDE;

Expand Down
3 changes: 2 additions & 1 deletion dom/media/webm/IntelWebMVideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,12 @@ IntelWebMVideoDecoder::DecodeVideoFrame(bool& aKeyframeSkip,
MOZ_ASSERT(mPlatform && mReader->GetDecoder());

if (aKeyframeSkip) {
bool ok = SkipVideoDemuxToNextKeyFrame(aTimeThreshold, a.mParsed);
bool ok = SkipVideoDemuxToNextKeyFrame(aTimeThreshold, a.mDropped);
if (!ok) {
NS_WARNING("Failed to skip demux up to next keyframe");
return false;
}
a.mParsed = a.mDropped;
aKeyframeSkip = false;
nsresult rv = mMediaDataDecoder->Flush();
NS_ENSURE_SUCCESS(rv, false);
Expand Down
2 changes: 2 additions & 0 deletions dom/media/webm/SoftwareWebMVideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
if (aKeyframeSkip && (!si.is_kf || tstamp_usecs < aTimeThreshold)) {
// Skipping to next keyframe...
a.mParsed++; // Assume 1 frame per chunk.
a.mDropped++;
continue;
}

Expand All @@ -159,6 +160,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
// to the video queue and won't be displayed.
if (tstamp_usecs < aTimeThreshold) {
a.mParsed++; // Assume 1 frame per chunk.
a.mDropped++;
continue;
}

Expand Down

0 comments on commit 69c0b09

Please sign in to comment.