]> granicus.if.org Git - libvpx/blobdiff - vpxenc.c
tools_common.sh: Move vpxdec() test support to vpxdec.sh
[libvpx] / vpxenc.c
index 4d9629408d0ba25f8084151cf91378a2d38d26f5..d4bb034a413524cab1cc9fcd92fd3c6c4e1b5570 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -133,6 +133,10 @@ static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0,
                                           "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 @@ static const arg_def_t pass_arg         = ARG_DEF(NULL, "pass", 1,
                                                   "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 @@ static const arg_def_t lag_in_frames    = ARG_DEF(NULL, "lag-in-frames", 1,
                                                   "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 @@ void usage_exit() {
   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 stream_config {
   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 @@ struct stream_state {
   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 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
   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 @@ static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
     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))
@@ -756,6 +775,7 @@ void open_input_file(struct VpxInputContext *input) {
       input->framerate.numerator = input->y4m.fps_n;
       input->framerate.denominator = input->y4m.fps_d;
       input->fmt = input->y4m.vpx_fmt;
+      input->bit_depth = input->y4m.bit_depth;
     } else
       fatal("Unsupported Y4M stream.");
   } else if (input->detect.buf_read == 4 && fourcc_is_ivf(input->detect.buf)) {
@@ -787,7 +807,7 @@ static struct stream_state *new_stream(struct VpxEncoderConfig *global,
     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)
@@ -872,6 +892,10 @@ static int parse_stream_params(struct VpxEncoderConfig *global,
       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)) {
@@ -964,8 +988,8 @@ static int parse_stream_params(struct VpxEncoderConfig *global,
               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)
@@ -1028,6 +1052,17 @@ static void validate_stream_config(const struct stream_state *stream,
         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
   }
 }
 
@@ -1086,7 +1121,7 @@ static void show_stream_config(struct stream_state *stream,
 
   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),
@@ -1199,11 +1234,27 @@ static void setup_pass(struct stream_state *stream,
       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;
@@ -1220,7 +1271,7 @@ static void initialize_encoder(struct stream_state *stream,
   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");
 
@@ -1241,7 +1292,7 @@ static void initialize_encoder(struct stream_state *stream,
 #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
 }
@@ -1268,6 +1319,7 @@ static void encode_frame(struct stream_state *stream,
       fprintf(stderr, "%s can only scale 4:2:0 8bpp inputs\n", exec_name);
       exit(EXIT_FAILURE);
     }
+#if CONFIG_LIBYUV
     if (!stream->img)
       stream->img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420,
                                   cfg->g_w, cfg->g_h, 16);
@@ -1283,8 +1335,15 @@ static void encode_frame(struct stream_state *stream,
               stream->img->stride[VPX_PLANE_V],
               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
   }
 
   vpx_usec_timer_start(&timer);
@@ -1379,6 +1438,14 @@ static void get_cx_data(struct stream_state *stream,
                     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) {
@@ -1508,7 +1575,7 @@ int main(int argc, const char **argv_) {
   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;
@@ -1516,6 +1583,7 @@ int main(int argc, const char **argv_) {
   int stream_cnt = 0;
   int res = 0;
 
+  memset(&input, 0, sizeof(input));
   exec_name = argv_[0];
 
   if (argc < 3)
@@ -1525,6 +1593,7 @@ int main(int argc, const char **argv_) {
   input.framerate.numerator = 30;
   input.framerate.denominator = 1;
   input.only_i420 = 1;
+  input.bit_depth = 0;
 
   /* First parse the global configuration values, because we want to apply
    * other parameters on top of the default configuration provided by the
@@ -1533,7 +1602,20 @@ int main(int argc, const char **argv_) {
   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
@@ -1676,7 +1758,6 @@ int main(int argc, const char **argv_) {
                   fps >= 1.0 ? fps : fps * 60,
                   fps >= 1.0 ? "fps" : "fpm");
           print_time("ETA", estimated_time_left);
-          fprintf(stderr, "\033[K");
         }
 
       } else
@@ -1727,6 +1808,8 @@ int main(int argc, const char **argv_) {
       }
 
       fflush(stdout);
+      if (!global.quiet)
+        fprintf(stderr, "\033[K");
     }
 
     if (stream_cnt > 1)
@@ -1766,6 +1849,10 @@ int main(int argc, const char **argv_) {
 
     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;
   }