1 /*
2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "video/rtp_video_stream_receiver_frame_transformer_delegate.h"
12
13 #include <cstdio>
14 #include <memory>
15 #include <utility>
16 #include <vector>
17
18 #include "absl/memory/memory.h"
19 #include "api/call/transport.h"
20 #include "call/video_receive_stream.h"
21 #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h"
22 #include "rtc_base/event.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 #include "test/mock_frame_transformer.h"
26
27 namespace webrtc {
28 namespace {
29
30 using ::testing::_;
31 using ::testing::ElementsAre;
32 using ::testing::NiceMock;
33 using ::testing::SaveArg;
34
CreateRtpFrameObject(const RTPVideoHeader & video_header)35 std::unique_ptr<RtpFrameObject> CreateRtpFrameObject(
36 const RTPVideoHeader& video_header) {
37 return std::make_unique<RtpFrameObject>(
38 0, 0, true, 0, 0, 0, 0, 0, VideoSendTiming(), 0, video_header.codec,
39 kVideoRotation_0, VideoContentType::UNSPECIFIED, video_header,
40 absl::nullopt, RtpPacketInfos(), EncodedImageBuffer::Create(0));
41 }
42
CreateRtpFrameObject()43 std::unique_ptr<RtpFrameObject> CreateRtpFrameObject() {
44 return CreateRtpFrameObject(RTPVideoHeader());
45 }
46
47 class TestRtpVideoFrameReceiver : public RtpVideoFrameReceiver {
48 public:
TestRtpVideoFrameReceiver()49 TestRtpVideoFrameReceiver() {}
50 ~TestRtpVideoFrameReceiver() override = default;
51
52 MOCK_METHOD(void,
53 ManageFrame,
54 (std::unique_ptr<RtpFrameObject> frame),
55 (override));
56 };
57
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,RegisterTransformedFrameCallbackSinkOnInit)58 TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
59 RegisterTransformedFrameCallbackSinkOnInit) {
60 TestRtpVideoFrameReceiver receiver;
61 auto frame_transformer(rtc::make_ref_counted<MockFrameTransformer>());
62 auto delegate(
63 rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
64 &receiver, frame_transformer, rtc::Thread::Current(),
65 /*remote_ssrc*/ 1111));
66 EXPECT_CALL(*frame_transformer,
67 RegisterTransformedFrameSinkCallback(testing::_, 1111));
68 delegate->Init();
69 }
70
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,UnregisterTransformedFrameSinkCallbackOnReset)71 TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
72 UnregisterTransformedFrameSinkCallbackOnReset) {
73 TestRtpVideoFrameReceiver receiver;
74 auto frame_transformer(rtc::make_ref_counted<MockFrameTransformer>());
75 auto delegate(
76 rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
77 &receiver, frame_transformer, rtc::Thread::Current(),
78 /*remote_ssrc*/ 1111));
79 EXPECT_CALL(*frame_transformer, UnregisterTransformedFrameSinkCallback(1111));
80 delegate->Reset();
81 }
82
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,TransformFrame)83 TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, TransformFrame) {
84 TestRtpVideoFrameReceiver receiver;
85 auto frame_transformer(
86 rtc::make_ref_counted<testing::NiceMock<MockFrameTransformer>>());
87 auto delegate(
88 rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
89 &receiver, frame_transformer, rtc::Thread::Current(),
90 /*remote_ssrc*/ 1111));
91 auto frame = CreateRtpFrameObject();
92 EXPECT_CALL(*frame_transformer, Transform);
93 delegate->TransformFrame(std::move(frame));
94 }
95
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,ManageFrameOnTransformedFrame)96 TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
97 ManageFrameOnTransformedFrame) {
98 rtc::AutoThread main_thread_;
99 TestRtpVideoFrameReceiver receiver;
100 auto mock_frame_transformer(
101 rtc::make_ref_counted<NiceMock<MockFrameTransformer>>());
102 auto delegate =
103 rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
104 &receiver, mock_frame_transformer, rtc::Thread::Current(),
105 /*remote_ssrc*/ 1111);
106
107 rtc::scoped_refptr<TransformedFrameCallback> callback;
108 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameSinkCallback)
109 .WillOnce(SaveArg<0>(&callback));
110 delegate->Init();
111 ASSERT_TRUE(callback);
112
113 EXPECT_CALL(receiver, ManageFrame);
114 ON_CALL(*mock_frame_transformer, Transform)
115 .WillByDefault(
116 [&callback](std::unique_ptr<TransformableFrameInterface> frame) {
117 callback->OnTransformedFrame(std::move(frame));
118 });
119 delegate->TransformFrame(CreateRtpFrameObject());
120 rtc::ThreadManager::ProcessAllMessageQueuesForTesting();
121 }
122
TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,TransformableFrameMetadataHasCorrectValue)123 TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest,
124 TransformableFrameMetadataHasCorrectValue) {
125 TestRtpVideoFrameReceiver receiver;
126 auto mock_frame_transformer =
127 rtc::make_ref_counted<NiceMock<MockFrameTransformer>>();
128 auto delegate =
129 rtc::make_ref_counted<RtpVideoStreamReceiverFrameTransformerDelegate>(
130 &receiver, mock_frame_transformer, rtc::Thread::Current(), 1111);
131 delegate->Init();
132 RTPVideoHeader video_header;
133 video_header.width = 1280u;
134 video_header.height = 720u;
135 RTPVideoHeader::GenericDescriptorInfo& generic =
136 video_header.generic.emplace();
137 generic.frame_id = 10;
138 generic.temporal_index = 3;
139 generic.spatial_index = 2;
140 generic.decode_target_indications = {DecodeTargetIndication::kSwitch};
141 generic.dependencies = {5};
142
143 // Check that the transformable frame passed to the frame transformer has the
144 // correct metadata.
145 EXPECT_CALL(*mock_frame_transformer, Transform)
146 .WillOnce(
147 [](std::unique_ptr<TransformableFrameInterface> transformable_frame) {
148 auto frame =
149 absl::WrapUnique(static_cast<TransformableVideoFrameInterface*>(
150 transformable_frame.release()));
151 ASSERT_TRUE(frame);
152 auto metadata = frame->GetMetadata();
153 EXPECT_EQ(metadata.GetWidth(), 1280u);
154 EXPECT_EQ(metadata.GetHeight(), 720u);
155 EXPECT_EQ(metadata.GetFrameId(), 10);
156 EXPECT_EQ(metadata.GetTemporalIndex(), 3);
157 EXPECT_EQ(metadata.GetSpatialIndex(), 2);
158 EXPECT_THAT(metadata.GetFrameDependencies(), ElementsAre(5));
159 EXPECT_THAT(metadata.GetDecodeTargetIndications(),
160 ElementsAre(DecodeTargetIndication::kSwitch));
161 });
162 // The delegate creates a transformable frame from the RtpFrameObject.
163 delegate->TransformFrame(CreateRtpFrameObject(video_header));
164 }
165
166 } // namespace
167 } // namespace webrtc
168