Add ssse3 aom_smooth_h_predictor_4xh
[aom.git] / test / encode_test_driver.h
blob4249b48fa9edf0685b9601dbfb7795067809faa5
1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
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.
11 #ifndef TEST_ENCODE_TEST_DRIVER_H_
12 #define TEST_ENCODE_TEST_DRIVER_H_
14 #include <string>
15 #include <vector>
17 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
19 #include "./aom_config.h"
20 #if CONFIG_AV1_ENCODER
21 #include "aom/aomcx.h"
22 #endif
23 #include "aom/aom_encoder.h"
25 namespace libaom_test {
27 class CodecFactory;
28 class VideoSource;
30 enum TestMode { kRealTime, kOnePassGood, kTwoPassGood };
31 #define ALL_TEST_MODES \
32 ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood, \
33 ::libaom_test::kTwoPassGood)
35 #define ONE_PASS_TEST_MODES \
36 ::testing::Values(::libaom_test::kRealTime, ::libaom_test::kOnePassGood)
38 #define TWO_PASS_TEST_MODES ::testing::Values(::libaom_test::kTwoPassGood)
40 #define NONREALTIME_TEST_MODES \
41 ::testing::Values(::libaom_test::kOnePassGood, ::libaom_test::kTwoPassGood)
43 // Provides an object to handle the libaom get_cx_data() iteration pattern
44 class CxDataIterator {
45 public:
46 explicit CxDataIterator(aom_codec_ctx_t *encoder)
47 : encoder_(encoder), iter_(NULL) {}
49 const aom_codec_cx_pkt_t *Next() {
50 return aom_codec_get_cx_data(encoder_, &iter_);
53 private:
54 aom_codec_ctx_t *encoder_;
55 aom_codec_iter_t iter_;
58 // Implements an in-memory store for libaom twopass statistics
59 class TwopassStatsStore {
60 public:
61 void Append(const aom_codec_cx_pkt_t &pkt) {
62 buffer_.append(reinterpret_cast<char *>(pkt.data.twopass_stats.buf),
63 pkt.data.twopass_stats.sz);
66 aom_fixed_buf_t buf() {
67 const aom_fixed_buf_t buf = { &buffer_[0], buffer_.size() };
68 return buf;
71 void Reset() { buffer_.clear(); }
73 protected:
74 std::string buffer_;
77 // Provides a simplified interface to manage one video encoding pass, given
78 // a configuration and video source.
80 // TODO(jkoleszar): The exact services it provides and the appropriate
81 // level of abstraction will be fleshed out as more tests are written.
82 class Encoder {
83 public:
84 Encoder(aom_codec_enc_cfg_t cfg, const uint32_t init_flags,
85 TwopassStatsStore *stats)
86 : cfg_(cfg), init_flags_(init_flags), stats_(stats) {
87 memset(&encoder_, 0, sizeof(encoder_));
90 virtual ~Encoder() { aom_codec_destroy(&encoder_); }
92 CxDataIterator GetCxData() { return CxDataIterator(&encoder_); }
94 void InitEncoder(VideoSource *video);
96 const aom_image_t *GetPreviewFrame() {
97 return aom_codec_get_preview_frame(&encoder_);
99 // This is a thin wrapper around aom_codec_encode(), so refer to
100 // aom_encoder.h for its semantics.
101 void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
103 // Convenience wrapper for EncodeFrame()
104 void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); }
106 void Control(int ctrl_id, int arg) {
107 const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg);
108 ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError();
111 void Control(int ctrl_id, int *arg) {
112 const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg);
113 ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError();
116 void Control(int ctrl_id, struct aom_scaling_mode *arg) {
117 const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg);
118 ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError();
121 #if CONFIG_AV1_ENCODER
122 void Control(int ctrl_id, aom_active_map_t *arg) {
123 const aom_codec_err_t res = aom_codec_control_(&encoder_, ctrl_id, arg);
124 ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError();
126 #endif
128 void Config(const aom_codec_enc_cfg_t *cfg) {
129 const aom_codec_err_t res = aom_codec_enc_config_set(&encoder_, cfg);
130 ASSERT_EQ(AOM_CODEC_OK, res) << EncoderError();
131 cfg_ = *cfg;
134 protected:
135 virtual aom_codec_iface_t *CodecInterface() const = 0;
137 const char *EncoderError() {
138 const char *detail = aom_codec_error_detail(&encoder_);
139 return detail ? detail : aom_codec_error(&encoder_);
142 // Encode an image
143 void EncodeFrameInternal(const VideoSource &video,
144 const unsigned long frame_flags);
146 // Flush the encoder on EOS
147 void Flush();
149 aom_codec_ctx_t encoder_;
150 aom_codec_enc_cfg_t cfg_;
151 unsigned long init_flags_;
152 TwopassStatsStore *stats_;
155 // Common test functionality for all Encoder tests.
157 // This class is a mixin which provides the main loop common to all
158 // encoder tests. It provides hooks which can be overridden by subclasses
159 // to implement each test's specific behavior, while centralizing the bulk
160 // of the boilerplate. Note that it doesn't inherit the gtest testing
161 // classes directly, so that tests can be parameterized differently.
162 class EncoderTest {
163 protected:
164 explicit EncoderTest(const CodecFactory *codec)
165 : codec_(codec), abort_(false), init_flags_(0), frame_flags_(0),
166 last_pts_(0), mode_(kRealTime) {
167 // Default to 1 thread.
168 cfg_.g_threads = 1;
171 virtual ~EncoderTest() {}
173 // Initialize the cfg_ member with the default configuration.
174 void InitializeConfig();
176 // Map the TestMode enum to the passes_ variables.
177 void SetMode(TestMode mode);
179 // Set encoder flag.
180 void set_init_flags(unsigned long flag) { // NOLINT(runtime/int)
181 init_flags_ = flag;
184 // Main loop
185 virtual void RunLoop(VideoSource *video);
187 // Hook to be called at the beginning of a pass.
188 virtual void BeginPassHook(unsigned int /*pass*/) {}
190 // Hook to be called at the end of a pass.
191 virtual void EndPassHook() {}
193 // Hook to be called before encoding a frame.
194 virtual void PreEncodeFrameHook(VideoSource * /*video*/) {}
195 virtual void PreEncodeFrameHook(VideoSource * /*video*/,
196 Encoder * /*encoder*/) {}
198 // Hook to be called on every compressed data packet.
199 virtual void FramePktHook(const aom_codec_cx_pkt_t * /*pkt*/) {}
201 // Hook to be called on every PSNR packet.
202 virtual void PSNRPktHook(const aom_codec_cx_pkt_t * /*pkt*/) {}
204 // Hook to determine whether the encode loop should continue.
205 virtual bool Continue() const {
206 return !(::testing::Test::HasFatalFailure() || abort_);
209 const CodecFactory *codec_;
210 // Hook to determine whether to decode frame after encoding
211 virtual bool DoDecode() const { return 1; }
213 // Hook to handle encode/decode mismatch
214 virtual void MismatchHook(const aom_image_t *img1, const aom_image_t *img2);
216 // Hook to be called on every decompressed frame.
217 virtual void DecompressedFrameHook(const aom_image_t & /*img*/,
218 aom_codec_pts_t /*pts*/) {}
220 // Hook to be called to handle decode result. Return true to continue.
221 virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
222 Decoder *decoder) {
223 EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
224 return AOM_CODEC_OK == res_dec;
227 // Hook that can modify the encoder's output data
228 virtual const aom_codec_cx_pkt_t *MutateEncoderOutputHook(
229 const aom_codec_cx_pkt_t *pkt) {
230 return pkt;
233 bool abort_;
234 aom_codec_enc_cfg_t cfg_;
235 unsigned int passes_;
236 TwopassStatsStore stats_;
237 unsigned long init_flags_;
238 unsigned long frame_flags_;
239 aom_codec_pts_t last_pts_;
240 TestMode mode_;
243 } // namespace libaom_test
245 #endif // TEST_ENCODE_TEST_DRIVER_H_