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