xref: /aosp_15_r20/external/libaom/test/decode_test_driver.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_TEST_DECODE_TEST_DRIVER_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_TEST_DECODE_TEST_DRIVER_H_
14*77c1e3ccSAndroid Build Coastguard Worker #include <cstring>
15*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
16*77c1e3ccSAndroid Build Coastguard Worker 
17*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
18*77c1e3ccSAndroid Build Coastguard Worker 
19*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_decoder.h"
20*77c1e3ccSAndroid Build Coastguard Worker 
21*77c1e3ccSAndroid Build Coastguard Worker namespace libaom_test {
22*77c1e3ccSAndroid Build Coastguard Worker 
23*77c1e3ccSAndroid Build Coastguard Worker class CodecFactory;
24*77c1e3ccSAndroid Build Coastguard Worker class CompressedVideoSource;
25*77c1e3ccSAndroid Build Coastguard Worker 
26*77c1e3ccSAndroid Build Coastguard Worker // Provides an object to handle decoding output
27*77c1e3ccSAndroid Build Coastguard Worker class DxDataIterator {
28*77c1e3ccSAndroid Build Coastguard Worker  public:
DxDataIterator(aom_codec_ctx_t * decoder)29*77c1e3ccSAndroid Build Coastguard Worker   explicit DxDataIterator(aom_codec_ctx_t *decoder)
30*77c1e3ccSAndroid Build Coastguard Worker       : decoder_(decoder), iter_(nullptr) {}
31*77c1e3ccSAndroid Build Coastguard Worker 
Next()32*77c1e3ccSAndroid Build Coastguard Worker   const aom_image_t *Next() { return aom_codec_get_frame(decoder_, &iter_); }
33*77c1e3ccSAndroid Build Coastguard Worker 
34*77c1e3ccSAndroid Build Coastguard Worker  private:
35*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t *decoder_;
36*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iter_t iter_;
37*77c1e3ccSAndroid Build Coastguard Worker };
38*77c1e3ccSAndroid Build Coastguard Worker 
39*77c1e3ccSAndroid Build Coastguard Worker // Provides a simplified interface to manage one video decoding.
40*77c1e3ccSAndroid Build Coastguard Worker // Similar to Encoder class, the exact services should be added
41*77c1e3ccSAndroid Build Coastguard Worker // as more tests are added.
42*77c1e3ccSAndroid Build Coastguard Worker class Decoder {
43*77c1e3ccSAndroid Build Coastguard Worker  public:
Decoder(aom_codec_dec_cfg_t cfg)44*77c1e3ccSAndroid Build Coastguard Worker   explicit Decoder(aom_codec_dec_cfg_t cfg)
45*77c1e3ccSAndroid Build Coastguard Worker       : cfg_(cfg), flags_(0), init_done_(false) {
46*77c1e3ccSAndroid Build Coastguard Worker     memset(&decoder_, 0, sizeof(decoder_));
47*77c1e3ccSAndroid Build Coastguard Worker   }
48*77c1e3ccSAndroid Build Coastguard Worker 
Decoder(aom_codec_dec_cfg_t cfg,const aom_codec_flags_t flag)49*77c1e3ccSAndroid Build Coastguard Worker   Decoder(aom_codec_dec_cfg_t cfg, const aom_codec_flags_t flag)
50*77c1e3ccSAndroid Build Coastguard Worker       : cfg_(cfg), flags_(flag), init_done_(false) {
51*77c1e3ccSAndroid Build Coastguard Worker     memset(&decoder_, 0, sizeof(decoder_));
52*77c1e3ccSAndroid Build Coastguard Worker   }
53*77c1e3ccSAndroid Build Coastguard Worker 
~Decoder()54*77c1e3ccSAndroid Build Coastguard Worker   virtual ~Decoder() { aom_codec_destroy(&decoder_); }
55*77c1e3ccSAndroid Build Coastguard Worker 
56*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
57*77c1e3ccSAndroid Build Coastguard Worker                              aom_codec_stream_info_t *stream_info);
58*77c1e3ccSAndroid Build Coastguard Worker 
59*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size);
60*77c1e3ccSAndroid Build Coastguard Worker 
61*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
62*77c1e3ccSAndroid Build Coastguard Worker                               void *user_priv);
63*77c1e3ccSAndroid Build Coastguard Worker 
GetDxData()64*77c1e3ccSAndroid Build Coastguard Worker   DxDataIterator GetDxData() { return DxDataIterator(&decoder_); }
65*77c1e3ccSAndroid Build Coastguard Worker 
Control(int ctrl_id,int arg)66*77c1e3ccSAndroid Build Coastguard Worker   void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, AOM_CODEC_OK); }
67*77c1e3ccSAndroid Build Coastguard Worker 
Control(int ctrl_id,const void * arg)68*77c1e3ccSAndroid Build Coastguard Worker   void Control(int ctrl_id, const void *arg) {
69*77c1e3ccSAndroid Build Coastguard Worker     InitOnce();
70*77c1e3ccSAndroid Build Coastguard Worker     const aom_codec_err_t res = aom_codec_control(&decoder_, ctrl_id, arg);
71*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError();
72*77c1e3ccSAndroid Build Coastguard Worker   }
73*77c1e3ccSAndroid Build Coastguard Worker 
Control(int ctrl_id,int arg,aom_codec_err_t expected_value)74*77c1e3ccSAndroid Build Coastguard Worker   void Control(int ctrl_id, int arg, aom_codec_err_t expected_value) {
75*77c1e3ccSAndroid Build Coastguard Worker     InitOnce();
76*77c1e3ccSAndroid Build Coastguard Worker     const aom_codec_err_t res = aom_codec_control(&decoder_, ctrl_id, arg);
77*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(expected_value, res) << DecodeError();
78*77c1e3ccSAndroid Build Coastguard Worker   }
79*77c1e3ccSAndroid Build Coastguard Worker 
DecodeError()80*77c1e3ccSAndroid Build Coastguard Worker   const char *DecodeError() {
81*77c1e3ccSAndroid Build Coastguard Worker     const char *detail = aom_codec_error_detail(&decoder_);
82*77c1e3ccSAndroid Build Coastguard Worker     return detail ? detail : aom_codec_error(&decoder_);
83*77c1e3ccSAndroid Build Coastguard Worker   }
84*77c1e3ccSAndroid Build Coastguard Worker 
85*77c1e3ccSAndroid Build Coastguard Worker   // Passes the external frame buffer information to libaom.
SetFrameBufferFunctions(aom_get_frame_buffer_cb_fn_t cb_get,aom_release_frame_buffer_cb_fn_t cb_release,void * user_priv)86*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t SetFrameBufferFunctions(
87*77c1e3ccSAndroid Build Coastguard Worker       aom_get_frame_buffer_cb_fn_t cb_get,
88*77c1e3ccSAndroid Build Coastguard Worker       aom_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
89*77c1e3ccSAndroid Build Coastguard Worker     InitOnce();
90*77c1e3ccSAndroid Build Coastguard Worker     return aom_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release,
91*77c1e3ccSAndroid Build Coastguard Worker                                                 user_priv);
92*77c1e3ccSAndroid Build Coastguard Worker   }
93*77c1e3ccSAndroid Build Coastguard Worker 
GetDecoderName()94*77c1e3ccSAndroid Build Coastguard Worker   const char *GetDecoderName() const {
95*77c1e3ccSAndroid Build Coastguard Worker     return aom_codec_iface_name(CodecInterface());
96*77c1e3ccSAndroid Build Coastguard Worker   }
97*77c1e3ccSAndroid Build Coastguard Worker 
98*77c1e3ccSAndroid Build Coastguard Worker   bool IsAV1() const;
99*77c1e3ccSAndroid Build Coastguard Worker 
GetDecoder()100*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t *GetDecoder() { return &decoder_; }
101*77c1e3ccSAndroid Build Coastguard Worker 
102*77c1e3ccSAndroid Build Coastguard Worker  protected:
103*77c1e3ccSAndroid Build Coastguard Worker   virtual aom_codec_iface_t *CodecInterface() const = 0;
104*77c1e3ccSAndroid Build Coastguard Worker 
InitOnce()105*77c1e3ccSAndroid Build Coastguard Worker   void InitOnce() {
106*77c1e3ccSAndroid Build Coastguard Worker     if (!init_done_) {
107*77c1e3ccSAndroid Build Coastguard Worker       const aom_codec_err_t res =
108*77c1e3ccSAndroid Build Coastguard Worker           aom_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_);
109*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_EQ(AOM_CODEC_OK, res) << DecodeError();
110*77c1e3ccSAndroid Build Coastguard Worker       init_done_ = true;
111*77c1e3ccSAndroid Build Coastguard Worker     }
112*77c1e3ccSAndroid Build Coastguard Worker   }
113*77c1e3ccSAndroid Build Coastguard Worker 
114*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t decoder_;
115*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_dec_cfg_t cfg_;
116*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_flags_t flags_;
117*77c1e3ccSAndroid Build Coastguard Worker   bool init_done_;
118*77c1e3ccSAndroid Build Coastguard Worker };
119*77c1e3ccSAndroid Build Coastguard Worker 
120*77c1e3ccSAndroid Build Coastguard Worker // Common test functionality for all Decoder tests.
121*77c1e3ccSAndroid Build Coastguard Worker class DecoderTest {
122*77c1e3ccSAndroid Build Coastguard Worker  public:
123*77c1e3ccSAndroid Build Coastguard Worker   // Main decoding loop
124*77c1e3ccSAndroid Build Coastguard Worker   virtual void RunLoop(CompressedVideoSource *video);
125*77c1e3ccSAndroid Build Coastguard Worker   virtual void RunLoop(CompressedVideoSource *video,
126*77c1e3ccSAndroid Build Coastguard Worker                        const aom_codec_dec_cfg_t &dec_cfg);
127*77c1e3ccSAndroid Build Coastguard Worker 
128*77c1e3ccSAndroid Build Coastguard Worker   virtual void set_cfg(const aom_codec_dec_cfg_t &dec_cfg);
129*77c1e3ccSAndroid Build Coastguard Worker   virtual void set_flags(const aom_codec_flags_t flags);
130*77c1e3ccSAndroid Build Coastguard Worker 
131*77c1e3ccSAndroid Build Coastguard Worker   // Hook to be called before decompressing every frame.
PreDecodeFrameHook(const CompressedVideoSource &,Decoder *)132*77c1e3ccSAndroid Build Coastguard Worker   virtual void PreDecodeFrameHook(const CompressedVideoSource & /*video*/,
133*77c1e3ccSAndroid Build Coastguard Worker                                   Decoder * /*decoder*/) {}
134*77c1e3ccSAndroid Build Coastguard Worker 
135*77c1e3ccSAndroid Build Coastguard Worker   // Hook to be called to handle decode result. Return true to continue.
HandleDecodeResult(const aom_codec_err_t res_dec,const CompressedVideoSource &,Decoder * decoder)136*77c1e3ccSAndroid Build Coastguard Worker   virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
137*77c1e3ccSAndroid Build Coastguard Worker                                   const CompressedVideoSource & /*video*/,
138*77c1e3ccSAndroid Build Coastguard Worker                                   Decoder *decoder) {
139*77c1e3ccSAndroid Build Coastguard Worker     EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
140*77c1e3ccSAndroid Build Coastguard Worker     return AOM_CODEC_OK == res_dec;
141*77c1e3ccSAndroid Build Coastguard Worker   }
142*77c1e3ccSAndroid Build Coastguard Worker 
143*77c1e3ccSAndroid Build Coastguard Worker   // Hook to be called on every decompressed frame.
DecompressedFrameHook(const aom_image_t &,const unsigned int)144*77c1e3ccSAndroid Build Coastguard Worker   virtual void DecompressedFrameHook(const aom_image_t & /*img*/,
145*77c1e3ccSAndroid Build Coastguard Worker                                      const unsigned int /*frame_number*/) {}
146*77c1e3ccSAndroid Build Coastguard Worker 
147*77c1e3ccSAndroid Build Coastguard Worker   // Hook to be called on peek result
148*77c1e3ccSAndroid Build Coastguard Worker   virtual void HandlePeekResult(Decoder *const decoder,
149*77c1e3ccSAndroid Build Coastguard Worker                                 CompressedVideoSource *video,
150*77c1e3ccSAndroid Build Coastguard Worker                                 const aom_codec_err_t res_peek);
151*77c1e3ccSAndroid Build Coastguard Worker 
152*77c1e3ccSAndroid Build Coastguard Worker  protected:
DecoderTest(const CodecFactory * codec)153*77c1e3ccSAndroid Build Coastguard Worker   explicit DecoderTest(const CodecFactory *codec)
154*77c1e3ccSAndroid Build Coastguard Worker       : codec_(codec), cfg_(), flags_(0) {}
155*77c1e3ccSAndroid Build Coastguard Worker 
156*77c1e3ccSAndroid Build Coastguard Worker   virtual ~DecoderTest() = default;
157*77c1e3ccSAndroid Build Coastguard Worker 
158*77c1e3ccSAndroid Build Coastguard Worker   const CodecFactory *codec_;
159*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_dec_cfg_t cfg_;
160*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_flags_t flags_;
161*77c1e3ccSAndroid Build Coastguard Worker };
162*77c1e3ccSAndroid Build Coastguard Worker 
163*77c1e3ccSAndroid Build Coastguard Worker }  // namespace libaom_test
164*77c1e3ccSAndroid Build Coastguard Worker 
165*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_TEST_DECODE_TEST_DRIVER_H_
166