blob: 691561dd540cb47198d20c36f1f25956b12534d0 [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
13#include <vector>
14
15#include "absl/types/optional.h"
16#include "api/task_queue/default_task_queue_factory.h"
17#include "common_video/test/utilities.h"
18#include "modules/video_coding/timing.h"
19#include "rtc_base/critical_section.h"
20#include "rtc_base/event.h"
21#include "system_wrappers/include/clock.h"
22#include "test/fake_decoder.h"
23#include "test/gmock.h"
24#include "test/gtest.h"
25
26namespace webrtc {
27namespace video_coding {
28
29class ReceiveCallback : public VCMReceiveCallback {
30 public:
31 int32_t FrameToRender(VideoFrame& videoFrame, // NOLINT
32 absl::optional<uint8_t> qp,
33 VideoContentType content_type) override {
34 {
35 rtc::CritScope cs(&lock_);
36 last_frame_ = videoFrame;
37 }
38 received_frame_event_.Set();
39 return 0;
40 }
41
42 absl::optional<VideoFrame> GetLastFrame() {
43 rtc::CritScope cs(&lock_);
44 return last_frame_;
45 }
46
47 absl::optional<VideoFrame> WaitForFrame(int64_t wait_ms) {
48 if (received_frame_event_.Wait(wait_ms)) {
49 rtc::CritScope cs(&lock_);
50 return last_frame_;
51 } else {
52 return absl::nullopt;
53 }
54 }
55
56 private:
57 rtc::CriticalSection lock_;
58 rtc::Event received_frame_event_;
59 absl::optional<VideoFrame> last_frame_ RTC_GUARDED_BY(lock_);
60};
61
62class GenericDecoderTest : public ::testing::Test {
63 protected:
64 GenericDecoderTest()
65 : clock_(0),
66 timing_(&clock_),
67 task_queue_factory_(CreateDefaultTaskQueueFactory()),
68 decoder_(task_queue_factory_.get()),
69 vcm_callback_(&timing_, &clock_),
70 generic_decoder_(&decoder_, /*isExternal=*/true) {}
71
72 void SetUp() override {
73 generic_decoder_.RegisterDecodeCompleteCallback(&vcm_callback_);
74 vcm_callback_.SetUserReceiveCallback(&user_callback_);
75 VideoCodec settings;
76 settings.codecType = kVideoCodecVP8;
77 settings.width = 10;
78 settings.height = 10;
79 generic_decoder_.InitDecode(&settings, /*numberOfCores=*/4);
80 }
81
82 SimulatedClock clock_;
83 VCMTiming timing_;
84 std::unique_ptr<TaskQueueFactory> task_queue_factory_;
85 webrtc::test::FakeDecoder decoder_;
86 VCMDecodedFrameCallback vcm_callback_;
87 VCMGenericDecoder generic_decoder_;
88 ReceiveCallback user_callback_;
89};
90
91TEST_F(GenericDecoderTest, PassesColorSpace) {
92 webrtc::ColorSpace color_space =
93 CreateTestColorSpace(/*with_hdr_metadata=*/true);
94 VCMEncodedFrame encoded_frame;
95 encoded_frame.SetColorSpace(color_space);
96 generic_decoder_.Decode(encoded_frame, clock_.TimeInMilliseconds());
97 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
98 ASSERT_TRUE(decoded_frame.has_value());
99 absl::optional<webrtc::ColorSpace> decoded_color_space =
100 decoded_frame->color_space();
101 ASSERT_TRUE(decoded_color_space.has_value());
102 EXPECT_EQ(*decoded_color_space, color_space);
103}
104
105TEST_F(GenericDecoderTest, PassesColorSpaceForDelayedDecoders) {
106 webrtc::ColorSpace color_space =
107 CreateTestColorSpace(/*with_hdr_metadata=*/true);
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.SetColorSpace(color_space);
114 generic_decoder_.Decode(encoded_frame, clock_.TimeInMilliseconds());
115 }
116
117 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(200);
118 ASSERT_TRUE(decoded_frame.has_value());
119 absl::optional<webrtc::ColorSpace> decoded_color_space =
120 decoded_frame->color_space();
121 ASSERT_TRUE(decoded_color_space.has_value());
122 EXPECT_EQ(*decoded_color_space, color_space);
123}
124
Chen Xingf00bf422019-06-20 10:05:55 +0200125TEST_F(GenericDecoderTest, PassesPacketInfos) {
126 RtpPacketInfos packet_infos = CreatePacketInfos(3);
127 VCMEncodedFrame encoded_frame;
128 encoded_frame.SetPacketInfos(packet_infos);
129 generic_decoder_.Decode(encoded_frame, clock_.TimeInMilliseconds());
130 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(10);
131 ASSERT_TRUE(decoded_frame.has_value());
132 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
133}
134
135TEST_F(GenericDecoderTest, PassesPacketInfosForDelayedDecoders) {
136 RtpPacketInfos packet_infos = CreatePacketInfos(3);
137 decoder_.SetDelayedDecoding(100);
138
139 {
140 // Ensure the original frame is destroyed before the decoding is completed.
141 VCMEncodedFrame encoded_frame;
142 encoded_frame.SetPacketInfos(packet_infos);
143 generic_decoder_.Decode(encoded_frame, clock_.TimeInMilliseconds());
144 }
145
146 absl::optional<VideoFrame> decoded_frame = user_callback_.WaitForFrame(200);
147 ASSERT_TRUE(decoded_frame.has_value());
148 EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
149}
150
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200151} // namespace video_coding
152} // namespace webrtc