Refactor FrameGenerator to return VideoFrameBuffer with VideoFrame::UpdateRect

Bug: webrtc:10138
Change-Id: I22079e2630bb1f3bb27472795fe923f9143b3401
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161010
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29973}
diff --git a/api/video/video_frame.cc b/api/video/video_frame.cc
index ccd92ad..d97e3aa 100644
--- a/api/video/video_frame.cc
+++ b/api/video/video_frame.cc
@@ -221,7 +221,7 @@
 }
 
 VideoFrame::Builder& VideoFrame::Builder::set_update_rect(
-    const VideoFrame::UpdateRect& update_rect) {
+    const absl::optional<VideoFrame::UpdateRect>& update_rect) {
   update_rect_ = update_rect;
   return *this;
 }
diff --git a/api/video/video_frame.h b/api/video/video_frame.h
index 9b3761e..f312e7a 100644
--- a/api/video/video_frame.h
+++ b/api/video/video_frame.h
@@ -89,7 +89,7 @@
     Builder& set_color_space(const absl::optional<ColorSpace>& color_space);
     Builder& set_color_space(const ColorSpace* color_space);
     Builder& set_id(uint16_t id);
-    Builder& set_update_rect(const UpdateRect& update_rect);
+    Builder& set_update_rect(const absl::optional<UpdateRect>& update_rect);
     Builder& set_packet_infos(RtpPacketInfos packet_infos);
 
    private:
diff --git a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
index d65cc4f..595e627 100644
--- a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
+++ b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc
@@ -55,8 +55,8 @@
 #endif
 
 TEST_F(TestH264Impl, MAYBE_EncodeDecode) {
-  VideoFrame* input_frame = NextInputFrame();
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*input_frame, nullptr));
+  VideoFrame input_frame = NextInputFrame();
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(input_frame, nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -67,7 +67,7 @@
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
-  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
+  EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
 
   const ColorSpace color_space = *decoded_frame->color_space();
   EXPECT_EQ(ColorSpace::PrimaryID::kUnspecified, color_space.primaries());
@@ -81,8 +81,7 @@
 }
 
 TEST_F(TestH264Impl, MAYBE_DecodedQpEqualsEncodedQp) {
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
diff --git a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
index 53ae285..8983fb0 100644
--- a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
+++ b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc
@@ -105,9 +105,9 @@
   }
 
   std::unique_ptr<VideoFrame> CreateI420AInputFrame() {
-    VideoFrame* input_frame = NextInputFrame();
+    VideoFrame input_frame = NextInputFrame();
     rtc::scoped_refptr<webrtc::I420BufferInterface> yuv_buffer =
-        input_frame->video_frame_buffer()->ToI420();
+        input_frame.video_frame_buffer()->ToI420();
     rtc::scoped_refptr<I420ABufferInterface> yuva_buffer = WrapI420ABuffer(
         yuv_buffer->width(), yuv_buffer->height(), yuv_buffer->DataY(),
         yuv_buffer->StrideY(), yuv_buffer->DataU(), yuv_buffer->StrideU(),
@@ -126,14 +126,14 @@
     if (contains_alpha) {
       video_frame = CreateI420AInputFrame();
     } else {
-      VideoFrame* next_frame = NextInputFrame();
+      VideoFrame next_frame = NextInputFrame();
       video_frame = std::make_unique<VideoFrame>(
           VideoFrame::Builder()
-              .set_video_frame_buffer(next_frame->video_frame_buffer())
-              .set_timestamp_rtp(next_frame->timestamp())
-              .set_timestamp_ms(next_frame->render_time_ms())
-              .set_rotation(next_frame->rotation())
-              .set_id(next_frame->id())
+              .set_video_frame_buffer(next_frame.video_frame_buffer())
+              .set_timestamp_rtp(next_frame.timestamp())
+              .set_timestamp_ms(next_frame.render_time_ms())
+              .set_rotation(next_frame.rotation())
+              .set_id(next_frame.id())
               .build());
     }
     if (supports_augmenting_data_) {
diff --git a/modules/video_coding/codecs/test/video_codec_unittest.cc b/modules/video_coding/codecs/test/video_codec_unittest.cc
index 4acfee2..57fb25d 100644
--- a/modules/video_coding/codecs/test/video_codec_unittest.cc
+++ b/modules/video_coding/codecs/test/video_codec_unittest.cc
@@ -93,13 +93,18 @@
 
 void VideoCodecUnitTest::ModifyCodecSettings(VideoCodec* codec_settings) {}
 
-VideoFrame* VideoCodecUnitTest::NextInputFrame() {
-  VideoFrame* input_frame = input_frame_generator_->NextFrame();
+VideoFrame VideoCodecUnitTest::NextInputFrame() {
+  test::FrameGenerator::VideoFrameData frame_data =
+      input_frame_generator_->NextFrame();
+  VideoFrame input_frame = VideoFrame::Builder()
+                               .set_video_frame_buffer(frame_data.buffer)
+                               .set_update_rect(frame_data.update_rect)
+                               .build();
 
   const uint32_t timestamp =
       last_input_frame_timestamp_ +
       kVideoPayloadTypeFrequency / codec_settings_.maxFramerate;
-  input_frame->set_timestamp(timestamp);
+  input_frame.set_timestamp(timestamp);
 
   last_input_frame_timestamp_ = timestamp;
   return input_frame;
diff --git a/modules/video_coding/codecs/test/video_codec_unittest.h b/modules/video_coding/codecs/test/video_codec_unittest.h
index 1b6a1f9..abf4d96 100644
--- a/modules/video_coding/codecs/test/video_codec_unittest.h
+++ b/modules/video_coding/codecs/test/video_codec_unittest.h
@@ -77,7 +77,7 @@
 
   virtual void ModifyCodecSettings(VideoCodec* codec_settings);
 
-  VideoFrame* NextInputFrame();
+  VideoFrame NextInputFrame();
 
   // Helper method for waiting a single encoded frame.
   bool WaitForEncodedFrame(EncodedImage* frame,
diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
index 2dd2f46..d390534 100644
--- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc
@@ -256,12 +256,11 @@
 
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame,
-                        &codec_specific_info);
+  EncodeAndWaitForFrame(NextInputFrame(), &encoded_frame, &codec_specific_info);
 
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+            encoder_->Encode(NextInputFrame(), nullptr));
 }
 
 TEST_F(TestVp8Impl, InitDecode) {
@@ -271,13 +270,13 @@
 }
 
 TEST_F(TestVp8Impl, OnEncodedImageReportsInfo) {
-  VideoFrame* input_frame = NextInputFrame();
-  input_frame->set_timestamp(kInitialTimestampRtp);
-  input_frame->set_timestamp_us(kInitialTimestampMs *
-                                rtc::kNumMicrosecsPerMillisec);
+  VideoFrame input_frame = NextInputFrame();
+  input_frame.set_timestamp(kInitialTimestampRtp);
+  input_frame.set_timestamp_us(kInitialTimestampMs *
+                               rtc::kNumMicrosecsPerMillisec);
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);
+  EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info);
 
   EXPECT_EQ(kInitialTimestampRtp, encoded_frame.Timestamp());
   EXPECT_EQ(kWidth, static_cast<int>(encoded_frame._encodedWidth));
@@ -285,10 +284,10 @@
 }
 
 TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) {
-  VideoFrame* input_frame = NextInputFrame();
+  VideoFrame input_frame = NextInputFrame();
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);
+  EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info);
 
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
@@ -298,7 +297,7 @@
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   ASSERT_TRUE(decoded_qp);
-  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
+  EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
   EXPECT_EQ(encoded_frame.qp_, *decoded_qp);
 }
 
