| /* |
| * Copyright (c) 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. |
| */ |
| |
| #ifndef AUDIO_AUDIO_SEND_STREAM_H_ |
| #define AUDIO_AUDIO_SEND_STREAM_H_ |
| |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "absl/functional/any_invocable.h" |
| #include "api/field_trials_view.h" |
| #include "api/sequence_checker.h" |
| #include "api/task_queue/task_queue_base.h" |
| #include "audio/audio_level.h" |
| #include "audio/channel_send.h" |
| #include "call/audio_send_stream.h" |
| #include "call/audio_state.h" |
| #include "call/bitrate_allocator.h" |
| #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" |
| #include "rtc_base/experiments/struct_parameters_parser.h" |
| #include "rtc_base/race_checker.h" |
| #include "rtc_base/synchronization/mutex.h" |
| #include "rtc_base/task_queue.h" |
| |
| namespace webrtc { |
| class RtcEventLog; |
| class RtcpRttStats; |
| class RtpTransportControllerSendInterface; |
| |
| struct AudioAllocationConfig { |
| static constexpr char kKey[] = "WebRTC-Audio-Allocation"; |
| // Field Trial configured bitrates to use as overrides over default/user |
| // configured bitrate range when audio bitrate allocation is enabled. |
| absl::optional<DataRate> min_bitrate; |
| absl::optional<DataRate> max_bitrate; |
| DataRate priority_bitrate = DataRate::Zero(); |
| // By default the priority_bitrate is compensated for packet overhead. |
| // Use this flag to configure a raw value instead. |
| absl::optional<DataRate> priority_bitrate_raw; |
| absl::optional<double> bitrate_priority; |
| |
| std::unique_ptr<StructParametersParser> Parser(); |
| explicit AudioAllocationConfig(const FieldTrialsView& field_trials); |
| }; |
| namespace internal { |
| class AudioState; |
| |
| class AudioSendStream final : public webrtc::AudioSendStream, |
| public webrtc::BitrateAllocatorObserver { |
| public: |
| AudioSendStream(Clock* clock, |
| const webrtc::AudioSendStream::Config& config, |
| const rtc::scoped_refptr<webrtc::AudioState>& audio_state, |
| TaskQueueFactory* task_queue_factory, |
| RtpTransportControllerSendInterface* rtp_transport, |
| BitrateAllocatorInterface* bitrate_allocator, |
| RtcEventLog* event_log, |
| RtcpRttStats* rtcp_rtt_stats, |
| const absl::optional<RtpState>& suspended_rtp_state, |
| const FieldTrialsView& field_trials); |
| // For unit tests, which need to supply a mock ChannelSend. |
| AudioSendStream(Clock* clock, |
| const webrtc::AudioSendStream::Config& config, |
| const rtc::scoped_refptr<webrtc::AudioState>& audio_state, |
| TaskQueueFactory* task_queue_factory, |
| RtpTransportControllerSendInterface* rtp_transport, |
| BitrateAllocatorInterface* bitrate_allocator, |
| RtcEventLog* event_log, |
| const absl::optional<RtpState>& suspended_rtp_state, |
| std::unique_ptr<voe::ChannelSendInterface> channel_send, |
| const FieldTrialsView& field_trials); |
| |
| AudioSendStream() = delete; |
| AudioSendStream(const AudioSendStream&) = delete; |
| AudioSendStream& operator=(const AudioSendStream&) = delete; |
| |
| ~AudioSendStream() override; |
| |
| // webrtc::AudioSendStream implementation. |
| const webrtc::AudioSendStream::Config& GetConfig() const override; |
| void Reconfigure(const webrtc::AudioSendStream::Config& config, |
| SetParametersCallback callback) override; |
| void Start() override; |
| void Stop() override; |
| void SendAudioData(std::unique_ptr<AudioFrame> audio_frame) override; |
| bool SendTelephoneEvent(int payload_type, |
| int payload_frequency, |
| int event, |
| int duration_ms) override; |
| void SetMuted(bool muted) override; |
| webrtc::AudioSendStream::Stats GetStats() const override; |
| webrtc::AudioSendStream::Stats GetStats( |
| bool has_remote_tracks) const override; |
| |
| void DeliverRtcp(const uint8_t* packet, size_t length); |
| |
| // Implements BitrateAllocatorObserver. |
| uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) override; |
| |
| void SetTransportOverhead(int transport_overhead_per_packet_bytes); |
| |
| RtpState GetRtpState() const; |
| const voe::ChannelSendInterface* GetChannel() const; |
| |
| // Returns combined per-packet overhead. |
| size_t TestOnlyGetPerPacketOverheadBytes() const |
| RTC_LOCKS_EXCLUDED(overhead_per_packet_lock_); |
| |
| private: |
| class TimedTransport; |
| // Constraints including overhead. |
| struct TargetAudioBitrateConstraints { |
| DataRate min; |
| DataRate max; |
| }; |
| |
| internal::AudioState* audio_state(); |
| const internal::AudioState* audio_state() const; |
| |
| void StoreEncoderProperties(int sample_rate_hz, size_t num_channels) |
| RTC_RUN_ON(worker_thread_checker_); |
| |
| void ConfigureStream(const Config& new_config, |
| bool first_time, |
| SetParametersCallback callback) |
| RTC_RUN_ON(worker_thread_checker_); |
| bool SetupSendCodec(const Config& new_config) |
| RTC_RUN_ON(worker_thread_checker_); |
| bool ReconfigureSendCodec(const Config& new_config) |
| RTC_RUN_ON(worker_thread_checker_); |
| void ReconfigureANA(const Config& new_config) |
| RTC_RUN_ON(worker_thread_checker_); |
| void ReconfigureCNG(const Config& new_config) |
| RTC_RUN_ON(worker_thread_checker_); |
| void ReconfigureBitrateObserver(const Config& new_config) |
| RTC_RUN_ON(worker_thread_checker_); |
| |
| void ConfigureBitrateObserver() RTC_RUN_ON(worker_thread_checker_); |
| void RemoveBitrateObserver() RTC_RUN_ON(worker_thread_checker_); |
| |
| // Returns bitrate constraints, maybe including overhead when enabled by |
| // field trial. |
| absl::optional<TargetAudioBitrateConstraints> GetMinMaxBitrateConstraints() |
| const RTC_RUN_ON(worker_thread_checker_); |
| |
| // Sets per-packet overhead on encoded (for ANA) based on current known values |
| // of transport and packetization overheads. |
| void UpdateOverheadForEncoder() |
| RTC_EXCLUSIVE_LOCKS_REQUIRED(overhead_per_packet_lock_); |
| |
| // Returns combined per-packet overhead. |
| size_t GetPerPacketOverheadBytes() const |
| RTC_EXCLUSIVE_LOCKS_REQUIRED(overhead_per_packet_lock_); |
| |
| void RegisterCngPayloadType(int payload_type, int clockrate_hz) |
| RTC_RUN_ON(worker_thread_checker_); |
| |
| void UpdateCachedTargetAudioBitrateConstraints() |
| RTC_RUN_ON(worker_thread_checker_); |
| |
| Clock* clock_; |
| const FieldTrialsView& field_trials_; |
| |
| SequenceChecker worker_thread_checker_; |
| rtc::RaceChecker audio_capture_race_checker_; |
| |
| const bool allocate_audio_without_feedback_; |
| const bool force_no_audio_feedback_ = allocate_audio_without_feedback_; |
| const bool enable_audio_alr_probing_; |
| const AudioAllocationConfig allocation_settings_; |
| |
| webrtc::AudioSendStream::Config config_ |
| RTC_GUARDED_BY(worker_thread_checker_); |
| rtc::scoped_refptr<webrtc::AudioState> audio_state_; |
| const std::unique_ptr<voe::ChannelSendInterface> channel_send_; |
| RtcEventLog* const event_log_; |
| const bool use_legacy_overhead_calculation_; |
| |
| int encoder_sample_rate_hz_ RTC_GUARDED_BY(worker_thread_checker_) = 0; |
| size_t encoder_num_channels_ RTC_GUARDED_BY(worker_thread_checker_) = 0; |
| bool sending_ RTC_GUARDED_BY(worker_thread_checker_) = false; |
| mutable Mutex audio_level_lock_; |
| // Keeps track of audio level, total audio energy and total samples duration. |
| // https://w3c.github.io/webrtc-stats/#dom-rtcaudiohandlerstats-totalaudioenergy |
| webrtc::voe::AudioLevel audio_level_ RTC_GUARDED_BY(audio_level_lock_); |
| |
| BitrateAllocatorInterface* const bitrate_allocator_ |
| RTC_GUARDED_BY(worker_thread_checker_); |
| absl::optional<AudioSendStream::TargetAudioBitrateConstraints> |
| cached_constraints_ RTC_GUARDED_BY(worker_thread_checker_) = |
| absl::nullopt; |
| RtpTransportControllerSendInterface* const rtp_transport_; |
| |
| RtpRtcpInterface* const rtp_rtcp_module_; |
| absl::optional<RtpState> const suspended_rtp_state_; |
| |
| // RFC 5285: Each distinct extension MUST have a unique ID. The value 0 is |
| // reserved for padding and MUST NOT be used as a local identifier. |
| // So it should be safe to use 0 here to indicate "not configured". |
| struct ExtensionIds { |
| int audio_level = 0; |
| int abs_send_time = 0; |
| int abs_capture_time = 0; |
| int transport_sequence_number = 0; |
| int mid = 0; |
| int rid = 0; |
| int repaired_rid = 0; |
| }; |
| static ExtensionIds FindExtensionIds( |
| const std::vector<RtpExtension>& extensions); |
| static int TransportSeqNumId(const Config& config); |
| |
| mutable Mutex overhead_per_packet_lock_; |
| size_t overhead_per_packet_ RTC_GUARDED_BY(overhead_per_packet_lock_) = 0; |
| |
| // Current transport overhead (ICE, TURN, etc.) |
| size_t transport_overhead_per_packet_bytes_ |
| RTC_GUARDED_BY(overhead_per_packet_lock_) = 0; |
| |
| bool registered_with_allocator_ RTC_GUARDED_BY(worker_thread_checker_) = |
| false; |
| size_t total_packet_overhead_bytes_ RTC_GUARDED_BY(worker_thread_checker_) = |
| 0; |
| absl::optional<std::pair<TimeDelta, TimeDelta>> frame_length_range_ |
| RTC_GUARDED_BY(worker_thread_checker_); |
| }; |
| } // namespace internal |
| } // namespace webrtc |
| |
| #endif // AUDIO_AUDIO_SEND_STREAM_H_ |