tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

media_channel_impl.cc (9471B)


      1 /*
      2 *  Copyright (c) 2018 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 #include "media/base/media_channel_impl.h"
     12 
     13 #include <cstdint>
     14 #include <map>
     15 #include <string>
     16 #include <utility>
     17 
     18 #include "absl/functional/any_invocable.h"
     19 #include "api/array_view.h"
     20 #include "api/audio_options.h"
     21 #include "api/call/transport.h"
     22 #include "api/media_stream_interface.h"
     23 #include "api/rtc_error.h"
     24 #include "api/rtp_sender_interface.h"
     25 #include "api/sequence_checker.h"
     26 #include "api/task_queue/pending_task_safety_flag.h"
     27 #include "api/task_queue/task_queue_base.h"
     28 #include "media/base/media_channel.h"
     29 #include "media/base/rtp_utils.h"
     30 #include "rtc_base/async_packet_socket.h"
     31 #include "rtc_base/checks.h"
     32 #include "rtc_base/copy_on_write_buffer.h"
     33 #include "rtc_base/dscp.h"
     34 #include "rtc_base/socket.h"
     35 
     36 namespace webrtc {
     37 
     38 VideoOptions::VideoOptions()
     39    : content_hint(VideoTrackInterface::ContentHint::kNone) {}
     40 VideoOptions::~VideoOptions() = default;
     41 
     42 MediaChannelUtil::MediaChannelUtil(TaskQueueBase* network_thread,
     43                                   bool enable_dscp)
     44    : transport_(network_thread, enable_dscp) {}
     45 
     46 MediaChannelUtil::~MediaChannelUtil() {}
     47 
     48 void MediaChannelUtil::SetInterface(MediaChannelNetworkInterface* iface) {
     49  transport_.SetInterface(iface);
     50 }
     51 
     52 int MediaChannelUtil::GetRtpSendTimeExtnId() const {
     53  return -1;
     54 }
     55 
     56 bool MediaChannelUtil::SendPacket(CopyOnWriteBuffer* packet,
     57                                  const AsyncSocketPacketOptions& options) {
     58  return transport_.DoSendPacket(packet, false, options);
     59 }
     60 
     61 bool MediaChannelUtil::SendRtcp(CopyOnWriteBuffer* packet,
     62                                const AsyncSocketPacketOptions& options) {
     63  return transport_.DoSendPacket(packet, true, options);
     64 }
     65 
     66 int MediaChannelUtil::SetOption(MediaChannelNetworkInterface::SocketType type,
     67                                Socket::Option opt,
     68                                int option) {
     69  return transport_.SetOption(type, opt, option);
     70 }
     71 
     72 // Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
     73 // Set to true if it's allowed to mix one- and two-byte RTP header extensions
     74 // in the same stream. The setter and getter must only be called from
     75 // worker_thread.
     76 void MediaChannelUtil::SetExtmapAllowMixed(bool extmap_allow_mixed) {
     77  extmap_allow_mixed_ = extmap_allow_mixed;
     78 }
     79 
     80 bool MediaChannelUtil::ExtmapAllowMixed() const {
     81  return extmap_allow_mixed_;
     82 }
     83 
     84 bool MediaChannelUtil::HasNetworkInterface() const {
     85  return transport_.HasNetworkInterface();
     86 }
     87 
     88 bool MediaChannelUtil::DscpEnabled() const {
     89  return transport_.DscpEnabled();
     90 }
     91 
     92 void MediaChannelUtil::SetPreferredDscp(DiffServCodePoint new_dscp) {
     93  transport_.SetPreferredDscp(new_dscp);
     94 }
     95 
     96 MediaSenderInfo::MediaSenderInfo() = default;
     97 MediaSenderInfo::~MediaSenderInfo() = default;
     98 
     99 MediaReceiverInfo::MediaReceiverInfo() = default;
    100 MediaReceiverInfo::~MediaReceiverInfo() = default;
    101 
    102 VoiceSenderInfo::VoiceSenderInfo() = default;
    103 VoiceSenderInfo::~VoiceSenderInfo() = default;
    104 
    105 VoiceReceiverInfo::VoiceReceiverInfo() = default;
    106 VoiceReceiverInfo::~VoiceReceiverInfo() = default;
    107 
    108 VideoSenderInfo::VideoSenderInfo() = default;
    109 VideoSenderInfo::~VideoSenderInfo() = default;
    110 
    111 VideoReceiverInfo::VideoReceiverInfo() = default;
    112 VideoReceiverInfo::~VideoReceiverInfo() = default;
    113 
    114 VoiceMediaInfo::VoiceMediaInfo() = default;
    115 VoiceMediaInfo::~VoiceMediaInfo() = default;
    116 
    117 VideoMediaInfo::VideoMediaInfo() = default;
    118 VideoMediaInfo::~VideoMediaInfo() = default;
    119 
    120 VideoMediaSendInfo::VideoMediaSendInfo() = default;
    121 VideoMediaSendInfo::~VideoMediaSendInfo() = default;
    122 
    123 VoiceMediaSendInfo::VoiceMediaSendInfo() = default;
    124 VoiceMediaSendInfo::~VoiceMediaSendInfo() = default;
    125 
    126 VideoMediaReceiveInfo::VideoMediaReceiveInfo() = default;
    127 VideoMediaReceiveInfo::~VideoMediaReceiveInfo() = default;
    128 
    129 VoiceMediaReceiveInfo::VoiceMediaReceiveInfo() = default;
    130 VoiceMediaReceiveInfo::~VoiceMediaReceiveInfo() = default;
    131 
    132 AudioSenderParameter::AudioSenderParameter() = default;
    133 AudioSenderParameter::~AudioSenderParameter() = default;
    134 
    135 std::map<std::string, std::string> AudioSenderParameter::ToStringMap() const {
    136  auto params = SenderParameters::ToStringMap();
    137  params["options"] = options.ToString();
    138  return params;
    139 }
    140 
    141 VideoSenderParameters::VideoSenderParameters() = default;
    142 VideoSenderParameters::~VideoSenderParameters() = default;
    143 
    144 std::map<std::string, std::string> VideoSenderParameters::ToStringMap() const {
    145  auto params = SenderParameters::ToStringMap();
    146  params["conference_mode"] = (conference_mode ? "yes" : "no");
    147  return params;
    148 }
    149 
    150 // --------------------- MediaChannelUtil::TransportForMediaChannels -----
    151 
    152 MediaChannelUtil::TransportForMediaChannels::TransportForMediaChannels(
    153    TaskQueueBase* network_thread,
    154    bool enable_dscp)
    155    : network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()),
    156      network_thread_(network_thread),
    157 
    158      enable_dscp_(enable_dscp) {}
    159 
    160 MediaChannelUtil::TransportForMediaChannels::~TransportForMediaChannels() {
    161  RTC_DCHECK(!network_interface_);
    162 }
    163 
    164 AsyncSocketPacketOptions
    165 MediaChannelUtil::TransportForMediaChannels::TranslatePacketOptions(
    166    const PacketOptions& options) {
    167  AsyncSocketPacketOptions rtc_options;
    168  rtc_options.packet_id = options.packet_id;
    169  if (DscpEnabled()) {
    170    rtc_options.dscp = PreferredDscp();
    171  }
    172  rtc_options.info_signaled_after_sent.included_in_feedback =
    173      options.included_in_feedback;
    174  rtc_options.info_signaled_after_sent.included_in_allocation =
    175      options.included_in_allocation;
    176  rtc_options.info_signaled_after_sent.is_media = options.is_media;
    177  rtc_options.ect_1 = options.send_as_ect1;
    178  rtc_options.batchable = options.batchable;
    179  rtc_options.last_packet_in_batch = options.last_packet_in_batch;
    180  return rtc_options;
    181 }
    182 
    183 bool MediaChannelUtil::TransportForMediaChannels::SendRtcp(
    184    ArrayView<const uint8_t> packet,
    185    const PacketOptions& options) {
    186  auto send = [this, packet = CopyOnWriteBuffer(packet, kMaxRtpPacketLen),
    187               options]() mutable {
    188    DoSendPacket(&packet, true, TranslatePacketOptions(options));
    189  };
    190 
    191  if (network_thread_->IsCurrent()) {
    192    send();
    193  } else {
    194    network_thread_->PostTask(SafeTask(network_safety_, std::move(send)));
    195  }
    196  return true;
    197 }
    198 
    199 bool MediaChannelUtil::TransportForMediaChannels::SendRtp(
    200    ArrayView<const uint8_t> packet,
    201    const PacketOptions& options) {
    202  auto send = [this, packet = CopyOnWriteBuffer(packet, kMaxRtpPacketLen),
    203               options]() mutable {
    204    DoSendPacket(&packet, false, TranslatePacketOptions(options));
    205  };
    206 
    207  // TODO(bugs.webrtc.org/11993): ModuleRtpRtcpImpl2 and related classes (e.g.
    208  // RTCPSender) aren't aware of the network thread and may trigger calls to
    209  // this function from different threads. Update those classes to keep
    210  // network traffic on the network thread.
    211  if (network_thread_->IsCurrent()) {
    212    send();
    213  } else {
    214    network_thread_->PostTask(SafeTask(network_safety_, std::move(send)));
    215  }
    216  return true;
    217 }
    218 
    219 void MediaChannelUtil::TransportForMediaChannels::SetInterface(
    220    MediaChannelNetworkInterface* iface) {
    221  RTC_DCHECK_RUN_ON(network_thread_);
    222  iface ? network_safety_->SetAlive() : network_safety_->SetNotAlive();
    223  network_interface_ = iface;
    224  UpdateDscp();
    225 }
    226 
    227 void MediaChannelUtil::TransportForMediaChannels::UpdateDscp() {
    228  DiffServCodePoint value = enable_dscp_ ? preferred_dscp_ : DSCP_DEFAULT;
    229  int ret = SetOptionLocked(MediaChannelNetworkInterface::ST_RTP,
    230                            Socket::OPT_DSCP, value);
    231  if (ret == 0)
    232    SetOptionLocked(MediaChannelNetworkInterface::ST_RTCP, Socket::OPT_DSCP,
    233                    value);
    234 }
    235 
    236 bool MediaChannelUtil::TransportForMediaChannels::DoSendPacket(
    237    CopyOnWriteBuffer* packet,
    238    bool rtcp,
    239    const AsyncSocketPacketOptions& options) {
    240  RTC_DCHECK_RUN_ON(network_thread_);
    241  if (!network_interface_)
    242    return false;
    243 
    244  return (!rtcp) ? network_interface_->SendPacket(packet, options)
    245                 : network_interface_->SendRtcp(packet, options);
    246 }
    247 
    248 int MediaChannelUtil::TransportForMediaChannels::SetOption(
    249    MediaChannelNetworkInterface::SocketType type,
    250    Socket::Option opt,
    251    int option) {
    252  RTC_DCHECK_RUN_ON(network_thread_);
    253  return SetOptionLocked(type, opt, option);
    254 }
    255 
    256 int MediaChannelUtil::TransportForMediaChannels::SetOptionLocked(
    257    MediaChannelNetworkInterface::SocketType type,
    258    Socket::Option opt,
    259    int option) {
    260  if (!network_interface_)
    261    return -1;
    262  return network_interface_->SetOption(type, opt, option);
    263 }
    264 
    265 void MediaChannelUtil::TransportForMediaChannels::SetPreferredDscp(
    266    DiffServCodePoint new_dscp) {
    267  if (!network_thread_->IsCurrent()) {
    268    // This is currently the common path as the derived channel classes
    269    // get called on the worker thread. There are still some tests though
    270    // that call directly on the network thread.
    271    network_thread_->PostTask(SafeTask(
    272        network_safety_, [this, new_dscp]() { SetPreferredDscp(new_dscp); }));
    273    return;
    274  }
    275 
    276  RTC_DCHECK_RUN_ON(network_thread_);
    277  if (new_dscp == preferred_dscp_)
    278    return;
    279 
    280  preferred_dscp_ = new_dscp;
    281  UpdateDscp();
    282 }
    283 
    284 }  // namespace webrtc