@@ -376,13 +375,13 @@
 #define MAYBE_AlignedStrideEncodeDecode AlignedStrideEncodeDecode
 #endif
 TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) {
-  VideoFrame* input_frame = NextInputFrame();
-  input_frame->set_timestamp(kInitialTimestampRtp);
-  input_frame->set_timestamp_us(kInitialTimestampMs *
-                                rtc::kNumMicrosecsPerMillisec);
+  VideoFrame input_frame = NextInputFrame();
+  input_frame.set_timestamp(kInitialTimestampRtp);
+  input_frame.set_timestamp_us(kInitialTimestampMs *
+                               rtc::kNumMicrosecsPerMillisec);
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);
+  EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info);
 
   // First frame should be a key frame.
   encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
@@ -394,7 +393,7 @@
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
   // Compute PSNR on all planes (faster than SSIM).
-  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
+  EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
   EXPECT_EQ(kInitialTimestampRtp, decoded_frame->timestamp());
 }
 
@@ -404,10 +403,10 @@
 #define MAYBE_DecodeWithACompleteKeyFrame DecodeWithACompleteKeyFrame
 #endif
 TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
-  VideoFrame* input_frame = NextInputFrame();
+  VideoFrame input_frame = NextInputFrame();
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);
+  EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info);
 
   // Setting complete to false -> should return an error.
   encoded_frame._completeFrame = false;
@@ -425,7 +424,7 @@
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
-  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
+  EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
 }
 
 TEST_F(TestVp8Impl, EncoderWith2TemporalLayers) {
@@ -436,16 +435,15 @@
   // Temporal layer 0.
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame,
-                        &codec_specific_info);
+  EncodeAndWaitForFrame(NextInputFrame(), &encoded_frame, &codec_specific_info);
 
   EXPECT_EQ(0, codec_specific_info.codecSpecific.VP8.temporalIdx);
   // Temporal layer 1.
-  EncodeAndExpectFrameWith(*NextInputFrame(), 1);
+  EncodeAndExpectFrameWith(NextInputFrame(), 1);
   // Temporal layer 0.
-  EncodeAndExpectFrameWith(*NextInputFrame(), 0);
+  EncodeAndExpectFrameWith(NextInputFrame(), 0);
   // Temporal layer 1.
-  EncodeAndExpectFrameWith(*NextInputFrame(), 1);
+  EncodeAndExpectFrameWith(NextInputFrame(), 1);
 }
 
 TEST_F(TestVp8Impl, ScalingDisabledIfAutomaticResizeOff) {
@@ -505,11 +503,11 @@
 
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
-  EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame, &codec_specific_info,
+  EncodeAndWaitForFrame(NextInputFrame(), &encoded_frame, &codec_specific_info,
                         true);
-  EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
-  EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
-  EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
+  EncodeAndExpectFrameWith(NextInputFrame(), 0, true);
+  EncodeAndExpectFrameWith(NextInputFrame(), 0, true);
+  EncodeAndExpectFrameWith(NextInputFrame(), 0, true);
 }
 
 TEST_F(TestVp8Impl, KeepsTimestampOnReencode) {
@@ -547,7 +545,7 @@
 
   auto delta_frame =
       std::vector<VideoFrameType>{VideoFrameType::kVideoFrameDelta};
-  encoder.Encode(*NextInputFrame(), &delta_frame);
+  encoder.Encode(NextInputFrame(), &delta_frame);
 }
 
 TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationNoLayers) {
diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index 4463f18..ef81547 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -126,8 +126,8 @@
 #else
 TEST_F(TestVp9Impl, EncodeDecode) {
 #endif
-  VideoFrame* input_frame = NextInputFrame();
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*input_frame, nullptr));
+  VideoFrame input_frame = NextInputFrame();
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(input_frame, nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -138,7 +138,7 @@
   absl::optional<uint8_t> decoded_qp;
   ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
   ASSERT_TRUE(decoded_frame);
-  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
+  EXPECT_GT(I420PSNR(&input_frame, decoded_frame.get()), 36);
 
   const ColorSpace color_space = *decoded_frame->color_space();
   EXPECT_EQ(ColorSpace::PrimaryID::kUnspecified, color_space.primaries());
@@ -152,8 +152,7 @@
 }
 
 TEST_F(TestVp9Impl, DecodedColorSpaceFromBitstream) {
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -171,8 +170,7 @@
 }
 
 TEST_F(TestVp9Impl, DecodedQpEqualsEncodedQp) {
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -188,8 +186,7 @@
 }
 
 TEST_F(TestVp9Impl, ParserQpEqualsEncodedQp) {
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -208,26 +205,22 @@
             encoder_->InitEncode(&codec_settings_, kSettings));
 
   // Temporal layer 0.
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
   EXPECT_EQ(0, codec_specific_info.codecSpecific.VP9.temporal_idx);
 
   // Temporal layer 1.
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ExpectFrameWith(1);
 
   // Temporal layer 0.
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ExpectFrameWith(0);
 
   // Temporal layer 1.
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ExpectFrameWith(1);
 }
 
@@ -237,8 +230,7 @@
             encoder_->InitEncode(&codec_settings_, kSettings));
 
   SetWaitForEncodedFramesThreshold(2);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   std::vector<EncodedImage> encoded_frame;
   std::vector<CodecSpecificInfo> codec_info;
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_info));
@@ -324,7 +316,7 @@
     for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
       SetWaitForEncodedFramesThreshold(sl_idx + 1);
       EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-                encoder_->Encode(*NextInputFrame(), nullptr));
