1ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* 2ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * 4ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * Use of this source code is governed by a BSD-style license 5ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * that can be found in the LICENSE file in the root of the source 6ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * tree. An additional intellectual property rights grant can be found 7ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * in the file PATENTS. All contributing project authors may 8ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * be found in the AUTHORS file in the root of the source tree. 9ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */ 10ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 11ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#ifndef TEST_DECODE_TEST_DRIVER_H_ 12ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#define TEST_DECODE_TEST_DRIVER_H_ 13ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#include <cstring> 14ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#include "third_party/googletest/src/include/gtest/gtest.h" 15f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "./vpx_config.h" 16ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#include "vpx/vpx_decoder.h" 17ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 18ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgnamespace libvpx_test { 19ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 20923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.orgclass CodecFactory; 21ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgclass CompressedVideoSource; 22ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 23ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org// Provides an object to handle decoding output 24ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgclass DxDataIterator { 25ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org public: 26ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org explicit DxDataIterator(vpx_codec_ctx_t *decoder) 27ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org : decoder_(decoder), iter_(NULL) {} 28ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 29ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org const vpx_image_t *Next() { 30ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org return vpx_codec_get_frame(decoder_, &iter_); 31ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 32ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 33ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org private: 34ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org vpx_codec_ctx_t *decoder_; 35ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org vpx_codec_iter_t iter_; 36ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org}; 37ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 38ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org// Provides a simplified interface to manage one video decoding. 39f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org// Similar to Encoder class, the exact services should be added 40f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org// as more tests are added. 41ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgclass Decoder { 42ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org public: 43ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline) 44923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org : cfg_(cfg), deadline_(deadline), init_done_(false) { 45ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org memset(&decoder_, 0, sizeof(decoder_)); 46ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 47ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 48923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org virtual ~Decoder() { 49ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org vpx_codec_destroy(&decoder_); 50ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 51ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 52e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size, 53e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vpx_codec_stream_info_t *stream_info); 54e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 5576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); 56ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 57e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size, 58e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org void *user_priv); 59e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 60ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org DxDataIterator GetDxData() { 61ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org return DxDataIterator(&decoder_); 62ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 63ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 64ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org void set_deadline(unsigned long deadline) { 65ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org deadline_ = deadline; 66ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 67ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 68ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org void Control(int ctrl_id, int arg) { 69923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org InitOnce(); 70ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 71ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 72ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 73ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 74ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org void Control(int ctrl_id, const void *arg) { 75923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org InitOnce(); 76ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); 77ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 78ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org } 79ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org 80923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org const char* DecodeError() { 81ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org const char *detail = vpx_codec_error_detail(&decoder_); 82ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org return detail ? detail : vpx_codec_error(&decoder_); 83ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org } 84ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 8576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org // Passes the external frame buffer information to libvpx. 8676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_codec_err_t SetFrameBufferFunctions( 8776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_get_frame_buffer_cb_fn_t cb_get, 8876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { 8976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org InitOnce(); 9076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org return vpx_codec_set_frame_buffer_functions( 9176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org &decoder_, cb_get, cb_release, user_priv); 9276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org } 9376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org 94ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org const char* GetDecoderName() const { 95e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org return vpx_codec_iface_name(CodecInterface()); 96e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org } 97e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 98ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org bool IsVP8() const; 99ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 100ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org protected: 10176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org virtual vpx_codec_iface_t* CodecInterface() const = 0; 102923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org 103923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org void InitOnce() { 104923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org if (!init_done_) { 105923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, 106923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org CodecInterface(), 107923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org &cfg_, 0); 108923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); 109923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org init_done_ = true; 110923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org } 111ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org } 112ab3cb4e3f1f39482ee3bd15c6918af868144d6dejohannkoenig@chromium.org 113ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org vpx_codec_ctx_t decoder_; 114ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org vpx_codec_dec_cfg_t cfg_; 115ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org unsigned int deadline_; 116923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org bool init_done_; 117ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org}; 118ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 119ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org// Common test functionality for all Decoder tests. 120ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.orgclass DecoderTest { 121ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org public: 122923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org // Main decoding loop 123ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org virtual void RunLoop(CompressedVideoSource *video); 12495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com virtual void RunLoop(CompressedVideoSource *video, 12595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com const vpx_codec_dec_cfg_t &dec_cfg); 126ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 127d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org // Hook to be called before decompressing every frame. 128d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org virtual void PreDecodeFrameHook(const CompressedVideoSource& /*video*/, 129d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org Decoder* /*decoder*/) {} 130d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 131f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org // Hook to be called to handle decode result. Return true to continue. 132f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec, 133d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org const CompressedVideoSource& /*video*/, 134f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org Decoder *decoder) { 135f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); 136f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org return VPX_CODEC_OK == res_dec; 137f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org } 138f6ac5240e9583122bd001dbee63a53b28e6f5beafgalligan@chromium.org 139ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org // Hook to be called on every decompressed frame. 140d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org virtual void DecompressedFrameHook(const vpx_image_t& /*img*/, 141d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org const unsigned int /*frame_number*/) {} 142ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 143ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org // Hook to be called on peek result 144ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org virtual void HandlePeekResult(Decoder* const decoder, 145ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org CompressedVideoSource *video, 146ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org const vpx_codec_err_t res_peek); 147ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 148ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org protected: 149923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {} 150ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 151ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org virtual ~DecoderTest() {} 152923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org 153923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org const CodecFactory *codec_; 154ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org}; 155ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 156ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org} // namespace libvpx_test 157ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org 158ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org#endif // TEST_DECODE_TEST_DRIVER_H_ 159