From a0d9a9dd5179d0c6816c871f073b18a8aff67b1a Mon Sep 17 00:00:00 2001 From: Jim Bankoski Date: Thu, 11 Dec 2014 17:34:32 -0800 Subject: [PATCH] Adds a test to make sure encoder parms get to decoder. This is meant as a framework for testing that encode parms make it through to the decoder. Change-Id: Idb86ee3668b45b4e73c23c6e4daef94b0650b786 --- test/decode_test_driver.h | 4 + test/test-data.mk | 1 + test/test.mk | 6 + test/vp9_encoder_parms_get_to_decoder.cc | 189 +++++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 test/vp9_encoder_parms_get_to_decoder.cc diff --git a/test/decode_test_driver.h b/test/decode_test_driver.h index a757b5974..76cd12e02 100644 --- a/test/decode_test_driver.h +++ b/test/decode_test_driver.h @@ -97,6 +97,10 @@ class Decoder { bool IsVP8() const; + vpx_codec_ctx_t * GetDecoder() { + return &decoder_; + } + protected: virtual vpx_codec_iface_t* CodecInterface() const = 0; diff --git a/test/test-data.mk b/test/test-data.mk index 0a40eb530..157d1bc34 100644 --- a/test/test-data.mk +++ b/test/test-data.mk @@ -17,6 +17,7 @@ LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_422.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_444.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv +LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m diff --git a/test/test.mk b/test/test.mk index 7d2f740d7..4b12a7693 100644 --- a/test/test.mk +++ b/test/test.mk @@ -124,6 +124,12 @@ LIBVPX_TEST_SRCS-yes += superframe_test.cc LIBVPX_TEST_SRCS-yes += tile_independence_test.cc LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc +# TODO(jbb): Remove this when the TODO(minghai): in vpx_encoder.h gets resolved. +# This test fails because of a mismatch in the size of the vpx_codec_alg_priv +# between encoder and decoder when this is enabled. +ifneq ($(CONFIG_SPATIAL_SVC),yes) +LIBVPX_TEST_SRCS-yes += vp9_encoder_parms_get_to_decoder.cc +endif endif LIBVPX_TEST_SRCS-$(CONFIG_VP9) += convolve_test.cc diff --git a/test/vp9_encoder_parms_get_to_decoder.cc b/test/vp9_encoder_parms_get_to_decoder.cc new file mode 100644 index 000000000..6c354fd38 --- /dev/null +++ b/test/vp9_encoder_parms_get_to_decoder.cc @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "test/codec_factory.h" +#include "test/encode_test_driver.h" +#include "test/y4m_video_source.h" +#include "test/yuv_video_source.h" +#include "test/util.h" +#include "third_party/googletest/src/include/gtest/gtest.h" +#include "vp9/decoder/vp9_decoder.h" + +typedef vpx_codec_stream_info_t vp9_stream_info_t; +struct vpx_codec_alg_priv { + vpx_codec_priv_t base; + vpx_codec_dec_cfg_t cfg; + vp9_stream_info_t si; + struct VP9Decoder *pbi; + int postproc_cfg_set; + vp8_postproc_cfg_t postproc_cfg; + vpx_decrypt_cb decrypt_cb; + void *decrypt_state; + vpx_image_t img; + int img_avail; + int flushed; + int invert_tile_order; + int frame_parallel_decode; + + // External frame buffer info to save for VP9 common. + void *ext_priv; // Private data associated with the external frame buffers. + vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; + vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; +}; + +static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) { + return (vpx_codec_alg_priv_t *)ctx->priv; +} + +namespace { + +const unsigned int kFramerate = 50; +const int kCpuUsed = 2; + +struct EncodePerfTestVideo { + const char *name; + uint32_t width; + uint32_t height; + uint32_t bitrate; + int frames; +}; + +const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = { + {"niklas_1280_720_30.yuv", 1280, 720, 600, 10}, +}; + +struct EncodeParameters { + int32_t tile_rows; + int32_t tile_cols; + int32_t lossless; + int32_t error_resilient; + int32_t frame_parallel; + // TODO(JBB): quantizers / bitrate +}; + +const EncodeParameters kVP9EncodeParameterSet[] = { + {0, 0, 0, 1, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0}, + {0, 2, 0, 0, 1}, + // TODO(JBB): Test profiles (requires more work). +}; + +int is_extension_y4m(const char *filename) { + const char *dot = strrchr(filename, '.'); + if (!dot || dot == filename) + return 0; + else + return !strcmp(dot, ".y4m"); +} + +class Vp9EncoderParmsGetToDecoder + : public ::libvpx_test::EncoderTest, + public ::libvpx_test::CodecTestWith2Params { + protected: + Vp9EncoderParmsGetToDecoder() + : EncoderTest(GET_PARAM(0)), + encode_parms(GET_PARAM(1)) { + } + + virtual ~Vp9EncoderParmsGetToDecoder() {} + + virtual void SetUp() { + InitializeConfig(); + SetMode(::libvpx_test::kTwoPassGood); + cfg_.g_lag_in_frames = 25; + cfg_.g_error_resilient = encode_parms.error_resilient; + dec_cfg_.threads = 4; + test_video_ = GET_PARAM(2); + cfg_.rc_target_bitrate = test_video_.bitrate; + } + + virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, + ::libvpx_test::Encoder *encoder) { + if (video->frame() == 1) { + encoder->Control(VP9E_SET_LOSSLESS, encode_parms.lossless); + encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, + encode_parms.frame_parallel); + encoder->Control(VP9E_SET_TILE_ROWS, encode_parms.tile_rows); + encoder->Control(VP9E_SET_TILE_COLUMNS, encode_parms.tile_cols); + encoder->Control(VP8E_SET_CPUUSED, kCpuUsed); + encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); + encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); + encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); + encoder->Control(VP8E_SET_ARNR_TYPE, 3); + } + } + + virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec, + const libvpx_test::VideoSource& video, + libvpx_test::Decoder *decoder) { + vpx_codec_ctx_t* vp9_decoder = decoder->GetDecoder(); + vpx_codec_alg_priv_t* priv = + (vpx_codec_alg_priv_t*) get_alg_priv(vp9_decoder); + + VP9Decoder* pbi = priv->pbi; + VP9_COMMON* common = &pbi->common; + + if (encode_parms.lossless) { + EXPECT_EQ(common->base_qindex, 0); + EXPECT_EQ(common->y_dc_delta_q, 0); + EXPECT_EQ(common->uv_dc_delta_q, 0); + EXPECT_EQ(common->uv_ac_delta_q, 0); + EXPECT_EQ(common->tx_mode, ONLY_4X4); + } + EXPECT_EQ(common->error_resilient_mode, encode_parms.error_resilient); + if (encode_parms.error_resilient) { + EXPECT_EQ(common->frame_parallel_decoding_mode, 1); + EXPECT_EQ(common->use_prev_frame_mvs, 0); + } else { + EXPECT_EQ(common->frame_parallel_decoding_mode, + encode_parms.frame_parallel); + } + + EXPECT_EQ(common->log2_tile_cols, encode_parms.tile_cols); + EXPECT_EQ(common->log2_tile_rows, encode_parms.tile_rows); + + EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); + return VPX_CODEC_OK == res_dec; + } + + EncodePerfTestVideo test_video_; + + private: + EncodeParameters encode_parms; +}; + +TEST_P(Vp9EncoderParmsGetToDecoder, BitstreamParms) { + init_flags_ = VPX_CODEC_USE_PSNR; + + libvpx_test::VideoSource *video; + if (is_extension_y4m(test_video_.name)) { + video = new libvpx_test::Y4mVideoSource(test_video_.name, + 0, test_video_.frames); + } else { + video = new libvpx_test::YUVVideoSource(test_video_.name, + VPX_IMG_FMT_I420, + test_video_.width, + test_video_.height, + kFramerate, 1, 0, + test_video_.frames); + } + + ASSERT_NO_FATAL_FAILURE(RunLoop(video)); + delete(video); +} + +VP9_INSTANTIATE_TEST_CASE( + Vp9EncoderParmsGetToDecoder, + ::testing::ValuesIn(kVP9EncodeParameterSet), + ::testing::ValuesIn(kVP9EncodePerfTestVectors)); + +} // namespace -- 2.40.0