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