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 "absl/memory/memory.h"
17 #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h"
18 #include "modules/rtp_rtcp/source/rtp_sender_video.h"
19 #include "rtc_base/task_utils/to_queued_task.h"
20
21 namespace webrtc {
22 namespace {
23
24 class TransformableVideoSenderFrame : public TransformableVideoFrameInterface {
25 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)26 TransformableVideoSenderFrame(
27 const EncodedImage& encoded_image,
28 const RTPVideoHeader& video_header,
29 int payload_type,
30 absl::optional<VideoCodecType> codec_type,
31 uint32_t rtp_timestamp,
32 absl::optional<int64_t> expected_retransmission_time_ms,
33 uint32_t ssrc)
34 : encoded_data_(encoded_image.GetEncodedData()),
35 header_(video_header),
36 metadata_(header_),
37 frame_type_(encoded_image._frameType),
38 payload_type_(payload_type),
39 codec_type_(codec_type),
40 timestamp_(rtp_timestamp),
41 capture_time_ms_(encoded_image.capture_time_ms_),
42 expected_retransmission_time_ms_(expected_retransmission_time_ms),
43 ssrc_(ssrc) {}
44
45 ~TransformableVideoSenderFrame() override = default;
46
47 // Implements TransformableVideoFrameInterface.
GetData() const48 rtc::ArrayView<const uint8_t> GetData() const override {
49 return *encoded_data_;
50 }
51
SetData(rtc::ArrayView<const uint8_t> data)52 void SetData(rtc::ArrayView<const uint8_t> data) override {
53 encoded_data_ = EncodedImageBuffer::Create(data.data(), data.size());
54 }
55
GetTimestamp() const56 uint32_t GetTimestamp() const override { return timestamp_; }
GetSsrc() const57 uint32_t GetSsrc() const override { return ssrc_; }
58
IsKeyFrame() const59 bool IsKeyFrame() const override {
60 return frame_type_ == VideoFrameType::kVideoFrameKey;
61 }
62
GetAdditionalData() const63 std::vector<uint8_t> GetAdditionalData() const override {
64 return RtpDescriptorAuthentication(header_);
65 }
66
GetMetadata() const67 const VideoFrameMetadata& GetMetadata() const override { return metadata_; }
68
GetHeader() const69 const RTPVideoHeader& GetHeader() const { return header_; }
GetPayloadType() const70 int GetPayloadType() const { return payload_type_; }
GetCodecType() const71 absl::optional<VideoCodecType> GetCodecType() const { return codec_type_; }
GetCaptureTimeMs() const72 int64_t GetCaptureTimeMs() const { return capture_time_ms_; }
73
GetExpectedRetransmissionTimeMs() const74 const absl::optional<int64_t>& GetExpectedRetransmissionTimeMs() const {
75 return expected_retransmission_time_ms_;
76 }
77
78 private:
79 rtc::scoped_refptr<EncodedImageBufferInterface> encoded_data_;
80 const RTPVideoHeader header_;
81 const VideoFrameMetadata metadata_;
82 const VideoFrameType frame_type_;
83 const int payload_type_;
84 const absl::optional<VideoCodecType> codec_type_ = absl::nullopt;
85 const uint32_t timestamp_;
86 const int64_t capture_time_ms_;
87 const absl::optional<int64_t> expected_retransmission_time_ms_;
88 const uint32_t ssrc_;
89 };
90 } // namespace
91
RTPSenderVideoFrameTransformerDelegate(RTPSenderVideo * sender,rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,uint32_t ssrc,TaskQueueBase * send_transport_queue)92 RTPSenderVideoFrameTransformerDelegate::RTPSenderVideoFrameTransformerDelegate(
93 RTPSenderVideo* sender,
94 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
95 uint32_t ssrc,
96 TaskQueueBase* send_transport_queue)
97 : sender_(sender),
98 frame_transformer_(std::move(frame_transformer)),
99 ssrc_(ssrc),
100 send_transport_queue_(send_transport_queue) {}
101
Init()102 void RTPSenderVideoFrameTransformerDelegate::Init() {
103 frame_transformer_->RegisterTransformedFrameSinkCallback(
104 rtc::scoped_refptr<TransformedFrameCallback>(this), ssrc_);
105 }
106
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)107 bool RTPSenderVideoFrameTransformerDelegate::TransformFrame(
108 int payload_type,
109 absl::optional<VideoCodecType> codec_type,
110 uint32_t rtp_timestamp,
111 const EncodedImage& encoded_image,
112 RTPVideoHeader video_header,
113 absl::optional<int64_t> expected_retransmission_time_ms) {
114 if (!encoder_queue_) {
115 // Save the current task queue to post the transformed frame for sending
116 // once it is transformed. When there is no current task queue, i.e.
117 // encoding is done on an external thread (for example in the case of
118 // hardware encoders), use the send transport queue instead.
119 TaskQueueBase* current = TaskQueueBase::Current();
120 encoder_queue_ = current ? current : send_transport_queue_;
121 }
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 // The encoder queue gets destroyed after the sender; as long as the sender is
133 // alive, it's safe to post.
134 if (!sender_)
135 return;
136 rtc::scoped_refptr<RTPSenderVideoFrameTransformerDelegate> delegate = this;
137 encoder_queue_->PostTask(ToQueuedTask(
138 [delegate = std::move(delegate), frame = std::move(frame)]() mutable {
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_CHECK(encoder_queue_->IsCurrent());
146 MutexLock lock(&sender_lock_);
147 if (!sender_)
148 return;
149 auto* transformed_video_frame =
150 static_cast<TransformableVideoSenderFrame*>(transformed_frame.get());
151 sender_->SendVideo(
152 transformed_video_frame->GetPayloadType(),
153 transformed_video_frame->GetCodecType(),
154 transformed_video_frame->GetTimestamp(),
155 transformed_video_frame->GetCaptureTimeMs(),
156 transformed_video_frame->GetData(),
157 transformed_video_frame->GetHeader(),
158 transformed_video_frame->GetExpectedRetransmissionTimeMs());
159 }
160
SetVideoStructureUnderLock(const FrameDependencyStructure * video_structure)161 void RTPSenderVideoFrameTransformerDelegate::SetVideoStructureUnderLock(
162 const FrameDependencyStructure* video_structure) {
163 MutexLock lock(&sender_lock_);
164 RTC_CHECK(sender_);
165 sender_->SetVideoStructureUnderLock(video_structure);
166 }
167
Reset()168 void RTPSenderVideoFrameTransformerDelegate::Reset() {
169 frame_transformer_->UnregisterTransformedFrameSinkCallback(ssrc_);
170 frame_transformer_ = nullptr;
171 {
172 MutexLock lock(&sender_lock_);
173 sender_ = nullptr;
174 }
175 }
176 } // namespace webrtc
177