Make a copy of the frame if the processing has to be posted.

Since the frame is processed on the same thread as the decoding happens
on, keeping a reference to the frame may cause deadlocks on some
implementations.

Longer term, we should probably move the frame processing to a separate
thread but this is an easy fix for now.

Bug: b/110246814
Change-Id: I251737e2188e1755d45b35165586d1b0daf14595
Reviewed-on: https://webrtc-review.googlesource.com/87104
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23843}
diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc
index 98ba07f..0cf2fa0 100644
--- a/modules/video_coding/codecs/test/videoprocessor.cc
+++ b/modules/video_coding/codecs/test/videoprocessor.cc
@@ -310,6 +310,25 @@
       << "Failed to update encoder with new rate " << bitrate_kbps << ".";
 }
 
+int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded(
+    VideoFrame& image) {
+  // Post the callback to the right task queue, if needed.
+  if (!task_queue_->IsCurrent()) {
+    // There might be a limited amount of output buffers, make a copy to make
+    // sure we don't block the decoder.
+    VideoFrame copy(I420Buffer::Copy(*image.video_frame_buffer()->ToI420()),
+                    image.rotation(), image.timestamp_us());
+    copy.set_timestamp(image.timestamp());
+
+    task_queue_->PostTask([this, copy]() {
+      video_processor_->FrameDecoded(copy, simulcast_svc_idx_);
+    });
+    return 0;
+  }
+  video_processor_->FrameDecoded(image, simulcast_svc_idx_);
+  return 0;
+}
+
 void VideoProcessor::FrameEncoded(
     const webrtc::EncodedImage& encoded_image,
     const webrtc::CodecSpecificInfo& codec_specific) {
diff --git a/modules/video_coding/codecs/test/videoprocessor.h b/modules/video_coding/codecs/test/videoprocessor.h
index d44ee1f..f3808f8 100644
--- a/modules/video_coding/codecs/test/videoprocessor.h
+++ b/modules/video_coding/codecs/test/videoprocessor.h
@@ -133,17 +133,7 @@
       RTC_DCHECK(task_queue_);
     }
 
-    int32_t Decoded(webrtc::VideoFrame& image) override {
-      // Post the callback to the right task queue, if needed.
-      if (!task_queue_->IsCurrent()) {
-        task_queue_->PostTask([this, image]() {
-          video_processor_->FrameDecoded(image, simulcast_svc_idx_);
-        });
-        return 0;
-      }
-      video_processor_->FrameDecoded(image, simulcast_svc_idx_);
-      return 0;
-    }
+    int32_t Decoded(webrtc::VideoFrame& image) override;
 
     int32_t Decoded(webrtc::VideoFrame& image,
                     int64_t decode_time_ms) override {