Allow Video Sender OnTransformedFrame() before TransformFrame()
Lazily initialize the RTPSenderVideoFrameTransformerDelegate's
encoder_queue_ on either OnTransformedFrame() or TransformFrame(), to
allow apps to write to an encoded insertable stream's writable before
reading from its readable.
Bug: chromium:1393373
Change-Id: I08f11682fa142884b575bb207d7d7044e80bbb9c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/284921
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tony Herre <herre@google.com>
Auto-Submit: Tony Herre <herre@google.com>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38728}
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
index 3d6931f..3e42781 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
@@ -112,14 +112,9 @@
rtc::scoped_refptr<TransformedFrameCallback>(this), ssrc_);
}
-bool RTPSenderVideoFrameTransformerDelegate::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) {
+void RTPSenderVideoFrameTransformerDelegate::EnsureEncoderQueueCreated() {
TaskQueueBase* current = TaskQueueBase::Current();
+
if (!encoder_queue_) {
// Save the current task queue to post the transformed frame for sending
// once it is transformed. When there is no current task queue, i.e.
@@ -133,6 +128,18 @@
encoder_queue_ = owned_encoder_queue_.get();
}
}
+}
+
+bool RTPSenderVideoFrameTransformerDelegate::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) {
+ EnsureEncoderQueueCreated();
+
+ TaskQueueBase* current = TaskQueueBase::Current();
// DCHECK that the current queue does not change, or if does then it was due
// to a hardware encoder fallback and thus there is an owned queue.
RTC_DCHECK(!current || current == encoder_queue_ || owned_encoder_queue_)
@@ -152,10 +159,9 @@
std::unique_ptr<TransformableFrameInterface> frame) {
MutexLock lock(&sender_lock_);
- // The encoder queue normally gets destroyed after the sender;
- // however, it might still be null by the time a previously queued frame
- // arrives.
- if (!sender_ || !encoder_queue_)
+ EnsureEncoderQueueCreated();
+
+ if (!sender_)
return;
rtc::scoped_refptr<RTPSenderVideoFrameTransformerDelegate> delegate(this);
encoder_queue_->PostTask(
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h
index 65d6d3f..0c2a643 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h
@@ -74,6 +74,8 @@
~RTPSenderVideoFrameTransformerDelegate() override = default;
private:
+ void EnsureEncoderQueueCreated();
+
mutable Mutex sender_lock_;
RTPSenderVideo* sender_ RTC_GUARDED_BY(sender_lock_);
rtc::scoped_refptr<FrameTransformerInterface> frame_transformer_;