text: /*
   *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
   *
   *  Use of this source code is governed by a BSD-style license
   *  that can be found in the LICENSE file in the root of the source
   *  tree. An additional intellectual property rights grant can be found
   *  in the file PATENTS.  All contributing project authors may
   *  be found in the AUTHORS file in the root of the source tree.
   */
  
  // This file contains classes that implement RtpSenderInterface.
  // An RtpSender associates a MediaStreamTrackInterface with an underlying
  // transport (provided by AudioProviderInterface/VideoProviderInterface)
  
  #ifndef PC_RTPSENDER_H_
  #define PC_RTPSENDER_H_
  
  #include <memory>
  #include <string>
  #include <vector>
  
  #include "api/mediastreaminterface.h"
  #include "api/rtpsenderinterface.h"
  #include "media/base/audiosource.h"
  #include "media/base/mediachannel.h"
  #include "pc/dtmfsender.h"
  #include "rtc_base/criticalsection.h"
  
  namespace webrtc {
  
  class StatsCollector;
  
  // Internal interface used by PeerConnection.
  class RtpSenderInternal : public RtpSenderInterface {
   public:
    // Sets the underlying MediaEngine channel associated with this RtpSender.
    // SetVoiceMediaChannel should be used for audio RtpSenders and
    // SetVideoMediaChannel should be used for video RtpSenders. Must call the
    // appropriate SetXxxMediaChannel(nullptr) before the media channel is
    // destroyed.
    virtual void SetVoiceMediaChannel(
        cricket::VoiceMediaChannel* voice_media_channel) = 0;
    virtual void SetVideoMediaChannel(
        cricket::VideoMediaChannel* video_media_channel) = 0;
  
    // Used to set the SSRC of the sender, once a local description has been set.
    // If |ssrc| is 0, this indiates that the sender should disconnect from the
    // underlying transport (this occurs if the sender isn't seen in a local
    // description).
    virtual void SetSsrc(uint32_t ssrc) = 0;
  
    virtual void set_stream_ids(const std::vector<std::string>& stream_ids) = 0;
  
    virtual void Stop() = 0;
  
    // Returns an ID that changes every time SetTrack() is called, but
    // otherwise remains constant. Used to generate IDs for stats.
    // The special value zero means that no track is attached.
    virtual int AttachmentId() const = 0;
  };
  
  // LocalAudioSinkAdapter receives data callback as a sink to the local
  // AudioTrack, and passes the data to the sink of AudioSource.
  class LocalAudioSinkAdapter : public AudioTrackSinkInterface,
                                public cricket::AudioSource {
   public:
    LocalAudioSinkAdapter();
    virtual ~LocalAudioSinkAdapter();
  
   private:
    // AudioSinkInterface implementation.
    void OnData(const void* audio_data,
                int bits_per_sample,
                int sample_rate,
                size_t number_of_channels,
                size_t number_of_frames) override;
  
    // cricket::AudioSource implementation.
    void SetSink(cricket::AudioSource::Sink* sink) override;
  
    cricket::AudioSource::Sink* sink_;
    // Critical section protecting |sink_|.
    rtc::CriticalSection lock_;
  };
  
  class AudioRtpSender : public DtmfProviderInterface,
                         public ObserverInterface,
                         public rtc::RefCountedObject<RtpSenderInternal> {
   public:
    // StatsCollector provided so that Add/RemoveLocalAudioTrack can be called
    // at the appropriate times.
  
    // Construct an AudioRtpSender with a null track, a single, randomly generated
    // stream id, and a randomly generated ID.
    AudioRtpSender(rtc::Thread* worker_thread, StatsCollector* stats);
  
    // Construct an AudioRtpSender with the given track and stream ids. The
    // sender ID will be set to the track's ID.
    AudioRtpSender(rtc::Thread* worker_thread,
                   rtc::scoped_refptr<AudioTrackInterface> track,
                   const std::vector<std::string>& stream_ids,
                   StatsCollector* stats);
  
    virtual ~AudioRtpSender();
  
    // DtmfSenderProvider implementation.
    bool CanInsertDtmf() override;
    bool InsertDtmf(int code, int duration) override;
    sigslot::signal0<>* GetOnDestroyedSignal() override;
  
    // ObserverInterface implementation.
    void OnChanged() override;
  
    // RtpSenderInterface implementation.
    bool SetTrack(MediaStreamTrackInterface* track) override;
    rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
      return track_;
    }
  
    uint32_t ssrc() const override { return ssrc_; }
  
    cricket::MediaType media_type() const override {
      return cricket::MEDIA_TYPE_AUDIO;
    }
  
    std::string id() const override { return id_; }
  
    std::vector<std::string> stream_ids() const override { return stream_ids_; }
  
    RtpParameters GetParameters() override;
    RTCError SetParameters(const RtpParameters& parameters) override;
  
    rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override;
  
    // RtpSenderInternal implementation.
    void SetSsrc(uint32_t ssrc) override;
  
    void set_stream_ids(const std::vector<std::string>& stream_ids) override {
      stream_ids_ = stream_ids;
    }
  
    void Stop() override;
  
    int AttachmentId() const override { return attachment_id_; }
  
    void SetVoiceMediaChannel(
        cricket::VoiceMediaChannel* voice_media_channel) override {
      media_channel_ = voice_media_channel;
    }
    void SetVideoMediaChannel(
        cricket::VideoMediaChannel* video_media_channel) override {
      RTC_NOTREACHED();
    }
  
   private:
    // TODO(nisse): Since SSRC == 0 is technically valid, figure out
    // some other way to test if we have a valid SSRC.
    bool can_send_track() const { return track_ && ssrc_; }
    // Helper function to construct options for
    // AudioProviderInterface::SetAudioSend.
    void SetAudioSend();
    // Helper function to call SetAudioSend with "stop sending" parameters.
    void ClearAudioSend();
  
    sigslot::signal0<> SignalDestroyed;
  
    rtc::Thread* const worker_thread_;
    const std::string id_;
    std::vector<std::string> stream_ids_;
    cricket::VoiceMediaChannel* media_channel_ = nullptr;
    StatsCollector* stats_;
    rtc::scoped_refptr<AudioTrackInterface> track_;
    rtc::scoped_refptr<DtmfSenderInterface> dtmf_sender_proxy_;
    absl::optional<std::string> last_transaction_id_;
    uint32_t ssrc_ = 0;
    bool cached_track_enabled_ = false;
    bool stopped_ = false;
  
    // Used to pass the data callback from the |track_| to the other end of
    // cricket::AudioSource.
    std::unique_ptr<LocalAudioSinkAdapter> sink_adapter_;
    int attachment_id_ = 0;
  };
  
  class VideoRtpSender : public ObserverInterface,
                         public rtc::RefCountedObject<RtpSenderInternal> {
   public:
    // Construct a VideoRtpSender with a null track, a single, randomly generated
    // stream id, and a randomly generated ID.
    explicit VideoRtpSender(rtc::Thread* worker_thread);
  
    // Construct a VideoRtpSender with the given track and stream ids. The
    // sender ID will be set to the track's ID.
    VideoRtpSender(rtc::Thread* worker_thread,
                   rtc::scoped_refptr<VideoTrackInterface> track,
                   const std::vector<std::string>& stream_ids);
  
    virtual ~VideoRtpSender();
  
    // ObserverInterface implementation
    void OnChanged() override;
  
    // RtpSenderInterface implementation
    bool SetTrack(MediaStreamTrackInterface* track) override;
    rtc::scoped_refptr<MediaStreamTrackInterface> track() const override {
      return track_;
    }
  
    uint32_t ssrc() const override { return ssrc_; }
  
    cricket::MediaType media_type() const override {
      return cricket::MEDIA_TYPE_VIDEO;
    }
  
    std::string id() const override { return id_; }
  
    std::vector<std::string> stream_ids() const override { return stream_ids_; }
  
    RtpParameters GetParameters() override;
    RTCError SetParameters(const RtpParameters& parameters) override;
  
    rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override;
  
    // RtpSenderInternal implementation.
    void SetSsrc(uint32_t ssrc) override;
  
    void set_stream_ids(const std::vector<std::string>& stream_ids) override {
      stream_ids_ = stream_ids;
    }
  
    void Stop() override;
    int AttachmentId() const override { return attachment_id_; }
  
    void SetVoiceMediaChannel(
        cricket::VoiceMediaChannel* voice_media_channel) override {
      RTC_NOTREACHED();
    }
    void SetVideoMediaChannel(
        cricket::VideoMediaChannel* video_media_channel) override {
      media_channel_ = video_media_channel;
    }
  
   private:
    bool can_send_track() const { return track_ && ssrc_; }
    // Helper function to construct options for
    // VideoProviderInterface::SetVideoSend.
    void SetVideoSend();
    // Helper function to call SetVideoSend with "stop sending" parameters.
    void ClearVideoSend();
  
    rtc::Thread* worker_thread_;
    const std::string id_;
    std::vector<std::string> stream_ids_;
    cricket::VideoMediaChannel* media_channel_ = nullptr;
    rtc::scoped_refptr<VideoTrackInterface> track_;
    absl::optional<std::string> last_transaction_id_;
    uint32_t ssrc_ = 0;
    VideoTrackInterface::ContentHint cached_track_content_hint_ =
        VideoTrackInterface::ContentHint::kNone;
    bool stopped_ = false;
    int attachment_id_ = 0;
  };
  
  }  // namespace webrtc
  
  #endif  // PC_RTPSENDER_H_
  