diff --git a/modules/video_coding/frame_object.cc b/modules/video_coding/frame_object.cc index d226dcd013..2b391e381a 100644 --- a/modules/video_coding/frame_object.cc +++ b/modules/video_coding/frame_object.cc @@ -63,6 +63,10 @@ RtpFrameObject::RtpFrameObject( _encodedWidth = rtp_video_header_.width; _encodedHeight = rtp_video_header_.height; + if (packet_infos.begin() != packet_infos.end()) { + csrcs_ = packet_infos.begin()->csrcs(); + } + // EncodedFrame members SetPacketInfos(std::move(packet_infos)); diff --git a/modules/video_coding/frame_object.h b/modules/video_coding/frame_object.h index c6f069f241..df5dae8ac5 100644 --- a/modules/video_coding/frame_object.h +++ b/modules/video_coding/frame_object.h @@ -11,6 +11,8 @@ #ifndef MODULES_VIDEO_CODING_FRAME_OBJECT_H_ #define MODULES_VIDEO_CODING_FRAME_OBJECT_H_ +#include + #include "absl/types/optional.h" #include "api/video/encoded_frame.h" @@ -49,6 +51,8 @@ class RtpFrameObject : public EncodedFrame { uint8_t* mutable_data() { return image_buffer_->data(); } + const std::vector& Csrcs() const { return csrcs_; } + private: // Reference for mutable access. rtc::scoped_refptr image_buffer_; @@ -57,6 +61,7 @@ class RtpFrameObject : public EncodedFrame { uint16_t first_seq_num_; uint16_t last_seq_num_; int64_t last_packet_received_time_; + std::vector csrcs_; // Equal to times nacked of the packet with the highet times nacked // belonging to this frame. diff --git a/video/rtp_video_stream_receiver_frame_transformer_delegate.cc b/video/rtp_video_stream_receiver_frame_transformer_delegate.cc index b1907fa7a2..36b42678da 100644 --- a/video/rtp_video_stream_receiver_frame_transformer_delegate.cc +++ b/video/rtp_video_stream_receiver_frame_transformer_delegate.cc @@ -28,7 +28,9 @@ class TransformableVideoReceiverFrame uint32_t ssrc) : frame_(std::move(frame)), metadata_(frame_->GetRtpVideoHeader().GetAsMetadata()), - ssrc_(ssrc) {} + ssrc_(ssrc) { + metadata_.SetCsrcs(frame_->Csrcs()); + } ~TransformableVideoReceiverFrame() override = default; // Implements TransformableVideoFrameInterface. @@ -67,7 +69,7 @@ class TransformableVideoReceiverFrame private: std::unique_ptr frame_; - const VideoFrameMetadata metadata_; + VideoFrameMetadata metadata_; const uint32_t ssrc_; }; } // namespace diff --git a/video/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc b/video/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc index e757fa20ac..df55f19743 100644 --- a/video/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc +++ b/video/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc @@ -17,6 +17,7 @@ #include "absl/memory/memory.h" #include "api/call/transport.h" +#include "api/units/timestamp.h" #include "call/video_receive_stream.h" #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h" #include "rtc_base/event.h" @@ -33,15 +34,19 @@ using ::testing::NiceMock; using ::testing::SaveArg; std::unique_ptr CreateRtpFrameObject( - const RTPVideoHeader& video_header) { + const RTPVideoHeader& video_header, + std::vector csrcs) { + RtpPacketInfo packet_info(/*ssrc=*/123, csrcs, /*rtc_timestamp=*/0, + /*receive_time=*/Timestamp::Seconds(123456)); return std::make_unique( 0, 0, true, 0, 0, 0, 0, 0, VideoSendTiming(), 0, video_header.codec, kVideoRotation_0, VideoContentType::UNSPECIFIED, video_header, - absl::nullopt, RtpPacketInfos(), EncodedImageBuffer::Create(0)); + absl::nullopt, RtpPacketInfos({packet_info}), + EncodedImageBuffer::Create(0)); } std::unique_ptr CreateRtpFrameObject() { - return CreateRtpFrameObject(RTPVideoHeader()); + return CreateRtpFrameObject(RTPVideoHeader(), /*csrcs=*/{}); } class TestRtpVideoFrameReceiver : public RtpVideoFrameReceiver { @@ -99,6 +104,7 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, TestRtpVideoFrameReceiver receiver; auto mock_frame_transformer( rtc::make_ref_counted>()); + std::vector csrcs = {234, 345, 456}; auto delegate = rtc::make_ref_counted( &receiver, mock_frame_transformer, rtc::Thread::Current(), @@ -110,13 +116,16 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, delegate->Init(); ASSERT_TRUE(callback); - EXPECT_CALL(receiver, ManageFrame); + EXPECT_CALL(receiver, ManageFrame) + .WillOnce([&](std::unique_ptr frame) { + EXPECT_EQ(frame->Csrcs(), csrcs); + }); ON_CALL(*mock_frame_transformer, Transform) .WillByDefault( [&callback](std::unique_ptr frame) { callback->OnTransformedFrame(std::move(frame)); }); - delegate->TransformFrame(CreateRtpFrameObject()); + delegate->TransformFrame(CreateRtpFrameObject(RTPVideoHeader(), csrcs)); rtc::ThreadManager::ProcessAllMessageQueuesForTesting(); } @@ -140,11 +149,14 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, generic.decode_target_indications = {DecodeTargetIndication::kSwitch}; generic.dependencies = {5}; + std::vector csrcs = {234, 345, 456}; + // Check that the transformable frame passed to the frame transformer has the // correct metadata. EXPECT_CALL(*mock_frame_transformer, Transform) .WillOnce( - [](std::unique_ptr transformable_frame) { + [&](std::unique_ptr + transformable_frame) { auto frame = absl::WrapUnique(static_cast( transformable_frame.release())); @@ -158,9 +170,10 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, EXPECT_THAT(metadata.GetFrameDependencies(), ElementsAre(5)); EXPECT_THAT(metadata.GetDecodeTargetIndications(), ElementsAre(DecodeTargetIndication::kSwitch)); + EXPECT_EQ(metadata.GetCsrcs(), csrcs); }); // The delegate creates a transformable frame from the RtpFrameObject. - delegate->TransformFrame(CreateRtpFrameObject(video_header)); + delegate->TransformFrame(CreateRtpFrameObject(video_header, csrcs)); } } // namespace