1 /*
2 * Copyright (c) 2018, Alliance for Open Media. All rights reserved.
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <memory>
13 #include <string>
14 #include "common/tools_common.h"
15 #include "config/aom_config.h"
16 #include "test/codec_factory.h"
17 #include "test/decode_test_driver.h"
18 #include "test/ivf_video_source.h"
19 #include "test/md5_helper.h"
20 #include "test/test_vectors.h"
21 #include "test/util.h"
22 #if CONFIG_WEBM_IO
23 #include "test/webm_video_source.h"
24 #endif
25
26 namespace {
27
28 const int kVideoNameParam = 1;
29
30 struct ExternalFrameBuffer {
31 uint8_t *data;
32 size_t size;
33 int in_use;
34 };
35
36 // Class to manipulate a list of external frame buffers.
37 class ExternalFrameBufferList {
38 public:
ExternalFrameBufferList()39 ExternalFrameBufferList()
40 : num_buffers_(0), num_used_buffers_(0), ext_fb_list_(nullptr) {}
41
~ExternalFrameBufferList()42 virtual ~ExternalFrameBufferList() {
43 for (int i = 0; i < num_buffers_; ++i) {
44 delete[] ext_fb_list_[i].data;
45 }
46 delete[] ext_fb_list_;
47 }
48
49 // Creates the list to hold the external buffers. Returns true on success.
CreateBufferList(int num_buffers)50 bool CreateBufferList(int num_buffers) {
51 if (num_buffers < 0) return false;
52
53 num_buffers_ = num_buffers;
54 ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
55 if (ext_fb_list_ == nullptr) {
56 EXPECT_NE(ext_fb_list_, nullptr);
57 return false;
58 }
59 memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_);
60 return true;
61 }
62
63 // Searches the frame buffer list for a free frame buffer. Makes sure
64 // that the frame buffer is at least |min_size| in bytes. Marks that the
65 // frame buffer is in use by libaom. Finally sets |fb| to point to the
66 // external frame buffer. Returns < 0 on an error.
GetFreeFrameBuffer(size_t min_size,aom_codec_frame_buffer_t * fb)67 int GetFreeFrameBuffer(size_t min_size, aom_codec_frame_buffer_t *fb) {
68 EXPECT_NE(fb, nullptr);
69 const int idx = FindFreeBufferIndex();
70 if (idx == num_buffers_) return -1;
71
72 if (ext_fb_list_[idx].size < min_size) {
73 delete[] ext_fb_list_[idx].data;
74 ext_fb_list_[idx].data = new uint8_t[min_size];
75 if (ext_fb_list_[idx].data == nullptr) {
76 EXPECT_NE(ext_fb_list_[idx].data, nullptr);
77 }
78 memset(ext_fb_list_[idx].data, 0, min_size);
79 ext_fb_list_[idx].size = min_size;
80 }
81
82 SetFrameBuffer(idx, fb);
83
84 num_used_buffers_++;
85 return 0;
86 }
87
88 // Test function that will not allocate any data for the frame buffer.
89 // Returns < 0 on an error.
GetZeroFrameBuffer(size_t min_size,aom_codec_frame_buffer_t * fb)90 int GetZeroFrameBuffer(size_t min_size, aom_codec_frame_buffer_t *fb) {
91 EXPECT_NE(fb, nullptr);
92 const int idx = FindFreeBufferIndex();
93 if (idx == num_buffers_) return -1;
94
95 if (ext_fb_list_[idx].size < min_size) {
96 delete[] ext_fb_list_[idx].data;
97 ext_fb_list_[idx].data = nullptr;
98 ext_fb_list_[idx].size = min_size;
99 }
100
101 SetFrameBuffer(idx, fb);
102 return 0;
103 }
104
105 // Marks the external frame buffer that |fb| is pointing to as free.
106 // Returns < 0 on an error.
ReturnFrameBuffer(aom_codec_frame_buffer_t * fb)107 int ReturnFrameBuffer(aom_codec_frame_buffer_t *fb) {
108 if (fb == nullptr) {
109 EXPECT_NE(fb, nullptr);
110 return -1;
111 }
112 ExternalFrameBuffer *const ext_fb =
113 reinterpret_cast<ExternalFrameBuffer *>(fb->priv);
114 if (ext_fb == nullptr) {
115 EXPECT_NE(ext_fb, nullptr);
116 return -1;
117 }
118 EXPECT_EQ(1, ext_fb->in_use);
119 ext_fb->in_use = 0;
120 num_used_buffers_--;
121 return 0;
122 }
123
124 // Checks that the aom_image_t data is contained within the external frame
125 // buffer private data passed back in the aom_image_t.
CheckImageFrameBuffer(const aom_image_t * img)126 void CheckImageFrameBuffer(const aom_image_t *img) {
127 const struct ExternalFrameBuffer *const ext_fb =
128 reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
129
130 ASSERT_TRUE(img->planes[0] >= ext_fb->data &&
131 img->planes[0] < (ext_fb->data + ext_fb->size));
132 }
133
num_used_buffers() const134 int num_used_buffers() const { return num_used_buffers_; }
135
136 private:
137 // Returns the index of the first free frame buffer. Returns |num_buffers_|
138 // if there are no free frame buffers.
FindFreeBufferIndex()139 int FindFreeBufferIndex() {
140 int i;
141 // Find a free frame buffer.
142 for (i = 0; i < num_buffers_; ++i) {
143 if (!ext_fb_list_[i].in_use) break;
144 }
145 return i;
146 }
147
148 // Sets |fb| to an external frame buffer. idx is the index into the frame
149 // buffer list.
SetFrameBuffer(int idx,aom_codec_frame_buffer_t * fb)150 void SetFrameBuffer(int idx, aom_codec_frame_buffer_t *fb) {
151 ASSERT_NE(fb, nullptr);
152 fb->data = ext_fb_list_[idx].data;
153 fb->size = ext_fb_list_[idx].size;
154 ASSERT_EQ(0, ext_fb_list_[idx].in_use);
155 ext_fb_list_[idx].in_use = 1;
156 fb->priv = &ext_fb_list_[idx];
157 }
158
159 int num_buffers_;
160 int num_used_buffers_;
161 ExternalFrameBuffer *ext_fb_list_;
162 };
163
164 #if CONFIG_WEBM_IO
165
166 // Callback used by libaom to request the application to return a frame
167 // buffer of at least |min_size| in bytes.
get_aom_frame_buffer(void * user_priv,size_t min_size,aom_codec_frame_buffer_t * fb)168 int get_aom_frame_buffer(void *user_priv, size_t min_size,
169 aom_codec_frame_buffer_t *fb) {
170 ExternalFrameBufferList *const fb_list =
171 reinterpret_cast<ExternalFrameBufferList *>(user_priv);
172 return fb_list->GetFreeFrameBuffer(min_size, fb);
173 }
174
175 // Callback used by libaom to tell the application that |fb| is not needed
176 // anymore.
release_aom_frame_buffer(void * user_priv,aom_codec_frame_buffer_t * fb)177 int release_aom_frame_buffer(void *user_priv, aom_codec_frame_buffer_t *fb) {
178 ExternalFrameBufferList *const fb_list =
179 reinterpret_cast<ExternalFrameBufferList *>(user_priv);
180 return fb_list->ReturnFrameBuffer(fb);
181 }
182
183 // Callback will not allocate data for frame buffer.
get_aom_zero_frame_buffer(void * user_priv,size_t min_size,aom_codec_frame_buffer_t * fb)184 int get_aom_zero_frame_buffer(void *user_priv, size_t min_size,
185 aom_codec_frame_buffer_t *fb) {
186 ExternalFrameBufferList *const fb_list =
187 reinterpret_cast<ExternalFrameBufferList *>(user_priv);
188 return fb_list->GetZeroFrameBuffer(min_size, fb);
189 }
190
191 // Callback will allocate one less byte than |min_size|.
get_aom_one_less_byte_frame_buffer(void * user_priv,size_t min_size,aom_codec_frame_buffer_t * fb)192 int get_aom_one_less_byte_frame_buffer(void *user_priv, size_t min_size,
193 aom_codec_frame_buffer_t *fb) {
194 ExternalFrameBufferList *const fb_list =
195 reinterpret_cast<ExternalFrameBufferList *>(user_priv);
196 return fb_list->GetFreeFrameBuffer(min_size - 1, fb);
197 }
198
199 // Callback will not release the external frame buffer.
do_not_release_aom_frame_buffer(void * user_priv,aom_codec_frame_buffer_t * fb)200 int do_not_release_aom_frame_buffer(void *user_priv,
201 aom_codec_frame_buffer_t *fb) {
202 (void)user_priv;
203 (void)fb;
204 return 0;
205 }
206
207 #endif // CONFIG_WEBM_IO
208
209 // Class for testing passing in external frame buffers to libaom.
210 class ExternalFrameBufferMD5Test
211 : public ::libaom_test::DecoderTest,
212 public ::libaom_test::CodecTestWithParam<const char *> {
213 protected:
ExternalFrameBufferMD5Test()214 ExternalFrameBufferMD5Test()
215 : DecoderTest(GET_PARAM(::libaom_test::kCodecFactoryParam)),
216 md5_file_(nullptr), num_buffers_(0) {}
217
~ExternalFrameBufferMD5Test()218 ~ExternalFrameBufferMD5Test() override {
219 if (md5_file_ != nullptr) fclose(md5_file_);
220 }
221
PreDecodeFrameHook(const libaom_test::CompressedVideoSource & video,libaom_test::Decoder * decoder)222 void PreDecodeFrameHook(const libaom_test::CompressedVideoSource &video,
223 libaom_test::Decoder *decoder) override {
224 if (num_buffers_ > 0 && video.frame_number() == 0) {
225 // Have libaom use frame buffers we create.
226 ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
227 ASSERT_EQ(AOM_CODEC_OK,
228 decoder->SetFrameBufferFunctions(GetAV1FrameBuffer,
229 ReleaseAV1FrameBuffer, this));
230 }
231 }
232
OpenMD5File(const std::string & md5_file_name_)233 void OpenMD5File(const std::string &md5_file_name_) {
234 md5_file_ = libaom_test::OpenTestDataFile(md5_file_name_);
235 ASSERT_NE(md5_file_, nullptr)
236 << "Md5 file open failed. Filename: " << md5_file_name_;
237 }
238
DecompressedFrameHook(const aom_image_t & img,const unsigned int frame_number)239 void DecompressedFrameHook(const aom_image_t &img,
240 const unsigned int frame_number) override {
241 ASSERT_NE(md5_file_, nullptr);
242 char expected_md5[33];
243 char junk[128];
244
245 // Read correct md5 checksums.
246 const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
247 ASSERT_NE(EOF, res) << "Read md5 data failed";
248 expected_md5[32] = '\0';
249
250 ::libaom_test::MD5 md5_res;
251 #if FORCE_HIGHBITDEPTH_DECODING
252 const aom_img_fmt_t shifted_fmt =
253 (aom_img_fmt)(img.fmt & ~AOM_IMG_FMT_HIGHBITDEPTH);
254 if (img.bit_depth == 8 && shifted_fmt != img.fmt) {
255 aom_image_t *img_shifted =
256 aom_img_alloc(nullptr, shifted_fmt, img.d_w, img.d_h, 16);
257 img_shifted->bit_depth = img.bit_depth;
258 img_shifted->monochrome = img.monochrome;
259 aom_img_downshift(img_shifted, &img, 0);
260 md5_res.Add(img_shifted);
261 aom_img_free(img_shifted);
262 } else {
263 #endif
264 md5_res.Add(&img);
265 #if FORCE_HIGHBITDEPTH_DECODING
266 }
267 #endif
268 const char *const actual_md5 = md5_res.Get();
269
270 // Check md5 match.
271 ASSERT_STREQ(expected_md5, actual_md5)
272 << "Md5 checksums don't match: frame number = " << frame_number;
273
274 const struct ExternalFrameBuffer *const ext_fb =
275 reinterpret_cast<ExternalFrameBuffer *>(img.fb_priv);
276
277 ASSERT_TRUE(img.planes[0] >= ext_fb->data &&
278 img.planes[0] < (ext_fb->data + ext_fb->size));
279 }
280
281 // Callback to get a free external frame buffer. Return value < 0 is an
282 // error.
GetAV1FrameBuffer(void * user_priv,size_t min_size,aom_codec_frame_buffer_t * fb)283 static int GetAV1FrameBuffer(void *user_priv, size_t min_size,
284 aom_codec_frame_buffer_t *fb) {
285 ExternalFrameBufferMD5Test *const md5Test =
286 reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
287 return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb);
288 }
289
290 // Callback to release an external frame buffer. Return value < 0 is an
291 // error.
ReleaseAV1FrameBuffer(void * user_priv,aom_codec_frame_buffer_t * fb)292 static int ReleaseAV1FrameBuffer(void *user_priv,
293 aom_codec_frame_buffer_t *fb) {
294 ExternalFrameBufferMD5Test *const md5Test =
295 reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
296 return md5Test->fb_list_.ReturnFrameBuffer(fb);
297 }
298
set_num_buffers(int num_buffers)299 void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; }
num_buffers() const300 int num_buffers() const { return num_buffers_; }
301
302 private:
303 FILE *md5_file_;
304 int num_buffers_;
305 ExternalFrameBufferList fb_list_;
306 };
307
308 #if CONFIG_WEBM_IO
309 const char kAV1TestFile[] = "av1-1-b8-03-sizeup.mkv";
310 const char kAV1NonRefTestFile[] = "av1-1-b8-01-size-226x226.ivf";
311
312 // Class for testing passing in external frame buffers to libaom.
313 class ExternalFrameBufferTest : public ::testing::Test {
314 protected:
ExternalFrameBufferTest()315 ExternalFrameBufferTest()
316 : video_(nullptr), decoder_(nullptr), num_buffers_(0) {}
317
SetUp()318 void SetUp() override {
319 video_ = new libaom_test::WebMVideoSource(kAV1TestFile);
320 ASSERT_NE(video_, nullptr);
321 video_->Init();
322 video_->Begin();
323
324 aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
325 cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING;
326 decoder_ = new libaom_test::AV1Decoder(cfg, 0);
327 ASSERT_NE(decoder_, nullptr);
328 }
329
TearDown()330 void TearDown() override {
331 delete decoder_;
332 decoder_ = nullptr;
333 delete video_;
334 video_ = nullptr;
335 }
336
337 // Passes the external frame buffer information to libaom.
SetFrameBufferFunctions(int num_buffers,aom_get_frame_buffer_cb_fn_t cb_get,aom_release_frame_buffer_cb_fn_t cb_release)338 aom_codec_err_t SetFrameBufferFunctions(
339 int num_buffers, aom_get_frame_buffer_cb_fn_t cb_get,
340 aom_release_frame_buffer_cb_fn_t cb_release) {
341 if (num_buffers > 0) {
342 num_buffers_ = num_buffers;
343 EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_));
344 }
345
346 return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_);
347 }
348
DecodeOneFrame()349 aom_codec_err_t DecodeOneFrame() {
350 const aom_codec_err_t res =
351 decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
352 CheckDecodedFrames();
353 if (res == AOM_CODEC_OK) video_->Next();
354 return res;
355 }
356
DecodeRemainingFrames()357 aom_codec_err_t DecodeRemainingFrames() {
358 for (; video_->cxdata() != nullptr; video_->Next()) {
359 const aom_codec_err_t res =
360 decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
361 if (res != AOM_CODEC_OK) return res;
362 CheckDecodedFrames();
363 }
364 return AOM_CODEC_OK;
365 }
366
367 protected:
CheckDecodedFrames()368 void CheckDecodedFrames() {
369 libaom_test::DxDataIterator dec_iter = decoder_->GetDxData();
370 const aom_image_t *img = nullptr;
371
372 // Get decompressed data
373 while ((img = dec_iter.Next()) != nullptr) {
374 fb_list_.CheckImageFrameBuffer(img);
375 }
376 }
377
378 libaom_test::CompressedVideoSource *video_;
379 libaom_test::AV1Decoder *decoder_;
380 int num_buffers_;
381 ExternalFrameBufferList fb_list_;
382 };
383
384 class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest {
385 protected:
SetUp()386 void SetUp() override {
387 video_ = new libaom_test::IVFVideoSource(kAV1NonRefTestFile);
388 ASSERT_NE(video_, nullptr);
389 video_->Init();
390 video_->Begin();
391
392 aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
393 cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING;
394 decoder_ = new libaom_test::AV1Decoder(cfg, 0);
395 ASSERT_NE(decoder_, nullptr);
396 }
397
CheckFrameBufferRelease()398 virtual void CheckFrameBufferRelease() {
399 TearDown();
400 ASSERT_EQ(0, fb_list_.num_used_buffers());
401 }
402 };
403 #endif // CONFIG_WEBM_IO
404
405 // This test runs through the set of test vectors, and decodes them.
406 // Libaom will call into the application to allocate a frame buffer when
407 // needed. The md5 checksums are computed for each frame in the video file.
408 // If md5 checksums match the correct md5 data, then the test is passed.
409 // Otherwise, the test failed.
TEST_P(ExternalFrameBufferMD5Test,ExtFBMD5Match)410 TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
411 const std::string filename = GET_PARAM(kVideoNameParam);
412 aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
413
414 // Number of buffers equals #AOM_MAXIMUM_REF_BUFFERS +
415 // #AOM_MAXIMUM_WORK_BUFFERS + four jitter buffers.
416 const int jitter_buffers = 4;
417 const int num_buffers =
418 AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS + jitter_buffers;
419 set_num_buffers(num_buffers);
420
421 // Open compressed video file.
422 std::unique_ptr<libaom_test::CompressedVideoSource> video;
423 if (filename.substr(filename.length() - 3, 3) == "ivf") {
424 video.reset(new libaom_test::IVFVideoSource(filename));
425 } else {
426 #if CONFIG_WEBM_IO
427 video.reset(new libaom_test::WebMVideoSource(filename));
428 #else
429 fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
430 filename.c_str());
431 return;
432 #endif
433 }
434 ASSERT_NE(video, nullptr);
435 video->Init();
436
437 // Construct md5 file name.
438 const std::string md5_filename = filename + ".md5";
439 OpenMD5File(md5_filename);
440
441 // Set decode config.
442 cfg.allow_lowbitdepth = !FORCE_HIGHBITDEPTH_DECODING;
443 set_cfg(cfg);
444
445 // Decode frame, and check the md5 matching.
446 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
447 }
448
449 #if CONFIG_WEBM_IO
TEST_F(ExternalFrameBufferTest,MinFrameBuffers)450 TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
451 // Minimum number of external frame buffers for AV1 is
452 // #AOM_MAXIMUM_REF_BUFFERS + #AOM_MAXIMUM_WORK_BUFFERS.
453 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
454 ASSERT_EQ(AOM_CODEC_OK,
455 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
456 release_aom_frame_buffer));
457 ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames());
458 }
459
TEST_F(ExternalFrameBufferTest,EightJitterBuffers)460 TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
461 // Number of buffers equals #AOM_MAXIMUM_REF_BUFFERS +
462 // #AOM_MAXIMUM_WORK_BUFFERS + eight jitter buffers.
463 const int jitter_buffers = 8;
464 const int num_buffers =
465 AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS + jitter_buffers;
466 ASSERT_EQ(AOM_CODEC_OK,
467 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
468 release_aom_frame_buffer));
469 ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames());
470 }
471
TEST_F(ExternalFrameBufferTest,NotEnoughBuffers)472 TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
473 // Minimum number of external frame buffers for AV1 is
474 // #AOM_MAXIMUM_REF_BUFFERS + #AOM_MAXIMUM_WORK_BUFFERS. Most files will
475 // only use 5 frame buffers at one time.
476 const int num_buffers = 2;
477 ASSERT_EQ(AOM_CODEC_OK,
478 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
479 release_aom_frame_buffer));
480 ASSERT_EQ(AOM_CODEC_OK, DecodeOneFrame());
481 // Only run this on long clips. Decoding a very short clip will return
482 // AOM_CODEC_OK even with only 2 buffers.
483 ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeRemainingFrames());
484 }
485
TEST_F(ExternalFrameBufferTest,NoRelease)486 TEST_F(ExternalFrameBufferTest, NoRelease) {
487 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
488 ASSERT_EQ(AOM_CODEC_OK,
489 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
490 do_not_release_aom_frame_buffer));
491 ASSERT_EQ(AOM_CODEC_OK, DecodeOneFrame());
492 ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeRemainingFrames());
493 }
494
TEST_F(ExternalFrameBufferTest,NullRealloc)495 TEST_F(ExternalFrameBufferTest, NullRealloc) {
496 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
497 ASSERT_EQ(AOM_CODEC_OK,
498 SetFrameBufferFunctions(num_buffers, get_aom_zero_frame_buffer,
499 release_aom_frame_buffer));
500 ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeOneFrame());
501 }
502
TEST_F(ExternalFrameBufferTest,ReallocOneLessByte)503 TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
504 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
505 ASSERT_EQ(AOM_CODEC_OK, SetFrameBufferFunctions(
506 num_buffers, get_aom_one_less_byte_frame_buffer,
507 release_aom_frame_buffer));
508 ASSERT_EQ(AOM_CODEC_MEM_ERROR, DecodeOneFrame());
509 }
510
TEST_F(ExternalFrameBufferTest,NullGetFunction)511 TEST_F(ExternalFrameBufferTest, NullGetFunction) {
512 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
513 ASSERT_EQ(
514 AOM_CODEC_INVALID_PARAM,
515 SetFrameBufferFunctions(num_buffers, nullptr, release_aom_frame_buffer));
516 }
517
TEST_F(ExternalFrameBufferTest,NullReleaseFunction)518 TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
519 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
520 ASSERT_EQ(
521 AOM_CODEC_INVALID_PARAM,
522 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer, nullptr));
523 }
524
TEST_F(ExternalFrameBufferTest,SetAfterDecode)525 TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
526 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
527 ASSERT_EQ(AOM_CODEC_OK, DecodeOneFrame());
528 ASSERT_EQ(AOM_CODEC_ERROR,
529 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
530 release_aom_frame_buffer));
531 }
532
TEST_F(ExternalFrameBufferNonRefTest,ReleaseNonRefFrameBuffer)533 TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) {
534 const int num_buffers = AOM_MAXIMUM_REF_BUFFERS + AOM_MAXIMUM_WORK_BUFFERS;
535 ASSERT_EQ(AOM_CODEC_OK,
536 SetFrameBufferFunctions(num_buffers, get_aom_frame_buffer,
537 release_aom_frame_buffer));
538 ASSERT_EQ(AOM_CODEC_OK, DecodeRemainingFrames());
539 CheckFrameBufferRelease();
540 }
541 #endif // CONFIG_WEBM_IO
542
543 AV1_INSTANTIATE_TEST_SUITE(
544 ExternalFrameBufferMD5Test,
545 ::testing::ValuesIn(libaom_test::kAV1TestVectors,
546 libaom_test::kAV1TestVectors +
547 libaom_test::kNumAV1TestVectors));
548 } // namespace
549