diff --git a/audio/channel_receive_frame_transformer_delegate_unittest.cc b/audio/channel_receive_frame_transformer_delegate_unittest.cc index b08dcff78d..38ceb6d96d 100644 --- a/audio/channel_receive_frame_transformer_delegate_unittest.cc +++ b/audio/channel_receive_frame_transformer_delegate_unittest.cc @@ -146,7 +146,7 @@ TEST(ChannelReceiveFrameTransformerDelegateTest, delegate->Reset(); EXPECT_CALL(mock_channel, ReceiveFrame).Times(0); - delegate->OnTransformedFrame(std::make_unique()); + delegate->OnTransformedFrame(std::make_unique()); rtc::ThreadManager::ProcessAllMessageQueuesForTesting(); } diff --git a/audio/channel_send_frame_transformer_delegate.cc b/audio/channel_send_frame_transformer_delegate.cc index a63f5706ba..e07e1a70c8 100644 --- a/audio/channel_send_frame_transformer_delegate.cc +++ b/audio/channel_send_frame_transformer_delegate.cc @@ -160,19 +160,25 @@ void ChannelSendFrameTransformerDelegate::SendFrame( std::unique_ptr frame) const { MutexLock lock(&send_lock_); RTC_DCHECK_RUN_ON(encoder_queue_); - RTC_CHECK_EQ(frame->GetDirection(), - TransformableFrameInterface::Direction::kSender); if (!send_frame_callback_) return; + uint32_t rtp_start_timestamp = 0; + if (frame->GetDirection() == + TransformableFrameInterface::Direction::kSender) { + auto* outgoing_frame = + static_cast(frame.get()); + rtp_start_timestamp = outgoing_frame->GetStartTimestamp(); + } auto* transformed_frame = - static_cast(frame.get()); + static_cast(frame.get()); send_frame_callback_( InterfaceFrameTypeToInternalFrameType(transformed_frame->Type()), transformed_frame->GetPayloadType(), - transformed_frame->GetTimestamp() - - transformed_frame->GetStartTimestamp(), + transformed_frame->GetTimestamp() - rtp_start_timestamp, transformed_frame->GetData(), - *transformed_frame->AbsoluteCaptureTimestamp()); + transformed_frame->AbsoluteCaptureTimestamp() + ? *transformed_frame->AbsoluteCaptureTimestamp() + : 0); } std::unique_ptr CloneSenderAudioFrame( diff --git a/audio/channel_send_frame_transformer_delegate_unittest.cc b/audio/channel_send_frame_transformer_delegate_unittest.cc index 9196bcb41f..998a6e689a 100644 --- a/audio/channel_send_frame_transformer_delegate_unittest.cc +++ b/audio/channel_send_frame_transformer_delegate_unittest.cc @@ -22,7 +22,10 @@ namespace webrtc { namespace { +using ::testing::_; +using ::testing::ElementsAre; using ::testing::NiceMock; +using ::testing::Return; using ::testing::SaveArg; class MockChannelSend { @@ -48,6 +51,18 @@ class MockChannelSend { } }; +std::unique_ptr CreateMockReceiverFrame() { + const uint8_t mock_data[] = {1, 2, 3, 4}; + std::unique_ptr mock_frame = + std::make_unique(); + rtc::ArrayView payload(mock_data); + ON_CALL(*mock_frame, GetData).WillByDefault(Return(payload)); + ON_CALL(*mock_frame, GetPayloadType).WillByDefault(Return(0)); + ON_CALL(*mock_frame, GetDirection) + .WillByDefault(Return(TransformableFrameInterface::Direction::kReceiver)); + return mock_frame; +} + // Test that the delegate registers itself with the frame transformer on Init(). TEST(ChannelSendFrameTransformerDelegateTest, RegisterTransformedFrameCallbackOnInit) { @@ -104,6 +119,36 @@ TEST(ChannelSendFrameTransformerDelegateTest, channel_queue.WaitForPreviouslyPostedTasks(); } +// Test that when the delegate receives a Incoming frame from the frame +// transformer, it passes it to the channel using the SendFrameCallback. +TEST(ChannelSendFrameTransformerDelegateTest, + TransformRunsChannelSendCallbackForIncomingFrame) { + TaskQueueForTest channel_queue("channel_queue"); + rtc::scoped_refptr mock_frame_transformer = + rtc::make_ref_counted>(); + MockChannelSend mock_channel; + rtc::scoped_refptr delegate = + rtc::make_ref_counted( + mock_channel.callback(), mock_frame_transformer, &channel_queue); + rtc::scoped_refptr callback; + EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback) + .WillOnce(SaveArg<0>(&callback)); + delegate->Init(); + ASSERT_TRUE(callback); + + const uint8_t data[] = {1, 2, 3, 4}; + EXPECT_CALL(mock_channel, SendFrame).Times(0); + EXPECT_CALL(mock_channel, SendFrame(_, 0, 0, ElementsAre(1, 2, 3, 4), _)); + ON_CALL(*mock_frame_transformer, Transform) + .WillByDefault( + [&callback](std::unique_ptr frame) { + callback->OnTransformedFrame(CreateMockReceiverFrame()); + }); + delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, 0, data, sizeof(data), + 0, 0); + channel_queue.WaitForPreviouslyPostedTasks(); +} + // Test that if the delegate receives a transformed frame after it has been // reset, it does not run the SendFrameCallback, as the channel is destroyed // after resetting the delegate. @@ -119,7 +164,7 @@ TEST(ChannelSendFrameTransformerDelegateTest, delegate->Reset(); EXPECT_CALL(mock_channel, SendFrame).Times(0); - delegate->OnTransformedFrame(std::make_unique()); + delegate->OnTransformedFrame(std::make_unique()); channel_queue.WaitForPreviouslyPostedTasks(); } diff --git a/test/mock_transformable_frame.h b/test/mock_transformable_frame.h index 9361aaeb06..35b8d92d22 100644 --- a/test/mock_transformable_frame.h +++ b/test/mock_transformable_frame.h @@ -16,14 +16,19 @@ namespace webrtc { -class MockTransformableFrame : public TransformableFrameInterface { +class MockTransformableAudioFrame : public TransformableAudioFrameInterface { public: MOCK_METHOD(rtc::ArrayView, GetData, (), (const, override)); + MOCK_METHOD(rtc::ArrayView, + GetContributingSources, + (), + (const, override)); MOCK_METHOD(void, SetData, (rtc::ArrayView), (override)); MOCK_METHOD(uint8_t, GetPayloadType, (), (const, override)); MOCK_METHOD(uint32_t, GetSsrc, (), (const, override)); MOCK_METHOD(uint32_t, GetTimestamp, (), (const, override)); MOCK_METHOD(void, SetRTPTimestamp, (uint32_t), (override)); + MOCK_METHOD(Direction, GetDirection, (), (const, override)); }; } // namespace webrtc