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