/*
 *  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_RTP_SENDER_H_
#define PC_RTP_SENDER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <variant>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/audio_codecs/audio_encoder_factory.h"
#include "api/crypto/frame_encryptor_interface.h"
#include "api/dtls_transport_interface.h"
#include "api/dtmf_sender_interface.h"
#include "api/encoded_audio_frame_injector_interface.h"
#include "api/encoded_video_frame_injector_interface.h"
#include "api/environment/environment.h"
#include "api/frame_transformer_interface.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/rtp_sender_interface.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/sframe/sframe_encryptor_interface.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/task_queue/task_queue_base.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "media/base/audio_source.h"
#include "media/base/codec.h"
#include "media/base/media_channel.h"
#include "pc/dtmf_sender.h"
#include "pc/encoded_audio_frame_injector.h"
#include "pc/encoded_video_frame_injector.h"
#include "pc/legacy_stats_collector_interface.h"
#include "pc/scoped_operations_batcher.h"
#include "pc/simulcast_description.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/plan_b_only.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters);

// Internal interface used by PeerConnection.
class RtpSenderInternal : public RtpSenderInterface {
 public:
  // Sets the underlying MediaEngine channel associated with this RtpSender.
  // A VoiceMediaChannel should be used for audio RtpSenders and
  // a VideoMediaChannel should be used for video RtpSenders.
  // Must call SetMediaChannel(nullptr) before the media channel is destroyed.
  virtual void SetMediaChannel(MediaSendChannelInterface* 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).
  PLAN_B_ONLY virtual void SetSsrc(uint32_t ssrc) = 0;

  // Same as `SetSsrc()` but performs the worker thread part of the work in a
  // task that the caller must run on the worker thread.
  // `layer_count` is the number of send layers that the applied local
  // description describes for this sender, i.e. the number of primary SSRCs in
  // the `StreamParams` for the stream the sender is being attached to. This is
  // the same value that the media channel derives its encodings from (see
  // `CreateRtpParametersWithEncodings()`), which allows the sender to
  // reconcile the encodings the application asked for with what was negotiated
  // without querying the media channel. Must be 0 when `ssrc` is 0.
  [[nodiscard]] virtual ScopedOperationsBatcher::BatchTaskWithFinalizer
  SetSsrcTask(uint32_t ssrc, size_t layer_count) = 0;

  virtual void set_stream_ids(const std::vector<std::string>& stream_ids) = 0;
  virtual void set_init_send_encodings(
      const std::vector<RtpEncodingParameters>& init_send_encodings) = 0;
  virtual void set_transport(
      scoped_refptr<DtlsTransportInterface> dtls_transport) = 0;

  virtual void Stop() = 0;

  // Cleans up the state on the signaling thread, as `Stop()` does, but does
  // not perform the worker thread cleanup directly. Instead, returns a task
  // that the caller must invoke on the worker thread to perform that work.
  // Note that if no worker thread needs to be done, the retuned task will be
  // empty.
  virtual absl::AnyInvocable<void() &&> DetachTrackAndGetStopTask() = 0;

  // `GetParameters` and `SetParameters` operate with a transactional model.
  // Allow access to get/set parameters without invalidating transaction id.
  virtual RtpParameters GetParametersInternal(bool may_use_cache,
                                              bool with_all_layers) const = 0;
  virtual RTCError SetParametersInternal(const RtpParameters& parameters,
                                         SetParametersCallback,
                                         bool blocking) = 0;
  virtual void SetCachedParameters(std::optional<RtpParameters> parameters) = 0;

  // GetParameters and SetParameters will remove deactivated simulcast layers
  // and restore them on SetParameters. This is probably a Bad Idea, but we
  // do not know who depends on this behavior
  virtual RtpParameters GetParametersInternalWithAllLayers() const = 0;
  virtual RTCError SetParametersInternalWithAllLayers(
      const RtpParameters& parameters) = 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;

  // Disables the layers identified by the specified RIDs.
  // If the specified list is empty, this is a no-op.
  virtual RTCError DisableEncodingLayers(
      const std::vector<std::string>& rid) = 0;

  // Used by the owning transceiver to inform the sender on the currently
  // selected codecs.
  virtual void SetSendCodecs(std::vector<Codec> send_codecs) = 0;
  virtual std::vector<Codec> GetSendCodecs() const = 0;

  virtual void NotifyFirstPacketSent() = 0;
  virtual void OnParametersChanged() = 0;
};

// Shared implementation for RtpSenderInternal interface.
class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
 public:
  class SetStreamsObserver {
   public:
    virtual ~SetStreamsObserver() = default;
    virtual void OnSetStreams() = 0;
  };

  ~RtpSenderBase() override;

  // Sets the underlying MediaEngine channel associated with this RtpSender.
  // A VoiceMediaChannel should be used for audio RtpSenders and
  // a VideoMediaChannel should be used for video RtpSenders.
  // Must call SetMediaChannel(nullptr) before the media channel is destroyed.
  void SetMediaChannel(MediaSendChannelInterface* media_channel) override;

  bool SetTrack(MediaStreamTrackInterface* track) override;
  scoped_refptr<MediaStreamTrackInterface> track() const override {
    RTC_DCHECK_RUN_ON(signaling_thread_);
    return frame_injector_ ? nullptr : track_;
  }

  MediaType media_type() const final { return media_type_; }

  RtpParameters GetParameters() const override;
  RTCError SetParameters(const RtpParameters& parameters) override;
  void SetParametersAsync(const RtpParameters& parameters,
                          SetParametersCallback callback) override;

  // `GetParameters` and `SetParameters` operate with a transactional model.
  // Allow access to get/set parameters without invalidating transaction id.
  RtpParameters GetParametersInternal(
      bool may_use_cache = true,
      bool with_all_layers = false) const override;
  RTCError SetParametersInternal(const RtpParameters& parameters,
                                 SetParametersCallback callback = nullptr,
                                 bool blocking = true) override;
  void SetCachedParameters(std::optional<RtpParameters> parameters) override;
  RTCError CheckSetParameters(const RtpParameters& parameters);
  RtpParameters GetParametersInternalWithAllLayers() const override;
  RTCError SetParametersInternalWithAllLayers(
      const RtpParameters& parameters) override;
  std::optional<RTCError> ValidateAndMaybeUpdateInitParameters(
      const RtpParameters& parameters) RTC_RUN_ON(signaling_thread_);

  // 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).
  PLAN_B_ONLY void SetSsrc(uint32_t ssrc) override;
  ScopedOperationsBatcher::BatchTaskWithFinalizer SetSsrcTask(
      uint32_t ssrc,
      size_t layer_count) override;

  uint32_t ssrc() const override {
    RTC_DCHECK_RUN_ON(signaling_thread_);
    return ssrc_;
  }

  std::vector<std::string> stream_ids() const override {
    RTC_DCHECK_RUN_ON(signaling_thread_);
    return stream_ids_;
  }

  // Set stream ids, eliminating duplicates in the process.
  void set_stream_ids(const std::vector<std::string>& stream_ids) override;
  void SetStreams(const std::vector<std::string>& stream_ids) override;

  std::string id() const override { return id_; }

  void set_init_send_encodings(
      const std::vector<RtpEncodingParameters>& init_send_encodings) override {
    init_parameters_.encodings = init_send_encodings;
  }
  std::vector<RtpEncodingParameters> init_send_encodings() const override {
    RTC_DCHECK_RUN_ON(signaling_thread_);
    return init_parameters_.encodings;
  }

  void set_transport(
      scoped_refptr<DtlsTransportInterface> dtls_transport) override {
    dtls_transport_ = dtls_transport;
  }
  scoped_refptr<DtlsTransportInterface> dtls_transport() const override {
    RTC_DCHECK_RUN_ON(signaling_thread_);
    return dtls_transport_;
  }

  void SetFrameEncryptor(
      scoped_refptr<FrameEncryptorInterface> frame_encryptor) override;

  scoped_refptr<FrameEncryptorInterface> GetFrameEncryptor() const override {
    return frame_encryptor_;
  }

  void Stop() override;
  absl::AnyInvocable<void() &&> DetachTrackAndGetStopTask() override;

  // 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.
  int AttachmentId() const override { return attachment_id_; }

  // Disables the layers identified by the specified RIDs.
  // If the specified list is empty, this is a no-op.
  RTCError DisableEncodingLayers(const std::vector<std::string>& rid) override;

  void SetFrameTransformer(
      scoped_refptr<FrameTransformerInterface> frame_transformer) override;

  scoped_refptr<EncodedVideoFrameInjectorInterface>
  CreateEncodedVideoFrameInjector(
      KeyFrameCallback keyframe_callback,
      BitrateInfoCallback bitrate_callback) override;

  scoped_refptr<EncodedAudioFrameInjectorInterface>
  CreateEncodedAudioFrameInjector(
      TargetBitrateCallback bitrate_callback) override;

  RTCErrorOr<scoped_refptr<SframeEncryptorInterface>>
  CreateSframeEncryptorOrError(const SframeEncryptorInit& options) override;

  void SetEncoderSelector(
      std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
          encoder_selector) override;

  void SetEncoderSelector(
      scoped_refptr<VideoEncoderFactory::EncoderSelectorInterface>
          encoder_selector) override;

  void SetEncoderSelectorOnChannel();

  void SetSendCodecs(std::vector<Codec> send_codecs) override {
    send_codecs_ = send_codecs;
  }
  std::vector<Codec> GetSendCodecs() const override { return send_codecs_; }

  void NotifyFirstPacketSent() override;
  void OnParametersChanged() override;
  void SetObserver(RtpSenderObserverInterface* observer) override;

 protected:
  void InvalidateCache() {
    RTC_DCHECK_RUN_ON(signaling_thread_);
    cached_parameters_.reset();
  }

  // If `set_streams_observer` is not null, it is invoked when SetStreams()
  // is called. `set_streams_observer` is not owned by this object. If not
  // null, it must be valid at least until this sender becomes stopped.
  RtpSenderBase(const Environment& env,
                Thread* signaling_thread,
                Thread* worker_thread,
                absl::string_view id,
                MediaType media_type,
                SetStreamsObserver* set_streams_observer,
                absl::AnyInvocable<RTCError()> enable_sframe_at_owner,
                MediaSendChannelInterface* media_channel,
                std::vector<std::string> stream_ids,
                std::vector<RtpEncodingParameters> init_send_encodings,
                std::vector<Codec> send_codecs);

  // TODO(bugs.webrtc.org/8694): Since SSRC == 0 is technically valid, figure
  // out some other way to test if we have a valid SSRC.
  bool can_send_track() const RTC_RUN_ON(signaling_thread_) {
    return track_ && ssrc_;
  }

  virtual std::string track_kind() const = 0;

  // Enable sending on the media channel.
  virtual void SetSend() = 0;
  // Disable sending on the media channel.
  virtual void ClearSend() = 0;
  virtual void ClearSend_w(uint32_t ssrc) RTC_RUN_ON(worker_thread_) = 0;

  // Template method pattern to allow subclasses to add custom behavior for
  // when tracks are attached, detached, and for adding tracks to statistics.
  virtual void AttachTrack() RTC_RUN_ON(signaling_thread_) {}
  virtual void DetachTrack() RTC_RUN_ON(signaling_thread_) {}
  virtual void AddTrackToStats() RTC_RUN_ON(signaling_thread_) {}
  virtual void RemoveTrackFromStats() RTC_RUN_ON(signaling_thread_) {}

  // Special case for downstream code that calls into this code with a
  // configuration where the signaling, worker and network threads are all
  // configured to be the same thread.
  RTCError SetParametersInternalWorkaround(const RtpParameters& parameters);

  // Helper function to extract the factory override from the injector.
  // At least one of the returned value is nullptr, both if no injetor is set.
  // Returns what CreateEncoderFactory() would return when called on the
  // injector.
  std::tuple<std::unique_ptr<VideoEncoderFactory>,
             scoped_refptr<AudioEncoderFactory>>
  MaybeCreateFactoryOverride();
  void ClearFrameInjector();

  // Applies the encodings and degradation preference the application
  // configured before negotiation to the send stream for `ssrc`, and clears
  // them. A nullopt `ssrc` means that there is no send stream to apply them
  // to. Returns the parameters the media channel ended up with, or nullopt if
  // the media channel was left untouched.
  std::optional<RtpParameters> ApplyInitParameters_w(
      std::optional<uint32_t> ssrc) RTC_RUN_ON(worker_thread_);

  const Environment env_;
  TaskQueueBase* const signaling_thread_;
  Thread* const worker_thread_;
  // TODO(tommi): The type for ssrc_ should be `std::optional<uint32_t>`
  // since 0 is a legal SSRC value.
  uint32_t ssrc_ RTC_GUARDED_BY(signaling_thread_) = 0;
  bool stopped_ RTC_GUARDED_BY(signaling_thread_) = false;
  int attachment_id_ = 0;
  const std::string id_;
  const MediaType media_type_;

  std::vector<std::string> stream_ids_;
  RtpParameters init_parameters_;
  mutable std::optional<RtpParameters> cached_parameters_
      RTC_GUARDED_BY(signaling_thread_);
  std::vector<Codec> send_codecs_;

  // TODO(tommi): Several member variables in this class (ssrc_, stopped_, etc)
  // are accessed from more than one thread without a guard or lock. Internally
  // there are also several Invoke()s that we could remove since the upstream
  // code may already be performing several operations on the worker thread. Add
  // RTC_GUARDED_BY(worker_thread_).
  MediaSendChannelInterface* media_channel_ RTC_GUARDED_BY(worker_thread_) =
      nullptr;
  // Apply RTC_GUARDED_BY(signaling_thread_) when not accessed from worker.
  scoped_refptr<MediaStreamTrackInterface> track_;

  scoped_refptr<DtlsTransportInterface> dtls_transport_;
  // Apply RTC_GUARDED_BY(worker_thread_) when no longer accessed from unknown
  // threads. Alternatively make const.
  scoped_refptr<FrameEncryptorInterface> frame_encryptor_;
  // `last_transaction_id_` is used to verify that `SetParameters` is receiving
  // the parameters object that was last returned from `GetParameters`.
  // As such, it is used for internal verification and is not observable by the
  // the client. It is marked as mutable to enable `GetParameters` to be a
  // const method.
  mutable std::optional<std::string> last_transaction_id_
      RTC_GUARDED_BY(signaling_thread_);
  std::vector<std::string> disabled_rids_;

  SetStreamsObserver* const set_streams_observer_ = nullptr;
  RtpSenderObserverInterface* observer_ RTC_GUARDED_BY(signaling_thread_) =
      nullptr;
  bool sent_first_packet_ = false;

  using FrameInjector =
      std::optional<std::variant<scoped_refptr<EncodedVideoFrameInjector>,
                                 scoped_refptr<EncodedAudioFrameInjector>>>;
  FrameInjector frame_injector_ RTC_GUARDED_BY(signaling_thread_);

  scoped_refptr<FrameTransformerInterface> frame_transformer_;
  scoped_refptr<VideoEncoderFactory::EncoderSelectorInterface>
      encoder_selector_;

  scoped_refptr<PendingTaskSafetyFlag> worker_safety_;
  ScopedTaskSafety signaling_safety_;

  absl::AnyInvocable<RTCError()> enable_sframe_at_owner_
      RTC_GUARDED_BY(signaling_thread_);
};

// 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 AudioSource {
 public:
  LocalAudioSinkAdapter();
  ~LocalAudioSinkAdapter() override;

 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,
              std::optional<int64_t> absolute_capture_timestamp_ms) override;

  // 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 {
    OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
           number_of_frames,
           /*absolute_capture_timestamp_ms=*/std::nullopt);
  }

  // AudioSinkInterface implementation.
  int NumPreferredChannels() const override { return num_preferred_channels_; }

  // webrtc::AudioSource implementation.
  void SetSink(AudioSource::Sink* sink) override;

  AudioSource::Sink* sink_;
  // Critical section protecting `sink_`.
  Mutex lock_;
  int num_preferred_channels_ = -1;
};

