Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / dav1d_video_decoder_unittest.cc
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6 #include <string>
7 #include <utility>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "base/hash/md5.h"
13 #include "base/run_loop.h"
14 #include "base/test/task_environment.h"
15 #include "build/build_config.h"
16 #include "media/base/decoder_buffer.h"
17 #include "media/base/limits.h"
18 #include "media/base/mock_media_log.h"
19 #include "media/base/test_data_util.h"
20 #include "media/base/test_helpers.h"
21 #include "media/base/video_frame.h"
22 #include "media/ffmpeg/ffmpeg_common.h"
23 #include "media/filters/dav1d_video_decoder.h"
24 #include "media/filters/in_memory_url_protocol.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26
27 using ::testing::_;
28
29 namespace media {
30
31 namespace {
32
33 MATCHER(ContainsDecoderErrorLog, "") {
34   return CONTAINS_STRING(arg, "dav1d_send_data() failed");
35 }
36
37 }  // namespace
38
39 class Dav1dVideoDecoderTest : public testing::Test {
40  public:
41   Dav1dVideoDecoderTest()
42       : decoder_(new Dav1dVideoDecoder(&media_log_)),
43         i_frame_buffer_(ReadTestDataFile("av1-I-frame-320x240")) {}
44
45   Dav1dVideoDecoderTest(const Dav1dVideoDecoderTest&) = delete;
46   Dav1dVideoDecoderTest& operator=(const Dav1dVideoDecoderTest&) = delete;
47
48   ~Dav1dVideoDecoderTest() override { Destroy(); }
49
50   void Initialize() {
51     InitializeWithConfig(TestVideoConfig::Normal(VideoCodec::kAV1));
52   }
53
54   void InitializeWithConfigWithResult(const VideoDecoderConfig& config,
55                                       bool success) {
56     decoder_->Initialize(
57         config, true,  // Use low delay so we get 1 frame out for each frame in.
58         nullptr,
59         base::BindOnce(
60             [](bool success, DecoderStatus status) {
61               EXPECT_EQ(status.is_ok(), success);
62             },
63             success),
64         base::BindRepeating(&Dav1dVideoDecoderTest::FrameReady,
65                             base::Unretained(this)),
66         base::NullCallback());
67     base::RunLoop().RunUntilIdle();
68   }
69
70   void InitializeWithConfig(const VideoDecoderConfig& config) {
71     InitializeWithConfigWithResult(config, true);
72   }
73
74   void Reinitialize() {
75     InitializeWithConfig(TestVideoConfig::Large(VideoCodec::kAV1));
76   }
77
78   void Reset() {
79     decoder_->Reset(NewExpectedClosure());
80     base::RunLoop().RunUntilIdle();
81   }
82
83   void Destroy() {
84     decoder_.reset();
85     base::RunLoop().RunUntilIdle();
86   }
87
88   // Sets up expectations and actions to put Dav1dVideoDecoder in an active
89   // decoding state.
90   void ExpectDecodingState() {
91     EXPECT_TRUE(DecodeSingleFrame(i_frame_buffer_).is_ok());
92     ASSERT_EQ(1U, output_frames_.size());
93   }
94
95   // Sets up expectations and actions to put Dav1dVideoDecoder in an end
96   // of stream state.
97   void ExpectEndOfStreamState() {
98     EXPECT_TRUE(DecodeSingleFrame(DecoderBuffer::CreateEOSBuffer()).is_ok());
99     ASSERT_FALSE(output_frames_.empty());
100   }
101
102   using InputBuffers = std::vector<scoped_refptr<DecoderBuffer>>;
103   using OutputFrames = std::vector<scoped_refptr<VideoFrame>>;
104
105   // Decodes all buffers in |input_buffers| and push all successfully decoded
106   // output frames into |output_frames|. Returns the last decode status returned
107   // by the decoder.
108   DecoderStatus DecodeMultipleFrames(const InputBuffers& input_buffers) {
109     for (auto iter = input_buffers.begin(); iter != input_buffers.end();
110          ++iter) {
111       DecoderStatus status = Decode(*iter);
112       switch (status.code()) {
113         case DecoderStatus::Codes::kOk:
114           break;
115         case DecoderStatus::Codes::kAborted:
116           NOTREACHED();
117           [[fallthrough]];
118         default:
119           DCHECK(output_frames_.empty());
120           return status;
121       }
122     }
123     return DecoderStatus::Codes::kOk;
124   }
125
126   // Decodes the single compressed frame in |buffer|.
127   DecoderStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) {
128     InputBuffers input_buffers;
129     input_buffers.push_back(std::move(buffer));
130     return DecodeMultipleFrames(input_buffers);
131   }
132
133   // Decodes |i_frame_buffer_| and then decodes the data contained in the file
134   // named |test_file_name|. This function expects both buffers to decode to
135   // frames that are the same size.
136   void DecodeIFrameThenTestFile(const std::string& test_file_name,
137                                 const gfx::Size& expected_size) {
138     Initialize();
139     scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name);
140
141     InputBuffers input_buffers;
142     input_buffers.push_back(i_frame_buffer_);
143     input_buffers.push_back(buffer);
144     input_buffers.push_back(DecoderBuffer::CreateEOSBuffer());
145
146     DecoderStatus status = DecodeMultipleFrames(input_buffers);
147
148     EXPECT_TRUE(status.is_ok());
149     ASSERT_EQ(2U, output_frames_.size());
150
151     gfx::Size original_size = TestVideoConfig::NormalCodedSize();
152     EXPECT_EQ(original_size.width(),
153               output_frames_[0]->visible_rect().size().width());
154     EXPECT_EQ(original_size.height(),
155               output_frames_[0]->visible_rect().size().height());
156     EXPECT_EQ(expected_size.width(),
157               output_frames_[1]->visible_rect().size().width());
158     EXPECT_EQ(expected_size.height(),
159               output_frames_[1]->visible_rect().size().height());
160   }
161
162   DecoderStatus Decode(scoped_refptr<DecoderBuffer> buffer) {
163     DecoderStatus status;
164     EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status));
165
166     decoder_->Decode(std::move(buffer),
167                      base::BindOnce(&Dav1dVideoDecoderTest::DecodeDone,
168                                     base::Unretained(this)));
169     base::RunLoop().RunUntilIdle();
170
171     return status;
172   }
173
174   void FrameReady(scoped_refptr<VideoFrame> frame) {
175     DCHECK(!frame->metadata().end_of_stream);
176     output_frames_.push_back(std::move(frame));
177   }
178
179   std::string GetVideoFrameHash(const VideoFrame& frame) {
180     base::MD5Context md5_context;
181     base::MD5Init(&md5_context);
182     VideoFrame::HashFrameForTesting(&md5_context, frame);
183     base::MD5Digest digest;
184     base::MD5Final(&digest, &md5_context);
185     return base::MD5DigestToBase16(digest);
186   }
187
188   MOCK_METHOD1(DecodeDone, void(DecoderStatus));
189
190   testing::StrictMock<MockMediaLog> media_log_;
191
192   base::test::SingleThreadTaskEnvironment task_environment_;
193   std::unique_ptr<Dav1dVideoDecoder> decoder_;
194
195   scoped_refptr<DecoderBuffer> i_frame_buffer_;
196   OutputFrames output_frames_;
197 };
198
199 TEST_F(Dav1dVideoDecoderTest, Initialize_Normal) {
200   Initialize();
201 }
202
203 TEST_F(Dav1dVideoDecoderTest, Reinitialize_Normal) {
204   Initialize();
205   Reinitialize();
206 }
207
208 TEST_F(Dav1dVideoDecoderTest, Reinitialize_AfterDecodeFrame) {
209   Initialize();
210   ExpectDecodingState();
211   Reinitialize();
212 }
213
214 TEST_F(Dav1dVideoDecoderTest, Reinitialize_AfterReset) {
215   Initialize();
216   ExpectDecodingState();
217   Reset();
218   Reinitialize();
219 }
220
221 TEST_F(Dav1dVideoDecoderTest, DecodeFrame_Normal) {
222   Initialize();
223
224   // Simulate decoding a single frame.
225   EXPECT_TRUE(DecodeSingleFrame(i_frame_buffer_).is_ok());
226   ASSERT_EQ(1U, output_frames_.size());
227
228   const auto& frame = output_frames_.front();
229   EXPECT_EQ(PIXEL_FORMAT_I420, frame->format());
230   EXPECT_EQ("589dc641b7742ffe7a2b0d4c16aa3e86", GetVideoFrameHash(*frame));
231 }
232
233 TEST_F(Dav1dVideoDecoderTest, DecodeFrame_8bitMono) {
234   Initialize();
235   EXPECT_TRUE(
236       DecodeSingleFrame(ReadTestDataFile("av1-monochrome-I-frame-320x240-8bpp"))
237           .is_ok());
238   ASSERT_EQ(1U, output_frames_.size());
239
240   const auto& frame = output_frames_.front();
241   EXPECT_EQ(PIXEL_FORMAT_I420, frame->format());
242   EXPECT_EQ(frame->data(VideoFrame::kUPlane), frame->data(VideoFrame::kVPlane));
243   EXPECT_EQ("eeba03dcc9c22c4632bf74b481db36b2", GetVideoFrameHash(*frame));
244 }
245
246 TEST_F(Dav1dVideoDecoderTest, DecodeFrame_10bitMono) {
247   Initialize();
248   EXPECT_TRUE(DecodeSingleFrame(
249                   ReadTestDataFile("av1-monochrome-I-frame-320x240-10bpp"))
250                   .is_ok());
251   ASSERT_EQ(1U, output_frames_.size());
252
253   const auto& frame = output_frames_.front();
254   EXPECT_EQ(PIXEL_FORMAT_YUV420P10, frame->format());
255   EXPECT_EQ(frame->data(VideoFrame::kUPlane), frame->data(VideoFrame::kVPlane));
256   EXPECT_EQ("026c1fed9e161f09d816ac7278458a80", GetVideoFrameHash(*frame));
257 }
258
259 TEST_F(Dav1dVideoDecoderTest, DecodeFrame_12bitMono) {
260   Initialize();
261   EXPECT_TRUE(DecodeSingleFrame(
262                   ReadTestDataFile("av1-monochrome-I-frame-320x240-12bpp"))
263                   .is_ok());
264   ASSERT_EQ(1U, output_frames_.size());
265
266   const auto& frame = output_frames_.front();
267   EXPECT_EQ(PIXEL_FORMAT_YUV420P12, frame->format());
268   EXPECT_EQ(frame->data(VideoFrame::kUPlane), frame->data(VideoFrame::kVPlane));
269   EXPECT_EQ("32115092dc00fbe86823b0b714a0f63e", GetVideoFrameHash(*frame));
270 }
271
272 // Decode |i_frame_buffer_| and then a frame with a larger width and verify
273 // the output size was adjusted.
274 TEST_F(Dav1dVideoDecoderTest, DecodeFrame_LargerWidth) {
275   DecodeIFrameThenTestFile("av1-I-frame-1280x720", gfx::Size(1280, 720));
276 }
277
278 // Decode a VP9 frame which should trigger a decoder error.
279 TEST_F(Dav1dVideoDecoderTest, DecodeFrame_Error) {
280   Initialize();
281   EXPECT_MEDIA_LOG(ContainsDecoderErrorLog());
282   DecodeSingleFrame(ReadTestDataFile("vp9-I-frame-320x240"));
283 }
284
285 // Test resetting when decoder has initialized but not decoded.
286 TEST_F(Dav1dVideoDecoderTest, Reset_Initialized) {
287   Initialize();
288   Reset();
289 }
290
291 // Test resetting when decoder has decoded single frame.
292 TEST_F(Dav1dVideoDecoderTest, Reset_Decoding) {
293   Initialize();
294   ExpectDecodingState();
295   Reset();
296 }
297
298 // Test resetting when decoder has hit end of stream.
299 TEST_F(Dav1dVideoDecoderTest, Reset_EndOfStream) {
300   Initialize();
301   ExpectDecodingState();
302   ExpectEndOfStreamState();
303   Reset();
304 }
305
306 // Test destruction when decoder has initialized but not decoded.
307 TEST_F(Dav1dVideoDecoderTest, Destroy_Initialized) {
308   Initialize();
309   Destroy();
310 }
311
312 // Test destruction when decoder has decoded single frame.
313 TEST_F(Dav1dVideoDecoderTest, Destroy_Decoding) {
314   Initialize();
315   ExpectDecodingState();
316   Destroy();
317 }
318
319 // Test destruction when decoder has hit end of stream.
320 TEST_F(Dav1dVideoDecoderTest, Destroy_EndOfStream) {
321   Initialize();
322   ExpectDecodingState();
323   ExpectEndOfStreamState();
324   Destroy();
325 }
326
327 TEST_F(Dav1dVideoDecoderTest, FrameValidAfterPoolDestruction) {
328   Initialize();
329   Decode(i_frame_buffer_);
330   Destroy();
331
332   ASSERT_FALSE(output_frames_.empty());
333
334   // Write to the Y plane. The memory tools should detect a
335   // use-after-free if the storage was actually removed by pool destruction.
336   memset(output_frames_.front()->writable_data(VideoFrame::kYPlane), 0xff,
337          output_frames_.front()->rows(VideoFrame::kYPlane) *
338              output_frames_.front()->stride(VideoFrame::kYPlane));
339 }
340
341 }  // namespace media