1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef TEST_DECODE_TEST_DRIVER_H_ 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TEST_DECODE_TEST_DRIVER_H_ 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <cstring> 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "third_party/googletest/src/include/gtest/gtest.h" 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_config.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_decoder.h" 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan 18233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace libvpx_test { 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan 20233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass CodecFactory; 21233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass CompressedVideoSource; 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Provides an object to handle decoding output 24233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass DxDataIterator { 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan public: 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan explicit DxDataIterator(vpx_codec_ctx_t *decoder) 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan : decoder_(decoder), iter_(NULL) {} 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_image_t *Next() { 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vpx_codec_get_frame(decoder_, &iter_); 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan private: 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_ctx_t *decoder_; 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iter_t iter_; 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Provides a simplified interface to manage one video decoding. 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Similar to Encoder class, the exact services should be added 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan// as more tests are added. 41233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Decoder { 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan public: 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline) 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan : cfg_(cfg), deadline_(deadline), init_done_(false) { 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan memset(&decoder_, 0, sizeof(decoder_)); 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual ~Decoder() { 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_destroy(&decoder_); 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan DxDataIterator GetDxData() { 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan return DxDataIterator(&decoder_); 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan void set_deadline(unsigned long deadline) { 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan deadline_ = deadline; 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan void Control(int ctrl_id, int arg) { 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan InitOnce(); 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan void Control(int ctrl_id, const void *arg) { 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan InitOnce(); 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan const char* DecodeError() { 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan const char *detail = vpx_codec_error_detail(&decoder_); 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan return detail ? detail : vpx_codec_error(&decoder_); 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Passes the external frame buffer information to libvpx. 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t SetFrameBufferFunctions( 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_get_frame_buffer_cb_fn_t cb_get, 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan InitOnce(); 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vpx_codec_set_frame_buffer_functions( 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan &decoder_, cb_get, cb_release, user_priv); 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected: 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual vpx_codec_iface_t* CodecInterface() const = 0; 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan void InitOnce() { 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!init_done_) { 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan CodecInterface(), 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cfg_, 0); 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan init_done_ = true; 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_ctx_t decoder_; 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_dec_cfg_t cfg_; 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int deadline_; 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan bool init_done_; 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Common test functionality for all Decoder tests. 108233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass DecoderTest { 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan public: 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Main decoding loop 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void RunLoop(CompressedVideoSource *video); 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Hook to be called before decompressing every frame. 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void PreDecodeFrameHook(const CompressedVideoSource& video, 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan Decoder *decoder) {} 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Hook to be called on every decompressed frame. 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual void DecompressedFrameHook(const vpx_image_t& img, 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int frame_number) {} 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan protected: 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {} 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan virtual ~DecoderTest() {} 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan const CodecFactory *codec_; 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // namespace libvpx_test 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif // TEST_DECODE_TEST_DRIVER_H_ 132