class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase {
 public:
  // Construct an RtpSender for audio with the given sender ID.
  // The sender is initialized with no track to send and no associated streams.
  // StatsCollector provided so that Add/RemoveLocalAudioTrack can be called
  // at the appropriate times.
  // If `set_streams_observer` is not null, it is invoked when SetStreams()
  // is called. `set_streams_observer` is not owned by this object. If not
  // null, it must be valid at least until this sender becomes stopped.
  static scoped_refptr<AudioRtpSender> Create(
      const Environment& env,
      Thread* signaling_thread,
      Thread* worker_thread,
      absl::string_view id,
      LegacyStatsCollectorInterface* stats,
      SetStreamsObserver* set_streams_observer,
      absl::AnyInvocable<RTCError()> enable_sframe_at_owner,
      MediaSendChannelInterface* media_channel,
      std::vector<std::string> stream_ids = {},
      std::vector<RtpEncodingParameters> init_send_encodings =
          std::vector<RtpEncodingParameters>(1),
      std::vector<Codec> send_codecs = {});
  ~AudioRtpSender() override;

  // DtmfSenderProvider implementation.
  bool CanInsertDtmf() override;
  bool InsertDtmf(int code, int duration) override;

  // ObserverInterface implementation.
  void OnChanged() override;

  std::string track_kind() const override {
    return MediaStreamTrackInterface::kAudioKind;
  }

  scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override;
  RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override;

 protected:
  AudioRtpSender(const Environment& env,
                 Thread* signaling_thread,
                 Thread* worker_thread,
                 absl::string_view id,
                 LegacyStatsCollectorInterface* legacy_stats,
                 SetStreamsObserver* set_streams_observer,
                 absl::AnyInvocable<RTCError()> enable_sframe_at_owner,
                 MediaSendChannelInterface* media_channel,
                 std::vector<std::string> stream_ids,
                 std::vector<RtpEncodingParameters> init_send_encodings,
                 std::vector<Codec> send_codecs);

  void SetSend() override;
  void ClearSend() override;
  void ClearSend_w(uint32_t ssrc) RTC_RUN_ON(worker_thread_) override;

  // Hooks to allow custom logic when tracks are attached and detached.
  void AttachTrack() RTC_RUN_ON(signaling_thread_) override;
  void DetachTrack() RTC_RUN_ON(signaling_thread_) override;
  void AddTrackToStats() RTC_RUN_ON(signaling_thread_) override;
  void RemoveTrackFromStats() RTC_RUN_ON(signaling_thread_) override;

 private:
  VoiceMediaSendChannelInterface* voice_media_channel()
      RTC_RUN_ON(worker_thread_) {
    return media_channel_->AsVoiceSendChannel();
  }
  scoped_refptr<AudioTrackInterface> audio_track() const
      RTC_RUN_ON(signaling_thread_) {
    return scoped_refptr<AudioTrackInterface>(
        static_cast<AudioTrackInterface*>(track_.get()));
  }

