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