vp9_encoder_parms_get_to_decoder.cc 6.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
/*
 *  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;
68
  vpx_color_space_t cs;
69 70 71 72
  // TODO(JBB): quantizers / bitrate
};

const EncodeParameters kVP9EncodeParameterSet[] = {
73 74 75 76
    {0, 0, 0, 1, 0, VPX_CS_BT_601},
    {0, 0, 0, 0, 0, VPX_CS_BT_709},
    {0, 0, 1, 0, 0, VPX_CS_BT_2020},
    {0, 2, 0, 0, 1, VPX_CS_UNKNOWN},
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    // 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<EncodeParameters, \
                                                 EncodePerfTestVideo> {
 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) {
113
      encoder->Control(VP9E_SET_COLOR_SPACE, encode_parms.cs);
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
      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);
    }
152
    EXPECT_EQ(common->color_space, encode_parms.cs);
153 154 155 156 157 158 159 160 161 162 163 164 165
    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;
};

166 167 168
// TODO(hkuang): This test conflicts with frame parallel decode. So disable it
// for now until fix.
TEST_P(Vp9EncoderParmsGetToDecoder, DISABLED_BitstreamParms) {
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
  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