Bug 1289668 - HTMLMediaElement uses video decoder's frame statistics - r?kamidphish
HTMLVideoElement can expose its thread-safe FrameStatistics object, so that
HTMLMediaElement can access more adequate data for its telemetry, without
having to use an intermediary (and potentially less accurate)
VideoPlaybackQuality object.
This will also help with accessing other/new FrameStatistics members later on.
MozReview-Commit-ID: AT7mEGy0zGr
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3076,28 +3076,29 @@ HTMLMediaElement::ReportTelemetry()
state = STALLED;
}
}
Telemetry::Accumulate(Telemetry::VIDEO_UNLOAD_STATE, state);
LOG(LogLevel::Debug, ("%p VIDEO_UNLOAD_STATE = %d", this, state));
if (HTMLVideoElement* vid = HTMLVideoElement::FromContentOrNull(this)) {
- RefPtr<VideoPlaybackQuality> quality = vid->GetVideoPlaybackQuality();
- uint32_t totalFrames = quality->TotalVideoFrames();
- if (totalFrames) {
- uint32_t droppedFrames = quality->DroppedVideoFrames();
- MOZ_ASSERT(droppedFrames <= totalFrames);
- // Dropped frames <= total frames, so 'percentage' cannot be higher than
- // 100 and therefore can fit in a uint32_t (that Telemetry takes).
- uint32_t percentage = 100 * droppedFrames / totalFrames;
- LOG(LogLevel::Debug,
- ("Reporting telemetry DROPPED_FRAMES_IN_VIDEO_PLAYBACK"));
- Telemetry::Accumulate(Telemetry::VIDEO_DROPPED_FRAMES_PROPORTION,
- percentage);
+ FrameStatistics* stats = vid->GetFrameStatistics();
+ if (stats) {
+ FrameStatisticsData data = stats->GetFrameStatisticsData();
+ if (data.mParsedFrames) {
+ MOZ_ASSERT(data.mDroppedFrames <= data.mParsedFrames);
+ // Dropped frames <= total frames, so 'percentage' cannot be higher than
+ // 100 and therefore can fit in a uint32_t (that Telemetry takes).
+ uint32_t percentage = 100 * data.mDroppedFrames / data.mParsedFrames;
+ LOG(LogLevel::Debug,
+ ("Reporting telemetry DROPPED_FRAMES_IN_VIDEO_PLAYBACK"));
+ Telemetry::Accumulate(Telemetry::VIDEO_DROPPED_FRAMES_PROPORTION,
+ percentage);
+ }
}
}
if (mMediaInfo.HasVideo() &&
mMediaInfo.mVideo.mImage.height > 0) {
// We have a valid video.
double playTime = mPlayTime.Total();
double hiddenPlayTime = mHiddenPlayTime.Total();
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -223,16 +223,22 @@ HTMLVideoElement::WrapNode(JSContext* aC
bool
HTMLVideoElement::NotifyOwnerDocumentActivityChangedInternal()
{
bool pauseElement = HTMLMediaElement::NotifyOwnerDocumentActivityChangedInternal();
UpdateScreenWakeLock();
return pauseElement;
}
+FrameStatistics*
+HTMLVideoElement::GetFrameStatistics()
+{
+ return mDecoder ? &(mDecoder->GetFrameStatistics()) : nullptr;
+}
+
already_AddRefed<VideoPlaybackQuality>
HTMLVideoElement::GetVideoPlaybackQuality()
{
DOMHighResTimeStamp creationTime = 0;
uint32_t totalFrames = 0;
uint32_t droppedFrames = 0;
uint32_t corruptedFrames = 0;
--- a/dom/html/HTMLVideoElement.h
+++ b/dom/html/HTMLVideoElement.h
@@ -125,16 +125,19 @@ public:
bool MozHasAudio() const;
bool MozUseScreenWakeLock() const;
void SetMozUseScreenWakeLock(bool aValue);
bool NotifyOwnerDocumentActivityChangedInternal() override;
+ // Gives access to the decoder's frame statistics, if present.
+ FrameStatistics* GetFrameStatistics();
+
already_AddRefed<VideoPlaybackQuality> GetVideoPlaybackQuality();
protected:
virtual ~HTMLVideoElement();
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
virtual void WakeLockCreate() override;