blob: d9ca8c670262e095a3dcbde38e8d26c51d68a3f9 [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"
20#include "modules/video_coding/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,
Johannes Kronbfd343b2019-07-01 10:07:50 +020036 int32_t decode_time_ms,
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());
127 EXPECT_FALSE(decoded_frame->max_composition_delay_in_frames());
128}
129
130TEST_F(GenericDecoderTest, MaxCompositionDelayActivatedByPlayoutDelay) {
131 VCMEncodedFrame encoded_frame;
132 // VideoReceiveStream2 would set MaxCompositionDelayInFrames if playout delay
133 // is specified as X,Y, where X=0, Y>0.
134 const VideoPlayoutDelay kPlayoutDelay = {0, 50};
135 constexpr int kMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
136 encoded_frame.SetPlayoutDelay(kPlayoutDelay);
137 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());
142 EXPECT_EQ(kMaxCompositionDelayInFrames,
143 decoded_frame->max_composition_delay_in_frames());
144}
145
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200146} // namespace video_coding
147} // namespace webrtc