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), deadline_(deadline), init_done_(false) { 45 memset(&decoder_, 0, sizeof(decoder_)); 46 } 47 ~Decoder()48 virtual ~Decoder() { 49 vpx_codec_destroy(&decoder_); 50 } 51 52 vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); 53 GetDxData()54 DxDataIterator GetDxData() { 55 return DxDataIterator(&decoder_); 56 } 57 set_deadline(unsigned long deadline)58 void set_deadline(unsigned long deadline) { 59 deadline_ = deadline; 60 } 61 Control(int ctrl_id,int arg)62 void Control(int ctrl_id, int arg) { 63 InitOnce(); 64 const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 65 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 66 } 67 Control(int ctrl_id,const void * arg)68 void Control(int ctrl_id, const void *arg) { 69 InitOnce(); 70 const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 71 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 72 } 73 DecodeError()74 const char* DecodeError() { 75 const char *detail = vpx_codec_error_detail(&decoder_); 76 return detail ? detail : vpx_codec_error(&decoder_); 77 } 78 79 // 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)80 vpx_codec_err_t SetFrameBufferFunctions( 81 vpx_get_frame_buffer_cb_fn_t cb_get, 82 vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { 83 InitOnce(); 84 return vpx_codec_set_frame_buffer_functions( 85 &decoder_, cb_get, cb_release, user_priv); 86 } 87 88 protected: 89 virtual vpx_codec_iface_t* CodecInterface() const = 0; 90 InitOnce()91 void InitOnce() { 92 if (!init_done_) { 93 const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, 94 CodecInterface(), 95 &cfg_, 0); 96 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 97 init_done_ = true; 98 } 99 } 100 101 vpx_codec_ctx_t decoder_; 102 vpx_codec_dec_cfg_t cfg_; 103 unsigned int deadline_; 104 bool init_done_; 105 }; 106 107 // Common test functionality for all Decoder tests. 108 class DecoderTest { 109 public: 110 // Main decoding loop 111 virtual void RunLoop(CompressedVideoSource *video); 112 113 // Hook to be called before decompressing every frame. PreDecodeFrameHook(const CompressedVideoSource & video,Decoder * decoder)114 virtual void PreDecodeFrameHook(const CompressedVideoSource& video, 115 Decoder *decoder) {} 116 117 // Hook to be called on every decompressed frame. DecompressedFrameHook(const vpx_image_t & img,const unsigned int frame_number)118 virtual void DecompressedFrameHook(const vpx_image_t& img, 119 const unsigned int frame_number) {} 120 121 protected: DecoderTest(const CodecFactory * codec)122 explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {} 123 ~DecoderTest()124 virtual ~DecoderTest() {} 125 126 const CodecFactory *codec_; 127 }; 128 129 } // namespace libvpx_test 130 131 #endif // TEST_DECODE_TEST_DRIVER_H_ 132