summaryrefslogtreecommitdiff
path: root/chromium/media/remoting/metrics.h
blob: 017ad9de60fa59be4e5042caa5f43a1016ec49c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_REMOTING_METRICS_H_
#define MEDIA_REMOTING_METRICS_H_

#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "media/base/pipeline_metadata.h"
#include "media/remoting/triggers.h"
#include "ui/gfx/geometry/size.h"

namespace media {
namespace remoting {

// The compatibility of a media content with remoting, and the reasons for
// incompatibilities.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class RemotingCompatibility {
  kCompatible = 0,
  kNoAudioNorVideo = 1,
  kEncryptedVideo = 2,
  kIncompatibleVideoCodec = 3,
  kEncryptedAudio = 4,
  kIncompatibleAudioCodec = 5,
  kDisabledByPage = 6,
  kDurationBelowThreshold = 7,
  // Add new values here. Don't re-number existing values.

  kMaxValue = kDurationBelowThreshold,
};

// The rate of pixels in a video and whether the receiver supports its playback.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class PixelRateSupport {
  // Pixels per second is at most the equivalent of 1080p 30fps.
  k2kSupported = 0,
  // More than 1080p 30fps and at most 2160p 30fps.
  k4kSupported = 1,
  k4kNotSupported = 2,
  kOver4kNotSupported = 3,
  // Add new values here. Don't re-number existing values.

  kMaxValue = kOver4kNotSupported,
};

class SessionMetricsRecorder {
 public:
  SessionMetricsRecorder();
  ~SessionMetricsRecorder();

  // When attempting to start a remoting session, WillStartSession() is called,
  // followed by either OnSessionStartSucceeded() or OnSessionStop() to indicate
  // whether the start succeeded. Later, OnSessionStop() is called when the
  // session ends.
  void WillStartSession(StartTrigger trigger);
  void DidStartSession();
  void WillStopSession(StopTrigger trigger);

  // These may be called before, during, or after a remoting session.
  void OnPipelineMetadataChanged(const PipelineMetadata& metadata);
  void OnRemotePlaybackDisabled(bool disabled);

  // Records the rate of pixels in a video (bucketed into FHD, 4K, etc.) and
  // whether the receiver supports its playback. Records only on the first call
  // for the recorder instance.
  void RecordVideoPixelRateSupport(PixelRateSupport support);

  // Records the compatibility of a media content with remoting.
  void RecordCompatibility(RemotingCompatibility compatibility);

 private:
  // Whether audio only, video only, or both were played during the session.
  //
  // NOTE: Never re-number or re-use numbers here. These are used in UMA
  // histograms, and must remain backwards-compatible for all time. However,
  // *do* change TRACK_CONFIGURATION_MAX to one after the greatest value when
  // adding new ones. Also, don't forget to update histograms.xml!
  enum TrackConfiguration {
    NEITHER_AUDIO_NOR_VIDEO = 0,
    AUDIO_ONLY = 1,
    VIDEO_ONLY = 2,
    AUDIO_AND_VIDEO = 3,

    TRACK_CONFIGURATION_MAX = 3,
  };

  // Helper methods to record media configuration at relevant times.
  void RecordAudioConfiguration();
  void RecordVideoConfiguration();
  void RecordTrackConfiguration();

  // |start_trigger_| is set while a remoting session is active.
  base::Optional<StartTrigger> start_trigger_;

  // When the current (or last) remoting session started.
  base::TimeTicks start_time_;

  // Last known audio and video configuration. These can change before/after a
  // remoting session as well as during one.
  AudioCodec last_audio_codec_;
  ChannelLayout last_channel_layout_;
  int last_sample_rate_;
  VideoCodec last_video_codec_;
  VideoCodecProfile last_video_profile_;
  gfx::Size last_natural_size_;

  // Last known disabled playback state. This can change before/after a remoting
  // session as well as during one.
  bool remote_playback_is_disabled_ = false;

  bool did_record_pixel_rate_support_ = false;

  DISALLOW_COPY_AND_ASSIGN(SessionMetricsRecorder);
};

class RendererMetricsRecorder {
 public:
  RendererMetricsRecorder();
  ~RendererMetricsRecorder();

  // Called when an "initialize success" message is received from the remote.
  void OnRendererInitialized();

  // Called whenever there is direct (or indirect, but close-in-time) evidence
  // that playout has occurred.
  void OnEvidenceOfPlayoutAtReceiver();

  // These are called at regular intervals throughout the session to provide
  // estimated data flow rates.
  void OnAudioRateEstimate(int kilobits_per_second);
  void OnVideoRateEstimate(int kilobits_per_second);

 private:
  const base::TimeTicks start_time_;
  bool did_record_first_playout_ = false;

  DISALLOW_COPY_AND_ASSIGN(RendererMetricsRecorder);
};

}  // namespace remoting
}  // namespace media

#endif  // MEDIA_REMOTING_METRICS_H_