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 "vpx/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 
90 #if CONFIG_VP9_HIGHBITDEPTH
91 static const struct arg_enum_list bitdepth_enum[] = {
92  { "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 }
93 };
94 
95 static const arg_def_t bitdepth_arg = ARG_DEF_ENUM(
96  "d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ", bitdepth_enum);
97 #endif // CONFIG_VP9_HIGHBITDEPTH
98 
99 static const arg_def_t *svc_args[] = { &frames_arg,
100  &width_arg,
101  &height_arg,
102  &timebase_arg,
103  &bitrate_arg,
104  &skip_frames_arg,
105  &spatial_layers_arg,
106  &kf_dist_arg,
107  &scale_factors_arg,
108  &passes_arg,
109  &pass_arg,
110  &fpf_name_arg,
111  &min_q_arg,
112  &max_q_arg,
113  &min_bitrate_arg,
114  &max_bitrate_arg,
115  &temporal_layers_arg,
116  &temporal_layering_mode_arg,
117  &lag_in_frame_arg,
118  &threads_arg,
119  &aqmode_arg,
120 #if OUTPUT_RC_STATS
121  &output_rc_stats_arg,
122 #endif
123 
124 #if CONFIG_VP9_HIGHBITDEPTH
125  &bitdepth_arg,
126 #endif
127  &speed_arg,
128  &rc_end_usage_arg,
129  &bitrates_arg,
130  NULL };
131 
132 static const uint32_t default_frames_to_skip = 0;
133 static const uint32_t default_frames_to_code = 60 * 60;
134 static const uint32_t default_width = 1920;
135 static const uint32_t default_height = 1080;
136 static const uint32_t default_timebase_num = 1;
137 static const uint32_t default_timebase_den = 60;
138 static const uint32_t default_bitrate = 1000;
139 static const uint32_t default_spatial_layers = 5;
140 static const uint32_t default_temporal_layers = 1;
141 static const uint32_t default_kf_dist = 100;
142 static const uint32_t default_temporal_layering_mode = 0;
143 static const uint32_t default_output_rc_stats = 0;
144 static const int32_t default_speed = -1; // -1 means use library default.
145 static const uint32_t default_threads = 0; // zero means use library default.
146 
147 typedef struct {
148  const char *input_filename;
149  const char *output_filename;
150  uint32_t frames_to_code;
151  uint32_t frames_to_skip;
152  struct VpxInputContext input_ctx;
153  stats_io_t rc_stats;
154  int passes;
155  int pass;
156 } AppInput;
157 
158 static const char *exec_name;
159 
160 void usage_exit(void) {
161  fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
162  exec_name);
163  fprintf(stderr, "Options:\n");
164  arg_show_usage(stderr, svc_args);
165  exit(EXIT_FAILURE);
166 }
167 
168 static void parse_command_line(int argc, const char **argv_,
169  AppInput *app_input, SvcContext *svc_ctx,
170  vpx_codec_enc_cfg_t *enc_cfg) {
171  struct arg arg;
172  char **argv = NULL;
173  char **argi = NULL;
174  char **argj = NULL;
175  vpx_codec_err_t res;
176  int passes = 0;
177  int pass = 0;
178  const char *fpf_file_name = NULL;
179  unsigned int min_bitrate = 0;
180  unsigned int max_bitrate = 0;
181  char string_options[1024] = { 0 };
182 
183  // initialize SvcContext with parameters that will be passed to vpx_svc_init
184  svc_ctx->log_level = SVC_LOG_DEBUG;
185  svc_ctx->spatial_layers = default_spatial_layers;
186  svc_ctx->temporal_layers = default_temporal_layers;
187  svc_ctx->temporal_layering_mode = default_temporal_layering_mode;
188 #if OUTPUT_RC_STATS
189  svc_ctx->output_rc_stat = default_output_rc_stats;
190 #endif
191  svc_ctx->speed = default_speed;
192  svc_ctx->threads = default_threads;
193 
194  // start with default encoder configuration
195  res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
196  if (res) {
197  die("Failed to get config: %s\n", vpx_codec_err_to_string(res));
198  }
199  // update enc_cfg with app default values
200  enc_cfg->g_w = default_width;
201  enc_cfg->g_h = default_height;
202  enc_cfg->g_timebase.num = default_timebase_num;
203  enc_cfg->g_timebase.den = default_timebase_den;
204  enc_cfg->rc_target_bitrate = default_bitrate;
205  enc_cfg->kf_min_dist = default_kf_dist;
206  enc_cfg->kf_max_dist = default_kf_dist;
207  enc_cfg->rc_end_usage = VPX_CQ;
208 
209  // initialize AppInput with default values
210  app_input->frames_to_code = default_frames_to_code;
211  app_input->frames_to_skip = default_frames_to_skip;
212 
213  // process command line options
214  argv = argv_dup(argc - 1, argv_ + 1);
215  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
216  arg.argv_step = 1;
217 
218  if (arg_match(&arg, &frames_arg, argi)) {
219  app_input->frames_to_code = arg_parse_uint(&arg);
220  } else if (arg_match(&arg, &width_arg, argi)) {
221  enc_cfg->g_w = arg_parse_uint(&arg);
222  } else if (arg_match(&arg, &height_arg, argi)) {
223  enc_cfg->g_h = arg_parse_uint(&arg);
224  } else if (arg_match(&arg, &timebase_arg, argi)) {
225  enc_cfg->g_timebase = arg_parse_rational(&arg);
226  } else if (arg_match(&arg, &bitrate_arg, argi)) {
227  enc_cfg->rc_target_bitrate = arg_parse_uint(&arg);
228  } else if (arg_match(&arg, &skip_frames_arg, argi)) {
229  app_input->frames_to_skip = arg_parse_uint(&arg);
230  } else if (arg_match(&arg, &spatial_layers_arg, argi)) {
231  svc_ctx->spatial_layers = arg_parse_uint(&arg);
232  } else if (arg_match(&arg, &temporal_layers_arg, argi)) {
233  svc_ctx->temporal_layers = arg_parse_uint(&arg);
234 #if OUTPUT_RC_STATS
235  } else if (arg_match(&arg, &output_rc_stats_arg, argi)) {
236  svc_ctx->output_rc_stat = arg_parse_uint(&arg);
237 #endif
238  } else if (arg_match(&arg, &speed_arg, argi)) {
239  svc_ctx->speed = arg_parse_uint(&arg);
240  } else if (arg_match(&arg, &aqmode_arg, argi)) {
241  svc_ctx->aqmode = arg_parse_uint(&arg);
242  } else if (arg_match(&arg, &threads_arg, argi)) {
243  svc_ctx->threads = arg_parse_uint(&arg);
244  } else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
245  svc_ctx->temporal_layering_mode = enc_cfg->temporal_layering_mode =
246  arg_parse_int(&arg);
247  if (svc_ctx->temporal_layering_mode) {
248  enc_cfg->g_error_resilient = 1;
249  }
250  } else if (arg_match(&arg, &kf_dist_arg, argi)) {
251  enc_cfg->kf_min_dist = arg_parse_uint(&arg);
252  enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
253  } else if (arg_match(&arg, &scale_factors_arg, argi)) {
254  snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
255  string_options, arg.val);
256  } else if (arg_match(&arg, &bitrates_arg, argi)) {
257  snprintf(string_options, sizeof(string_options), "%s bitrates=%s",
258  string_options, arg.val);
259  } else if (arg_match(&arg, &passes_arg, argi)) {
260  passes = arg_parse_uint(&arg);
261  if (passes < 1 || passes > 2) {
262  die("Error: Invalid number of passes (%d)\n", passes);
263  }
264  } else if (arg_match(&arg, &pass_arg, argi)) {
265  pass = arg_parse_uint(&arg);
266  if (pass < 1 || pass > 2) {
267  die("Error: Invalid pass selected (%d)\n", pass);
268  }
269  } else if (arg_match(&arg, &fpf_name_arg, argi)) {
270  fpf_file_name = arg.val;
271  } else if (arg_match(&arg, &min_q_arg, argi)) {
272  snprintf(string_options, sizeof(string_options), "%s min-quantizers=%s",
273  string_options, arg.val);
274  } else if (arg_match(&arg, &max_q_arg, argi)) {
275  snprintf(string_options, sizeof(string_options), "%s max-quantizers=%s",
276  string_options, arg.val);
277  } else if (arg_match(&arg, &min_bitrate_arg, argi)) {
278  min_bitrate = arg_parse_uint(&arg);
279  } else if (arg_match(&arg, &max_bitrate_arg, argi)) {
280  max_bitrate = arg_parse_uint(&arg);
281  } else if (arg_match(&arg, &lag_in_frame_arg, argi)) {
282  enc_cfg->g_lag_in_frames = arg_parse_uint(&arg);
283  } else if (arg_match(&arg, &rc_end_usage_arg, argi)) {
284  enc_cfg->rc_end_usage = arg_parse_uint(&arg);
285 #if CONFIG_VP9_HIGHBITDEPTH
286  } else if (arg_match(&arg, &bitdepth_arg, argi)) {
287  enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg);
288  switch (enc_cfg->g_bit_depth) {
289  case VPX_BITS_8:
290  enc_cfg->g_input_bit_depth = 8;
291  enc_cfg->g_profile = 0;
292  break;
293  case VPX_BITS_10:
294  enc_cfg->g_input_bit_depth = 10;
295  enc_cfg->g_profile = 2;
296  break;
297  case VPX_BITS_12:
298  enc_cfg->g_input_bit_depth = 12;
299  enc_cfg->g_profile = 2;
300  break;
301  default:
302  die("Error: Invalid bit depth selected (%d)\n", enc_cfg->g_bit_depth);
303  break;
304  }
305 #endif // CONFIG_VP9_HIGHBITDEPTH
306  } else {
307  ++argj;
308  }
309  }
310 
311  // There will be a space in front of the string options
312  if (strlen(string_options) > 0)
313  vpx_svc_set_options(svc_ctx, string_options + 1);
314 
315  if (passes == 0 || passes == 1) {
316  if (pass) {
317  fprintf(stderr, "pass is ignored since there's only one pass\n");
318  }
319  enc_cfg->g_pass = VPX_RC_ONE_PASS;
320  } else {
321  if (pass == 0) {
322  die("pass must be specified when passes is 2\n");
323  }
324 
325  if (fpf_file_name == NULL) {
326  die("fpf must be specified when passes is 2\n");
327  }
328 
329  if (pass == 1) {
330  enc_cfg->g_pass = VPX_RC_FIRST_PASS;
331  if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 0)) {
332  fatal("Failed to open statistics store");
333  }
334  } else {
335  enc_cfg->g_pass = VPX_RC_LAST_PASS;
336  if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 1)) {
337  fatal("Failed to open statistics store");
338  }
339  enc_cfg->rc_twopass_stats_in = stats_get(&app_input->rc_stats);
340  }
341  app_input->passes = passes;
342  app_input->pass = pass;
343  }
344 
345  if (enc_cfg->rc_target_bitrate > 0) {
346  if (min_bitrate > 0) {
347  enc_cfg->rc_2pass_vbr_minsection_pct =
348  min_bitrate * 100 / enc_cfg->rc_target_bitrate;
349  }
350  if (max_bitrate > 0) {
351  enc_cfg->rc_2pass_vbr_maxsection_pct =
352  max_bitrate * 100 / enc_cfg->rc_target_bitrate;
353  }
354  }
355 
356  // Check for unrecognized options
357  for (argi = argv; *argi; ++argi)
358  if (argi[0][0] == '-' && strlen(argi[0]) > 1)
359  die("Error: Unrecognized option %s\n", *argi);
360 
361  if (argv[0] == NULL || argv[1] == 0) {
362  usage_exit();
363  }
364  app_input->input_filename = argv[0];
365  app_input->output_filename = argv[1];
366  free(argv);
367 
368  if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 ||
369  enc_cfg->g_h % 2)
370  die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h);
371 
372  printf(
373  "Codec %s\nframes: %d, skip: %d\n"
374  "layers: %d\n"
375  "width %d, height: %d,\n"
376  "num: %d, den: %d, bitrate: %d,\n"
377  "gop size: %d\n",
378  vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
379  app_input->frames_to_skip, svc_ctx->spatial_layers, enc_cfg->g_w,
380  enc_cfg->g_h, enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
381  enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
382 }
383 
384 #if OUTPUT_RC_STATS
385 // For rate control encoding stats.
386 struct RateControlStats {
387  // Number of input frames per layer.
388  int layer_input_frames[VPX_MAX_LAYERS];
389  // Total (cumulative) number of encoded frames per layer.
390  int layer_tot_enc_frames[VPX_MAX_LAYERS];
391  // Number of encoded non-key frames per layer.
392  int layer_enc_frames[VPX_MAX_LAYERS];
393  // Framerate per layer (cumulative).
394  double layer_framerate[VPX_MAX_LAYERS];
395  // Target average frame size per layer (per-frame-bandwidth per layer).
396  double layer_pfb[VPX_MAX_LAYERS];
397  // Actual average frame size per layer.
398  double layer_avg_frame_size[VPX_MAX_LAYERS];
399  // Average rate mismatch per layer (|target - actual| / target).
400  double layer_avg_rate_mismatch[VPX_MAX_LAYERS];
401  // Actual encoding bitrate per layer (cumulative).
402  double layer_encoding_bitrate[VPX_MAX_LAYERS];
403  // Average of the short-time encoder actual bitrate.
404  // TODO(marpan): Should we add these short-time stats for each layer?
405  double avg_st_encoding_bitrate;
406  // Variance of the short-time encoder actual bitrate.
407  double variance_st_encoding_bitrate;
408  // Window (number of frames) for computing short-time encoding bitrate.
409  int window_size;
410  // Number of window measurements.
411  int window_count;
412 };
413 
414 // Note: these rate control stats assume only 1 key frame in the
415 // sequence (i.e., first frame only).
416 static void set_rate_control_stats(struct RateControlStats *rc,
417  vpx_codec_enc_cfg_t *cfg) {
418  unsigned int sl, tl;
419  // Set the layer (cumulative) framerate and the target layer (non-cumulative)
420  // per-frame-bandwidth, for the rate control encoding stats below.
421  const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
422 
423  for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
424  for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
425  const int layer = sl * cfg->ts_number_layers + tl;
426  if (cfg->ts_number_layers == 1)
427  rc->layer_framerate[layer] = framerate;
428  else
429  rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
430  if (tl > 0) {
431  rc->layer_pfb[layer] =
432  1000.0 *
433  (cfg->layer_target_bitrate[layer] -
434  cfg->layer_target_bitrate[layer - 1]) /
435  (rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
436  } else {
437  rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] /
438  rc->layer_framerate[layer];
439  }
440  rc->layer_input_frames[layer] = 0;
441  rc->layer_enc_frames[layer] = 0;
442  rc->layer_tot_enc_frames[layer] = 0;
443  rc->layer_encoding_bitrate[layer] = 0.0;
444  rc->layer_avg_frame_size[layer] = 0.0;
445  rc->layer_avg_rate_mismatch[layer] = 0.0;
446  }
447  }
448  rc->window_count = 0;
449  rc->window_size = 15;
450  rc->avg_st_encoding_bitrate = 0.0;
451  rc->variance_st_encoding_bitrate = 0.0;
452 }
453 
454 static void printout_rate_control_summary(struct RateControlStats *rc,
455  vpx_codec_enc_cfg_t *cfg,
456  int frame_cnt) {
457  unsigned int sl, tl;
458  double perc_fluctuation = 0.0;
459  int tot_num_frames = 0;
460  printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
461  printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
463  for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
464  tot_num_frames = 0;
465  for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
466  const int layer = sl * cfg->ts_number_layers + tl;
467  const int num_dropped =
468  (tl > 0)
469  ? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
470  : (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
471  1);
472  tot_num_frames += rc->layer_input_frames[layer];
473  rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
474  rc->layer_encoding_bitrate[layer] /
475  tot_num_frames;
476  rc->layer_avg_frame_size[layer] =
477  rc->layer_avg_frame_size[layer] / rc->layer_enc_frames[layer];
478  rc->layer_avg_rate_mismatch[layer] = 100.0 *
479  rc->layer_avg_rate_mismatch[layer] /
480  rc->layer_enc_frames[layer];
481  printf("For layer#: sl%d tl%d \n", sl, tl);
482  printf("Bitrate (target vs actual): %d %f.0 kbps\n",
483  cfg->layer_target_bitrate[layer],
484  rc->layer_encoding_bitrate[layer]);
485  printf("Average frame size (target vs actual): %f %f bits\n",
486  rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
487  printf("Average rate_mismatch: %f\n", rc->layer_avg_rate_mismatch[layer]);
488  printf(
489  "Number of input frames, encoded (non-key) frames, "
490  "and percent dropped frames: %d %d %f.0 \n",
491  rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
492  100.0 * num_dropped / rc->layer_input_frames[layer]);
493  printf("\n");
494  }
495  }
496  rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count;
497  rc->variance_st_encoding_bitrate =
498  rc->variance_st_encoding_bitrate / rc->window_count -
499  (rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate);
500  perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) /
501  rc->avg_st_encoding_bitrate;
502  printf("Short-time stats, for window of %d frames: \n", rc->window_size);
503  printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
504  rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
505  perc_fluctuation);
506  printf("Num of input, num of encoded (super) frames: %d %d \n", frame_cnt,
507  tot_num_frames);
508 }
509 
510 vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
511  uint64_t sizes[8], int *count) {
512  // A chunk ending with a byte matching 0xc0 is an invalid chunk unless
513  // it is a super frame index. If the last byte of real video compression
514  // data is 0xc0 the encoder must add a 0 byte. If we have the marker but
515  // not the associated matching marker byte at the front of the index we have
516  // an invalid bitstream and need to return an error.
517 
518  uint8_t marker;
519 
520  marker = *(data + data_sz - 1);
521  *count = 0;
522 
523  if ((marker & 0xe0) == 0xc0) {
524  const uint32_t frames = (marker & 0x7) + 1;
525  const uint32_t mag = ((marker >> 3) & 0x3) + 1;
526  const size_t index_sz = 2 + mag * frames;
527 
528  // This chunk is marked as having a superframe index but doesn't have
529  // enough data for it, thus it's an invalid superframe index.
530  if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
531 
532  {
533  const uint8_t marker2 = *(data + data_sz - index_sz);
534 
535  // This chunk is marked as having a superframe index but doesn't have
536  // the matching marker byte at the front of the index therefore it's an
537  // invalid chunk.
538  if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
539  }
540 
541  {
542  // Found a valid superframe index.
543  uint32_t i, j;
544  const uint8_t *x = &data[data_sz - index_sz + 1];
545 
546  for (i = 0; i < frames; ++i) {
547  uint32_t this_sz = 0;
548 
549  for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
550  sizes[i] = this_sz;
551  }
552  *count = frames;
553  }
554  }
555  return VPX_CODEC_OK;
556 }
557 #endif
558 
559 // Example pattern for spatial layers and 2 temporal layers used in the
560 // bypass/flexible mode. The pattern corresponds to the pattern
561 // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
562 // non-flexible mode.
563 void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
564  int is_key_frame,
565  vpx_svc_ref_frame_config_t *ref_frame_config) {
566  int sl;
567  for (sl = 0; sl < num_spatial_layers; ++sl) {
568  if (!tl) {
569  if (!sl) {
570  ref_frame_config->frame_flags[sl] =
573  } else {
574  if (is_key_frame) {
575  ref_frame_config->frame_flags[sl] =
578  } else {
579  ref_frame_config->frame_flags[sl] =
581  }
582  }
583  } else if (tl == 1) {
584  if (!sl) {
585  ref_frame_config->frame_flags[sl] =
588  } else {
589  ref_frame_config->frame_flags[sl] =
591  if (sl == num_spatial_layers - 1)
592  ref_frame_config->frame_flags[sl] =
595  }
596  }
597  if (tl == 0) {
598  ref_frame_config->lst_fb_idx[sl] = sl;
599  if (sl) {
600  if (is_key_frame) {
601  ref_frame_config->lst_fb_idx[sl] = sl - 1;
602  ref_frame_config->gld_fb_idx[sl] = sl;
603  } else {
604  ref_frame_config->gld_fb_idx[sl] = sl - 1;
605  }
606  } else {
607  ref_frame_config->gld_fb_idx[sl] = 0;
608  }
609  ref_frame_config->alt_fb_idx[sl] = 0;
610  } else if (tl == 1) {
611  ref_frame_config->lst_fb_idx[sl] = sl;
612  ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
613  ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
614  }
615  }
616 }
617 
618 int main(int argc, const char **argv) {
619  AppInput app_input;
620  VpxVideoWriter *writer = NULL;
621  VpxVideoInfo info;
622  vpx_codec_ctx_t codec;
623  vpx_codec_enc_cfg_t enc_cfg;
624  SvcContext svc_ctx;
625  uint32_t i;
626  uint32_t frame_cnt = 0;
627  vpx_image_t raw;
628  vpx_codec_err_t res;
629  int pts = 0; /* PTS starts at 0 */
630  int frame_duration = 1; /* 1 timebase tick per frame */
631  FILE *infile = NULL;
632  int end_of_stream = 0;
633  int frames_received = 0;
634 #if OUTPUT_RC_STATS
635  VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
636  struct RateControlStats rc;
637  vpx_svc_layer_id_t layer_id;
638  vpx_svc_ref_frame_config_t ref_frame_config;
639  unsigned int sl, tl;
640  double sum_bitrate = 0.0;
641  double sum_bitrate2 = 0.0;
642  double framerate = 30.0;
643 #endif
644  struct vpx_usec_timer timer;
645  int64_t cx_time = 0;
646  memset(&svc_ctx, 0, sizeof(svc_ctx));
647  exec_name = argv[0];
648  parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
649 
650 // Allocate image buffer
651 #if CONFIG_VP9_HIGHBITDEPTH
652  if (!vpx_img_alloc(&raw,
653  enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
654  : VPX_IMG_FMT_I42016,
655  enc_cfg.g_w, enc_cfg.g_h, 32)) {
656  die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
657  }
658 #else
659  if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) {
660  die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
661  }
662 #endif // CONFIG_VP9_HIGHBITDEPTH
663 
664  if (!(infile = fopen(app_input.input_filename, "rb")))
665  die("Failed to open %s for reading\n", app_input.input_filename);
666 
667  // Initialize codec
668  if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) !=
669  VPX_CODEC_OK)
670  die("Failed to initialize encoder\n");
671 
672 #if OUTPUT_RC_STATS
673  rc.window_count = 1;
674  rc.window_size = 15; // Silence a static analysis warning.
675  rc.avg_st_encoding_bitrate = 0.0;
676  rc.variance_st_encoding_bitrate = 0.0;
677  if (svc_ctx.output_rc_stat) {
678  set_rate_control_stats(&rc, &enc_cfg);
679  framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
680  }
681 #endif
682 
683  info.codec_fourcc = VP9_FOURCC;
684  info.time_base.numerator = enc_cfg.g_timebase.num;
685  info.time_base.denominator = enc_cfg.g_timebase.den;
686 
687  if (!(app_input.passes == 2 && app_input.pass == 1)) {
688  // We don't save the bitstream for the 1st pass on two pass rate control
689  writer =
690  vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info);
691  if (!writer)
692  die("Failed to open %s for writing\n", app_input.output_filename);
693  }
694 #if OUTPUT_RC_STATS
695  // For now, just write temporal layer streams.
696  // TODO(marpan): do spatial by re-writing superframe.
697  if (svc_ctx.output_rc_stat) {
698  for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
699  char file_name[PATH_MAX];
700 
701  snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
702  app_input.output_filename, tl);
703  outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
704  if (!outfile[tl]) die("Failed to open %s for writing", file_name);
705  }
706  }
707 #endif
708 
709  // skip initial frames
710  for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
711 
712  if (svc_ctx.speed != -1)
713  vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
714  if (svc_ctx.threads) {
715  vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
716  if (svc_ctx.threads > 1)
718  else
720  }
721  if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
723  if (svc_ctx.speed >= 5)
726 
728 
729  // Encode frames
730  while (!end_of_stream) {
731  vpx_codec_iter_t iter = NULL;
732  const vpx_codec_cx_pkt_t *cx_pkt;
733  if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) {
734  // We need one extra vpx_svc_encode call at end of stream to flush
735  // encoder and get remaining data
736  end_of_stream = 1;
737  }
738 
739  // For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
740  // and the buffer indices for each spatial layer of the current
741  // (super)frame to be encoded. The temporal layer_id for the current frame
742  // also needs to be set.
743  // TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
744  // mode to "VP9E_LAYERING_MODE_BYPASS".
745  if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
746  layer_id.spatial_layer_id = 0;
747  // Example for 2 temporal layers.
748  if (frame_cnt % 2 == 0)
749  layer_id.temporal_layer_id = 0;
750  else
751  layer_id.temporal_layer_id = 1;
752  // Note that we only set the temporal layer_id, since we are calling
753  // the encode for the whole superframe. The encoder will internally loop
754  // over all the spatial layers for the current superframe.
755  vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
756  // TODO(jianj): Fix the parameter passing for "is_key_frame" in
757  // set_frame_flags_bypass_model() for case of periodic key frames.
758  set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
759  svc_ctx.spatial_layers, frame_cnt == 0,
760  &ref_frame_config);
762  &ref_frame_config);
763  // Keep track of input frames, to account for frame drops in rate control
764  // stats/metrics.
765  for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
766  ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
767  layer_id.temporal_layer_id];
768  }
769  } else {
770  // For the fixed pattern SVC, temporal layer is given by superframe count.
771  unsigned int tl = 0;
772  if (enc_cfg.ts_number_layers == 2)
773  tl = (frame_cnt % 2 != 0);
774  else if (enc_cfg.ts_number_layers == 3) {
775  if (frame_cnt % 2 != 0) tl = 2;
776  if ((frame_cnt > 1) && ((frame_cnt - 2) % 4 == 0)) tl = 1;
777  }
778  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl)
779  ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + tl];
780  }
781 
782  vpx_usec_timer_start(&timer);
783  res = vpx_svc_encode(
784  &svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
785  svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
786  vpx_usec_timer_mark(&timer);
787  cx_time += vpx_usec_timer_elapsed(&timer);
788 
789  fflush(stdout);
790  if (res != VPX_CODEC_OK) {
791  die_codec(&codec, "Failed to encode frame");
792  }
793 
794  while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
795  switch (cx_pkt->kind) {
796  case VPX_CODEC_CX_FRAME_PKT: {
797  SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
798  if (cx_pkt->data.frame.sz > 0) {
799 #if OUTPUT_RC_STATS
800  uint64_t sizes[8];
801  uint64_t sizes_parsed[8];
802  int count = 0;
803  vp9_zero(sizes);
804  vp9_zero(sizes_parsed);
805 #endif
806  vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
807  cx_pkt->data.frame.sz,
808  cx_pkt->data.frame.pts);
809 #if OUTPUT_RC_STATS
810  // TODO(marpan): Put this (to line728) in separate function.
811  if (svc_ctx.output_rc_stat) {
812  vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
813  parse_superframe_index(cx_pkt->data.frame.buf,
814  cx_pkt->data.frame.sz, sizes_parsed,
815  &count);
816  if (enc_cfg.ss_number_layers == 1)
817  sizes[0] = cx_pkt->data.frame.sz;
818  if (svc_ctx.temporal_layering_mode !=
820  int num_layers_encoded = 0;
821  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
822  sizes[sl] = 0;
823  if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
824  sizes[sl] = sizes_parsed[num_layers_encoded];
825  num_layers_encoded++;
826  }
827  }
828  }
829  for (tl = layer_id.temporal_layer_id;
830  tl < enc_cfg.ts_number_layers; ++tl) {
831  vpx_video_writer_write_frame(
832  outfile[tl], cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
833  cx_pkt->data.frame.pts);
834  }
835 
836  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
837  if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
838  for (tl = layer_id.temporal_layer_id;
839  tl < enc_cfg.ts_number_layers; ++tl) {
840  const int layer = sl * enc_cfg.ts_number_layers + tl;
841  ++rc.layer_tot_enc_frames[layer];
842  rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
843  // Keep count of rate control stats per layer, for non-key
844  // frames.
845  if (tl == (unsigned int)layer_id.temporal_layer_id &&
846  !(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
847  rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
848  rc.layer_avg_rate_mismatch[layer] +=
849  fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
850  rc.layer_pfb[layer];
851  ++rc.layer_enc_frames[layer];
852  }
853  }
854  }
855  }
856 
857  // Update for short-time encoding bitrate states, for moving
858  // window of size rc->window, shifted by rc->window / 2.
859  // Ignore first window segment, due to key frame.
860  if (frame_cnt > (unsigned int)rc.window_size) {
861  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
862  if (cx_pkt->data.frame.spatial_layer_encoded[sl])
863  sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
864  }
865  if (frame_cnt % rc.window_size == 0) {
866  rc.window_count += 1;
867  rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
868  rc.variance_st_encoding_bitrate +=
869  (sum_bitrate / rc.window_size) *
870  (sum_bitrate / rc.window_size);
871  sum_bitrate = 0.0;
872  }
873  }
874 
875  // Second shifted window.
876  if (frame_cnt >
877  (unsigned int)(rc.window_size + rc.window_size / 2)) {
878  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
879  sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
880  }
881 
882  if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
883  frame_cnt % rc.window_size == 0) {
884  rc.window_count += 1;
885  rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
886  rc.variance_st_encoding_bitrate +=
887  (sum_bitrate2 / rc.window_size) *
888  (sum_bitrate2 / rc.window_size);
889  sum_bitrate2 = 0.0;
890  }
891  }
892  }
893 #endif
894  }
895  /*
896  printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
897  !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
898  (int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
899  */
900  if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
901  si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
902  ++frames_received;
903  break;
904  }
905  case VPX_CODEC_STATS_PKT: {
906  stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf,
907  cx_pkt->data.twopass_stats.sz);
908  break;
909  }
910  default: { break; }
911  }
912  }
913 
914  if (!end_of_stream) {
915  ++frame_cnt;
916  pts += frame_duration;
917  }
918  }
919 
920  // Compensate for the extra frame count for the bypass mode.
921  if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
922  for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
923  const int layer =
924  sl * enc_cfg.ts_number_layers + layer_id.temporal_layer_id;
925  --rc.layer_input_frames[layer];
926  }
927  }
928 
929  printf("Processed %d frames\n", frame_cnt);
930  fclose(infile);
931 #if OUTPUT_RC_STATS
932  if (svc_ctx.output_rc_stat) {
933  printout_rate_control_summary(&rc, &enc_cfg, frame_cnt);
934  printf("\n");
935  }
936 #endif
937  if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
938  if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
939  if (writer) {
940  vpx_video_writer_close(writer);
941  }
942 #if OUTPUT_RC_STATS
943  if (svc_ctx.output_rc_stat) {
944  for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
945  vpx_video_writer_close(outfile[tl]);
946  }
947  }
948 #endif
949  printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
950  frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
951  1000000 * (double)frame_cnt / (double)cx_time);
952  vpx_img_free(&raw);
953  // display average size, psnr
954  vpx_svc_dump_statistics(&svc_ctx);
955  vpx_svc_release(&svc_ctx);
956  return EXIT_SUCCESS;
957 }
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
#define VP8_EFLAG_NO_UPD_GF
Don&#39;t update the golden frame.
Definition: vp8cx.h:88
Image Descriptor.
Definition: vpx_image.h:88
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:761
#define VPX_TS_MAX_LAYERS
Definition: vpx_encoder.h:40
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:354
unsigned int layer_target_bitrate[12]
Target bitrate for each spatial/temporal layer.
Definition: vpx_encoder.h:700
#define VP8_EFLAG_NO_REF_GF
Don&#39;t reference the golden frame.
Definition: vp8cx.h:66
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
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
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
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
int frame_flags[5]
Definition: vp8cx.h:760
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:55
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:315
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
vp9 svc layer parameters
Definition: vp8cx.h:746
Operation completed without error.
Definition: vpx_codec.h:92
#define VP8_EFLAG_NO_UPD_LAST
Don&#39;t update the last frame.
Definition: vp8cx.h:81
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
#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:652
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.
Definition: vpx_encoder.h:242
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition: vpx_codec.h:404
#define VP8_EFLAG_NO_REF_ARF
Don&#39;t reference the alternate reference frame.
Definition: vp8cx.h:74
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:759
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:182
#define VPX_FRAME_IS_KEY
Definition: vpx_encoder.h:122
Definition: vpx_codec.h:219
int alt_fb_idx[5]
Definition: vp8cx.h:763
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
#define VP8_EFLAG_NO_UPD_ARF
Don&#39;t update the alternate reference frame.
Definition: vp8cx.h:95
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:762
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