Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #ifndef TEST_DECODE_TEST_DRIVER_H_ |
| 13 | #define TEST_DECODE_TEST_DRIVER_H_ |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 14 | #include <cstring> |
Tom Finegan | 7a07ece | 2017-02-07 17:14:05 -0800 | [diff] [blame] | 15 | #include "third_party/googletest/src/googletest/include/gtest/gtest.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 16 | #include "./aom_config.h" |
| 17 | #include "aom/aom_decoder.h" |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 18 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 19 | namespace libaom_test { |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 20 | |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 21 | class CodecFactory; |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 22 | class CompressedVideoSource; |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 23 | |
| 24 | // Provides an object to handle decoding output |
| 25 | class DxDataIterator { |
| 26 | public: |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 27 | explicit DxDataIterator(aom_codec_ctx_t *decoder) |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 28 | : decoder_(decoder), iter_(NULL) {} |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 29 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 30 | const aom_image_t *Next() { return aom_codec_get_frame(decoder_, &iter_); } |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 31 | |
| 32 | private: |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 33 | aom_codec_ctx_t *decoder_; |
| 34 | aom_codec_iter_t iter_; |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 35 | }; |
| 36 | |
| 37 | // Provides a simplified interface to manage one video decoding. |
Yaowu Xu | afffa3d | 2013-09-05 08:45:56 -0700 | [diff] [blame] | 38 | // Similar to Encoder class, the exact services should be added |
| 39 | // as more tests are added. |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 40 | class Decoder { |
| 41 | public: |
James Zern | 3b96b76 | 2017-03-24 17:12:19 -0700 | [diff] [blame] | 42 | explicit Decoder(aom_codec_dec_cfg_t cfg) |
| 43 | : cfg_(cfg), flags_(0), init_done_(false) { |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 44 | memset(&decoder_, 0, sizeof(decoder_)); |
| 45 | } |
| 46 | |
James Zern | 3b96b76 | 2017-03-24 17:12:19 -0700 | [diff] [blame] | 47 | Decoder(aom_codec_dec_cfg_t cfg, const aom_codec_flags_t flag) |
| 48 | : cfg_(cfg), flags_(flag), init_done_(false) { |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 49 | memset(&decoder_, 0, sizeof(decoder_)); |
| 50 | } |
| 51 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 52 | virtual ~Decoder() { aom_codec_destroy(&decoder_); } |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 53 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 54 | aom_codec_err_t PeekStream(const uint8_t *cxdata, size_t size, |
| 55 | aom_codec_stream_info_t *stream_info); |
Jim Bankoski | 96727b9 | 2014-06-23 08:37:18 -0700 | [diff] [blame] | 56 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 57 | aom_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 58 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 59 | aom_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size, |
hkuang | 5e7242d | 2014-06-23 14:59:20 -0700 | [diff] [blame] | 60 | void *user_priv); |
| 61 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 62 | DxDataIterator GetDxData() { return DxDataIterator(&decoder_); } |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 63 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 64 | void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, AOM_CODEC_OK); } |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 65 | |
Dmitry Kovalev | 26cec5c | 2013-03-15 18:21:55 -0700 | [diff] [blame] | 66 | void Control(int ctrl_id, const void *arg) { |
John Koleszar | 771fc83 | 2013-03-27 10:41:29 -0700 | [diff] [blame] | 67 | InitOnce(); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 68 | const aom_codec_err_t res = aom_codec_control_(&decoder_, ctrl_id, arg); |
| 69 | ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError(); |
Dmitry Kovalev | 26cec5c | 2013-03-15 18:21:55 -0700 | [diff] [blame] | 70 | } |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 71 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 72 | void Control(int ctrl_id, int arg, aom_codec_err_t expected_value) { |
Frank Galligan | c4f7079 | 2014-12-15 12:00:09 -0800 | [diff] [blame] | 73 | InitOnce(); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 74 | const aom_codec_err_t res = aom_codec_control_(&decoder_, ctrl_id, arg); |
Frank Galligan | c4f7079 | 2014-12-15 12:00:09 -0800 | [diff] [blame] | 75 | ASSERT_EQ(expected_value, res) << DecodeError(); |
| 76 | } |
| 77 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 78 | const char *DecodeError() { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 79 | const char *detail = aom_codec_error_detail(&decoder_); |
| 80 | return detail ? detail : aom_codec_error(&decoder_); |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 81 | } |
| 82 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 83 | // Passes the external frame buffer information to libaom. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 84 | aom_codec_err_t SetFrameBufferFunctions( |
| 85 | aom_get_frame_buffer_cb_fn_t cb_get, |
| 86 | aom_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { |
Frank Galligan | a4f30a5 | 2014-02-06 17:13:08 -0800 | [diff] [blame] | 87 | InitOnce(); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 88 | return aom_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 89 | user_priv); |
Frank Galligan | a4f30a5 | 2014-02-06 17:13:08 -0800 | [diff] [blame] | 90 | } |
| 91 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 92 | const char *GetDecoderName() const { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 93 | return aom_codec_iface_name(CodecInterface()); |
Jim Bankoski | 96727b9 | 2014-06-23 08:37:18 -0700 | [diff] [blame] | 94 | } |
| 95 | |
Deb Mukherjee | c447a50 | 2014-07-15 01:54:29 -0700 | [diff] [blame] | 96 | bool IsVP8() const; |
| 97 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 98 | bool IsAV1() const; |
Yunqing Wang | 8e5e338 | 2016-05-05 16:42:57 -0700 | [diff] [blame] | 99 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 100 | aom_codec_ctx_t *GetDecoder() { return &decoder_; } |
Jim Bankoski | a0d9a9d | 2014-12-11 17:34:32 -0800 | [diff] [blame] | 101 | |
Dmitry Kovalev | 26cec5c | 2013-03-15 18:21:55 -0700 | [diff] [blame] | 102 | protected: |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 103 | virtual aom_codec_iface_t *CodecInterface() const = 0; |
John Koleszar | 771fc83 | 2013-03-27 10:41:29 -0700 | [diff] [blame] | 104 | |
| 105 | void InitOnce() { |
| 106 | if (!init_done_) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 107 | const aom_codec_err_t res = |
| 108 | aom_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_); |
| 109 | ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError(); |
John Koleszar | 771fc83 | 2013-03-27 10:41:29 -0700 | [diff] [blame] | 110 | init_done_ = true; |
| 111 | } |
Dmitry Kovalev | 26cec5c | 2013-03-15 18:21:55 -0700 | [diff] [blame] | 112 | } |
| 113 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 114 | aom_codec_ctx_t decoder_; |
| 115 | aom_codec_dec_cfg_t cfg_; |
| 116 | aom_codec_flags_t flags_; |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 117 | bool init_done_; |
Yaowu Xu | c953aea | 2012-08-30 13:43:15 -0700 | [diff] [blame] | 118 | }; |
| 119 | |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 120 | // Common test functionality for all Decoder tests. |
| 121 | class DecoderTest { |
| 122 | public: |
Deb Mukherjee | 01cafaa | 2013-01-15 06:43:35 -0800 | [diff] [blame] | 123 | // Main decoding loop |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 124 | virtual void RunLoop(CompressedVideoSource *video); |
hkuang | c147cf3 | 2014-07-01 16:04:53 -0700 | [diff] [blame] | 125 | virtual void RunLoop(CompressedVideoSource *video, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 126 | const aom_codec_dec_cfg_t &dec_cfg); |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 127 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 128 | virtual void set_cfg(const aom_codec_dec_cfg_t &dec_cfg); |
| 129 | virtual void set_flags(const aom_codec_flags_t flags); |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 130 | |
Frank Galligan | f9d69bd | 2013-12-09 17:07:10 -0800 | [diff] [blame] | 131 | // Hook to be called before decompressing every frame. |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 132 | virtual void PreDecodeFrameHook(const CompressedVideoSource & /*video*/, |
| 133 | Decoder * /*decoder*/) {} |
Frank Galligan | f9d69bd | 2013-12-09 17:07:10 -0800 | [diff] [blame] | 134 | |
Jim Bankoski | dc2f2ce | 2014-06-20 13:52:06 -0700 | [diff] [blame] | 135 | // Hook to be called to handle decode result. Return true to continue. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 136 | virtual bool HandleDecodeResult(const aom_codec_err_t res_dec, |
Jim Bankoski | dc2f2ce | 2014-06-20 13:52:06 -0700 | [diff] [blame] | 137 | Decoder *decoder) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 138 | EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError(); |
| 139 | return AOM_CODEC_OK == res_dec; |
Jim Bankoski | dc2f2ce | 2014-06-20 13:52:06 -0700 | [diff] [blame] | 140 | } |
| 141 | |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 142 | // Hook to be called on every decompressed frame. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 143 | virtual void DecompressedFrameHook(const aom_image_t & /*img*/, |
James Zern | adfda32 | 2014-08-22 11:58:48 -0700 | [diff] [blame] | 144 | const unsigned int /*frame_number*/) {} |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 145 | |
Deb Mukherjee | c447a50 | 2014-07-15 01:54:29 -0700 | [diff] [blame] | 146 | // Hook to be called on peek result |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 147 | virtual void HandlePeekResult(Decoder *const decoder, |
Deb Mukherjee | c447a50 | 2014-07-15 01:54:29 -0700 | [diff] [blame] | 148 | CompressedVideoSource *video, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 149 | const aom_codec_err_t res_peek); |
Deb Mukherjee | c447a50 | 2014-07-15 01:54:29 -0700 | [diff] [blame] | 150 | |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 151 | protected: |
hkuang | 9353607 | 2014-11-20 15:39:56 -0800 | [diff] [blame] | 152 | explicit DecoderTest(const CodecFactory *codec) |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 153 | : codec_(codec), cfg_(), flags_(0) {} |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 154 | |
| 155 | virtual ~DecoderTest() {} |
John Koleszar | 706cafe | 2013-01-18 11:51:12 -0800 | [diff] [blame] | 156 | |
| 157 | const CodecFactory *codec_; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 158 | aom_codec_dec_cfg_t cfg_; |
| 159 | aom_codec_flags_t flags_; |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 160 | }; |
| 161 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 162 | } // namespace libaom_test |
Yunqing Wang | 15dffcf | 2012-10-04 12:59:36 -0700 | [diff] [blame] | 163 | |
| 164 | #endif // TEST_DECODE_TEST_DRIVER_H_ |