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: 26 explicit DxDataIterator(vpx_codec_ctx_t *decoder) 27 : decoder_(decoder), iter_(NULL) {} 28 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: 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 48 virtual ~Decoder() { 49 vpx_codec_destroy(&decoder_); 50 } 51 52 vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, int size); 53 54 DxDataIterator GetDxData() { 55 return DxDataIterator(&decoder_); 56 } 57 58 void set_deadline(unsigned long deadline) { 59 deadline_ = deadline; 60 } 61 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 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 74 const char* DecodeError() { 75 const char *detail = vpx_codec_error_detail(&decoder_); 76 return detail ? detail : vpx_codec_error(&decoder_); 77 } 78 79 protected: 80 virtual const vpx_codec_iface_t* CodecInterface() const = 0; 81 82 void InitOnce() { 83 if (!init_done_) { 84 const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, 85 CodecInterface(), 86 &cfg_, 0); 87 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 88 init_done_ = true; 89 } 90 } 91 92 vpx_codec_ctx_t decoder_; 93 vpx_codec_dec_cfg_t cfg_; 94 unsigned int deadline_; 95 bool init_done_; 96 }; 97 98 // Common test functionality for all Decoder tests. 99 class DecoderTest { 100 public: 101 // Main decoding loop 102 virtual void RunLoop(CompressedVideoSource *video); 103 104 // Hook to be called on every decompressed frame. 105 virtual void DecompressedFrameHook(const vpx_image_t& img, 106 const unsigned int frame_number) {} 107 108 protected: 109 explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {} 110 111 virtual ~DecoderTest() {} 112 113 const CodecFactory *codec_; 114 }; 115 116 } // namespace libvpx_test 117 118 #endif // TEST_DECODE_TEST_DRIVER_H_ 119