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
11 #include "modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h"
12
13 #include <utility>
14 #include <vector>
15
16 #include "api/sequence_checker.h"
17 #include "api/task_queue/task_queue_factory.h"
18 #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h"
19 #include "modules/rtp_rtcp/source/rtp_sender_video.h"
20 #include "rtc_base/checks.h"
21
22 namespace webrtc {
23 namespace {
24
25 class TransformableVideoSenderFrame : public TransformableVideoFrameInterface {
26 public:
TransformableVideoSenderFrame(const EncodedImage & encoded_image,const RTPVideoHeader & video_header,int payload_type,absl::optional<VideoCodecType> codec_type,uint32_t rtp_timestamp,absl::optional<int64_t> expected_retransmission_time_ms,uint32_t ssrc)27 TransformableVideoSenderFrame(
28 const EncodedImage& encoded_image,
29 const RTPVideoHeader& video_header,
30 int payload_type,
31 absl::optional<VideoCodecType> codec_type,
32 uint32_t rtp_timestamp,
33 absl::optional<int64_t> expected_retransmission_time_ms,
34 uint32_t ssrc)
35 : encoded_data_(encoded_image.GetEncodedData()),
36 header_(video_header),
37 metadata_(header_.GetAsMetadata()),
38 frame_type_(encoded_image._frameType),
39 payload_type_(payload_type),
40 codec_type_(codec_type),
41 timestamp_(rtp_timestamp),
42 capture_time_ms_(encoded_image.capture_time_ms_),
43 expected_retransmission_time_ms_(expected_retransmission_time_ms),
44 ssrc_(ssrc) {
45 RTC_DCHECK_GE(payload_type_, 0);
46 RTC_DCHECK_LE(payload_type_, 127);
47 }
48
49 ~TransformableVideoSenderFrame() override = default;
50
51 // Implements TransformableVideoFrameInterface.
GetData() const52 rtc::ArrayView<const uint8_t> GetData() const override {
53 return *encoded_data_;
54 }
55
SetData(rtc::ArrayView<const uint8_t> data)56 void SetData(rtc::ArrayView<const uint8_t> data) override {
57 encoded_data_ = EncodedImageBuffer::Create(data.data(), data.size());
58 }
59
GetTimestamp() const60 uint32_t GetTimestamp() const override { return timestamp_; }
GetSsrc() const61 uint32_t GetSsrc() const override { return ssrc_; }
62
IsKeyFrame() const63 bool IsKeyFrame() const override {
64 return frame_type_ == VideoFrameType::kVideoFrameKey;
65 }
66
GetAdditionalData() const67 std::vector<uint8_t> GetAdditionalData() const override {
68 return RtpDescriptorAuthentication(header_);
69 }
70
GetMetadata() const71 const VideoFrameMetadata& GetMetadata() const override { return metadata_; }
72
GetHeader() const73 const RTPVideoHeader& GetHeader() const { return header_; }
GetPayloadType() const74 uint8_t GetPayloadType() const override { return payload_type_; }
GetCodecType() const75 absl::optional<VideoCodecType> GetCodecType() const { return codec_type_; }
GetCaptureTimeMs() const76 int64_t GetCaptureTimeMs() const { return capture_time_ms_; }
77
GetExpectedRetransmissionTimeMs() const78 const absl::optional<int64_t>& GetExpectedRetransmissionTimeMs() const {
79 return expected_retransmission_time_ms_;
80 }
81
GetDirection() const82 Direction GetDirection() const override { return Direction::kSender; }
83
84 private:
85 rtc::scoped_refptr<EncodedImageBufferInterface> encoded_data_;
86 const RTPVideoHeader header_;
87 const VideoFrameMetadata metadata_;
88 const VideoFrameType frame_type_;
89 const uint8_t payload_type_;
90 const absl::optional<VideoCodecType> codec_type_ = absl::nullopt;
91 const uint32_t timestamp_;
92 const int64_t capture_time_ms_;
93 const absl::optional<int64_t> expected_retransmission_time_ms_;
94 const uint32_t ssrc_;
95 };
96 } // namespace
97
RTPSenderVideoFrameTransformerDelegate(RTPSenderVideo * sender,rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,uint32_t ssrc,TaskQueueFactory * task_queue_factory)98 RTPSenderVideoFrameTransformerDelegate::RTPSenderVideoFrameTransformerDelegate(
99 RTPSenderVideo* sender,
100 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
101 uint32_t ssrc,
102 TaskQueueFactory* task_queue_factory)
103 : sender_(sender),
104 frame_transformer_(std::move(frame_transformer)),
105 ssrc_(ssrc),
106 transformation_queue_(task_queue_factory->CreateTaskQueue(
107 "video_frame_transformer",
108 TaskQueueFactory::Priority::NORMAL)) {}
109
Init()110 void RTPSenderVideoFrameTransformerDelegate::Init() {
111 frame_transformer_->RegisterTransformedFrameSinkCallback(
112 rtc::scoped_refptr<TransformedFrameCallback>(this), ssrc_);
113 }
114
TransformFrame(int payload_type,absl::optional<VideoCodecType> codec_type,uint32_t rtp_timestamp,const EncodedImage & encoded_image,RTPVideoHeader video_header,absl::optional<int64_t> expected_retransmission_time_ms)115 bool RTPSenderVideoFrameTransformerDelegate::TransformFrame(
116 int payload_type,
117 absl::optional<VideoCodecType> codec_type,
118 uint32_t rtp_timestamp,
119 const EncodedImage& encoded_image,
120 RTPVideoHeader video_header,
121 absl::optional<int64_t> expected_retransmission_time_ms) {
122 frame_transformer_->Transform(std::make_unique<TransformableVideoSenderFrame>(
123 encoded_image, video_header, payload_type, codec_type, rtp_timestamp,
124 expected_retransmission_time_ms, ssrc_));
125 return true;
126 }
127
OnTransformedFrame(std::unique_ptr<TransformableFrameInterface> frame)128 void RTPSenderVideoFrameTransformerDelegate::OnTransformedFrame(
129 std::unique_ptr<TransformableFrameInterface> frame) {
130 MutexLock lock(&sender_lock_);
131
132 if (!sender_) {
133 return;
134 }
135 rtc::scoped_refptr<RTPSenderVideoFrameTransformerDelegate> delegate(this);
136 transformation_queue_->PostTask(
137 [delegate = std::move(delegate), frame = std::move(frame)]() mutable {
138 RTC_DCHECK_RUN_ON(delegate->transformation_queue_.get());
139 delegate->SendVideo(std::move(frame));
140 });
141 }
142
SendVideo(std::unique_ptr<TransformableFrameInterface> transformed_frame) const143 void RTPSenderVideoFrameTransformerDelegate::SendVideo(
144 std::unique_ptr<TransformableFrameInterface> transformed_frame) const {
145 RTC_DCHECK_RUN_ON(transformation_queue_.get());
146 RTC_CHECK_EQ(transformed_frame->GetDirection(),
147 TransformableFrameInterface::Direction::kSender);
148 MutexLock lock(&sender_lock_);
149 if (!sender_)
150 return;
151 auto* transformed_video_frame =
152 static_cast<TransformableVideoSenderFrame*>(transformed_frame.get());
153 sender_->SendVideo(
154 transformed_video_frame->GetPayloadType(),
155 transformed_video_frame->GetCodecType(),
156 transformed_video_frame->GetTimestamp(),
157 transformed_video_frame->GetCaptureTimeMs(),
158 transformed_video_frame->GetData(), transformed_video_frame->GetHeader(),
159 transformed_video_frame->GetExpectedRetransmissionTimeMs());
160 }
161
SetVideoStructureUnderLock(const FrameDependencyStructure * video_structure)162 void RTPSenderVideoFrameTransformerDelegate::SetVideoStructureUnderLock(
163 const FrameDependencyStructure* video_structure) {
164 MutexLock lock(&sender_lock_);
165 RTC_CHECK(sender_);
166 sender_->SetVideoStructureAfterTransformation(video_structure);
167 }
168
SetVideoLayersAllocationUnderLock(VideoLayersAllocation allocation)169 void RTPSenderVideoFrameTransformerDelegate::SetVideoLayersAllocationUnderLock(
170 VideoLayersAllocation allocation) {
171 MutexLock lock(&sender_lock_);
172 RTC_CHECK(sender_);
173 sender_->SetVideoLayersAllocationAfterTransformation(std::move(allocation));
174 }
175
Reset()176 void RTPSenderVideoFrameTransformerDelegate::Reset() {
177 frame_transformer_->UnregisterTransformedFrameSinkCallback(ssrc_);
178 frame_transformer_ = nullptr;
179 {
180 MutexLock lock(&sender_lock_);
181 sender_ = nullptr;
182 }
183 }
184
CloneSenderVideoFrame(TransformableVideoFrameInterface * original)185 std::unique_ptr<TransformableVideoFrameInterface> CloneSenderVideoFrame(
186 TransformableVideoFrameInterface* original) {
187 auto encoded_image_buffer = EncodedImageBuffer::Create(
188 original->GetData().data(), original->GetData().size());
189 EncodedImage encoded_image;
190 encoded_image.SetEncodedData(encoded_image_buffer);
191 RTPVideoHeader new_header;
192 absl::optional<VideoCodecType> new_codec_type;
193 // TODO(bugs.webrtc.org/14708): Figure out a way to get the header information
194 // without casting to TransformableVideoSenderFrame.
195 if (original->GetDirection() ==
196 TransformableFrameInterface::Direction::kSender) {
197 // TODO(bugs.webrtc.org/14708): Figure out a way to bulletproof this cast.
198 auto original_as_sender =
199 static_cast<TransformableVideoSenderFrame*>(original);
200 new_header = original_as_sender->GetHeader();
201 new_codec_type = original_as_sender->GetCodecType();
202 } else {
203 // TODO(bugs.webrtc.org/14708): Make this codec dependent
204 new_header.video_type_header.emplace<RTPVideoHeaderVP8>();
205 new_codec_type = kVideoCodecVP8;
206 // TODO(bugs.webrtc.org/14708): Fill in the new_header when it's not
207 // `Direction::kSender`
208 }
209 // TODO(bugs.webrtc.org/14708): Fill in other EncodedImage parameters
210 return std::make_unique<TransformableVideoSenderFrame>(
211 encoded_image, new_header, original->GetPayloadType(), new_codec_type,
212 original->GetTimestamp(),
213 absl::nullopt, // expected_retransmission_time_ms
214 original->GetSsrc());
215 }
216
217 } // namespace webrtc
218