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 18namespace libvpx_test { 19 20class CodecFactory; 21class CompressedVideoSource; 22 23// Provides an object to handle decoding output 24class 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. 41class 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, size_t 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 // Passes the external frame buffer information to libvpx. 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 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. 108class DecoderTest { 109 public: 110 // Main decoding loop 111 virtual void RunLoop(CompressedVideoSource *video); 112 113 // Hook to be called before decompressing every frame. 114 virtual void PreDecodeFrameHook(const CompressedVideoSource& video, 115 Decoder *decoder) {} 116 117 // Hook to be called on every decompressed frame. 118 virtual void DecompressedFrameHook(const vpx_image_t& img, 119 const unsigned int frame_number) {} 120 121 protected: 122 explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {} 123 124 virtual ~DecoderTest() {} 125 126 const CodecFactory *codec_; 127}; 128 129} // namespace libvpx_test 130 131#endif // TEST_DECODE_TEST_DRIVER_H_ 132