• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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