+                encoder_->Encode(NextInputFrame(), nullptr));
       std::vector<EncodedImage> encoded_frame;
       std::vector<CodecSpecificInfo> codec_specific_info;
       ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -342,7 +334,7 @@
     for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
       SetWaitForEncodedFramesThreshold(sl_idx);
       EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-                encoder_->Encode(*NextInputFrame(), nullptr));
+                encoder_->Encode(NextInputFrame(), nullptr));
       std::vector<EncodedImage> encoded_frame;
       std::vector<CodecSpecificInfo> codec_specific_info;
       ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -386,7 +378,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -407,7 +399,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -431,7 +423,7 @@
   std::vector<VideoFrameType> frame_types = {VideoFrameType::kVideoFrameKey};
   SetWaitForEncodedFramesThreshold(1);
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), &frame_types));
+            encoder_->Encode(NextInputFrame(), &frame_types));
   std::vector<EncodedImage> encoded_frame;
   std::vector<CodecSpecificInfo> codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -443,7 +435,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -463,7 +455,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -492,7 +484,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -536,7 +528,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -554,7 +546,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -570,7 +562,7 @@
   std::vector<VideoFrameType> frame_types = {VideoFrameType::kVideoFrameKey};
   SetWaitForEncodedFramesThreshold(1);
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), &frame_types));
+            encoder_->Encode(NextInputFrame(), &frame_types));
   std::vector<EncodedImage> encoded_frame;
   std::vector<CodecSpecificInfo> codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -587,7 +579,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -614,7 +606,7 @@
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frame;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -647,8 +639,7 @@
   encoder_->SetRates(VideoEncoder::RateControlParameters(
       bitrate_allocation, codec_settings_.maxFramerate));
   SetWaitForEncodedFramesThreshold(2);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
 
   std::vector<EncodedImage> frames;
   std::vector<CodecSpecificInfo> codec_specific;
@@ -665,8 +656,7 @@
             encoder_->InitEncode(&codec_settings_, kSettings));
 
   SetWaitForEncodedFramesThreshold(1);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
 
   ASSERT_TRUE(WaitForEncodedFrames(&frames, &codec_specific));
   EXPECT_FALSE(frames[0].SpatialIndex());
@@ -698,7 +688,7 @@
 
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
 
     std::vector<EncodedImage> frames;
     std::vector<CodecSpecificInfo> codec_specific;
@@ -725,7 +715,7 @@
     // Delta frame.
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     ASSERT_TRUE(WaitForEncodedFrames(&frames, &codec_specific));
 
     ASSERT_EQ(frames[0].SpatialIndex(), 0);
@@ -774,7 +764,7 @@
            ++frame_num) {
         SetWaitForEncodedFramesThreshold(sl_idx + 1);
         EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-                  encoder_->Encode(*NextInputFrame(), nullptr));
+                  encoder_->Encode(NextInputFrame(), nullptr));
         std::vector<EncodedImage> encoded_frame;
         std::vector<CodecSpecificInfo> codec_specific_info;
         ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -832,7 +822,7 @@
            ++frame_num) {
         SetWaitForEncodedFramesThreshold(sl_idx + 1);
         EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-                  encoder_->Encode(*NextInputFrame(), nullptr));
+                  encoder_->Encode(NextInputFrame(), nullptr));
         std::vector<EncodedImage> encoded_frame;
         std::vector<CodecSpecificInfo> codec_specific_info;
         ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
@@ -891,7 +881,7 @@
   for (int i = 0; i < 3; ++i) {
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
     ASSERT_EQ(codec_specific_info.size(), 2u);
   }
@@ -904,8 +894,7 @@
 
   // Encode 1 frame.
   SetWaitForEncodedFramesThreshold(1);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
   ASSERT_EQ(codec_specific_info.size(), 1u);
   EXPECT_EQ(encoded_frame[0]._frameType, VideoFrameType::kVideoFrameDelta);
@@ -922,8 +911,7 @@
 
   // Encode 1 frame.
   SetWaitForEncodedFramesThreshold(2);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
   ASSERT_EQ(codec_specific_info.size(), 2u);
   EXPECT_EQ(encoded_frame[0]._frameType, VideoFrameType::kVideoFrameDelta);
@@ -965,7 +953,7 @@
   for (int i = 0; i < 3; ++i) {
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
     ASSERT_EQ(codec_specific_info.size(), 2u);
   }
@@ -980,7 +968,7 @@
   for (int i = 0; i < 11; ++i) {
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
     ASSERT_EQ(codec_specific_info.size(), 1u);
     EXPECT_EQ(encoded_frame[0]._frameType, VideoFrameType::kVideoFrameDelta);
@@ -999,8 +987,7 @@
 
   // Encode 1 frame.
   SetWaitForEncodedFramesThreshold(2);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frame, &codec_specific_info));
   ASSERT_EQ(codec_specific_info.size(), 2u);
   EXPECT_EQ(encoded_frame[0]._frameType, VideoFrameType::kVideoFrameDelta);
@@ -1045,7 +1032,7 @@
        ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers - 1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frames;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
@@ -1061,8 +1048,7 @@
 
   // All layers are encoded, even though frame dropping should happen.
   SetWaitForEncodedFramesThreshold(num_spatial_layers);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   // Now all 3 layers should be encoded.
   std::vector<EncodedImage> encoded_frames;
   std::vector<CodecSpecificInfo> codec_specific_info;
