blob: d82925a8adeb22e04ce8acb753807a829f7796cb [file] [log] [blame]
Marina Ciocea48623202020-04-01 08:19:441/*
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
11#include "audio/channel_receive_frame_transformer_delegate.h"
12
Harald Alvestrand6431a642024-06-04 21:29:1413#include <cstdint>
14#include <memory>
Florent Castelli8037fc62024-08-29 13:00:4015#include <optional>
Philipp Hancked2098932023-11-01 18:18:3216#include <string>
Marina Ciocea48623202020-04-01 08:19:4417#include <utility>
18
Harald Alvestrand6431a642024-06-04 21:29:1419#include "api/array_view.h"
20#include "api/frame_transformer_interface.h"
21#include "api/rtp_headers.h"
22#include "api/scoped_refptr.h"
23#include "api/sequence_checker.h"
24#include "api/task_queue/task_queue_base.h"
Lionel Koenig Gélasb4462512024-07-30 13:47:4125#include "api/units/timestamp.h"
Marina Ciocea48623202020-04-01 08:19:4426#include "rtc_base/buffer.h"
Lionel Koenig Gélasb4462512024-07-30 13:47:4127#include "rtc_base/string_encode.h"
Marina Ciocea48623202020-04-01 08:19:4428
29namespace webrtc {
Marina Ciocea48623202020-04-01 08:19:4430
Tony Herre8fb41a32021-09-24 12:05:2031class TransformableIncomingAudioFrame
32 : public TransformableAudioFrameInterface {
Marina Ciocea48623202020-04-01 08:19:4433 public:
Tony Herre8fb41a32021-09-24 12:05:2034 TransformableIncomingAudioFrame(rtc::ArrayView<const uint8_t> payload,
35 const RTPHeader& header,
Philipp Hancked2098932023-11-01 18:18:3236 uint32_t ssrc,
Lionel Koenig Gélasb4462512024-07-30 13:47:4137 const std::string& codec_mime_type,
38 Timestamp receive_time)
Tony Herrea45c7052024-05-16 11:38:2539 : TransformableAudioFrameInterface(Passkey()),
40 payload_(payload.data(), payload.size()),
Marina Ciocea48623202020-04-01 08:19:4441 header_(header),
Philipp Hancked2098932023-11-01 18:18:3242 ssrc_(ssrc),
Lionel Koenig Gélasb4462512024-07-30 13:47:4143 codec_mime_type_(codec_mime_type),
44 receive_time_(receive_time) {}
Tony Herre8fb41a32021-09-24 12:05:2045 ~TransformableIncomingAudioFrame() override = default;
Marina Ciocea48623202020-04-01 08:19:4446 rtc::ArrayView<const uint8_t> GetData() const override { return payload_; }
47
48 void SetData(rtc::ArrayView<const uint8_t> data) override {
49 payload_.SetData(data.data(), data.size());
50 }
51
Palak Agarwalfc260a182023-06-07 14:17:4952 void SetRTPTimestamp(uint32_t timestamp) override {
53 header_.timestamp = timestamp;
54 }
55
Philipp Hancke2ace42f2021-08-24 08:40:1256 uint8_t GetPayloadType() const override { return header_.payloadType; }
Marina Ciocea48623202020-04-01 08:19:4457 uint32_t GetSsrc() const override { return ssrc_; }
Philipp Hancke2ace42f2021-08-24 08:40:1258 uint32_t GetTimestamp() const override { return header_.timestamp; }
Sergio Garcia Murillo15dfc5a2022-10-11 10:34:4459 rtc::ArrayView<const uint32_t> GetContributingSources() const override {
60 return rtc::ArrayView<const uint32_t>(header_.arrOfCSRCs, header_.numCSRCs);
61 }
Tony Herre8fb41a32021-09-24 12:05:2062 Direction GetDirection() const override { return Direction::kReceiver; }
Marina Ciocea48623202020-04-01 08:19:4463
Philipp Hancked2098932023-11-01 18:18:3264 std::string GetMimeType() const override { return codec_mime_type_; }
Florent Castelli8037fc62024-08-29 13:00:4065 const std::optional<uint16_t> SequenceNumber() const override {
Tony Herre097a4de2023-06-19 15:13:0866 return header_.sequenceNumber;
67 }
68
Florent Castelli8037fc62024-08-29 13:00:4069 std::optional<uint64_t> AbsoluteCaptureTimestamp() const override {
Tony Herrefc68f1f2023-06-22 13:32:2470 // This could be extracted from received header extensions + extrapolation,
71 // if required in future, eg for being able to re-send received frames.
Florent Castelli8037fc62024-08-29 13:00:4072 return std::nullopt;
Tony Herrefc68f1f2023-06-22 13:32:2473 }
74 const RTPHeader& Header() const { return header_; }
75
76 FrameType Type() const override {
Joachim Reiersen5075cb42024-03-22 01:08:5477 if (!header_.extension.audio_level()) {
78 // Audio level extension not set.
79 return FrameType::kAudioFrameCN;
80 }
81 return header_.extension.audio_level()->voice_activity()
82 ? FrameType::kAudioFrameSpeech
83 : FrameType::kAudioFrameCN;
Tony Herrefc68f1f2023-06-22 13:32:2484 }
85
Florent Castelli8037fc62024-08-29 13:00:4086 std::optional<uint8_t> AudioLevel() const override {
Tony Herre64437e82024-04-29 13:13:4887 if (header_.extension.audio_level()) {
88 return header_.extension.audio_level()->level();
89 }
Florent Castelli8037fc62024-08-29 13:00:4090 return std::nullopt;
Tony Herre64437e82024-04-29 13:13:4891 }
92
Florent Castelli8037fc62024-08-29 13:00:4093 std::optional<Timestamp> ReceiveTime() const override {
Lionel Koenig Gélasb4462512024-07-30 13:47:4194 return receive_time_ == Timestamp::MinusInfinity()
Florent Castelli8037fc62024-08-29 13:00:4095 ? std::nullopt
96 : std::optional<Timestamp>(receive_time_);
Lionel Koenig Gélasb4462512024-07-30 13:47:4197 }
98
Marina Ciocea48623202020-04-01 08:19:4499 private:
100 rtc::Buffer payload_;
101 RTPHeader header_;
102 uint32_t ssrc_;
Philipp Hancked2098932023-11-01 18:18:32103 std::string codec_mime_type_;
Lionel Koenig Gélasb4462512024-07-30 13:47:41104 Timestamp receive_time_;
Marina Ciocea48623202020-04-01 08:19:44105};
Marina Ciocea48623202020-04-01 08:19:44106
107ChannelReceiveFrameTransformerDelegate::ChannelReceiveFrameTransformerDelegate(
108 ReceiveFrameCallback receive_frame_callback,
109 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
Tommie2e04642021-06-09 14:11:11110 TaskQueueBase* channel_receive_thread)
Marina Ciocea48623202020-04-01 08:19:44111 : receive_frame_callback_(receive_frame_callback),
112 frame_transformer_(std::move(frame_transformer)),
113 channel_receive_thread_(channel_receive_thread) {}
114
115void ChannelReceiveFrameTransformerDelegate::Init() {
116 RTC_DCHECK_RUN_ON(&sequence_checker_);
117 frame_transformer_->RegisterTransformedFrameCallback(
118 rtc::scoped_refptr<TransformedFrameCallback>(this));
119}
120
121void ChannelReceiveFrameTransformerDelegate::Reset() {
122 RTC_DCHECK_RUN_ON(&sequence_checker_);
123 frame_transformer_->UnregisterTransformedFrameCallback();
124 frame_transformer_ = nullptr;
125 receive_frame_callback_ = ReceiveFrameCallback();
126}
127
128void ChannelReceiveFrameTransformerDelegate::Transform(
129 rtc::ArrayView<const uint8_t> packet,
130 const RTPHeader& header,
Philipp Hancked2098932023-11-01 18:18:32131 uint32_t ssrc,
Lionel Koenig Gélasb4462512024-07-30 13:47:41132 const std::string& codec_mime_type,
133 Timestamp receive_time) {
Marina Ciocea48623202020-04-01 08:19:44134 RTC_DCHECK_RUN_ON(&sequence_checker_);
Tony Herre6e956052023-11-16 13:59:54135 if (short_circuit_) {
Lionel Koenig Gélasb4462512024-07-30 13:47:41136 receive_frame_callback_(packet, header, receive_time);
Tony Herre6e956052023-11-16 13:59:54137 } else {
138 frame_transformer_->Transform(
Lionel Koenig Gélasb4462512024-07-30 13:47:41139 std::make_unique<TransformableIncomingAudioFrame>(
140 packet, header, ssrc, codec_mime_type, receive_time));
Tony Herre6e956052023-11-16 13:59:54141 }
Marina Ciocea48623202020-04-01 08:19:44142}
143
144void ChannelReceiveFrameTransformerDelegate::OnTransformedFrame(
145 std::unique_ptr<TransformableFrameInterface> frame) {
Niels Möllera3361ff2022-01-13 13:05:38146 rtc::scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate(this);
Danil Chapovalovc05a1be2022-07-19 11:07:12147 channel_receive_thread_->PostTask(
Marina Ciocea48623202020-04-01 08:19:44148 [delegate = std::move(delegate), frame = std::move(frame)]() mutable {
149 delegate->ReceiveFrame(std::move(frame));
Danil Chapovalovc05a1be2022-07-19 11:07:12150 });
Marina Ciocea48623202020-04-01 08:19:44151}
152
Tony Herre6e956052023-11-16 13:59:54153void ChannelReceiveFrameTransformerDelegate::StartShortCircuiting() {
154 rtc::scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate(this);
155 channel_receive_thread_->PostTask([delegate = std::move(delegate)]() mutable {
156 RTC_DCHECK_RUN_ON(&delegate->sequence_checker_);
157 delegate->short_circuit_ = true;
158 });
159}
160
Marina Ciocea48623202020-04-01 08:19:44161void ChannelReceiveFrameTransformerDelegate::ReceiveFrame(
162 std::unique_ptr<TransformableFrameInterface> frame) const {
163 RTC_DCHECK_RUN_ON(&sequence_checker_);
164 if (!receive_frame_callback_)
165 return;
Palak Agarwalf263e1e2023-08-18 12:09:53166
Lionel Koenig Gélasb4462512024-07-30 13:47:41167 auto* transformed_frame =
168 static_cast<TransformableAudioFrameInterface*>(frame.get());
169 Timestamp receive_time =
170 transformed_frame->ReceiveTime().value_or(Timestamp::MinusInfinity());
Palak Agarwalf263e1e2023-08-18 12:09:53171 RTPHeader header;
172 if (frame->GetDirection() ==
173 TransformableFrameInterface::Direction::kSender) {
Palak Agarwalf263e1e2023-08-18 12:09:53174 header.payloadType = transformed_frame->GetPayloadType();
175 header.timestamp = transformed_frame->GetTimestamp();
176 header.ssrc = transformed_frame->GetSsrc();
177 if (transformed_frame->AbsoluteCaptureTimestamp().has_value()) {
178 header.extension.absolute_capture_time = AbsoluteCaptureTime();
179 header.extension.absolute_capture_time->absolute_capture_timestamp =
180 transformed_frame->AbsoluteCaptureTimestamp().value();
181 }
182 } else {
Lionel Koenig Gélasb4462512024-07-30 13:47:41183 auto* transformed_incoming_frame =
Palak Agarwalf263e1e2023-08-18 12:09:53184 static_cast<TransformableIncomingAudioFrame*>(frame.get());
Lionel Koenig Gélasb4462512024-07-30 13:47:41185 header = transformed_incoming_frame->Header();
Palak Agarwalf263e1e2023-08-18 12:09:53186 }
187
188 // TODO(crbug.com/1464860): Take an explicit struct with the required
189 // information rather than the RTPHeader to make it easier to
190 // construct the required information when injecting transformed frames not
191 // originally from this receiver.
Lionel Koenig Gélasb4462512024-07-30 13:47:41192 receive_frame_callback_(frame->GetData(), header, receive_time);
Marina Ciocea48623202020-04-01 08:19:44193}
Tony Herref921d252023-11-27 09:37:06194
195rtc::scoped_refptr<FrameTransformerInterface>
196ChannelReceiveFrameTransformerDelegate::FrameTransformer() {
197 RTC_DCHECK_RUN_ON(&sequence_checker_);
198 return frame_transformer_;
199}
200
Lionel Koenig Gélasb4462512024-07-30 13:47:41201std::unique_ptr<TransformableAudioFrameInterface> CloneReceiverAudioFrame(
202 TransformableAudioFrameInterface* original) {
203 RTC_CHECK(original->GetDirection() ==
204 TransformableFrameInterface::Direction::kReceiver);
205
206 auto* original_incoming_frame =
207 static_cast<TransformableIncomingAudioFrame*>(original);
208 return std::make_unique<TransformableIncomingAudioFrame>(
209 original->GetData(), original_incoming_frame->Header(),
210 original->GetSsrc(), original->GetMimeType(),
211 original->ReceiveTime().value_or(Timestamp::MinusInfinity()));
212}
Marina Ciocea48623202020-04-01 08:19:44213} // namespace webrtc