audio_egress.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (c) 2020 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. #ifndef AUDIO_VOIP_AUDIO_EGRESS_H_
  11. #define AUDIO_VOIP_AUDIO_EGRESS_H_
  12. #include <memory>
  13. #include <string>
  14. #include "api/audio_codecs/audio_format.h"
  15. #include "api/task_queue/task_queue_factory.h"
  16. #include "audio/utility/audio_frame_operations.h"
  17. #include "call/audio_sender.h"
  18. #include "modules/audio_coding/include/audio_coding_module.h"
  19. #include "modules/rtp_rtcp/include/report_block_data.h"
  20. #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
  21. #include "modules/rtp_rtcp/source/rtp_sender_audio.h"
  22. #include "rtc_base/task_queue.h"
  23. #include "rtc_base/thread_checker.h"
  24. #include "rtc_base/time_utils.h"
  25. namespace webrtc {
  26. // AudioEgress receives input samples from AudioDeviceModule via
  27. // AudioTransportImpl through AudioSender interface. Once it encodes the sample
  28. // via selected encoder through AudioPacketizationCallback interface, the
  29. // encoded payload will be packetized by the RTP stack, resulting in ready to
  30. // send RTP packet to remote endpoint.
  31. //
  32. // TaskQueue is used to encode and send RTP asynchrounously as some OS platform
  33. // uses the same thread for both audio input and output sample deliveries which
  34. // can affect audio quality.
  35. //
  36. // Note that this class is originally based on ChannelSend in
  37. // audio/channel_send.cc with non-audio related logic trimmed as aimed for
  38. // smaller footprint.
  39. class AudioEgress : public AudioSender, public AudioPacketizationCallback {
  40. public:
  41. AudioEgress(RtpRtcpInterface* rtp_rtcp,
  42. Clock* clock,
  43. TaskQueueFactory* task_queue_factory);
  44. ~AudioEgress() override;
  45. // Set the encoder format and payload type for AudioCodingModule.
  46. // It's possible to change the encoder type during its active usage.
  47. // |payload_type| must be the type that is negotiated with peer through
  48. // offer/answer.
  49. void SetEncoder(int payload_type,
  50. const SdpAudioFormat& encoder_format,
  51. std::unique_ptr<AudioEncoder> encoder);
  52. // Start or stop sending operation of AudioEgress. This will start/stop
  53. // the RTP stack also causes encoder queue thread to start/stop
  54. // processing input audio samples.
  55. void StartSend();
  56. void StopSend();
  57. // Query the state of the RTP stack. This returns true if StartSend()
  58. // called and false if StopSend() is called.
  59. bool IsSending() const;
  60. // Enable or disable Mute state.
  61. void SetMute(bool mute);
  62. // Retrieve current encoder format info. This returns encoder format set
  63. // by SetEncoder() and if encoder is not set, this will return nullopt.
  64. absl::optional<SdpAudioFormat> GetEncoderFormat() const {
  65. rtc::CritScope lock(&lock_);
  66. return encoder_format_;
  67. }
  68. // Register the payload type and sample rate for DTMF (RFC 4733) payload.
  69. void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz);
  70. // Send DTMF named event as specified by
  71. // https://tools.ietf.org/html/rfc4733#section-3.2
  72. // |duration_ms| specifies the duration of DTMF packets that will be emitted
  73. // in place of real RTP packets instead.
  74. // This will return true when requested dtmf event is successfully scheduled
  75. // otherwise false when the dtmf queue reached maximum of 20 events.
  76. bool SendTelephoneEvent(int dtmf_event, int duration_ms);
  77. // Implementation of AudioSender interface.
  78. void SendAudioData(std::unique_ptr<AudioFrame> audio_frame) override;
  79. // Implementation of AudioPacketizationCallback interface.
  80. int32_t SendData(AudioFrameType frame_type,
  81. uint8_t payload_type,
  82. uint32_t timestamp,
  83. const uint8_t* payload_data,
  84. size_t payload_size) override;
  85. private:
  86. void SetEncoderFormat(const SdpAudioFormat& encoder_format) {
  87. rtc::CritScope lock(&lock_);
  88. encoder_format_ = encoder_format;
  89. }
  90. rtc::CriticalSection lock_;
  91. // Current encoder format selected by caller.
  92. absl::optional<SdpAudioFormat> encoder_format_ RTC_GUARDED_BY(lock_);
  93. // Synchronization is handled internally by RtpRtcp.
  94. RtpRtcpInterface* const rtp_rtcp_;
  95. // Synchronization is handled internally by RTPSenderAudio.
  96. RTPSenderAudio rtp_sender_audio_;
  97. // Synchronization is handled internally by AudioCodingModule.
  98. const std::unique_ptr<AudioCodingModule> audio_coding_;
  99. // Struct that holds all variables used by encoder task queue.
  100. struct EncoderContext {
  101. // Offset used to mark rtp timestamp in sample rate unit in
  102. // newly received audio frame from AudioTransport.
  103. uint32_t frame_rtp_timestamp_ = 0;
  104. // Flag to track mute state from caller. |previously_muted_| is used to
  105. // track previous state as part of input to AudioFrameOperations::Mute
  106. // to implement fading effect when (un)mute is invoked.
  107. bool mute_ = false;
  108. bool previously_muted_ = false;
  109. };
  110. EncoderContext encoder_context_ RTC_GUARDED_BY(encoder_queue_);
  111. // Defined last to ensure that there are no running tasks when the other
  112. // members are destroyed.
  113. rtc::TaskQueue encoder_queue_;
  114. };
  115. } // namespace webrtc
  116. #endif // AUDIO_VOIP_AUDIO_EGRESS_H_