@@ -1107,7 +1093,7 @@
        ++frame_num) {
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frames;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
@@ -1127,8 +1113,7 @@
   encoder_->SetRates(VideoEncoder::RateControlParameters(
       bitrate_allocation, codec_settings_.maxFramerate));
   SetWaitForEncodedFramesThreshold(1);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   std::vector<EncodedImage> encoded_frames;
   std::vector<CodecSpecificInfo> codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
@@ -1142,7 +1127,7 @@
        ++frame_num) {
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frames;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
@@ -1196,7 +1181,7 @@
        ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     std::vector<EncodedImage> encoded_frames;
     std::vector<CodecSpecificInfo> codec_specific_info;
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
@@ -1206,7 +1191,7 @@
   for (size_t frame_num = 0; frame_num < num_dropped_frames - 2; ++frame_num) {
     SetWaitForEncodedFramesThreshold(2);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     // First layer is dropped due to frame rate cap. The last layer should not
     // be enabled yet.
     std::vector<EncodedImage> encoded_frames;
@@ -1227,7 +1212,7 @@
     // Expect back one frame.
     SetWaitForEncodedFramesThreshold(1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     // First layer is dropped due to frame rate cap. The last layer should not
     // be enabled yet.
     std::vector<EncodedImage> encoded_frames;
@@ -1240,8 +1225,7 @@
   }
 
   SetWaitForEncodedFramesThreshold(2);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   std::vector<EncodedImage> encoded_frames;
   std::vector<CodecSpecificInfo> codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
@@ -1282,8 +1266,7 @@
 
   // Encode one TL0 frame
   SetWaitForEncodedFramesThreshold(num_spatial_layers);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
   EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 0u);
 
@@ -1297,16 +1280,14 @@
   // Next is TL1 frame. The last layer is disabled immediately, but SS structure
   // is not provided here.
   SetWaitForEncodedFramesThreshold(num_spatial_layers - 1);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
   EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 1u);
   EXPECT_FALSE(codec_specific_info[0].codecSpecific.VP9.ss_data_available);
 
   // Next is TL0 frame, which should have delayed SS structure.
   SetWaitForEncodedFramesThreshold(num_spatial_layers - 1);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
   EXPECT_EQ(codec_specific_info[0].codecSpecific.VP9.temporal_idx, 0u);
   EXPECT_TRUE(codec_specific_info[0].codecSpecific.VP9.ss_data_available);
@@ -1330,8 +1311,7 @@
       0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000);
   encoder_->SetRates(VideoEncoder::RateControlParameters(
       bitrate_allocation, codec_settings_.maxFramerate));
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_info));
@@ -1344,8 +1324,7 @@
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
             encoder_->InitEncode(&codec_settings_, kSettings));
 
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -1462,7 +1441,7 @@
        ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers_);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
 
     const bool is_key_frame = frame_num == 0;
     const size_t gof_idx = frame_num % gof.num_frames_in_gof;
@@ -1500,7 +1479,7 @@
        ++frame_num) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers_);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
 
     const bool is_key_frame = frame_num == 0;
     const size_t gof_idx = frame_num % gof.num_frames_in_gof;
@@ -1541,12 +1520,12 @@
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
             encoder_->InitEncode(&codec_settings_, kSettings));
 
-  VideoFrame* input_frame = NextInputFrame();
+  VideoFrame input_frame = NextInputFrame();
   for (size_t frame_num = 0; frame_num < num_frames_to_encode; ++frame_num) {
-    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*input_frame, nullptr));
-    const size_t timestamp = input_frame->timestamp() +
+    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(input_frame, nullptr));
+    const size_t timestamp = input_frame.timestamp() +
                              kVideoPayloadTypeFrequency / input_framerate_fps;
-    input_frame->set_timestamp(static_cast<uint32_t>(timestamp));
+    input_frame.set_timestamp(static_cast<uint32_t>(timestamp));
   }
 
   const size_t num_encoded_frames = GetNumEncodedFrames();
@@ -1593,12 +1572,12 @@
   encoder_->SetRates(VideoEncoder::RateControlParameters(
       bitrate_allocation, codec_settings_.maxFramerate));
 
-  VideoFrame* input_frame = NextInputFrame();
+  VideoFrame input_frame = NextInputFrame();
   for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
-    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*input_frame, nullptr));
-    const size_t timestamp = input_frame->timestamp() +
+    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(input_frame, nullptr));
+    const size_t timestamp = input_frame.timestamp() +
                              kVideoPayloadTypeFrequency / input_framerate_fps;
-    input_frame->set_timestamp(static_cast<uint32_t>(timestamp));
+    input_frame.set_timestamp(static_cast<uint32_t>(timestamp));
   }
 
   std::vector<EncodedImage> encoded_frames;
@@ -1658,8 +1637,8 @@
   if (!encoder_)
     return;
 
-  VideoFrame* input_frame = NextInputFrame();
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*input_frame, nullptr));
+  VideoFrame input_frame = NextInputFrame();
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(input_frame, nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -1672,7 +1651,7 @@
   ASSERT_TRUE(decoded_frame);
 
   // TODO(emircan): Add PSNR for different color depths.
-  EXPECT_GT(I420PSNR(*input_frame->video_frame_buffer()->ToI420(),
+  EXPECT_GT(I420PSNR(*input_frame.video_frame_buffer()->ToI420(),
                      *decoded_frame->video_frame_buffer()->ToI420()),
             31);
 }
@@ -1690,8 +1669,7 @@
   params.framerate_fps = 30.0;
 
   encoder_->SetRates(params);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   EncodedImage encoded_frame;
   CodecSpecificInfo codec_specific_info;
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
@@ -1699,8 +1677,7 @@
   // Set no headroom and encode again.
   params.bandwidth_allocation = DataRate::Zero();
   encoder_->SetRates(params);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info));
 }
 
@@ -1734,7 +1711,7 @@
   for (int i = 0; i < num_frames_to_encode; ++i) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific));
     EXPECT_EQ(encoded_frames.size(), num_spatial_layers);
   }
@@ -1747,7 +1724,7 @@
   for (int i = 0; i < num_frames_to_encode; ++i) {
     SetWaitForEncodedFramesThreshold(num_spatial_layers - 1);
     EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-              encoder_->Encode(*NextInputFrame(), nullptr));
+              encoder_->Encode(NextInputFrame(), nullptr));
     ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific));
     EXPECT_EQ(encoded_frames.size(), num_spatial_layers - 1);
   }
@@ -1757,7 +1734,7 @@
   // Force a key-frame with the last layer still disabled.
   SetWaitForEncodedFramesThreshold(num_spatial_layers - 1);
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), &frame_types));
+            encoder_->Encode(NextInputFrame(), &frame_types));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific));
   EXPECT_EQ(encoded_frames.size(), num_spatial_layers - 1);
   ASSERT_EQ(encoded_frames[0]._frameType, VideoFrameType::kVideoFrameKey);
@@ -1771,8 +1748,7 @@
       bitrate_allocation, codec_settings_.maxFramerate));
 
   SetWaitForEncodedFramesThreshold(num_spatial_layers);
-  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
-            encoder_->Encode(*NextInputFrame(), nullptr));
+  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(NextInputFrame(), nullptr));
   ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific));
   EXPECT_EQ(encoded_frames.size(), num_spatial_layers);
   EXPECT_EQ(encoded_frames[0]._frameType, VideoFrameType::kVideoFrameDelta);
diff --git a/test/frame_generator.cc b/test/frame_generator.cc
index 281102d..6c5ac51 100644
--- a/test/frame_generator.cc
+++ b/test/frame_generator.cc
@@ -68,7 +68,7 @@
     return buffer;
   }
 
