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