blob: 68bc307e65d1e583b01e2ccd778d00bd8334dc3a [file] [log] [blame]
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +02001/*
2 * Copyright (c) 2016 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/generic_decoder.h"
12
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000013#include <cstdint>
Danil Chapovalov7b78a312021-08-06 12:30:02 +020014#include <memory>
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020015#include <vector>
16
17#include "absl/types/optional.h"
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000018#include "api/array_view.h"
19#include "api/rtp_packet_infos.h"
Danil Chapovalov355b8d22021-08-13 16:50:37 +020020#include "api/video_codecs/video_decoder.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020021#include "common_video/test/utilities.h"
Rasmus Brandtc4d253c2022-05-25 12:03:35 +020022#include "modules/video_coding/timing/timing.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020023#include "system_wrappers/include/clock.h"
24#include "test/fake_decoder.h"
25#include "test/gmock.h"
26#include "test/gtest.h"
Jonas Orelande02f9ee2022-03-25 12:43:14 +010027#include "test/scoped_key_value_config.h"
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000028#include "test/time_controller/simulated_time_controller.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020029
30namespace webrtc {
31namespace video_coding {
32
33class ReceiveCallback : public VCMReceiveCallback {
34 public:
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000035 int32_t FrameToRender(VideoFrame& frame,
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020036 absl::optional<uint8_t> qp,
Philipp Hancked970b092022-06-17 07:34:23 +020037 TimeDelta decode_time,
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020038 VideoContentType content_type) override {
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000039 frames_.push_back(frame);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020040 return 0;
41 }
42
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000043 absl::optional<VideoFrame> PopLastFrame() {
44 if (frames_.empty())
45 return absl::nullopt;
46 auto ret = frames_.front();
47 frames_.pop_back();
48 return ret;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020049 }
50
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000051 rtc::ArrayView<const VideoFrame> GetAllFrames() const { return frames_; }
52
53 void OnDroppedFrames(uint32_t frames_dropped) {
54 frames_dropped_ += frames_dropped;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020055 }
56
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000057 uint32_t frames_dropped() const { return frames_dropped_; }
58
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020059 private:
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000060 std::vector<VideoFrame> frames_;
61 uint32_t frames_dropped_ = 0;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020062};
63
64class GenericDecoderTest : public ::testing::Test {
65 protected:
66 GenericDecoderTest()
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000067 : time_controller_(Timestamp::Zero()),
68 clock_(time_controller_.GetClock()),
69 timing_(time_controller_.GetClock(), field_trials_),
70 decoder_(time_controller_.GetTaskQueueFactory()),
71 vcm_callback_(&timing_, time_controller_.GetClock(), field_trials_),
Danil Chapovalov7b78a312021-08-06 12:30:02 +020072 generic_decoder_(&decoder_) {}
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020073
74 void SetUp() override {
75 generic_decoder_.RegisterDecodeCompleteCallback(&vcm_callback_);
76 vcm_callback_.SetUserReceiveCallback(&user_callback_);
Danil Chapovalov355b8d22021-08-13 16:50:37 +020077 VideoDecoder::Settings settings;
78 settings.set_codec_type(kVideoCodecVP8);
79 settings.set_max_render_resolution({10, 10});
80 settings.set_number_of_cores(4);
81 generic_decoder_.Configure(settings);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020082 }
83
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000084 GlobalSimulatedTimeController time_controller_;
85 Clock* const clock_;
Jonas Orelande02f9ee2022-03-25 12:43:14 +010086 test::ScopedKeyValueConfig field_trials_;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020087 VCMTiming timing_;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020088 webrtc::test::FakeDecoder decoder_;
89 VCMDecodedFrameCallback vcm_callback_;
90 VCMGenericDecoder generic_decoder_;
91 ReceiveCallback user_callback_;
92};
93
Chen Xingf00bf422019-06-20 10:05:55 +020094TEST_F(GenericDecoderTest, PassesPacketInfos) {
95 RtpPacketInfos packet_infos = CreatePacketInfos(3);
96 VCMEncodedFrame encoded_frame;
97 encoded_frame.SetPacketInfos(packet_infos);
Evan Shrubsole1c51ec42022-08-08 11:21:26 +000098 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
99 time_controller_.AdvanceTime(TimeDelta::Millis(10));
100 absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
Chen Xingf00bf422019-06-20 10:05:55 +0200101 ASSERT_TRUE(decoded_frame.has_value());
102 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
103}
104
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000105TEST_F(GenericDecoderTest, FrameDroppedIfTooManyFramesInFlight) {
106 constexpr int kMaxFramesInFlight = 10;
107 decoder_.SetDelayedDecoding(10);
108 for (int i = 0; i < kMaxFramesInFlight + 1; ++i) {
109 VCMEncodedFrame encoded_frame;
110 encoded_frame.SetTimestamp(90000 * i);
111 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
112 }
113
114 time_controller_.AdvanceTime(TimeDelta::Millis(10));
115
116 auto frames = user_callback_.GetAllFrames();
117 ASSERT_EQ(10U, frames.size());
118 // Expect that the first frame was dropped since all decodes released at the
119 // same time and the oldest frame info is the first one dropped.
120 EXPECT_EQ(frames[0].timestamp(), 90000u);
121 EXPECT_EQ(1u, user_callback_.frames_dropped());
122}
123
Chen Xingf00bf422019-06-20 10:05:55 +0200124TEST_F(GenericDecoderTest, PassesPacketInfosForDelayedDecoders) {
125 RtpPacketInfos packet_infos = CreatePacketInfos(3);
126 decoder_.SetDelayedDecoding(100);
127
128 {
129 // Ensure the original frame is destroyed before the decoding is completed.
130 VCMEncodedFrame encoded_frame;
131 encoded_frame.SetPacketInfos(packet_infos);
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000132 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
Chen Xingf00bf422019-06-20 10:05:55 +0200133 }
134
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000135 time_controller_.AdvanceTime(TimeDelta::Millis(200));
136 absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
Chen Xingf00bf422019-06-20 10:05:55 +0200137 ASSERT_TRUE(decoded_frame.has_value());
138 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
139}
140
Johannes Kron111e9812020-10-26 13:54:40 +0100141TEST_F(GenericDecoderTest, MaxCompositionDelayNotSetByDefault) {
142 VCMEncodedFrame encoded_frame;
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000143 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
144 time_controller_.AdvanceTime(TimeDelta::Millis(10));
145 absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
Johannes Kron111e9812020-10-26 13:54:40 +0100146 ASSERT_TRUE(decoded_frame.has_value());
Johannes Kronbbf639e2022-06-15 12:27:23 +0200147 EXPECT_THAT(
148 decoded_frame->render_parameters().max_composition_delay_in_frames,
149 testing::Eq(absl::nullopt));
Johannes Kron111e9812020-10-26 13:54:40 +0100150}
151
152TEST_F(GenericDecoderTest, MaxCompositionDelayActivatedByPlayoutDelay) {
153 VCMEncodedFrame encoded_frame;
154 // VideoReceiveStream2 would set MaxCompositionDelayInFrames if playout delay
155 // is specified as X,Y, where X=0, Y>0.
Johannes Kron111e9812020-10-26 13:54:40 +0100156 constexpr int kMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
Johannes Kron111e9812020-10-26 13:54:40 +0100157 timing_.SetMaxCompositionDelayInFrames(
158 absl::make_optional(kMaxCompositionDelayInFrames));
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000159 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
160 time_controller_.AdvanceTime(TimeDelta::Millis(10));
161 absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
Johannes Kron111e9812020-10-26 13:54:40 +0100162 ASSERT_TRUE(decoded_frame.has_value());
Johannes Kronbbf639e2022-06-15 12:27:23 +0200163 EXPECT_THAT(
164 decoded_frame->render_parameters().max_composition_delay_in_frames,
165 testing::Optional(kMaxCompositionDelayInFrames));
166}
167
168TEST_F(GenericDecoderTest, IsLowLatencyStreamFalseByDefault) {
169 VCMEncodedFrame encoded_frame;
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000170 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
171 time_controller_.AdvanceTime(TimeDelta::Millis(10));
172 absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
Johannes Kronbbf639e2022-06-15 12:27:23 +0200173 ASSERT_TRUE(decoded_frame.has_value());
174 EXPECT_FALSE(decoded_frame->render_parameters().use_low_latency_rendering);
175}
176
177TEST_F(GenericDecoderTest, IsLowLatencyStreamActivatedByPlayoutDelay) {
178 VCMEncodedFrame encoded_frame;
179 const VideoPlayoutDelay kPlayoutDelay = {0, 50};
180 timing_.set_min_playout_delay(TimeDelta::Millis(kPlayoutDelay.min_ms));
181 timing_.set_max_playout_delay(TimeDelta::Millis(kPlayoutDelay.max_ms));
Evan Shrubsole1c51ec42022-08-08 11:21:26 +0000182 generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
183 time_controller_.AdvanceTime(TimeDelta::Millis(10));
184 absl::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
Johannes Kronbbf639e2022-06-15 12:27:23 +0200185 ASSERT_TRUE(decoded_frame.has_value());
186 EXPECT_TRUE(decoded_frame->render_parameters().use_low_latency_rendering);
Johannes Kron111e9812020-10-26 13:54:40 +0100187}
188
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200189} // namespace video_coding
190} // namespace webrtc