xref: /aosp_15_r20/external/webrtc/modules/video_coding/video_receiver2_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2022 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 "modules/video_coding/video_receiver2.h"
12 
13 #include <memory>
14 #include <utility>
15 
16 #include "api/test/mock_video_decoder.h"
17 #include "api/units/timestamp.h"
18 #include "api/video/encoded_frame.h"
19 #include "common_video/test/utilities.h"
20 #include "modules/video_coding/decoder_database.h"
21 #include "modules/video_coding/timing/timing.h"
22 #include "system_wrappers/include/clock.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 #include "test/scoped_key_value_config.h"
26 
27 namespace webrtc {
28 namespace {
29 
30 using ::testing::_;
31 using ::testing::NiceMock;
32 using ::testing::Return;
33 
34 class MockVCMReceiveCallback : public VCMReceiveCallback {
35  public:
36   MockVCMReceiveCallback() = default;
37 
38   MOCK_METHOD(
39       int32_t,
40       FrameToRender,
41       (VideoFrame&, absl::optional<uint8_t>, TimeDelta, VideoContentType),
42       (override));
43   MOCK_METHOD(void, OnIncomingPayloadType, (int), (override));
44   MOCK_METHOD(void,
45               OnDecoderInfoChanged,
46               (const VideoDecoder::DecoderInfo&),
47               (override));
48 };
49 
50 class TestEncodedFrame : public EncodedFrame {
51  public:
TestEncodedFrame(int payload_type)52   explicit TestEncodedFrame(int payload_type) {
53     _payloadType = payload_type;
54     SetPacketInfos(CreatePacketInfos(3));
55   }
56 
SetReceivedTime(webrtc::Timestamp received_time)57   void SetReceivedTime(webrtc::Timestamp received_time) {
58     received_time_ = received_time;
59   }
60 
ReceivedTime() const61   int64_t ReceivedTime() const override { return received_time_.ms(); }
62 
RenderTime() const63   int64_t RenderTime() const override { return _renderTimeMs; }
64 
65  private:
66   webrtc::Timestamp received_time_ = webrtc::Timestamp::Millis(0);
67 };
68 
69 class VideoReceiver2Test : public ::testing::Test {
70  protected:
VideoReceiver2Test()71   VideoReceiver2Test() {
72     receiver_.RegisterReceiveCallback(&receive_callback_);
73   }
74 
RegisterReceiveCodecSettings(int payload_type,VideoCodecType codec_type=kVideoCodecVP8)75   void RegisterReceiveCodecSettings(
76       int payload_type,
77       VideoCodecType codec_type = kVideoCodecVP8) {
78     VideoDecoder::Settings settings;
79     settings.set_codec_type(codec_type);
80     settings.set_max_render_resolution({10, 10});
81     settings.set_number_of_cores(4);
82     receiver_.RegisterReceiveCodec(payload_type, settings);
83   }
84 
85   test::ScopedKeyValueConfig field_trials_;
86   SimulatedClock clock_{Timestamp::Millis(1337)};
87   VCMTiming timing_{&clock_, field_trials_};
88   NiceMock<MockVCMReceiveCallback> receive_callback_;
89   VideoReceiver2 receiver_{&clock_, &timing_, field_trials_};
90 };
91 
TEST_F(VideoReceiver2Test,RegisterExternalDecoder)92 TEST_F(VideoReceiver2Test, RegisterExternalDecoder) {
93   constexpr int kPayloadType = 1;
94   ASSERT_FALSE(receiver_.IsExternalDecoderRegistered(kPayloadType));
95 
96   // Register a decoder, check for correctness, then unregister and check again.
97   auto decoder = std::make_unique<NiceMock<MockVideoDecoder>>();
98   bool decoder_deleted = false;
99   EXPECT_CALL(*decoder, Destruct).WillOnce([&decoder_deleted] {
100     decoder_deleted = true;
101   });
102   receiver_.RegisterExternalDecoder(std::move(decoder), kPayloadType);
103   EXPECT_TRUE(receiver_.IsExternalDecoderRegistered(kPayloadType));
104   receiver_.RegisterExternalDecoder(nullptr, kPayloadType);
105   EXPECT_TRUE(decoder_deleted);
106   EXPECT_FALSE(receiver_.IsExternalDecoderRegistered(kPayloadType));
107 }
108 
TEST_F(VideoReceiver2Test,RegisterReceiveCodecs)109 TEST_F(VideoReceiver2Test, RegisterReceiveCodecs) {
110   constexpr int kPayloadType = 1;
111 
112   RegisterReceiveCodecSettings(kPayloadType);
113 
114   TestEncodedFrame frame(kPayloadType);
115 
116   // A decoder has not been registered yet, so an attempt to decode should fail.
117   EXPECT_EQ(receiver_.Decode(&frame), VCM_NO_CODEC_REGISTERED);
118 
119   // Register a decoder that will accept the Decode operation.
120   auto decoder = std::make_unique<NiceMock<MockVideoDecoder>>();
121   EXPECT_CALL(*decoder, RegisterDecodeCompleteCallback)
122       .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
123   EXPECT_CALL(*decoder, Decode).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
124   EXPECT_CALL(*decoder, Release).WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
125 
126   // Register the decoder. Note that this moves ownership of the mock object
127   // to the `receiver_`.
128   receiver_.RegisterExternalDecoder(std::move(decoder), kPayloadType);
129   EXPECT_TRUE(receiver_.IsExternalDecoderRegistered(kPayloadType));
130 
131   EXPECT_CALL(receive_callback_, OnIncomingPayloadType(kPayloadType));
132   EXPECT_CALL(receive_callback_, OnDecoderInfoChanged);
133 
134   // Call `Decode`. This triggers the above call expectations.
135   EXPECT_EQ(receiver_.Decode(&frame), VCM_OK);
136 
137   // Unregister the decoder and verify.
138   receiver_.RegisterExternalDecoder(nullptr, kPayloadType);
139   EXPECT_FALSE(receiver_.IsExternalDecoderRegistered(kPayloadType));
140 
141   receiver_.DeregisterReceiveCodec(kPayloadType);
142 }
143 
144 }  // namespace
145 }  // namespace webrtc
146