1
2
3
4
5
6
7
8
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
27#if CONFIG_DECODERS
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
37#endif
38#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
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
53static 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
59static const char *exec_name;
60
61static VPX_TOOLS_FORMAT_PRINTF(3, 0) void warn_or_exit_on_errorv(
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
75static VPX_TOOLS_FORMAT_PRINTF(2,
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
85static VPX_TOOLS_FORMAT_PRINTF(3, 4) void warn_or_exit_on_error(
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
94static const arg_def_t help =
95 ARG_DEF(NULL, "help", 0, "Show usage options and exit");
96static const arg_def_t debugmode =
97 ARG_DEF("D", "debug", 0, "Debug mode (makes output deterministic)");
98static const arg_def_t outputfile =
99 ARG_DEF("o", "output", 1, "Output filename");
100static const arg_def_t use_nv12 =
101 ARG_DEF(NULL, "nv12", 0, "Input file is NV12 ");
102static const arg_def_t use_yv12 =
103 ARG_DEF(NULL, "yv12", 0, "Input file is YV12 ");
104static const arg_def_t use_i420 =
105 ARG_DEF(NULL, "i420", 0, "Input file is I420 (default)");
106static const arg_def_t use_i422 =
107 ARG_DEF(NULL, "i422", 0, "Input file is I422");
108static const arg_def_t use_i444 =
109 ARG_DEF(NULL, "i444", 0, "Input file is I444");
110static const arg_def_t use_i440 =
111 ARG_DEF(NULL, "i440", 0, "Input file is I440");
112static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use");
113static const arg_def_t passes =
114 ARG_DEF("p", "passes", 1, "Number of passes (1/2)");
115static const arg_def_t pass_arg =
116 ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)");
117static const arg_def_t fpf_name =
118 ARG_DEF(NULL, "fpf", 1, "First pass statistics file name");
119static const arg_def_t limit =
120 ARG_DEF(NULL, "limit", 1, "Stop encoding after n input frames");
121static const arg_def_t skip =
122 ARG_DEF(NULL, "skip", 1, "Skip the first n input frames");
123static const arg_def_t deadline =
124 ARG_DEF("d", "deadline", 1, "Deadline per frame (usec)");
125static const arg_def_t best_dl =
126 ARG_DEF(NULL, "best", 0, "Use Best Quality Deadline");
127static const arg_def_t good_dl =
128 ARG_DEF(NULL, "good", 0, "Use Good Quality Deadline");
129static const arg_def_t rt_dl =
130 ARG_DEF(NULL, "rt", 0, "Use Realtime Quality Deadline");
131static const arg_def_t quietarg =
132 ARG_DEF("q", "quiet", 0, "Do not print encode progress");
133static const arg_def_t verbosearg =
134 ARG_DEF("v", "verbose", 0, "Show encoder parameters");
135static const arg_def_t psnrarg =
136 ARG_DEF(NULL, "psnr", 0, "Show PSNR in status line");
137
138static 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};
144static const arg_def_t recontest = ARG_DEF_ENUM(
145 NULL, "test-decode", 1, "Test encode/decode mismatch", test_decode_enum);
146static const arg_def_t framerate =
147 ARG_DEF(NULL, "fps", 1, "Stream frame rate (rate/scale)");
148static const arg_def_t use_webm =
149 ARG_DEF(NULL, "webm", 0, "Output WebM (default when WebM IO is enabled)");
150static const arg_def_t use_ivf = ARG_DEF(NULL, "ivf", 0, "Output IVF");
151static const arg_def_t out_part =
152 ARG_DEF("P", "output-partitions", 0,
153 "Makes encoder output partitions. Requires IVF output!");
154static const arg_def_t q_hist_n =
155 ARG_DEF(NULL, "q-hist", 1, "Show quantizer histogram (n-buckets)");
156static const arg_def_t rate_hist_n =
157 ARG_DEF(NULL, "rate-hist", 1, "Show rate histogram (n-buckets)");
158static const arg_def_t disable_warnings =
159 ARG_DEF(NULL, "disable-warnings", 0,
160 "Disable warnings about potentially incorrect encode settings.");
161static 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
166static const arg_def_t test16bitinternalarg = ARG_DEF(
167 NULL, "test-16bit-internal", 0, "Force use of 16 bit internal buffer");
168#endif
169
170static 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
196static const arg_def_t usage =
197 ARG_DEF("u", "usage", 1, "Usage profile number to use");
198static const arg_def_t threads =
199 ARG_DEF("t", "threads", 1, "Max number of threads to use");
200static const arg_def_t profile =
201 ARG_DEF(NULL, "profile", 1, "Bitstream profile number to use");
202static const arg_def_t width = ARG_DEF("w", "width", 1, "Frame width");
203static const arg_def_t height = ARG_DEF("h", "height", 1, "Frame height");
204#if CONFIG_WEBM_IO
205static 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};
213static const arg_def_t stereo_mode = ARG_DEF_ENUM(
214 NULL, "stereo-mode", 1, "Stereo 3D video format", stereo_mode_enum);
215#endif
216static const arg_def_t timebase = ARG_DEF(
217 NULL, "timebase", 1, "Output timestamp precision (fractional seconds)");
218static const arg_def_t error_resilient =
219 ARG_DEF(NULL, "error-resilient", 1, "Enable error resiliency features");
220static const arg_def_t lag_in_frames =
221 ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag");
222
223static 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
246static const arg_def_t dropframe_thresh =
247 ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
248static const arg_def_t resize_allowed =
249 ARG_DEF(NULL, "resize-allowed", 1, "Spatial resampling enabled (bool)");
250static const arg_def_t resize_width =
251 ARG_DEF(NULL, "resize-width", 1, "Width of encoded frame");
252static const arg_def_t resize_height =
253 ARG_DEF(NULL, "resize-height", 1, "Height of encoded frame");
254static const arg_def_t resize_up_thresh =
255 ARG_DEF(NULL, "resize-up", 1, "Upscale threshold (buf %)");
256static const arg_def_t resize_down_thresh =
257 ARG_DEF(NULL, "resize-down", 1, "Downscale threshold (buf %)");
258static const struct arg_enum_list end_usage_enum[] = { {
"vbr",
VPX_VBR },
262 { NULL, 0 } };
263static const arg_def_t end_usage =
264 ARG_DEF_ENUM(NULL, "end-usage", 1, "Rate control mode", end_usage_enum);
265static const arg_def_t target_bitrate =
266 ARG_DEF(NULL, "target-bitrate", 1, "Bitrate (kbps)");
267static const arg_def_t min_quantizer =
268 ARG_DEF(NULL, "min-q", 1, "Minimum (best) quantizer");
269static const arg_def_t max_quantizer =
270 ARG_DEF(NULL, "max-q", 1, "Maximum (worst) quantizer");
271static const arg_def_t undershoot_pct =
272 ARG_DEF(NULL, "undershoot-pct", 1, "Datarate undershoot (min) target (%)");
273static const arg_def_t overshoot_pct =
274 ARG_DEF(NULL, "overshoot-pct", 1, "Datarate overshoot (max) target (%)");
275static const arg_def_t buf_sz =
276 ARG_DEF(NULL, "buf-sz", 1, "Client buffer size (ms)");
277static const arg_def_t buf_initial_sz =
278 ARG_DEF(NULL, "buf-initial-sz", 1, "Client initial buffer size (ms)");
279static const arg_def_t buf_optimal_sz =
280 ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)");
281static 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
289static const arg_def_t use_vizier_rc_params =
290 ARG_DEF(NULL, "use-vizier-rc-params", 1, "Use vizier rc params");
291static const arg_def_t active_wq_factor =
292 ARG_DEF(NULL, "active-wq-factor", 1, "Active worst quality factor");
293static const arg_def_t err_per_mb_factor =
294 ARG_DEF(NULL, "err-per-mb-factor", 1, "Error per macroblock factor");
295static const arg_def_t sr_default_decay_limit = ARG_DEF(
296 NULL, "sr-default-decay-limit", 1, "Second reference default decay limit");
297static const arg_def_t sr_diff_factor =
298 ARG_DEF(NULL, "sr-diff-factor", 1, "Second reference diff factor");
299static const arg_def_t kf_err_per_mb_factor = ARG_DEF(
300 NULL, "kf-err-per-mb-factor", 1, "Keyframe error per macroblock factor");
301static const arg_def_t kf_frame_min_boost_factor =
302 ARG_DEF(NULL, "kf-frame-min-boost-factor", 1, "Keyframe min boost");
303static 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");
306static 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");
309static const arg_def_t kf_max_total_boost_factor = ARG_DEF(
310 NULL, "kf-max-total-boost-factor", 1, "Keyframe max total boost factor");
311static 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");
314static 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");
317static const arg_def_t zm_factor =
318 ARG_DEF(NULL, "zm-factor", 1, "Zero motion power factor");
319static 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");
322static 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");
325static 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");
327static 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
346static const arg_def_t bias_pct =
347 ARG_DEF(NULL, "bias-pct", 1, "CBR/VBR bias (0=CBR, 100=VBR)");
348static const arg_def_t minsection_pct =
349 ARG_DEF(NULL, "minsection-pct", 1, "GOP min bitrate (% of target)");
350static const arg_def_t maxsection_pct =
351 ARG_DEF(NULL, "maxsection-pct", 1, "GOP max bitrate (% of target)");
352static const arg_def_t corpus_complexity =
353 ARG_DEF(NULL, "corpus-complexity", 1, "corpus vbr complexity midpoint");
354static const arg_def_t *rc_twopass_args[] = { &bias_pct, &minsection_pct,
355 &maxsection_pct,
356 &corpus_complexity, NULL };
357
358static const arg_def_t kf_min_dist =
359 ARG_DEF(NULL, "kf-min-dist", 1, "Minimum keyframe interval (frames)");
360static const arg_def_t kf_max_dist =
361 ARG_DEF(NULL, "kf-max-dist", 1, "Maximum keyframe interval (frames)");
362static const arg_def_t kf_disabled =
363 ARG_DEF(NULL, "disable-kf", 0, "Disable keyframe placement");
364static const arg_def_t *kf_args[] = { &kf_min_dist, &kf_max_dist, &kf_disabled,
365 NULL };
366
367static const arg_def_t noise_sens =
368 ARG_DEF(NULL, "noise-sensitivity", 1, "Noise sensitivity (frames to blur)");
369static const arg_def_t sharpness =
370 ARG_DEF(NULL, "sharpness", 1,
371 "Increase sharpness at the expense of lower PSNR. (0..7)");
372static const arg_def_t static_thresh =
373 ARG_DEF(NULL, "static-thresh", 1, "Motion detection threshold");
374static const arg_def_t arnr_maxframes =
375 ARG_DEF(NULL, "arnr-maxframes", 1, "AltRef max frames (0..15)");
376static const arg_def_t arnr_strength =
377 ARG_DEF(NULL, "arnr-strength", 1, "AltRef filter strength (0..6)");
378static const arg_def_t arnr_type =
379 ARG_DEF(NULL, "arnr-type", 1, "AltRef filter type (1..3)");
380static const struct arg_enum_list tuning_enum[] = { { "psnr", VP8_TUNE_PSNR },
381 { "ssim", VP8_TUNE_SSIM },
382 { NULL, 0 } };
383static const arg_def_t tune_ssim =
384 ARG_DEF_ENUM(NULL, "tune", 1, "Material to favor", tuning_enum);
385static const arg_def_t cq_level =
386 ARG_DEF(NULL, "cq-level", 1, "Constant/Constrained Quality level");
387static const arg_def_t max_intra_rate_pct =
388 ARG_DEF(NULL, "max-intra-rate", 1, "Max I-frame bitrate (pct)");
389static 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
393static const arg_def_t cpu_used_vp8 =
394 ARG_DEF(NULL, "cpu-used", 1, "CPU Used (-16..16)");
395static const arg_def_t auto_altref_vp8 = ARG_DEF(
396 NULL, "auto-alt-ref", 1, "Enable automatic alt reference frames. (0..1)");
397static const arg_def_t token_parts =
398 ARG_DEF(NULL, "token-parts", 1, "Number of token partitions to use, log2");
399static const arg_def_t screen_content_mode =
400 ARG_DEF(NULL, "screen-content-mode", 1, "Screen content mode");
401static 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 };
430 0 };
431#endif
432
433#if CONFIG_VP9_ENCODER
434static const arg_def_t cpu_used_vp9 =
435 ARG_DEF(NULL, "cpu-used", 1, "CPU Used (-9..9)");
436static 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)");
439static const arg_def_t tile_cols =
440 ARG_DEF(NULL, "tile-columns", 1, "Number of tile columns to use, log2");
441static 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
445static const arg_def_t enable_tpl_model =
446 ARG_DEF(NULL, "enable-tpl", 1, "Enable temporal dependency model");
447static 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
451static const arg_def_t lossless =
452 ARG_DEF(NULL, "lossless", 1, "Lossless mode (0: false (default), 1: true)");
453static const arg_def_t frame_parallel_decoding = ARG_DEF(
454 NULL, "frame-parallel", 1, "Enable frame parallel decodability features");
455static 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)");
459static const arg_def_t alt_ref_aq = ARG_DEF(NULL, "alt-ref-aq", 1,
460 "Special adaptive quantization for "
461 "the alternate reference frames.");
462static const arg_def_t frame_periodic_boost =
463 ARG_DEF(NULL, "frame-boost", 1,
464 "Enable frame periodic boost (0: off (default), 1: on)");
465static const arg_def_t max_inter_rate_pct =
466 ARG_DEF(NULL, "max-inter-rate", 1, "Max P-frame bitrate (pct)");
467static 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)");
470static 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
474static const struct arg_enum_list color_space_enum[] = {
483 { NULL, 0 }
484};
485
486static 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
491static const struct arg_enum_list bitdepth_enum[] = {
493};
494
495static 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);
499static const arg_def_t inbitdeptharg =
500 ARG_DEF(NULL, "input-bit-depth", 1, "Actual bit depth of input source");
501#endif
502
503static 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
510static const arg_def_t tune_content = ARG_DEF_ENUM(
511 NULL, "tune-content", 1, "Tune content type", tune_content_enum);
512
513static 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
524static const arg_def_t row_mt =
525 ARG_DEF(NULL, "row-mt", 1,
526 "Enable row based non-deterministic multi-threading in VP9");
527
528static 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");
537static 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
545static 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
576
577
578#if CONFIG_VP9_HIGHBITDEPTH
579 &bitdeptharg,
580 &inbitdeptharg,
581#endif
582 NULL };
613 0 };
614#endif
615
616static const arg_def_t *no_args[] = { NULL };
617
618static 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,
661 }
662 fprintf(fout, "\n ");
663 fprintf(fout, "Use --codec to switch to a non-default encoder.\n\n");
664}
665
666void 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
679typedef int stereo_format_t;
680struct WebmOutputContext {
681 int debug;
682};
683#endif
684
685
686struct 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
696 int use_16bit_internal;
697#endif
698};
699
700struct 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];
713 unsigned int frames_out;
714 uint64_t cx_time;
715 size_t nbytes;
716 stats_io_t stats;
717 struct vpx_image *img;
719 int mismatch_seen;
720};
721
722static void validate_positive_rational(const char *msg,
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
734static 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
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
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))
775 else if (arg_match(&arg, &good_dl, argi))
777 else if (arg_match(&arg, &rt_dl, argi))
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
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
832 if (global->passes == 0) {
833#if CONFIG_VP9_ENCODER
834
835
836 if (global->codec != NULL && global->codec->name != NULL)
837 global->passes = (strcmp(global->codec->name, "vp9") == 0 &&
839 ? 2
840 : 1;
841#else
842 global->passes = 1;
843#endif
844 }
845
847 warn("Enforcing one-pass encoding in realtime mode\n");
848 global->passes = 1;
849 }
850}
851
852static 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 {
867
868
870 &stream->config.cfg, global->usage);
872
873
874
875
876 stream->config.cfg.g_timebase.den = 1000;
877
878
879
880
881 stream->config.cfg.g_w = 0;
882 stream->config.cfg.g_h = 0;
883
884
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
894 stream->webm_ctx.debug = global->debug;
895
896
898 stream->config.cfg.rc_end_usage ==
VPX_CBR)
899 stream->config.cfg.g_lag_in_frames = 0;
900 }
901
902
903 stream->config.out_fn = NULL;
904
905 stream->next = NULL;
906 return stream;
907}
908
909static 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
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
939
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);
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)) {
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
1097
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
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
1133static 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
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
1154 if (!streami->config.out_fn)
1155 fatal("Stream %d: Output file is required (specify with -o)",
1156 streami->index);
1157
1158
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
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
1178static 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
1191static 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
1200 switch (f) {
1210 default: return "Other";
1211 }
1212}
1213
1214static 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",
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
1267 SHOW(use_vizier_rc_params);
1268 SHOW(active_wq_factor.num);
1269 SHOW(active_wq_factor.den);
1270}
1271
1272static 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;
1277
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
1302static void close_output_file(struct stream_state *stream,
1303 unsigned int fourcc) {
1305
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
1323static 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
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
1345static void initialize_encoder(struct stream_state *stream,
1346 struct VpxEncoderConfig *global) {
1347 int i;
1348 int flags = 0;
1349
1352#if CONFIG_VP9_HIGHBITDEPTH
1354#endif
1355
1356
1358 &stream->config.cfg, flags);
1359 ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder");
1360
1361
1362
1363
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];
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);
1378 }
1379#endif
1380}
1381
1382static void encode_frame(struct stream_state *stream,
1383 struct VpxEncoderConfig *global,
struct vpx_image *img,
1384 unsigned int frames_in) {
1387 struct vpx_usec_timer timer;
1388
1389 frame_start =
1390 (cfg->
g_timebase.
den * (int64_t)(frames_in - 1) * global->framerate.den) /
1392 next_frame_start =
1393 (cfg->
g_timebase.
den * (int64_t)(frames_in)*global->framerate.den) /
1395
1396
1397#if CONFIG_VP9_HIGHBITDEPTH
1398 if (img) {
1400 (img->d_w != cfg->
g_w || img->d_h != cfg->
g_h)) {
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 =
1409 }
1410 I420Scale_16(
1414 img->d_w, img->d_h, (uint16_t *)stream->img->planes[
VPX_PLANE_Y],
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)) {
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 =
1442 I420Scale(
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);
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
1471static void update_quantizer_histogram(struct stream_state *stream) {
1473 int q;
1474
1476 ctx_exit_on_error(&stream->encoder, "Failed to read quantizer");
1477 stream->counts[q]++;
1478 }
1479}
1480
1481static void get_cx_data(struct stream_state *stream,
1482 struct VpxEncoderConfig *global, int *got_data) {
1486
1487 *got_data = 0;
1489 static size_t fsize = 0;
1490 static FileOffset ivf_header_pos = 0;
1491
1492 switch (pkt->
kind) {
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) {
1508 ivf_header_pos = ftello(stream->file);
1510
1511 ivf_write_frame_header(stream->file, pkt->
data.
frame.
pts, fsize);
1512 } else {
1514
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
1524 stream->file);
1525 }
1527
1528 *got_data = 1;
1529#if CONFIG_DECODERS
1530 if (global->test_decode != TEST_DECODE_OFF && !stream->mismatch_seen) {
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;
1544 stream->frames_out++;
1548 break;
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
1570static 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
1587static float usec_to_fps(uint64_t usec, unsigned int frames) {
1588 return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0);
1589}
1590
1591static void test_decode(struct stream_state *stream,
1592 enum TestDecodeFatality fatal,
1593 const VpxInterface *codec) {
1595
1596 if (stream->mismatch_seen) return;
1597
1598
1599 if (strcmp(codec->name, "vp8") == 0) {
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
1605 1);
1606 enc_img = ref_enc.img;
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;
1615 } else {
1617
1619 ref_dec.idx = 0;
1621 enc_img = ref_enc.img;
1623 dec_img = ref_dec.img;
1624#if CONFIG_VP9_HIGHBITDEPTH
1629 enc_img.
d_w, enc_img.
d_h, 16);
1630 vpx_img_truncate_16_to_8(&enc_img, &ref_enc.img);
1631 }
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
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
1667}
1668
1669static 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
1688int main(int argc, const char **argv_) {
1689 int pass;
1691#if CONFIG_VP9_HIGHBITDEPTH
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
1712 input.framerate.numerator = 30;
1713 input.framerate.denominator = 1;
1714 input.only_i420 = 1;
1715 input.bit_depth = 0;
1716
1717
1718
1719
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) {
1737 }
1738
1739 {
1740
1741
1742
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
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
1762 input.filename = argv[0];
1763
1764 if (!input.filename) {
1765 fprintf(stderr, "No input file specified!\n");
1766 usage_exit();
1767 }
1768
1769
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
1781
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
1794 if (!input.width || !input.height)
1795 fatal(
1796 "Specify stream dimensions with --width (-w) "
1797 " and --height (-h)");
1798
1799
1800
1801
1802
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 });
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
1822
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
1844
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
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
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
1874
1875
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
1926 if (input_shift || (use_16bit_internal && input.bit_depth == 8)) {
1927 assert(use_16bit_internal);
1928
1929
1930 if (!allocated_raw_shift) {
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) {
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 {
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
2032
2033 if (global.test_decode != TEST_DECODE_OFF) {
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
2060
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
2077#endif
2079 free(argv);
2080 free(streams);
2081 return res ? EXIT_FAILURE : EXIT_SUCCESS;
2082}
const char * vpx_codec_err_to_string(vpx_codec_err_t err)
Convert error number to printable string.
struct vpx_codec_ctx vpx_codec_ctx_t
Codec context structure.
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.
#define vpx_codec_control(ctx, id, data)
vpx_codec_control wrapper macro
Definition vpx_codec.h:408
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
const vpx_codec_cx_pkt_t * vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter)
Encoded data iterator.
#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.
struct vpx_codec_cx_pkt vpx_codec_cx_pkt_t
Encoder output packet.
#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
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
union vpx_codec_cx_pkt::@105367030154200007005241002351245163342006201240 data
struct vpx_codec_cx_pkt::@105367030154200007005241002351245163342006201240::@337301343345304110063267327113124066016321050157 frame
vpx_codec_frame_flags_t flags
Definition vpx_encoder.h:177
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
size_t sz
Definition vpx_encoder.h:172
void * buf
Definition vpx_encoder.h:171
vpx_codec_pts_t pts
time stamp to show frame (in timebase units)
Definition vpx_encoder.h:174
vpx_fixed_buf_t raw
Definition vpx_encoder.h:198
int partition_id
the partition id defines the decoding order of the partitions. Only applicable when "output partition...
Definition vpx_encoder.h:181
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
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
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_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
#define VPX_PLANE_V
Definition vpx_image.h:102
enum vpx_img_fmt vpx_img_fmt_t
List of supported image formats.
struct vpx_image vpx_image_t
Image Descriptor.
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.