encode_api_test.cc 5.58 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
/*
 *  Copyright (c) 2016 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 "third_party/googletest/src/include/gtest/gtest.h"

#include "./vpx_config.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"

namespace {

#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))

TEST(EncodeAPI, InvalidParams) {
  static const vpx_codec_iface_t *kCodecs[] = {
#if CONFIG_VP8_ENCODER
    &vpx_codec_vp8_cx_algo,
#endif
#if CONFIG_VP9_ENCODER
    &vpx_codec_vp9_cx_algo,
#endif
  };
clang-format's avatar
clang-format committed
30
  uint8_t buf[1] = { 0 };
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
  vpx_image_t img;
  vpx_codec_ctx_t enc;
  vpx_codec_enc_cfg_t cfg;

  EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));

  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_config_default(NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_config_default(NULL, &cfg, 0));
  EXPECT_TRUE(vpx_codec_error(NULL) != NULL);

  for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
    SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i]));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_config_default(kCodecs[i], &cfg, 1));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0));
    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0));
    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
  }
}

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
TEST(EncodeAPI, HighBitDepthCapability) {
// VP8 should not claim VP9 HBD as a capability.
#if CONFIG_VP8_ENCODER
  const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
  EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
#endif

#if CONFIG_VP9_ENCODER
  const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
#if CONFIG_VP9_HIGHBITDEPTH
  EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
#else
  EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
#endif
#endif
}

82
#if CONFIG_VP8_ENCODER
83
TEST(EncodeAPI, ImageSizeSetting) {
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
  const int width = 711;
  const int height = 360;
  const int bps = 12;
  vpx_image_t img;
  vpx_codec_ctx_t enc;
  vpx_codec_enc_cfg_t cfg;
  uint8_t *img_buf = reinterpret_cast<uint8_t *>(
      calloc(width * height * bps / 8, sizeof(*img_buf)));
  vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);

  cfg.g_w = width;
  cfg.g_h = height;

  vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);

  vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);

  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));

  free(img_buf);

  vpx_codec_destroy(&enc);
}
#endif

109 110 111 112 113 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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
#if CONFIG_MULTI_RES_ENCODING
// Set up 2 spatial streams with 2 temporal layers per stream, and generate
// invalid configuration by setting the temporal layer rate allocation
// (ts_target_bitrate[]) to 0 for both layers.
TEST(EncodeAPI, VP8MultiResEncode) {
  const int width = 1280;
  const int height = 720;
  const int width_down = width / 2;
  const int height_down = height / 2;
  const int target_bitrate = 1000;
  const int framerate = 30;
  vpx_codec_ctx_t enc[2];
  vpx_codec_enc_cfg_t cfg[2];
  vpx_rational_t dsf[2] = { { 2, 1 }, { 2, 1 } };

  memset(enc, 0, sizeof(enc));

  for (int i = 0; i < 2; i++) {
    vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg[i], 0);
  }

  /* Highest-resolution encoder settings */
  cfg[0].g_w = width;
  cfg[0].g_h = height;
  cfg[0].rc_dropframe_thresh = 0;
  cfg[0].rc_end_usage = VPX_CBR;
  cfg[0].rc_resize_allowed = 0;
  cfg[0].rc_min_quantizer = 2;
  cfg[0].rc_max_quantizer = 56;
  cfg[0].rc_undershoot_pct = 100;
  cfg[0].rc_overshoot_pct = 15;
  cfg[0].rc_buf_initial_sz = 500;
  cfg[0].rc_buf_optimal_sz = 600;
  cfg[0].rc_buf_sz = 1000;
  cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
  cfg[0].g_lag_in_frames = 0;

  cfg[0].kf_mode = VPX_KF_AUTO;
  cfg[0].kf_min_dist = 3000;
  cfg[0].kf_max_dist = 3000;

  cfg[0].rc_target_bitrate = target_bitrate; /* Set target bitrate */
  cfg[0].g_timebase.num = 1;                 /* Set fps */
  cfg[0].g_timebase.den = framerate;

  memcpy(&cfg[1], &cfg[0], sizeof(cfg[0]));
  cfg[1].rc_target_bitrate = 500;
  cfg[1].g_w = width_down;
  cfg[1].g_h = height_down;

  for (int i = 0; i < 2; i++) {
    cfg[i].ts_number_layers = 2;
    cfg[i].ts_periodicity = 2;
    cfg[i].ts_rate_decimator[0] = 2;
    cfg[i].ts_rate_decimator[1] = 1;
    cfg[i].ts_layer_id[0] = 0;
    cfg[i].ts_layer_id[1] = 1;
    // Invalid parameters.
    cfg[i].ts_target_bitrate[0] = 0;
    cfg[i].ts_target_bitrate[1] = 0;
  }

  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_init_multi(&enc[0], vpx_codec_vp8_cx(), &cfg[0], 2, 0,
                                     &dsf[0]));

  for (int i = 0; i < 2; i++) {
    vpx_codec_destroy(&enc[i]);
  }
}
#endif

181
}  // namespace