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