blob: 64722f43a7f5835fd64655400062f67cfdf0dc54 [file] [log] [blame]
Yaowu Xuc953aea2012-08-30 13:43:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc953aea2012-08-30 13:43:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Yaowu Xuc953aea2012-08-30 13:43:15 -070010 */
11
James Zerne1cbb132018-08-22 14:10:36 -070012#ifndef AOM_TEST_DECODE_TEST_DRIVER_H_
13#define AOM_TEST_DECODE_TEST_DRIVER_H_
Yunqing Wang15dffcf2012-10-04 12:59:36 -070014#include <cstring>
Tom Finegan7a07ece2017-02-07 17:14:05 -080015#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Tom Finegan60e653d2018-05-22 11:34:58 -070016
17#include "config/aom_config.h"
18
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "aom/aom_decoder.h"
Yunqing Wang15dffcf2012-10-04 12:59:36 -070020
Yaowu Xuc27fc142016-08-22 16:08:15 -070021namespace libaom_test {
Yaowu Xuc953aea2012-08-30 13:43:15 -070022
John Koleszar706cafe2013-01-18 11:51:12 -080023class CodecFactory;
Yunqing Wang15dffcf2012-10-04 12:59:36 -070024class CompressedVideoSource;
Yaowu Xuc953aea2012-08-30 13:43:15 -070025
26// Provides an object to handle decoding output
27class DxDataIterator {
28 public:
Yaowu Xuf883b422016-08-30 14:01:10 -070029 explicit DxDataIterator(aom_codec_ctx_t *decoder)
Yunqing Wang15dffcf2012-10-04 12:59:36 -070030 : decoder_(decoder), iter_(NULL) {}
Yaowu Xuc953aea2012-08-30 13:43:15 -070031
Yaowu Xuf883b422016-08-30 14:01:10 -070032 const aom_image_t *Next() { return aom_codec_get_frame(decoder_, &iter_); }
Yaowu Xuc953aea2012-08-30 13:43:15 -070033
34 private:
Yaowu Xuf883b422016-08-30 14:01:10 -070035 aom_codec_ctx_t *decoder_;
36 aom_codec_iter_t iter_;
Yaowu Xuc953aea2012-08-30 13:43:15 -070037};
38
39// Provides a simplified interface to manage one video decoding.
Yaowu Xuafffa3d2013-09-05 08:45:56 -070040// Similar to Encoder class, the exact services should be added
41// as more tests are added.
Yaowu Xuc953aea2012-08-30 13:43:15 -070042class Decoder {
43 public:
James Zern3b96b762017-03-24 17:12:19 -070044 explicit Decoder(aom_codec_dec_cfg_t cfg)
45 : cfg_(cfg), flags_(0), init_done_(false) {
hkuang93536072014-11-20 15:39:56 -080046 memset(&decoder_, 0, sizeof(decoder_));
47 }
48
James Zern3b96b762017-03-24 17:12:19 -070049 Decoder(aom_codec_dec_cfg_t cfg, const aom_codec_flags_t flag)
50 : cfg_(cfg), flags_(flag), init_done_(false) {
Yaowu Xuc953aea2012-08-30 13:43:15 -070051 memset(&decoder_, 0, sizeof(decoder_));
52 }
53
Yaowu Xuf883b422016-08-30 14:01:10 -070054 virtual ~Decoder() { aom_codec_destroy(&decoder_); }
Yaowu Xuc953aea2012-08-30 13:43:15 -070055
Yaowu Xuf883b422016-08-30 14:01:10 -070056 aom_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
57 aom_codec_stream_info_t *stream_info);
Jim Bankoski96727b92014-06-23 08:37:18 -070058
Yaowu Xuf883b422016-08-30 14:01:10 -070059 aom_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size);
Yaowu Xuc953aea2012-08-30 13:43:15 -070060
Yaowu Xuf883b422016-08-30 14:01:10 -070061 aom_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
hkuang5e7242d2014-06-23 14:59:20 -070062 void *user_priv);
63
clang-format3a826f12016-08-11 17:46:05 -070064 DxDataIterator GetDxData() { return DxDataIterator(&decoder_); }
Yaowu Xuc953aea2012-08-30 13:43:15 -070065
Yaowu Xuf883b422016-08-30 14:01:10 -070066 void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, AOM_CODEC_OK); }
Yaowu Xuc953aea2012-08-30 13:43:15 -070067
Dmitry Kovalev26cec5c2013-03-15 18:21:55 -070068 void Control(int ctrl_id, const void *arg) {
John Koleszar771fc832013-03-27 10:41:29 -070069 InitOnce();
Elliott Karpilovsky60dd0f92020-04-30 19:19:27 -070070 const aom_codec_err_t res = aom_codec_control(&decoder_, ctrl_id, arg);
Yaowu Xuf883b422016-08-30 14:01:10 -070071 ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError();
Dmitry Kovalev26cec5c2013-03-15 18:21:55 -070072 }
John Koleszar706cafe2013-01-18 11:51:12 -080073
Yaowu Xuf883b422016-08-30 14:01:10 -070074 void Control(int ctrl_id, int arg, aom_codec_err_t expected_value) {
Frank Galliganc4f70792014-12-15 12:00:09 -080075 InitOnce();
Elliott Karpilovsky60dd0f92020-04-30 19:19:27 -070076 const aom_codec_err_t res = aom_codec_control(&decoder_, ctrl_id, arg);
Frank Galliganc4f70792014-12-15 12:00:09 -080077 ASSERT_EQ(expected_value, res) << DecodeError();
78 }
79
clang-format3a826f12016-08-11 17:46:05 -070080 const char *DecodeError() {
Yaowu Xuf883b422016-08-30 14:01:10 -070081 const char *detail = aom_codec_error_detail(&decoder_);
82 return detail ? detail : aom_codec_error(&decoder_);
Yaowu Xuc953aea2012-08-30 13:43:15 -070083 }
84
Yaowu Xuc27fc142016-08-22 16:08:15 -070085 // Passes the external frame buffer information to libaom.
Yaowu Xuf883b422016-08-30 14:01:10 -070086 aom_codec_err_t SetFrameBufferFunctions(
87 aom_get_frame_buffer_cb_fn_t cb_get,
88 aom_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
Frank Galligana4f30a52014-02-06 17:13:08 -080089 InitOnce();
Yaowu Xuf883b422016-08-30 14:01:10 -070090 return aom_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release,
clang-format3a826f12016-08-11 17:46:05 -070091 user_priv);
Frank Galligana4f30a52014-02-06 17:13:08 -080092 }
93
clang-format3a826f12016-08-11 17:46:05 -070094 const char *GetDecoderName() const {
Yaowu Xuf883b422016-08-30 14:01:10 -070095 return aom_codec_iface_name(CodecInterface());
Jim Bankoski96727b92014-06-23 08:37:18 -070096 }
97
Yaowu Xuf883b422016-08-30 14:01:10 -070098 bool IsAV1() const;
Yunqing Wang8e5e3382016-05-05 16:42:57 -070099
Yaowu Xuf883b422016-08-30 14:01:10 -0700100 aom_codec_ctx_t *GetDecoder() { return &decoder_; }
Jim Bankoskia0d9a9d2014-12-11 17:34:32 -0800101
Dmitry Kovalev26cec5c2013-03-15 18:21:55 -0700102 protected:
Yaowu Xuf883b422016-08-30 14:01:10 -0700103 virtual aom_codec_iface_t *CodecInterface() const = 0;
John Koleszar771fc832013-03-27 10:41:29 -0700104
105 void InitOnce() {
106 if (!init_done_) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700107 const aom_codec_err_t res =
108 aom_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_);
109 ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError();
John Koleszar771fc832013-03-27 10:41:29 -0700110 init_done_ = true;
111 }
Dmitry Kovalev26cec5c2013-03-15 18:21:55 -0700112 }
113
Yaowu Xuf883b422016-08-30 14:01:10 -0700114 aom_codec_ctx_t decoder_;
115 aom_codec_dec_cfg_t cfg_;
116 aom_codec_flags_t flags_;
clang-format3a826f12016-08-11 17:46:05 -0700117 bool init_done_;
Yaowu Xuc953aea2012-08-30 13:43:15 -0700118};
119
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700120// Common test functionality for all Decoder tests.
121class DecoderTest {
122 public:
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800123 // Main decoding loop
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700124 virtual void RunLoop(CompressedVideoSource *video);
hkuangc147cf32014-07-01 16:04:53 -0700125 virtual void RunLoop(CompressedVideoSource *video,
Yaowu Xuf883b422016-08-30 14:01:10 -0700126 const aom_codec_dec_cfg_t &dec_cfg);
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700127
Yaowu Xuf883b422016-08-30 14:01:10 -0700128 virtual void set_cfg(const aom_codec_dec_cfg_t &dec_cfg);
129 virtual void set_flags(const aom_codec_flags_t flags);
hkuang93536072014-11-20 15:39:56 -0800130
Frank Galliganf9d69bd2013-12-09 17:07:10 -0800131 // Hook to be called before decompressing every frame.
clang-format3a826f12016-08-11 17:46:05 -0700132 virtual void PreDecodeFrameHook(const CompressedVideoSource & /*video*/,
133 Decoder * /*decoder*/) {}
Frank Galliganf9d69bd2013-12-09 17:07:10 -0800134
Jim Bankoskidc2f2ce2014-06-20 13:52:06 -0700135 // Hook to be called to handle decode result. Return true to continue.
Yaowu Xuf883b422016-08-30 14:01:10 -0700136 virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
Wan-Teh Chang6fe004d2018-04-30 16:50:29 -0700137 const CompressedVideoSource & /*video*/,
Jim Bankoskidc2f2ce2014-06-20 13:52:06 -0700138 Decoder *decoder) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700139 EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
140 return AOM_CODEC_OK == res_dec;
Jim Bankoskidc2f2ce2014-06-20 13:52:06 -0700141 }
142
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700143 // Hook to be called on every decompressed frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700144 virtual void DecompressedFrameHook(const aom_image_t & /*img*/,
James Zernadfda322014-08-22 11:58:48 -0700145 const unsigned int /*frame_number*/) {}
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700146
Deb Mukherjeec447a502014-07-15 01:54:29 -0700147 // Hook to be called on peek result
clang-format3a826f12016-08-11 17:46:05 -0700148 virtual void HandlePeekResult(Decoder *const decoder,
Deb Mukherjeec447a502014-07-15 01:54:29 -0700149 CompressedVideoSource *video,
Yaowu Xuf883b422016-08-30 14:01:10 -0700150 const aom_codec_err_t res_peek);
Deb Mukherjeec447a502014-07-15 01:54:29 -0700151
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700152 protected:
hkuang93536072014-11-20 15:39:56 -0800153 explicit DecoderTest(const CodecFactory *codec)
clang-format3a826f12016-08-11 17:46:05 -0700154 : codec_(codec), cfg_(), flags_(0) {}
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700155
156 virtual ~DecoderTest() {}
John Koleszar706cafe2013-01-18 11:51:12 -0800157
158 const CodecFactory *codec_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700159 aom_codec_dec_cfg_t cfg_;
160 aom_codec_flags_t flags_;
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700161};
162
Yaowu Xuc27fc142016-08-22 16:08:15 -0700163} // namespace libaom_test
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700164
James Zerne1cbb132018-08-22 14:10:36 -0700165#endif // AOM_TEST_DECODE_TEST_DRIVER_H_