1 /* 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef TEST_DECODE_TEST_DRIVER_H_ 12 #define TEST_DECODE_TEST_DRIVER_H_ 13 #include <cstring> 14 #include "third_party/googletest/src/include/gtest/gtest.h" 15 #include "./vpx_config.h" 16 #include "vpx/vpx_decoder.h" 17 18 namespace libvpx_test { 19 20 class CodecFactory; 21 class CompressedVideoSource; 22 23 // Provides an object to handle decoding output 24 class DxDataIterator { 25 public: DxDataIterator(vpx_codec_ctx_t * decoder)26 explicit DxDataIterator(vpx_codec_ctx_t *decoder) 27 : decoder_(decoder), iter_(NULL) {} 28 Next()29 const vpx_image_t *Next() { 30 return vpx_codec_get_frame(decoder_, &iter_); 31 } 32 33 private: 34 vpx_codec_ctx_t *decoder_; 35 vpx_codec_iter_t iter_; 36 }; 37 38 // Provides a simplified interface to manage one video decoding. 39 // Similar to Encoder class, the exact services should be added 40 // as more tests are added. 41 class Decoder { 42 public: Decoder(vpx_codec_dec_cfg_t cfg,unsigned long deadline)43 Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline) 44 : cfg_(cfg), flags_(0), deadline_(deadline), init_done_(false) { 45 memset(&decoder_, 0, sizeof(decoder_)); 46 } 47 Decoder(vpx_codec_dec_cfg_t cfg,const vpx_codec_flags_t flag,unsigned long deadline)48 Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag, 49 unsigned long deadline) // NOLINT 50 : cfg_(cfg), flags_(flag), deadline_(deadline), init_done_(false) { 51 memset(&decoder_, 0, sizeof(decoder_)); 52 } 53 ~Decoder()54 virtual ~Decoder() { 55 vpx_codec_destroy(&decoder_); 56 } 57 58 vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size, 59 vpx_codec_stream_info_t *stream_info); 60 61 vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); 62 63 vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size, 64 void *user_priv); 65 GetDxData()66 DxDataIterator GetDxData() { 67 return DxDataIterator(&decoder_); 68 } 69 set_deadline(unsigned long deadline)70 void set_deadline(unsigned long deadline) { 71 deadline_ = deadline; 72 } 73 Control(int ctrl_id,int arg)74 void Control(int ctrl_id, int arg) { 75 Control(ctrl_id, arg, VPX_CODEC_OK); 76 } 77 Control(int ctrl_id,const void * arg)78 void Control(int ctrl_id, const void *arg) { 79 InitOnce(); 80 const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 81 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 82 } 83 Control(int ctrl_id,int arg,vpx_codec_err_t expected_value)84 void Control(int ctrl_id, int arg, vpx_codec_err_t expected_value) { 85 InitOnce(); 86 const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 87 ASSERT_EQ(expected_value, res) << DecodeError(); 88 } 89 DecodeError()90 const char* DecodeError() { 91 const char *detail = vpx_codec_error_detail(&decoder_); 92 return detail ? detail : vpx_codec_error(&decoder_); 93 } 94 95 // Passes the external frame buffer information to libvpx. SetFrameBufferFunctions(vpx_get_frame_buffer_cb_fn_t cb_get,vpx_release_frame_buffer_cb_fn_t cb_release,void * user_priv)96 vpx_codec_err_t SetFrameBufferFunctions( 97 vpx_get_frame_buffer_cb_fn_t cb_get, 98 vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { 99 InitOnce(); 100 return vpx_codec_set_frame_buffer_functions( 101 &decoder_, cb_get, cb_release, user_priv); 102 } 103 GetDecoderName()104 const char* GetDecoderName() const { 105 return vpx_codec_iface_name(CodecInterface()); 106 } 107 108 bool IsVP8() const; 109 GetDecoder()110 vpx_codec_ctx_t * GetDecoder() { 111 return &decoder_; 112 } 113 114 protected: 115 virtual vpx_codec_iface_t* CodecInterface() const = 0; 116 InitOnce()117 void InitOnce() { 118 if (!init_done_) { 119 const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, 120 CodecInterface(), 121 &cfg_, flags_); 122 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 123 init_done_ = true; 124 } 125 } 126 127 vpx_codec_ctx_t decoder_; 128 vpx_codec_dec_cfg_t cfg_; 129 vpx_codec_flags_t flags_; 130 unsigned int deadline_; 131 bool init_done_; 132 }; 133 134 // Common test functionality for all Decoder tests. 135 class DecoderTest { 136 public: 137 // Main decoding loop 138 virtual void RunLoop(CompressedVideoSource *video); 139 virtual void RunLoop(CompressedVideoSource *video, 140 const vpx_codec_dec_cfg_t &dec_cfg); 141 142 virtual void set_cfg(const vpx_codec_dec_cfg_t &dec_cfg); 143 virtual void set_flags(const vpx_codec_flags_t flags); 144 145 // Hook to be called before decompressing every frame. PreDecodeFrameHook(const CompressedVideoSource &,Decoder *)146 virtual void PreDecodeFrameHook(const CompressedVideoSource& /*video*/, 147 Decoder* /*decoder*/) {} 148 149 // Hook to be called to handle decode result. Return true to continue. HandleDecodeResult(const vpx_codec_err_t res_dec,const CompressedVideoSource &,Decoder * decoder)150 virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec, 151 const CompressedVideoSource& /*video*/, 152 Decoder *decoder) { 153 EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); 154 return VPX_CODEC_OK == res_dec; 155 } 156 157 // Hook to be called on every decompressed frame. DecompressedFrameHook(const vpx_image_t &,const unsigned int)158 virtual void DecompressedFrameHook(const vpx_image_t& /*img*/, 159 const unsigned int /*frame_number*/) {} 160 161 // Hook to be called on peek result 162 virtual void HandlePeekResult(Decoder* const decoder, 163 CompressedVideoSource *video, 164 const vpx_codec_err_t res_peek); 165 166 protected: DecoderTest(const CodecFactory * codec)167 explicit DecoderTest(const CodecFactory *codec) 168 : codec_(codec), 169 cfg_(), 170 flags_(0) {} 171 ~DecoderTest()172 virtual ~DecoderTest() {} 173 174 const CodecFactory *codec_; 175 vpx_codec_dec_cfg_t cfg_; 176 vpx_codec_flags_t flags_; 177 }; 178 179 } // namespace libvpx_test 180 181 #endif // TEST_DECODE_TEST_DRIVER_H_ 182