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 vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
543  uint64_t sizes[8], int *count) {
544  // A chunk ending with a byte matching 0xc0 is an invalid chunk unless
545  // it is a super frame index. If the last byte of real video compression
546  // data is 0xc0 the encoder must add a 0 byte. If we have the marker but
547  // not the associated matching marker byte at the front of the index we have
548  // an invalid bitstream and need to return an error.
549 
550  uint8_t marker;
551 
552  marker = *(data + data_sz - 1);
553  *count = 0;
554 
555  if ((marker & 0xe0) == 0xc0) {
556  const uint32_t frames = (marker & 0x7) + 1;
557  const uint32_t mag = ((marker >> 3) & 0x3) + 1;
558  const size_t index_sz = 2 + mag * frames;
559 
560  // This chunk is marked as having a superframe index but doesn't have
561  // enough data for it, thus it's an invalid superframe index.
562  if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
563 
564  {
565  const uint8_t marker2 = *(data + data_sz - index_sz);
566 
567  // This chunk is marked as having a superframe index but doesn't have
568  // the matching marker byte at the front of the index therefore it's an
569  // invalid chunk.
570  if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
571  }
572 
573  {
574  // Found a valid superframe index.
575  uint32_t i, j;
576  const uint8_t *x = &data[data_sz - index_sz + 1];
577 
578  for (i = 0; i < frames; ++i) {
579  uint32_t this_sz = 0;
580 
581  for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
582  sizes[i] = this_sz;
583  }
584  *count = frames;
585  }
586  }
587  return VPX_CODEC_OK;
588 }
589 #endif
590 
591 // Example pattern for spatial layers and 2 temporal layers used in the
592 // bypass/flexible mode. The pattern corresponds to the pattern
593 // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
594 // non-flexible mode.
595 static void set_frame_flags_bypass_mode_ex0(
596  int tl, int num_spatial_layers, int is_key_frame,
597  vpx_svc_ref_frame_config_t *ref_frame_config) {
598  int sl;
599  for (sl = 0; sl < num_spatial_layers; ++sl)
600  ref_frame_config->update_buffer_slot[sl] = 0;
601 
602  for (sl = 0; sl < num_spatial_layers; ++sl) {
603  // Set the buffer idx.
604  if (tl == 0) {
605  ref_frame_config->lst_fb_idx[sl] = sl;
606  if (sl) {
607  if (is_key_frame) {
608  ref_frame_config->lst_fb_idx[sl] = sl - 1;
609  ref_frame_config->gld_fb_idx[sl] = sl;
610  } else {
611  ref_frame_config->gld_fb_idx[sl] = sl - 1;
612  }
613  } else {
614  ref_frame_config->gld_fb_idx[sl] = 0;
615  }
616  ref_frame_config->alt_fb_idx[sl] = 0;
617  } else if (tl == 1) {
618  ref_frame_config->lst_fb_idx[sl] = sl;
619  ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
620  ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
621  }
622  // Set the reference and update flags.
623  if (!tl) {
624  if (!sl) {
625  // Base spatial and base temporal (sl = 0, tl = 0)
626  ref_frame_config->reference_last[sl] = 1;
627  ref_frame_config->reference_golden[sl] = 0;
628  ref_frame_config->reference_alt_ref[sl] = 0;
629  ref_frame_config->update_buffer_slot[sl] |=
630  1 << ref_frame_config->lst_fb_idx[sl];
631  } else {
632  if (is_key_frame) {
633  ref_frame_config->reference_last[sl] = 1;
634  ref_frame_config->reference_golden[sl] = 0;
635  ref_frame_config->reference_alt_ref[sl] = 0;
636  ref_frame_config->update_buffer_slot[sl] |=
637  1 << ref_frame_config->gld_fb_idx[sl];
638  } else {
639  // Non-zero spatiall layer.
640  ref_frame_config->reference_last[sl] = 1;
641  ref_frame_config->reference_golden[sl] = 1;
642  ref_frame_config->reference_alt_ref[sl] = 1;
643  ref_frame_config->update_buffer_slot[sl] |=
644  1 << ref_frame_config->lst_fb_idx[sl];
645  }
646  }
647  } else if (tl == 1) {
648  if (!sl) {
649  // Base spatial and top temporal (tl = 1)
650  ref_frame_config->reference_last[sl] = 1;
651  ref_frame_config->reference_golden[sl] = 0;
652  ref_frame_config->reference_alt_ref[sl] = 0;
653  ref_frame_config->update_buffer_slot[sl] |=
654  1 << ref_frame_config->alt_fb_idx[sl];
655  } else {
656  // Non-zero spatial.
657  if (sl < num_spatial_layers - 1) {
658  ref_frame_config->reference_last[sl] = 1;
659  ref_frame_config->reference_golden[sl] = 1;
660  ref_frame_config->reference_alt_ref[sl] = 0;
661  ref_frame_config->update_buffer_slot[sl] |=
662  1 << ref_frame_config->alt_fb_idx[sl];
663  } else if (sl == num_spatial_layers - 1) {
664  // Top spatial and top temporal (non-reference -- doesn't update any
665  // reference buffers)
666  ref_frame_config->reference_last[sl] = 1;
667  ref_frame_config->reference_golden[sl] = 1;
668  ref_frame_config->reference_alt_ref[sl] = 0;
669  }
670  }
671  }
672  }
673 }
674 
675 // Example pattern for 2 spatial layers and 2 temporal layers used in the
676 // bypass/flexible mode, except only 1 spatial layer when temporal_layer_id = 1.
677 static void set_frame_flags_bypass_mode_ex1(
678  int tl, int num_spatial_layers, int is_key_frame,
679  vpx_svc_ref_frame_config_t *ref_frame_config) {
680  int sl;
681  for (sl = 0; sl < num_spatial_layers; ++sl)
682  ref_frame_config->update_buffer_slot[sl] = 0;
683 
684  if (tl == 0) {
685  if (is_key_frame) {
686  ref_frame_config->lst_fb_idx[1] = 0;
687  ref_frame_config->gld_fb_idx[1] = 1;
688  } else {
689  ref_frame_config->lst_fb_idx[1] = 1;
690  ref_frame_config->gld_fb_idx[1] = 0;
691  }
692  ref_frame_config->alt_fb_idx[1] = 0;
693 
694  ref_frame_config->lst_fb_idx[0] = 0;
695  ref_frame_config->gld_fb_idx[0] = 0;
696  ref_frame_config->alt_fb_idx[0] = 0;
697  }
698  if (tl == 1) {
699  ref_frame_config->lst_fb_idx[0] = 0;
700  ref_frame_config->gld_fb_idx[0] = 1;
701  ref_frame_config->alt_fb_idx[0] = 2;
702 
703  ref_frame_config->lst_fb_idx[1] = 1;
704  ref_frame_config->gld_fb_idx[1] = 2;
705  ref_frame_config->alt_fb_idx[1] = 3;
706  }
707  // Set the reference and update flags.
708  if (tl == 0) {
709  // Base spatial and base temporal (sl = 0, tl = 0)
710  ref_frame_config->reference_last[0] = 1;
711  ref_frame_config->reference_golden[0] = 0;
712  ref_frame_config->reference_alt_ref[0] = 0;
713  ref_frame_config->update_buffer_slot[0] |=
714  1 << ref_frame_config->lst_fb_idx[0];
715 
716  if (is_key_frame) {
717  ref_frame_config->reference_last[1] = 1;
718  ref_frame_config->reference_golden[1] = 0;
719  ref_frame_config->reference_alt_ref[1] = 0;
720  ref_frame_config->update_buffer_slot[1] |=
721  1 << ref_frame_config->gld_fb_idx[1];
722  } else {
723  // Non-zero spatiall layer.
724  ref_frame_config->reference_last[1] = 1;
725  ref_frame_config->reference_golden[1] = 1;
726  ref_frame_config->reference_alt_ref[1] = 1;
727  ref_frame_config->update_buffer_slot[1] |=
728  1 << ref_frame_config->lst_fb_idx[1];
729  }
730  }
731  if (tl == 1) {
732  // Top spatial and top temporal (non-reference -- doesn't update any
733  // reference buffers)
734  ref_frame_config->reference_last[1] = 1;
735  ref_frame_config->reference_golden[1] = 0;
736  ref_frame_config->reference_alt_ref[1] = 0;
737  }
738 }
739 
740 int main(int argc, const char **argv) {
741  AppInput app_input;
742  VpxVideoWriter *writer = NULL;
743  VpxVideoInfo info;
744  vpx_codec_ctx_t codec;
745  vpx_codec_enc_cfg_t enc_cfg;
746  SvcContext svc_ctx;
747  vpx_svc_frame_drop_t svc_drop_frame;
748  uint32_t i;
749  uint32_t frame_cnt = 0;
750  vpx_image_t raw;
751  vpx_codec_err_t res;
752  int pts = 0; /* PTS starts at 0 */
753  int frame_duration = 1; /* 1 timebase tick per frame */
754  FILE *infile = NULL;
755  int end_of_stream = 0;
756  int frames_received = 0;
757 #if OUTPUT_RC_STATS
758  VpxVideoWriter *outfile[VPX_SS_MAX_LAYERS] = { NULL };
759  struct RateControlStats rc;
760  vpx_svc_layer_id_t layer_id;
761  vpx_svc_ref_frame_config_t ref_frame_config;
762  unsigned int sl, tl;
763  double sum_bitrate = 0.0;
764  double sum_bitrate2 = 0.0;
765  double framerate = 30.0;
766 #endif
767  struct vpx_usec_timer timer;
768  int64_t cx_time = 0;
769  memset(&svc_ctx, 0, sizeof(svc_ctx));
770  memset(&app_input, 0, sizeof(AppInput));
771  memset(&info, 0, sizeof(VpxVideoInfo));
772  memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
773  memset(&rc, 0, sizeof(struct RateControlStats));
774  exec_name = argv[0];
775  parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
776 
777 // Allocate image buffer
778 #if CONFIG_VP9_HIGHBITDEPTH
779  if (!vpx_img_alloc(&raw,
780  enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
781  : VPX_IMG_FMT_I42016,
782  enc_cfg.g_w, enc_cfg.g_h, 32)) {
783  die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
784  }
785 #else
786  if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) {
787  die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
788  }
789 #endif // CONFIG_VP9_HIGHBITDEPTH
790 
791  if (!(infile = fopen(app_input.input_filename, "rb")))
792  die("Failed to open %s for reading\n", app_input.input_filename);
793 
794  // Initialize codec
795  if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) !=
796  VPX_CODEC_OK)
797  die("Failed to initialize encoder\n");
798 
799 #if OUTPUT_RC_STATS
800  rc.window_count = 1;
801  rc.window_size = 15; // Silence a static analysis warning.
802  rc.avg_st_encoding_bitrate = 0.0;
803  rc.variance_st_encoding_bitrate = 0.0;
804  if (svc_ctx.output_rc_stat) {
805  set_rate_control_stats(&rc, &enc_cfg);
806  framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
807  }
808 #endif
809 
810  info.codec_fourcc = VP9_FOURCC;
811  info.time_base.numerator = enc_cfg.g_timebase.num;
812  info.time_base.denominator = enc_cfg.g_timebase.den;
813 
814  if (!(app_input.passes == 2 && app_input.pass == 1)) {
815  // We don't save the bitstream for the 1st pass on two pass rate control
816  writer =
817  vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info);
818  if (!writer)
819  die("Failed to open %s for writing\n", app_input.output_filename);
820  }
821 #if OUTPUT_RC_STATS
822  // Write out spatial layer stream.
823  // TODO(marpan/jianj): allow for writing each spatial and temporal stream.
824  if (svc_ctx.output_rc_stat) {
825  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
826  char file_name[PATH_MAX];
827 
828  snprintf(file_name, sizeof(file_name), "%s_s%d.ivf",
829  app_input.output_filename, sl);
830  outfile[sl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
831  if (!outfile[sl]) die("Failed to open %s for writing", file_name);
832  }
833  }
834 #endif
835 
836  // skip initial frames
837  for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
838 
839  if (svc_ctx.speed != -1)
840  vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
841  if (svc_ctx.threads) {
842  vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(svc_ctx.threads));
843  if (svc_ctx.threads > 1)
845  else
847  }
848  if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
850  if (svc_ctx.speed >= 5)
853 
855  app_input.inter_layer_pred);
856 
858 
859  vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, app_input.tune_content);
860 
861  svc_drop_frame.framedrop_mode = FULL_SUPERFRAME_DROP;
862  for (sl = 0; sl < (unsigned int)svc_ctx.spatial_layers; ++sl)
863  svc_drop_frame.framedrop_thresh[sl] = enc_cfg.rc_dropframe_thresh;
864  svc_drop_frame.max_consec_drop = INT_MAX;
865  vpx_codec_control(&codec, VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
866 
867  // Encode frames
868  while (!end_of_stream) {
869  vpx_codec_iter_t iter = NULL;
870  const vpx_codec_cx_pkt_t *cx_pkt;
871  // Example patterns for bypass/flexible mode:
872  // example_pattern = 0: 2 temporal layers, and spatial_layers = 1,2,3. Exact
873  // to fixed SVC patterns. example_pattern = 1: 2 spatial and 2 temporal
874  // layers, with SL0 only has TL0, and SL1 has both TL0 and TL1. This example
875  // uses the extended API.
876  int example_pattern = 0;
877  if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) {
878  // We need one extra vpx_svc_encode call at end of stream to flush
879  // encoder and get remaining data
880  end_of_stream = 1;
881  }
882 
883  // For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
884  // and the buffer indices for each spatial layer of the current
885  // (super)frame to be encoded. The spatial and temporal layer_id for the
886  // current frame also needs to be set.
887  // TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
888  // mode to "VP9E_LAYERING_MODE_BYPASS".
889  if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
890  layer_id.spatial_layer_id = 0;
891  // Example for 2 temporal layers.
892  if (frame_cnt % 2 == 0) {
893  layer_id.temporal_layer_id = 0;
894  for (i = 0; i < VPX_SS_MAX_LAYERS; i++)
895  layer_id.temporal_layer_id_per_spatial[i] = 0;
896  } else {
897  layer_id.temporal_layer_id = 1;
898  for (i = 0; i < VPX_SS_MAX_LAYERS; i++)
899  layer_id.temporal_layer_id_per_spatial[i] = 1;
900  }
901  if (example_pattern == 1) {
902  // example_pattern 1 is hard-coded for 2 spatial and 2 temporal layers.
903  assert(svc_ctx.spatial_layers == 2);
904  assert(svc_ctx.temporal_layers == 2);
905  if (frame_cnt % 2 == 0) {
906  // Spatial layer 0 and 1 are encoded.
907  layer_id.temporal_layer_id_per_spatial[0] = 0;
908  layer_id.temporal_layer_id_per_spatial[1] = 0;
909  layer_id.spatial_layer_id = 0;
910  } else {
911  // Only spatial layer 1 is encoded here.
912  layer_id.temporal_layer_id_per_spatial[1] = 1;
913  layer_id.spatial_layer_id = 1;
914  }
915  }
916  vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
917  // TODO(jianj): Fix the parameter passing for "is_key_frame" in
918  // set_frame_flags_bypass_model() for case of periodic key frames.
919  if (example_pattern == 0) {
920  set_frame_flags_bypass_mode_ex0(layer_id.temporal_layer_id,
921  svc_ctx.spatial_layers, frame_cnt == 0,
922  &ref_frame_config);
923  } else if (example_pattern == 1) {
924  set_frame_flags_bypass_mode_ex1(layer_id.temporal_layer_id,
925  svc_ctx.spatial_layers, frame_cnt == 0,
926  &ref_frame_config);
927  }
928  ref_frame_config.duration[0] = frame_duration * 1;
929  ref_frame_config.duration[1] = frame_duration * 1;
930 
932  &ref_frame_config);
933  // Keep track of input frames, to account for frame drops in rate control
934  // stats/metrics.
935  for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
936  ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
937  layer_id.temporal_layer_id];
938  }
939  } else {
940  // For the fixed pattern SVC, temporal layer is given by superframe count.
941  unsigned int tl = 0;
942  if (enc_cfg.ts_number_layers == 2)
943  tl = (frame_cnt % 2 != 0);
944  else if (enc_cfg.ts_number_layers == 3) {
945  if (frame_cnt % 2 != 0) tl = 2;
946  if ((frame_cnt > 1) && ((frame_cnt - 2) % 4 == 0)) tl = 1;
947  }
948  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl)
949  ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + tl];
950  }
951 
952  vpx_usec_timer_start(&timer);
953  res = vpx_svc_encode(
954  &svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
955  svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
956  vpx_usec_timer_mark(&timer);
957  cx_time += vpx_usec_timer_elapsed(&timer);
958 
959  fflush(stdout);
960  if (res != VPX_CODEC_OK) {
961  die_codec(&codec, "Failed to encode frame");
962  }
963 
964  while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
965  switch (cx_pkt->kind) {
966  case VPX_CODEC_CX_FRAME_PKT: {
967  SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
968  if (cx_pkt->data.frame.sz > 0) {
969 #if OUTPUT_RC_STATS
970  uint64_t sizes[8];
971  uint64_t sizes_parsed[8];
972  int count = 0;
973  vp9_zero(sizes);
974  vp9_zero(sizes_parsed);
975 #endif
976  vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
977  cx_pkt->data.frame.sz,
978  cx_pkt->data.frame.pts);
979 #if OUTPUT_RC_STATS
980  // TODO(marpan): Put this (to line728) in separate function.
981  if (svc_ctx.output_rc_stat) {
982  int num_layers_encoded = 0;
983  vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
984  parse_superframe_index(cx_pkt->data.frame.buf,
985  cx_pkt->data.frame.sz, sizes_parsed,
986  &count);
987  if (enc_cfg.ss_number_layers == 1)
988  sizes[0] = cx_pkt->data.frame.sz;
989  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
990  sizes[sl] = 0;
991  if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
992  sizes[sl] = sizes_parsed[num_layers_encoded];
993  num_layers_encoded++;
994  }
995  }
996  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
997  unsigned int sl2;
998  uint64_t tot_size = 0;
999  for (sl2 = 0; sl2 <= sl; ++sl2) {
1000  if (cx_pkt->data.frame.spatial_layer_encoded[sl2])
1001  tot_size += sizes[sl2];
1002  }
1003  if (tot_size > 0)
1004  vpx_video_writer_write_frame(
1005  outfile[sl], cx_pkt->data.frame.buf, (size_t)(tot_size),
1006  cx_pkt->data.frame.pts);
1007  }
1008  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1009  if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
1010  for (tl = layer_id.temporal_layer_id;
1011  tl < enc_cfg.ts_number_layers; ++tl) {
1012  const int layer = sl * enc_cfg.ts_number_layers + tl;
1013  ++rc.layer_tot_enc_frames[layer];
1014  rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
1015  // Keep count of rate control stats per layer, for non-key
1016  // frames.
1017  if (tl == (unsigned int)layer_id.temporal_layer_id &&
1018  !(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
1019  rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
1020  rc.layer_avg_rate_mismatch[layer] +=
1021  fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
1022  rc.layer_pfb[layer];
1023  ++rc.layer_enc_frames[layer];
1024  }
1025  }
1026  }
1027  }
1028 
1029  // Update for short-time encoding bitrate states, for moving
1030  // window of size rc->window, shifted by rc->window / 2.
1031  // Ignore first window segment, due to key frame.
1032  if (frame_cnt > (unsigned int)rc.window_size) {
1033  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1034  if (cx_pkt->data.frame.spatial_layer_encoded[sl])
1035  sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
1036  }
1037  if (frame_cnt % rc.window_size == 0) {
1038  rc.window_count += 1;
1039  rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
1040  rc.variance_st_encoding_bitrate +=
1041  (sum_bitrate / rc.window_size) *
1042  (sum_bitrate / rc.window_size);
1043  sum_bitrate = 0.0;
1044  }
1045  }
1046 
1047  // Second shifted window.
1048  if (frame_cnt >
1049  (unsigned int)(rc.window_size + rc.window_size / 2)) {
1050  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1051  sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
1052  }
1053 
1054  if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
1055  frame_cnt % rc.window_size == 0) {
1056  rc.window_count += 1;
1057  rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
1058  rc.variance_st_encoding_bitrate +=
1059  (sum_bitrate2 / rc.window_size) *
1060  (sum_bitrate2 / rc.window_size);
1061  sum_bitrate2 = 0.0;
1062  }
1063  }
1064  }
1065 #endif
1066  }
1067  /*
1068  printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
1069  !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
1070  (int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
1071  */
1072  if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
1073  si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
1074  ++frames_received;
1075  break;
1076  }
1077  case VPX_CODEC_STATS_PKT: {
1078  stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf,
1079  cx_pkt->data.twopass_stats.sz);
1080  break;
1081  }
1082  default: { break; }
1083  }
1084  }
1085 
1086  if (!end_of_stream) {
1087  ++frame_cnt;
1088  pts += frame_duration;
1089  }
1090  }
1091 
1092  printf("Processed %d frames\n", frame_cnt);
1093  fclose(infile);
1094 #if OUTPUT_RC_STATS
1095  if (svc_ctx.output_rc_stat) {
1096  printout_rate_control_summary(&rc, &enc_cfg, frame_cnt);
1097  printf("\n");
1098  }
1099 #endif
1100  if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
1101  if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
1102  if (writer) {
1103  vpx_video_writer_close(writer);
1104  }
1105 #if OUTPUT_RC_STATS
1106  if (svc_ctx.output_rc_stat) {
1107  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
1108  vpx_video_writer_close(outfile[sl]);
1109  }
1110  }
1111 #endif
1112  printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
1113  frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1114  1000000 * (double)frame_cnt / (double)cx_time);
1115  vpx_img_free(&raw);
1116  // display average size, psnr
1117  vpx_svc_dump_statistics(&svc_ctx);
1118  vpx_svc_release(&svc_ctx);
1119  return EXIT_SUCCESS;
1120 }
vpx_fixed_buf_t twopass_stats
Definition: vpx_encoder.h:188
unsigned int ts_number_layers
Number of temporal coding layers.
Definition: vpx_encoder.h:660
Codec control function to set encoder internal speed settings.
Definition: vp8cx.h:155
#define VPX_MAX_LAYERS
Definition: vpx_encoder.h:46
int reference_alt_ref[5]
Definition: vp8cx.h:812
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:613
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:802
Codec control function to set content type.
Definition: vp8cx.h:457
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:354
Codec control function to set noise sensitivity.
Definition: vp8cx.h:415
unsigned int layer_target_bitrate[12]
Target bitrate for each spatial/temporal layer.
Definition: vpx_encoder.h:700
SVC_LAYER_DROP_MODE framedrop_mode
Definition: vp8cx.h:838
unsigned int g_input_bit_depth
Bit-depth of the input frames.
Definition: vpx_encoder.h:340
int den
Definition: vpx_encoder.h:228
Definition: vpx_encoder.h:154
int framedrop_thresh[5]
Definition: vp8cx.h:836
unsigned int kf_max_dist
Keyframe maximum interval.
Definition: vpx_encoder.h:630
unsigned int g_lag_in_frames
Allow lagged encoding.
Definition: vpx_encoder.h:383
Encoder configuration structure.
Definition: vpx_encoder.h:276
int reference_golden[5]
Definition: vp8cx.h:811
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:564
Codec control function to set Max data rate for Intra frames.
Definition: vp8cx.h:251
Encoder output packet.
Definition: vpx_encoder.h:165
void * buf
Definition: vpx_encoder.h:103
unsigned int ts_rate_decimator[5]
Frame rate decimation factor for each temporal layer.
Definition: vpx_encoder.h:674
unsigned int kf_min_dist
Keyframe minimum interval.
Definition: vpx_encoder.h:621
Definition: vpx_encoder.h:234
vp9 svc frame dropping parameters.
Definition: vp8cx.h:835
unsigned int g_profile
Bitstream profile to use.
Definition: vpx_encoder.h:306
Definition: vpx_encoder.h:235
Codec control function to set number of tile columns.
Definition: vp8cx.h:345
struct vpx_codec_cx_pkt::@1::@2 frame
#define VPX_SS_MAX_LAYERS
Definition: vpx_encoder.h:52
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:315
int reference_last[5]
Definition: vp8cx.h:810
int update_buffer_slot[5]
Definition: vp8cx.h:805
Codec control function to set adaptive quantization mode.
Definition: vp8cx.h:392
Codec control function to get svc layer ID.
Definition: vp8cx.h:465
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:324
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:166
unsigned int rc_dropframe_thresh
Temporal resampling configuration, if supported by the codec.
Definition: vpx_encoder.h:405
vp9 svc layer parameters
Definition: vp8cx.h:786
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:474
#define VPX_DL_REALTIME
deadline parameter analogous to VPx REALTIME mode.
Definition: vpx_encoder.h:846
int num
Definition: vpx_encoder.h:227
Definition: vpx_codec.h:220
Codec control function to set the frame flags and buffer indices for spatial layers. The frame flags and buffer indices are set using the struct vpx_svc_ref_frame_config defined below.
Definition: vp8cx.h:539
enum vpx_enc_pass g_pass
Multi-pass Encoding Mode.
Definition: vpx_encoder.h:369
Codec control function to set mode and thresholds for frame dropping in SVC. Drop frame thresholds ar...
Definition: vp8cx.h:622
#define VPX_DL_GOOD_QUALITY
deadline parameter analogous to VPx GOOD QUALITY mode.
Definition: vpx_encoder.h:848
unsigned int ss_number_layers
Number of spatial coding layers.
Definition: vpx_encoder.h:640
vpx_bit_depth_t g_bit_depth
Bit-depth of the codec.
Definition: vpx_encoder.h:332
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:692
Definition: vp8cx.h:825
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:709
vpx_fixed_buf_t rc_twopass_stats_in
Two-pass stats buffer.
Definition: vpx_encoder.h:461
vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, unsigned int reserved)
Get a default configuration.
int max_consec_drop
Definition: vp8cx.h:839
Definition: vpx_encoder.h:242
#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:104
Definition: vpx_codec.h:218
vp9 svc frame flag parameters.
Definition: vp8cx.h:801
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:182
int64_t duration[5]
Definition: vp8cx.h:813
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:122
Definition: vpx_codec.h:219
int alt_fb_idx[5]
Definition: vp8cx.h:804
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:187
Definition: vpx_encoder.h:153
unsigned int rc_2pass_vbr_maxsection_pct
Two-pass mode per-GOP maximum bitrate.
Definition: vpx_encoder.h:593
vpx_codec_er_flags_t g_error_resilient
Enable error resilient modes.
Definition: vpx_encoder.h:362
unsigned int rc_2pass_vbr_minsection_pct
Two-pass mode per-GOP minimum bitrate.
Definition: vpx_encoder.h:586
int gld_fb_idx[5]
Definition: vp8cx.h:803
Codec control function to set svc layer for spatial and temporal.
Definition: vp8cx.h:447
enum vpx_rc_mode rc_end_usage
Rate control algorithm to use.
Definition: vpx_encoder.h:454
Definition: vpx_encoder.h:233
Codec context structure.
Definition: vpx_codec.h:197