Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: source/libvpx/vpxenc.c

Issue 554673004: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vpxdec.c ('k') | source/libvpx/y4minput.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vpxenc.c
===================================================================
--- source/libvpx/vpxenc.c (revision 291857)
+++ source/libvpx/vpxenc.c (working copy)
@@ -200,6 +200,10 @@
ARG_DEF(NULL, "experimental-bitstream", 0,
"Allow experimental bitstream features.");
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+static const arg_def_t test16bitinternalarg = ARG_DEF(
+ NULL, "test-16bit-internal", 0, "Force use of 16 bit internal buffer");
+#endif
static const arg_def_t *main_args[] = {
&debugmode,
@@ -248,6 +252,9 @@
#endif
&timebase, &framerate,
&error_resilient,
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ &test16bitinternalarg,
+#endif
&lag_in_frames, NULL
};
@@ -321,7 +328,7 @@
static const arg_def_t noise_sens = ARG_DEF(NULL, "noise-sensitivity", 1,
"Noise sensitivity (frames to blur)");
static const arg_def_t sharpness = ARG_DEF(NULL, "sharpness", 1,
- "Filter sharpness (0-7)");
+ "Loop filter sharpness (0..7)");
static const arg_def_t static_thresh = ARG_DEF(NULL, "static-thresh", 1,
"Motion detection threshold");
static const arg_def_t cpu_used = ARG_DEF(NULL, "cpu-used", 1,
@@ -329,11 +336,11 @@
static const arg_def_t auto_altref = ARG_DEF(NULL, "auto-alt-ref", 1,
"Enable automatic alt reference frames");
static const arg_def_t arnr_maxframes = ARG_DEF(NULL, "arnr-maxframes", 1,
- "AltRef Max Frames");
+ "AltRef max frames (0..15)");
static const arg_def_t arnr_strength = ARG_DEF(NULL, "arnr-strength", 1,
- "AltRef Strength");
+ "AltRef filter strength (0..6)");
static const arg_def_t arnr_type = ARG_DEF(NULL, "arnr-type", 1,
- "AltRef Type");
+ "AltRef type");
static const struct arg_enum_list tuning_enum[] = {
{"psnr", VP8_TUNE_PSNR},
{"ssim", VP8_TUNE_SSIM},
@@ -378,9 +385,26 @@
"Adaptive quantization mode (0: off (default), 1: variance 2: complexity, "
"3: cyclic refresh)");
static const arg_def_t frame_periodic_boost = ARG_DEF(
- NULL, "frame_boost", 1,
+ NULL, "frame-boost", 1,
"Enable frame periodic boost (0: off (default), 1: on)");
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+static const struct arg_enum_list bitdepth_enum[] = {
+ {"8", VPX_BITS_8},
+ {"10", VPX_BITS_10},
+ {"12", VPX_BITS_12},
+ {NULL, 0}
+};
+
+static const arg_def_t bitdeptharg = ARG_DEF_ENUM("b", "bit-depth", 1,
+ "Bit depth for codec "
+ "(8 for version <=1, "
+ "10 or 12 for version 2)",
+ bitdepth_enum);
+static const arg_def_t inbitdeptharg = ARG_DEF(NULL, "input-bit-depth", 1,
+ "Bit depth of input");
+#endif
+
static const struct arg_enum_list tune_content_enum[] = {
{"default", VP9E_CONTENT_DEFAULT},
{"screen", VP9E_CONTENT_SCREEN},
@@ -395,6 +419,9 @@
&tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type,
&tune_ssim, &cq_level, &max_intra_rate_pct, &lossless,
&frame_parallel_decoding, &aq_mode, &frame_periodic_boost, &tune_content,
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ &bitdeptharg, &inbitdeptharg,
+#endif
NULL
};
static const int vp9_arg_ctrl_map[] = {
@@ -450,6 +477,102 @@
}
#define mmin(a, b) ((a) < (b) ? (a) : (b))
+
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+static void find_mismatch_high(const vpx_image_t *const img1,
+ const vpx_image_t *const img2,
+ int yloc[4], int uloc[4], int vloc[4]) {
+ uint16_t *plane1, *plane2;
+ uint32_t stride1, stride2;
+ const uint32_t bsize = 64;
+ const uint32_t bsizey = bsize >> img1->y_chroma_shift;
+ const uint32_t bsizex = bsize >> img1->x_chroma_shift;
+ const uint32_t c_w =
+ (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
+ const uint32_t c_h =
+ (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
+ int match = 1;
+ uint32_t i, j;
+ yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
+ plane1 = (uint16_t*)img1->planes[VPX_PLANE_Y];
+ plane2 = (uint16_t*)img2->planes[VPX_PLANE_Y];
+ stride1 = img1->stride[VPX_PLANE_Y]/2;
+ stride2 = img2->stride[VPX_PLANE_Y]/2;
+ for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
+ for (j = 0; match && j < img1->d_w; j += bsize) {
+ int k, l;
+ const int si = mmin(i + bsize, img1->d_h) - i;
+ const int sj = mmin(j + bsize, img1->d_w) - j;
+ for (k = 0; match && k < si; ++k) {
+ for (l = 0; match && l < sj; ++l) {
+ if (*(plane1 + (i + k) * stride1 + j + l) !=
+ *(plane2 + (i + k) * stride2 + j + l)) {
+ yloc[0] = i + k;
+ yloc[1] = j + l;
+ yloc[2] = *(plane1 + (i + k) * stride1 + j + l);
+ yloc[3] = *(plane2 + (i + k) * stride2 + j + l);
+ match = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
+ plane1 = (uint16_t*)img1->planes[VPX_PLANE_U];
+ plane2 = (uint16_t*)img2->planes[VPX_PLANE_U];
+ stride1 = img1->stride[VPX_PLANE_U]/2;
+ stride2 = img2->stride[VPX_PLANE_U]/2;
+ for (i = 0, match = 1; match && i < c_h; i += bsizey) {
+ for (j = 0; match && j < c_w; j += bsizex) {
+ int k, l;
+ const int si = mmin(i + bsizey, c_h - i);
+ const int sj = mmin(j + bsizex, c_w - j);
+ for (k = 0; match && k < si; ++k) {
+ for (l = 0; match && l < sj; ++l) {
+ if (*(plane1 + (i + k) * stride1 + j + l) !=
+ *(plane2 + (i + k) * stride2 + j + l)) {
+ uloc[0] = i + k;
+ uloc[1] = j + l;
+ uloc[2] = *(plane1 + (i + k) * stride1 + j + l);
+ uloc[3] = *(plane2 + (i + k) * stride2 + j + l);
+ match = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
+ plane1 = (uint16_t*)img1->planes[VPX_PLANE_V];
+ plane2 = (uint16_t*)img2->planes[VPX_PLANE_V];
+ stride1 = img1->stride[VPX_PLANE_V]/2;
+ stride2 = img2->stride[VPX_PLANE_V]/2;
+ for (i = 0, match = 1; match && i < c_h; i += bsizey) {
+ for (j = 0; match && j < c_w; j += bsizex) {
+ int k, l;
+ const int si = mmin(i + bsizey, c_h - i);
+ const int sj = mmin(j + bsizex, c_w - j);
+ for (k = 0; match && k < si; ++k) {
+ for (l = 0; match && l < sj; ++l) {
+ if (*(plane1 + (i + k) * stride1 + j + l) !=
+ *(plane2 + (i + k) * stride2 + j + l)) {
+ vloc[0] = i + k;
+ vloc[1] = j + l;
+ vloc[2] = *(plane1 + (i + k) * stride1 + j + l);
+ vloc[3] = *(plane2 + (i + k) * stride2 + j + l);
+ match = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
static void find_mismatch(const vpx_image_t *const img1,
const vpx_image_t *const img2,
int yloc[4], int uloc[4], int vloc[4]) {
@@ -542,7 +665,8 @@
static int compare_img(const vpx_image_t *const img1,
const vpx_image_t *const img2) {
- const uint32_t c_w =
+ uint32_t l_w = img1->d_w;
+ uint32_t c_w =
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
@@ -552,11 +676,17 @@
match &= (img1->fmt == img2->fmt);
match &= (img1->d_w == img2->d_w);
match &= (img1->d_h == img2->d_h);
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if (img1->fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
+ l_w *= 2;
+ c_w *= 2;
+ }
+#endif
for (i = 0; i < img1->d_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
- img1->d_w) == 0);
+ l_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
@@ -601,6 +731,10 @@
int arg_ctrl_cnt;
int write_webm;
int have_kf_max_dist;
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ // whether to use 16bit internal buffers
+ int use_16bit_internal;
+#endif
};
@@ -740,8 +874,9 @@
#if CONFIG_VP9_ENCODER
// Make default VP9 passes = 2 until there is a better quality 1-pass
// encoder
- global->passes = (strcmp(global->codec->name, "vp9") == 0 &&
- global->deadline != VPX_DL_REALTIME) ? 2 : 1;
+ if (global->codec != NULL && global->codec->name != NULL)
+ global->passes = (strcmp(global->codec->name, "vp9") == 0 &&
+ global->deadline != VPX_DL_REALTIME) ? 2 : 1;
#else
global->passes = 1;
#endif
@@ -809,8 +944,10 @@
struct stream_state *stream;
stream = calloc(1, sizeof(*stream));
- if (!stream)
+ if (stream == NULL) {
fatal("Failed to allocate new stream.");
+ }
+
if (prev) {
memcpy(stream, prev, sizeof(*stream));
stream->index++;
@@ -870,6 +1007,9 @@
static const int *ctrl_args_map = NULL;
struct stream_config *config = &stream->config;
int eos_mark_found = 0;
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ int test_16bit_internal = 0;
+#endif
// Handle codec specific options
if (0) {
@@ -918,6 +1058,12 @@
config->cfg.g_w = arg_parse_uint(&arg);
} else if (arg_match(&arg, &height, argi)) {
config->cfg.g_h = arg_parse_uint(&arg);
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ } else if (arg_match(&arg, &bitdeptharg, argi)) {
+ config->cfg.g_bit_depth = arg_parse_enum_or_int(&arg);
+ } else if (arg_match(&arg, &inbitdeptharg, argi)) {
+ config->cfg.g_input_bit_depth = arg_parse_uint(&arg);
+#endif
#if CONFIG_WEBM_IO
} else if (arg_match(&arg, &stereo_mode, argi)) {
config->stereo_fmt = arg_parse_enum_or_int(&arg);
@@ -985,6 +1131,12 @@
config->have_kf_max_dist = 1;
} else if (arg_match(&arg, &kf_disabled, argi)) {
config->cfg.kf_mode = VPX_KF_DISABLED;
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ } else if (arg_match(&arg, &test16bitinternalarg, argi)) {
+ if (strcmp(global->codec->name, "vp9") == 0) {
+ test_16bit_internal = 1;
+ }
+#endif
} else {
int i, match = 0;
for (i = 0; ctrl_args[i]; i++) {
@@ -996,12 +1148,13 @@
* instance of this control.
*/
for (j = 0; j < config->arg_ctrl_cnt; j++)
- if (config->arg_ctrls[j][0] == ctrl_args_map[i])
+ if (ctrl_args_map != NULL &&
+ config->arg_ctrls[j][0] == ctrl_args_map[i])
break;
/* Update/insert */
assert(j < (int)ARG_CTRL_CNT_MAX);
- if (j < (int)ARG_CTRL_CNT_MAX) {
+ if (ctrl_args_map != NULL && j < (int)ARG_CTRL_CNT_MAX) {
config->arg_ctrls[j][0] = ctrl_args_map[i];
config->arg_ctrls[j][1] = arg_parse_enum_or_int(&arg);
if (j == config->arg_ctrl_cnt)
@@ -1014,6 +1167,12 @@
argj++;
}
}
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if (strcmp(global->codec->name, "vp9") == 0) {
+ config->use_16bit_internal = test_16bit_internal |
+ (config->cfg.g_profile > 1);
+ }
+#endif
return eos_mark_found;
}
@@ -1041,6 +1200,14 @@
experimental_bitstream.long_name);
}
+ // Check that the codec bit depth is greater than the input bit depth.
+ if (stream->config.cfg.g_input_bit_depth >
+ (unsigned int)stream->config.cfg.g_bit_depth) {
+ fatal("Stream %d: codec bit depth (%d) less than input bit depth (%d)",
+ stream->index, (int)stream->config.cfg.g_bit_depth,
+ stream->config.cfg.g_input_bit_depth);
+ }
+
for (streami = stream; streami; streami = streami->next) {
/* All streams require output files */
if (!streami->config.out_fn)
@@ -1149,6 +1316,8 @@
SHOW(g_profile);
SHOW(g_w);
SHOW(g_h);
+ SHOW(g_bit_depth);
+ SHOW(g_input_bit_depth);
SHOW(g_timebase.num);
SHOW(g_timebase.den);
SHOW(g_error_resilient);
@@ -1281,6 +1450,9 @@
flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0;
flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0;
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ flags |= stream->config.use_16bit_internal ? VPX_CODEC_USE_HIGHBITDEPTH : 0;
+#endif
/* Construct Encoder Context */
vpx_codec_enc_init(&stream->encoder, global->codec->codec_interface(),
@@ -1326,6 +1498,46 @@
/ cfg->g_timebase.num / global->framerate.num;
/* Scale if necessary */
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if (img) {
+ if ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) &&
+ (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) {
+ if (img->fmt != VPX_IMG_FMT_I42016) {
+ fprintf(stderr, "%s can only scale 4:2:0 inputs\n", exec_name);
+ exit(EXIT_FAILURE);
+ }
+#if CONFIG_LIBYUV
+ if (!stream->img) {
+ stream->img = vpx_img_alloc(NULL, VPX_IMG_FMT_I42016,
+ cfg->g_w, cfg->g_h, 16);
+ }
+ I420Scale_16((uint16*)img->planes[VPX_PLANE_Y],
+ img->stride[VPX_PLANE_Y]/2,
+ (uint16*)img->planes[VPX_PLANE_U],
+ img->stride[VPX_PLANE_U]/2,
+ (uint16*)img->planes[VPX_PLANE_V],
+ img->stride[VPX_PLANE_V]/2,
+ img->d_w, img->d_h,
+ (uint16*)stream->img->planes[VPX_PLANE_Y],
+ stream->img->stride[VPX_PLANE_Y]/2,
+ (uint16*)stream->img->planes[VPX_PLANE_U],
+ stream->img->stride[VPX_PLANE_U]/2,
+ (uint16*)stream->img->planes[VPX_PLANE_V],
+ stream->img->stride[VPX_PLANE_V]/2,
+ stream->img->d_w, stream->img->d_h,
+ kFilterBox);
+ img = stream->img;
+#else
+ stream->encoder.err = 1;
+ ctx_exit_on_error(&stream->encoder,
+ "Stream %d: Failed to encode frame.\n"
+ "Scaling disabled in this configuration. \n"
+ "To enable, configure with --enable-libyuv\n",
+ stream->index);
+#endif
+ }
+ }
+#endif
if (img && (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) {
if (img->fmt != VPX_IMG_FMT_I420 && img->fmt != VPX_IMG_FMT_YV12) {
fprintf(stderr, "%s can only scale 4:2:0 8bpp inputs\n", exec_name);
@@ -1504,7 +1716,132 @@
return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0);
}
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+static void high_img_upshift(vpx_image_t *dst, vpx_image_t *src,
+ int input_shift) {
+ // Note the offset is 1 less than half
+ const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
+ int plane;
+ if (dst->w != src->w || dst->h != src->h ||
+ dst->x_chroma_shift != src->x_chroma_shift ||
+ dst->y_chroma_shift != src->y_chroma_shift ||
+ dst->fmt != src->fmt || input_shift < 0) {
+ fatal("Unsupported image conversion");
+ }
+ switch (src->fmt) {
+ case VPX_IMG_FMT_I42016:
+ case VPX_IMG_FMT_I42216:
+ case VPX_IMG_FMT_I44416:
+ break;
+ default:
+ fatal("Unsupported image conversion");
+ break;
+ }
+ for (plane = 0; plane < 3; plane++) {
+ int w = src->w;
+ int h = src->h;
+ int x, y;
+ if (plane) {
+ w >>= src->x_chroma_shift;
+ h >>= src->y_chroma_shift;
+ }
+ for (y = 0; y < h; y++) {
+ uint16_t *p_src = (uint16_t *)(src->planes[plane] +
+ y * src->stride[plane]);
+ uint16_t *p_dst = (uint16_t *)(dst->planes[plane] +
+ y * dst->stride[plane]);
+ for (x = 0; x < w; x++)
+ *p_dst++ = (*p_src++ << input_shift) + offset;
+ }
+ }
+}
+static void low_img_upshift(vpx_image_t *dst, vpx_image_t *src,
+ int input_shift) {
+ // Note the offset is 1 less than half
+ const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0;
+ int plane;
+ if (dst->w != src->w || dst->h != src->h ||
+ dst->x_chroma_shift != src->x_chroma_shift ||
+ dst->y_chroma_shift != src->y_chroma_shift ||
+ dst->fmt != src->fmt + VPX_IMG_FMT_HIGHBITDEPTH ||
+ input_shift < 0) {
+ fatal("Unsupported image conversion");
+ }
+ switch (src->fmt) {
+ case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_I422:
+ case VPX_IMG_FMT_I444:
+ break;
+ default:
+ fatal("Unsupported image conversion");
+ break;
+ }
+ for (plane = 0; plane < 3; plane++) {
+ int w = src->w;
+ int h = src->h;
+ int x, y;
+ if (plane) {
+ w >>= src->x_chroma_shift;
+ h >>= src->y_chroma_shift;
+ }
+ for (y = 0; y < h; y++) {
+ uint8_t *p_src = src->planes[plane] + y * src->stride[plane];
+ uint16_t *p_dst = (uint16_t *)(dst->planes[plane] +
+ y * dst->stride[plane]);
+ for (x = 0; x < w; x++) {
+ *p_dst++ = (*p_src++ << input_shift) + offset;
+ }
+ }
+ }
+}
+
+static void img_upshift(vpx_image_t *dst, vpx_image_t *src,
+ int input_shift) {
+ if (src->fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
+ high_img_upshift(dst, src, input_shift);
+ } else {
+ low_img_upshift(dst, src, input_shift);
+ }
+}
+
+static void img_cast_16_to_8(vpx_image_t *dst, vpx_image_t *src) {
+ int plane;
+ if (dst->fmt + VPX_IMG_FMT_HIGHBITDEPTH != src->fmt ||
+ dst->d_w != src->d_w || dst->d_h != src->d_h ||
+ dst->x_chroma_shift != src->x_chroma_shift ||
+ dst->y_chroma_shift != src->y_chroma_shift) {
+ fatal("Unsupported image conversion");
+ }
+ switch (dst->fmt) {
+ case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_I422:
+ case VPX_IMG_FMT_I444:
+ break;
+ default:
+ fatal("Unsupported image conversion");
+ break;
+ }
+ for (plane = 0; plane < 3; plane++) {
+ int w = src->d_w;
+ int h = src->d_h;
+ int x, y;
+ if (plane) {
+ w >>= src->x_chroma_shift;
+ h >>= src->y_chroma_shift;
+ }
+ for (y = 0; y < h; y++) {
+ uint16_t *p_src = (uint16_t *)(src->planes[plane] +
+ y * src->stride[plane]);
+ uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane];
+ for (x = 0; x < w; x++) {
+ *p_dst++ = *p_src++;
+ }
+ }
+ }
+}
+#endif
+
static void test_decode(struct stream_state *stream,
enum TestDecodeFatality fatal,
const VpxInterface *codec) {
@@ -1530,20 +1867,44 @@
vpx_codec_control(&stream->encoder, VP8_COPY_REFERENCE, &ref_enc);
vpx_codec_control(&stream->decoder, VP8_COPY_REFERENCE, &ref_dec);
} else {
- struct vp9_ref_frame ref;
+ struct vp9_ref_frame ref_enc, ref_dec;
- ref.idx = 0;
- vpx_codec_control(&stream->encoder, VP9_GET_REFERENCE, &ref);
- enc_img = ref.img;
- vpx_codec_control(&stream->decoder, VP9_GET_REFERENCE, &ref);
- dec_img = ref.img;
+ ref_enc.idx = 0;
+ ref_dec.idx = 0;
+ vpx_codec_control(&stream->encoder, VP9_GET_REFERENCE, &ref_enc);
+ enc_img = ref_enc.img;
+ vpx_codec_control(&stream->decoder, VP9_GET_REFERENCE, &ref_dec);
+ dec_img = ref_dec.img;
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if ((enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) !=
+ (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)) {
+ if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
+ vpx_img_alloc(&enc_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
+ enc_img.d_w, enc_img.d_h, 16);
+ img_cast_16_to_8(&enc_img, &ref_enc.img);
+ }
+ if (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
+ vpx_img_alloc(&dec_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
+ dec_img.d_w, dec_img.d_h, 16);
+ img_cast_16_to_8(&dec_img, &ref_dec.img);
+ }
+ }
+#endif
}
ctx_exit_on_error(&stream->encoder, "Failed to get encoder reference frame");
ctx_exit_on_error(&stream->decoder, "Failed to get decoder reference frame");
if (!compare_img(&enc_img, &dec_img)) {
int y[4], u[4], v[4];
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
+ find_mismatch_high(&enc_img, &dec_img, y, u, v);
+ } else {
+ find_mismatch(&enc_img, &dec_img, y, u, v);
+ }
+#else
find_mismatch(&enc_img, &dec_img, y, u, v);
+#endif
stream->decoder.err = 1;
warn_or_exit_on_error(&stream->decoder, fatal == TEST_DECODE_FATAL,
"Stream %d: Encode/decode mismatch on frame %d at"
@@ -1585,6 +1946,12 @@
int main(int argc, const char **argv_) {
int pass;
vpx_image_t raw;
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ vpx_image_t raw_shift;
+ int allocated_raw_shift = 0;
+ int use_16bit_internal = 0;
+ int input_shift = 0;
+#endif
int frame_avail, got_data;
struct VpxInputContext input;
@@ -1686,6 +2053,27 @@
if (!input.width || !input.height)
fatal("Specify stream dimensions with --width (-w) "
" and --height (-h)");
+
+ /* If input file does not specify bit-depth but input-bit-depth parameter
+ * exists, assume that to be the input bit-depth. However, if the
+ * input-bit-depth paramter does not exist, assume the input bit-depth
+ * to be the same as the codec bit-depth.
+ */
+ if (!input.bit_depth) {
+ FOREACH_STREAM({
+ if (stream->config.cfg.g_input_bit_depth)
+ input.bit_depth = stream->config.cfg.g_input_bit_depth;
+ else
+ input.bit_depth = stream->config.cfg.g_input_bit_depth =
+ (int)stream->config.cfg.g_bit_depth;
+ });
+ if (input.bit_depth > 8) input.fmt |= VPX_IMG_FMT_HIGHBITDEPTH;
+ } else {
+ FOREACH_STREAM({
+ stream->config.cfg.g_input_bit_depth = input.bit_depth;
+ });
+ }
+
FOREACH_STREAM(set_stream_dimensions(stream, input.width, input.height));
FOREACH_STREAM(validate_stream_config(stream, &global));
@@ -1739,6 +2127,25 @@
FOREACH_STREAM(open_output_file(stream, &global));
FOREACH_STREAM(initialize_encoder(stream, &global));
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if (strcmp(global.codec->name, "vp9") == 0) {
+ // Check to see if at least one stream uses 16 bit internal.
+ // Currently assume that the bit_depths for all streams using
+ // highbitdepth are the same.
+ FOREACH_STREAM({
+ if (stream->config.use_16bit_internal) {
+ use_16bit_internal = 1;
+ }
+ if (stream->config.cfg.g_profile == 0) {
+ input_shift = 0;
+ } else {
+ input_shift = (int)stream->config.cfg.g_bit_depth -
+ stream->config.cfg.g_input_bit_depth;
+ }
+ });
+ }
+#endif
+
frame_avail = 1;
got_data = 0;
@@ -1776,10 +2183,45 @@
frame_avail = 0;
if (frames_in > global.skip_frames) {
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ vpx_image_t *frame_to_encode;
+ if (input_shift || (use_16bit_internal && input.bit_depth == 8)) {
+ assert(use_16bit_internal);
+ // Input bit depth and stream bit depth do not match, so up
+ // shift frame to stream bit depth
+ if (!allocated_raw_shift) {
+ vpx_img_alloc(&raw_shift, raw.fmt | VPX_IMG_FMT_HIGHBITDEPTH,
+ input.width, input.height, 32);
+ allocated_raw_shift = 1;
+ }
+ img_upshift(&raw_shift, &raw, input_shift);
+ frame_to_encode = &raw_shift;
+ } else {
+ frame_to_encode = &raw;
+ }
vpx_usec_timer_start(&timer);
+ if (use_16bit_internal) {
+ assert(frame_to_encode->fmt & VPX_IMG_FMT_HIGHBITDEPTH);
+ FOREACH_STREAM({
+ if (stream->config.use_16bit_internal)
+ encode_frame(stream, &global,
+ frame_avail ? frame_to_encode : NULL,
+ frames_in);
+ else
+ assert(0);
+ });
+ } else {
+ assert((frame_to_encode->fmt & VPX_IMG_FMT_HIGHBITDEPTH) == 0);
+ FOREACH_STREAM(encode_frame(stream, &global,
+ frame_avail ? frame_to_encode : NULL,
+ frames_in));
+ }
+#else
+ vpx_usec_timer_start(&timer);
FOREACH_STREAM(encode_frame(stream, &global,
frame_avail ? &raw : NULL,
frames_in));
+#endif
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
@@ -1788,7 +2230,8 @@
got_data = 0;
FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
- if (!got_data && input.length && !streams->frames_out) {
+ if (!got_data && input.length && streams != NULL &&
+ !streams->frames_out) {
lagged_count = global.limit ? seen_frames : ftello(input.file);
} else if (input.length) {
int64_t remaining;
@@ -1896,6 +2339,10 @@
});
#endif
+#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
+ if (allocated_raw_shift)
+ vpx_img_free(&raw_shift);
+#endif
vpx_img_free(&raw);
free(argv);
free(streams);
« no previous file with comments | « source/libvpx/vpxdec.c ('k') | source/libvpx/y4minput.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698