-  VideoFrame* NextFrame() override {
+  VideoFrameData NextFrame() override {
     rtc::CritScope lock(&crit_);
 
     rtc::scoped_refptr<VideoFrameBuffer> buffer = nullptr;
@@ -102,13 +102,7 @@
       buffer = I010Buffer::Copy(*buffer->ToI420());
     }
 
-    frame_ =
-        std::make_unique<VideoFrame>(VideoFrame::Builder()
-                                         .set_video_frame_buffer(buffer)
-                                         .set_rotation(webrtc::kVideoRotation_0)
-                                         .set_timestamp_us(0)
-                                         .build());
-    return frame_.get();
+    return VideoFrameData(buffer, absl::nullopt);
   }
 
  private:
@@ -174,7 +168,6 @@
   int width_ RTC_GUARDED_BY(&crit_);
   int height_ RTC_GUARDED_BY(&crit_);
   std::vector<std::unique_ptr<Square>> squares_ RTC_GUARDED_BY(&crit_);
-  std::unique_ptr<VideoFrame> frame_ RTC_GUARDED_BY(&crit_);
 };
 
 class YuvFileGenerator : public FrameGenerator {
@@ -204,7 +197,7 @@
       fclose(file);
   }
 
-  VideoFrame* NextFrame() override {
+  VideoFrameData NextFrame() override {
     // Empty update by default.
     VideoFrame::UpdateRect update_rect{0, 0, 0, 0};
     if (current_display_count_ == 0) {
@@ -218,14 +211,7 @@
     if (++current_display_count_ >= frame_display_count_)
       current_display_count_ = 0;
 
-    temp_frame_ = std::make_unique<VideoFrame>(
-        VideoFrame::Builder()
-            .set_video_frame_buffer(last_read_buffer_)
-            .set_rotation(webrtc::kVideoRotation_0)
-            .set_timestamp_us(0)
-            .set_update_rect(update_rect)
-            .build());
-    return temp_frame_.get();
+    return VideoFrameData(last_read_buffer_, update_rect);
   }
 
   // Returns true if the new frame was loaded.
@@ -262,7 +248,6 @@
   const int frame_display_count_;
   int current_display_count_;
   rtc::scoped_refptr<I420Buffer> last_read_buffer_;
-  std::unique_ptr<VideoFrame> temp_frame_;
 };
 
 // SlideGenerator works similarly to YuvFileGenerator but it fills the frames
@@ -281,19 +266,13 @@
     RTC_DCHECK_GT(frame_repeat_count, 0);
   }
 
