Propagate received video csrcs to encodedframe metadata

Before this, an empty list of CSRCs was always provided up to encoded
insertable streams transforms for remote video tracks, regardless of
the actual CSRCs on received frames. Audio already works correctly.

Bug: chromium:1411614
Change-Id: I51ab4dc5e67a1a35893fefff16c1f057e9047e6b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291539
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tony Herre <herre@google.com>
Cr-Commit-Position: refs/heads/main@{#39240}
This commit is contained in:
Tony Herre 2023-02-01 10:26:01 +01:00 committed by WebRTC LUCI CQ
parent 0507fbdd05
commit 16a8792e0a
4 changed files with 33 additions and 9 deletions

View File

@ -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));

View File

@ -11,6 +11,8 @@
#ifndef MODULES_VIDEO_CODING_FRAME_OBJECT_H_
#define MODULES_VIDEO_CODING_FRAME_OBJECT_H_
#include <vector>
#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<uint32_t>& Csrcs() const { return csrcs_; }
private:
// Reference for mutable access.
rtc::scoped_refptr<EncodedImageBuffer> 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<uint32_t> csrcs_;
// Equal to times nacked of the packet with the highet times nacked
// belonging to this frame.

View File

@ -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<RtpFrameObject> frame_;
const VideoFrameMetadata metadata_;
VideoFrameMetadata metadata_;
const uint32_t ssrc_;
};
} // namespace

View File

@ -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<RtpFrameObject> CreateRtpFrameObject(
const RTPVideoHeader& video_header) {
const RTPVideoHeader& video_header,
std::vector<uint32_t> csrcs) {
RtpPacketInfo packet_info(/*ssrc=*/123, csrcs, /*rtc_timestamp=*/0,
/*receive_time=*/Timestamp::Seconds(123456));
return std::make_unique<RtpFrameObject>(
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<RtpFrameObject> 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<NiceMock<MockFrameTransformer>>());
std::vector<uint32_t> csrcs = {234, 345, 456};
auto delegate =
rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
&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<RtpFrameObject> frame) {
EXPECT_EQ(frame->Csrcs(), csrcs);
});
ON_CALL(*mock_frame_transformer, Transform)
.WillByDefault(
[&callback](std::unique_ptr<TransformableFrameInterface> 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<uint32_t> 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<TransformableFrameInterface> transformable_frame) {
[&](std::unique_ptr<TransformableFrameInterface>
transformable_frame) {
auto frame =
absl::WrapUnique(static_cast<TransformableVideoFrameInterface*>(
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