Implement setMetadata for receiver encoded video frames
This change adds a new function to RTPFrameObject to allow setting the RTPVideoHeader from VideoFrameMetadata. The setMetadata function in TransformableVideoReceiverFrame disallows changing anything other than frameID and dependencies. Change-Id: I74e55ffbe1f426b660c2e243b20358c6a6cc2ffd Bug: chromium:1464853 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/314963 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Palak Agarwal <agpalak@google.com> Reviewed-by: Tony Herre <herre@google.com> Cr-Commit-Position: refs/heads/main@{#40530}
This commit is contained in:
parent
762f193ca4
commit
86162d94d5
@ -297,6 +297,7 @@ rtc_library("rtp_rtcp") {
|
||||
"../../api/video:video_bitrate_allocator",
|
||||
"../../api/video:video_codec_constants",
|
||||
"../../api/video:video_frame",
|
||||
"../../api/video:video_frame_metadata",
|
||||
"../../api/video:video_frame_type",
|
||||
"../../api/video:video_layers_allocation",
|
||||
"../../api/video:video_rtp_headers",
|
||||
|
||||
@ -131,4 +131,7 @@ const RTPVideoHeader& RtpFrameObject::GetRtpVideoHeader() const {
|
||||
return rtp_video_header_;
|
||||
}
|
||||
|
||||
void RtpFrameObject::SetHeaderFromMetadata(const VideoFrameMetadata& metadata) {
|
||||
rtp_video_header_.SetFromMetadata(metadata);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/video/encoded_frame.h"
|
||||
#include "api/video/video_frame_metadata.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -57,6 +58,7 @@ class RtpFrameObject : public EncodedFrame {
|
||||
first_seq_num_ = first_seq_num;
|
||||
}
|
||||
void SetLastSeqNum(uint16_t last_seq_num) { last_seq_num_ = last_seq_num; }
|
||||
void SetHeaderFromMetadata(const VideoFrameMetadata& metadata);
|
||||
|
||||
private:
|
||||
// Reference for mutable access.
|
||||
|
||||
@ -46,7 +46,7 @@ class TransformableVideoReceiverFrame
|
||||
}
|
||||
|
||||
uint8_t GetPayloadType() const override { return frame_->PayloadType(); }
|
||||
uint32_t GetSsrc() const override { return metadata_.GetSsrc(); }
|
||||
uint32_t GetSsrc() const override { return Metadata().GetSsrc(); }
|
||||
uint32_t GetTimestamp() const override { return frame_->Timestamp(); }
|
||||
void SetRTPTimestamp(uint32_t timestamp) override {
|
||||
frame_->SetTimestamp(timestamp);
|
||||
@ -58,9 +58,16 @@ class TransformableVideoReceiverFrame
|
||||
|
||||
VideoFrameMetadata Metadata() const override { return metadata_; }
|
||||
|
||||
void SetMetadata(const VideoFrameMetadata&) override {
|
||||
RTC_DCHECK_NOTREACHED()
|
||||
<< "TransformableVideoReceiverFrame::SetMetadata is not implemented";
|
||||
void SetMetadata(const VideoFrameMetadata& metadata) override {
|
||||
// Create |new_metadata| from existing metadata and change only frameId and
|
||||
// dependencies.
|
||||
VideoFrameMetadata new_metadata = Metadata();
|
||||
new_metadata.SetFrameId(metadata.GetFrameId());
|
||||
new_metadata.SetFrameDependencies(metadata.GetFrameDependencies());
|
||||
RTC_DCHECK(new_metadata == metadata)
|
||||
<< "TransformableVideoReceiverFrame::SetMetadata can be only used to "
|
||||
"change frameID and dependencies";
|
||||
frame_->SetHeaderFromMetadata(new_metadata);
|
||||
}
|
||||
|
||||
std::unique_ptr<RtpFrameObject> ExtractFrame() && {
|
||||
|
||||
@ -32,6 +32,7 @@ namespace {
|
||||
using ::testing::_;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::NotNull;
|
||||
using ::testing::Return;
|
||||
using ::testing::SaveArg;
|
||||
|
||||
@ -191,6 +192,70 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
|
||||
delegate->TransformFrame(CreateRtpFrameObject(video_header, csrcs));
|
||||
}
|
||||
|
||||
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
|
||||
TransformableFrameMetadataHasCorrectValueAfterSetMetadata) {
|
||||
rtc::AutoThread main_thread;
|
||||
TestRtpVideoFrameReceiver receiver;
|
||||
auto mock_frame_transformer =
|
||||
rtc::make_ref_counted<NiceMock<MockFrameTransformer>>();
|
||||
SimulatedClock clock(1000);
|
||||
auto delegate =
|
||||
rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
|
||||
&receiver, &clock, mock_frame_transformer, rtc::Thread::Current(),
|
||||
1111);
|
||||
|
||||
rtc::scoped_refptr<TransformedFrameCallback> callback;
|
||||
EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameSinkCallback)
|
||||
.WillOnce(SaveArg<0>(&callback));
|
||||
delegate->Init();
|
||||
ASSERT_TRUE(callback);
|
||||
|
||||
RTPVideoHeader video_header;
|
||||
RTPVideoHeader::GenericDescriptorInfo& generic =
|
||||
video_header.generic.emplace();
|
||||
generic.frame_id = 10;
|
||||
generic.dependencies = {5};
|
||||
|
||||
std::vector<uint32_t> csrcs = {234, 345, 456};
|
||||
|
||||
// Checks that the recieved RTPFrameObject has the new metadata.
|
||||
EXPECT_CALL(receiver, ManageFrame)
|
||||
.WillOnce([&](std::unique_ptr<RtpFrameObject> frame) {
|
||||
const absl::optional<RTPVideoHeader::GenericDescriptorInfo>&
|
||||
descriptor = frame->GetRtpVideoHeader().generic;
|
||||
if (!descriptor.has_value()) {
|
||||
ADD_FAILURE() << "GenericDescriptorInfo in RTPVideoHeader doesn't "
|
||||
"have a value.";
|
||||
} else {
|
||||
EXPECT_EQ(descriptor->frame_id, 20);
|
||||
EXPECT_THAT(descriptor->dependencies, ElementsAre(15));
|
||||
}
|
||||
EXPECT_EQ(frame->Csrcs(), csrcs);
|
||||
});
|
||||
|
||||
// Sets new metadata to the transformable frame.
|
||||
ON_CALL(*mock_frame_transformer, Transform)
|
||||
.WillByDefault([&](std::unique_ptr<TransformableFrameInterface>
|
||||
transformable_frame) {
|
||||
ASSERT_THAT(transformable_frame, NotNull());
|
||||
auto& video_frame = static_cast<TransformableVideoFrameInterface&>(
|
||||
*transformable_frame);
|
||||
VideoFrameMetadata metadata = video_frame.Metadata();
|
||||
EXPECT_EQ(metadata.GetFrameId(), 10);
|
||||
EXPECT_THAT(metadata.GetFrameDependencies(), ElementsAre(5));
|
||||
EXPECT_EQ(metadata.GetCsrcs(), csrcs);
|
||||
|
||||
metadata.SetFrameId(20);
|
||||
metadata.SetFrameDependencies(std::vector<int64_t>{15});
|
||||
video_frame.SetMetadata(metadata);
|
||||
callback->OnTransformedFrame(std::move(transformable_frame));
|
||||
});
|
||||
|
||||
// The delegate creates a transformable frame from the RtpFrameObject.
|
||||
delegate->TransformFrame(CreateRtpFrameObject(video_header, csrcs));
|
||||
rtc::ThreadManager::ProcessAllMessageQueuesForTesting();
|
||||
}
|
||||
|
||||
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
|
||||
SenderFramesAreConvertedToReceiverFrames) {
|
||||
rtc::AutoThread main_thread_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user