-  VideoFrame* NextFrame() override {
+  VideoFrameData NextFrame() override {
     if (current_display_count_ == 0)
       GenerateNewFrame();
     if (++current_display_count_ >= frame_display_count_)
       current_display_count_ = 0;
 
-    frame_ =
-        std::make_unique<VideoFrame>(VideoFrame::Builder()
-                                         .set_video_frame_buffer(buffer_)
-                                         .set_rotation(webrtc::kVideoRotation_0)
-                                         .set_timestamp_us(0)
-                                         .build());
-    return frame_.get();
+    return VideoFrameData(buffer_, absl::nullopt);
   }
 
   // Generates some randomly sized and colored squares scattered
@@ -345,7 +324,6 @@
   int current_display_count_;
   Random random_generator_;
   rtc::scoped_refptr<I420Buffer> buffer_;
-  std::unique_ptr<VideoFrame> frame_;
 };
 
 class ScrollingImageFrameGenerator : public FrameGenerator {
@@ -367,7 +345,8 @@
         target_height_(static_cast<int>(target_height)),
         current_frame_num_(num_frames_ - 1),
         prev_frame_not_scrolled_(false),
-        current_source_frame_(nullptr),
+        current_source_frame_(nullptr, absl::nullopt),
+        current_frame_(nullptr, absl::nullopt),
         file_generator_(files, source_width, source_height, 1) {
     RTC_DCHECK(clock_ != nullptr);
     RTC_DCHECK_GT(num_frames_, 0);
@@ -380,7 +359,7 @@
 
   ~ScrollingImageFrameGenerator() override {}
 
-  VideoFrame* NextFrame() override {
+  VideoFrameData NextFrame() override {
     const int64_t kFrameDisplayTime = scroll_time_ + pause_time_;
     const int64_t now = clock_->TimeInMilliseconds();
     int64_t ms_since_start = now - start_time_;
@@ -403,39 +382,39 @@
 
     bool same_scroll_position =
         prev_frame_not_scrolled_ && cur_frame_not_scrolled;
-    if (!same_scroll_position && current_frame_) {
+    if (!same_scroll_position) {
       // If scrolling is not finished yet, force full frame update.
-      current_frame_->set_update_rect(
-          VideoFrame::UpdateRect{0, 0, target_width_, target_height_});
+      current_frame_.update_rect =
+          VideoFrame::UpdateRect{0, 0, target_width_, target_height_};
     }
     prev_frame_not_scrolled_ = cur_frame_not_scrolled;
 
-    return current_frame_ ? &*current_frame_ : nullptr;
+    return current_frame_;
   }
 
   void UpdateSourceFrame(size_t frame_num) {
     VideoFrame::UpdateRect acc_update{0, 0, 0, 0};
-    while (current_frame_num_ != frame_num ||
-           current_source_frame_ == nullptr) {
+    while (current_frame_num_ != frame_num) {
       current_source_frame_ = file_generator_.NextFrame();
-      if (current_source_frame_)
-        acc_update.Union(current_source_frame_->update_rect());
+      if (current_source_frame_.update_rect) {
+        acc_update.Union(*current_source_frame_.update_rect);
+      }
       current_frame_num_ = (current_frame_num_ + 1) % num_frames_;
     }
-    RTC_DCHECK(current_source_frame_ != nullptr);
-    current_source_frame_->set_update_rect(acc_update);
+    current_source_frame_.update_rect = acc_update;
   }
 
   void CropSourceToScrolledImage(double scroll_factor) {
-    int scroll_margin_x = current_source_frame_->width() - target_width_;
+    int scroll_margin_x = current_source_frame_.buffer->width() - target_width_;
     int pixels_scrolled_x =
         static_cast<int>(scroll_margin_x * scroll_factor + 0.5);
-    int scroll_margin_y = current_source_frame_->height() - target_height_;
+    int scroll_margin_y =
+        current_source_frame_.buffer->height() - target_height_;
     int pixels_scrolled_y =
         static_cast<int>(scroll_margin_y * scroll_factor + 0.5);
 
     rtc::scoped_refptr<I420BufferInterface> i420_buffer =
-        current_source_frame_->video_frame_buffer()->ToI420();
+        current_source_frame_.buffer->ToI420();
     int offset_y =
         (i420_buffer->StrideY() * pixels_scrolled_y) + pixels_scrolled_x;
     int offset_u = (i420_buffer->StrideU() * (pixels_scrolled_y / 2)) +
@@ -444,20 +423,16 @@
                    (pixels_scrolled_x / 2);
 
     VideoFrame::UpdateRect update_rect =
-        current_source_frame_->update_rect().IsEmpty()
+        current_source_frame_.update_rect->IsEmpty()
             ? VideoFrame::UpdateRect{0, 0, 0, 0}
             : VideoFrame::UpdateRect{0, 0, target_width_, target_height_};
-    current_frame_ =
-        VideoFrame::Builder()
-            .set_video_frame_buffer(WrapI420Buffer(
-                target_width_, target_height_, &i420_buffer->DataY()[offset_y],
-                i420_buffer->StrideY(), &i420_buffer->DataU()[offset_u],
-                i420_buffer->StrideU(), &i420_buffer->DataV()[offset_v],
-                i420_buffer->StrideV(), KeepRefUntilDone(i420_buffer)))
-            .set_rotation(kVideoRotation_0)
-            .set_timestamp_us(0)
-            .set_update_rect(update_rect)
-            .build();
+    current_frame_ = VideoFrameData(
+        WrapI420Buffer(target_width_, target_height_,
+                       &i420_buffer->DataY()[offset_y], i420_buffer->StrideY(),
+                       &i420_buffer->DataU()[offset_u], i420_buffer->StrideU(),
+                       &i420_buffer->DataV()[offset_v], i420_buffer->StrideV(),
+                       KeepRefUntilDone(i420_buffer)),
+        update_rect);
   }
 
   Clock* const clock_;
@@ -470,8 +445,8 @@
 
   size_t current_frame_num_;
   bool prev_frame_not_scrolled_;
-  VideoFrame* current_source_frame_;
-  absl::optional<VideoFrame> current_frame_;
+  VideoFrameData current_source_frame_;
+  VideoFrameData current_frame_;
   YuvFileGenerator file_generator_;
 };
 
diff --git a/test/frame_generator.h b/test/frame_generator.h
index 8cc0ac3..95b710f 100644
--- a/test/frame_generator.h
+++ b/test/frame_generator.h
@@ -47,13 +47,20 @@
 
 class FrameGenerator {
  public:
+  struct VideoFrameData {
+    VideoFrameData(rtc::scoped_refptr<VideoFrameBuffer> buffer,
+                   absl::optional<VideoFrame::UpdateRect> update_rect)
+        : buffer(std::move(buffer)), update_rect(update_rect) {}
+
+    rtc::scoped_refptr<VideoFrameBuffer> buffer;
+    absl::optional<VideoFrame::UpdateRect> update_rect;
+  };
+
   virtual ~FrameGenerator() = default;
 
-  // Returns video frame that remains valid until next call.
-  // TODO(kron): Return rtc::scoped_refptr<VideoFrameBuffer> instead of
-  // VideoFrame* and populate the VideoFrame struct in FrameGeneratorCapturer
-  // using VideoFrame::Builder.
-  virtual VideoFrame* NextFrame() = 0;
+  // Returns VideoFrameBuffer and area where most of update was done to set them
+  // on the VideoFrame object. Returned frames can share same buffer.
+  virtual VideoFrameData NextFrame() = 0;
 
   // Change the capture resolution.
   virtual void ChangeResolution(size_t width, size_t height);
diff --git a/test/frame_generator_capturer.cc b/test/frame_generator_capturer.cc
index 9eda4df..5f1c6e0 100644
--- a/test/frame_generator_capturer.cc
+++ b/test/frame_generator_capturer.cc
@@ -176,24 +176,27 @@
 void FrameGeneratorCapturer::InsertFrame() {
   rtc::CritScope cs(&lock_);
   if (sending_) {
-    VideoFrame* frame = frame_generator_->NextFrame();
+    FrameGenerator::VideoFrameData frame_data = frame_generator_->NextFrame();
     // TODO(srte): Use more advanced frame rate control to allow arbritrary
     // fractions.
     int decimation =
         std::round(static_cast<double>(source_fps_) / target_capture_fps_);
     for (int i = 1; i < decimation; ++i)
-      frame = frame_generator_->NextFrame();
-    frame->set_timestamp_us(clock_->TimeInMicroseconds());
-    frame->set_ntp_time_ms(clock_->CurrentNtpInMilliseconds());
-    frame->set_rotation(fake_rotation_);
-    if (fake_color_space_) {
-      frame->set_color_space(fake_color_space_);
-    }
+      frame_data = frame_generator_->NextFrame();
+
+    VideoFrame frame = VideoFrame::Builder()
+                           .set_video_frame_buffer(frame_data.buffer)
+                           .set_rotation(fake_rotation_)
+                           .set_timestamp_us(clock_->TimeInMicroseconds())
+                           .set_ntp_time_ms(clock_->CurrentNtpInMilliseconds())
+                           .set_update_rect(frame_data.update_rect)
+                           .set_color_space(fake_color_space_)
+                           .build();
     if (first_frame_capture_time_ == -1) {
-      first_frame_capture_time_ = frame->ntp_time_ms();
+      first_frame_capture_time_ = frame.ntp_time_ms();
     }
 
-    TestVideoCapturer::OnFrame(*frame);
+    TestVideoCapturer::OnFrame(frame);
   }
 }
 
diff --git a/test/frame_generator_unittest.cc b/test/frame_generator_unittest.cc
index 4be304a..26cb319 100644
--- a/test/frame_generator_unittest.cc
+++ b/test/frame_generator_unittest.cc
@@ -62,11 +62,13 @@
     fwrite(plane_buffer.get(), 1, uv_size, file);
   }
 
-  void CheckFrameAndMutate(VideoFrame* frame, uint8_t y, uint8_t u, uint8_t v) {
+  void CheckFrameAndMutate(const FrameGenerator::VideoFrameData& frame,
+                           uint8_t y,
+                           uint8_t u,
+                           uint8_t v) {
     // Check that frame is valid, has the correct color and timestamp are clean.
-    ASSERT_NE(nullptr, frame);
     rtc::scoped_refptr<I420BufferInterface> i420_buffer =
-        frame->video_frame_buffer()->ToI420();
+        frame.buffer->ToI420();
     const uint8_t* buffer;
     buffer = i420_buffer->DataY();
     for (int i = 0; i < y_size; ++i)
@@ -77,21 +79,13 @@
     buffer = i420_buffer->DataV();
     for (int i = 0; i < uv_size; ++i)
       ASSERT_EQ(v, buffer[i]);
-    EXPECT_EQ(0, frame->ntp_time_ms());
-    EXPECT_EQ(0, frame->render_time_ms());
-    EXPECT_EQ(0u, frame->timestamp());
-
-    // Mutate to something arbitrary non-zero.
-    frame->set_ntp_time_ms(11);
-    frame->set_timestamp_us(12);
-    frame->set_timestamp(13);
   }
 
-  uint64_t Hash(VideoFrame* frame) {
+  uint64_t Hash(const FrameGenerator::VideoFrameData& frame) {
     // Generate a 64-bit hash from the frame's buffer.
     uint64_t hash = 19;
     rtc::scoped_refptr<I420BufferInterface> i420_buffer =
-        frame->video_frame_buffer()->ToI420();
+        frame.buffer->ToI420();
     const uint8_t* buffer = i420_buffer->DataY();
     for (int i = 0; i < y_size; ++i) {
       hash = (37 * hash) + buffer[i];
diff --git a/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc b/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc
index 436418b..70dbcd2 100644
--- a/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc
+++ b/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc
@@ -70,45 +70,6 @@
       sinks_;
 };
 
-// Intercepts generated frames and passes them also to video quality analyzer
-// and to provided sinks.
-class AnalyzingFrameGenerator final : public test::FrameGenerator {
- public:
-  AnalyzingFrameGenerator(
-      std::string stream_label,
-      std::unique_ptr<test::FrameGenerator> delegate,
-      VideoQualityAnalyzerInterface* analyzer,
-      std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>> sinks)
-      : stream_label_(std::move(stream_label)),
-        delegate_(std::move(delegate)),
-        analyzer_(analyzer),
-        sinks_(std::move(sinks)) {}
-  ~AnalyzingFrameGenerator() override = default;
-
-  VideoFrame* NextFrame() override {
-    VideoFrame* frame = delegate_->NextFrame();
-
-    uint16_t frame_id = analyzer_->OnFrameCaptured(stream_label_, *frame);
-    frame->set_id(frame_id);
-
-    for (auto& sink : sinks_) {
-      sink->OnFrame(*frame);
-    }
-    return frame;
-  }
-
-  void ChangeResolution(size_t width, size_t height) override {
-    delegate_->ChangeResolution(width, height);
-  }
-
- private:
-  const std::string stream_label_;
-  std::unique_ptr<test::FrameGenerator> delegate_;
-  VideoQualityAnalyzerInterface* const analyzer_;
-  const std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>>
-      sinks_;
-};
-
 // Implements the video sink, that forwards rendered frames to the video quality
 // analyzer and provided sinks.
 class AnalyzingVideoSink final : public rtc::VideoSinkInterface<VideoFrame> {
diff --git a/test/testsupport/ivf_video_frame_generator.cc b/test/testsupport/ivf_video_frame_generator.cc
index 54d8bc3..559de43 100644
--- a/test/testsupport/ivf_video_frame_generator.cc
+++ b/test/testsupport/ivf_video_frame_generator.cc
@@ -64,20 +64,15 @@
   }
 }
 
-VideoFrame* IvfVideoFrameGenerator::NextFrame() {
+FrameGenerator::VideoFrameData IvfVideoFrameGenerator::NextFrame() {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
   next_frame_decoded_.Reset();
-  if (!file_reader_) {
-    return nullptr;
-  }
+  RTC_CHECK(file_reader_);
   if (!file_reader_->HasMoreFrames()) {
     file_reader_->Reset();
   }
   absl::optional<EncodedImage> image = file_reader_->NextFrame();
-  if (!image) {
-    return nullptr;
-  }
-  RTC_DCHECK(image);
+  RTC_CHECK(image);
   // Last parameter is undocumented and there is no usage of it found.
   RTC_DCHECK_EQ(WEBRTC_VIDEO_CODEC_OK,
                 video_decoder_->Decode(*image, /*missing_frames=*/false,
@@ -87,21 +82,18 @@
                      << kMaxNextFrameWaitTemeoutMs << "ms. Can't continue";
 
   rtc::CritScope crit(&lock_);
-  if (width_ != static_cast<size_t>(next_frame_->width()) ||
-      height_ != static_cast<size_t>(next_frame_->height())) {
+  rtc::scoped_refptr<VideoFrameBuffer> buffer =
+      next_frame_->video_frame_buffer();
+  if (width_ != static_cast<size_t>(buffer->width()) ||
+      height_ != static_cast<size_t>(buffer->height())) {
     // Video adapter has requested a down-scale. Allocate a new buffer and
     // return scaled version.
     rtc::scoped_refptr<I420Buffer> scaled_buffer =
         I420Buffer::Create(width_, height_);
-    scaled_buffer->ScaleFrom(*next_frame_->video_frame_buffer()->ToI420());
-    next_frame_ = VideoFrame::Builder()
-                      .set_video_frame_buffer(scaled_buffer)
-                      .set_rotation(kVideoRotation_0)
-                      .set_timestamp_us(next_frame_->timestamp_us())
-                      .set_id(next_frame_->id())
-                      .build();
+    scaled_buffer->ScaleFrom(*buffer->ToI420());
+    buffer = scaled_buffer;
   }
-  return &next_frame_.value();
+  return VideoFrameData(buffer, next_frame_->update_rect());
 }
 
 void IvfVideoFrameGenerator::ChangeResolution(size_t width, size_t height) {
diff --git a/test/testsupport/ivf_video_frame_generator.h b/test/testsupport/ivf_video_frame_generator.h
index f1f00d7..b0985fc 100644
--- a/test/testsupport/ivf_video_frame_generator.h
+++ b/test/testsupport/ivf_video_frame_generator.h
@@ -33,7 +33,7 @@
   explicit IvfVideoFrameGenerator(const std::string& file_name);
   ~IvfVideoFrameGenerator() override;
 
-  VideoFrame* NextFrame() override;
+  VideoFrameData NextFrame() override;
   void ChangeResolution(size_t width, size_t height) override;
 
  private:
diff --git a/test/testsupport/ivf_video_frame_generator_unittest.cc b/test/testsupport/ivf_video_frame_generator_unittest.cc
index fd469f2..01ae778 100644
--- a/test/testsupport/ivf_video_frame_generator_unittest.cc
+++ b/test/testsupport/ivf_video_frame_generator_unittest.cc
@@ -102,6 +102,13 @@
   }
   void TearDown() override { webrtc::test::RemoveFile(file_name_); }
 
+  VideoFrame BuildFrame(FrameGenerator::VideoFrameData frame_data) {
+    return VideoFrame::Builder()
+        .set_video_frame_buffer(frame_data.buffer)
+        .set_update_rect(frame_data.update_rect)
+        .build();
+  }
+
   void CreateTestVideoFile(VideoCodecType video_codec_type,
                            std::unique_ptr<VideoEncoder> video_encoder) {
     std::unique_ptr<test::FrameGenerator> frame_generator =
@@ -133,16 +140,16 @@
     uint32_t last_frame_timestamp = 0;
 
     for (int i = 0; i < kVideoFramesCount; ++i) {
-      VideoFrame* frame = frame_generator->NextFrame();
+      VideoFrame frame = BuildFrame(frame_generator->NextFrame());
       const uint32_t timestamp =
           last_frame_timestamp +
           kVideoPayloadTypeFrequency / codec_settings.maxFramerate;
-      frame->set_timestamp(timestamp);
+      frame.set_timestamp(timestamp);
 
       last_frame_timestamp = timestamp;
 
-      ASSERT_EQ(WEBRTC_VIDEO_CODEC_OK, video_encoder->Encode(*frame, nullptr));
-      video_frames_.push_back(*frame);
+      ASSERT_EQ(WEBRTC_VIDEO_CODEC_OK, video_encoder->Encode(frame, nullptr));
+      video_frames_.push_back(frame);
     }
 
     ASSERT_TRUE(ivf_writer_callback.WaitForExpectedFramesReceived(
@@ -160,9 +167,8 @@
   IvfVideoFrameGenerator generator(file_name_);
   for (size_t i = 0; i < video_frames_.size(); ++i) {
     auto& expected_frame = video_frames_[i];
-    VideoFrame* actual_frame = generator.NextFrame();
-    EXPECT_TRUE(actual_frame);
-    EXPECT_GT(I420PSNR(&expected_frame, actual_frame), kExpectedMinPsnr);
+    VideoFrame actual_frame = BuildFrame(generator.NextFrame());
+    EXPECT_GT(I420PSNR(&expected_frame, &actual_frame), kExpectedMinPsnr);
   }
 }
 
@@ -171,9 +177,8 @@
   IvfVideoFrameGenerator generator(file_name_);
   for (size_t i = 0; i < video_frames_.size() * 2; ++i) {
     auto& expected_frame = video_frames_[i % video_frames_.size()];
-    VideoFrame* actual_frame = generator.NextFrame();
-    EXPECT_TRUE(actual_frame);
-    EXPECT_GT(I420PSNR(&expected_frame, actual_frame), kExpectedMinPsnr);
+    VideoFrame actual_frame = BuildFrame(generator.NextFrame());
+    EXPECT_GT(I420PSNR(&expected_frame, &actual_frame), kExpectedMinPsnr);
   }
 }
 
@@ -182,9 +187,8 @@
   IvfVideoFrameGenerator generator(file_name_);
   for (size_t i = 0; i < video_frames_.size(); ++i) {
     auto& expected_frame = video_frames_[i];
-    VideoFrame* actual_frame = generator.NextFrame();
-    EXPECT_TRUE(actual_frame);
-    EXPECT_GT(I420PSNR(&expected_frame, actual_frame), kExpectedMinPsnr);
+    VideoFrame actual_frame = BuildFrame(generator.NextFrame());
+    EXPECT_GT(I420PSNR(&expected_frame, &actual_frame), kExpectedMinPsnr);
   }
 }
 
@@ -196,9 +200,8 @@
   IvfVideoFrameGenerator generator(file_name_);
   for (size_t i = 0; i < video_frames_.size(); ++i) {
     auto& expected_frame = video_frames_[i];
-    VideoFrame* actual_frame = generator.NextFrame();
-    EXPECT_TRUE(actual_frame);
-    EXPECT_GT(I420PSNR(&expected_frame, actual_frame), kExpectedMinPsnr);
+    VideoFrame actual_frame = BuildFrame(generator.NextFrame());
+    EXPECT_GT(I420PSNR(&expected_frame, &actual_frame), kExpectedMinPsnr);
   }
 }
 #endif
diff --git a/video/end_to_end_tests/call_operation_tests.cc b/video/end_to_end_tests/call_operation_tests.cc
index 6774c4d..b38062b 100644
--- a/video/end_to_end_tests/call_operation_tests.cc
+++ b/video/end_to_end_tests/call_operation_tests.cc
@@ -131,7 +131,13 @@
         GetVideoSendStream()->SetSource(
             &frame_forwarder, DegradationPreference::MAINTAIN_FRAMERATE);
 
-        frame_forwarder.IncomingCapturedFrame(*frame_generator->NextFrame());
+        test::FrameGenerator::VideoFrameData frame_data =
+            frame_generator->NextFrame();
+        VideoFrame frame = VideoFrame::Builder()
+                               .set_video_frame_buffer(frame_data.buffer)
+                               .set_update_rect(frame_data.update_rect)
+                               .build();
+        frame_forwarder.IncomingCapturedFrame(frame);
       });
 
   EXPECT_TRUE(renderer.Wait())
@@ -195,7 +201,13 @@
             kDefaultWidth, kDefaultHeight, absl::nullopt, absl::nullopt);
         GetVideoSendStream()->SetSource(
             &frame_forwarder, DegradationPreference::MAINTAIN_FRAMERATE);
-        frame_forwarder.IncomingCapturedFrame(*frame_generator->NextFrame());
+        test::FrameGenerator::VideoFrameData frame_data =
+            frame_generator->NextFrame();
+        VideoFrame frame = VideoFrame::Builder()
+                               .set_video_frame_buffer(frame_data.buffer)
+                               .set_update_rect(frame_data.update_rect)
+                               .build();
+        frame_forwarder.IncomingCapturedFrame(frame);
       });
 
   EXPECT_TRUE(renderer.Wait())
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 9178e13..f50afbd 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -482,7 +482,7 @@
             .set_timestamp_rtp(99)
             .set_timestamp_ms(99)
             .set_rotation(kVideoRotation_0)
-            .set_update_rect({offset_x, 0, 1, 1})
+            .set_update_rect(VideoFrame::UpdateRect{offset_x, 0, 1, 1})
             .build();
     frame.set_ntp_time_ms(ntp_time_ms);
     return frame;