WebM Codec SDK
vpxenc
1 /*
2  * Copyright (c) 2010 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 #include "./vpxenc.h"
12 #include "./vpx_config.h"
13 
14 #include <assert.h>
15 #include <limits.h>
16 #include <math.h>
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #if CONFIG_LIBYUV
23 #include "third_party/libyuv/include/libyuv/scale.h"
24 #endif
25 
26 #include "vpx/vpx_encoder.h"
27 #if CONFIG_DECODERS
28 #include "vpx/vpx_decoder.h"
29 #endif
30 
31 #include "./args.h"
32 #include "./ivfenc.h"
33 #include "./tools_common.h"
34 
35 #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
36 #include "vpx/vp8cx.h"
37 #endif
38 #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
39 #include "vpx/vp8dx.h"
40 #endif
41 
42 #include "vpx/vpx_integer.h"
43 #include "vpx_ports/mem_ops.h"
44 #include "vpx_ports/vpx_timer.h"
45 #include "./rate_hist.h"
46 #include "./vpxstats.h"
47 #include "./warnings.h"
48 #if CONFIG_WEBM_IO
49 #include "./webmenc.h"
50 #endif
51 #include "./y4minput.h"
52 
53 static size_t wrap_fwrite(const void *ptr, size_t size, size_t nmemb,
54  FILE *stream) {
55  return fwrite(ptr, size, nmemb, stream);
56 }
57 #define fwrite wrap_fwrite
58 
59 static const char *exec_name;
60 
61 static VPX_TOOLS_FORMAT_PRINTF(3, 0) void warn_or_exit_on_errorv(
62  vpx_codec_ctx_t *ctx, int fatal, const char *s, va_list ap) {
63  if (ctx->err) {
64  const char *detail = vpx_codec_error_detail(ctx);
65 
66  vfprintf(stderr, s, ap);
67  fprintf(stderr, ": %s\n", vpx_codec_error(ctx));
68 
69  if (detail) fprintf(stderr, " %s\n", detail);
70 
71  if (fatal) exit(EXIT_FAILURE);
72  }
73 }
74 
75 static VPX_TOOLS_FORMAT_PRINTF(2,
76  3) void ctx_exit_on_error(vpx_codec_ctx_t *ctx,
77  const char *s, ...) {
78  va_list ap;
79 
80  va_start(ap, s);
81  warn_or_exit_on_errorv(ctx, 1, s, ap);
82  va_end(ap);
83 }
84 
85 static VPX_TOOLS_FORMAT_PRINTF(3, 4) void warn_or_exit_on_error(
86  vpx_codec_ctx_t *ctx, int fatal, const char *s, ...) {
87  va_list ap;
88 
89  va_start(ap, s);
90  warn_or_exit_on_errorv(ctx, fatal, s, ap);
91  va_end(ap);
92 }
93 
94 static const arg_def_t help =
95  ARG_DEF(NULL, "help", 0, "Show usage options and exit");
96 static const arg_def_t debugmode =
97  ARG_DEF("D", "debug", 0, "Debug mode (makes output deterministic)");
98 static const arg_def_t outputfile =
99  ARG_DEF("o", "output", 1, "Output filename");
100 static const arg_def_t use_nv12 =
101  ARG_DEF(NULL, "nv12", 0, "Input file is NV12 ");
102 static const arg_def_t use_yv12 =
103  ARG_DEF(NULL, "yv12", 0, "Input file is YV12 ");
104 static const arg_def_t use_i420 =
105  ARG_DEF(NULL, "i420", 0, "Input file is I420 (default)");
106 static const arg_def_t use_i422 =
107  ARG_DEF(NULL, "i422", 0, "Input file is I422");
108 static const arg_def_t use_i444 =
109  ARG_DEF(NULL, "i444", 0, "Input file is I444");
110 static const arg_def_t use_i440 =
111  ARG_DEF(NULL, "i440", 0, "Input file is I440");
112 static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use");
113 static const arg_def_t passes =
114  ARG_DEF("p", "passes", 1, "Number of passes (1/2)");
115 static const arg_def_t pass_arg =
116  ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)");
117 static const arg_def_t fpf_name =
118  ARG_DEF(NULL, "fpf", 1, "First pass statistics file name");
119 static const arg_def_t limit =
120  ARG_DEF(NULL, "limit", 1, "Stop encoding after n input frames");
121 static const arg_def_t skip =
122  ARG_DEF(NULL, "skip", 1, "Skip the first n input frames");
123 static const arg_def_t deadline =
124  ARG_DEF("d", "deadline", 1, "Deadline per frame (usec)");
125 static const arg_def_t best_dl =
126  ARG_DEF(NULL, "best", 0, "Use Best Quality Deadline");
127 static const arg_def_t good_dl =
128  ARG_DEF(NULL, "good", 0, "Use Good Quality Deadline");
129 static const arg_def_t rt_dl =
130  ARG_DEF(NULL, "rt", 0, "Use Realtime Quality Deadline");
131 static const arg_def_t quietarg =
132  ARG_DEF("q", "quiet", 0, "Do not print encode progress");
133 static const arg_def_t verbosearg =
134  ARG_DEF("v", "verbose", 0, "Show encoder parameters");
135 static const arg_def_t psnrarg =
136  ARG_DEF(NULL, "psnr", 0, "Show PSNR in status line");
137 
138 static const struct arg_enum_list test_decode_enum[] = {
139  { "off", TEST_DECODE_OFF },
140  { "fatal", TEST_DECODE_FATAL },
141  { "warn", TEST_DECODE_WARN },
142  { NULL, 0 }
143 };
144 static const arg_def_t recontest = ARG_DEF_ENUM(
145  NULL, "test-decode", 1, "Test encode/decode mismatch", test_decode_enum);
146 static const arg_def_t framerate =
147  ARG_DEF(NULL, "fps", 1, "Stream frame rate (rate/scale)");
148 static const arg_def_t use_webm =
149  ARG_DEF(NULL, "webm", 0, "Output WebM (default when WebM IO is enabled)");
150 static const arg_def_t use_ivf = ARG_DEF(NULL, "ivf", 0, "Output IVF");
151 static const arg_def_t out_part =
152  ARG_DEF("P", "output-partitions", 0,
153  "Makes encoder output partitions. Requires IVF output!");
154 static const arg_def_t q_hist_n =
155  ARG_DEF(NULL, "q-hist", 1, "Show quantizer histogram (n-buckets)");
156 static const arg_def_t rate_hist_n =
157  ARG_DEF(NULL, "rate-hist", 1, "Show rate histogram (n-buckets)");
158 static const arg_def_t disable_warnings =
159  ARG_DEF(NULL, "disable-warnings", 0,
160  "Disable warnings about potentially incorrect encode settings.");
161 static const arg_def_t disable_warning_prompt =
162  ARG_DEF("y", "disable-warning-prompt", 0,
163  "Display warnings, but do not prompt user to continue.");
164 
165 #if CONFIG_VP9_HIGHBITDEPTH
166 static const arg_def_t test16bitinternalarg = ARG_DEF(
167  NULL, "test-16bit-internal", 0, "Force use of 16 bit internal buffer");
168 #endif
169 
170 static const arg_def_t *main_args[] = { &help,
171  &debugmode,
172  &outputfile,
173  &codecarg,
174  &passes,
175  &pass_arg,
176  &fpf_name,
177  &limit,
178  &skip,
179  &deadline,
180  &best_dl,
181  &good_dl,
182  &rt_dl,
183  &quietarg,
184  &verbosearg,
185  &psnrarg,
186  &use_webm,
187  &use_ivf,
188  &out_part,
189  &q_hist_n,
190  &rate_hist_n,
191  &disable_warnings,
192  &disable_warning_prompt,
193  &recontest,
194  NULL };
195 
196 static const arg_def_t usage =
197  ARG_DEF("u", "usage", 1, "Usage profile number to use");
198 static const arg_def_t threads =
199  ARG_DEF("t", "threads", 1, "Max number of threads to use");
200 static const arg_def_t profile =
201  ARG_DEF(NULL, "profile", 1, "Bitstream profile number to use");
202 static const arg_def_t width = ARG_DEF("w", "width", 1, "Frame width");
203 static const arg_def_t height = ARG_DEF("h", "height", 1, "Frame height");
204 #if CONFIG_WEBM_IO
205 static const struct arg_enum_list stereo_mode_enum[] = {
206  { "mono", STEREO_FORMAT_MONO },
207  { "left-right", STEREO_FORMAT_LEFT_RIGHT },
208  { "bottom-top", STEREO_FORMAT_BOTTOM_TOP },
209  { "top-bottom", STEREO_FORMAT_TOP_BOTTOM },
210  { "right-left", STEREO_FORMAT_RIGHT_LEFT },
211  { NULL, 0 }
212 };
213 static const arg_def_t stereo_mode = ARG_DEF_ENUM(
214  NULL, "stereo-mode", 1, "Stereo 3D video format", stereo_mode_enum);
215 #endif
216 static const arg_def_t timebase = ARG_DEF(
217  NULL, "timebase", 1, "Output timestamp precision (fractional seconds)");
218 static const arg_def_t error_resilient =
219  ARG_DEF(NULL, "error-resilient", 1, "Enable error resiliency features");
220 static const arg_def_t lag_in_frames =
221  ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag");
222 
223 static const arg_def_t *global_args[] = { &use_nv12,
224  &use_yv12,
225  &use_i420,
226  &use_i422,
227  &use_i444,
228  &use_i440,
229  &usage,
230  &threads,
231  &profile,
232  &width,
233  &height,
234 #if CONFIG_WEBM_IO
235  &stereo_mode,
236 #endif
237  &timebase,
238  &framerate,
239  &error_resilient,
240 #if CONFIG_VP9_HIGHBITDEPTH
241  &test16bitinternalarg,
242 #endif
243  &lag_in_frames,
244  NULL };
245 
246 static const arg_def_t dropframe_thresh =
247  ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
248 static const arg_def_t resize_allowed =
249  ARG_DEF(NULL, "resize-allowed", 1, "Spatial resampling enabled (bool)");
250 static const arg_def_t resize_width =
251  ARG_DEF(NULL, "resize-width", 1, "Width of encoded frame");
252 static const arg_def_t resize_height =
253  ARG_DEF(NULL, "resize-height", 1, "Height of encoded frame");
254 static const arg_def_t resize_up_thresh =
255  ARG_DEF(NULL, "resize-up", 1, "Upscale threshold (buf %)");
256 static const arg_def_t resize_down_thresh =
257  ARG_DEF(NULL, "resize-down", 1, "Downscale threshold (buf %)");
258 static const struct arg_enum_list end_usage_enum[] = { { "vbr", VPX_VBR },
259  { "cbr", VPX_CBR },
260  { "cq", VPX_CQ },
261  { "q", VPX_Q },
262  { NULL, 0 } };
263 static const arg_def_t end_usage =
264  ARG_DEF_ENUM(NULL, "end-usage", 1, "Rate control mode", end_usage_enum);
265 static const arg_def_t target_bitrate =
266  ARG_DEF(NULL, "target-bitrate", 1, "Bitrate (kbps)");
267 static const arg_def_t min_quantizer =
268  ARG_DEF(NULL, "min-q", 1, "Minimum (best) quantizer");
269 static const arg_def_t max_quantizer =
270  ARG_DEF(NULL, "max-q", 1, "Maximum (worst) quantizer");
271 static const arg_def_t undershoot_pct =
272  ARG_DEF(NULL, "undershoot-pct", 1, "Datarate undershoot (min) target (%)");
273 static const arg_def_t overshoot_pct =
274  ARG_DEF(NULL, "overshoot-pct", 1, "Datarate overshoot (max) target (%)");
275 static const arg_def_t buf_sz =
276  ARG_DEF(NULL, "buf-sz", 1, "Client buffer size (ms)");
277 static const arg_def_t buf_initial_sz =
278  ARG_DEF(NULL, "buf-initial-sz", 1, "Client initial buffer size (ms)");
279 static const arg_def_t buf_optimal_sz =
280  ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)");
281 static const arg_def_t *rc_args[] = {
282  &dropframe_thresh, &resize_allowed, &resize_width, &resize_height,
283  &resize_up_thresh, &resize_down_thresh, &end_usage, &target_bitrate,
284  &min_quantizer, &max_quantizer, &undershoot_pct, &overshoot_pct,
285  &buf_sz, &buf_initial_sz, &buf_optimal_sz, NULL
286 };
287 
288 #if CONFIG_VP9_ENCODER
289 static const arg_def_t use_vizier_rc_params =
290  ARG_DEF(NULL, "use-vizier-rc-params", 1, "Use vizier rc params");
291 static const arg_def_t active_wq_factor =
292  ARG_DEF(NULL, "active-wq-factor", 1, "Active worst quality factor");
293 static const arg_def_t err_per_mb_factor =
294  ARG_DEF(NULL, "err-per-mb-factor", 1, "Error per macroblock factor");
295 static const arg_def_t sr_default_decay_limit = ARG_DEF(
296  NULL, "sr-default-decay-limit", 1, "Second reference default decay limit");
297 static const arg_def_t sr_diff_factor =
298  ARG_DEF(NULL, "sr-diff-factor", 1, "Second reference diff factor");
299 static const arg_def_t kf_err_per_mb_factor = ARG_DEF(
300  NULL, "kf-err-per-mb-factor", 1, "Keyframe error per macroblock factor");
301 static const arg_def_t kf_frame_min_boost_factor =
302  ARG_DEF(NULL, "kf-frame-min-boost-factor", 1, "Keyframe min boost");
303 static const arg_def_t kf_frame_max_boost_first_factor =
304  ARG_DEF(NULL, "kf-frame-max-boost-first-factor", 1,
305  "Max keyframe boost adjustment factor for first frame");
306 static const arg_def_t kf_frame_max_boost_subs_factor =
307  ARG_DEF(NULL, "kf-frame-max-boost-subs-factor", 1,
308  "Max boost adjustment factor for subsequent KFs");
309 static const arg_def_t kf_max_total_boost_factor = ARG_DEF(
310  NULL, "kf-max-total-boost-factor", 1, "Keyframe max total boost factor");
311 static const arg_def_t gf_max_total_boost_factor =
312  ARG_DEF(NULL, "gf-max-total-boost-factor", 1,
313  "Golden frame max total boost factor");
314 static const arg_def_t gf_frame_max_boost_factor =
315  ARG_DEF(NULL, "gf-frame-max-boost-factor", 1,
316  "Golden frame max per frame boost factor");
317 static const arg_def_t zm_factor =
318  ARG_DEF(NULL, "zm-factor", 1, "Zero motion power factor");
319 static const arg_def_t rd_mult_inter_qp_fac =
320  ARG_DEF(NULL, "rd-mult-inter-qp-fac", 1,
321  "RD multiplier adjustment for inter frames");
322 static const arg_def_t rd_mult_arf_qp_fac =
323  ARG_DEF(NULL, "rd-mult-arf-qp-fac", 1,
324  "RD multiplier adjustment for alt-ref frames");
325 static const arg_def_t rd_mult_key_qp_fac = ARG_DEF(
326  NULL, "rd-mult-key-qp-fac", 1, "RD multiplier adjustment for key frames");
327 static const arg_def_t *vizier_rc_args[] = { &use_vizier_rc_params,
328  &active_wq_factor,
329  &err_per_mb_factor,
330  &sr_default_decay_limit,
331  &sr_diff_factor,
332  &kf_err_per_mb_factor,
333  &kf_frame_min_boost_factor,
334  &kf_frame_max_boost_first_factor,
335  &kf_frame_max_boost_subs_factor,
336  &kf_max_total_boost_factor,
337  &gf_max_total_boost_factor,
338  &gf_frame_max_boost_factor,
339  &zm_factor,
340  &rd_mult_inter_qp_fac,
341  &rd_mult_arf_qp_fac,
342  &rd_mult_key_qp_fac,
343  NULL };
344 #endif
345 
346 static const arg_def_t bias_pct =
347  ARG_DEF(NULL, "bias-pct", 1, "CBR/VBR bias (0=CBR, 100=VBR)");
348 static const arg_def_t minsection_pct =
349  ARG_DEF(NULL, "minsection-pct", 1, "GOP min bitrate (% of target)");
350 static const arg_def_t maxsection_pct =
351  ARG_DEF(NULL, "maxsection-pct", 1, "GOP max bitrate (% of target)");
352 static const arg_def_t corpus_complexity =
353  ARG_DEF(NULL, "corpus-complexity", 1, "corpus vbr complexity midpoint");
354 static const arg_def_t *rc_twopass_args[] = { &bias_pct, &minsection_pct,
355  &maxsection_pct,
356  &corpus_complexity, NULL };
357 
358 static const arg_def_t kf_min_dist =
359  ARG_DEF(NULL, "kf-min-dist", 1, "Minimum keyframe interval (frames)");
360 static const arg_def_t kf_max_dist =
361  ARG_DEF(NULL, "kf-max-dist", 1, "Maximum keyframe interval (frames)");
362 static const arg_def_t kf_disabled =
363  ARG_DEF(NULL, "disable-kf", 0, "Disable keyframe placement");
364 static const arg_def_t *kf_args[] = { &kf_min_dist, &kf_max_dist, &kf_disabled,
365  NULL };
366 
367 static const arg_def_t noise_sens =
368  ARG_DEF(NULL, "noise-sensitivity", 1, "Noise sensitivity (frames to blur)");
369 static const arg_def_t sharpness =
370  ARG_DEF(NULL, "sharpness", 1,
371  "Increase sharpness at the expense of lower PSNR. (0..7)");
372 static const arg_def_t static_thresh =
373  ARG_DEF(NULL, "static-thresh", 1, "Motion detection threshold");
374 static const arg_def_t arnr_maxframes =
375  ARG_DEF(NULL, "arnr-maxframes", 1, "AltRef max frames (0..15)");
376 static const arg_def_t arnr_strength =
377  ARG_DEF(NULL, "arnr-strength", 1, "AltRef filter strength (0..6)");
378 static const arg_def_t arnr_type =
379  ARG_DEF(NULL, "arnr-type", 1, "AltRef filter type (1..3)");
380 static const struct arg_enum_list tuning_enum[] = { { "psnr", VP8_TUNE_PSNR },
381  { "ssim", VP8_TUNE_SSIM },
382  { NULL, 0 } };
383 static const arg_def_t tune_ssim =
384  ARG_DEF_ENUM(NULL, "tune", 1, "Material to favor", tuning_enum);
385 static const arg_def_t cq_level =
386  ARG_DEF(NULL, "cq-level", 1, "Constant/Constrained Quality level");
387 static const arg_def_t max_intra_rate_pct =
388  ARG_DEF(NULL, "max-intra-rate", 1, "Max I-frame bitrate (pct)");
389 static const arg_def_t gf_cbr_boost_pct = ARG_DEF(
390  NULL, "gf-cbr-boost", 1, "Boost for Golden Frame in CBR mode (pct)");
391 
392 #if CONFIG_VP8_ENCODER
393 static const arg_def_t cpu_used_vp8 =
394  ARG_DEF(NULL, "cpu-used", 1, "CPU Used (-16..16)");
395 static const arg_def_t auto_altref_vp8 = ARG_DEF(
396  NULL, "auto-alt-ref", 1, "Enable automatic alt reference frames. (0..1)");
397 static const arg_def_t token_parts =
398  ARG_DEF(NULL, "token-parts", 1, "Number of token partitions to use, log2");
399 static const arg_def_t screen_content_mode =
400  ARG_DEF(NULL, "screen-content-mode", 1, "Screen content mode");
401 static const arg_def_t *vp8_args[] = { &cpu_used_vp8,
402  &auto_altref_vp8,
403  &noise_sens,
404  &sharpness,
405  &static_thresh,
406  &token_parts,
407  &arnr_maxframes,
408  &arnr_strength,
409  &arnr_type,
410  &tune_ssim,
411  &cq_level,
412  &max_intra_rate_pct,
413  &gf_cbr_boost_pct,
414  &screen_content_mode,
415  NULL };
416 static const int vp8_arg_ctrl_map[] = { VP8E_SET_CPUUSED,
430  0 };
431 #endif
432 
433 #if CONFIG_VP9_ENCODER
434 static const arg_def_t cpu_used_vp9 =
435  ARG_DEF(NULL, "cpu-used", 1, "CPU Used (-9..9)");
436 static const arg_def_t auto_altref_vp9 = ARG_DEF(
437  NULL, "auto-alt-ref", 1,
438  "Enable automatic alt reference frames, 2+ enables multi-layer. (0..6)");
439 static const arg_def_t tile_cols =
440  ARG_DEF(NULL, "tile-columns", 1, "Number of tile columns to use, log2");
441 static const arg_def_t tile_rows =
442  ARG_DEF(NULL, "tile-rows", 1,
443  "Number of tile rows to use, log2 (set to 0 while threads > 1)");
444 
445 static const arg_def_t enable_tpl_model =
446  ARG_DEF(NULL, "enable-tpl", 1, "Enable temporal dependency model");
447 
448 static const arg_def_t lossless =
449  ARG_DEF(NULL, "lossless", 1, "Lossless mode (0: false (default), 1: true)");
450 static const arg_def_t frame_parallel_decoding = ARG_DEF(
451  NULL, "frame-parallel", 1, "Enable frame parallel decodability features");
452 static const arg_def_t aq_mode = ARG_DEF(
453  NULL, "aq-mode", 1,
454  "Adaptive quantization mode (0: off (default), 1: variance 2: complexity, "
455  "3: cyclic refresh, 4: equator360)");
456 static const arg_def_t alt_ref_aq = ARG_DEF(NULL, "alt-ref-aq", 1,
457  "Special adaptive quantization for "
458  "the alternate reference frames.");
459 static const arg_def_t frame_periodic_boost =
460  ARG_DEF(NULL, "frame-boost", 1,
461  "Enable frame periodic boost (0: off (default), 1: on)");
462 static const arg_def_t max_inter_rate_pct =
463  ARG_DEF(NULL, "max-inter-rate", 1, "Max P-frame bitrate (pct)");
464 static const arg_def_t min_gf_interval = ARG_DEF(
465  NULL, "min-gf-interval", 1,
466  "min gf/arf frame interval (default 0, indicating in-built behavior)");
467 static const arg_def_t max_gf_interval = ARG_DEF(
468  NULL, "max-gf-interval", 1,
469  "max gf/arf frame interval (default 0, indicating in-built behavior)");
470 
471 static const struct arg_enum_list color_space_enum[] = {
472  { "unknown", VPX_CS_UNKNOWN },
473  { "bt601", VPX_CS_BT_601 },
474  { "bt709", VPX_CS_BT_709 },
475  { "smpte170", VPX_CS_SMPTE_170 },
476  { "smpte240", VPX_CS_SMPTE_240 },
477  { "bt2020", VPX_CS_BT_2020 },
478  { "reserved", VPX_CS_RESERVED },
479  { "sRGB", VPX_CS_SRGB },
480  { NULL, 0 }
481 };
482 
483 static const arg_def_t input_color_space =
484  ARG_DEF_ENUM(NULL, "color-space", 1,
485  "The color space of input content:", color_space_enum);
486 
487 #if CONFIG_VP9_HIGHBITDEPTH
488 static const struct arg_enum_list bitdepth_enum[] = {
489  { "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 }
490 };
491 
492 static const arg_def_t bitdeptharg = ARG_DEF_ENUM(
493  "b", "bit-depth", 1,
494  "Bit depth for codec (8 for version <=1, 10 or 12 for version 2)",
495  bitdepth_enum);
496 static const arg_def_t inbitdeptharg =
497  ARG_DEF(NULL, "input-bit-depth", 1, "Bit depth of input");
498 #endif
499 
500 static const struct arg_enum_list tune_content_enum[] = {
501  { "default", VP9E_CONTENT_DEFAULT },
502  { "screen", VP9E_CONTENT_SCREEN },
503  { "film", VP9E_CONTENT_FILM },
504  { NULL, 0 }
505 };
506 
507 static const arg_def_t tune_content = ARG_DEF_ENUM(
508  NULL, "tune-content", 1, "Tune content type", tune_content_enum);
509 
510 static const arg_def_t target_level = ARG_DEF(
511  NULL, "target-level", 1,
512  "Target level\n"
513  " 255: off (default)\n"
514  " 0: only keep level stats\n"
515  " 1: adaptively set alt-ref "
516  "distance and column tile limit based on picture size, and keep"
517  " level stats\n"
518  " 10: level 1.0 11: level 1.1 "
519  "... 62: level 6.2");
520 
521 static const arg_def_t row_mt =
522  ARG_DEF(NULL, "row-mt", 1,
523  "Enable row based non-deterministic multi-threading in VP9");
524 
525 static const arg_def_t disable_loopfilter =
526  ARG_DEF(NULL, "disable-loopfilter", 1,
527  "Control Loopfilter in VP9\n"
528  "0: Loopfilter on for all frames (default)\n"
529  "1: Loopfilter off for non reference frames\n"
530  "2: Loopfilter off for all frames");
531 #endif
532 
533 #if CONFIG_VP9_ENCODER
534 static const arg_def_t *vp9_args[] = { &cpu_used_vp9,
535  &auto_altref_vp9,
536  &sharpness,
537  &static_thresh,
538  &tile_cols,
539  &tile_rows,
540  &enable_tpl_model,
541  &arnr_maxframes,
542  &arnr_strength,
543  &arnr_type,
544  &tune_ssim,
545  &cq_level,
546  &max_intra_rate_pct,
547  &max_inter_rate_pct,
548  &gf_cbr_boost_pct,
549  &lossless,
550  &frame_parallel_decoding,
551  &aq_mode,
552  &alt_ref_aq,
553  &frame_periodic_boost,
554  &noise_sens,
555  &tune_content,
556  &input_color_space,
557  &min_gf_interval,
558  &max_gf_interval,
559  &target_level,
560  &row_mt,
561  &disable_loopfilter,
562 // NOTE: The entries above have a corresponding entry in vp9_arg_ctrl_map. The
563 // entries below do not have a corresponding entry in vp9_arg_ctrl_map. They
564 // must be listed at the end of vp9_args.
565 #if CONFIG_VP9_HIGHBITDEPTH
566  &bitdeptharg,
567  &inbitdeptharg,
568 #endif // CONFIG_VP9_HIGHBITDEPTH
569  NULL };
570 static const int vp9_arg_ctrl_map[] = { VP8E_SET_CPUUSED,
576  VP9E_SET_TPL,
598  0 };
599 #endif
600 
601 static const arg_def_t *no_args[] = { NULL };
602 
603 static void show_help(FILE *fout, int shorthelp) {
604  int i;
605  const int num_encoder = get_vpx_encoder_count();
606 
607  fprintf(fout, "Usage: %s <options> -o dst_filename src_filename \n",
608  exec_name);
609 
610  if (shorthelp) {
611  fprintf(fout, "Use --help to see the full list of options.\n");
612  return;
613  }
614 
615  fprintf(fout, "\nOptions:\n");
616  arg_show_usage(fout, main_args);
617  fprintf(fout, "\nEncoder Global Options:\n");
618  arg_show_usage(fout, global_args);
619  fprintf(fout, "\nRate Control Options:\n");
620  arg_show_usage(fout, rc_args);
621  fprintf(fout, "\nTwopass Rate Control Options:\n");
622  arg_show_usage(fout, rc_twopass_args);
623  fprintf(fout, "\nKeyframe Placement Options:\n");
624  arg_show_usage(fout, kf_args);
625 #if CONFIG_VP8_ENCODER
626  fprintf(fout, "\nVP8 Specific Options:\n");
627  arg_show_usage(fout, vp8_args);
628 #endif
629 #if CONFIG_VP9_ENCODER
630  fprintf(fout, "\nVP9 Specific Options:\n");
631  arg_show_usage(fout, vp9_args);
632  fprintf(fout, "\nVizier Rate Control Options:\n");
633  arg_show_usage(fout, vizier_rc_args);
634 #endif
635  fprintf(fout,
636  "\nStream timebase (--timebase):\n"
637  " The desired precision of timestamps in the output, expressed\n"
638  " in fractional seconds. Default is 1/1000.\n");
639  fprintf(fout, "\nIncluded encoders:\n\n");
640 
641  for (i = 0; i < num_encoder; ++i) {
642  const VpxInterface *const encoder = get_vpx_encoder_by_index(i);
643  const char *defstr = (i == (num_encoder - 1)) ? "(default)" : "";
644  fprintf(fout, " %-6s - %s %s\n", encoder->name,
645  vpx_codec_iface_name(encoder->codec_interface()), defstr);
646  }
647  fprintf(fout, "\n ");
648  fprintf(fout, "Use --codec to switch to a non-default encoder.\n\n");
649 }
650 
651 void usage_exit(void) {
652  show_help(stderr, 1);
653  exit(EXIT_FAILURE);
654 }
655 
656 #define NELEMENTS(x) (sizeof(x) / sizeof(x[0]))
657 #if CONFIG_VP9_ENCODER
658 #define ARG_CTRL_CNT_MAX NELEMENTS(vp9_arg_ctrl_map)
659 #else
660 #define ARG_CTRL_CNT_MAX NELEMENTS(vp8_arg_ctrl_map)
661 #endif
662 
663 #if !CONFIG_WEBM_IO
664 typedef int stereo_format_t;
665 struct WebmOutputContext {
666  int debug;
667 };
668 #endif
669 
670 /* Per-stream configuration */
671 struct stream_config {
672  struct vpx_codec_enc_cfg cfg;
673  const char *out_fn;
674  const char *stats_fn;
675  stereo_format_t stereo_fmt;
676  int arg_ctrls[ARG_CTRL_CNT_MAX][2];
677  int arg_ctrl_cnt;
678  int write_webm;
679 #if CONFIG_VP9_HIGHBITDEPTH
680  // whether to use 16bit internal buffers
681  int use_16bit_internal;
682 #endif
683 };
684 
685 struct stream_state {
686  int index;
687  struct stream_state *next;
688  struct stream_config config;
689  FILE *file;
690  struct rate_hist *rate_hist;
691  struct WebmOutputContext webm_ctx;
692  uint64_t psnr_sse_total;
693  uint64_t psnr_samples_total;
694  double psnr_totals[4];
695  int psnr_count;
696  int counts[64];
697  vpx_codec_ctx_t encoder;
698  unsigned int frames_out;
699  uint64_t cx_time;
700  size_t nbytes;
701  stats_io_t stats;
702  struct vpx_image *img;
703  vpx_codec_ctx_t decoder;
704  int mismatch_seen;
705 };
706 
707 static void validate_positive_rational(const char *msg,
708  struct vpx_rational *rat) {
709  if (rat->den < 0) {
710  rat->num *= -1;
711  rat->den *= -1;
712  }
713 
714  if (rat->num < 0) die("Error: %s must be positive\n", msg);
715 
716  if (!rat->den) die("Error: %s has zero denominator\n", msg);
717 }
718 
719 static void parse_global_config(struct VpxEncoderConfig *global, char **argv) {
720  char **argi, **argj;
721  struct arg arg;
722  const int num_encoder = get_vpx_encoder_count();
723 
724  if (num_encoder < 1) die("Error: no valid encoder available\n");
725 
726  /* Initialize default parameters */
727  memset(global, 0, sizeof(*global));
728  global->codec = get_vpx_encoder_by_index(num_encoder - 1);
729  global->passes = 0;
730  global->color_type = I420;
731  /* Assign default deadline to good quality */
732  global->deadline = VPX_DL_GOOD_QUALITY;
733 
734  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
735  arg.argv_step = 1;
736 
737  if (arg_match(&arg, &help, argi)) {
738  show_help(stdout, 0);
739  exit(EXIT_SUCCESS);
740  } else if (arg_match(&arg, &codecarg, argi)) {
741  global->codec = get_vpx_encoder_by_name(arg.val);
742  if (!global->codec)
743  die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
744  } else if (arg_match(&arg, &passes, argi)) {
745  global->passes = arg_parse_uint(&arg);
746 
747  if (global->passes < 1 || global->passes > 2)
748  die("Error: Invalid number of passes (%d)\n", global->passes);
749  } else if (arg_match(&arg, &pass_arg, argi)) {
750  global->pass = arg_parse_uint(&arg);
751 
752  if (global->pass < 1 || global->pass > 2)
753  die("Error: Invalid pass selected (%d)\n", global->pass);
754  } else if (arg_match(&arg, &usage, argi))
755  global->usage = arg_parse_uint(&arg);
756  else if (arg_match(&arg, &deadline, argi))
757  global->deadline = arg_parse_uint(&arg);
758  else if (arg_match(&arg, &best_dl, argi))
759  global->deadline = VPX_DL_BEST_QUALITY;
760  else if (arg_match(&arg, &good_dl, argi))
761  global->deadline = VPX_DL_GOOD_QUALITY;
762  else if (arg_match(&arg, &rt_dl, argi))
763  global->deadline = VPX_DL_REALTIME;
764  else if (arg_match(&arg, &use_yv12, argi))
765  global->color_type = YV12;
766  else if (arg_match(&arg, &use_nv12, argi))
767  global->color_type = NV12;
768  else if (arg_match(&arg, &use_i420, argi))
769  global->color_type = I420;
770  else if (arg_match(&arg, &use_i422, argi))
771  global->color_type = I422;
772  else if (arg_match(&arg, &use_i444, argi))
773  global->color_type = I444;
774  else if (arg_match(&arg, &use_i440, argi))
775  global->color_type = I440;
776  else if (arg_match(&arg, &quietarg, argi))
777  global->quiet = 1;
778  else if (arg_match(&arg, &verbosearg, argi))
779  global->verbose = 1;
780  else if (arg_match(&arg, &limit, argi))
781  global->limit = arg_parse_uint(&arg);
782  else if (arg_match(&arg, &skip, argi))
783  global->skip_frames = arg_parse_uint(&arg);
784  else if (arg_match(&arg, &psnrarg, argi))
785  global->show_psnr = 1;
786  else if (arg_match(&arg, &recontest, argi))
787  global->test_decode = arg_parse_enum_or_int(&arg);
788  else if (arg_match(&arg, &framerate, argi)) {
789  global->framerate = arg_parse_rational(&arg);
790  validate_positive_rational(arg.name, &global->framerate);
791  global->have_framerate = 1;
792  } else if (arg_match(&arg, &out_part, argi))
793  global->out_part = 1;
794  else if (arg_match(&arg, &debugmode, argi))
795  global->debug = 1;
796  else if (arg_match(&arg, &q_hist_n, argi))
797  global->show_q_hist_buckets = arg_parse_uint(&arg);
798  else if (arg_match(&arg, &rate_hist_n, argi))
799  global->show_rate_hist_buckets = arg_parse_uint(&arg);
800  else if (arg_match(&arg, &disable_warnings, argi))
801  global->disable_warnings = 1;
802  else if (arg_match(&arg, &disable_warning_prompt, argi))
803  global->disable_warning_prompt = 1;
804  else
805  argj++;
806  }
807 
808  if (global->pass) {
809  /* DWIM: Assume the user meant passes=2 if pass=2 is specified */
810  if (global->pass > global->passes) {
811  warn("Assuming --pass=%d implies --passes=%d\n", global->pass,
812  global->pass);
813  global->passes = global->pass;
814  }
815  }
816  /* Validate global config */
817  if (global->passes == 0) {
818 #if CONFIG_VP9_ENCODER
819  // Make default VP9 passes = 2 until there is a better quality 1-pass
820  // encoder
821  if (global->codec != NULL && global->codec->name != NULL)
822  global->passes = (strcmp(global->codec->name, "vp9") == 0 &&
823  global->deadline != VPX_DL_REALTIME)
824  ? 2
825  : 1;
826 #else
827  global->passes = 1;
828 #endif
829  }
830 
831  if (global->deadline == VPX_DL_REALTIME && global->passes > 1) {
832  warn("Enforcing one-pass encoding in realtime mode\n");
833  global->passes = 1;
834  }
835 }
836 
837 static struct stream_state *new_stream(struct VpxEncoderConfig *global,
838  struct stream_state *prev) {
839  struct stream_state *stream;
840 
841  stream = calloc(1, sizeof(*stream));
842  if (stream == NULL) {
843  fatal("Failed to allocate new stream.");
844  }
845 
846  if (prev) {
847  memcpy(stream, prev, sizeof(*stream));
848  stream->index++;
849  prev->next = stream;
850  } else {
851  vpx_codec_err_t res;
852 
853  /* Populate encoder configuration */
854  res = vpx_codec_enc_config_default(global->codec->codec_interface(),
855  &stream->config.cfg, global->usage);
856  if (res) fatal("Failed to get config: %s\n", vpx_codec_err_to_string(res));
857 
858  /* Change the default timebase to a high enough value so that the
859  * encoder will always create strictly increasing timestamps.
860  */
861  stream->config.cfg.g_timebase.den = 1000;
862 
863  /* Never use the library's default resolution, require it be parsed
864  * from the file or set on the command line.
865  */
866  stream->config.cfg.g_w = 0;
867  stream->config.cfg.g_h = 0;
868 
869  /* Initialize remaining stream parameters */
870  stream->config.write_webm = 1;
871 #if CONFIG_WEBM_IO
872  stream->config.stereo_fmt = STEREO_FORMAT_MONO;
873  stream->webm_ctx.last_pts_ns = -1;
874  stream->webm_ctx.writer = NULL;
875  stream->webm_ctx.segment = NULL;
876 #endif
877 
878  /* Allows removal of the application version from the EBML tags */
879  stream->webm_ctx.debug = global->debug;
880 
881  /* Default lag_in_frames is 0 in realtime mode CBR mode*/
882  if (global->deadline == VPX_DL_REALTIME &&
883  stream->config.cfg.rc_end_usage == 1)
884  stream->config.cfg.g_lag_in_frames = 0;
885  }
886 
887  /* Output files must be specified for each stream */
888  stream->config.out_fn = NULL;
889 
890  stream->next = NULL;
891  return stream;
892 }
893 
894 static int parse_stream_params(struct VpxEncoderConfig *global,
895  struct stream_state *stream, char **argv) {
896  char **argi, **argj;
897  struct arg arg;
898  static const arg_def_t **ctrl_args = no_args;
899  static const int *ctrl_args_map = NULL;
900  struct stream_config *config = &stream->config;
901  int eos_mark_found = 0;
902 #if CONFIG_VP9_HIGHBITDEPTH
903  int test_16bit_internal = 0;
904 #endif
905 
906  // Handle codec specific options
907  if (0) {
908 #if CONFIG_VP8_ENCODER
909  } else if (strcmp(global->codec->name, "vp8") == 0) {
910  ctrl_args = vp8_args;
911  ctrl_args_map = vp8_arg_ctrl_map;
912 #endif
913 #if CONFIG_VP9_ENCODER
914  } else if (strcmp(global->codec->name, "vp9") == 0) {
915  ctrl_args = vp9_args;
916  ctrl_args_map = vp9_arg_ctrl_map;
917 #endif
918  }
919 
920  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
921  arg.argv_step = 1;
922 
923  /* Once we've found an end-of-stream marker (--) we want to continue
924  * shifting arguments but not consuming them.
925  */
926  if (eos_mark_found) {
927  argj++;
928  continue;
929  } else if (!strcmp(*argj, "--")) {
930  eos_mark_found = 1;
931  continue;
932  }
933 
934  if (arg_match(&arg, &outputfile, argi)) {
935  config->out_fn = arg.val;
936  } else if (arg_match(&arg, &fpf_name, argi)) {
937  config->stats_fn = arg.val;
938  } else if (arg_match(&arg, &use_webm, argi)) {
939 #if CONFIG_WEBM_IO
940  config->write_webm = 1;
941 #else
942  die("Error: --webm specified but webm is disabled.");
943 #endif
944  } else if (arg_match(&arg, &use_ivf, argi)) {
945  config->write_webm = 0;
946  } else if (arg_match(&arg, &threads, argi)) {
947  config->cfg.g_threads = arg_parse_uint(&arg);
948  } else if (arg_match(&arg, &profile, argi)) {
949  config->cfg.g_profile = arg_parse_uint(&arg);
950  } else if (arg_match(&arg, &width, argi)) {
951  config->cfg.g_w = arg_parse_uint(&arg);
952  } else if (arg_match(&arg, &height, argi)) {
953  config->cfg.g_h = arg_parse_uint(&arg);
954 #if CONFIG_VP9_HIGHBITDEPTH
955  } else if (arg_match(&arg, &bitdeptharg, argi)) {
956  config->cfg.g_bit_depth = arg_parse_enum_or_int(&arg);
957  } else if (arg_match(&arg, &inbitdeptharg, argi)) {
958  config->cfg.g_input_bit_depth = arg_parse_uint(&arg);
959 #endif
960 #if CONFIG_WEBM_IO
961  } else if (arg_match(&arg, &stereo_mode, argi)) {
962  config->stereo_fmt = arg_parse_enum_or_int(&arg);
963 #endif
964  } else if (arg_match(&arg, &timebase, argi)) {
965  config->cfg.g_timebase = arg_parse_rational(&arg);
966  validate_positive_rational(arg.name, &config->cfg.g_timebase);
967  } else if (arg_match(&arg, &error_resilient, argi)) {
968  config->cfg.g_error_resilient = arg_parse_uint(&arg);
969  } else if (arg_match(&arg, &end_usage, argi)) {
970  config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg);
971  } else if (arg_match(&arg, &lag_in_frames, argi)) {
972  config->cfg.g_lag_in_frames = arg_parse_uint(&arg);
973  if (global->deadline == VPX_DL_REALTIME &&
974  config->cfg.rc_end_usage == VPX_CBR &&
975  config->cfg.g_lag_in_frames != 0) {
976  warn("non-zero %s option ignored in realtime CBR mode.\n", arg.name);
977  config->cfg.g_lag_in_frames = 0;
978  }
979  } else if (arg_match(&arg, &dropframe_thresh, argi)) {
980  config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
981  } else if (arg_match(&arg, &resize_allowed, argi)) {
982  config->cfg.rc_resize_allowed = arg_parse_uint(&arg);
983  } else if (arg_match(&arg, &resize_width, argi)) {
984  config->cfg.rc_scaled_width = arg_parse_uint(&arg);
985  } else if (arg_match(&arg, &resize_height, argi)) {
986  config->cfg.rc_scaled_height = arg_parse_uint(&arg);
987  } else if (arg_match(&arg, &resize_up_thresh, argi)) {
988  config->cfg.rc_resize_up_thresh = arg_parse_uint(&arg);
989  } else if (arg_match(&arg, &resize_down_thresh, argi)) {
990  config->cfg.rc_resize_down_thresh = arg_parse_uint(&arg);
991  } else if (arg_match(&arg, &end_usage, argi)) {
992  config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg);
993  } else if (arg_match(&arg, &target_bitrate, argi)) {
994  config->cfg.rc_target_bitrate = arg_parse_uint(&arg);
995  } else if (arg_match(&arg, &min_quantizer, argi)) {
996  config->cfg.rc_min_quantizer = arg_parse_uint(&arg);
997  } else if (arg_match(&arg, &max_quantizer, argi)) {
998  config->cfg.rc_max_quantizer = arg_parse_uint(&arg);
999  } else if (arg_match(&arg, &undershoot_pct, argi)) {
1000  config->cfg.rc_undershoot_pct = arg_parse_uint(&arg);
1001  } else if (arg_match(&arg, &overshoot_pct, argi)) {
1002  config->cfg.rc_overshoot_pct = arg_parse_uint(&arg);
1003  } else if (arg_match(&arg, &buf_sz, argi)) {
1004  config->cfg.rc_buf_sz = arg_parse_uint(&arg);
1005  } else if (arg_match(&arg, &buf_initial_sz, argi)) {
1006  config->cfg.rc_buf_initial_sz = arg_parse_uint(&arg);
1007  } else if (arg_match(&arg, &buf_optimal_sz, argi)) {
1008  config->cfg.rc_buf_optimal_sz = arg_parse_uint(&arg);
1009  } else if (arg_match(&arg, &bias_pct, argi)) {
1010  config->cfg.rc_2pass_vbr_bias_pct = arg_parse_uint(&arg);
1011  if (global->passes < 2)
1012  warn("option %s ignored in one-pass mode.\n", arg.name);
1013  } else if (arg_match(&arg, &minsection_pct, argi)) {
1014  config->cfg.rc_2pass_vbr_minsection_pct = arg_parse_uint(&arg);
1015 
1016  if (global->passes < 2)
1017  warn("option %s ignored in one-pass mode.\n", arg.name);
1018  } else if (arg_match(&arg, &maxsection_pct, argi)) {
1019  config->cfg.rc_2pass_vbr_maxsection_pct = arg_parse_uint(&arg);
1020 
1021  if (global->passes < 2)
1022  warn("option %s ignored in one-pass mode.\n", arg.name);
1023  } else if (arg_match(&arg, &corpus_complexity, argi)) {
1024  config->cfg.rc_2pass_vbr_corpus_complexity = arg_parse_uint(&arg);
1025 
1026  if (global->passes < 2)
1027  warn("option %s ignored in one-pass mode.\n", arg.name);
1028  } else if (arg_match(&arg, &kf_min_dist, argi)) {
1029  config->cfg.kf_min_dist = arg_parse_uint(&arg);
1030  } else if (arg_match(&arg, &kf_max_dist, argi)) {
1031  config->cfg.kf_max_dist = arg_parse_uint(&arg);
1032  } else if (arg_match(&arg, &kf_disabled, argi)) {
1033  config->cfg.kf_mode = VPX_KF_DISABLED;
1034 #if CONFIG_VP9_ENCODER
1035  } else if (arg_match(&arg, &use_vizier_rc_params, argi)) {
1036  config->cfg.use_vizier_rc_params = arg_parse_int(&arg);
1037  } else if (arg_match(&arg, &active_wq_factor, argi)) {
1038  config->cfg.active_wq_factor = arg_parse_rational(&arg);
1039  } else if (arg_match(&arg, &err_per_mb_factor, argi)) {
1040  config->cfg.err_per_mb_factor = arg_parse_rational(&arg);
1041  } else if (arg_match(&arg, &sr_default_decay_limit, argi)) {
1042  config->cfg.sr_default_decay_limit = arg_parse_rational(&arg);
1043  } else if (arg_match(&arg, &sr_diff_factor, argi)) {
1044  config->cfg.sr_diff_factor = arg_parse_rational(&arg);
1045  } else if (arg_match(&arg, &kf_err_per_mb_factor, argi)) {
1046  config->cfg.kf_err_per_mb_factor = arg_parse_rational(&arg);
1047  } else if (arg_match(&arg, &kf_frame_min_boost_factor, argi)) {
1048  config->cfg.kf_frame_min_boost_factor = arg_parse_rational(&arg);
1049  } else if (arg_match(&arg, &kf_frame_max_boost_first_factor, argi)) {
1050  config->cfg.kf_frame_max_boost_first_factor = arg_parse_rational(&arg);
1051  } else if (arg_match(&arg, &kf_frame_max_boost_subs_factor, argi)) {
1052  config->cfg.kf_frame_max_boost_subs_factor = arg_parse_rational(&arg);
1053  } else if (arg_match(&arg, &kf_max_total_boost_factor, argi)) {
1054  config->cfg.kf_max_total_boost_factor = arg_parse_rational(&arg);
1055  } else if (arg_match(&arg, &gf_max_total_boost_factor, argi)) {
1056  config->cfg.gf_max_total_boost_factor = arg_parse_rational(&arg);
1057  } else if (arg_match(&arg, &gf_frame_max_boost_factor, argi)) {
1058  config->cfg.gf_frame_max_boost_factor = arg_parse_rational(&arg);
1059  } else if (arg_match(&arg, &zm_factor, argi)) {
1060  config->cfg.zm_factor = arg_parse_rational(&arg);
1061  } else if (arg_match(&arg, &rd_mult_inter_qp_fac, argi)) {
1062  config->cfg.rd_mult_inter_qp_fac = arg_parse_rational(&arg);
1063  } else if (arg_match(&arg, &rd_mult_arf_qp_fac, argi)) {
1064  config->cfg.rd_mult_arf_qp_fac = arg_parse_rational(&arg);
1065  } else if (arg_match(&arg, &rd_mult_key_qp_fac, argi)) {
1066  config->cfg.rd_mult_key_qp_fac = arg_parse_rational(&arg);
1067 #endif
1068 #if CONFIG_VP9_HIGHBITDEPTH
1069  } else if (arg_match(&arg, &test16bitinternalarg, argi)) {
1070  if (strcmp(global->codec->name, "vp9") == 0) {
1071  test_16bit_internal = 1;
1072  }
1073 #endif
1074  } else {
1075  int i, match = 0;
1076  for (i = 0; ctrl_args[i]; i++) {
1077  if (arg_match(&arg, ctrl_args[i], argi)) {
1078  int j;
1079  match = 1;
1080 
1081  /* Point either to the next free element or the first
1082  * instance of this control.
1083  */
1084  for (j = 0; j < config->arg_ctrl_cnt; j++)
1085  if (ctrl_args_map != NULL &&
1086  config->arg_ctrls[j][0] == ctrl_args_map[i])
1087  break;
1088 
1089  /* Update/insert */
1090  assert(j < (int)ARG_CTRL_CNT_MAX);
1091  if (ctrl_args_map != NULL && j < (int)ARG_CTRL_CNT_MAX) {
1092  config->arg_ctrls[j][0] = ctrl_args_map[i];
1093  config->arg_ctrls[j][1] = arg_parse_enum_or_int(&arg);
1094  if (j == config->arg_ctrl_cnt) config->arg_ctrl_cnt++;
1095  }
1096  }
1097  }
1098  if (!match) argj++;
1099  }
1100  }
1101 #if CONFIG_VP9_HIGHBITDEPTH
1102  if (strcmp(global->codec->name, "vp9") == 0) {
1103  config->use_16bit_internal =
1104  test_16bit_internal | (config->cfg.g_profile > 1);
1105  }
1106 #endif
1107  return eos_mark_found;
1108 }
1109 
1110 #define FOREACH_STREAM(func) \
1111  do { \
1112  struct stream_state *stream; \
1113  for (stream = streams; stream; stream = stream->next) { \
1114  func; \
1115  } \
1116  } while (0)
1117 
1118 static void validate_stream_config(const struct stream_state *stream,
1119  const struct VpxEncoderConfig *global) {
1120  const struct stream_state *streami;
1121  (void)global;
1122 
1123  if (!stream->config.cfg.g_w || !stream->config.cfg.g_h)
1124  fatal(
1125  "Stream %d: Specify stream dimensions with --width (-w) "
1126  " and --height (-h)",
1127  stream->index);
1128 
1129  // Check that the codec bit depth is greater than the input bit depth.
1130  if (stream->config.cfg.g_input_bit_depth >
1131  (unsigned int)stream->config.cfg.g_bit_depth) {
1132  fatal("Stream %d: codec bit depth (%d) less than input bit depth (%d)",
1133  stream->index, (int)stream->config.cfg.g_bit_depth,
1134  stream->config.cfg.g_input_bit_depth);
1135  }
1136 
1137  for (streami = stream; streami; streami = streami->next) {
1138  /* All streams require output files */
1139  if (!streami->config.out_fn)
1140  fatal("Stream %d: Output file is required (specify with -o)",
1141  streami->index);
1142 
1143  /* Check for two streams outputting to the same file */
1144  if (streami != stream) {
1145  const char *a = stream->config.out_fn;
1146  const char *b = streami->config.out_fn;
1147  if (!strcmp(a, b) && strcmp(a, "/dev/null") && strcmp(a, ":nul"))
1148  fatal("Stream %d: duplicate output file (from stream %d)",
1149  streami->index, stream->index);
1150  }
1151 
1152  /* Check for two streams sharing a stats file. */
1153  if (streami != stream) {
1154  const char *a = stream->config.stats_fn;
1155  const char *b = streami->config.stats_fn;
1156  if (a && b && !strcmp(a, b))
1157  fatal("Stream %d: duplicate stats file (from stream %d)",
1158  streami->index, stream->index);
1159  }
1160  }
1161 }
1162 
1163 static void set_stream_dimensions(struct stream_state *stream, unsigned int w,
1164  unsigned int h) {
1165  if (!stream->config.cfg.g_w) {
1166  if (!stream->config.cfg.g_h)
1167  stream->config.cfg.g_w = w;
1168  else
1169  stream->config.cfg.g_w = w * stream->config.cfg.g_h / h;
1170  }
1171  if (!stream->config.cfg.g_h) {
1172  stream->config.cfg.g_h = h * stream->config.cfg.g_w / w;
1173  }
1174 }
1175 
1176 static const char *file_type_to_string(enum VideoFileType t) {
1177  switch (t) {
1178  case FILE_TYPE_RAW: return "RAW";
1179  case FILE_TYPE_Y4M: return "Y4M";
1180  default: return "Other";
1181  }
1182 }
1183 
1184 static const char *image_format_to_string(vpx_img_fmt_t f) {
1185  switch (f) {
1186  case VPX_IMG_FMT_I420: return "I420";
1187  case VPX_IMG_FMT_I422: return "I422";
1188  case VPX_IMG_FMT_I444: return "I444";
1189  case VPX_IMG_FMT_I440: return "I440";
1190  case VPX_IMG_FMT_YV12: return "YV12";
1191  case VPX_IMG_FMT_I42016: return "I42016";
1192  case VPX_IMG_FMT_I42216: return "I42216";
1193  case VPX_IMG_FMT_I44416: return "I44416";
1194  case VPX_IMG_FMT_I44016: return "I44016";
1195  default: return "Other";
1196  }
1197 }
1198 
1199 static void show_stream_config(struct stream_state *stream,
1200  struct VpxEncoderConfig *global,
1201  struct VpxInputContext *input) {
1202 #define SHOW(field) \
1203  fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field)
1204 
1205  if (stream->index == 0) {
1206  fprintf(stderr, "Codec: %s\n",
1207  vpx_codec_iface_name(global->codec->codec_interface()));
1208  fprintf(stderr, "Source file: %s File Type: %s Format: %s\n",
1209  input->filename, file_type_to_string(input->file_type),
1210  image_format_to_string(input->fmt));
1211  }
1212  if (stream->next || stream->index)
1213  fprintf(stderr, "\nStream Index: %d\n", stream->index);
1214  fprintf(stderr, "Destination file: %s\n", stream->config.out_fn);
1215  fprintf(stderr, "Encoder parameters:\n");
1216 
1217  SHOW(g_usage);
1218  SHOW(g_threads);
1219  SHOW(g_profile);
1220  SHOW(g_w);
1221  SHOW(g_h);
1222  SHOW(g_bit_depth);
1223  SHOW(g_input_bit_depth);
1224  SHOW(g_timebase.num);
1225  SHOW(g_timebase.den);
1226  SHOW(g_error_resilient);
1227  SHOW(g_pass);
1228  SHOW(g_lag_in_frames);
1229  SHOW(rc_dropframe_thresh);
1230  SHOW(rc_resize_allowed);
1231  SHOW(rc_scaled_width);
1232  SHOW(rc_scaled_height);
1233  SHOW(rc_resize_up_thresh);
1234  SHOW(rc_resize_down_thresh);
1235  SHOW(rc_end_usage);
1236  SHOW(rc_target_bitrate);
1237  SHOW(rc_min_quantizer);
1238  SHOW(rc_max_quantizer);
1239  SHOW(rc_undershoot_pct);
1240  SHOW(rc_overshoot_pct);
1241  SHOW(rc_buf_sz);
1242  SHOW(rc_buf_initial_sz);
1243  SHOW(rc_buf_optimal_sz);
1244  SHOW(rc_2pass_vbr_bias_pct);
1245  SHOW(rc_2pass_vbr_minsection_pct);
1246  SHOW(rc_2pass_vbr_maxsection_pct);
1247  SHOW(rc_2pass_vbr_corpus_complexity);
1248  SHOW(kf_mode);
1249  SHOW(kf_min_dist);
1250  SHOW(kf_max_dist);
1251  // Temporary use for debug
1252  SHOW(use_vizier_rc_params);
1253  SHOW(active_wq_factor.num);
1254  SHOW(active_wq_factor.den);
1255 }
1256 
1257 static void open_output_file(struct stream_state *stream,
1258  struct VpxEncoderConfig *global,
1259  const struct VpxRational *pixel_aspect_ratio) {
1260  const char *fn = stream->config.out_fn;
1261  const struct vpx_codec_enc_cfg *const cfg = &stream->config.cfg;
1262 
1263  if (cfg->g_pass == VPX_RC_FIRST_PASS) return;
1264 
1265  stream->file = strcmp(fn, "-") ? fopen(fn, "wb") : set_binary_mode(stdout);
1266 
1267  if (!stream->file) fatal("Failed to open output file");
1268 
1269  if (stream->config.write_webm && fseek(stream->file, 0, SEEK_CUR))
1270  fatal("WebM output to pipes not supported.");
1271 
1272 #if CONFIG_WEBM_IO
1273  if (stream->config.write_webm) {
1274  stream->webm_ctx.stream = stream->file;
1275  write_webm_file_header(&stream->webm_ctx, cfg, stream->config.stereo_fmt,
1276  global->codec->fourcc, pixel_aspect_ratio);
1277  }
1278 #else
1279  (void)pixel_aspect_ratio;
1280 #endif
1281 
1282  if (!stream->config.write_webm) {
1283  ivf_write_file_header(stream->file, cfg, global->codec->fourcc, 0);
1284  }
1285 }
1286 
1287 static void close_output_file(struct stream_state *stream,
1288  unsigned int fourcc) {
1289  const struct vpx_codec_enc_cfg *const cfg = &stream->config.cfg;
1290 
1291  if (cfg->g_pass == VPX_RC_FIRST_PASS) return;
1292 
1293 #if CONFIG_WEBM_IO
1294  if (stream->config.write_webm) {
1295  write_webm_file_footer(&stream->webm_ctx);
1296  }
1297 #endif
1298 
1299  if (!stream->config.write_webm) {
1300  if (!fseek(stream->file, 0, SEEK_SET))
1301  ivf_write_file_header(stream->file, &stream->config.cfg, fourcc,
1302  stream->frames_out);
1303  }
1304 
1305  fclose(stream->file);
1306 }
1307 
1308 static void setup_pass(struct stream_state *stream,
1309  struct VpxEncoderConfig *global, int pass) {
1310  if (stream->config.stats_fn) {
1311  if (!stats_open_file(&stream->stats, stream->config.stats_fn, pass))
1312  fatal("Failed to open statistics store");
1313  } else {
1314  if (!stats_open_mem(&stream->stats, pass))
1315  fatal("Failed to open statistics store");
1316  }
1317 
1318  stream->config.cfg.g_pass = global->passes == 2
1320  : VPX_RC_ONE_PASS;
1321  if (pass) {
1322  stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats);
1323  }
1324 
1325  stream->cx_time = 0;
1326  stream->nbytes = 0;
1327  stream->frames_out = 0;
1328 }
1329 
1330 static void initialize_encoder(struct stream_state *stream,
1331  struct VpxEncoderConfig *global) {
1332  int i;
1333  int flags = 0;
1334 
1335  flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0;
1336  flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0;
1337 #if CONFIG_VP9_HIGHBITDEPTH
1338  flags |= stream->config.use_16bit_internal ? VPX_CODEC_USE_HIGHBITDEPTH : 0;
1339 #endif
1340 
1341  /* Construct Encoder Context */
1342  vpx_codec_enc_init(&stream->encoder, global->codec->codec_interface(),
1343  &stream->config.cfg, flags);
1344  ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder");
1345 
1346  /* Note that we bypass the vpx_codec_control wrapper macro because
1347  * we're being clever to store the control IDs in an array. Real
1348  * applications will want to make use of the enumerations directly
1349  */
1350  for (i = 0; i < stream->config.arg_ctrl_cnt; i++) {
1351  int ctrl = stream->config.arg_ctrls[i][0];
1352  int value = stream->config.arg_ctrls[i][1];
1353  if (vpx_codec_control_(&stream->encoder, ctrl, value))
1354  fprintf(stderr, "Error: Tried to set control %d = %d\n", ctrl, value);
1355 
1356  ctx_exit_on_error(&stream->encoder, "Failed to control codec");
1357  }
1358 
1359 #if CONFIG_DECODERS
1360  if (global->test_decode != TEST_DECODE_OFF) {
1361  const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name);
1362  vpx_codec_dec_init(&stream->decoder, decoder->codec_interface(), NULL, 0);
1363  }
1364 #endif
1365 }
1366 
1367 static void encode_frame(struct stream_state *stream,
1368  struct VpxEncoderConfig *global, struct vpx_image *img,
1369  unsigned int frames_in) {
1370  vpx_codec_pts_t frame_start, next_frame_start;
1371  struct vpx_codec_enc_cfg *cfg = &stream->config.cfg;
1372  struct vpx_usec_timer timer;
1373 
1374  frame_start =
1375  (cfg->g_timebase.den * (int64_t)(frames_in - 1) * global->framerate.den) /
1376  cfg->g_timebase.num / global->framerate.num;
1377  next_frame_start =
1378  (cfg->g_timebase.den * (int64_t)(frames_in)*global->framerate.den) /
1379  cfg->g_timebase.num / global->framerate.num;
1380 
1381 /* Scale if necessary */
1382 #if CONFIG_VP9_HIGHBITDEPTH
1383  if (img) {
1384  if ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) &&
1385  (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) {
1386  if (img->fmt != VPX_IMG_FMT_I42016) {
1387  fprintf(stderr, "%s can only scale 4:2:0 inputs\n", exec_name);
1388  exit(EXIT_FAILURE);
1389  }
1390 #if CONFIG_LIBYUV
1391  if (!stream->img) {
1392  stream->img =
1393  vpx_img_alloc(NULL, VPX_IMG_FMT_I42016, cfg->g_w, cfg->g_h, 16);
1394  }
1395  I420Scale_16(
1396  (uint16_t *)img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y] / 2,
1397  (uint16_t *)img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U] / 2,
1398  (uint16_t *)img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V] / 2,
1399  img->d_w, img->d_h, (uint16_t *)stream->img->planes[VPX_PLANE_Y],
1400  stream->img->stride[VPX_PLANE_Y] / 2,
1401  (uint16_t *)stream->img->planes[VPX_PLANE_U],
1402  stream->img->stride[VPX_PLANE_U] / 2,
1403  (uint16_t *)stream->img->planes[VPX_PLANE_V],
1404  stream->img->stride[VPX_PLANE_V] / 2, stream->img->d_w,
1405  stream->img->d_h, kFilterBox);
1406  img = stream->img;
1407 #else
1408  stream->encoder.err = 1;
1409  ctx_exit_on_error(&stream->encoder,
1410  "Stream %d: Failed to encode frame.\n"
1411  "Scaling disabled in this configuration. \n"
1412  "To enable, configure with --enable-libyuv\n",
1413  stream->index);
1414 #endif
1415  }
1416  }
1417 #endif
1418  if (img && (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) {
1419  if (img->fmt != VPX_IMG_FMT_I420 && img->fmt != VPX_IMG_FMT_YV12) {
1420  fprintf(stderr, "%s can only scale 4:2:0 8bpp inputs\n", exec_name);
1421  exit(EXIT_FAILURE);
1422  }
1423 #if CONFIG_LIBYUV
1424  if (!stream->img)
1425  stream->img =
1426  vpx_img_alloc(NULL, VPX_IMG_FMT_I420, cfg->g_w, cfg->g_h, 16);
1427  I420Scale(
1428  img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y],
1429  img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U],
1430  img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], img->d_w, img->d_h,
1431  stream->img->planes[VPX_PLANE_Y], stream->img->stride[VPX_PLANE_Y],
1432  stream->img->planes[VPX_PLANE_U], stream->img->stride[VPX_PLANE_U],
1433  stream->img->planes[VPX_PLANE_V], stream->img->stride[VPX_PLANE_V],
1434  stream->img->d_w, stream->img->d_h, kFilterBox);
1435  img = stream->img;
1436 #else
1437  stream->encoder.err = 1;
1438  ctx_exit_on_error(&stream->encoder,
1439  "Stream %d: Failed to encode frame.\n"
1440  "Scaling disabled in this configuration. \n"
1441  "To enable, configure with --enable-libyuv\n",
1442  stream->index);
1443 #endif
1444  }
1445 
1446  vpx_usec_timer_start(&timer);
1447  vpx_codec_encode(&stream->encoder, img, frame_start,
1448  (unsigned long)(next_frame_start - frame_start), 0,
1449  global->deadline);
1450  vpx_usec_timer_mark(&timer);
1451  stream->cx_time += vpx_usec_timer_elapsed(&timer);
1452  ctx_exit_on_error(&stream->encoder, "Stream %d: Failed to encode frame",
1453  stream->index);
1454 }
1455 
1456 static void update_quantizer_histogram(struct stream_state *stream) {
1457  if (stream->config.cfg.g_pass != VPX_RC_FIRST_PASS) {
1458  int q;
1459 
1460  vpx_codec_control(&stream->encoder, VP8E_GET_LAST_QUANTIZER_64, &q);
1461  ctx_exit_on_error(&stream->encoder, "Failed to read quantizer");
1462  stream->counts[q]++;
1463  }
1464 }
1465 
1466 static void get_cx_data(struct stream_state *stream,
1467  struct VpxEncoderConfig *global, int *got_data) {
1468  const vpx_codec_cx_pkt_t *pkt;
1469  const struct vpx_codec_enc_cfg *cfg = &stream->config.cfg;
1470  vpx_codec_iter_t iter = NULL;
1471 
1472  *got_data = 0;
1473  while ((pkt = vpx_codec_get_cx_data(&stream->encoder, &iter))) {
1474  static size_t fsize = 0;
1475  static FileOffset ivf_header_pos = 0;
1476 
1477  switch (pkt->kind) {
1479  if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
1480  stream->frames_out++;
1481  }
1482  if (!global->quiet)
1483  fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz);
1484 
1485  update_rate_histogram(stream->rate_hist, cfg, pkt);
1486 #if CONFIG_WEBM_IO
1487  if (stream->config.write_webm) {
1488  write_webm_block(&stream->webm_ctx, cfg, pkt);
1489  }
1490 #endif
1491  if (!stream->config.write_webm) {
1492  if (pkt->data.frame.partition_id <= 0) {
1493  ivf_header_pos = ftello(stream->file);
1494  fsize = pkt->data.frame.sz;
1495 
1496  ivf_write_frame_header(stream->file, pkt->data.frame.pts, fsize);
1497  } else {
1498  fsize += pkt->data.frame.sz;
1499 
1500  if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
1501  const FileOffset currpos = ftello(stream->file);
1502  fseeko(stream->file, ivf_header_pos, SEEK_SET);
1503  ivf_write_frame_size(stream->file, fsize);
1504  fseeko(stream->file, currpos, SEEK_SET);
1505  }
1506  }
1507 
1508  (void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
1509  stream->file);
1510  }
1511  stream->nbytes += pkt->data.raw.sz;
1512 
1513  *got_data = 1;
1514 #if CONFIG_DECODERS
1515  if (global->test_decode != TEST_DECODE_OFF && !stream->mismatch_seen) {
1516  vpx_codec_decode(&stream->decoder, pkt->data.frame.buf,
1517  (unsigned int)pkt->data.frame.sz, NULL, 0);
1518  if (stream->decoder.err) {
1519  warn_or_exit_on_error(&stream->decoder,
1520  global->test_decode == TEST_DECODE_FATAL,
1521  "Failed to decode frame %d in stream %d",
1522  stream->frames_out + 1, stream->index);
1523  stream->mismatch_seen = stream->frames_out + 1;
1524  }
1525  }
1526 #endif
1527  break;
1528  case VPX_CODEC_STATS_PKT:
1529  stream->frames_out++;
1530  stats_write(&stream->stats, pkt->data.twopass_stats.buf,
1531  pkt->data.twopass_stats.sz);
1532  stream->nbytes += pkt->data.raw.sz;
1533  break;
1534  case VPX_CODEC_PSNR_PKT:
1535 
1536  if (global->show_psnr) {
1537  int i;
1538 
1539  stream->psnr_sse_total += pkt->data.psnr.sse[0];
1540  stream->psnr_samples_total += pkt->data.psnr.samples[0];
1541  for (i = 0; i < 4; i++) {
1542  if (!global->quiet)
1543  fprintf(stderr, "%.3f ", pkt->data.psnr.psnr[i]);
1544  stream->psnr_totals[i] += pkt->data.psnr.psnr[i];
1545  }
1546  stream->psnr_count++;
1547  }
1548 
1549  break;
1550  default: break;
1551  }
1552  }
1553 }
1554 
1555 static void show_psnr(struct stream_state *stream, double peak) {
1556  int i;
1557  double ovpsnr;
1558 
1559  if (!stream->psnr_count) return;
1560 
1561  fprintf(stderr, "Stream %d PSNR (Overall/Avg/Y/U/V)", stream->index);
1562  ovpsnr = sse_to_psnr((double)stream->psnr_samples_total, peak,
1563  (double)stream->psnr_sse_total);
1564  fprintf(stderr, " %.3f", ovpsnr);
1565 
1566  for (i = 0; i < 4; i++) {
1567  fprintf(stderr, " %.3f", stream->psnr_totals[i] / stream->psnr_count);
1568  }
1569  fprintf(stderr, "\n");
1570 }
1571 
1572 static float usec_to_fps(uint64_t usec, unsigned int frames) {
1573  return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0);
1574 }
1575 
1576 static void test_decode(struct stream_state *stream,
1577  enum TestDecodeFatality fatal,
1578  const VpxInterface *codec) {
1579  vpx_image_t enc_img, dec_img;
1580 
1581  if (stream->mismatch_seen) return;
1582 
1583  /* Get the internal reference frame */
1584  if (strcmp(codec->name, "vp8") == 0) {
1585  struct vpx_ref_frame ref_enc, ref_dec;
1586  int width, height;
1587 
1588  width = (stream->config.cfg.g_w + 15) & ~15;
1589  height = (stream->config.cfg.g_h + 15) & ~15;
1590  vpx_img_alloc(&ref_enc.img, VPX_IMG_FMT_I420, width, height, 1);
1591  enc_img = ref_enc.img;
1592  vpx_img_alloc(&ref_dec.img, VPX_IMG_FMT_I420, width, height, 1);
1593  dec_img = ref_dec.img;
1594 
1595  ref_enc.frame_type = VP8_LAST_FRAME;
1596  ref_dec.frame_type = VP8_LAST_FRAME;
1597  vpx_codec_control(&stream->encoder, VP8_COPY_REFERENCE, &ref_enc);
1598  vpx_codec_control(&stream->decoder, VP8_COPY_REFERENCE, &ref_dec);
1599  } else {
1600  struct vp9_ref_frame ref_enc, ref_dec;
1601 
1602  ref_enc.idx = 0;
1603  ref_dec.idx = 0;
1604  vpx_codec_control(&stream->encoder, VP9_GET_REFERENCE, &ref_enc);
1605  enc_img = ref_enc.img;
1606  vpx_codec_control(&stream->decoder, VP9_GET_REFERENCE, &ref_dec);
1607  dec_img = ref_dec.img;
1608 #if CONFIG_VP9_HIGHBITDEPTH
1609  if ((enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) !=
1610  (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)) {
1611  if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
1612  vpx_img_alloc(&enc_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
1613  enc_img.d_w, enc_img.d_h, 16);
1614  vpx_img_truncate_16_to_8(&enc_img, &ref_enc.img);
1615  }
1616  if (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
1617  vpx_img_alloc(&dec_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
1618  dec_img.d_w, dec_img.d_h, 16);
1619  vpx_img_truncate_16_to_8(&dec_img, &ref_dec.img);
1620  }
1621  }
1622 #endif
1623  }
1624  ctx_exit_on_error(&stream->encoder, "Failed to get encoder reference frame");
1625  ctx_exit_on_error(&stream->decoder, "Failed to get decoder reference frame");
1626 
1627  if (!compare_img(&enc_img, &dec_img)) {
1628  int y[4], u[4], v[4];
1629 #if CONFIG_VP9_HIGHBITDEPTH
1630  if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
1631  find_mismatch_high(&enc_img, &dec_img, y, u, v);
1632  } else {
1633  find_mismatch(&enc_img, &dec_img, y, u, v);
1634  }
1635 #else
1636  find_mismatch(&enc_img, &dec_img, y, u, v);
1637 #endif
1638  stream->decoder.err = 1;
1639  warn_or_exit_on_error(&stream->decoder, fatal == TEST_DECODE_FATAL,
1640  "Stream %d: Encode/decode mismatch on frame %d at"
1641  " Y[%d, %d] {%d/%d},"
1642  " U[%d, %d] {%d/%d},"
1643  " V[%d, %d] {%d/%d}",
1644  stream->index, stream->frames_out, y[0], y[1], y[2],
1645  y[3], u[0], u[1], u[2], u[3], v[0], v[1], v[2], v[3]);
1646  stream->mismatch_seen = stream->frames_out;
1647  }
1648 
1649  vpx_img_free(&enc_img);
1650  vpx_img_free(&dec_img);
1651 }
1652 
1653 static void print_time(const char *label, int64_t etl) {
1654  int64_t hours;
1655  int64_t mins;
1656  int64_t secs;
1657 
1658  if (etl >= 0) {
1659  hours = etl / 3600;
1660  etl -= hours * 3600;
1661  mins = etl / 60;
1662  etl -= mins * 60;
1663  secs = etl;
1664 
1665  fprintf(stderr, "[%3s %2" PRId64 ":%02" PRId64 ":%02" PRId64 "] ", label,
1666  hours, mins, secs);
1667  } else {
1668  fprintf(stderr, "[%3s unknown] ", label);
1669  }
1670 }
1671 
1672 int main(int argc, const char **argv_) {
1673  int pass;
1674  vpx_image_t raw;
1675 #if CONFIG_VP9_HIGHBITDEPTH
1676  vpx_image_t raw_shift;
1677  int allocated_raw_shift = 0;
1678  int use_16bit_internal = 0;
1679  int input_shift = 0;
1680 #endif
1681  int frame_avail, got_data;
1682 
1683  struct VpxInputContext input;
1684  struct VpxEncoderConfig global;
1685  struct stream_state *streams = NULL;
1686  char **argv, **argi;
1687  uint64_t cx_time = 0;
1688  int stream_cnt = 0;
1689  int res = 0;
1690 
1691  memset(&input, 0, sizeof(input));
1692  memset(&raw, 0, sizeof(raw));
1693  exec_name = argv_[0];
1694 
1695  /* Setup default input stream settings */
1696  input.framerate.numerator = 30;
1697  input.framerate.denominator = 1;
1698  input.only_i420 = 1;
1699  input.bit_depth = 0;
1700 
1701  /* First parse the global configuration values, because we want to apply
1702  * other parameters on top of the default configuration provided by the
1703  * codec.
1704  */
1705  argv = argv_dup(argc - 1, argv_ + 1);
1706  if (!argv) {
1707  fprintf(stderr, "Error allocating argument list\n");
1708  return EXIT_FAILURE;
1709  }
1710  parse_global_config(&global, argv);
1711 
1712  if (argc < 3) usage_exit();
1713 
1714  switch (global.color_type) {
1715  case I420: input.fmt = VPX_IMG_FMT_I420; break;
1716  case I422: input.fmt = VPX_IMG_FMT_I422; break;
1717  case I444: input.fmt = VPX_IMG_FMT_I444; break;
1718  case I440: input.fmt = VPX_IMG_FMT_I440; break;
1719  case YV12: input.fmt = VPX_IMG_FMT_YV12; break;
1720  case NV12: input.fmt = VPX_IMG_FMT_NV12; break;
1721  }
1722 
1723  {
1724  /* Now parse each stream's parameters. Using a local scope here
1725  * due to the use of 'stream' as loop variable in FOREACH_STREAM
1726  * loops
1727  */
1728  struct stream_state *stream = NULL;
1729 
1730  do {
1731  stream = new_stream(&global, stream);
1732  stream_cnt++;
1733  if (!streams) streams = stream;
1734  } while (parse_stream_params(&global, stream, argv));
1735  }
1736 
1737  /* Check for unrecognized options */
1738  for (argi = argv; *argi; argi++)
1739  if (argi[0][0] == '-' && argi[0][1])
1740  die("Error: Unrecognized option %s\n", *argi);
1741 
1742  FOREACH_STREAM(check_encoder_config(global.disable_warning_prompt, &global,
1743  &stream->config.cfg););
1744 
1745  /* Handle non-option arguments */
1746  input.filename = argv[0];
1747 
1748  if (!input.filename) {
1749  fprintf(stderr, "No input file specified!\n");
1750  usage_exit();
1751  }
1752 
1753  /* Decide if other chroma subsamplings than 4:2:0 are supported */
1754  if (global.codec->fourcc == VP9_FOURCC) input.only_i420 = 0;
1755 
1756  for (pass = global.pass ? global.pass - 1 : 0; pass < global.passes; pass++) {
1757  int frames_in = 0, seen_frames = 0;
1758  int64_t estimated_time_left = -1;
1759  int64_t average_rate = -1;
1760  int64_t lagged_count = 0;
1761 
1762  open_input_file(&input);
1763 
1764  /* If the input file doesn't specify its w/h (raw files), try to get
1765  * the data from the first stream's configuration.
1766  */
1767  if (!input.width || !input.height) {
1768  FOREACH_STREAM({
1769  if (stream->config.cfg.g_w && stream->config.cfg.g_h) {
1770  input.width = stream->config.cfg.g_w;
1771  input.height = stream->config.cfg.g_h;
1772  break;
1773  }
1774  });
1775  }
1776 
1777  /* Update stream configurations from the input file's parameters */
1778  if (!input.width || !input.height)
1779  fatal(
1780  "Specify stream dimensions with --width (-w) "
1781  " and --height (-h)");
1782 
1783  /* If input file does not specify bit-depth but input-bit-depth parameter
1784  * exists, assume that to be the input bit-depth. However, if the
1785  * input-bit-depth paramter does not exist, assume the input bit-depth
1786  * to be the same as the codec bit-depth.
1787  */
1788  if (!input.bit_depth) {
1789  FOREACH_STREAM({
1790  if (stream->config.cfg.g_input_bit_depth)
1791  input.bit_depth = stream->config.cfg.g_input_bit_depth;
1792  else
1793  input.bit_depth = stream->config.cfg.g_input_bit_depth =
1794  (int)stream->config.cfg.g_bit_depth;
1795  });
1796  if (input.bit_depth > 8) input.fmt |= VPX_IMG_FMT_HIGHBITDEPTH;
1797  } else {
1798  FOREACH_STREAM(
1799  { stream->config.cfg.g_input_bit_depth = input.bit_depth; });
1800  }
1801 
1802  FOREACH_STREAM(set_stream_dimensions(stream, input.width, input.height));
1803  FOREACH_STREAM(validate_stream_config(stream, &global));
1804 
1805  /* Ensure that --passes and --pass are consistent. If --pass is set and
1806  * --passes=2, ensure --fpf was set.
1807  */
1808  if (global.pass && global.passes == 2)
1809  FOREACH_STREAM({
1810  if (!stream->config.stats_fn)
1811  die("Stream %d: Must specify --fpf when --pass=%d"
1812  " and --passes=2\n",
1813  stream->index, global.pass);
1814  });
1815 
1816 #if !CONFIG_WEBM_IO
1817  FOREACH_STREAM({
1818  if (stream->config.write_webm) {
1819  stream->config.write_webm = 0;
1820  warn(
1821  "vpxenc was compiled without WebM container support."
1822  "Producing IVF output");
1823  }
1824  });
1825 #endif
1826 
1827  /* Use the frame rate from the file only if none was specified
1828  * on the command-line.
1829  */
1830  if (!global.have_framerate) {
1831  global.framerate.num = input.framerate.numerator;
1832  global.framerate.den = input.framerate.denominator;
1833  FOREACH_STREAM(stream->config.cfg.g_timebase.den = global.framerate.num;
1834  stream->config.cfg.g_timebase.num = global.framerate.den);
1835  }
1836 
1837  /* Show configuration */
1838  if (global.verbose && pass == 0)
1839  FOREACH_STREAM(show_stream_config(stream, &global, &input));
1840 
1841  if (pass == (global.pass ? global.pass - 1 : 0)) {
1842  // The Y4M reader does its own allocation.
1843  if (input.file_type != FILE_TYPE_Y4M) {
1844  vpx_img_alloc(&raw, input.fmt, input.width, input.height, 32);
1845  }
1846  FOREACH_STREAM(stream->rate_hist = init_rate_histogram(
1847  &stream->config.cfg, &global.framerate));
1848  }
1849 
1850  FOREACH_STREAM(setup_pass(stream, &global, pass));
1851  FOREACH_STREAM(
1852  open_output_file(stream, &global, &input.pixel_aspect_ratio));
1853  FOREACH_STREAM(initialize_encoder(stream, &global));
1854 
1855 #if CONFIG_VP9_HIGHBITDEPTH
1856  if (strcmp(global.codec->name, "vp9") == 0) {
1857  // Check to see if at least one stream uses 16 bit internal.
1858  // Currently assume that the bit_depths for all streams using
1859  // highbitdepth are the same.
1860  FOREACH_STREAM({
1861  if (stream->config.use_16bit_internal) {
1862  use_16bit_internal = 1;
1863  }
1864  if (stream->config.cfg.g_profile == 0) {
1865  input_shift = 0;
1866  } else {
1867  input_shift = (int)stream->config.cfg.g_bit_depth -
1868  stream->config.cfg.g_input_bit_depth;
1869  }
1870  });
1871  }
1872 #endif
1873 
1874  frame_avail = 1;
1875  got_data = 0;
1876 
1877  while (frame_avail || got_data) {
1878  struct vpx_usec_timer timer;
1879 
1880  if (!global.limit || frames_in < global.limit) {
1881  frame_avail = read_frame(&input, &raw);
1882 
1883  if (frame_avail) frames_in++;
1884  seen_frames =
1885  frames_in > global.skip_frames ? frames_in - global.skip_frames : 0;
1886 
1887  if (!global.quiet) {
1888  float fps = usec_to_fps(cx_time, seen_frames);
1889  fprintf(stderr, "\rPass %d/%d ", pass + 1, global.passes);
1890 
1891  if (stream_cnt == 1)
1892  fprintf(stderr, "frame %4d/%-4d %7" PRId64 "B ", frames_in,
1893  streams->frames_out, (int64_t)streams->nbytes);
1894  else
1895  fprintf(stderr, "frame %4d ", frames_in);
1896 
1897  fprintf(stderr, "%7" PRId64 " %s %.2f %s ",
1898  cx_time > 9999999 ? cx_time / 1000 : cx_time,
1899  cx_time > 9999999 ? "ms" : "us", fps >= 1.0 ? fps : fps * 60,
1900  fps >= 1.0 ? "fps" : "fpm");
1901  print_time("ETA", estimated_time_left);
1902  }
1903 
1904  } else
1905  frame_avail = 0;
1906 
1907  if (frames_in > global.skip_frames) {
1908 #if CONFIG_VP9_HIGHBITDEPTH
1909  vpx_image_t *frame_to_encode;
1910  if (input_shift || (use_16bit_internal && input.bit_depth == 8)) {
1911  assert(use_16bit_internal);
1912  // Input bit depth and stream bit depth do not match, so up
1913  // shift frame to stream bit depth
1914  if (!allocated_raw_shift) {
1915  vpx_img_alloc(&raw_shift, raw.fmt | VPX_IMG_FMT_HIGHBITDEPTH,
1916  input.width, input.height, 32);
1917  allocated_raw_shift = 1;
1918  }
1919  vpx_img_upshift(&raw_shift, &raw, input_shift);
1920  frame_to_encode = &raw_shift;
1921  } else {
1922  frame_to_encode = &raw;
1923  }
1924  vpx_usec_timer_start(&timer);
1925  if (use_16bit_internal) {
1926  assert(frame_to_encode->fmt & VPX_IMG_FMT_HIGHBITDEPTH);
1927  FOREACH_STREAM({
1928  if (stream->config.use_16bit_internal)
1929  encode_frame(stream, &global,
1930  frame_avail ? frame_to_encode : NULL, frames_in);
1931  else
1932  assert(0);
1933  });
1934  } else {
1935  assert((frame_to_encode->fmt & VPX_IMG_FMT_HIGHBITDEPTH) == 0);
1936  FOREACH_STREAM(encode_frame(stream, &global,
1937  frame_avail ? frame_to_encode : NULL,
1938  frames_in));
1939  }
1940 #else
1941  vpx_usec_timer_start(&timer);
1942  FOREACH_STREAM(encode_frame(stream, &global, frame_avail ? &raw : NULL,
1943  frames_in));
1944 #endif
1945  vpx_usec_timer_mark(&timer);
1946  cx_time += vpx_usec_timer_elapsed(&timer);
1947 
1948  FOREACH_STREAM(update_quantizer_histogram(stream));
1949 
1950  got_data = 0;
1951  FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
1952 
1953  if (!got_data && input.length && streams != NULL &&
1954  !streams->frames_out) {
1955  lagged_count = global.limit ? seen_frames : ftello(input.file);
1956  } else if (input.length) {
1957  int64_t remaining;
1958  int64_t rate;
1959 
1960  if (global.limit) {
1961  const int64_t frame_in_lagged = (seen_frames - lagged_count) * 1000;
1962 
1963  rate = cx_time ? frame_in_lagged * (int64_t)1000000 / cx_time : 0;
1964  remaining = 1000 * (global.limit - global.skip_frames -
1965  seen_frames + lagged_count);
1966  } else {
1967  const int64_t input_pos = ftello(input.file);
1968  const int64_t input_pos_lagged = input_pos - lagged_count;
1969  const int64_t limit = input.length;
1970 
1971  rate = cx_time ? input_pos_lagged * (int64_t)1000000 / cx_time : 0;
1972  remaining = limit - input_pos + lagged_count;
1973  }
1974 
1975  average_rate =
1976  (average_rate <= 0) ? rate : (average_rate * 7 + rate) / 8;
1977  estimated_time_left = average_rate ? remaining / average_rate : -1;
1978  }
1979 
1980  if (got_data && global.test_decode != TEST_DECODE_OFF)
1981  FOREACH_STREAM(test_decode(stream, global.test_decode, global.codec));
1982  }
1983 
1984  fflush(stdout);
1985  if (!global.quiet) fprintf(stderr, "\033[K");
1986  }
1987 
1988  if (stream_cnt > 1) fprintf(stderr, "\n");
1989 
1990  if (!global.quiet) {
1991  FOREACH_STREAM(fprintf(
1992  stderr,
1993  "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64 "b/f %7" PRId64
1994  "b/s %7" PRId64 " %s (%.2f fps)\033[K\n",
1995  pass + 1, global.passes, frames_in, stream->frames_out,
1996  (int64_t)stream->nbytes,
1997  seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0,
1998  seen_frames
1999  ? (int64_t)stream->nbytes * 8 * (int64_t)global.framerate.num /
2000  global.framerate.den / seen_frames
2001  : 0,
2002  stream->cx_time > 9999999 ? stream->cx_time / 1000 : stream->cx_time,
2003  stream->cx_time > 9999999 ? "ms" : "us",
2004  usec_to_fps(stream->cx_time, seen_frames)));
2005  }
2006 
2007  if (global.show_psnr) {
2008  if (global.codec->fourcc == VP9_FOURCC) {
2009  FOREACH_STREAM(
2010  show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1));
2011  } else {
2012  FOREACH_STREAM(show_psnr(stream, 255.0));
2013  }
2014  }
2015 
2016  FOREACH_STREAM(vpx_codec_destroy(&stream->encoder));
2017 
2018  if (global.test_decode != TEST_DECODE_OFF) {
2019  FOREACH_STREAM(vpx_codec_destroy(&stream->decoder));
2020  }
2021 
2022  close_input_file(&input);
2023 
2024  if (global.test_decode == TEST_DECODE_FATAL) {
2025  FOREACH_STREAM(res |= stream->mismatch_seen);
2026  }
2027  FOREACH_STREAM(close_output_file(stream, global.codec->fourcc));
2028 
2029  FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1));
2030 
2031  if (global.pass) break;
2032  }
2033 
2034  if (global.show_q_hist_buckets)
2035  FOREACH_STREAM(
2036  show_q_histogram(stream->counts, global.show_q_hist_buckets));
2037 
2038  if (global.show_rate_hist_buckets)
2039  FOREACH_STREAM(show_rate_histogram(stream->rate_hist, &stream->config.cfg,
2040  global.show_rate_hist_buckets));
2041  FOREACH_STREAM(destroy_rate_histogram(stream->rate_hist));
2042 
2043 #if CONFIG_INTERNAL_STATS
2044  /* TODO(jkoleszar): This doesn't belong in this executable. Do it for now,
2045  * to match some existing utilities.
2046  */
2047  if (!(global.pass == 1 && global.passes == 2))
2048  FOREACH_STREAM({
2049  FILE *f = fopen("opsnr.stt", "a");
2050  if (stream->mismatch_seen) {
2051  fprintf(f, "First mismatch occurred in frame %d\n",
2052  stream->mismatch_seen);
2053  } else {
2054  fprintf(f, "No mismatch detected in recon buffers\n");
2055  }
2056  fclose(f);
2057  });
2058 #endif
2059 
2060 #if CONFIG_VP9_HIGHBITDEPTH
2061  if (allocated_raw_shift) vpx_img_free(&raw_shift);
2062 #endif
2063  vpx_img_free(&raw);
2064  free(argv);
2065  free(streams);
2066  return res ? EXIT_FAILURE : EXIT_SUCCESS;
2067 }
const char * vpx_codec_error_detail(vpx_codec_ctx_t *ctx)
Retrieve detailed error information for codec context.
const char * vpx_codec_error(vpx_codec_ctx_t *ctx)
Retrieve error synopsis for codec context.
vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
Destroy a codec instance.
const void * vpx_codec_iter_t
Iterator.
Definition: vpx_codec.h:190
const char * vpx_codec_iface_name(vpx_codec_iface_t *iface)
Return the name for a given interface.
const char * vpx_codec_err_to_string(vpx_codec_err_t err)
Convert error number to printable string.
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition: vpx_codec.h:407
vpx_codec_err_t
Algorithm return codes.
Definition: vpx_codec.h:93
vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx, int ctrl_id,...)
Control algorithm.
@ VPX_BITS_8
Definition: vpx_codec.h:221
@ VPX_BITS_12
Definition: vpx_codec.h:223
@ VPX_BITS_10
Definition: vpx_codec.h:222
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.
#define vpx_codec_dec_init(ctx, iface, cfg, flags)
Convenience macro for vpx_codec_dec_init_ver()
Definition: vpx_decoder.h:143
#define VPX_DL_REALTIME
deadline parameter analogous to VPx REALTIME mode.
Definition: vpx_encoder.h:978
#define vpx_codec_enc_init(ctx, iface, cfg, flags)
Convenience macro for vpx_codec_enc_init_ver()
Definition: vpx_encoder.h:889
#define VPX_CODEC_USE_PSNR
Initialization-time Feature Enabling.
Definition: vpx_encoder.h:89
#define VPX_DL_GOOD_QUALITY
deadline parameter analogous to VPx GOOD QUALITY mode.
Definition: vpx_encoder.h:980
#define VPX_CODEC_USE_HIGHBITDEPTH
Definition: vpx_encoder.h:92
int64_t vpx_codec_pts_t
Time Stamp Type.
Definition: vpx_encoder.h:108
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.
#define VPX_DL_BEST_QUALITY
deadline parameter analogous to VPx BEST QUALITY mode.
Definition: vpx_encoder.h:982
#define VPX_CODEC_USE_OUTPUT_PARTITION
Make the encoder output one partition at a time.
Definition: vpx_encoder.h:91
const vpx_codec_cx_pkt_t * vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter)
Encoded data iterator.
vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx, const vpx_image_t *img, vpx_codec_pts_t pts, unsigned long duration, vpx_enc_frame_flags_t flags, unsigned long deadline)
Encode a frame.
#define VPX_FRAME_IS_FRAGMENT
this is a fragment of the encoded frame
Definition: vpx_encoder.h:125
@ VPX_CODEC_PSNR_PKT
Definition: vpx_encoder.h:152
@ VPX_CODEC_CX_FRAME_PKT
Definition: vpx_encoder.h:149
@ VPX_CODEC_STATS_PKT
Definition: vpx_encoder.h:150
@ VPX_RC_LAST_PASS
Definition: vpx_encoder.h:229
@ VPX_RC_ONE_PASS
Definition: vpx_encoder.h:227
@ VPX_RC_FIRST_PASS
Definition: vpx_encoder.h:228
@ VPX_KF_DISABLED
Definition: vpx_encoder.h:251
@ VPX_Q
Definition: vpx_encoder.h:237
@ VPX_CQ
Definition: vpx_encoder.h:236
@ VPX_CBR
Definition: vpx_encoder.h:235
@ VPX_VBR
Definition: vpx_encoder.h:234
@ VP9E_SET_MIN_GF_INTERVAL
Codec control function to set minimum interval between GF/ARF frames.
Definition: vp8cx.h:519
@ VP9E_SET_MAX_INTER_BITRATE_PCT
Codec control function to set max data rate for Inter frames.
Definition: vp8cx.h:295
@ VP9E_SET_FRAME_PERIODIC_BOOST
Codec control function to enable/disable periodic Q boost.
Definition: vp8cx.h:430
@ VP8E_SET_MAX_INTRA_BITRATE_PCT
Codec control function to set Max data rate for Intra frames.
Definition: vp8cx.h:274
@ VP8E_SET_ARNR_STRENGTH
Codec control function to set the filter strength for the arf.
Definition: vp8cx.h:240
@ VP8E_SET_TUNING
Codec control function to set visual tuning.
Definition: vp8cx.h:249
@ VP8E_SET_ENABLEAUTOALTREF
Codec control function to enable automatic use of arf frames.
Definition: vp8cx.h:181
@ VP9E_SET_TARGET_LEVEL
Codec control function to set target level.
Definition: vp8cx.h:567
@ VP9E_SET_AQ_MODE
Codec control function to set adaptive quantization mode.
Definition: vp8cx.h:415
@ VP8E_SET_NOISE_SENSITIVITY
control function to set noise sensitivity
Definition: vp8cx.h:190
@ VP8E_SET_TOKEN_PARTITIONS
Codec control function to set the number of token partitions.
Definition: vp8cx.h:211
@ VP8E_SET_ARNR_TYPE
Definition: vp8cx.h:243
@ VP9E_SET_TILE_ROWS
Codec control function to set number of tile rows.
Definition: vp8cx.h:388
@ VP8E_SET_ARNR_MAXFRAMES
Codec control function to set the max no of frames to create arf.
Definition: vp8cx.h:234
@ VP9E_SET_LOSSLESS
Codec control function to set lossless encoding mode.
Definition: vp8cx.h:344
@ VP9E_SET_FRAME_PARALLEL_DECODING
Codec control function to enable frame parallel decoding feature.
Definition: vp8cx.h:402
@ VP8E_SET_SHARPNESS
Codec control function to set higher sharpness at the expense of a lower PSNR.
Definition: vp8cx.h:199
@ VP8E_SET_GF_CBR_BOOST_PCT
Boost percentage for Golden Frame in CBR mode.
Definition: vp8cx.h:606
@ VP9E_SET_TUNE_CONTENT
Codec control function to set content type.
Definition: vp8cx.h:480
@ VP9E_SET_TPL
Codec control function to enable temporal dependency model.
Definition: vp8cx.h:673
@ VP9E_SET_ROW_MT
Codec control function to set row level multi-threading.
Definition: vp8cx.h:575
@ VP8E_SET_CPUUSED
Codec control function to set encoder internal speed settings.
Definition: vp8cx.h:172
@ VP9E_SET_TILE_COLUMNS
Codec control function to set number of tile columns.
Definition: vp8cx.h:368
@ VP8E_SET_STATIC_THRESHOLD
Codec control function to set the threshold for MBs treated static.
Definition: vp8cx.h:205
@ VP9E_SET_COLOR_SPACE
Codec control function to set color space info.
Definition: vp8cx.h:511
@ VP8E_SET_SCREEN_CONTENT_MODE
Codec control function to set encoder screen content mode.
Definition: vp8cx.h:329
@ VP9E_SET_DISABLE_LOOPFILTER
Codec control function to disable loopfilter.
Definition: vp8cx.h:708
@ VP8E_SET_CQ_LEVEL
Codec control function to set constrained / constant quality level.
Definition: vp8cx.h:259
@ VP9E_SET_NOISE_SENSITIVITY
Codec control function to set noise sensitivity.
Definition: vp8cx.h:438
@ VP8E_GET_LAST_QUANTIZER_64
Codec control function to get last quantizer chosen by the encoder.
Definition: vp8cx.h:228
@ VP9E_SET_GF_CBR_BOOST_PCT
Boost percentage for Golden Frame in CBR mode.
Definition: vp8cx.h:310
@ VP9E_SET_MAX_GF_INTERVAL
Codec control function to set minimum interval between GF/ARF frames.
Definition: vp8cx.h:527
@ VP9E_SET_ALT_REF_AQ
Codec control function to enable/disable special mode for altref adaptive quantization....
Definition: vp8cx.h:591
@ VP8_COPY_REFERENCE
Definition: vp8.h:48
@ VP9_GET_REFERENCE
Definition: vp8.h:55
VP9 specific reference frame data struct.
Definition: vp8.h:110
int idx
Definition: vp8.h:111
Codec context structure.
Definition: vpx_codec.h:200
Encoder output packet.
Definition: vpx_encoder.h:161
vpx_fixed_buf_t twopass_stats
Definition: vpx_encoder.h:184
enum vpx_codec_cx_pkt_kind kind
Definition: vpx_encoder.h:162
double psnr[4]
Definition: vpx_encoder.h:189
struct vpx_codec_cx_pkt::@1::@2 frame
vpx_fixed_buf_t raw
Definition: vpx_encoder.h:191
union vpx_codec_cx_pkt::@1 data
Encoder configuration structure.
Definition: vpx_encoder.h:270
unsigned int g_h
Height of the frame.
Definition: vpx_encoder.h:315
unsigned int g_w
Width of the frame.
Definition: vpx_encoder.h:306
struct vpx_rational g_timebase
Stream timebase units.
Definition: vpx_encoder.h:345
enum vpx_enc_pass g_pass
Multi-pass Encoding Mode.
Definition: vpx_encoder.h:360
size_t sz
Definition: vpx_encoder.h:100
void * buf
Definition: vpx_encoder.h:99
Image Descriptor.
Definition: vpx_image.h:72
vpx_img_fmt_t fmt
Definition: vpx_image.h:73
unsigned int d_h
Definition: vpx_image.h:84
unsigned int d_w
Definition: vpx_image.h:83
unsigned char * planes[4]
Definition: vpx_image.h:100
int stride[4]
Definition: vpx_image.h:101
Rational Number.
Definition: vpx_encoder.h:220
int den
Definition: vpx_encoder.h:222
int num
Definition: vpx_encoder.h:221
reference frame data struct
Definition: vp8.h:101
Provides definitions for using VP8 or VP9 encoder algorithm within the vpx Codec Interface.
Provides definitions for using VP8 or VP9 within the vpx Decoder interface.
Describes the decoder algorithm interface to applications.
Describes the encoder algorithm interface to applications.
@ VPX_CS_BT_709
Definition: vpx_image.h:57
@ VPX_CS_SRGB
Definition: vpx_image.h:62
@ VPX_CS_BT_601
Definition: vpx_image.h:56
@ VPX_CS_BT_2020
Definition: vpx_image.h:60
@ VPX_CS_SMPTE_170
Definition: vpx_image.h:58
@ VPX_CS_UNKNOWN
Definition: vpx_image.h:55
@ VPX_CS_SMPTE_240
Definition: vpx_image.h:59
@ VPX_CS_RESERVED
Definition: vpx_image.h:61
#define VPX_PLANE_Y
Definition: vpx_image.h:96
#define VPX_IMG_FMT_HIGHBITDEPTH
Definition: vpx_image.h:35
#define VPX_PLANE_U
Definition: vpx_image.h:97
@ VPX_IMG_FMT_I42216
Definition: vpx_image.h:48
@ VPX_IMG_FMT_I44016
Definition: vpx_image.h:50
@ VPX_IMG_FMT_NV12
Definition: vpx_image.h:46
@ VPX_IMG_FMT_YV12
Definition: vpx_image.h:40
@ VPX_IMG_FMT_I42016
Definition: vpx_image.h:47
@ VPX_IMG_FMT_I444
Definition: vpx_image.h:44
@ VPX_IMG_FMT_I440
Definition: vpx_image.h:45
@ VPX_IMG_FMT_I44416
Definition: vpx_image.h:49
@ VPX_IMG_FMT_I420
Definition: vpx_image.h:42
@ VPX_IMG_FMT_I422
Definition: vpx_image.h:43
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.
#define VPX_PLANE_V
Definition: vpx_image.h:98
enum vpx_img_fmt vpx_img_fmt_t
List of supported image formats.
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.