  LegacyStatsCollectorInterface* const legacy_stats_ = nullptr;
  const scoped_refptr<DtmfSender> dtmf_sender_;
  const scoped_refptr<DtmfSenderInterface> dtmf_sender_proxy_;
  bool cached_track_enabled_ = false;

  // Used to pass the data callback from the `track_` to the other end of
  // webrtc::AudioSource.
  const std::unique_ptr<LocalAudioSinkAdapter> sink_adapter_;
};

class VideoRtpSender : public RtpSenderBase {
 public:
  // Construct an RtpSender for video with the given sender ID.
  // The sender is initialized with no track to send and no associated streams.
  // If `set_streams_observer` is not null, it is invoked when SetStreams()
  // is called. `set_streams_observer` is not owned by this object. If not
  // null, it must be valid at least until this sender becomes stopped.
  // `initial_simulcast_layers` filters the initial encodings by RID and sets
  // their active state. Works with `simulcast_rejected` to determine the final
  // set of layers.
  static scoped_refptr<VideoRtpSender> Create(
      const Environment& env,
      Thread* signaling_thread,
      Thread* worker_thread,
      absl::string_view id,
      SetStreamsObserver* set_streams_observer,
      absl::AnyInvocable<RTCError()> enable_sframe_at_owner,
      MediaSendChannelInterface* media_channel,
      const std::vector<RtpEncodingParameters>& init_send_encodings,
      bool simulcast_rejected,
      const std::vector<SimulcastLayer>& initial_simulcast_layers,
      std::vector<std::string> stream_ids = {},
      std::vector<Codec> send_codecs = {});
  ~VideoRtpSender() override;

