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 PeekStream(const uint8_t *cxdata, size_t size, 53 vpx_codec_stream_info_t *stream_info); 54 55 vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); 56 57 vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size, 58 void *user_priv); 59 60 DxDataIterator GetDxData() { 61 return DxDataIterator(&decoder_); 62 } 63 64 void set_deadline(unsigned long deadline) { 65 deadline_ = deadline; 66 } 67 68 void Control(int ctrl_id, int 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 void Control(int ctrl_id, const void *arg) { 75 InitOnce(); 76 const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 77 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 78 } 79 80 const char* DecodeError() { 81 const char *detail = vpx_codec_error_detail(&decoder_); 82 return detail ? detail : vpx_codec_error(&decoder_); 83 } 84 85 // Passes the external frame buffer information to libvpx. 86 vpx_codec_err_t SetFrameBufferFunctions( 87 vpx_get_frame_buffer_cb_fn_t cb_get, 88 vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { 89 InitOnce(); 90 return vpx_codec_set_frame_buffer_functions( 91 &decoder_, cb_get, cb_release, user_priv); 92 } 93 94 const char* GetDecoderName() const { 95 return vpx_codec_iface_name(CodecInterface()); 96 } 97 98 bool IsVP8() const; 99 100 protected: 101 virtual vpx_codec_iface_t* CodecInterface() const = 0; 102 103 void InitOnce() { 104 if (!init_done_) { 105 const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, 106 CodecInterface(), 107 &cfg_, 0); 108 ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 109 init_done_ = true; 110 } 111 } 112 113 vpx_codec_ctx_t decoder_; 114 vpx_codec_dec_cfg_t cfg_; 115 unsigned int deadline_; 116 bool init_done_; 117}; 118 119// Common test functionality for all Decoder tests. 120class DecoderTest { 121 public: 122 // Main decoding loop 123 virtual void RunLoop(CompressedVideoSource *video); 124 virtual void RunLoop(CompressedVideoSource *video, 125 const vpx_codec_dec_cfg_t &dec_cfg); 126 127 // Hook to be called before decompressing every frame. 128 virtual void PreDecodeFrameHook(const CompressedVideoSource& /*video*/, 129 Decoder* /*decoder*/) {} 130 131 // Hook to be called to handle decode result. Return true to continue. 132 virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec, 133 const CompressedVideoSource& /*video*/, 134 Decoder *decoder) { 135 EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); 136 return VPX_CODEC_OK == res_dec; 137 } 138 139 // Hook to be called on every decompressed frame. 140 virtual void DecompressedFrameHook(const vpx_image_t& /*img*/, 141 const unsigned int /*frame_number*/) {} 142 143 // Hook to be called on peek result 144 virtual void HandlePeekResult(Decoder* const decoder, 145 CompressedVideoSource *video, 146 const vpx_codec_err_t res_peek); 147 148 protected: 149 explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {} 150 151 virtual ~DecoderTest() {} 152 153 const CodecFactory *codec_; 154}; 155 156} // namespace libvpx_test 157 158#endif // TEST_DECODE_TEST_DRIVER_H_ 159