diff --git a/video/frame_encode_metadata_writer.cc b/video/frame_encode_metadata_writer.cc index 999ca7481c..13d63728a4 100644 --- a/video/frame_encode_metadata_writer.cc +++ b/video/frame_encode_metadata_writer.cc @@ -217,7 +217,9 @@ FrameEncodeMetadataWriter::UpdateBitstream( void FrameEncodeMetadataWriter::Reset() { rtc::CritScope cs(&lock_); - timing_frames_info_.clear(); + for (auto& info : timing_frames_info_) { + info.frames.clear(); + } last_timing_frame_time_ms_ = -1; reordered_frames_logged_messages_ = 0; stalled_encoder_logged_messages_ = 0; @@ -242,20 +244,20 @@ FrameEncodeMetadataWriter::ExtractEncodeStartTimeAndFillMetadata( EncodedImageCallback::DropReason::kDroppedByEncoder); metadata_list->pop_front(); } + + encoded_image->content_type_ = + (codec_settings_.mode == VideoCodecMode::kScreensharing) + ? VideoContentType::SCREENSHARE + : VideoContentType::UNSPECIFIED; + if (!metadata_list->empty() && metadata_list->front().rtp_timestamp == encoded_image->Timestamp()) { result.emplace(metadata_list->front().encode_start_time_ms); - encoded_image->capture_time_ms_ = metadata_list->front().timestamp_us / 1000; encoded_image->ntp_time_ms_ = metadata_list->front().ntp_time_ms; encoded_image->rotation_ = metadata_list->front().rotation; encoded_image->SetColorSpace(metadata_list->front().color_space); - encoded_image->content_type_ = - (codec_settings_.mode == VideoCodecMode::kScreensharing) - ? VideoContentType::SCREENSHARE - : VideoContentType::UNSPECIFIED; - metadata_list->pop_front(); } else { ++reordered_frames_logged_messages_; diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc index d20025dea5..1cf9436892 100644 --- a/video/video_stream_encoder_unittest.cc +++ b/video/video_stream_encoder_unittest.cc @@ -839,6 +839,15 @@ class VideoStreamEncoderTest : public ::testing::Test { EXPECT_EQ(expected_width, width); } + void CheckLastFrameRotationMatches(VideoRotation expected_rotation) { + VideoRotation rotation; + { + rtc::CritScope lock(&crit_); + rotation = last_rotation_; + } + EXPECT_EQ(expected_rotation, rotation); + } + void ExpectDroppedFrame() { EXPECT_FALSE(encoded_frame_event_.Wait(100)); } bool WaitForFrame(int64_t timeout_ms) { @@ -902,6 +911,7 @@ class VideoStreamEncoderTest : public ::testing::Test { last_capture_time_ms_ = encoded_image.capture_time_ms_; last_width_ = encoded_image._encodedWidth; last_height_ = encoded_image._encodedHeight; + last_rotation_ = encoded_image.rotation_; if (num_received_layers_ == num_expected_layers_) { encoded_frame_event_.Set(); } @@ -926,6 +936,7 @@ class VideoStreamEncoderTest : public ::testing::Test { int64_t last_capture_time_ms_ = 0; uint32_t last_height_ = 0; uint32_t last_width_ = 0; + VideoRotation last_rotation_ = kVideoRotation_0; size_t num_expected_layers_ = 1; size_t num_received_layers_ = 0; bool expect_frames_ = true; @@ -3921,4 +3932,43 @@ TEST_F(VideoStreamEncoderTest, RewritesH264BitstreamWithNonOptimalSps) { video_stream_encoder_->Stop(); } +TEST_F(VideoStreamEncoderTest, CopiesVideoFrameMetadataAfterDownscale) { + const int kFrameWidth = 1280; + const int kFrameHeight = 720; + const int kTargetBitrateBps = 300000; // To low for HD resolution. + + video_stream_encoder_->OnBitrateUpdated( + DataRate::bps(kTargetBitrateBps), DataRate::bps(kTargetBitrateBps), 0, 0); + video_stream_encoder_->WaitUntilTaskQueueIsIdle(); + + // Insert a first video frame. It should be dropped because of downscale in + // resolution. + int64_t timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; + VideoFrame frame = CreateFrame(timestamp_ms, kFrameWidth, kFrameHeight); + frame.set_rotation(kVideoRotation_270); + video_source_.IncomingCapturedFrame(frame); + + ExpectDroppedFrame(); + + // Second frame is downscaled. + timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; + frame = CreateFrame(timestamp_ms, kFrameWidth / 2, kFrameHeight / 2); + frame.set_rotation(kVideoRotation_90); + video_source_.IncomingCapturedFrame(frame); + + WaitForEncodedFrame(timestamp_ms); + sink_.CheckLastFrameRotationMatches(kVideoRotation_90); + + // Insert another frame, also downscaled. + timestamp_ms = fake_clock_.TimeNanos() / rtc::kNumNanosecsPerMillisec; + frame = CreateFrame(timestamp_ms, kFrameWidth / 2, kFrameHeight / 2); + frame.set_rotation(kVideoRotation_180); + video_source_.IncomingCapturedFrame(frame); + + WaitForEncodedFrame(timestamp_ms); + sink_.CheckLastFrameRotationMatches(kVideoRotation_180); + + video_stream_encoder_->Stop(); +} + } // namespace webrtc