  // ObserverInterface implementation
  void OnChanged() override;

  std::string track_kind() const override {
    return MediaStreamTrackInterface::kVideoKind;
  }

  scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override;
  RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override;

 protected:
  VideoRtpSender(const Environment& env,
                 Thread* signaling_thread,
                 Thread* worker_thread,
                 absl::string_view id,
                 SetStreamsObserver* set_streams_observer,
                 absl::AnyInvocable<RTCError()> enable_sframe_at_owner,
                 MediaSendChannelInterface* media_channel,
                 const std::vector<RtpEncodingParameters>& init_send_encodings,
                 bool simulcast_rejected,
                 const std::vector<SimulcastLayer>& initial_simulcast_layers,
                 std::vector<std::string> stream_ids,
                 std::vector<Codec> send_codecs);

  void SetSend() override;
  void ClearSend() override;
  void ClearSend_w(uint32_t ssrc) RTC_RUN_ON(worker_thread_) override;

  // Hook to allow custom logic when tracks are attached.
  void AttachTrack() RTC_RUN_ON(signaling_thread_) override;

 private:
  VideoMediaSendChannelInterface* video_media_channel()
      RTC_RUN_ON(worker_thread_) {
    return media_channel_->AsVideoSendChannel();
  }
  scoped_refptr<VideoTrackInterface> video_track() const
      RTC_RUN_ON(signaling_thread_) {
    return scoped_refptr<VideoTrackInterface>(
        static_cast<VideoTrackInterface*>(track_.get()));
  }

  VideoTrackInterface::ContentHint cached_track_content_hint_ =
      VideoTrackInterface::ContentHint::kNone;
};

}  // namespace webrtc

#endif  // PC_RTP_SENDER_H_
