WebM Codec SDK
vp9_spatial_svc_encoder
1 /*
2  * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3  *
4  * Use of this source code is governed by a BSD-style license
5  * that can be found in the LICENSE file in the root of the source
6  * tree. An additional intellectual property rights grant can be found
7  * in the file PATENTS. All contributing project authors may
8  * be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /*
12  * This is an example demonstrating how to implement a multi-layer
13  * VP9 encoding scheme based on spatial scalability for video applications
14  * that benefit from a scalable bitstream.
15  */
16 
17 #include <math.h>
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22 
23 #include "../args.h"
24 #include "../tools_common.h"
25 #include "../video_writer.h"
26 
27 #include "../vpx_ports/vpx_timer.h"
28 #include "./svc_context.h"
29 #include "vpx/vp8cx.h"
30 #include "vpx/vpx_encoder.h"
31 #include "../vpxstats.h"
32 #include "vp9/encoder/vp9_encoder.h"
33 #define OUTPUT_RC_STATS 1
34 
35 static const arg_def_t skip_frames_arg =
36  ARG_DEF("s", "skip-frames", 1, "input frames to skip");
37 static const arg_def_t frames_arg =
38  ARG_DEF("f", "frames", 1, "number of frames to encode");
39 static const arg_def_t threads_arg =
40  ARG_DEF("th", "threads", 1, "number of threads to use");
41 #if OUTPUT_RC_STATS
42 static const arg_def_t output_rc_stats_arg =
43  ARG_DEF("rcstat", "output_rc_stats", 1, "output rc stats");
44 #endif
45 static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width");
46 static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height");
47 static const arg_def_t timebase_arg =
48  ARG_DEF("t", "timebase", 1, "timebase (num/den)");
49 static const arg_def_t bitrate_arg = ARG_DEF(
50  "b", "target-bitrate", 1, "encoding bitrate, in kilobits per second");
51 static const arg_def_t spatial_layers_arg =
52  ARG_DEF("sl", "spatial-layers", 1, "number of spatial SVC layers");
53 static const arg_def_t temporal_layers_arg =
54  ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers");
55 static const arg_def_t temporal_layering_mode_arg =
56  ARG_DEF("tlm", "temporal-layering-mode", 1,
57  "temporal layering scheme."
58  "VP9E_TEMPORAL_LAYERING_MODE");
59 static const arg_def_t kf_dist_arg =
60  ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
61 static const arg_def_t scale_factors_arg =
62  ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)");
63 static const arg_def_t passes_arg =
64  ARG_DEF("p", "passes", 1, "Number of passes (1/2)");
65 static const arg_def_t pass_arg =
66  ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)");
67 static const arg_def_t fpf_name_arg =
68  ARG_DEF(NULL, "fpf", 1, "First pass statistics file name");
69 static const arg_def_t min_q_arg =
70  ARG_DEF(NULL, "min-q", 1, "Minimum quantizer");
71 static const arg_def_t max_q_arg =
72  ARG_DEF(NULL, "max-q", 1, "Maximum quantizer");
73 static const arg_def_t min_bitrate_arg =
74  ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate");
75 static const arg_def_t max_bitrate_arg =
76  ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
77 static const arg_def_t lag_in_frame_arg =
78  ARG_DEF(NULL, "lag-in-frames", 1,
79  "Number of frame to input before "
80  "generating any outputs");
81 static const arg_def_t rc_end_usage_arg =
82  ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q");
83 static const arg_def_t speed_arg =
84  ARG_DEF("sp", "speed", 1, "speed configuration");
85 static const arg_def_t aqmode_arg =
86  ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
87 static const arg_def_t bitrates_arg =
88  ARG_DEF("bl", "bitrates", 1, "bitrates[sl * num_tl + tl]");
89 static const arg_def_t dropframe_thresh_arg =
90  ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
91 static const struct arg_enum_list tune_content_enum[] = {
92  { "default", VP9E_CONTENT_DEFAULT },
93  { "screen", VP9E_CONTENT_SCREEN },
94  { "film", VP9E_CONTENT_FILM },
95  { NULL, 0 }
96 };
97 
98 static const arg_def_t tune_content_arg = ARG_DEF_ENUM(
99  NULL, "tune-content", 1, "Tune content type", tune_content_enum);
100 static const arg_def_t inter_layer_pred_arg = ARG_DEF(
101  NULL, "inter-layer-pred", 1, "0 - 3: On, Off, Key-frames, Constrained");
102 
103 #if CONFIG_VP9_HIGHBITDEPTH
104 static const struct arg_enum_list bitdepth_enum[] = {
105  { "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 }
106 };
107 
108 static const arg_def_t bitdepth_arg = ARG_DEF_ENUM(
109  "d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ", bitdepth_enum);
110 #endif // CONFIG_VP9_HIGHBITDEPTH
111 
112 static const arg_def_t *svc_args[] = { &frames_arg,
113  &width_arg,
114  &height_arg,
115  &timebase_arg,
116  &bitrate_arg,
117  &skip_frames_arg,
118  &spatial_layers_arg,
119  &kf_dist_arg,
120  &scale_factors_arg,
121  &passes_arg,
122  &pass_arg,
123  &fpf_name_arg,
124  &min_q_arg,
125  &max_q_arg,
126  &min_bitrate_arg,
127  &max_bitrate_arg,
128  &temporal_layers_arg,
129  &temporal_layering_mode_arg,
130  &lag_in_frame_arg,
131  &threads_arg,
132  &aqmode_arg,
133 #if OUTPUT_RC_STATS
134  &output_rc_stats_arg,
135 #endif
136 
137 #if CONFIG_VP9_HIGHBITDEPTH
138  &bitdepth_arg,
139 #endif
140  &speed_arg,
141  &rc_end_usage_arg,
142  &bitrates_arg,
143  &dropframe_thresh_arg,
144  &tune_content_arg,
145  &inter_layer_pred_arg,
146  NULL };
147 
148 static const uint32_t default_frames_to_skip = 0;
149 static const uint32_t default_frames_to_code = 60 * 60;
150 static const uint32_t default_width = 1920;
151 static const uint32_t default_height = 1080;
152 static const uint32_t default_timebase_num = 1;
153 static const uint32_t default_timebase_den = 60;
154 static const uint32_t default_bitrate = 1000;
155 static const uint32_t default_spatial_layers = 5;
156 static const uint32_t default_temporal_layers = 1;
157 static const uint32_t default_kf_dist = 100;
158 static const uint32_t default_temporal_layering_mode = 0;
159 static const uint32_t default_output_rc_stats = 0;
160 static const int32_t default_speed = -1; // -1 means use library default.
161 static const uint32_t default_threads = 0; // zero means use library default.
162 
163 typedef struct {
164  const char *input_filename;
165  const char *output_filename;
166  uint32_t frames_to_code;
167  uint32_t frames_to_skip;
168  struct VpxInputContext input_ctx;
169  stats_io_t rc_stats;
170  int passes;
171  int pass;
172  int tune_content;
173  int inter_layer_pred;
174 } AppInput;
175 
176 static const char *exec_name;
177 
178 void usage_exit(void) {
179  fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
180  exec_name);
181  fprintf(stderr, "Options:\n");
182  arg_show_usage(stderr, svc_args);
183  exit(EXIT_FAILURE);
184 }
185 
186 static void parse_command_line(int argc, const char **argv_,
187  AppInput *app_input, SvcContext *svc_ctx,
188  vpx_codec_enc_cfg_t *enc_cfg) {
189  struct arg arg;
190  char **argv = NULL;
191  char **argi = NULL;
192  char **argj = NULL;
193  vpx_codec_err_t res;
194  int passes = 0;
195  int pass = 0;
196  const char *fpf_file_name = NULL;
197  unsigned int min_bitrate = 0;
198  unsigned int max_bitrate = 0;
199  char string_options[1024] = { 0 };
200 
201  // initialize SvcContext with parameters that will be passed to vpx_svc_init
202  svc_ctx->log_level = SVC_LOG_DEBUG;
203  svc_ctx->spatial_layers = default_spatial_layers;
204  svc_ctx->temporal_layers = default_temporal_layers;
205  svc_ctx->temporal_layering_mode = default_temporal_layering_mode;
206 #if OUTPUT_RC_STATS
207  svc_ctx->output_rc_stat = default_output_rc_stats;
208 #endif
209  svc_ctx->speed = default_speed;
210  svc_ctx->threads = default_threads;
211 
212  // start with default encoder configuration
213  res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
214  if (res) {
215  die("Failed to get config: %s\n", vpx_codec_err_to_string(res));
216  }
217  // update enc_cfg with app default values
218  enc_cfg->g_w = default_width;
219  enc_cfg->g_h = default_height;
220  enc_cfg->g_timebase.num = default_timebase_num;
221  enc_cfg->g_timebase.den = default_timebase_den;
222  enc_cfg->rc_target_bitrate = default_bitrate;
223  enc_cfg->kf_min_dist = default_kf_dist;
224  enc_cfg->kf_max_dist = default_kf_dist;
225  enc_cfg->rc_end_usage = VPX_CQ;
226 
227  // initialize AppInput with default values
228  app_input->frames_to_code = default_frames_to_code;
229  app_input->frames_to_skip = default_frames_to_skip;
230 
231  // process command line options
232  argv = argv_dup(argc - 1, argv_ + 1);
233  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
234  arg.argv_step = 1;
235 
236  if (arg_match(&arg, &frames_arg, argi)) {
237  app_input->frames_to_code = arg_parse_uint(&arg);
238  } else if (arg_match(&arg, &width_arg, argi)) {
239  enc_cfg->g_w = arg_parse_uint(&arg);
240  } else if (arg_match(&arg, &height_arg, argi)) {
241  enc_cfg->g_h = arg_parse_uint(&arg);
242  } else if (arg_match(&arg, &timebase_arg, argi)) {
243  enc_cfg->g_timebase = arg_parse_rational(&arg);
244  } else if (arg_match(&arg, &bitrate_arg, argi)) {
245  enc_cfg->rc_target_bitrate = arg_parse_uint(&arg);
246  } else if (arg_match(&arg, &skip_frames_arg, argi)) {
247  app_input->frames_to_skip = arg_parse_uint(&arg);
248  } else if (arg_match(&arg, &spatial_layers_arg, argi)) {
249  svc_ctx->spatial_layers = arg_parse_uint(&arg);
250  } else if (arg_match(&arg, &temporal_layers_arg, argi)) {
251  svc_ctx->temporal_layers = arg_parse_uint(&arg);
252 #if OUTPUT_RC_STATS
253  } else if (arg_match(&arg, &output_rc_stats_arg, argi)) {
254  svc_ctx->output_rc_stat = arg_parse_uint(&arg);
255 #endif
256  } else if (arg_match(&arg, &speed_arg, argi)) {
257  svc_ctx->speed = arg_parse_uint(&arg);
258  } else if (arg_match(&arg, &aqmode_arg, argi)) {
259  svc_ctx->aqmode = arg_parse_uint(&arg);
260  } else if (arg_match(&arg, &threads_arg, argi)) {
261  svc_ctx->threads = arg_parse_uint(&arg);
262  } else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
263  svc_ctx->temporal_layering_mode = enc_cfg->temporal_layering_mode =
264  arg_parse_int(&arg);
265  if (svc_ctx->temporal_layering_mode) {
266  enc_cfg->g_error_resilient = 1;
267  }
268  } else if (arg_match(&arg, &kf_dist_arg, argi)) {
269  enc_cfg->kf_min_dist = arg_parse_uint(&arg);
270  enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
271  } else if (arg_match(&arg, &scale_factors_arg, argi)) {
272  strncat(string_options, " scale-factors=",
273  sizeof(string_options) - strlen(string_options) - 1);
274  strncat(string_options, arg.val,
275  sizeof(string_options) - strlen(string_options) - 1);
276  } else if (arg_match(&arg, &bitrates_arg, argi)) {
277  strncat(string_options, " bitrates=",
278  sizeof(string_options) - strlen(string_options) - 1);
279  strncat(string_options, arg.val,
280  sizeof(string_options) - strlen(string_options) - 1);
281  } else if (arg_match(&arg, &passes_arg, argi)) {
282  passes = arg_parse_uint(&arg);
283  if (passes < 1 || passes > 2) {
284  die("Error: Invalid number of passes (%d)\n", passes);
285  }
286  } else if (arg_match(&arg, &pass_arg, argi)) {
287  pass = arg_parse_uint(&arg);
288  if (pass < 1 || pass > 2) {
289  die("Error: Invalid pass selected (%d)\n", pass);
290  }
291  } else if (arg_match(&arg, &fpf_name_arg, argi)) {
292  fpf_file_name = arg.val;
293  } else if (arg_match(&arg, &min_q_arg, argi)) {
294  strncat(string_options, " min-quantizers=",
295  sizeof(string_options) - strlen(string_options) - 1);
296  strncat(string_options, arg.val,
297  sizeof(string_options) - strlen(string_options) - 1);
298  } else if (arg_match(&arg, &max_q_arg, argi)) {
299  strncat(string_options, " max-quantizers=",
300  sizeof(string_options) - strlen(string_options) - 1);
301  strncat(string_options, arg.val,
302  sizeof(string_options) - strlen(string_options) - 1);
303  } else if (arg_match(&arg, &min_bitrate_arg, argi)) {
304  min_bitrate = arg_parse_uint(&arg);
305  } else if (arg_match(&arg, &max_bitrate_arg, argi)) {
306  max_bitrate = arg_parse_uint(&arg);
307  } else if (arg_match(&arg, &lag_in_frame_arg, argi)) {
308  enc_cfg->g_lag_in_frames = arg_parse_uint(&arg);
309  } else if (arg_match(&arg, &rc_end_usage_arg, argi)) {
310  enc_cfg->rc_end_usage = arg_parse_uint(&arg);
311 #if CONFIG_VP9_HIGHBITDEPTH
312  } else if (arg_match(&arg, &bitdepth_arg, argi)) {
313  enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg);
314  switch (enc_cfg->g_bit_depth) {
315  case VPX_BITS_8:
316  enc_cfg->g_input_bit_depth = 8;
317  enc_cfg->g_profile = 0;
318  break;
319  case VPX_BITS_10:
320  enc_cfg->g_input_bit_depth = 10;
321  enc_cfg->g_profile = 2;
322  break;
323  case VPX_BITS_12:
324  enc_cfg->g_input_bit_depth = 12;
325  enc_cfg->g_profile = 2;
326  break;
327  default:
328  die("Error: Invalid bit depth selected (%d)\n", enc_cfg->g_bit_depth);
329  break;
330  }
331 #endif // CONFIG_VP9_HIGHBITDEPTH
332  } else if (arg_match(&arg, &dropframe_thresh_arg, argi)) {
333  enc_cfg->rc_dropframe_thresh = arg_parse_uint(&arg);
334  } else if (arg_match(&arg, &tune_content_arg, argi)) {
335  app_input->tune_content = arg_parse_uint(&arg);
336  } else if (arg_match(&arg, &inter_layer_pred_arg, argi)) {
337  app_input->inter_layer_pred = arg_parse_uint(&arg);
338  } else {
339  ++argj;
340  }
341  }
342 
343  // There will be a space in front of the string options
344  if (strlen(string_options) > 0)
345  vpx_svc_set_options(svc_ctx, string_options + 1);
346 
347  if (passes == 0 || passes == 1) {
348  if (pass) {
349  fprintf(stderr, "pass is ignored since there's only one pass\n");
350  }
351  enc_cfg->g_pass = VPX_RC_ONE_PASS;
352  } else {
353  if (pass == 0) {
354  die("pass must be specified when passes is 2\n");
355  }
356 
357  if (fpf_file_name == NULL) {
358  die("fpf must be specified when passes is 2\n");
359  }
360 
361  if (pass == 1) {
362  enc_cfg->g_pass = VPX_RC_FIRST_PASS;
363  if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 0)) {
364  fatal("Failed to open statistics store");
365  }
366  } else {
367  enc_cfg->g_pass = VPX_RC_LAST_PASS;
368  if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 1)) {
369  fatal("Failed to open statistics store");
370  }
371  enc_cfg->rc_twopass_stats_in = stats_get(&app_input->rc_stats);
372  }
373  app_input->passes = passes;
374  app_input->pass = pass;
375  }
376 
377  if (enc_cfg->rc_target_bitrate > 0) {
378  if (min_bitrate > 0) {
379  enc_cfg->rc_2pass_vbr_minsection_pct =
380  min_bitrate * 100 / enc_cfg->rc_target_bitrate;
381  }
382  if (max_bitrate > 0) {
383  enc_cfg->rc_2pass_vbr_maxsection_pct =
384  max_bitrate * 100 / enc_cfg->rc_target_bitrate;
385  }
386  }
387 
388  // Check for unrecognized options
389  for (argi = argv; *argi; ++argi)
390  if (argi[0][0] == '-' && strlen(argi[0]) > 1)
391  die("Error: Unrecognized option %s\n", *argi);
392 
393  if (argv[0] == NULL || argv[1] == 0) {
394  usage_exit();
395  }
396  app_input->input_filename = argv[0];
397  app_input->output_filename = argv[1];
398  free(argv);
399 
400  if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 ||
401  enc_cfg->g_h % 2)
402  die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h);
403 
404  printf(
405  "Codec %s\nframes: %d, skip: %d\n"
406  "layers: %d\n"
407  "width %d, height: %d,\n"
408  "num: %d, den: %d, bitrate: %d,\n"
409  "gop size: %d\n",
410  vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
411  app_input->frames_to_skip, svc_ctx->spatial_layers, enc_cfg->g_w,
412  enc_cfg->g_h, enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
413  enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
414 }
415 
416 #if OUTPUT_RC_STATS
417 // For rate control encoding stats.
418 struct RateControlStats {
419  // Number of input frames per layer.
420  int layer_input_frames[VPX_MAX_LAYERS];
421  // Total (cumulative) number of encoded frames per layer.
422  int layer_tot_enc_frames[VPX_MAX_LAYERS];
423  // Number of encoded non-key frames per layer.
424  int layer_enc_frames[VPX_MAX_LAYERS];
425  // Framerate per layer (cumulative).
426  double layer_framerate[VPX_MAX_LAYERS];
427  // Target average frame size per layer (per-frame-bandwidth per layer).
428  double layer_pfb[VPX_MAX_LAYERS];
429  // Actual average frame size per layer.
430  double layer_avg_frame_size[VPX_MAX_LAYERS];
431  // Average rate mismatch per layer (|target - actual| / target).
432  double layer_avg_rate_mismatch[VPX_MAX_LAYERS];
433  // Actual encoding bitrate per layer (cumulative).
434  double layer_encoding_bitrate[VPX_MAX_LAYERS];
435  // Average of the short-time encoder actual bitrate.
436  // TODO(marpan): Should we add these short-time stats for each layer?
437  double avg_st_encoding_bitrate;
438  // Variance of the short-time encoder actual bitrate.
439  double variance_st_encoding_bitrate;
440  // Window (number of frames) for computing short-time encoding bitrate.
441  int window_size;
442  // Number of window measurements.
443  int window_count;
444 };
445 
446 // Note: these rate control stats assume only 1 key frame in the
447 // sequence (i.e., first frame only).
448 static void set_rate_control_stats(struct RateControlStats *rc,
449  vpx_codec_enc_cfg_t *cfg) {
450  unsigned int sl, tl;
451  // Set the layer (cumulative) framerate and the target layer (non-cumulative)
452  // per-frame-bandwidth, for the rate control encoding stats below.
453  const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
454 
455  for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
456  for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
457  const int layer = sl * cfg->ts_number_layers + tl;
458  if (cfg->ts_number_layers == 1)
459  rc->layer_framerate[layer] = framerate;
460  else
461  rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
462  if (tl > 0) {
463  rc->layer_pfb[layer] =
464  1000.0 *
465  (cfg->layer_target_bitrate[layer] -
466  cfg->layer_target_bitrate[layer - 1]) /
467  (rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
468  } else {
469  rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] /
470  rc->layer_framerate[layer];
471  }
472  rc->layer_input_frames[layer] = 0;
473  rc->layer_enc_frames[layer] = 0;
474  rc->layer_tot_enc_frames[layer] = 0;
475  rc->layer_encoding_bitrate[layer] = 0.0;
476  rc->layer_avg_frame_size[layer] = 0.0;
477  rc->layer_avg_rate_mismatch[layer] = 0.0;
478  }
479  }
480  rc->window_count = 0;
481  rc->window_size = 15;
482  rc->avg_st_encoding_bitrate = 0.0;
483  rc->variance_st_encoding_bitrate = 0.0;
484 }
485 
486 static void printout_rate_control_summary(struct RateControlStats *rc,
487  vpx_codec_enc_cfg_t *cfg,
488  int frame_cnt) {
489  unsigned int sl, tl;
490  double perc_fluctuation = 0.0;
491  int tot_num_frames = 0;
492  printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
493  printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
495  for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
496  tot_num_frames = 0;
497  for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
498  const int layer = sl * cfg->ts_number_layers + tl;
499  const int num_dropped =
500  (tl > 0)
501  ? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
502  : (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
503  1);
504  tot_num_frames += rc->layer_input_frames[layer];
505  rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
506  rc->layer_encoding_bitrate[layer] /
507  tot_num_frames;
508  rc->layer_avg_frame_size[layer] =
509  rc->layer_avg_frame_size[layer] / rc->layer_enc_frames[layer];
510  rc->layer_avg_rate_mismatch[layer] = 100.0 *
511  rc->layer_avg_rate_mismatch[layer] /
512  rc->layer_enc_frames[layer];
513  printf("For layer#: sl%d tl%d \n", sl, tl);
514  printf("Bitrate (target vs actual): %d %f.0 kbps\n",
515  cfg->layer_target_bitrate[layer],
516  rc->layer_encoding_bitrate[layer]);
517  printf("Average frame size (target vs actual): %f %f bits\n",
518  rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
519  printf("Average rate_mismatch: %f\n", rc->layer_avg_rate_mismatch[layer]);
520  printf(
521  "Number of input frames, encoded (non-key) frames, "
522  "and percent dropped frames: %d %d %f.0 \n",
523  rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
524  100.0 * num_dropped / rc->layer_input_frames[layer]);
525  printf("\n");
526  }
527  }
528  rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count;
529  rc->variance_st_encoding_bitrate =
530  rc->variance_st_encoding_bitrate / rc->window_count -
531  (rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate);
532  perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) /
533  rc->avg_st_encoding_bitrate;
534  printf("Short-time stats, for window of %d frames: \n", rc->window_size);
535  printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
536  rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
537  perc_fluctuation);
538  printf("Num of input, num of encoded (super) frames: %d %d \n", frame_cnt,
539  tot_num_frames);
540 }
541 
542 static vpx_codec_err_t parse_superframe_index(const uint8_t *data,
543  size_t data_sz, uint64_t sizes[8],
544  int *count) {
545  // A chunk ending with a byte matching 0xc0 is an invalid chunk unless
546  // it is a super frame index. If the last byte of real video compression
547  // data is 0xc0 the encoder must add a 0 byte. If we have the marker but
548  // not the associated matching marker byte at the front of the index we have
549  // an invalid bitstream and need to return an error.
550 
551  uint8_t marker;
552 
553  marker = *(data + data_sz - 1);
554  *count = 0;
555 
556  if ((marker & 0xe0) == 0xc0) {
557  const uint32_t frames = (marker & 0x7) + 1;
558  const uint32_t mag = ((marker >> 3) & 0x3) + 1;
559  const size_t index_sz = 2 + mag * frames;
560 
561  // This chunk is marked as having a superframe index but doesn't have
562  // enough data for it, thus it's an invalid superframe index.
563  if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
564 
565  {
566  const uint8_t marker2 = *(data + data_sz - index_sz);
567 
568  // This chunk is marked as having a superframe index but doesn't have
569  // the matching marker byte at the front of the index therefore it's an
570  // invalid chunk.
571  if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
572  }
573 
574  {
575  // Found a valid superframe index.
576  uint32_t i, j;
577  const uint8_t *x = &data[data_sz - index_sz + 1];
578 
579  for (i = 0; i < frames; ++i) {
580  uint32_t this_sz = 0;
581 
582  for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
583  sizes[i] = this_sz;
584  }
585  *count = frames;
586  }
587  }
588  return VPX_CODEC_OK;
589 }
590 #endif
591 
592 // Example pattern for spatial layers and 2 temporal layers used in the
593 // bypass/flexible mode. The pattern corresponds to the pattern
594 // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
595 // non-flexible mode.
596 static void set_frame_flags_bypass_mode_ex0(
597  int tl, int num_spatial_layers, int is_key_frame,
598  vpx_svc_ref_frame_config_t *ref_frame_config) {
599  int sl;
600  for (sl = 0; sl < num_spatial_layers; ++sl)
601  ref_frame_config->update_buffer_slot[sl] = 0;
602 
603  for (sl = 0; sl < num_spatial_layers; ++sl) {
604  // Set the buffer idx.
605  if (tl == 0) {
606  ref_frame_config->lst_fb_idx[sl] = sl;
607  if (sl) {
608  if (is_key_frame) {
609  ref_frame_config->lst_fb_idx[sl] = sl - 1;
610  ref_frame_config->gld_fb_idx[sl] = sl;
611  } else {
612  ref_frame_config->gld_fb_idx[sl] = sl - 1;
613  }
614  } else {
615  ref_frame_config->gld_fb_idx[sl] = 0;
616  }
617  ref_frame_config->alt_fb_idx[sl] = 0;
618  } else if (tl == 1) {
619  ref_frame_config->lst_fb_idx[sl] = sl;
620  ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
621  ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
622  }
623  // Set the reference and update flags.
624  if (!tl) {
625  if (!sl) {
626  // Base spatial and base temporal (sl = 0, tl = 0)
627  ref_frame_config->reference_last[sl] = 1;
628  ref_frame_config->reference_golden[sl] = 0;
629  ref_frame_config->reference_alt_ref[sl] = 0;
630  ref_frame_config->update_buffer_slot[sl] |=
631  1 << ref_frame_config->lst_fb_idx[sl];
632  } else {
633  if (is_key_frame) {
634  ref_frame_config->reference_last[sl] = 1;
635  ref_frame_config->reference_golden[sl] = 0;
636  ref_frame_config->reference_alt_ref[sl] = 0;
637  ref_frame_config->update_buffer_slot[sl] |=
638  1 << ref_frame_config->gld_fb_idx[sl];
639  } else {
640  // Non-zero spatiall layer.
641  ref_frame_config->reference_last[sl] = 1;
642  ref_frame_config->reference_golden[sl] = 1;
643  ref_frame_config->reference_alt_ref[sl] = 1;
644  ref_frame_config->update_buffer_slot[sl] |=
645  1 << ref_frame_config->lst_fb_idx[sl];
646  }
647  }
648  } else if (tl == 1) {
649  if (!sl) {
650  // Base spatial and top temporal (tl = 1)
651  ref_frame_config->reference_last[sl] = 1;
652  ref_frame_config->reference_golden[sl] = 0;
653  ref_frame_config->reference_alt_ref[sl] = 0;
654  ref_frame_config->update_buffer_slot[sl] |=
655  1 << ref_frame_config->alt_fb_idx[sl];
656  } else {
657  // Non-zero spatial.
658  if (sl < num_spatial_layers - 1) {
659  ref_frame_config->reference_last[sl] = 1;
660  ref_frame_config->reference_golden[sl] = 1;
661  ref_frame_config->reference_alt_ref[sl] = 0;
662  ref_frame_config->update_buffer_slot[sl] |=
663  1 << ref_frame_config->alt_fb_idx[sl];
664  } else if (sl == num_spatial_layers - 1) {
665  // Top spatial and top temporal (non-reference -- doesn't update any
666  // reference buffers)
667  ref_frame_config->reference_last[sl] = 1;
668  ref_frame_config->reference_golden[sl] = 1;
669  ref_frame_config->reference_alt_ref[sl] = 0;
670  }
671  }
672  }
673  }
674 }
675 
676 // Example pattern for 2 spatial layers and 2 temporal layers used in the
677 // bypass/flexible mode, except only 1 spatial layer when temporal_layer_id = 1.
678 static void set_frame_flags_bypass_mode_ex1(
679  int tl, int num_spatial_layers, int is_key_frame,
680  vpx_svc_ref_frame_config_t *ref_frame_config) {
681  int sl;
682  for (sl = 0; sl < num_spatial_layers; ++sl)
683  ref_frame_config->update_buffer_slot[sl] = 0;
684 
685  if (tl == 0) {
686  if (is_key_frame) {
687  ref_frame_config->lst_fb_idx[1] = 0;
688  ref_frame_config->gld_fb_idx[1] = 1;
689  } else {
690  ref_frame_config->lst_fb_idx[1] = 1;
691  ref_frame_config->gld_fb_idx[1] = 0;
692  }
693  ref_frame_config->alt_fb_idx[1] = 0;
694 
695  ref_frame_config->lst_fb_idx[0] = 0;
696  ref_frame_config->gld_fb_idx[0] = 0;
697  ref_frame_config->alt_fb_idx[0] = 0;
698  }
699  if (tl == 1) {
700  ref_frame_config->lst_fb_idx[0] = 0;
701  ref_frame_config->gld_fb_idx[0] = 1;
702  ref_frame_config->alt_fb_idx[0] = 2;
703 
704  ref_frame_config->lst_fb_idx[1] = 1;
705  ref_frame_config->gld_fb_idx[1] = 2;
706  ref_frame_config->alt_fb_idx[1] = 3;
707  }
708  // Set the reference and update flags.
709  if (tl == 0) {
710  // Base spatial and base temporal (sl = 0, tl = 0)
711  ref_frame_config->reference_last[0] = 1;
712  ref_frame_config->reference_golden[0] = 0;
713  ref_frame_config->reference_alt_ref[0] = 0;
714  ref_frame_config->update_buffer_slot[0] |=
715  1 << ref_frame_config->lst_fb_idx[0];
716 
717  if (is_key_frame) {
718  ref_frame_config->reference_last[1] = 1;
719  ref_frame_config->reference_golden[1] = 0;
720  ref_frame_config->reference_alt_ref[1] = 0;
721  ref_frame_config->update_buffer_slot[1] |=
722  1 << ref_frame_config->gld_fb_idx[1];
723  } else {
724  // Non-zero spatiall layer.
725  ref_frame_config->reference_last[1] = 1;
726  ref_frame_config->reference_golden[1] = 1;
727  ref_frame_config->reference_alt_ref[1] = 1;
728  ref_frame_config->update_buffer_slot[1] |=
729  1 << ref_frame_config->lst_fb_idx[1];
730  }
731  }
732  if (tl == 1) {
733  // Top spatial and top temporal (non-reference -- doesn't update any
734  // reference buffers)
735  ref_frame_config->reference_last[1] = 1;
736  ref_frame_config->reference_golden[1] = 0;
737  ref_frame_config->reference_alt_ref[1] = 0;
738  }
739 }
740 
741 int main(int argc, const char **argv) {
742  AppInput app_input;
743  VpxVideoWriter *writer = NULL;
744  VpxVideoInfo info;
745  vpx_codec_ctx_t codec;
746  vpx_codec_enc_cfg_t enc_cfg;
747  SvcContext svc_ctx;
748  vpx_svc_frame_drop_t svc_drop_frame;
749  uint32_t i;
750  uint32_t frame_cnt = 0;
751  vpx_image_t raw;
752  vpx_codec_err_t res;
753  int pts = 0; /* PTS starts at 0 */
754  int frame_duration = 1; /* 1 timebase tick per frame */
755  FILE *infile = NULL;
756  int end_of_stream = 0;
757  int frames_received = 0;
758 #if OUTPUT_RC_STATS
759  VpxVideoWriter *outfile[VPX_SS_MAX_LAYERS] = { NULL };
760  struct RateControlStats rc;
761  vpx_svc_layer_id_t layer_id;
762  vpx_svc_ref_frame_config_t ref_frame_config;
763  unsigned int sl, tl;
764  double sum_bitrate = 0.0;
765  double sum_bitrate2 = 0.0;
766  double framerate = 30.0;
767 #endif
768  struct vpx_usec_timer timer;
769  int64_t cx_time = 0;
770  memset(&svc_ctx, 0, sizeof(svc_ctx));
771  memset(&app_input, 0, sizeof(AppInput));
772  memset(&info, 0, sizeof(VpxVideoInfo));
773  memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
774  memset(&rc, 0, sizeof(struct RateControlStats));
775  exec_name = argv[0];
776  parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
777 
778 // Allocate image buffer
779 #if CONFIG_VP9_HIGHBITDEPTH
780  if (!vpx_img_alloc(&raw,
781  enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
783  enc_cfg.g_w, enc_cfg.g_h, 32)) {
784  die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
785  }
786 #else
787  if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) {
788  die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
789  }
790 #endif // CONFIG_VP9_HIGHBITDEPTH
791 
792  if (!(infile = fopen(app_input.input_filename, "rb")))
793  die("Failed to open %s for reading\n", app_input.input_filename);
794 
795  // Initialize codec
796  if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) !=
797  VPX_CODEC_OK)
798  die("Failed to initialize encoder\n");
799 
800 #if OUTPUT_RC_STATS
801  rc.window_count = 1;
802  rc.window_size = 15; // Silence a static analysis warning.
803  rc.avg_st_encoding_bitrate = 0.0;
804  rc.variance_st_encoding_bitrate = 0.0;
805  if (svc_ctx.output_rc_stat) {
806  set_rate_control_stats(&rc, &enc_cfg);
807  framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
808  }
809 #endif
810 
811  info.codec_fourcc = VP9_FOURCC;
812  info.time_base.numerator = enc_cfg.g_timebase.num;
813  info.time_base.denominator = enc_cfg.g_timebase.den;
814 
815  if (!(app_input.passes == 2 && app_input.pass == 1)) {
816  // We don't save the bitstream for the 1st pass on two pass rate control
817  writer =
818  vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info);
819  if (!writer)
820  die("Failed to open %s for writing\n", app_input.output_filename);
821  }
822 #if OUTPUT_RC_STATS
823  // Write out spatial layer stream.
824  // TODO(marpan/jianj): allow for writing each spatial and temporal stream.
825  if (svc_ctx.output_rc_stat) {
826  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
827  char file_name[PATH_MAX];
828 
829  snprintf(file_name, sizeof(file_name), "%s_s%d.ivf",
830  app_input.output_filename, sl);
831  outfile[sl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
832  if (!outfile[sl]) die("Failed to open %s for writing", file_name);
833  }
834  }
835 #endif
836 
837  // skip initial frames
838  for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
839 
840  if (svc_ctx.speed != -1)
841  vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
842  if (svc_ctx.threads) {
843  vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(svc_ctx.threads));
844  if (svc_ctx.threads > 1)
846  else
848  }
849  if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
851  if (svc_ctx.speed >= 5)
854 
856  app_input.inter_layer_pred);
857 
859 
860  vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, app_input.tune_content);
861 
862  svc_drop_frame.framedrop_mode = FULL_SUPERFRAME_DROP;
863  for (sl = 0; sl < (unsigned int)svc_ctx.spatial_layers; ++sl)
864  svc_drop_frame.framedrop_thresh[sl] = enc_cfg.rc_dropframe_thresh;
865  svc_drop_frame.max_consec_drop = INT_MAX;
866  vpx_codec_control(&codec, VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
867 
868  // Encode frames
869  while (!end_of_stream) {
870  vpx_codec_iter_t iter = NULL;
871  const vpx_codec_cx_pkt_t *cx_pkt;
872  // Example patterns for bypass/flexible mode:
873  // example_pattern = 0: 2 temporal layers, and spatial_layers = 1,2,3. Exact
874  // to fixed SVC patterns. example_pattern = 1: 2 spatial and 2 temporal
875  // layers, with SL0 only has TL0, and SL1 has both TL0 and TL1. This example
876  // uses the extended API.
877  int example_pattern = 0;
878  if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) {
879  // We need one extra vpx_svc_encode call at end of stream to flush
880  // encoder and get remaining data
881  end_of_stream = 1;
882  }
883 
884  // For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
885  // and the buffer indices for each spatial layer of the current
886  // (super)frame to be encoded. The spatial and temporal layer_id for the
887  // current frame also needs to be set.
888  // TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
889  // mode to "VP9E_LAYERING_MODE_BYPASS".
890  if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
891  layer_id.spatial_layer_id = 0;
892  // Example for 2 temporal layers.
893  if (frame_cnt % 2 == 0) {
894  layer_id.temporal_layer_id = 0;
895  for (i = 0; i < VPX_SS_MAX_LAYERS; i++)
896  layer_id.temporal_layer_id_per_spatial[i] = 0;
897  } else {
898  layer_id.temporal_layer_id = 1;
899  for (i = 0; i < VPX_SS_MAX_LAYERS; i++)
900  layer_id.temporal_layer_id_per_spatial[i] = 1;
901  }
902  if (example_pattern == 1) {
903  // example_pattern 1 is hard-coded for 2 spatial and 2 temporal layers.
904  assert(svc_ctx.spatial_layers == 2);
905  assert(svc_ctx.temporal_layers == 2);
906  if (frame_cnt % 2 == 0) {
907  // Spatial layer 0 and 1 are encoded.
908  layer_id.temporal_layer_id_per_spatial[0] = 0;
909  layer_id.temporal_layer_id_per_spatial[1] = 0;
910  layer_id.spatial_layer_id = 0;
911  } else {
912  // Only spatial layer 1 is encoded here.
913  layer_id.temporal_layer_id_per_spatial[1] = 1;
914  layer_id.spatial_layer_id = 1;
915  }
916  }
917  vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
918  // TODO(jianj): Fix the parameter passing for "is_key_frame" in
919  // set_frame_flags_bypass_model() for case of periodic key frames.
920  if (example_pattern == 0) {
921  set_frame_flags_bypass_mode_ex0(layer_id.temporal_layer_id,
922  svc_ctx.spatial_layers, frame_cnt == 0,
923  &ref_frame_config);
924  } else if (example_pattern == 1) {
925  set_frame_flags_bypass_mode_ex1(layer_id.temporal_layer_id,
926  svc_ctx.spatial_layers, frame_cnt == 0,
927  &ref_frame_config);
928  }
929  ref_frame_config.duration[0] = frame_duration * 1;
930  ref_frame_config.duration[1] = frame_duration * 1;
931 
933  &ref_frame_config);
934  // Keep track of input frames, to account for frame drops in rate control
935  // stats/metrics.
936  for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
937  ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
938  layer_id.temporal_layer_id];
939  }
940  } else {
941  // For the fixed pattern SVC, temporal layer is given by superframe count.
942  unsigned int tl = 0;
943  if (enc_cfg.ts_number_layers == 2)
944  tl = (frame_cnt % 2 != 0);
945  else if (enc_cfg.ts_number_layers == 3) {
946  if (frame_cnt % 2 != 0) tl = 2;
947  if ((frame_cnt > 1) && ((frame_cnt - 2) % 4 == 0)) tl = 1;
948  }
949  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl)
950  ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + tl];
951  }
952 
953  vpx_usec_timer_start(&timer);
954  res = vpx_svc_encode(
955  &svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
956  svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
957  vpx_usec_timer_mark(&timer);
958  cx_time += vpx_usec_timer_elapsed(&timer);
959 
960  fflush(stdout);
961  if (res != VPX_CODEC_OK) {
962  die_codec(&codec, "Failed to encode frame");
963  }
964 
965  while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
966  switch (cx_pkt->kind) {
967  case VPX_CODEC_CX_FRAME_PKT: {
968  SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
969  if (cx_pkt->data.frame.sz > 0) {
970 #if OUTPUT_RC_STATS
971  uint64_t sizes[8];
972  uint64_t sizes_parsed[8];
973  int count = 0;
974  vp9_zero(sizes);
975  vp9_zero(sizes_parsed);
976 #endif
977  vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
978  cx_pkt->data.frame.sz,
979  cx_pkt->data.frame.pts);
980 #if OUTPUT_RC_STATS
981  // TODO(marpan): Put this (to line728) in separate function.
982  if (svc_ctx.output_rc_stat) {
983  int num_layers_encoded = 0;
984  vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
985  parse_superframe_index(cx_pkt->data.frame.buf,
986  cx_pkt->data.frame.sz, sizes_parsed,
987  &count);
988  if (enc_cfg.ss_number_layers == 1)
989  sizes[0] = cx_pkt->data.frame.sz;
990  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
991  sizes[sl] = 0;
992  if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
993  sizes[sl] = sizes_parsed[num_layers_encoded];
994  num_layers_encoded++;
995  }
996  }
997  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
998  unsigned int sl2;
999  uint64_t tot_size = 0;
1000  for (sl2 = 0; sl2 <= sl; ++sl2) {
1001  if (cx_pkt->data.frame.spatial_layer_encoded[sl2])
1002  tot_size += sizes[sl2];
1003  }
1004  if (tot_size > 0)
1005  vpx_video_writer_write_frame(
1006  outfile[sl], cx_pkt->data.frame.buf, (size_t)(tot_size),
1007  cx_pkt->data.frame.pts);
1008  }
1009  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1010  if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
1011  for (tl = layer_id.temporal_layer_id;
1012  tl < enc_cfg.ts_number_layers; ++tl) {
1013  const int layer = sl * enc_cfg.ts_number_layers + tl;
1014  ++rc.layer_tot_enc_frames[layer];
1015  rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
1016  // Keep count of rate control stats per layer, for non-key
1017  // frames.
1018  if (tl == (unsigned int)layer_id.temporal_layer_id &&
1019  !(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
1020  rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
1021  rc.layer_avg_rate_mismatch[layer] +=
1022  fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
1023  rc.layer_pfb[layer];
1024  ++rc.layer_enc_frames[layer];
1025  }
1026  }
1027  }
1028  }
1029 
1030  // Update for short-time encoding bitrate states, for moving
1031  // window of size rc->window, shifted by rc->window / 2.
1032  // Ignore first window segment, due to key frame.
1033  if (frame_cnt > (unsigned int)rc.window_size) {
1034  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1035  if (cx_pkt->data.frame.spatial_layer_encoded[sl])
1036  sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
1037  }
1038  if (frame_cnt % rc.window_size == 0) {
1039  rc.window_count += 1;
1040  rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
1041  rc.variance_st_encoding_bitrate +=
1042  (sum_bitrate / rc.window_size) *
1043  (sum_bitrate / rc.window_size);
1044  sum_bitrate = 0.0;
1045  }
1046  }
1047 
1048  // Second shifted window.
1049  if (frame_cnt >
1050  (unsigned int)(rc.window_size + rc.window_size / 2)) {
1051  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1052  sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
1053  }
1054 
1055  if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
1056  frame_cnt % rc.window_size == 0) {
1057  rc.window_count += 1;
1058  rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
1059  rc.variance_st_encoding_bitrate +=
1060  (sum_bitrate2 / rc.window_size) *
1061  (sum_bitrate2 / rc.window_size);
1062  sum_bitrate2 = 0.0;
1063  }
1064  }
1065  }
1066 #endif
1067  }
1068  /*
1069  printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
1070  !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
1071  (int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
1072  */
1073  if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
1074  si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
1075  ++frames_received;
1076  break;
1077  }
1078  case VPX_CODEC_STATS_PKT: {
1079  stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf,
1080  cx_pkt->data.twopass_stats.sz);
1081  break;
1082  }
1083  default: { break; }
1084  }
1085  }
1086 
1087  if (!end_of_stream) {
1088  ++frame_cnt;
1089  pts += frame_duration;
1090  }
1091  }
1092 
1093  printf("Processed %d frames\n", frame_cnt);
1094  fclose(infile);
1095 #if OUTPUT_RC_STATS
1096  if (svc_ctx.output_rc_stat) {
1097  printout_rate_control_summary(&rc, &enc_cfg, frame_cnt);
1098  printf("\n");
1099  }
1100 #endif
1101  if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
1102  if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
1103  if (writer) {
1104  vpx_video_writer_close(writer);
1105  }
1106 #if OUTPUT_RC_STATS
1107  if (svc_ctx.output_rc_stat) {
1108  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1109  vpx_video_writer_close(outfile[sl]);
1110  }
1111  }
1112 #endif
1113  printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
1114  frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1115  1000000 * (double)frame_cnt / (double)cx_time);
1116  vpx_img_free(&raw);
1117  // display average size, psnr
1118  vpx_svc_dump_statistics(&svc_ctx);
1119  vpx_svc_release(&svc_ctx);
1120  return EXIT_SUCCESS;
1121 }
vpx_fixed_buf_t twopass_stats
Definition: vpx_encoder.h:182
unsigned int ts_number_layers
Number of temporal coding layers.
Definition: vpx_encoder.h:644
Codec control function to set encoder internal speed settings.
Definition: vp8cx.h:155
#define VPX_MAX_LAYERS
Definition: vpx_encoder.h:43
int reference_alt_ref[5]
Definition: vp8cx.h:825
Image Descriptor.
Definition: vpx_image.h:71
Describes the encoder algorithm interface to applications.
const char * vpx_codec_iface_name(vpx_codec_iface_t *iface)
Return the name for a given interface.
Codec control function to constrain the inter-layer prediction (prediction of lower spatial resolutio...
Definition: vp8cx.h:616
const char * vpx_codec_err_to_string(vpx_codec_err_t err)
Convert error number to printable string.
int lst_fb_idx[5]
Definition: vp8cx.h:815
Codec control function to set content type.
Definition: vp8cx.h:460
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:343
Codec control function to set noise sensitivity.
Definition: vp8cx.h:418
unsigned int layer_target_bitrate[12]
Target bitrate for each spatial/temporal layer.
Definition: vpx_encoder.h:684
SVC_LAYER_DROP_MODE framedrop_mode
Definition: vp8cx.h:851
unsigned int g_input_bit_depth
Bit-depth of the input frames.
Definition: vpx_encoder.h:329
int den
Definition: vpx_encoder.h:220
Definition: vpx_encoder.h:148
int framedrop_thresh[5]
Definition: vp8cx.h:849
unsigned int kf_max_dist
Keyframe maximum interval.
Definition: vpx_encoder.h:614
unsigned int g_lag_in_frames
Allow lagged encoding.
Definition: vpx_encoder.h:372
Encoder configuration structure.
Definition: vpx_encoder.h:268
int reference_golden[5]
Definition: vp8cx.h:824
The coded data for this stream is corrupt or incomplete.
Definition: vpx_codec.h:130
Codec control function to set row level multi-threading.
Definition: vp8cx.h:567
Codec control function to set Max data rate for Intra frames.
Definition: vp8cx.h:254
Encoder output packet.
Definition: vpx_encoder.h:159
void * buf
Definition: vpx_encoder.h:97
unsigned int ts_rate_decimator[5]
Frame rate decimation factor for each temporal layer.
Definition: vpx_encoder.h:658
unsigned int kf_min_dist
Keyframe minimum interval.
Definition: vpx_encoder.h:605
Definition: vpx_encoder.h:226
vp9 svc frame dropping parameters.
Definition: vp8cx.h:848
unsigned int g_profile
Bitstream profile to use.
Definition: vpx_encoder.h:295
Definition: vpx_encoder.h:227
Codec control function to set number of tile columns.
Definition: vp8cx.h:348
struct vpx_codec_cx_pkt::@1::@2 frame
#define VPX_SS_MAX_LAYERS
Definition: vpx_encoder.h:46
vpx_image_t * vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
Definition: vpx_image.h:42
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:304
int reference_last[5]
Definition: vp8cx.h:823
int update_buffer_slot[5]
Definition: vp8cx.h:818
Codec control function to set adaptive quantization mode.
Definition: vp8cx.h:395
Codec control function to get svc layer ID.
Definition: vp8cx.h:468
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:313
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:160
unsigned int rc_dropframe_thresh
Temporal resampling configuration, if supported by the codec.
Definition: vpx_encoder.h:391
vp9 svc layer parameters
Definition: vp8cx.h:799
Operation completed without error.
Definition: vpx_codec.h:92
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.
unsigned int rc_target_bitrate
Target data rate.
Definition: vpx_encoder.h:460
#define VPX_DL_REALTIME
deadline parameter analogous to VPx REALTIME mode.
Definition: vpx_encoder.h:830
int num
Definition: vpx_encoder.h:219
Definition: vpx_codec.h:220
vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, unsigned int usage)
Get a default configuration.
Codec control function to set the frame flags and buffer indices for spatial layers....
Definition: vp8cx.h:542
enum vpx_enc_pass g_pass
Multi-pass Encoding Mode.
Definition: vpx_encoder.h:358
Codec control function to set mode and thresholds for frame dropping in SVC. Drop frame thresholds ar...
Definition: vp8cx.h:625
#define VPX_DL_GOOD_QUALITY
deadline parameter analogous to VPx GOOD QUALITY mode.
Definition: vpx_encoder.h:832
unsigned int ss_number_layers
Number of spatial coding layers.
Definition: vpx_encoder.h:624
vpx_bit_depth_t g_bit_depth
Bit-depth of the codec.
Definition: vpx_encoder.h:321
Provides definitions for using VP8 or VP9 encoder algorithm within the vpx Codec Interface.
Bypass mode. Used when application needs to control temporal layering. This will only work when the n...
Definition: vp8cx.h:705
Definition: vp8cx.h:838
vpx_codec_err_t
Algorithm return codes.
Definition: vpx_codec.h:90
const vpx_codec_cx_pkt_t * vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter)
Encoded data iterator.
union vpx_codec_cx_pkt::@1 data
int temporal_layering_mode
Temporal layering mode indicating which temporal layering scheme to use.
Definition: vpx_encoder.h:693
vpx_fixed_buf_t rc_twopass_stats_in
Two-pass stats buffer.
Definition: vpx_encoder.h:447
Definition: vpx_image.h:46
int max_consec_drop
Definition: vp8cx.h:852
Definition: vpx_encoder.h:234
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition: vpx_codec.h:404
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
Destroy a codec instance.
size_t sz
Definition: vpx_encoder.h:98
Definition: vpx_codec.h:218
vp9 svc frame flag parameters.
Definition: vp8cx.h:814
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:185
int64_t duration[5]
Definition: vp8cx.h:826
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:116
Definition: vpx_codec.h:219
int alt_fb_idx[5]
Definition: vp8cx.h:817
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:187
Definition: vpx_encoder.h:147
unsigned int rc_2pass_vbr_maxsection_pct
Two-pass mode per-GOP maximum bitrate.
Definition: vpx_encoder.h:577
vpx_codec_er_flags_t g_error_resilient
Enable error resilient modes.
Definition: vpx_encoder.h:351
unsigned int rc_2pass_vbr_minsection_pct
Two-pass mode per-GOP minimum bitrate.
Definition: vpx_encoder.h:570
int gld_fb_idx[5]
Definition: vp8cx.h:816
Codec control function to set svc layer for spatial and temporal.
Definition: vp8cx.h:450
enum vpx_rc_mode rc_end_usage
Rate control algorithm to use.
Definition: vpx_encoder.h:440
Definition: vpx_encoder.h:225
Codec context structure.
Definition: vpx_codec.h:197