Bug 1678373 - Add a way to specify the type of content (audio/video/both) in the TelemetryProbesReporter, change a bit visibility event handling. r=alwu

Differential Revision: https://phabricator.services.mozilla.com/D125078
This commit is contained in:
Paul Adenot 2021-10-07 15:44:51 +00:00
Родитель 26de5c39a8
Коммит d7ef88efff
3 изменённых файлов: 118 добавлений и 29 удалений

Просмотреть файл

@ -672,6 +672,9 @@ void MediaDecoder::MetadataLoaded(
aInfo->mMediaSeekableOnlyInBufferedRanges;
mInfo = std::move(aInfo);
mTelemetryProbesReporter->OnMediaContentChanged(
TelemetryProbesReporter::MediaInfoToMediaContent(*mInfo));
// Make sure the element and the frame (if any) are told about
// our new size.
if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) {
@ -735,6 +738,8 @@ void MediaDecoder::FirstFrameLoaded(
aInfo->HasVideo(), PlayStateStr(), IsTransportSeekable());
mInfo = std::move(aInfo);
mTelemetryProbesReporter->OnMediaContentChanged(
TelemetryProbesReporter::MediaInfoToMediaContent(*mInfo));
Invalidate();
@ -868,7 +873,9 @@ TelemetryProbesReporter::Visibility MediaDecoder::OwnerVisibility() const {
void MediaDecoder::UpdateTelemetryHelperBasedOnPlayState(
PlayState aState) const {
if (aState == PlayState::PLAY_STATE_PLAYING) {
mTelemetryProbesReporter->OnPlay(OwnerVisibility());
mTelemetryProbesReporter->OnPlay(
OwnerVisibility(),
TelemetryProbesReporter::MediaInfoToMediaContent(*mInfo));
} else if (aState == PlayState::PLAY_STATE_PAUSED ||
aState == PlayState::PLAY_STATE_ENDED) {
mTelemetryProbesReporter->OnPause(OwnerVisibility());

Просмотреть файл

@ -28,59 +28,122 @@ static const char* ToVisibilityStr(
return "visible";
case TelemetryProbesReporter::Visibility::eInvisible:
return "invisible";
case TelemetryProbesReporter::Visibility::eInitial:
return "initial";
default:
MOZ_ASSERT_UNREACHABLE("invalid visibility");
return "unknown";
}
}
MediaContent TelemetryProbesReporter::MediaInfoToMediaContent(
const MediaInfo& aInfo) {
if (aInfo.HasAudio() && aInfo.HasVideo()) {
return MediaContent::MEDIA_HAS_VIDEO | MediaContent::MEDIA_HAS_AUDIO;
}
if (aInfo.HasAudio()) {
return MediaContent::MEDIA_HAS_AUDIO;
}
if (aInfo.HasVideo()) {
return MediaContent::MEDIA_HAS_VIDEO;
}
return MediaContent::MEDIA_HAS_NOTHING;
}
TelemetryProbesReporter::TelemetryProbesReporter(
TelemetryProbesReporterOwner* aOwner)
: mOwner(aOwner) {
MOZ_ASSERT(mOwner);
}
void TelemetryProbesReporter::OnPlay(Visibility aVisibility) {
AssertOnMainThreadAndNotShutdown();
if (mTotalVideoPlayTime.IsStarted()) {
return;
}
void TelemetryProbesReporter::OnPlay(Visibility aVisibility,
MediaContent aMediaContent) {
LOG("Start time accumulation for total play time");
mTotalPlayTime.Start();
mOwner->DispatchAsyncTestingEvent(u"moztotalplaytimestarted"_ns);
if (aVisibility == Visibility::eInvisible) {
StartInvisibleVideoTimeAcculator();
AssertOnMainThreadAndNotShutdown();
MOZ_ASSERT_IF(mMediaContent & MediaContent::MEDIA_HAS_VIDEO,
!mTotalVideoPlayTime.IsStarted());
if (aMediaContent & MediaContent::MEDIA_HAS_VIDEO) {
mTotalVideoPlayTime.Start();
}
OnMediaContentChanged(aMediaContent);
OnVisibilityChanged(aVisibility);
mOwner->DispatchAsyncTestingEvent(u"moztotalplaytimestarted"_ns);
mIsPlaying = true;
}
void TelemetryProbesReporter::OnPause(Visibility aVisibility) {
AssertOnMainThreadAndNotShutdown();
if (!mTotalVideoPlayTime.IsStarted()) {
if (!mIsPlaying) {
// Not started
return;
}
if (aVisibility == Visibility::eInvisible) {
PauseInvisibleVideoTimeAcculator();
}
LOG("Pause time accumulation for total play time");
mTotalVideoPlayTime.Pause();
AssertOnMainThreadAndNotShutdown();
MOZ_ASSERT_IF(mMediaContent & MediaContent::MEDIA_HAS_VIDEO,
mTotalVideoPlayTime.IsStarted());
if (mMediaContent & MediaContent::MEDIA_HAS_VIDEO) {
LOG("Pause video time accumulation for total play time");
if (mInvisibleVideoPlayTime.IsStarted()) {
LOG("Pause invisible video time accumulation for total play time");
PauseInvisibleVideoTimeAcculator();
}
mTotalVideoPlayTime.Pause();
}
mOwner->DispatchAsyncTestingEvent(u"moztotalplaytimepaused"_ns);
ReportTelemetry();
mIsPlaying = false;
}
void TelemetryProbesReporter::OnVisibilityChanged(Visibility aVisibility) {
AssertOnMainThreadAndNotShutdown();
if (mMediaElementVisibility == aVisibility) {
return;
}
mMediaElementVisibility = aVisibility;
LOG("Corresponding media element visibility change=%s",
ToVisibilityStr(aVisibility));
if (mMediaElementVisibility == Visibility::eInvisible) {
LOG("Corresponding media element visibility change=%s -> %s",
ToVisibilityStr(mMediaElementVisibility), ToVisibilityStr(aVisibility));
if (aVisibility == Visibility::eInvisible) {
StartInvisibleVideoTimeAcculator();
} else {
PauseInvisibleVideoTimeAcculator();
if (aVisibility != Visibility::eInitial) {
PauseInvisibleVideoTimeAcculator();
} else {
LOG("Visibility was initial, not pausing.");
}
}
mMediaElementVisibility = aVisibility;
}
void TelemetryProbesReporter::OnMediaContentChanged(MediaContent aContent) {
AssertOnMainThreadAndNotShutdown();
if (aContent == mMediaContent) {
return;
}
if (mMediaContent & MediaContent::MEDIA_HAS_VIDEO &&
!(aContent & MediaContent::MEDIA_HAS_VIDEO)) {
LOG("Video track removed from media.");
if (mInvisibleVideoPlayTime.IsStarted()) {
PauseInvisibleVideoTimeAcculator();
}
if (mTotalVideoPlayTime.IsStarted()) {
mTotalVideoPlayTime.Pause();
}
}
if (!(mMediaContent & MediaContent::MEDIA_HAS_VIDEO) &&
aContent & MediaContent::MEDIA_HAS_VIDEO) {
LOG("Video track added to media.");
if (mIsPlaying) {
mTotalVideoPlayTime.Start();
if (mMediaElementVisibility == Visibility::eInvisible) {
StartInvisibleVideoTimeAccumulator();
}
}
}
mMediaContent = aContent;
}
void TelemetryProbesReporter::OnDecodeSuspended() {
@ -312,7 +375,8 @@ double TelemetryProbesReporter::GetTotalVideoPlayTimeInSeconds() const {
}
double TelemetryProbesReporter::GetVisibleVideoPlayTimeInSeconds() const {
return GetTotalVideoPlayTimeInSeconds() - GetInvisibleVideoPlayTimeInSeconds();
return GetTotalVideoPlayTimeInSeconds() -
GetInvisibleVideoPlayTimeInSeconds();
}
double TelemetryProbesReporter::GetInvisibleVideoPlayTimeInSeconds() const {

Просмотреть файл

@ -22,6 +22,14 @@ class TelemetryProbesReporterOwner {
virtual void DispatchAsyncTestingEvent(const nsAString& aName) = 0;
};
enum class MediaContent : uint8_t {
MEDIA_HAS_NOTHING = (0 << 0),
MEDIA_HAS_VIDEO = (1 << 0),
MEDIA_HAS_AUDIO = (1 << 1)
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MediaContent)
/**
* This class is used for collecting and reporting telemetry probes for
* its owner which should inherit from TelemetryProbesReporterOwner. We use it
@ -33,16 +41,22 @@ class TelemetryProbesReporter final {
~TelemetryProbesReporter() = default;
enum class Visibility {
eInitial,
eVisible,
eInvisible,
};
void OnPlay(Visibility aVisibility);
static MediaContent MediaInfoToMediaContent(const MediaInfo& aInfo);
// State transitions
void OnPlay(Visibility aVisibility, MediaContent aContent);
void OnPause(Visibility aVisibility);
void OnShutdown();
void OnVisibilityChanged(Visibility aVisibility);
void OnMediaContentChanged(MediaContent aContent);
void OnDecodeSuspended();
void OnDecodeResumed();
void OnShutdown();
double GetTotalVideoPlayTimeInSeconds() const;
double GetVisibleVideoPlayTimeInSeconds() const;
@ -113,7 +127,11 @@ class TelemetryProbesReporter final {
// Total time a VIDEO has spent in video-decode-suspend mode.
TimeDurationAccumulator mVideoDecodeSuspendedTime;
Visibility mMediaElementVisibility = Visibility::eInvisible;
Visibility mMediaElementVisibility = Visibility::eInitial;
MediaContent mMediaContent = MediaContent::MEDIA_HAS_NOTHING;
bool mIsPlaying = false;
};
} // namespace mozilla