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