blob: 811c296a677170bfd7c1e3a3130b10ec3f4e4b97 [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
Danil Chapovalov7b78a312021-08-06 12:30:02 +020013#include <memory>
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020014#include <vector>
15
16#include "absl/types/optional.h"
17#include "api/task_queue/default_task_queue_factory.h"
Danil Chapovalov355b8d22021-08-13 16:50:37 +020018#include "api/video_codecs/video_decoder.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020019#include "common_video/test/utilities.h"
Rasmus Brandtc4d253c2022-05-25 12:03:35 +020020#include "modules/video_coding/timing/timing.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020021#include "rtc_base/event.h"
Markus Handell6deec382020-07-07 12:17:12 +020022#include "rtc_base/synchronization/mutex.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"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020028
29namespace webrtc {
30namespace video_coding {
31
32class ReceiveCallback : public VCMReceiveCallback {
33 public:
34 int32_t FrameToRender(VideoFrame& videoFrame, // NOLINT
35 absl::optional<uint8_t> qp,
Philipp Hancked970b092022-06-17 07:34:23 +020036 TimeDelta decode_time,
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020037 VideoContentType content_type) override {
38 {
Markus Handell6deec382020-07-07 12:17:12 +020039 MutexLock lock(&lock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020040 last_frame_ = videoFrame;
41 }
42 received_frame_event_.Set();
43 return 0;
44 }
45
46 absl::optional<VideoFrame> GetLastFrame() {
Markus Handell6deec382020-07-07 12:17:12 +020047 MutexLock lock(&lock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020048 return last_frame_;
49 }
50
51 absl::optional<VideoFrame> WaitForFrame(int64_t wait_ms) {
52 if (received_frame_event_.Wait(wait_ms)) {
Markus Handell6deec382020-07-07 12:17:12 +020053 MutexLock lock(&lock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020054 return last_frame_;
55 } else {
56 return absl::nullopt;
57 }
58 }
59
60 private:
Markus Handell6deec382020-07-07 12:17:12 +020061 Mutex lock_;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020062 rtc::Event received_frame_event_;
63 absl::optional<VideoFrame> last_frame_ RTC_GUARDED_BY(lock_);
64};
65
66class GenericDecoderTest : public ::testing::Test {
67 protected:
68 GenericDecoderTest()
69 : clock_(0),
Jonas Orelande02f9ee2022-03-25 12:43:14 +010070 timing_(&clock_, field_trials_),
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020071 task_queue_factory_(CreateDefaultTaskQueueFactory()),
72 decoder_(task_queue_factory_.get()),
Jonas Orelande02f9ee2022-03-25 12:43:14 +010073 vcm_callback_(&timing_, &clock_, field_trials_),
Danil Chapovalov7b78a312021-08-06 12:30:02 +020074 generic_decoder_(&decoder_) {}
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020075
76 void SetUp() override {
77 generic_decoder_.RegisterDecodeCompleteCallback(&vcm_callback_);
78 vcm_callback_.SetUserReceiveCallback(&user_callback_);
Danil Chapovalov355b8d22021-08-13 16:50:37 +020079 VideoDecoder::Settings settings;
80 settings.set_codec_type(kVideoCodecVP8);
81 settings.set_max_render_resolution({10, 10});
82 settings.set_number_of_cores(4);
83 generic_decoder_.Configure(settings);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020084 }
85
Jonas Orelande02f9ee2022-03-25 12:43:14 +010086 test::ScopedKeyValueConfig field_trials_;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020087 SimulatedClock clock_;
88 VCMTiming timing_;
89 std::unique_ptr<TaskQueueFactory> task_queue_factory_;
90 webrtc::test::FakeDecoder decoder_;
91 VCMDecodedFrameCallback vcm_callback_;
92 VCMGenericDecoder generic_decoder_;
93 ReceiveCallback user_callback_;
94};
95
Chen Xingf00bf422019-06-20 10:05:55 +020096TEST_F(GenericDecoderTest, PassesPacketInfos) {
97 RtpPacketInfos packet_infos = CreatePacketInfos(3);
98 VCMEncodedFrame encoded_frame;
99 encoded_frame.SetPacketInfos(packet_infos);
Johannes Kron05f84872020-01-16 14:09:33 +0100100 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
Chen Xingf00bf422019-06-20 10:05:55 +0200101 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
102 ASSERT_TRUE(decoded_frame.has_value());
103 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
104}
105
106TEST_F(GenericDecoderTest, PassesPacketInfosForDelayedDecoders) {
107 RtpPacketInfos packet_infos = CreatePacketInfos(3);
108 decoder_.SetDelayedDecoding(100);
109
110 {
111 // Ensure the original frame is destroyed before the decoding is completed.
112 VCMEncodedFrame encoded_frame;
113 encoded_frame.SetPacketInfos(packet_infos);
Johannes Kron05f84872020-01-16 14:09:33 +0100114 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
Chen Xingf00bf422019-06-20 10:05:55 +0200115 }
116
117 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(200);
118 ASSERT_TRUE(decoded_frame.has_value());
119 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
120}
121
Johannes Kron111e9812020-10-26 13:54:40 +0100122TEST_F(GenericDecoderTest, MaxCompositionDelayNotSetByDefault) {
123 VCMEncodedFrame encoded_frame;
124 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
125 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
126 ASSERT_TRUE(decoded_frame.has_value());
Johannes Kronbbf639e2022-06-15 12:27:23 +0200127 EXPECT_THAT(
128 decoded_frame->render_parameters().max_composition_delay_in_frames,
129 testing::Eq(absl::nullopt));
Johannes Kron111e9812020-10-26 13:54:40 +0100130}
131
132TEST_F(GenericDecoderTest, MaxCompositionDelayActivatedByPlayoutDelay) {
133 VCMEncodedFrame encoded_frame;
134 // VideoReceiveStream2 would set MaxCompositionDelayInFrames if playout delay
135 // is specified as X,Y, where X=0, Y>0.
Johannes Kron111e9812020-10-26 13:54:40 +0100136 constexpr int kMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
Johannes Kron111e9812020-10-26 13:54:40 +0100137 timing_.SetMaxCompositionDelayInFrames(
138 absl::make_optional(kMaxCompositionDelayInFrames));
139 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
140 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
141 ASSERT_TRUE(decoded_frame.has_value());
Johannes Kronbbf639e2022-06-15 12:27:23 +0200142 EXPECT_THAT(
143 decoded_frame->render_parameters().max_composition_delay_in_frames,
144 testing::Optional(kMaxCompositionDelayInFrames));
145}
146
147TEST_F(GenericDecoderTest, IsLowLatencyStreamFalseByDefault) {
148 VCMEncodedFrame encoded_frame;
149 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
150 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
151 ASSERT_TRUE(decoded_frame.has_value());
152 EXPECT_FALSE(decoded_frame->render_parameters().use_low_latency_rendering);
153}
154
155TEST_F(GenericDecoderTest, IsLowLatencyStreamActivatedByPlayoutDelay) {
156 VCMEncodedFrame encoded_frame;
157 const VideoPlayoutDelay kPlayoutDelay = {0, 50};
158 timing_.set_min_playout_delay(TimeDelta::Millis(kPlayoutDelay.min_ms));
159 timing_.set_max_playout_delay(TimeDelta::Millis(kPlayoutDelay.max_ms));
160 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
161 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
162 ASSERT_TRUE(decoded_frame.has_value());
163 EXPECT_TRUE(decoded_frame->render_parameters().use_low_latency_rendering);
Johannes Kron111e9812020-10-26 13:54:40 +0100164}
165
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200166} // namespace video_coding
167} // namespace webrtc