Index: source/libvpx/vpxenc.c |
=================================================================== |
--- source/libvpx/vpxenc.c (revision 284462) |
+++ source/libvpx/vpxenc.c (working copy) |
@@ -133,6 +133,10 @@ |
"Input file is YV12 "); |
static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, |
"Input file is I420 (default)"); |
+static const arg_def_t use_i422 = ARG_DEF(NULL, "i422", 0, |
+ "Input file is I422"); |
+static const arg_def_t use_i444 = ARG_DEF(NULL, "i444", 0, |
+ "Input file is I444"); |
static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, |
"Codec to use"); |
static const arg_def_t passes = ARG_DEF("p", "passes", 1, |
@@ -141,6 +145,10 @@ |
"Pass to execute (1/2)"); |
static const arg_def_t fpf_name = ARG_DEF(NULL, "fpf", 1, |
"First pass statistics file name"); |
+#if CONFIG_FP_MB_STATS |
+static const arg_def_t fpmbf_name = ARG_DEF(NULL, "fpmbf", 1, |
+ "First pass block statistics file name"); |
+#endif |
static const arg_def_t limit = ARG_DEF(NULL, "limit", 1, |
"Stop encoding after n input frames"); |
static const arg_def_t skip = ARG_DEF(NULL, "skip", 1, |
@@ -229,7 +237,8 @@ |
"Max number of frames to lag"); |
static const arg_def_t *global_args[] = { |
- &use_yv12, &use_i420, &usage, &threads, &profile, |
+ &use_yv12, &use_i420, &use_i422, &use_i444, |
+ &usage, &threads, &profile, |
&width, &height, |
#if CONFIG_WEBM_IO |
&stereo_mode, |
@@ -422,7 +431,7 @@ |
for (i = 0; i < get_vpx_encoder_count(); ++i) { |
const VpxInterface *const encoder = get_vpx_encoder_by_index(i); |
fprintf(stderr, " %-6s - %s\n", |
- encoder->name, vpx_codec_iface_name(encoder->interface())); |
+ encoder->name, vpx_codec_iface_name(encoder->codec_interface())); |
} |
exit(EXIT_FAILURE); |
@@ -572,6 +581,9 @@ |
struct vpx_codec_enc_cfg cfg; |
const char *out_fn; |
const char *stats_fn; |
+#if CONFIG_FP_MB_STATS |
+ const char *fpmb_stats_fn; |
+#endif |
stereo_format_t stereo_fmt; |
int arg_ctrls[ARG_CTRL_CNT_MAX][2]; |
int arg_ctrl_cnt; |
@@ -597,6 +609,9 @@ |
uint64_t cx_time; |
size_t nbytes; |
stats_io_t stats; |
+#if CONFIG_FP_MB_STATS |
+ stats_io_t fpmb_stats; |
+#endif |
struct vpx_image *img; |
vpx_codec_ctx_t decoder; |
int mismatch_seen; |
@@ -626,7 +641,7 @@ |
memset(global, 0, sizeof(*global)); |
global->codec = get_vpx_encoder_by_index(0); |
global->passes = 0; |
- global->use_i420 = 1; |
+ global->color_type = I420; |
/* Assign default deadline to good quality */ |
global->deadline = VPX_DL_GOOD_QUALITY; |
@@ -659,9 +674,13 @@ |
else if (arg_match(&arg, &rt_dl, argi)) |
global->deadline = VPX_DL_REALTIME; |
else if (arg_match(&arg, &use_yv12, argi)) |
- global->use_i420 = 0; |
+ global->color_type = YV12; |
else if (arg_match(&arg, &use_i420, argi)) |
- global->use_i420 = 1; |
+ global->color_type = I420; |
+ else if (arg_match(&arg, &use_i422, argi)) |
+ global->color_type = I422; |
+ else if (arg_match(&arg, &use_i444, argi)) |
+ global->color_type = I444; |
else if (arg_match(&arg, &quietarg, argi)) |
global->quiet = 1; |
else if (arg_match(&arg, &verbosearg, argi)) |
@@ -788,7 +807,7 @@ |
vpx_codec_err_t res; |
/* Populate encoder configuration */ |
- res = vpx_codec_enc_config_default(global->codec->interface(), |
+ res = vpx_codec_enc_config_default(global->codec->codec_interface(), |
&stream->config.cfg, |
global->usage); |
if (res) |
@@ -873,6 +892,10 @@ |
config->out_fn = arg.val; |
} else if (arg_match(&arg, &fpf_name, argi)) { |
config->stats_fn = arg.val; |
+#if CONFIG_FP_MB_STATS |
+ } else if (arg_match(&arg, &fpmbf_name, argi)) { |
+ config->fpmb_stats_fn = arg.val; |
+#endif |
} else if (arg_match(&arg, &use_ivf, argi)) { |
config->write_webm = 0; |
} else if (arg_match(&arg, &threads, argi)) { |
@@ -965,8 +988,8 @@ |
break; |
/* Update/insert */ |
- assert(j < ARG_CTRL_CNT_MAX); |
- if (j < ARG_CTRL_CNT_MAX) { |
+ assert(j < (int)ARG_CTRL_CNT_MAX); |
+ if (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) |
@@ -1029,6 +1052,17 @@ |
fatal("Stream %d: duplicate stats file (from stream %d)", |
streami->index, stream->index); |
} |
+ |
+#if CONFIG_FP_MB_STATS |
+ /* Check for two streams sharing a mb stats file. */ |
+ if (streami != stream) { |
+ const char *a = stream->config.fpmb_stats_fn; |
+ const char *b = streami->config.fpmb_stats_fn; |
+ if (a && b && !strcmp(a, b)) |
+ fatal("Stream %d: duplicate mb stats file (from stream %d)", |
+ streami->index, stream->index); |
+ } |
+#endif |
} |
} |
@@ -1087,7 +1121,7 @@ |
if (stream->index == 0) { |
fprintf(stderr, "Codec: %s\n", |
- vpx_codec_iface_name(global->codec->interface())); |
+ vpx_codec_iface_name(global->codec->codec_interface())); |
fprintf(stderr, "Source file: %s File Type: %s Format: %s\n", |
input->filename, |
file_type_to_string(input->file_type), |
@@ -1200,11 +1234,27 @@ |
fatal("Failed to open statistics store"); |
} |
+#if CONFIG_FP_MB_STATS |
+ if (stream->config.fpmb_stats_fn) { |
+ if (!stats_open_file(&stream->fpmb_stats, |
+ stream->config.fpmb_stats_fn, pass)) |
+ fatal("Failed to open mb statistics store"); |
+ } else { |
+ if (!stats_open_mem(&stream->fpmb_stats, pass)) |
+ fatal("Failed to open mb statistics store"); |
+ } |
+#endif |
+ |
stream->config.cfg.g_pass = global->passes == 2 |
? pass ? VPX_RC_LAST_PASS : VPX_RC_FIRST_PASS |
: VPX_RC_ONE_PASS; |
- if (pass) |
+ if (pass) { |
stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats); |
+#if CONFIG_FP_MB_STATS |
+ stream->config.cfg.rc_firstpass_mb_stats_in = |
+ stats_get(&stream->fpmb_stats); |
+#endif |
+ } |
stream->cx_time = 0; |
stream->nbytes = 0; |
@@ -1221,7 +1271,7 @@ |
flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0; |
/* Construct Encoder Context */ |
- vpx_codec_enc_init(&stream->encoder, global->codec->interface(), |
+ vpx_codec_enc_init(&stream->encoder, global->codec->codec_interface(), |
&stream->config.cfg, flags); |
ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder"); |
@@ -1242,7 +1292,7 @@ |
#if CONFIG_DECODERS |
if (global->test_decode != TEST_DECODE_OFF) { |
const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name); |
- vpx_codec_dec_init(&stream->decoder, decoder->interface(), NULL, 0); |
+ vpx_codec_dec_init(&stream->decoder, decoder->codec_interface(), NULL, 0); |
} |
#endif |
} |
@@ -1388,6 +1438,14 @@ |
pkt->data.twopass_stats.sz); |
stream->nbytes += pkt->data.raw.sz; |
break; |
+#if CONFIG_FP_MB_STATS |
+ case VPX_CODEC_FPMB_STATS_PKT: |
+ stats_write(&stream->fpmb_stats, |
+ pkt->data.firstpass_mb_stats.buf, |
+ pkt->data.firstpass_mb_stats.sz); |
+ stream->nbytes += pkt->data.raw.sz; |
+ break; |
+#endif |
case VPX_CODEC_PSNR_PKT: |
if (global->show_psnr) { |
@@ -1517,7 +1575,7 @@ |
vpx_image_t raw; |
int frame_avail, got_data; |
- struct VpxInputContext input = {0}; |
+ struct VpxInputContext input; |
struct VpxEncoderConfig global; |
struct stream_state *streams = NULL; |
char **argv, **argi; |
@@ -1525,6 +1583,7 @@ |
int stream_cnt = 0; |
int res = 0; |
+ memset(&input, 0, sizeof(input)); |
exec_name = argv_[0]; |
if (argc < 3) |
@@ -1543,7 +1602,20 @@ |
argv = argv_dup(argc - 1, argv_ + 1); |
parse_global_config(&global, argv); |
- input.fmt = global.use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_YV12; |
+ switch (global.color_type) { |
+ case I420: |
+ input.fmt = VPX_IMG_FMT_I420; |
+ break; |
+ case I422: |
+ input.fmt = VPX_IMG_FMT_I422; |
+ break; |
+ case I444: |
+ input.fmt = VPX_IMG_FMT_I444; |
+ break; |
+ case YV12: |
+ input.fmt = VPX_IMG_FMT_YV12; |
+ break; |
+ } |
{ |
/* Now parse each stream's parameters. Using a local scope here |
@@ -1777,6 +1849,10 @@ |
FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1)); |
+#if CONFIG_FP_MB_STATS |
+ FOREACH_STREAM(stats_close(&stream->fpmb_stats, global.passes - 1)); |
+#endif |
+ |
if (global.pass) |
break; |
} |