already_AddRefed<VideoPlaybackQuality> HTMLVideoElement::GetVideoPlaybackQuality() { DOMHighResTimeStamp creationTime = 0; uint32_t totalFrames = 0; uint32_t droppedFrames = 0; uint32_t corruptedFrames = 0; if (IsVideoStatsEnabled()) { if (nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow()) { Performance* perf = window->GetPerformance(); if (perf) { creationTime = perf->Now(); } } if (mDecoder) { if (nsContentUtils::ShouldResistFingerprinting(OwnerDoc())) { totalFrames = nsRFPService::GetSpoofedTotalFrames(TotalPlayTime()); droppedFrames = nsRFPService::GetSpoofedDroppedFrames( TotalPlayTime(), VideoWidth(), VideoHeight()); corruptedFrames = 0; } else { FrameStatistics* stats = &mDecoder->GetFrameStatistics(); if (sizeof(totalFrames) >= sizeof(stats->GetParsedFrames())) { totalFrames = stats->GetTotalFrames(); droppedFrames = stats->GetDroppedFrames(); } else { uint64_t total = stats->GetTotalFrames(); const auto maxNumber = std::numeric_limits<uint32_t>::max(); if (total <= maxNumber) { totalFrames = uint32_t(total); droppedFrames = uint32_t(stats->GetDroppedFrames()); } else { // Too big number(s) -> Resize everything to fit in 32 bits. double ratio = double(maxNumber) / double(total); totalFrames = maxNumber; // === total * ratio droppedFrames = uint32_t(double(stats->GetDroppedFrames()) * ratio); } } corruptedFrames = 0; } } } RefPtr<VideoPlaybackQuality> playbackQuality = new VideoPlaybackQuality( this, creationTime, totalFrames, droppedFrames, corruptedFrames); return playbackQuality.forget(); }