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 34b4af0ec9..7dfd7ca4ad 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 @@ -158,21 +158,34 @@ void RTPSenderVideoFrameTransformerDelegate::OnTransformedFrame( void RTPSenderVideoFrameTransformerDelegate::SendVideo( std::unique_ptr transformed_frame) const { RTC_DCHECK_RUN_ON(transformation_queue_.get()); - RTC_CHECK_EQ(transformed_frame->GetDirection(), - TransformableFrameInterface::Direction::kSender); MutexLock lock(&sender_lock_); if (!sender_) return; - auto* transformed_video_frame = - static_cast(transformed_frame.get()); - sender_->SendVideo(transformed_video_frame->GetPayloadType(), - transformed_video_frame->GetCodecType(), - transformed_video_frame->GetTimestamp(), - transformed_video_frame->GetCaptureTimeMs(), - transformed_video_frame->GetData(), - transformed_video_frame->GetHeader(), - transformed_video_frame->GetExpectedRetransmissionTimeMs(), - transformed_video_frame->Metadata().GetCsrcs()); + if (transformed_frame->GetDirection() == + TransformableFrameInterface::Direction::kSender) { + auto* transformed_video_frame = + static_cast(transformed_frame.get()); + sender_->SendVideo( + transformed_video_frame->GetPayloadType(), + transformed_video_frame->GetCodecType(), + transformed_video_frame->GetTimestamp(), + transformed_video_frame->GetCaptureTimeMs(), + transformed_video_frame->GetData(), + transformed_video_frame->GetHeader(), + transformed_video_frame->GetExpectedRetransmissionTimeMs(), + transformed_video_frame->Metadata().GetCsrcs()); + } else { + auto* transformed_video_frame = + static_cast(transformed_frame.get()); + VideoFrameMetadata metadata = transformed_video_frame->Metadata(); + sender_->SendVideo( + transformed_video_frame->GetPayloadType(), metadata.GetCodec(), + transformed_video_frame->GetTimestamp(), + /*capture_time_ms=*/0, transformed_video_frame->GetData(), + RTPVideoHeader::FromMetadata(metadata), + /*expected_retransmission_time_ms_=*/absl::nullopt, + metadata.GetCsrcs()); + } } void RTPSenderVideoFrameTransformerDelegate::SetVideoStructureUnderLock( diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc index ad1d0b3d99..a3cd81e0d1 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc @@ -12,6 +12,7 @@ #include +#include "api/test/mock_transformable_video_frame.h" #include "rtc_base/event.h" #include "test/gmock.h" #include "test/gtest.h" @@ -22,6 +23,8 @@ namespace webrtc { namespace { using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; using ::testing::SaveArg; using ::testing::WithoutArgs; @@ -217,5 +220,54 @@ TEST_F(RtpSenderVideoFrameTransformerDelegateTest, MetadataAfterSetMetadata) { EXPECT_EQ(metadata.GetCsrcs(), actual_metadata.GetCsrcs()); } +TEST_F(RtpSenderVideoFrameTransformerDelegateTest, + ReceiverFrameConvertedToSenderFrame) { + auto delegate = rtc::make_ref_counted( + &test_sender_, frame_transformer_, + /*ssrc=*/1111, /*csrcs=*/std::vector(), + time_controller_.CreateTaskQueueFactory().get()); + + const uint8_t payload_type = 1; + const uint32_t timestamp = 2; + const std::vector frame_csrcs = {123, 456, 789}; + + auto mock_receiver_frame = + std::make_unique>(); + ON_CALL(*mock_receiver_frame, GetDirection) + .WillByDefault(Return(TransformableFrameInterface::Direction::kReceiver)); + VideoFrameMetadata metadata; + metadata.SetCodec(kVideoCodecVP8); + metadata.SetRTPVideoHeaderCodecSpecifics(RTPVideoHeaderVP8()); + metadata.SetCsrcs(frame_csrcs); + ON_CALL(*mock_receiver_frame, Metadata).WillByDefault(Return(metadata)); + rtc::ArrayView buffer = + (rtc::ArrayView)*EncodedImageBuffer::Create(1); + ON_CALL(*mock_receiver_frame, GetData).WillByDefault(Return(buffer)); + ON_CALL(*mock_receiver_frame, GetPayloadType) + .WillByDefault(Return(payload_type)); + ON_CALL(*mock_receiver_frame, GetTimestamp).WillByDefault(Return(timestamp)); + + rtc::scoped_refptr callback; + EXPECT_CALL(*frame_transformer_, RegisterTransformedFrameSinkCallback) + .WillOnce(SaveArg<0>(&callback)); + delegate->Init(); + ASSERT_TRUE(callback); + + rtc::Event event; + EXPECT_CALL(test_sender_, + SendVideo(payload_type, absl::make_optional(kVideoCodecVP8), + timestamp, /*capture_time_ms=*/0, buffer, _, + /*expected_retransmission_time_ms_=*/ + (absl::optional)absl::nullopt, frame_csrcs)) + .WillOnce(WithoutArgs([&] { + event.Set(); + return true; + })); + + callback->OnTransformedFrame(std::move(mock_receiver_frame)); + + event.Wait(TimeDelta::Seconds(1)); +} + } // namespace } // namespace webrtc