1 /*
2  *  Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MEDIA_BASE_MEDIA_CHANNEL_H_
12 #define MEDIA_BASE_MEDIA_CHANNEL_H_
13 
14 #include <map>
15 #include <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/types/optional.h"
21 #include "api/audio_codecs/audio_encoder.h"
22 #include "api/audio_options.h"
23 #include "api/crypto/frame_decryptor_interface.h"
24 #include "api/crypto/frame_encryptor_interface.h"
25 #include "api/frame_transformer_interface.h"
26 #include "api/media_stream_interface.h"
27 #include "api/rtc_error.h"
28 #include "api/rtp_parameters.h"
29 #include "api/transport/rtp/rtp_source.h"
30 #include "api/video/video_content_type.h"
31 #include "api/video/video_sink_interface.h"
32 #include "api/video/video_source_interface.h"
33 #include "api/video/video_timing.h"
34 #include "api/video_codecs/video_encoder_config.h"
35 #include "call/video_receive_stream.h"
36 #include "common_video/include/quality_limitation_reason.h"
37 #include "media/base/codec.h"
38 #include "media/base/delayable.h"
39 #include "media/base/media_config.h"
40 #include "media/base/media_constants.h"
41 #include "media/base/stream_params.h"
42 #include "modules/audio_processing/include/audio_processing_statistics.h"
43 #include "modules/rtp_rtcp/include/report_block_data.h"
44 #include "rtc_base/async_packet_socket.h"
45 #include "rtc_base/buffer.h"
46 #include "rtc_base/callback.h"
47 #include "rtc_base/copy_on_write_buffer.h"
48 #include "rtc_base/dscp.h"
49 #include "rtc_base/logging.h"
50 #include "rtc_base/network_route.h"
51 #include "rtc_base/socket.h"
52 #include "rtc_base/string_encode.h"
53 #include "rtc_base/strings/string_builder.h"
54 #include "rtc_base/synchronization/mutex.h"
55 #include "rtc_base/third_party/sigslot/sigslot.h"
56 
57 namespace rtc {
58 class Timing;
59 }
60 
61 namespace webrtc {
62 class AudioSinkInterface;
63 class VideoFrame;
64 }  // namespace webrtc
65 
66 namespace cricket {
67 
68 class AudioSource;
69 class VideoCapturer;
70 struct RtpHeader;
71 struct VideoFormat;
72 
73 const int kScreencastDefaultFps = 5;
74 
75 template <class T>
ToStringIfSet(const char * key,const absl::optional<T> & val)76 static std::string ToStringIfSet(const char* key,
77                                  const absl::optional<T>& val) {
78   std::string str;
79   if (val) {
80     str = key;
81     str += ": ";
82     str += val ? rtc::ToString(*val) : "";
83     str += ", ";
84   }
85   return str;
86 }
87 
88 template <class T>
VectorToString(const std::vector<T> & vals)89 static std::string VectorToString(const std::vector<T>& vals) {
90   rtc::StringBuilder ost;  // no-presubmit-check TODO(webrtc:8982)
91   ost << "[";
92   for (size_t i = 0; i < vals.size(); ++i) {
93     if (i > 0) {
94       ost << ", ";
95     }
96     ost << vals[i].ToString();
97   }
98   ost << "]";
99   return ost.Release();
100 }
101 
102 // Options that can be applied to a VideoMediaChannel or a VideoMediaEngine.
103 // Used to be flags, but that makes it hard to selectively apply options.
104 // We are moving all of the setting of options to structs like this,
105 // but some things currently still use flags.
106 struct VideoOptions {
107   VideoOptions();
108   ~VideoOptions();
109 
SetAllVideoOptions110   void SetAll(const VideoOptions& change) {
111     SetFrom(&video_noise_reduction, change.video_noise_reduction);
112     SetFrom(&screencast_min_bitrate_kbps, change.screencast_min_bitrate_kbps);
113     SetFrom(&is_screencast, change.is_screencast);
114   }
115 
116   bool operator==(const VideoOptions& o) const {
117     return video_noise_reduction == o.video_noise_reduction &&
118            screencast_min_bitrate_kbps == o.screencast_min_bitrate_kbps &&
119            is_screencast == o.is_screencast;
120   }
121   bool operator!=(const VideoOptions& o) const { return !(*this == o); }
122 
ToStringVideoOptions123   std::string ToString() const {
124     rtc::StringBuilder ost;
125     ost << "VideoOptions {";
126     ost << ToStringIfSet("noise reduction", video_noise_reduction);
127     ost << ToStringIfSet("screencast min bitrate kbps",
128                          screencast_min_bitrate_kbps);
129     ost << ToStringIfSet("is_screencast ", is_screencast);
130     ost << "}";
131     return ost.Release();
132   }
133 
134   // Enable denoising? This flag comes from the getUserMedia
135   // constraint 'googNoiseReduction', and WebRtcVideoEngine passes it
136   // on to the codec options. Disabled by default.
137   absl::optional<bool> video_noise_reduction;
138   // Force screencast to use a minimum bitrate. This flag comes from
139   // the PeerConnection constraint 'googScreencastMinBitrate'. It is
140   // copied to the encoder config by WebRtcVideoChannel.
141   absl::optional<int> screencast_min_bitrate_kbps;
142   // Set by screencast sources. Implies selection of encoding settings
143   // suitable for screencast. Most likely not the right way to do
144   // things, e.g., screencast of a text document and screencast of a
145   // youtube video have different needs.
146   absl::optional<bool> is_screencast;
147   webrtc::VideoTrackInterface::ContentHint content_hint;
148 
149  private:
150   template <typename T>
SetFromVideoOptions151   static void SetFrom(absl::optional<T>* s, const absl::optional<T>& o) {
152     if (o) {
153       *s = o;
154     }
155   }
156 };
157 
158 class MediaChannel : public sigslot::has_slots<> {
159  public:
160   class NetworkInterface {
161    public:
162     enum SocketType { ST_RTP, ST_RTCP };
163     virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet,
164                             const rtc::PacketOptions& options) = 0;
165     virtual bool SendRtcp(rtc::CopyOnWriteBuffer* packet,
166                           const rtc::PacketOptions& options) = 0;
167     virtual int SetOption(SocketType type,
168                           rtc::Socket::Option opt,
169                           int option) = 0;
~NetworkInterface()170     virtual ~NetworkInterface() {}
171   };
172 
173   explicit MediaChannel(const MediaConfig& config);
174   MediaChannel();
175   ~MediaChannel() override;
176 
177   virtual cricket::MediaType media_type() const = 0;
178 
179   // Sets the abstract interface class for sending RTP/RTCP data.
180   virtual void SetInterface(NetworkInterface* iface)
181       RTC_LOCKS_EXCLUDED(network_interface_mutex_);
182   // Called when a RTP packet is received.
183   virtual void OnPacketReceived(rtc::CopyOnWriteBuffer packet,
184                                 int64_t packet_time_us) = 0;
185   // Called when the socket's ability to send has changed.
186   virtual void OnReadyToSend(bool ready) = 0;
187   // Called when the network route used for sending packets changed.
188   virtual void OnNetworkRouteChanged(
189       const std::string& transport_name,
190       const rtc::NetworkRoute& network_route) = 0;
191   // Creates a new outgoing media stream with SSRCs and CNAME as described
192   // by sp.
193   virtual bool AddSendStream(const StreamParams& sp) = 0;
194   // Removes an outgoing media stream.
195   // SSRC must be the first SSRC of the media stream if the stream uses
196   // multiple SSRCs. In the case of an ssrc of 0, the possibly cached
197   // StreamParams is removed.
198   virtual bool RemoveSendStream(uint32_t ssrc) = 0;
199   // Creates a new incoming media stream with SSRCs, CNAME as described
200   // by sp. In the case of a sp without SSRCs, the unsignaled sp is cached
201   // to be used later for unsignaled streams received.
202   virtual bool AddRecvStream(const StreamParams& sp) = 0;
203   // Removes an incoming media stream.
204   // ssrc must be the first SSRC of the media stream if the stream uses
205   // multiple SSRCs.
206   virtual bool RemoveRecvStream(uint32_t ssrc) = 0;
207   // Resets any cached StreamParams for an unsignaled RecvStream.
208   virtual void ResetUnsignaledRecvStream() = 0;
209   // Returns the absoulte sendtime extension id value from media channel.
210   virtual int GetRtpSendTimeExtnId() const;
211   // Set the frame encryptor to use on all outgoing frames. This is optional.
212   // This pointers lifetime is managed by the set of RtpSender it is attached
213   // to.
214   // TODO(benwright) make pure virtual once internal supports it.
215   virtual void SetFrameEncryptor(
216       uint32_t ssrc,
217       rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor);
218   // Set the frame decryptor to use on all incoming frames. This is optional.
219   // This pointers lifetimes is managed by the set of RtpReceivers it is
220   // attached to.
221   // TODO(benwright) make pure virtual once internal supports it.
222   virtual void SetFrameDecryptor(
223       uint32_t ssrc,
224       rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor);
225 
226   // Enable network condition based codec switching.
227   virtual void SetVideoCodecSwitchingEnabled(bool enabled);
228 
229   // Base method to send packet using NetworkInterface.
SendPacket(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)230   bool SendPacket(rtc::CopyOnWriteBuffer* packet,
231                   const rtc::PacketOptions& options) {
232     return DoSendPacket(packet, false, options);
233   }
234 
SendRtcp(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)235   bool SendRtcp(rtc::CopyOnWriteBuffer* packet,
236                 const rtc::PacketOptions& options) {
237     return DoSendPacket(packet, true, options);
238   }
239 
SetOption(NetworkInterface::SocketType type,rtc::Socket::Option opt,int option)240   int SetOption(NetworkInterface::SocketType type,
241                 rtc::Socket::Option opt,
242                 int option) RTC_LOCKS_EXCLUDED(network_interface_mutex_) {
243     webrtc::MutexLock lock(&network_interface_mutex_);
244     return SetOptionLocked(type, opt, option);
245   }
246 
247   // Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
248   // Set to true if it's allowed to mix one- and two-byte RTP header extensions
249   // in the same stream. The setter and getter must only be called from
250   // worker_thread.
SetExtmapAllowMixed(bool extmap_allow_mixed)251   void SetExtmapAllowMixed(bool extmap_allow_mixed) {
252     extmap_allow_mixed_ = extmap_allow_mixed;
253   }
ExtmapAllowMixed()254   bool ExtmapAllowMixed() const { return extmap_allow_mixed_; }
255 
256   virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0;
257   virtual webrtc::RTCError SetRtpSendParameters(
258       uint32_t ssrc,
259       const webrtc::RtpParameters& parameters) = 0;
260 
261   virtual void SetEncoderToPacketizerFrameTransformer(
262       uint32_t ssrc,
263       rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer);
264   virtual void SetDepacketizerToDecoderFrameTransformer(
265       uint32_t ssrc,
266       rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer);
267 
268  protected:
SetOptionLocked(NetworkInterface::SocketType type,rtc::Socket::Option opt,int option)269   int SetOptionLocked(NetworkInterface::SocketType type,
270                       rtc::Socket::Option opt,
271                       int option)
272       RTC_EXCLUSIVE_LOCKS_REQUIRED(network_interface_mutex_) {
273     if (!network_interface_)
274       return -1;
275     return network_interface_->SetOption(type, opt, option);
276   }
277 
DscpEnabled()278   bool DscpEnabled() const { return enable_dscp_; }
279 
280   // This is the DSCP value used for both RTP and RTCP channels if DSCP is
281   // enabled. It can be changed at any time via |SetPreferredDscp|.
PreferredDscp()282   rtc::DiffServCodePoint PreferredDscp() const
283       RTC_LOCKS_EXCLUDED(network_interface_mutex_) {
284     webrtc::MutexLock lock(&network_interface_mutex_);
285     return preferred_dscp_;
286   }
287 
SetPreferredDscp(rtc::DiffServCodePoint preferred_dscp)288   int SetPreferredDscp(rtc::DiffServCodePoint preferred_dscp)
289       RTC_LOCKS_EXCLUDED(network_interface_mutex_) {
290     webrtc::MutexLock lock(&network_interface_mutex_);
291     if (preferred_dscp == preferred_dscp_) {
292       return 0;
293     }
294     preferred_dscp_ = preferred_dscp;
295     return UpdateDscp();
296   }
297 
298  private:
299   // Apply the preferred DSCP setting to the underlying network interface RTP
300   // and RTCP channels. If DSCP is disabled, then apply the default DSCP value.
UpdateDscp()301   int UpdateDscp() RTC_EXCLUSIVE_LOCKS_REQUIRED(network_interface_mutex_) {
302     rtc::DiffServCodePoint value =
303         enable_dscp_ ? preferred_dscp_ : rtc::DSCP_DEFAULT;
304     int ret =
305         SetOptionLocked(NetworkInterface::ST_RTP, rtc::Socket::OPT_DSCP, value);
306     if (ret == 0) {
307       ret = SetOptionLocked(NetworkInterface::ST_RTCP, rtc::Socket::OPT_DSCP,
308                             value);
309     }
310     return ret;
311   }
312 
DoSendPacket(rtc::CopyOnWriteBuffer * packet,bool rtcp,const rtc::PacketOptions & options)313   bool DoSendPacket(rtc::CopyOnWriteBuffer* packet,
314                     bool rtcp,
315                     const rtc::PacketOptions& options)
316       RTC_LOCKS_EXCLUDED(network_interface_mutex_) {
317     webrtc::MutexLock lock(&network_interface_mutex_);
318     if (!network_interface_)
319       return false;
320 
321     return (!rtcp) ? network_interface_->SendPacket(packet, options)
322                    : network_interface_->SendRtcp(packet, options);
323   }
324 
325   const bool enable_dscp_;
326   // |network_interface_| can be accessed from the worker_thread and
327   // from any MediaEngine threads. This critical section is to protect accessing
328   // of network_interface_ object.
329   mutable webrtc::Mutex network_interface_mutex_;
330   NetworkInterface* network_interface_
331       RTC_GUARDED_BY(network_interface_mutex_) = nullptr;
332   rtc::DiffServCodePoint preferred_dscp_
333       RTC_GUARDED_BY(network_interface_mutex_) = rtc::DSCP_DEFAULT;
334   bool extmap_allow_mixed_ = false;
335 };
336 
337 // The stats information is structured as follows:
338 // Media are represented by either MediaSenderInfo or MediaReceiverInfo.
339 // Media contains a vector of SSRC infos that are exclusively used by this
340 // media. (SSRCs shared between media streams can't be represented.)
341 
342 // Information about an SSRC.
343 // This data may be locally recorded, or received in an RTCP SR or RR.
344 struct SsrcSenderInfo {
345   uint32_t ssrc = 0;
346   double timestamp = 0.0;  // NTP timestamp, represented as seconds since epoch.
347 };
348 
349 struct SsrcReceiverInfo {
350   uint32_t ssrc = 0;
351   double timestamp = 0.0;
352 };
353 
354 struct MediaSenderInfo {
355   MediaSenderInfo();
356   ~MediaSenderInfo();
add_ssrcMediaSenderInfo357   void add_ssrc(const SsrcSenderInfo& stat) { local_stats.push_back(stat); }
358   // Temporary utility function for call sites that only provide SSRC.
359   // As more info is added into SsrcSenderInfo, this function should go away.
add_ssrcMediaSenderInfo360   void add_ssrc(uint32_t ssrc) {
361     SsrcSenderInfo stat;
362     stat.ssrc = ssrc;
363     add_ssrc(stat);
364   }
365   // Utility accessor for clients that are only interested in ssrc numbers.
ssrcsMediaSenderInfo366   std::vector<uint32_t> ssrcs() const {
367     std::vector<uint32_t> retval;
368     for (std::vector<SsrcSenderInfo>::const_iterator it = local_stats.begin();
369          it != local_stats.end(); ++it) {
370       retval.push_back(it->ssrc);
371     }
372     return retval;
373   }
374   // Returns true if the media has been connected.
connectedMediaSenderInfo375   bool connected() const { return local_stats.size() > 0; }
376   // Utility accessor for clients that make the assumption only one ssrc
377   // exists per media.
378   // This will eventually go away.
379   // Call sites that compare this to zero should use connected() instead.
380   // https://bugs.webrtc.org/8694
ssrcMediaSenderInfo381   uint32_t ssrc() const {
382     if (connected()) {
383       return local_stats[0].ssrc;
384     } else {
385       return 0;
386     }
387   }
388   // https://w3c.github.io/webrtc-stats/#dom-rtcsentrtpstreamstats-bytessent
389   int64_t payload_bytes_sent = 0;
390   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-headerbytessent
391   int64_t header_and_padding_bytes_sent = 0;
392   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-retransmittedbytessent
393   uint64_t retransmitted_bytes_sent = 0;
394   int packets_sent = 0;
395   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-retransmittedpacketssent
396   uint64_t retransmitted_packets_sent = 0;
397   int packets_lost = 0;
398   float fraction_lost = 0.0f;
399   int64_t rtt_ms = 0;
400   std::string codec_name;
401   absl::optional<int> codec_payload_type;
402   std::vector<SsrcSenderInfo> local_stats;
403   std::vector<SsrcReceiverInfo> remote_stats;
404   // A snapshot of the most recent Report Block with additional data of interest
405   // to statistics. Used to implement RTCRemoteInboundRtpStreamStats. Within
406   // this list, the ReportBlockData::RTCPReportBlock::source_ssrc(), which is
407   // the SSRC of the corresponding outbound RTP stream, is unique.
408   std::vector<webrtc::ReportBlockData> report_block_datas;
409 };
410 
411 struct MediaReceiverInfo {
412   MediaReceiverInfo();
413   ~MediaReceiverInfo();
add_ssrcMediaReceiverInfo414   void add_ssrc(const SsrcReceiverInfo& stat) { local_stats.push_back(stat); }
415   // Temporary utility function for call sites that only provide SSRC.
416   // As more info is added into SsrcSenderInfo, this function should go away.
add_ssrcMediaReceiverInfo417   void add_ssrc(uint32_t ssrc) {
418     SsrcReceiverInfo stat;
419     stat.ssrc = ssrc;
420     add_ssrc(stat);
421   }
ssrcsMediaReceiverInfo422   std::vector<uint32_t> ssrcs() const {
423     std::vector<uint32_t> retval;
424     for (std::vector<SsrcReceiverInfo>::const_iterator it = local_stats.begin();
425          it != local_stats.end(); ++it) {
426       retval.push_back(it->ssrc);
427     }
428     return retval;
429   }
430   // Returns true if the media has been connected.
connectedMediaReceiverInfo431   bool connected() const { return local_stats.size() > 0; }
432   // Utility accessor for clients that make the assumption only one ssrc
433   // exists per media.
434   // This will eventually go away.
435   // Call sites that compare this to zero should use connected();
436   // https://bugs.webrtc.org/8694
ssrcMediaReceiverInfo437   uint32_t ssrc() const {
438     if (connected()) {
439       return local_stats[0].ssrc;
440     } else {
441       return 0;
442     }
443   }
444 
445   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-bytesreceived
446   int64_t payload_bytes_rcvd = 0;
447   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-headerbytesreceived
448   int64_t header_and_padding_bytes_rcvd = 0;
449   int packets_rcvd = 0;
450   int packets_lost = 0;
451   // The timestamp at which the last packet was received, i.e. the time of the
452   // local clock when it was received - not the RTP timestamp of that packet.
453   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp
454   absl::optional<int64_t> last_packet_received_timestamp_ms;
455   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-estimatedplayouttimestamp
456   absl::optional<int64_t> estimated_playout_ntp_timestamp_ms;
457   std::string codec_name;
458   absl::optional<int> codec_payload_type;
459   std::vector<SsrcReceiverInfo> local_stats;
460   std::vector<SsrcSenderInfo> remote_stats;
461 };
462 
463 struct VoiceSenderInfo : public MediaSenderInfo {
464   VoiceSenderInfo();
465   ~VoiceSenderInfo();
466   int jitter_ms = 0;
467   // Current audio level, expressed linearly [0,32767].
468   int audio_level = 0;
469   // See description of "totalAudioEnergy" in the WebRTC stats spec:
470   // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy
471   double total_input_energy = 0.0;
472   double total_input_duration = 0.0;
473   bool typing_noise_detected = false;
474   webrtc::ANAStats ana_statistics;
475   webrtc::AudioProcessingStats apm_statistics;
476 };
477 
478 struct VoiceReceiverInfo : public MediaReceiverInfo {
479   VoiceReceiverInfo();
480   ~VoiceReceiverInfo();
481   int jitter_ms = 0;
482   int jitter_buffer_ms = 0;
483   int jitter_buffer_preferred_ms = 0;
484   int delay_estimate_ms = 0;
485   int audio_level = 0;
486   // Stats below correspond to similarly-named fields in the WebRTC stats spec.
487   // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats
488   double total_output_energy = 0.0;
489   uint64_t total_samples_received = 0;
490   double total_output_duration = 0.0;
491   uint64_t concealed_samples = 0;
492   uint64_t silent_concealed_samples = 0;
493   uint64_t concealment_events = 0;
494   double jitter_buffer_delay_seconds = 0.0;
495   uint64_t jitter_buffer_emitted_count = 0;
496   double jitter_buffer_target_delay_seconds = 0.0;
497   uint64_t inserted_samples_for_deceleration = 0;
498   uint64_t removed_samples_for_acceleration = 0;
499   uint64_t fec_packets_received = 0;
500   uint64_t fec_packets_discarded = 0;
501   // Stats below DO NOT correspond directly to anything in the WebRTC stats
502   // fraction of synthesized audio inserted through expansion.
503   float expand_rate = 0.0f;
504   // fraction of synthesized speech inserted through expansion.
505   float speech_expand_rate = 0.0f;
506   // fraction of data out of secondary decoding, including FEC and RED.
507   float secondary_decoded_rate = 0.0f;
508   // Fraction of secondary data, including FEC and RED, that is discarded.
509   // Discarding of secondary data can be caused by the reception of the primary
510   // data, obsoleting the secondary data. It can also be caused by early
511   // or late arrival of secondary data. This metric is the percentage of
512   // discarded secondary data since last query of receiver info.
513   float secondary_discarded_rate = 0.0f;
514   // Fraction of data removed through time compression.
515   float accelerate_rate = 0.0f;
516   // Fraction of data inserted through time stretching.
517   float preemptive_expand_rate = 0.0f;
518   int decoding_calls_to_silence_generator = 0;
519   int decoding_calls_to_neteq = 0;
520   int decoding_normal = 0;
521   // TODO(alexnarest): Consider decoding_neteq_plc for consistency
522   int decoding_plc = 0;
523   int decoding_codec_plc = 0;
524   int decoding_cng = 0;
525   int decoding_plc_cng = 0;
526   int decoding_muted_output = 0;
527   // Estimated capture start time in NTP time in ms.
528   int64_t capture_start_ntp_time_ms = -1;
529   // Count of the number of buffer flushes.
530   uint64_t jitter_buffer_flushes = 0;
531   // Number of samples expanded due to delayed packets.
532   uint64_t delayed_packet_outage_samples = 0;
533   // Arrival delay of received audio packets.
534   double relative_packet_arrival_delay_seconds = 0.0;
535   // Count and total duration of audio interruptions (loss-concealement periods
536   // longer than 150 ms).
537   int32_t interruption_count = 0;
538   int32_t total_interruption_duration_ms = 0;
539 };
540 
541 struct VideoSenderInfo : public MediaSenderInfo {
542   VideoSenderInfo();
543   ~VideoSenderInfo();
544   std::vector<SsrcGroup> ssrc_groups;
545   std::string encoder_implementation_name;
546   int firs_rcvd = 0;
547   int plis_rcvd = 0;
548   int nacks_rcvd = 0;
549   int send_frame_width = 0;
550   int send_frame_height = 0;
551   int framerate_input = 0;
552   int framerate_sent = 0;
553   int aggregated_framerate_sent = 0;
554   int nominal_bitrate = 0;
555   int adapt_reason = 0;
556   int adapt_changes = 0;
557   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationreason
558   webrtc::QualityLimitationReason quality_limitation_reason =
559       webrtc::QualityLimitationReason::kNone;
560   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationdurations
561   std::map<webrtc::QualityLimitationReason, int64_t>
562       quality_limitation_durations_ms;
563   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationresolutionchanges
564   uint32_t quality_limitation_resolution_changes = 0;
565   int avg_encode_ms = 0;
566   int encode_usage_percent = 0;
567   uint32_t frames_encoded = 0;
568   uint32_t key_frames_encoded = 0;
569   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodetime
570   uint64_t total_encode_time_ms = 0;
571   // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget
572   uint64_t total_encoded_bytes_target = 0;
573   uint64_t total_packet_send_delay_ms = 0;
574   bool has_entered_low_resolution = false;
575   absl::optional<uint64_t> qp_sum;
576   webrtc::VideoContentType content_type = webrtc::VideoContentType::UNSPECIFIED;
577   uint32_t frames_sent = 0;
578   // https://w3c.github.io/webrtc-stats/#dom-rtcvideosenderstats-hugeframessent
579   uint32_t huge_frames_sent = 0;
580   uint32_t aggregated_huge_frames_sent = 0;
581   absl::optional<std::string> rid;
582 };
583 
584 struct VideoReceiverInfo : public MediaReceiverInfo {
585   VideoReceiverInfo();
586   ~VideoReceiverInfo();
587   std::vector<SsrcGroup> ssrc_groups;
588   std::string decoder_implementation_name;
589   int packets_concealed = 0;
590   int firs_sent = 0;
591   int plis_sent = 0;
592   int nacks_sent = 0;
593   int frame_width = 0;
594   int frame_height = 0;
595   int framerate_rcvd = 0;
596   int framerate_decoded = 0;
597   int framerate_output = 0;
598   // Framerate as sent to the renderer.
599   int framerate_render_input = 0;
600   // Framerate that the renderer reports.
601   int framerate_render_output = 0;
602   uint32_t frames_received = 0;
603   uint32_t frames_dropped = 0;
604   uint32_t frames_decoded = 0;
605   uint32_t key_frames_decoded = 0;
606   uint32_t frames_rendered = 0;
607   absl::optional<uint64_t> qp_sum;
608   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totaldecodetime
609   uint64_t total_decode_time_ms = 0;
610   double total_inter_frame_delay = 0;
611   double total_squared_inter_frame_delay = 0;
612   int64_t interframe_delay_max_ms = -1;
613   uint32_t freeze_count = 0;
614   uint32_t pause_count = 0;
615   uint32_t total_freezes_duration_ms = 0;
616   uint32_t total_pauses_duration_ms = 0;
617   uint32_t total_frames_duration_ms = 0;
618   double sum_squared_frame_durations = 0.0;
619 
620   webrtc::VideoContentType content_type = webrtc::VideoContentType::UNSPECIFIED;
621 
622   // All stats below are gathered per-VideoReceiver, but some will be correlated
623   // across MediaStreamTracks.  NOTE(hta): when sinking stats into per-SSRC
624   // structures, reflect this in the new layout.
625 
626   // Current frame decode latency.
627   int decode_ms = 0;
628   // Maximum observed frame decode latency.
629   int max_decode_ms = 0;
630   // Jitter (network-related) latency.
631   int jitter_buffer_ms = 0;
632   // Jitter (network-related) latency (cumulative).
633   // https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats-jitterbufferdelay
634   double jitter_buffer_delay_seconds = 0;
635   // Number of observations for cumulative jitter latency.
636   // https://w3c.github.io/webrtc-stats/#dom-rtcvideoreceiverstats-jitterbufferemittedcount
637   uint64_t jitter_buffer_emitted_count = 0;
638   // Requested minimum playout latency.
639   int min_playout_delay_ms = 0;
640   // Requested latency to account for rendering delay.
641   int render_delay_ms = 0;
642   // Target overall delay: network+decode+render, accounting for
643   // min_playout_delay_ms.
644   int target_delay_ms = 0;
645   // Current overall delay, possibly ramping towards target_delay_ms.
646   int current_delay_ms = 0;
647 
648   // Estimated capture start time in NTP time in ms.
649   int64_t capture_start_ntp_time_ms = -1;
650 
651   // First frame received to first frame decoded latency.
652   int64_t first_frame_received_to_decoded_ms = -1;
653 
654   // Timing frame info: all important timestamps for a full lifetime of a
655   // single 'timing frame'.
656   absl::optional<webrtc::TimingFrameInfo> timing_frame_info;
657 };
658 
659 struct DataSenderInfo : public MediaSenderInfo {
660   uint32_t ssrc = 0;
661 };
662 
663 struct DataReceiverInfo : public MediaReceiverInfo {
664   uint32_t ssrc = 0;
665 };
666 
667 struct BandwidthEstimationInfo {
668   int available_send_bandwidth = 0;
669   int available_recv_bandwidth = 0;
670   int target_enc_bitrate = 0;
671   int actual_enc_bitrate = 0;
672   int retransmit_bitrate = 0;
673   int transmit_bitrate = 0;
674   int64_t bucket_delay = 0;
675 };
676 
677 // Maps from payload type to |RtpCodecParameters|.
678 typedef std::map<int, webrtc::RtpCodecParameters> RtpCodecParametersMap;
679 
680 struct VoiceMediaInfo {
681   VoiceMediaInfo();
682   ~VoiceMediaInfo();
ClearVoiceMediaInfo683   void Clear() {
684     senders.clear();
685     receivers.clear();
686     send_codecs.clear();
687     receive_codecs.clear();
688   }
689   std::vector<VoiceSenderInfo> senders;
690   std::vector<VoiceReceiverInfo> receivers;
691   RtpCodecParametersMap send_codecs;
692   RtpCodecParametersMap receive_codecs;
693   int32_t device_underrun_count = 0;
694 };
695 
696 struct VideoMediaInfo {
697   VideoMediaInfo();
698   ~VideoMediaInfo();
ClearVideoMediaInfo699   void Clear() {
700     senders.clear();
701     aggregated_senders.clear();
702     receivers.clear();
703     send_codecs.clear();
704     receive_codecs.clear();
705   }
706   // Each sender info represents one "outbound-rtp" stream.In non - simulcast,
707   // this means one info per RtpSender but if simulcast is used this means
708   // one info per simulcast layer.
709   std::vector<VideoSenderInfo> senders;
710   // Used for legacy getStats() API's "ssrc" stats and modern getStats() API's
711   // "track" stats. If simulcast is used, instead of having one sender info per
712   // simulcast layer, the metrics of all layers of an RtpSender are aggregated
713   // into a single sender info per RtpSender.
714   std::vector<VideoSenderInfo> aggregated_senders;
715   std::vector<VideoReceiverInfo> receivers;
716   RtpCodecParametersMap send_codecs;
717   RtpCodecParametersMap receive_codecs;
718 };
719 
720 struct DataMediaInfo {
721   DataMediaInfo();
722   ~DataMediaInfo();
ClearDataMediaInfo723   void Clear() {
724     senders.clear();
725     receivers.clear();
726   }
727   std::vector<DataSenderInfo> senders;
728   std::vector<DataReceiverInfo> receivers;
729 };
730 
731 struct RtcpParameters {
732   bool reduced_size = false;
733   bool remote_estimate = false;
734 };
735 
736 template <class Codec>
737 struct RtpParameters {
738   virtual ~RtpParameters() = default;
739 
740   std::vector<Codec> codecs;
741   std::vector<webrtc::RtpExtension> extensions;
742   // For a send stream this is true if we've neogtiated a send direction,
743   // for a receive stream this is true if we've negotiated a receive direction.
744   bool is_stream_active = true;
745 
746   // TODO(pthatcher): Add streams.
747   RtcpParameters rtcp;
748 
ToStringRtpParameters749   std::string ToString() const {
750     rtc::StringBuilder ost;
751     ost << "{";
752     const char* separator = "";
753     for (const auto& entry : ToStringMap()) {
754       ost << separator << entry.first << ": " << entry.second;
755       separator = ", ";
756     }
757     ost << "}";
758     return ost.Release();
759   }
760 
761  protected:
ToStringMapRtpParameters762   virtual std::map<std::string, std::string> ToStringMap() const {
763     return {{"codecs", VectorToString(codecs)},
764             {"extensions", VectorToString(extensions)}};
765   }
766 };
767 
768 // TODO(deadbeef): Rename to RtpSenderParameters, since they're intended to
769 // encapsulate all the parameters needed for an RtpSender.
770 template <class Codec>
771 struct RtpSendParameters : RtpParameters<Codec> {
772   int max_bandwidth_bps = -1;
773   // This is the value to be sent in the MID RTP header extension (if the header
774   // extension in included in the list of extensions).
775   std::string mid;
776   bool extmap_allow_mixed = false;
777 
778  protected:
ToStringMapRtpSendParameters779   std::map<std::string, std::string> ToStringMap() const override {
780     auto params = RtpParameters<Codec>::ToStringMap();
781     params["max_bandwidth_bps"] = rtc::ToString(max_bandwidth_bps);
782     params["mid"] = (mid.empty() ? "<not set>" : mid);
783     params["extmap-allow-mixed"] = extmap_allow_mixed ? "true" : "false";
784     return params;
785   }
786 };
787 
788 struct AudioSendParameters : RtpSendParameters<AudioCodec> {
789   AudioSendParameters();
790   ~AudioSendParameters() override;
791   AudioOptions options;
792 
793  protected:
794   std::map<std::string, std::string> ToStringMap() const override;
795 };
796 
797 struct AudioRecvParameters : RtpParameters<AudioCodec> {};
798 
799 class VoiceMediaChannel : public MediaChannel, public Delayable {
800  public:
VoiceMediaChannel()801   VoiceMediaChannel() {}
VoiceMediaChannel(const MediaConfig & config)802   explicit VoiceMediaChannel(const MediaConfig& config)
803       : MediaChannel(config) {}
~VoiceMediaChannel()804   ~VoiceMediaChannel() override {}
805 
806   cricket::MediaType media_type() const override;
807   virtual bool SetSendParameters(const AudioSendParameters& params) = 0;
808   virtual bool SetRecvParameters(const AudioRecvParameters& params) = 0;
809   // Get the receive parameters for the incoming stream identified by |ssrc|.
810   virtual webrtc::RtpParameters GetRtpReceiveParameters(
811       uint32_t ssrc) const = 0;
812   // Retrieve the receive parameters for the default receive
813   // stream, which is used when SSRCs are not signaled.
814   virtual webrtc::RtpParameters GetDefaultRtpReceiveParameters() const = 0;
815   // Starts or stops playout of received audio.
816   virtual void SetPlayout(bool playout) = 0;
817   // Starts or stops sending (and potentially capture) of local audio.
818   virtual void SetSend(bool send) = 0;
819   // Configure stream for sending.
820   virtual bool SetAudioSend(uint32_t ssrc,
821                             bool enable,
822                             const AudioOptions* options,
823                             AudioSource* source) = 0;
824   // Set speaker output volume of the specified ssrc.
825   virtual bool SetOutputVolume(uint32_t ssrc, double volume) = 0;
826   // Set speaker output volume for future unsignaled streams.
827   virtual bool SetDefaultOutputVolume(double volume) = 0;
828   // Returns if the telephone-event has been negotiated.
829   virtual bool CanInsertDtmf() = 0;
830   // Send a DTMF |event|. The DTMF out-of-band signal will be used.
831   // The |ssrc| should be either 0 or a valid send stream ssrc.
832   // The valid value for the |event| are 0 to 15 which corresponding to
833   // DTMF event 0-9, *, #, A-D.
834   virtual bool InsertDtmf(uint32_t ssrc, int event, int duration) = 0;
835   // Gets quality stats for the channel.
836   virtual bool GetStats(VoiceMediaInfo* info) = 0;
837 
838   virtual void SetRawAudioSink(
839       uint32_t ssrc,
840       std::unique_ptr<webrtc::AudioSinkInterface> sink) = 0;
841   virtual void SetDefaultRawAudioSink(
842       std::unique_ptr<webrtc::AudioSinkInterface> sink) = 0;
843 
844   virtual std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const = 0;
845 };
846 
847 // TODO(deadbeef): Rename to VideoSenderParameters, since they're intended to
848 // encapsulate all the parameters needed for a video RtpSender.
849 struct VideoSendParameters : RtpSendParameters<VideoCodec> {
850   VideoSendParameters();
851   ~VideoSendParameters() override;
852   // Use conference mode? This flag comes from the remote
853   // description's SDP line 'a=x-google-flag:conference', copied over
854   // by VideoChannel::SetRemoteContent_w, and ultimately used by
855   // conference mode screencast logic in
856   // WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig.
857   // The special screencast behaviour is disabled by default.
858   bool conference_mode = false;
859 
860  protected:
861   std::map<std::string, std::string> ToStringMap() const override;
862 };
863 
864 // TODO(deadbeef): Rename to VideoReceiverParameters, since they're intended to
865 // encapsulate all the parameters needed for a video RtpReceiver.
866 struct VideoRecvParameters : RtpParameters<VideoCodec> {};
867 
868 class VideoMediaChannel : public MediaChannel, public Delayable {
869  public:
VideoMediaChannel()870   VideoMediaChannel() {}
VideoMediaChannel(const MediaConfig & config)871   explicit VideoMediaChannel(const MediaConfig& config)
872       : MediaChannel(config) {}
~VideoMediaChannel()873   ~VideoMediaChannel() override {}
874 
875   cricket::MediaType media_type() const override;
876   virtual bool SetSendParameters(const VideoSendParameters& params) = 0;
877   virtual bool SetRecvParameters(const VideoRecvParameters& params) = 0;
878   // Get the receive parameters for the incoming stream identified by |ssrc|.
879   virtual webrtc::RtpParameters GetRtpReceiveParameters(
880       uint32_t ssrc) const = 0;
881   // Retrieve the receive parameters for the default receive
882   // stream, which is used when SSRCs are not signaled.
883   virtual webrtc::RtpParameters GetDefaultRtpReceiveParameters() const = 0;
884   // Gets the currently set codecs/payload types to be used for outgoing media.
885   virtual bool GetSendCodec(VideoCodec* send_codec) = 0;
886   // Starts or stops transmission (and potentially capture) of local video.
887   virtual bool SetSend(bool send) = 0;
888   // Configure stream for sending and register a source.
889   // The |ssrc| must correspond to a registered send stream.
890   virtual bool SetVideoSend(
891       uint32_t ssrc,
892       const VideoOptions* options,
893       rtc::VideoSourceInterface<webrtc::VideoFrame>* source) = 0;
894   // Sets the sink object to be used for the specified stream.
895   virtual bool SetSink(uint32_t ssrc,
896                        rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) = 0;
897   // The sink is used for the 'default' stream.
898   virtual void SetDefaultSink(
899       rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) = 0;
900   // This fills the "bitrate parts" (rtx, video bitrate) of the
901   // BandwidthEstimationInfo, since that part that isn't possible to get
902   // through webrtc::Call::GetStats, as they are statistics of the send
903   // streams.
904   // TODO(holmer): We should change this so that either BWE graphs doesn't
905   // need access to bitrates of the streams, or change the (RTC)StatsCollector
906   // so that it's getting the send stream stats separately by calling
907   // GetStats(), and merges with BandwidthEstimationInfo by itself.
908   virtual void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) = 0;
909   // Gets quality stats for the channel.
910   virtual bool GetStats(VideoMediaInfo* info) = 0;
911   // Set recordable encoded frame callback for |ssrc|
912   virtual void SetRecordableEncodedFrameCallback(
913       uint32_t ssrc,
914       std::function<void(const webrtc::RecordableEncodedFrame&)> callback) = 0;
915   // Clear recordable encoded frame callback for |ssrc|
916   virtual void ClearRecordableEncodedFrameCallback(uint32_t ssrc) = 0;
917   // Cause generation of a keyframe for |ssrc|
918   virtual void GenerateKeyFrame(uint32_t ssrc) = 0;
919 
920   virtual std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const = 0;
921 };
922 
923 enum DataMessageType {
924   // Chrome-Internal use only.  See SctpDataMediaChannel for the actual PPID
925   // values.
926   DMT_NONE = 0,
927   DMT_CONTROL = 1,
928   DMT_BINARY = 2,
929   DMT_TEXT = 3,
930 };
931 
932 // Info about data received in DataMediaChannel.  For use in
933 // DataMediaChannel::SignalDataReceived and in all of the signals that
934 // signal fires, on up the chain.
935 struct ReceiveDataParams {
936   // The in-packet stream indentifier.
937   // RTP data channels use SSRCs, SCTP data channels use SIDs.
938   union {
939     uint32_t ssrc;
940     int sid = 0;
941   };
942   // The type of message (binary, text, or control).
943   DataMessageType type = DMT_TEXT;
944   // A per-stream value incremented per packet in the stream.
945   int seq_num = 0;
946   // A per-stream value monotonically increasing with time.
947   int timestamp = 0;
948 };
949 
950 struct SendDataParams {
951   // The in-packet stream indentifier.
952   // RTP data channels use SSRCs, SCTP data channels use SIDs.
953   union {
954     uint32_t ssrc;
955     int sid = 0;
956   };
957   // The type of message (binary, text, or control).
958   DataMessageType type = DMT_TEXT;
959 
960   // TODO(pthatcher): Make |ordered| and |reliable| true by default?
961   // For SCTP, whether to send messages flagged as ordered or not.
962   // If false, messages can be received out of order.
963   bool ordered = false;
964   // For SCTP, whether the messages are sent reliably or not.
965   // If false, messages may be lost.
966   bool reliable = false;
967   // For SCTP, if reliable == false, provide partial reliability by
968   // resending up to this many times.  Either count or millis
969   // is supported, not both at the same time.
970   int max_rtx_count = 0;
971   // For SCTP, if reliable == false, provide partial reliability by
972   // resending for up to this many milliseconds.  Either count or millis
973   // is supported, not both at the same time.
974   int max_rtx_ms = 0;
975 };
976 
977 enum SendDataResult { SDR_SUCCESS, SDR_ERROR, SDR_BLOCK };
978 
979 struct DataSendParameters : RtpSendParameters<DataCodec> {};
980 
981 struct DataRecvParameters : RtpParameters<DataCodec> {};
982 
983 class DataMediaChannel : public MediaChannel {
984  public:
985   DataMediaChannel();
986   explicit DataMediaChannel(const MediaConfig& config);
987   ~DataMediaChannel() override;
988 
989   cricket::MediaType media_type() const override;
990   virtual bool SetSendParameters(const DataSendParameters& params) = 0;
991   virtual bool SetRecvParameters(const DataRecvParameters& params) = 0;
992 
993   // RtpParameter methods are not supported for Data channel.
994   webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override;
995   webrtc::RTCError SetRtpSendParameters(
996       uint32_t ssrc,
997       const webrtc::RtpParameters& parameters) override;
998 
999   // TODO(pthatcher): Implement this.
1000   virtual bool GetStats(DataMediaInfo* info);
1001 
1002   virtual bool SetSend(bool send) = 0;
1003   virtual bool SetReceive(bool receive) = 0;
1004 
OnNetworkRouteChanged(const std::string & transport_name,const rtc::NetworkRoute & network_route)1005   void OnNetworkRouteChanged(const std::string& transport_name,
1006                              const rtc::NetworkRoute& network_route) override {}
1007 
1008   virtual bool SendData(const SendDataParams& params,
1009                         const rtc::CopyOnWriteBuffer& payload,
1010                         SendDataResult* result = NULL) = 0;
1011   // Signals when data is received (params, data, len)
1012   sigslot::signal3<const ReceiveDataParams&, const char*, size_t>
1013       SignalDataReceived;
1014   // Signal when the media channel is ready to send the stream. Arguments are:
1015   //     writable(bool)
1016   sigslot::signal1<bool> SignalReadyToSend;
1017 };
1018 
1019 }  // namespace cricket
1020 
1021 #endif  // MEDIA_BASE_MEDIA_CHANNEL_H_
1022