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