[InsertableStreams] Send transformed frames on worker queue.

When video frame encoding is done on an external thread (for example in
the case of hardware encoders), the WebRTC TaskQueueBase::Current() is
null; in this case use the worker queue instead to send transformed
frames.

Bug: chromium:1086373
Change-Id: I903ddc52ad6832557fc5b5f76396fe26cf5a88f3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176303
Reviewed-by: Magnus Flodman <mflodman@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Marina Ciocea <marinaciocea@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31388}
diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc
index b6cb054..ca8baee 100644
--- a/call/rtp_video_sender.cc
+++ b/call/rtp_video_sender.cc
@@ -30,6 +30,7 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/location.h"
 #include "rtc_base/logging.h"
+#include "rtc_base/task_queue.h"
 
 namespace webrtc {
 
@@ -281,6 +282,7 @@
       video_config.fec_overhead_bytes = fec_generator->MaxPacketOverhead();
     }
     video_config.frame_transformer = frame_transformer;
+    video_config.worker_queue = transport->GetWorkerQueue()->Get();
     auto sender_video = std::make_unique<RTPSenderVideo>(video_config);
     rtp_streams.emplace_back(std::move(rtp_rtcp), std::move(sender_video),
                              std::move(fec_generator));
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 8dbcc90..040f1b6 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -144,7 +144,8 @@
                     RTPSenderVideoFrameTransformerDelegate>(
                     this,
                     config.frame_transformer,
-                    rtp_sender_->SSRC())
+                    rtp_sender_->SSRC(),
+                    config.worker_queue)
               : nullptr) {
   if (frame_transformer_delegate_)
     frame_transformer_delegate_->Init();
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index bf5f181..216f16f 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -20,6 +20,7 @@
 #include "api/array_view.h"
 #include "api/frame_transformer_interface.h"
 #include "api/scoped_refptr.h"
+#include "api/task_queue/task_queue_base.h"
 #include "api/transport/rtp/dependency_descriptor.h"
 #include "api/video/video_codec_type.h"
 #include "api/video/video_frame_type.h"
@@ -81,6 +82,7 @@
     absl::optional<int> red_payload_type;
     const WebRtcKeyValueConfig* field_trials = nullptr;
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer;
+    TaskQueueBase* worker_queue = nullptr;
   };
 
   explicit RTPSenderVideo(const Config& config);
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 60740d3..bae79c9 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
@@ -109,10 +109,12 @@
 RTPSenderVideoFrameTransformerDelegate::RTPSenderVideoFrameTransformerDelegate(
     RTPSenderVideo* sender,
     rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
-    uint32_t ssrc)
+    uint32_t ssrc,
+    TaskQueueBase* worker_queue)
     : sender_(sender),
       frame_transformer_(std::move(frame_transformer)),
-      ssrc_(ssrc) {}
+      ssrc_(ssrc),
+      worker_queue_(worker_queue) {}
 
 void RTPSenderVideoFrameTransformerDelegate::Init() {
   frame_transformer_->RegisterTransformedFrameSinkCallback(
@@ -127,8 +129,14 @@
     const RTPFragmentationHeader* fragmentation,
     RTPVideoHeader video_header,
     absl::optional<int64_t> expected_retransmission_time_ms) {
-  if (!encoder_queue_)
-    encoder_queue_ = 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.
+    // encoding is done on an external thread (for example in the case of
+    // hardware encoders), use the worker queue instead.
+    TaskQueueBase* current = TaskQueueBase::Current();
+    encoder_queue_ = current ? current : worker_queue_;
+  }
   frame_transformer_->Transform(std::make_unique<TransformableVideoSenderFrame>(
       encoded_image, video_header, payload_type, codec_type, rtp_timestamp,
       fragmentation, expected_retransmission_time_ms, ssrc_));
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 29ac9e4..bea5ba7 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
@@ -30,7 +30,8 @@
   RTPSenderVideoFrameTransformerDelegate(
       RTPSenderVideo* sender,
       rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
-      uint32_t ssrc);
+      uint32_t ssrc,
+      TaskQueueBase* worker_queue);
 
   void Init();
 
@@ -69,6 +70,7 @@
   rtc::scoped_refptr<FrameTransformerInterface> frame_transformer_;
   const uint32_t ssrc_;
   TaskQueueBase* encoder_queue_ = nullptr;
+  TaskQueueBase* worker_queue_;
 };
 
 }  // namespace webrtc