blob: 466459ef95e627ec72653f1b30032eca6990687b [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"
27
28namespace webrtc {
29namespace video_coding {
30
31class ReceiveCallback : public VCMReceiveCallback {
32 public:
33 int32_t FrameToRender(VideoFrame& videoFrame, // NOLINT
34 absl::optional<uint8_t> qp,
Johannes Kronbfd343b2019-07-01 10:07:50 +020035 int32_t decode_time_ms,
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020036 VideoContentType content_type) override {
37 {
Markus Handell6deec382020-07-07 12:17:12 +020038 MutexLock lock(&lock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020039 last_frame_ = videoFrame;
40 }
41 received_frame_event_.Set();
42 return 0;
43 }
44
45 absl::optional<VideoFrame> GetLastFrame() {
Markus Handell6deec382020-07-07 12:17:12 +020046 MutexLock lock(&lock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020047 return last_frame_;
48 }
49
50 absl::optional<VideoFrame> WaitForFrame(int64_t wait_ms) {
51 if (received_frame_event_.Wait(wait_ms)) {
Markus Handell6deec382020-07-07 12:17:12 +020052 MutexLock lock(&lock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020053 return last_frame_;
54 } else {
55 return absl::nullopt;
56 }
57 }
58
59 private:
Markus Handell6deec382020-07-07 12:17:12 +020060 Mutex lock_;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020061 rtc::Event received_frame_event_;
62 absl::optional<VideoFrame> last_frame_ RTC_GUARDED_BY(lock_);
63};
64
65class GenericDecoderTest : public ::testing::Test {
66 protected:
67 GenericDecoderTest()
68 : clock_(0),
69 timing_(&clock_),
70 task_queue_factory_(CreateDefaultTaskQueueFactory()),
71 decoder_(task_queue_factory_.get()),
72 vcm_callback_(&timing_, &clock_),
Danil Chapovalov7b78a312021-08-06 12:30:02 +020073 generic_decoder_(&decoder_) {}
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020074
75 void SetUp() override {
76 generic_decoder_.RegisterDecodeCompleteCallback(&vcm_callback_);
77 vcm_callback_.SetUserReceiveCallback(&user_callback_);
Danil Chapovalov355b8d22021-08-13 16:50:37 +020078 VideoDecoder::Settings settings;
79 settings.set_codec_type(kVideoCodecVP8);
80 settings.set_max_render_resolution({10, 10});
81 settings.set_number_of_cores(4);
82 generic_decoder_.Configure(settings);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020083 }
84
85 SimulatedClock clock_;
86 VCMTiming timing_;
87 std::unique_ptr<TaskQueueFactory> task_queue_factory_;
88 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);
Johannes Kron05f84872020-01-16 14:09:33 +010098 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
Chen Xingf00bf422019-06-20 10:05:55 +020099 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
100 ASSERT_TRUE(decoded_frame.has_value());
101 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
102}
103
104TEST_F(GenericDecoderTest, PassesPacketInfosForDelayedDecoders) {
105 RtpPacketInfos packet_infos = CreatePacketInfos(3);
106 decoder_.SetDelayedDecoding(100);
107
108 {
109 // Ensure the original frame is destroyed before the decoding is completed.
110 VCMEncodedFrame encoded_frame;
111 encoded_frame.SetPacketInfos(packet_infos);
Johannes Kron05f84872020-01-16 14:09:33 +0100112 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
Chen Xingf00bf422019-06-20 10:05:55 +0200113 }
114
115 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(200);
116 ASSERT_TRUE(decoded_frame.has_value());
117 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
118}
119
Johannes Kron111e9812020-10-26 13:54:40 +0100120TEST_F(GenericDecoderTest, MaxCompositionDelayNotSetByDefault) {
121 VCMEncodedFrame encoded_frame;
122 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
123 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
124 ASSERT_TRUE(decoded_frame.has_value());
125 EXPECT_FALSE(decoded_frame->max_composition_delay_in_frames());
126}
127
128TEST_F(GenericDecoderTest, MaxCompositionDelayActivatedByPlayoutDelay) {
129 VCMEncodedFrame encoded_frame;
130 // VideoReceiveStream2 would set MaxCompositionDelayInFrames if playout delay
131 // is specified as X,Y, where X=0, Y>0.
132 const VideoPlayoutDelay kPlayoutDelay = {0, 50};
133 constexpr int kMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
134 encoded_frame.SetPlayoutDelay(kPlayoutDelay);
135 timing_.SetMaxCompositionDelayInFrames(
136 absl::make_optional(kMaxCompositionDelayInFrames));
137 generic_decoder_.Decode(encoded_frame, clock_.CurrentTime());
138 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
139 ASSERT_TRUE(decoded_frame.has_value());
140 EXPECT_EQ(kMaxCompositionDelayInFrames,
141 decoded_frame->max_composition_delay_in_frames());
142}
143
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200144} // namespace video_coding
145} // namespace webrtc