| /* |
| * Copyright (c) 2020 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. |
| */ |
| |
| #include "audio/channel_send_frame_transformer_delegate.h" |
| |
| #include <utility> |
| |
| namespace webrtc { |
| namespace { |
| |
| class TransformableAudioFrame : public TransformableFrameInterface { |
| public: |
| TransformableAudioFrame(AudioFrameType frame_type, |
| uint8_t payload_type, |
| uint32_t rtp_timestamp, |
| uint32_t rtp_start_timestamp, |
| const uint8_t* payload_data, |
| size_t payload_size, |
| int64_t absolute_capture_timestamp_ms, |
| uint32_t ssrc) |
| : frame_type_(frame_type), |
| payload_type_(payload_type), |
| rtp_timestamp_(rtp_timestamp), |
| rtp_start_timestamp_(rtp_start_timestamp), |
| payload_(payload_data, payload_size), |
| absolute_capture_timestamp_ms_(absolute_capture_timestamp_ms), |
| ssrc_(ssrc) {} |
| ~TransformableAudioFrame() override = default; |
| rtc::ArrayView<const uint8_t> GetData() const override { return payload_; } |
| void SetData(rtc::ArrayView<const uint8_t> data) override { |
| payload_.SetData(data.data(), data.size()); |
| } |
| uint32_t GetTimestamp() const override { |
| return rtp_timestamp_ + rtp_start_timestamp_; |
| } |
| uint32_t GetStartTimestamp() const { return rtp_start_timestamp_; } |
| uint32_t GetSsrc() const override { return ssrc_; } |
| |
| AudioFrameType GetFrameType() const { return frame_type_; } |
| uint8_t GetPayloadType() const { return payload_type_; } |
| int64_t GetAbsoluteCaptureTimestampMs() const { |
| return absolute_capture_timestamp_ms_; |
| } |
| |
| private: |
| AudioFrameType frame_type_; |
| uint8_t payload_type_; |
| uint32_t rtp_timestamp_; |
| uint32_t rtp_start_timestamp_; |
| rtc::Buffer payload_; |
| int64_t absolute_capture_timestamp_ms_; |
| uint32_t ssrc_; |
| }; |
| } // namespace |
| |
| ChannelSendFrameTransformerDelegate::ChannelSendFrameTransformerDelegate( |
| SendFrameCallback send_frame_callback, |
| rtc::scoped_refptr<FrameTransformerInterface> frame_transformer, |
| rtc::TaskQueue* encoder_queue) |
| : send_frame_callback_(send_frame_callback), |
| frame_transformer_(std::move(frame_transformer)), |
| encoder_queue_(encoder_queue) {} |
| |
| void ChannelSendFrameTransformerDelegate::Init() { |
| frame_transformer_->RegisterTransformedFrameCallback( |
| rtc::scoped_refptr<TransformedFrameCallback>(this)); |
| } |
| |
| void ChannelSendFrameTransformerDelegate::Reset() { |
| frame_transformer_->UnregisterTransformedFrameCallback(); |
| frame_transformer_ = nullptr; |
| |
| MutexLock lock(&send_lock_); |
| send_frame_callback_ = SendFrameCallback(); |
| } |
| |
| void ChannelSendFrameTransformerDelegate::Transform( |
| AudioFrameType frame_type, |
| uint8_t payload_type, |
| uint32_t rtp_timestamp, |
| uint32_t rtp_start_timestamp, |
| const uint8_t* payload_data, |
| size_t payload_size, |
| int64_t absolute_capture_timestamp_ms, |
| uint32_t ssrc) { |
| frame_transformer_->Transform(std::make_unique<TransformableAudioFrame>( |
| frame_type, payload_type, rtp_timestamp, rtp_start_timestamp, |
| payload_data, payload_size, absolute_capture_timestamp_ms, ssrc)); |
| } |
| |
| void ChannelSendFrameTransformerDelegate::OnTransformedFrame( |
| std::unique_ptr<TransformableFrameInterface> frame) { |
| MutexLock lock(&send_lock_); |
| if (!send_frame_callback_) |
| return; |
| rtc::scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = this; |
| encoder_queue_->PostTask( |
| [delegate = std::move(delegate), frame = std::move(frame)]() mutable { |
| delegate->SendFrame(std::move(frame)); |
| }); |
| } |
| |
| void ChannelSendFrameTransformerDelegate::SendFrame( |
| std::unique_ptr<TransformableFrameInterface> frame) const { |
| MutexLock lock(&send_lock_); |
| RTC_DCHECK_RUN_ON(encoder_queue_); |
| if (!send_frame_callback_) |
| return; |
| auto* transformed_frame = static_cast<TransformableAudioFrame*>(frame.get()); |
| send_frame_callback_(transformed_frame->GetFrameType(), |
| transformed_frame->GetPayloadType(), |
| transformed_frame->GetTimestamp() - |
| transformed_frame->GetStartTimestamp(), |
| transformed_frame->GetData(), |
| transformed_frame->GetAbsoluteCaptureTimestampMs()); |
| } |
| |
| } // namespace webrtc |