| Index: source/libvpx/examples/simple_encoder.c
 | 
| ===================================================================
 | 
| --- source/libvpx/examples/simple_encoder.c	(revision 263011)
 | 
| +++ source/libvpx/examples/simple_encoder.c	(working copy)
 | 
| @@ -64,6 +64,15 @@
 | 
|  // frame is shown for one frame-time in duration. The flags parameter is
 | 
|  // unused in this example. The deadline is set to VPX_DL_REALTIME to
 | 
|  // make the example run as quickly as possible.
 | 
| +
 | 
| +// Forced Keyframes
 | 
| +// ----------------
 | 
| +// Keyframes can be forced by setting the VPX_EFLAG_FORCE_KF bit of the
 | 
| +// flags passed to `vpx_codec_control()`. In this example, we force a
 | 
| +// keyframe every <keyframe-interval> frames. Note, the output stream can
 | 
| +// contain additional keyframes beyond those that have been forced using the
 | 
| +// VPX_EFLAG_FORCE_KF flag because of automatic keyframe placement by the
 | 
| +// encoder.
 | 
|  //
 | 
|  // Processing The Encoded Data
 | 
|  // ---------------------------
 | 
| @@ -103,8 +112,8 @@
 | 
|  void usage_exit() {
 | 
|    fprintf(stderr,
 | 
|            "Usage: %s <codec> <width> <height> <infile> <outfile> "
 | 
| -              "[<error-resilient>]\nSee comments in simple_encoder.c for more "
 | 
| -              "information.\n",
 | 
| +              "<keyframe-interval> [<error-resilient>]\nSee comments in "
 | 
| +              "simple_encoder.c for more information.\n",
 | 
|            exec_name);
 | 
|    exit(EXIT_FAILURE);
 | 
|  }
 | 
| @@ -112,11 +121,12 @@
 | 
|  static void encode_frame(vpx_codec_ctx_t *codec,
 | 
|                           vpx_image_t *img,
 | 
|                           int frame_index,
 | 
| +                         int flags,
 | 
|                           VpxVideoWriter *writer) {
 | 
|    vpx_codec_iter_t iter = NULL;
 | 
|    const vpx_codec_cx_pkt_t *pkt = NULL;
 | 
| -  const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
 | 
| -                                               VPX_DL_GOOD_QUALITY);
 | 
| +  const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
 | 
| +                                               flags, VPX_DL_GOOD_QUALITY);
 | 
|    if (res != VPX_CODEC_OK)
 | 
|      die_codec(codec, "Failed to encode frame");
 | 
|  
 | 
| @@ -148,15 +158,20 @@
 | 
|    const VpxInterface *encoder = NULL;
 | 
|    const int fps = 30;        // TODO(dkovalev) add command line argument
 | 
|    const int bitrate = 200;   // kbit/s TODO(dkovalev) add command line argument
 | 
| +  int keyframe_interval = 0;
 | 
| +
 | 
| +  // TODO(dkovalev): Add some simple command line parsing code to make the
 | 
| +  // command line more flexible.
 | 
|    const char *codec_arg = NULL;
 | 
|    const char *width_arg = NULL;
 | 
|    const char *height_arg = NULL;
 | 
|    const char *infile_arg = NULL;
 | 
|    const char *outfile_arg = NULL;
 | 
| +  const char *keyframe_interval_arg = NULL;
 | 
|  
 | 
|    exec_name = argv[0];
 | 
|  
 | 
| -  if (argc < 6)
 | 
| +  if (argc < 7)
 | 
|      die("Invalid number of arguments");
 | 
|  
 | 
|    codec_arg = argv[1];
 | 
| @@ -164,6 +179,7 @@
 | 
|    height_arg = argv[3];
 | 
|    infile_arg = argv[4];
 | 
|    outfile_arg = argv[5];
 | 
| +  keyframe_interval_arg = argv[6];
 | 
|  
 | 
|    encoder = get_vpx_encoder_by_name(codec_arg);
 | 
|    if (!encoder)
 | 
| @@ -187,6 +203,10 @@
 | 
|      die("Failed to allocate image.");
 | 
|    }
 | 
|  
 | 
| +  keyframe_interval = strtol(keyframe_interval_arg, NULL, 0);
 | 
| +  if (keyframe_interval < 0)
 | 
| +    die("Invalid keyframe interval value.");
 | 
| +
 | 
|    printf("Using %s\n", vpx_codec_iface_name(encoder->interface()));
 | 
|  
 | 
|    res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0);
 | 
| @@ -198,7 +218,7 @@
 | 
|    cfg.g_timebase.num = info.time_base.numerator;
 | 
|    cfg.g_timebase.den = info.time_base.denominator;
 | 
|    cfg.rc_target_bitrate = bitrate;
 | 
| -  cfg.g_error_resilient = argc > 6 ? strtol(argv[6], NULL, 0) : 0;
 | 
| +  cfg.g_error_resilient = argc > 7 ? strtol(argv[7], NULL, 0) : 0;
 | 
|  
 | 
|    writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
 | 
|    if (!writer)
 | 
| @@ -210,9 +230,13 @@
 | 
|    if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0))
 | 
|      die_codec(&codec, "Failed to initialize encoder");
 | 
|  
 | 
| -  while (vpx_img_read(&raw, infile))
 | 
| -    encode_frame(&codec, &raw, frame_count++, writer);
 | 
| -  encode_frame(&codec, NULL, -1, writer);  // flush the encoder
 | 
| +  while (vpx_img_read(&raw, infile)) {
 | 
| +    int flags = 0;
 | 
| +    if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
 | 
| +      flags |= VPX_EFLAG_FORCE_KF;
 | 
| +    encode_frame(&codec, &raw, frame_count++, flags, writer);
 | 
| +  }
 | 
| +  encode_frame(&codec, NULL, -1, 0, writer);  // flush the encoder
 | 
|  
 | 
|    printf("\n");
 | 
|    fclose(infile);
 | 
| 
 |