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