[M120 Migration][MM][CAPI] Fix the logic for media using capi player.
[platform/framework/web/chromium-efl.git] / media / mojo / services / playback_events_recorder.cc
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/mojo/services/playback_events_recorder.h"
6
7 #include "base/metrics/user_metrics.h"
8 #include "base/strings/strcat.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h"
11 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
12
13 namespace media {
14
15 namespace {
16
17 void RecordEventWithValueAt(const char* name,
18                             int64_t value,
19                             base::TimeTicks time) {
20   base::RecordComputedActionAt(base::StrCat({"WebEngine.Media.", name, ":",
21                                              base::NumberToString(value)}),
22                                time);
23 }
24
25 void RecordEventWithValue(const char* name, int64_t value) {
26   RecordEventWithValueAt(name, value, base::TimeTicks::Now());
27 }
28
29 constexpr base::TimeDelta kBitrateReportPeriod = base::Seconds(5);
30
31 }  // namespace
32
33 PlaybackEventsRecorder::BitrateEstimator::BitrateEstimator() {}
34 PlaybackEventsRecorder::BitrateEstimator::~BitrateEstimator() {}
35
36 void PlaybackEventsRecorder::BitrateEstimator::Update(
37     const PipelineStatistics& stats) {
38   base::TimeTicks now = base::TimeTicks::Now();
39
40   // The code below trusts that |stats| are valid even though they came from an
41   // untrusted process. That's accepable because the stats are used only to
42   // record metrics.
43   if (last_stats_) {
44     time_elapsed_ += now - last_stats_time_;
45     audio_bytes_ +=
46         stats.audio_bytes_decoded - last_stats_->audio_bytes_decoded;
47     video_bytes_ +=
48         stats.video_bytes_decoded - last_stats_->video_bytes_decoded;
49     if (time_elapsed_ >= kBitrateReportPeriod) {
50       size_t audio_bitrate_kbps =
51           8 * audio_bytes_ / time_elapsed_.InMilliseconds();
52       RecordEventWithValueAt("AudioBitrate", audio_bitrate_kbps, now);
53
54       size_t video_bitrate_kbps =
55           8 * video_bytes_ / time_elapsed_.InMilliseconds();
56       RecordEventWithValueAt("VideoBitrate", video_bitrate_kbps, now);
57
58       time_elapsed_ = base::TimeDelta();
59       audio_bytes_ = 0;
60       video_bytes_ = 0;
61     }
62   }
63
64   last_stats_ = stats;
65   last_stats_time_ = now;
66 }
67
68 void PlaybackEventsRecorder::BitrateEstimator::OnPause() {
69   last_stats_ = {};
70 }
71
72 // static
73 void PlaybackEventsRecorder::Create(
74     mojo::PendingReceiver<mojom::PlaybackEventsRecorder> receiver) {
75   mojo::MakeSelfOwnedReceiver(std::make_unique<PlaybackEventsRecorder>(),
76                               std::move(receiver));
77 }
78
79 PlaybackEventsRecorder::PlaybackEventsRecorder() = default;
80 PlaybackEventsRecorder::~PlaybackEventsRecorder() = default;
81
82 void PlaybackEventsRecorder::OnPlaying() {
83   base::RecordComputedAction("WebEngine.Media.Playing");
84 }
85
86 void PlaybackEventsRecorder::OnPaused() {
87   base::RecordComputedAction("WebEngine.Media.Pause");
88   bitrate_estimator_.OnPause();
89 }
90
91 void PlaybackEventsRecorder::OnSeeking() {
92   buffering_state_ = BufferingState::kInitialBuffering;
93 }
94
95 void PlaybackEventsRecorder::OnEnded() {
96   base::RecordComputedAction("WebEngine.Media.Ended");
97 }
98
99 void PlaybackEventsRecorder::OnBuffering() {
100   DCHECK(buffering_state_ == BufferingState::kBuffered);
101
102   buffering_start_time_ = base::TimeTicks::Now();
103   buffering_state_ = BufferingState::kBuffering;
104
105   bitrate_estimator_.OnPause();
106 }
107
108 void PlaybackEventsRecorder::OnBufferingComplete() {
109   auto now = base::TimeTicks::Now();
110
111   if (buffering_state_ == BufferingState::kBuffering) {
112     base::TimeDelta time_between_buffering =
113         buffering_start_time_ - last_buffering_end_time_;
114     RecordEventWithValueAt("PlayTimeBeforeAutoPause",
115                            time_between_buffering.InMilliseconds(), now);
116
117     base::TimeDelta buffering_user_time = now - buffering_start_time_;
118     RecordEventWithValueAt("AutoPauseTime",
119                            buffering_user_time.InMilliseconds(), now);
120   }
121
122   buffering_state_ = BufferingState::kBuffered;
123   last_buffering_end_time_ = now;
124 }
125
126 void PlaybackEventsRecorder::OnError(const PipelineStatus& status) {
127   RecordEventWithValue("Error", status.code());
128 }
129
130 void PlaybackEventsRecorder::OnNaturalSizeChanged(const gfx::Size& size) {
131   int encoded_video_resolution = (size.width() << 16) | size.height();
132   base::RecordComputedAction(base::StringPrintf(
133       "WebEngine.Media.VideoResolution:%d", encoded_video_resolution));
134 }
135
136 void PlaybackEventsRecorder::OnPipelineStatistics(
137     const PipelineStatistics& stats) {
138   bitrate_estimator_.Update(stats);
139 }
140
141 }  // namespace media