| AOMedia AV1 Codec

aomenc
1/*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12#include "apps/aomenc.h"
13
14#include "config/aom_config.h"
15
16#include <assert.h>
17#include <limits.h>
18#include <math.h>
19#include <stdarg.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#if CONFIG_AV1_DECODER
25#include "aom/aom_decoder.h"
26#include "aom/aomdx.h"
27#endif
28
29#include "aom/aom_encoder.h"
30#include "aom/aom_integer.h"
31#include "aom/aomcx.h"
32#include "aom_dsp/aom_dsp_common.h"
33#include "aom_ports/aom_timer.h"
34#include "aom_ports/mem_ops.h"
35#include "common/args.h"
36#include "common/ivfenc.h"
37#include "common/tools_common.h"
38#include "common/warnings.h"
39
40#if CONFIG_WEBM_IO
41#include "common/webmenc.h"
42#endif
43
44#include "common/y4minput.h"
45#include "examples/encoder_util.h"
46#include "stats/aomstats.h"
47#include "stats/rate_hist.h"
48
49#if CONFIG_LIBYUV
50#include "third_party/libyuv/include/libyuv/scale.h"
51#endif
52
53/* Swallow warnings about unused results of fread/fwrite */
54 static size_t wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
55 return fread(ptr, size, nmemb, stream);
56}
57#define fread wrap_fread
58
59 static size_t wrap_fwrite(const void *ptr, size_t size, size_t nmemb,
60 FILE *stream) {
61 return fwrite(ptr, size, nmemb, stream);
62}
63#define fwrite wrap_fwrite
64
65 static const char *exec_name;
66
67 static AOM_TOOLS_FORMAT_PRINTF(3, 0) void warn_or_exit_on_errorv(
68 aom_codec_ctx_t *ctx, int fatal, const char *s, va_list ap) {
69 if (ctx->err) {
70 const char *detail = aom_codec_error_detail(ctx);
71
72 vfprintf(stderr, s, ap);
73 fprintf(stderr, ": %s\n", aom_codec_error(ctx));
74
75 if (detail) fprintf(stderr, " %s\n", detail);
76
77 if (fatal) {
78 aom_codec_destroy(ctx);
79 exit(EXIT_FAILURE);
80 }
81 }
82}
83
84 static AOM_TOOLS_FORMAT_PRINTF(2,
85 3) void ctx_exit_on_error(aom_codec_ctx_t *ctx,
86 const char *s, ...) {
87 va_list ap;
88
89 va_start(ap, s);
90 warn_or_exit_on_errorv(ctx, 1, s, ap);
91 va_end(ap);
92}
93
94 static AOM_TOOLS_FORMAT_PRINTF(3, 4) void warn_or_exit_on_error(
95 aom_codec_ctx_t *ctx, int fatal, const char *s, ...) {
96 va_list ap;
97
98 va_start(ap, s);
99 warn_or_exit_on_errorv(ctx, fatal, s, ap);
100 va_end(ap);
101}
102
103 static int read_frame(struct AvxInputContext *input_ctx, aom_image_t *img) {
104 FILE *f = input_ctx->file;
105 y4m_input *y4m = &input_ctx->y4m;
106 int shortread = 0;
107
108 if (input_ctx->file_type == FILE_TYPE_Y4M) {
109 if (y4m_input_fetch_frame(y4m, f, img) < 1) return 0;
110 } else {
111 shortread = read_yuv_frame(input_ctx, img);
112 }
113
114 return !shortread;
115}
116
117 static int file_is_y4m(const char detect[4]) {
118 if (memcmp(detect, "YUV4", 4) == 0) {
119 return 1;
120 }
121 return 0;
122}
123
124 static int fourcc_is_ivf(const char detect[4]) {
125 if (memcmp(detect, "DKIF", 4) == 0) {
126 return 1;
127 }
128 return 0;
129}
130
131 static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
132 AOME_SET_ENABLEAUTOALTREF,
133 AOME_SET_STATIC_THRESHOLD,
134 AV1E_SET_ROW_MT,
135 AV1E_SET_FP_MT,
136 AV1E_SET_TILE_COLUMNS,
137 AV1E_SET_TILE_ROWS,
138 AV1E_SET_ENABLE_TPL_MODEL,
139 AV1E_SET_ENABLE_KEYFRAME_FILTERING,
140 AOME_SET_ARNR_MAXFRAMES,
141 AOME_SET_ARNR_STRENGTH,
142 AOME_SET_TUNING,
143 AOME_SET_CQ_LEVEL,
144 AOME_SET_MAX_INTRA_BITRATE_PCT,
145 AV1E_SET_MAX_INTER_BITRATE_PCT,
146 AV1E_SET_GF_CBR_BOOST_PCT,
147 AV1E_SET_LOSSLESS,
148 AV1E_SET_ENABLE_CDEF,
149 AV1E_SET_ENABLE_RESTORATION,
150 AV1E_SET_ENABLE_RECT_PARTITIONS,
151 AV1E_SET_ENABLE_AB_PARTITIONS,
152 AV1E_SET_ENABLE_1TO4_PARTITIONS,
153 AV1E_SET_MIN_PARTITION_SIZE,
154 AV1E_SET_MAX_PARTITION_SIZE,
155 AV1E_SET_ENABLE_DUAL_FILTER,
156 AV1E_SET_ENABLE_CHROMA_DELTAQ,
157 AV1E_SET_ENABLE_INTRA_EDGE_FILTER,
158 AV1E_SET_ENABLE_ORDER_HINT,
159 AV1E_SET_ENABLE_TX64,
160 AV1E_SET_ENABLE_FLIP_IDTX,
161 AV1E_SET_ENABLE_RECT_TX,
162 AV1E_SET_ENABLE_DIST_WTD_COMP,
163 AV1E_SET_ENABLE_MASKED_COMP,
164 AV1E_SET_ENABLE_ONESIDED_COMP,
165 AV1E_SET_ENABLE_INTERINTRA_COMP,
166 AV1E_SET_ENABLE_SMOOTH_INTERINTRA,
167 AV1E_SET_ENABLE_DIFF_WTD_COMP,
168 AV1E_SET_ENABLE_INTERINTER_WEDGE,
169 AV1E_SET_ENABLE_INTERINTRA_WEDGE,
170 AV1E_SET_ENABLE_GLOBAL_MOTION,
171 AV1E_SET_ENABLE_WARPED_MOTION,
172 AV1E_SET_ENABLE_FILTER_INTRA,
173 AV1E_SET_ENABLE_SMOOTH_INTRA,
174 AV1E_SET_ENABLE_PAETH_INTRA,
175 AV1E_SET_ENABLE_CFL_INTRA,
176 AV1E_SET_ENABLE_DIAGONAL_INTRA,
177 AV1E_SET_FORCE_VIDEO_MODE,
178 AV1E_SET_ENABLE_OBMC,
179 AV1E_SET_ENABLE_OVERLAY,
180 AV1E_SET_ENABLE_PALETTE,
181 AV1E_SET_ENABLE_INTRABC,
182 AV1E_SET_ENABLE_ANGLE_DELTA,
183 AV1E_SET_DISABLE_TRELLIS_QUANT,
184 AV1E_SET_ENABLE_QM,
185 AV1E_SET_QM_MIN,
186 AV1E_SET_QM_MAX,
187 AV1E_SET_REDUCED_TX_TYPE_SET,
188 AV1E_SET_INTRA_DCT_ONLY,
189 AV1E_SET_INTER_DCT_ONLY,
190 AV1E_SET_INTRA_DEFAULT_TX_ONLY,
191 AV1E_SET_QUANT_B_ADAPT,
192 AV1E_SET_COEFF_COST_UPD_FREQ,
193 AV1E_SET_MODE_COST_UPD_FREQ,
194 AV1E_SET_MV_COST_UPD_FREQ,
195 AV1E_SET_FRAME_PARALLEL_DECODING,
196 AV1E_SET_ERROR_RESILIENT_MODE,
197 AV1E_SET_AQ_MODE,
198 AV1E_SET_DELTAQ_MODE,
199 AV1E_SET_DELTAQ_STRENGTH,
200 AV1E_SET_DELTALF_MODE,
201 AV1E_SET_FRAME_PERIODIC_BOOST,
202 AV1E_SET_NOISE_SENSITIVITY,
203 AV1E_SET_TUNE_CONTENT,
204 AV1E_SET_CDF_UPDATE_MODE,
205 AV1E_SET_COLOR_PRIMARIES,
206 AV1E_SET_TRANSFER_CHARACTERISTICS,
207 AV1E_SET_MATRIX_COEFFICIENTS,
208 AV1E_SET_CHROMA_SAMPLE_POSITION,
209 AV1E_SET_MIN_GF_INTERVAL,
210 AV1E_SET_MAX_GF_INTERVAL,
211 AV1E_SET_GF_MIN_PYRAMID_HEIGHT,
212 AV1E_SET_GF_MAX_PYRAMID_HEIGHT,
213 AV1E_SET_SUPERBLOCK_SIZE,
214 AV1E_SET_NUM_TG,
215 AV1E_SET_MTU,
216 AV1E_SET_TIMING_INFO_TYPE,
217 AV1E_SET_FILM_GRAIN_TEST_VECTOR,
218 AV1E_SET_FILM_GRAIN_TABLE,
219#if CONFIG_DENOISE
220 AV1E_SET_DENOISE_NOISE_LEVEL,
221 AV1E_SET_DENOISE_BLOCK_SIZE,
222 AV1E_SET_ENABLE_DNL_DENOISING,
223#endif // CONFIG_DENOISE
224 AV1E_SET_MAX_REFERENCE_FRAMES,
225 AV1E_SET_REDUCED_REFERENCE_SET,
226 AV1E_SET_ENABLE_REF_FRAME_MVS,
227 AV1E_SET_TARGET_SEQ_LEVEL_IDX,
228 AV1E_SET_TIER_MASK,
229 AV1E_SET_MIN_CR,
230 AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP,
231 AV1E_SET_CHROMA_SUBSAMPLING_X,
232 AV1E_SET_CHROMA_SUBSAMPLING_Y,
233#if CONFIG_TUNE_VMAF
234 AV1E_SET_VMAF_MODEL_PATH,
235#endif
236 AV1E_SET_DV_COST_UPD_FREQ,
237 AV1E_SET_PARTITION_INFO_PATH,
238 AV1E_SET_ENABLE_DIRECTIONAL_INTRA,
239 AV1E_SET_ENABLE_TX_SIZE_SEARCH,
240 AV1E_SET_LOOPFILTER_CONTROL,
241 AV1E_SET_AUTO_INTRA_TOOLS_OFF,
242 AV1E_ENABLE_RATE_GUIDE_DELTAQ,
243 AV1E_SET_RATE_DISTRIBUTION_INFO,
244 AV1E_SET_ENABLE_LOW_COMPLEXITY_DECODE,
245 0 };
246
247 static const arg_def_t *const main_args[] = {
248 &g_av1_codec_arg_defs.help,
249 &g_av1_codec_arg_defs.use_cfg,
250 &g_av1_codec_arg_defs.debugmode,
251 &g_av1_codec_arg_defs.outputfile,
252 &g_av1_codec_arg_defs.codecarg,
253 &g_av1_codec_arg_defs.passes,
254 &g_av1_codec_arg_defs.pass_arg,
255 &g_av1_codec_arg_defs.fpf_name,
256 &g_av1_codec_arg_defs.limit,
257 &g_av1_codec_arg_defs.skip,
258 &g_av1_codec_arg_defs.good_dl,
259 &g_av1_codec_arg_defs.rt_dl,
260 &g_av1_codec_arg_defs.ai_dl,
261 &g_av1_codec_arg_defs.quietarg,
262 &g_av1_codec_arg_defs.verbosearg,
263 &g_av1_codec_arg_defs.psnrarg,
264 &g_av1_codec_arg_defs.use_webm,
265 &g_av1_codec_arg_defs.use_ivf,
266 &g_av1_codec_arg_defs.use_obu,
267 &g_av1_codec_arg_defs.q_hist_n,
268 &g_av1_codec_arg_defs.rate_hist_n,
269 &g_av1_codec_arg_defs.disable_warnings,
270 &g_av1_codec_arg_defs.disable_warning_prompt,
271 &g_av1_codec_arg_defs.recontest,
272 NULL
273};
274
275 static const arg_def_t *const global_args[] = {
276 &g_av1_codec_arg_defs.use_nv12,
277 &g_av1_codec_arg_defs.use_yv12,
278 &g_av1_codec_arg_defs.use_i420,
279 &g_av1_codec_arg_defs.use_i422,
280 &g_av1_codec_arg_defs.use_i444,
281 &g_av1_codec_arg_defs.usage,
282 &g_av1_codec_arg_defs.threads,
283 &g_av1_codec_arg_defs.profile,
284 &g_av1_codec_arg_defs.width,
285 &g_av1_codec_arg_defs.height,
286 &g_av1_codec_arg_defs.forced_max_frame_width,
287 &g_av1_codec_arg_defs.forced_max_frame_height,
288#if CONFIG_WEBM_IO
289 &g_av1_codec_arg_defs.stereo_mode,
290#endif
291 &g_av1_codec_arg_defs.timebase,
292 &g_av1_codec_arg_defs.framerate,
293 &g_av1_codec_arg_defs.global_error_resilient,
294 &g_av1_codec_arg_defs.bitdeptharg,
295 &g_av1_codec_arg_defs.inbitdeptharg,
296 &g_av1_codec_arg_defs.lag_in_frames,
297 &g_av1_codec_arg_defs.large_scale_tile,
298 &g_av1_codec_arg_defs.monochrome,
299 &g_av1_codec_arg_defs.full_still_picture_hdr,
300 &g_av1_codec_arg_defs.use_16bit_internal,
301 &g_av1_codec_arg_defs.save_as_annexb,
302 NULL
303};
304
305 static const arg_def_t *const rc_args[] = {
306 &g_av1_codec_arg_defs.dropframe_thresh,
307 &g_av1_codec_arg_defs.resize_mode,
308 &g_av1_codec_arg_defs.resize_denominator,
309 &g_av1_codec_arg_defs.resize_kf_denominator,
310 &g_av1_codec_arg_defs.superres_mode,
311 &g_av1_codec_arg_defs.superres_denominator,
312 &g_av1_codec_arg_defs.superres_kf_denominator,
313 &g_av1_codec_arg_defs.superres_qthresh,
314 &g_av1_codec_arg_defs.superres_kf_qthresh,
315 &g_av1_codec_arg_defs.end_usage,
316 &g_av1_codec_arg_defs.target_bitrate,
317 &g_av1_codec_arg_defs.min_quantizer,
318 &g_av1_codec_arg_defs.max_quantizer,
319 &g_av1_codec_arg_defs.undershoot_pct,
320 &g_av1_codec_arg_defs.overshoot_pct,
321 &g_av1_codec_arg_defs.buf_sz,
322 &g_av1_codec_arg_defs.buf_initial_sz,
323 &g_av1_codec_arg_defs.buf_optimal_sz,
324 &g_av1_codec_arg_defs.bias_pct,
325 &g_av1_codec_arg_defs.minsection_pct,
326 &g_av1_codec_arg_defs.maxsection_pct,
327 NULL
328};
329
330 static const arg_def_t *const kf_args[] = {
331 &g_av1_codec_arg_defs.fwd_kf_enabled,
332 &g_av1_codec_arg_defs.kf_min_dist,
333 &g_av1_codec_arg_defs.kf_max_dist,
334 &g_av1_codec_arg_defs.kf_disabled,
335 &g_av1_codec_arg_defs.sframe_dist,
336 &g_av1_codec_arg_defs.sframe_mode,
337 NULL
338};
339
340// TODO(bohanli): Currently all options are supported by the key & value API.
341// Consider removing the control ID usages?
342 static const arg_def_t *const av1_ctrl_args[] = {
343 &g_av1_codec_arg_defs.cpu_used_av1,
344 &g_av1_codec_arg_defs.auto_altref,
345 &g_av1_codec_arg_defs.static_thresh,
346 &g_av1_codec_arg_defs.rowmtarg,
347 &g_av1_codec_arg_defs.fpmtarg,
348 &g_av1_codec_arg_defs.tile_cols,
349 &g_av1_codec_arg_defs.tile_rows,
350 &g_av1_codec_arg_defs.enable_tpl_model,
351 &g_av1_codec_arg_defs.enable_keyframe_filtering,
352 &g_av1_codec_arg_defs.arnr_maxframes,
353 &g_av1_codec_arg_defs.arnr_strength,
354 &g_av1_codec_arg_defs.tune_metric,
355 &g_av1_codec_arg_defs.cq_level,
356 &g_av1_codec_arg_defs.max_intra_rate_pct,
357 &g_av1_codec_arg_defs.max_inter_rate_pct,
358 &g_av1_codec_arg_defs.gf_cbr_boost_pct,
359 &g_av1_codec_arg_defs.lossless,
360 &g_av1_codec_arg_defs.enable_cdef,
361 &g_av1_codec_arg_defs.enable_restoration,
362 &g_av1_codec_arg_defs.enable_rect_partitions,
363 &g_av1_codec_arg_defs.enable_ab_partitions,
364 &g_av1_codec_arg_defs.enable_1to4_partitions,
365 &g_av1_codec_arg_defs.min_partition_size,
366 &g_av1_codec_arg_defs.max_partition_size,
367 &g_av1_codec_arg_defs.enable_dual_filter,
368 &g_av1_codec_arg_defs.enable_chroma_deltaq,
369 &g_av1_codec_arg_defs.enable_intra_edge_filter,
370 &g_av1_codec_arg_defs.enable_order_hint,
371 &g_av1_codec_arg_defs.enable_tx64,
372 &g_av1_codec_arg_defs.enable_flip_idtx,
373 &g_av1_codec_arg_defs.enable_rect_tx,
374 &g_av1_codec_arg_defs.enable_dist_wtd_comp,
375 &g_av1_codec_arg_defs.enable_masked_comp,
376 &g_av1_codec_arg_defs.enable_onesided_comp,
377 &g_av1_codec_arg_defs.enable_interintra_comp,
378 &g_av1_codec_arg_defs.enable_smooth_interintra,
379 &g_av1_codec_arg_defs.enable_diff_wtd_comp,
380 &g_av1_codec_arg_defs.enable_interinter_wedge,
381 &g_av1_codec_arg_defs.enable_interintra_wedge,
382 &g_av1_codec_arg_defs.enable_global_motion,
383 &g_av1_codec_arg_defs.enable_warped_motion,
384 &g_av1_codec_arg_defs.enable_filter_intra,
385 &g_av1_codec_arg_defs.enable_smooth_intra,
386 &g_av1_codec_arg_defs.enable_paeth_intra,
387 &g_av1_codec_arg_defs.enable_cfl_intra,
388 &g_av1_codec_arg_defs.enable_diagonal_intra,
389 &g_av1_codec_arg_defs.force_video_mode,
390 &g_av1_codec_arg_defs.enable_obmc,
391 &g_av1_codec_arg_defs.enable_overlay,
392 &g_av1_codec_arg_defs.enable_palette,
393 &g_av1_codec_arg_defs.enable_intrabc,
394 &g_av1_codec_arg_defs.enable_angle_delta,
395 &g_av1_codec_arg_defs.disable_trellis_quant,
396 &g_av1_codec_arg_defs.enable_qm,
397 &g_av1_codec_arg_defs.qm_min,
398 &g_av1_codec_arg_defs.qm_max,
399 &g_av1_codec_arg_defs.reduced_tx_type_set,
400 &g_av1_codec_arg_defs.use_intra_dct_only,
401 &g_av1_codec_arg_defs.use_inter_dct_only,
402 &g_av1_codec_arg_defs.use_intra_default_tx_only,
403 &g_av1_codec_arg_defs.quant_b_adapt,
404 &g_av1_codec_arg_defs.coeff_cost_upd_freq,
405 &g_av1_codec_arg_defs.mode_cost_upd_freq,
406 &g_av1_codec_arg_defs.mv_cost_upd_freq,
407 &g_av1_codec_arg_defs.frame_parallel_decoding,
408 &g_av1_codec_arg_defs.error_resilient_mode,
409 &g_av1_codec_arg_defs.aq_mode,
410 &g_av1_codec_arg_defs.deltaq_mode,
411 &g_av1_codec_arg_defs.deltaq_strength,
412 &g_av1_codec_arg_defs.deltalf_mode,
413 &g_av1_codec_arg_defs.frame_periodic_boost,
414 &g_av1_codec_arg_defs.noise_sens,
415 &g_av1_codec_arg_defs.tune_content,
416 &g_av1_codec_arg_defs.cdf_update_mode,
417 &g_av1_codec_arg_defs.input_color_primaries,
418 &g_av1_codec_arg_defs.input_transfer_characteristics,
419 &g_av1_codec_arg_defs.input_matrix_coefficients,
420 &g_av1_codec_arg_defs.input_chroma_sample_position,
421 &g_av1_codec_arg_defs.min_gf_interval,
422 &g_av1_codec_arg_defs.max_gf_interval,
423 &g_av1_codec_arg_defs.gf_min_pyr_height,
424 &g_av1_codec_arg_defs.gf_max_pyr_height,
425 &g_av1_codec_arg_defs.superblock_size,
426 &g_av1_codec_arg_defs.num_tg,
427 &g_av1_codec_arg_defs.mtu_size,
428 &g_av1_codec_arg_defs.timing_info,
429 &g_av1_codec_arg_defs.film_grain_test,
430 &g_av1_codec_arg_defs.film_grain_table,
431#if CONFIG_DENOISE
432 &g_av1_codec_arg_defs.denoise_noise_level,
433 &g_av1_codec_arg_defs.denoise_block_size,
434 &g_av1_codec_arg_defs.enable_dnl_denoising,
435#endif // CONFIG_DENOISE
436 &g_av1_codec_arg_defs.max_reference_frames,
437 &g_av1_codec_arg_defs.reduced_reference_set,
438 &g_av1_codec_arg_defs.enable_ref_frame_mvs,
439 &g_av1_codec_arg_defs.target_seq_level_idx,
440 &g_av1_codec_arg_defs.set_tier_mask,
441 &g_av1_codec_arg_defs.set_min_cr,
442 &g_av1_codec_arg_defs.vbr_corpus_complexity_lap,
443 &g_av1_codec_arg_defs.input_chroma_subsampling_x,
444 &g_av1_codec_arg_defs.input_chroma_subsampling_y,
445#if CONFIG_TUNE_VMAF
446 &g_av1_codec_arg_defs.vmaf_model_path,
447#endif
448 &g_av1_codec_arg_defs.dv_cost_upd_freq,
449 &g_av1_codec_arg_defs.partition_info_path,
450 &g_av1_codec_arg_defs.enable_directional_intra,
451 &g_av1_codec_arg_defs.enable_tx_size_search,
452 &g_av1_codec_arg_defs.loopfilter_control,
453 &g_av1_codec_arg_defs.auto_intra_tools_off,
454 &g_av1_codec_arg_defs.enable_rate_guide_deltaq,
455 &g_av1_codec_arg_defs.rate_distribution_info,
456 &g_av1_codec_arg_defs.enable_low_complexity_decode,
457 NULL,
458};
459
460 static const arg_def_t *const av1_key_val_args[] = {
461 &g_av1_codec_arg_defs.passes,
462 &g_av1_codec_arg_defs.two_pass_output,
463 &g_av1_codec_arg_defs.second_pass_log,
464 &g_av1_codec_arg_defs.fwd_kf_dist,
465 &g_av1_codec_arg_defs.strict_level_conformance,
466 &g_av1_codec_arg_defs.sb_qp_sweep,
467 &g_av1_codec_arg_defs.dist_metric,
468 &g_av1_codec_arg_defs.kf_max_pyr_height,
469 &g_av1_codec_arg_defs.auto_tiles,
470 &g_av1_codec_arg_defs.screen_detection_mode,
471 &g_av1_codec_arg_defs.sharpness,
472 &g_av1_codec_arg_defs.enable_adaptive_sharpness,
473 NULL,
474};
475
476 static const arg_def_t *const no_args[] = { NULL };
477
478 static void show_help(FILE *fout, int shorthelp) {
479 fprintf(fout, "Usage: %s <options> -o dst_filename src_filename\n",
480 exec_name);
481
482 if (shorthelp) {
483 fprintf(fout, "Use --help to see the full list of options.\n");
484 return;
485 }
486
487 fprintf(fout, "\nOptions:\n");
488 arg_show_usage(fout, main_args);
489 fprintf(fout, "\nEncoder Global Options:\n");
490 arg_show_usage(fout, global_args);
491 fprintf(fout, "\nRate Control Options:\n");
492 arg_show_usage(fout, rc_args);
493 fprintf(fout, "\nKeyframe Placement Options:\n");
494 arg_show_usage(fout, kf_args);
495#if CONFIG_AV1_ENCODER
496 fprintf(fout, "\nAV1 Specific Options:\n");
497 arg_show_usage(fout, av1_ctrl_args);
498 arg_show_usage(fout, av1_key_val_args);
499#endif
500 fprintf(fout,
501 "\nStream timebase (--timebase):\n"
502 " The desired precision of timestamps in the output, expressed\n"
503 " in fractional seconds. Default is 1/1000.\n");
504 fprintf(fout, "\nIncluded encoders:\n\n");
505
506 const int num_encoder = get_aom_encoder_count();
507 for (int i = 0; i < num_encoder; ++i) {
508 aom_codec_iface_t *encoder = get_aom_encoder_by_index(i);
509 const char *defstr = (i == (num_encoder - 1)) ? "(default)" : "";
510 fprintf(fout, " %-6s - %s %s\n", get_short_name_by_aom_encoder(encoder),
511 aom_codec_iface_name(encoder), defstr);
512 }
513 fprintf(fout, "\n ");
514 fprintf(fout, "Use --codec to switch to a non-default encoder.\n\n");
515}
516
517 void usage_exit(void) {
518 show_help(stderr, 1);
519 exit(EXIT_FAILURE);
520}
521
522#if CONFIG_AV1_ENCODER
523#define ARG_CTRL_CNT_MAX NELEMENTS(av1_arg_ctrl_map)
524#define ARG_KEY_VAL_CNT_MAX NELEMENTS(av1_key_val_args)
525#endif
526
527#if !CONFIG_WEBM_IO
528 typedef int stereo_format_t;
529 struct WebmOutputContext {
530 int debug;
531};
532#endif
533
534/* Per-stream configuration */
535 struct stream_config {
536 struct aom_codec_enc_cfg cfg;
537 const char *out_fn;
538 const char *stats_fn;
539 stereo_format_t stereo_fmt;
540 int arg_ctrls[ARG_CTRL_CNT_MAX][2];
541 int arg_ctrl_cnt;
542 const char *arg_key_vals[ARG_KEY_VAL_CNT_MAX][2];
543 int arg_key_val_cnt;
544 int write_webm;
545 const char *film_grain_filename;
546 int write_ivf;
547 // whether to use 16bit internal buffers
548 int use_16bit_internal;
549#if CONFIG_TUNE_VMAF
550 const char *vmaf_model_path;
551#endif
552 const char *partition_info_path;
553 unsigned int enable_rate_guide_deltaq;
554 const char *rate_distribution_info;
555 aom_color_range_t color_range;
556 const char *two_pass_input;
557 const char *two_pass_output;
558 int two_pass_width;
559 int two_pass_height;
560 unsigned int enable_low_complexity_decode;
561};
562
563 struct stream_state {
564 int index;
565 struct stream_state *next;
566 struct stream_config config;
567 FILE *file;
568 struct rate_hist *rate_hist;
569 struct WebmOutputContext webm_ctx;
570 uint64_t psnr_sse_total[2];
571 uint64_t psnr_samples_total[2];
572 double psnr_totals[2][4];
573 int psnr_count[2];
574 int counts[64];
575 aom_codec_ctx_t encoder;
576 unsigned int frames_out;
577 uint64_t cx_time;
578 size_t nbytes;
579 stats_io_t stats;
580 struct aom_image *img;
581 aom_codec_ctx_t decoder;
582 int mismatch_seen;
583 unsigned int chroma_subsampling_x;
584 unsigned int chroma_subsampling_y;
585 const char *orig_out_fn;
586 unsigned int orig_width;
587 unsigned int orig_height;
588 int orig_write_webm;
589 int orig_write_ivf;
590 char tmp_out_fn[1000];
591};
592
593 static void validate_positive_rational(const char *msg,
594 struct aom_rational *rat) {
595 if (rat->den < 0) {
596 rat->num *= -1;
597 rat->den *= -1;
598 }
599
600 if (rat->num < 0) die("Error: %s must be positive\n", msg);
601
602 if (!rat->den) die("Error: %s has zero denominator\n", msg);
603}
604
605 static void init_config(cfg_options_t *config) {
606 memset(config, 0, sizeof(cfg_options_t));
607 config->super_block_size = 0; // Dynamic
608 config->max_partition_size = 128;
609 config->min_partition_size = 4;
610 config->disable_trellis_quant = 3;
611}
612
613/* Parses global config arguments into the AvxEncoderConfig. Note that
614 * argv is modified and overwrites all parsed arguments.
615 */
616 static void parse_global_config(struct AvxEncoderConfig *global, char ***argv) {
617 char **argi, **argj;
618 struct arg arg;
619 const int num_encoder = get_aom_encoder_count();
620 char **argv_local = (char **)*argv;
621 if (num_encoder < 1) die("Error: no valid encoder available\n");
622
623 /* Initialize default parameters */
624 memset(global, 0, sizeof(*global));
625 global->codec = get_aom_encoder_by_index(num_encoder - 1);
626 global->passes = 0;
627 global->color_type = I420;
628 global->csp = AOM_CSP_UNKNOWN;
629 global->show_psnr = 0;
630
631 int cfg_included = 0;
632 init_config(&global->encoder_config);
633
634 for (argi = argj = argv_local; (*argj = *argi); argi += arg.argv_step) {
635 arg.argv_step = 1;
636
637 if (arg_match(&arg, &g_av1_codec_arg_defs.use_cfg, argi)) {
638 if (!cfg_included) {
639 parse_cfg(arg.val, &global->encoder_config);
640 cfg_included = 1;
641 }
642 } else if (arg_match(&arg, &g_av1_codec_arg_defs.help, argi)) {
643 show_help(stdout, 0);
644 exit(EXIT_SUCCESS);
645 } else if (arg_match(&arg, &g_av1_codec_arg_defs.codecarg, argi)) {
646 global->codec = get_aom_encoder_by_short_name(arg.val);
647 if (!global->codec)
648 die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
649 } else if (arg_match(&arg, &g_av1_codec_arg_defs.passes, argi)) {
650 global->passes = arg_parse_uint(&arg);
651
652 if (global->passes < 1 || global->passes > 3)
653 die("Error: Invalid number of passes (%d)\n", global->passes);
654 } else if (arg_match(&arg, &g_av1_codec_arg_defs.pass_arg, argi)) {
655 global->pass = arg_parse_uint(&arg);
656
657 if (global->pass < 1 || global->pass > 3)
658 die("Error: Invalid pass selected (%d)\n", global->pass);
659 } else if (arg_match(&arg,
660 &g_av1_codec_arg_defs.input_chroma_sample_position,
661 argi)) {
662 global->csp = arg_parse_enum(&arg);
663 /* Flag is used by later code as well, preserve it. */
664 argj++;
665 } else if (arg_match(&arg, &g_av1_codec_arg_defs.usage, argi)) {
666 global->usage = arg_parse_uint(&arg);
667 } else if (arg_match(&arg, &g_av1_codec_arg_defs.good_dl, argi)) {
668 global->usage = AOM_USAGE_GOOD_QUALITY; // Good quality usage
669 } else if (arg_match(&arg, &g_av1_codec_arg_defs.rt_dl, argi)) {
670 global->usage = AOM_USAGE_REALTIME; // Real-time usage
671 } else if (arg_match(&arg, &g_av1_codec_arg_defs.ai_dl, argi)) {
672 global->usage = AOM_USAGE_ALL_INTRA; // All intra usage
673 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_nv12, argi)) {
674 global->color_type = NV12;
675 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_yv12, argi)) {
676 global->color_type = YV12;
677 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_i420, argi)) {
678 global->color_type = I420;
679 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_i422, argi)) {
680 global->color_type = I422;
681 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_i444, argi)) {
682 global->color_type = I444;
683 } else if (arg_match(&arg, &g_av1_codec_arg_defs.quietarg, argi)) {
684 global->quiet = 1;
685 } else if (arg_match(&arg, &g_av1_codec_arg_defs.verbosearg, argi)) {
686 global->verbose = 1;
687 } else if (arg_match(&arg, &g_av1_codec_arg_defs.limit, argi)) {
688 global->limit = arg_parse_uint(&arg);
689 } else if (arg_match(&arg, &g_av1_codec_arg_defs.skip, argi)) {
690 global->skip_frames = arg_parse_uint(&arg);
691 } else if (arg_match(&arg, &g_av1_codec_arg_defs.psnrarg, argi)) {
692 if (arg.val)
693 global->show_psnr = arg_parse_int(&arg);
694 else
695 global->show_psnr = 1;
696 } else if (arg_match(&arg, &g_av1_codec_arg_defs.recontest, argi)) {
697 global->test_decode = arg_parse_enum_or_int(&arg);
698 } else if (arg_match(&arg, &g_av1_codec_arg_defs.framerate, argi)) {
699 global->framerate = arg_parse_rational(&arg);
700 validate_positive_rational(arg.name, &global->framerate);
701 global->have_framerate = 1;
702 } else if (arg_match(&arg, &g_av1_codec_arg_defs.debugmode, argi)) {
703 global->debug = 1;
704 } else if (arg_match(&arg, &g_av1_codec_arg_defs.q_hist_n, argi)) {
705 global->show_q_hist_buckets = arg_parse_uint(&arg);
706 } else if (arg_match(&arg, &g_av1_codec_arg_defs.rate_hist_n, argi)) {
707 global->show_rate_hist_buckets = arg_parse_uint(&arg);
708 } else if (arg_match(&arg, &g_av1_codec_arg_defs.disable_warnings, argi)) {
709 global->disable_warnings = 1;
710 } else if (arg_match(&arg, &g_av1_codec_arg_defs.disable_warning_prompt,
711 argi)) {
712 global->disable_warning_prompt = 1;
713 } else {
714 argj++;
715 }
716 }
717
718 if (global->pass) {
719 /* DWIM: Assume the user meant passes=2 if pass=2 is specified */
720 if (global->pass > global->passes) {
721 aom_tools_warn("Assuming --pass=%d implies --passes=%d\n", global->pass,
722 global->pass);
723 global->passes = global->pass;
724 }
725 }
726 /* Validate global config */
727 if (global->passes == 0) {
728#if CONFIG_AV1_ENCODER
729 // Make default AV1 passes = 2 until there is a better quality 1-pass
730 // encoder
731 if (global->codec != NULL)
732 global->passes =
733 (strcmp(get_short_name_by_aom_encoder(global->codec), "av1") == 0 &&
734 global->usage != AOM_USAGE_REALTIME)
735 ? 2
736 : 1;
737#else
738 global->passes = 1;
739#endif
740 }
741
742 if (global->usage == AOM_USAGE_REALTIME && global->passes > 1) {
743 aom_tools_warn("Enforcing one-pass encoding in realtime mode\n");
744 if (global->pass > 1)
745 die("Error: Invalid --pass=%d for one-pass encoding\n", global->pass);
746 global->passes = 1;
747 }
748
749 if (global->usage == AOM_USAGE_ALL_INTRA && global->passes > 1) {
750 aom_tools_warn("Enforcing one-pass encoding in all intra mode\n");
751 global->passes = 1;
752 }
753}
754
755 static void open_input_file(struct AvxInputContext *input,
756 aom_chroma_sample_position_t csp) {
757 /* Parse certain options from the input file, if possible */
758 input->file = strcmp(input->filename, "-") ? fopen(input->filename, "rb")
759 : set_binary_mode(stdin);
760
761 if (!input->file) fatal("Failed to open input file");
762
763 if (!fseeko(input->file, 0, SEEK_END)) {
764 /* Input file is seekable. Figure out how long it is, so we can get
765 * progress info.
766 */
767 input->length = ftello(input->file);
768 rewind(input->file);
769 }
770
771 /* Default to 1:1 pixel aspect ratio. */
772 input->pixel_aspect_ratio.numerator = 1;
773 input->pixel_aspect_ratio.denominator = 1;
774
775 /* For RAW input sources, these bytes will applied on the first frame
776 * in read_frame().
777 */
778 input->detect.buf_read = fread(input->detect.buf, 1, 4, input->file);
779 input->detect.position = 0;
780
781 if (input->detect.buf_read == 4 && file_is_y4m(input->detect.buf)) {
782 if (y4m_input_open(&input->y4m, input->file, input->detect.buf, 4, csp,
783 input->only_i420) >= 0) {
784 input->file_type = FILE_TYPE_Y4M;
785 input->width = input->y4m.pic_w;
786 input->height = input->y4m.pic_h;
787 input->pixel_aspect_ratio.numerator = input->y4m.par_n;
788 input->pixel_aspect_ratio.denominator = input->y4m.par_d;
789 input->framerate.numerator = input->y4m.fps_n;
790 input->framerate.denominator = input->y4m.fps_d;
791 input->fmt = input->y4m.aom_fmt;
792 input->bit_depth = input->y4m.bit_depth;
793 input->color_range = input->y4m.color_range;
794 } else
795 fatal("Unsupported Y4M stream.");
796 } else if (input->detect.buf_read == 4 && fourcc_is_ivf(input->detect.buf)) {
797 fatal("IVF is not supported as input.");
798 } else {
799 input->file_type = FILE_TYPE_RAW;
800 }
801}
802
803 static void close_input_file(struct AvxInputContext *input) {
804 fclose(input->file);
805 if (input->file_type == FILE_TYPE_Y4M) y4m_input_close(&input->y4m);
806}
807
808 static struct stream_state *new_stream(struct AvxEncoderConfig *global,
809 struct stream_state *prev) {
810 struct stream_state *stream;
811
812 stream = calloc(1, sizeof(*stream));
813 if (stream == NULL) {
814 fatal("Failed to allocate new stream.");
815 }
816
817 if (prev) {
818 *stream = *prev;
819 stream->index++;
820 prev->next = stream;
821 } else {
822 aom_codec_err_t res;
823
824 /* Populate encoder configuration */
825 res = aom_codec_enc_config_default(global->codec, &stream->config.cfg,
826 global->usage);
827 if (res) fatal("Failed to get config: %s\n", aom_codec_err_to_string(res));
828
829 /* Change the default timebase to a high enough value so that the
830 * encoder will always create strictly increasing timestamps.
831 */
832 stream->config.cfg.g_timebase.den = 1000;
833
834 /* Never use the library's default resolution, require it be parsed
835 * from the file or set on the command line.
836 */
837 stream->config.cfg.g_w = 0;
838 stream->config.cfg.g_h = 0;
839
840 /* Initialize remaining stream parameters */
841 stream->config.write_webm = 1;
842 stream->config.write_ivf = 0;
843
844#if CONFIG_WEBM_IO
845 stream->config.stereo_fmt = STEREO_FORMAT_MONO;
846 stream->webm_ctx.last_pts_ns = -1;
847 stream->webm_ctx.writer = NULL;
848 stream->webm_ctx.segment = NULL;
849#endif
850
851 /* Allows removal of the application version from the EBML tags */
852 stream->webm_ctx.debug = global->debug;
853 stream->config.cfg.encoder_cfg = global->encoder_config;
854 }
855
856 /* Output files must be specified for each stream */
857 stream->config.out_fn = NULL;
858 stream->config.two_pass_input = NULL;
859 stream->config.two_pass_output = NULL;
860 stream->config.two_pass_width = 0;
861 stream->config.two_pass_height = 0;
862
863 stream->next = NULL;
864 return stream;
865}
866
867 static void set_config_arg_ctrls(struct stream_config *config, int key,
868 const struct arg *arg) {
869 int j;
870 if (key == AV1E_SET_FILM_GRAIN_TABLE) {
871 config->film_grain_filename = arg->val;
872 return;
873 }
874
875 // For target level, the settings should accumulate rather than overwrite,
876 // so we simply append it.
877 if (key == AV1E_SET_TARGET_SEQ_LEVEL_IDX) {
878 j = config->arg_ctrl_cnt;
879 assert(j < ARG_CTRL_CNT_MAX);
880 config->arg_ctrls[j][0] = key;
881 config->arg_ctrls[j][1] = arg_parse_enum_or_int(arg);
882 ++config->arg_ctrl_cnt;
883 return;
884 }
885
886 /* Point either to the next free element or the first instance of this
887 * control.
888 */
889 for (j = 0; j < config->arg_ctrl_cnt; j++)
890 if (config->arg_ctrls[j][0] == key) break;
891
892 /* Update/insert */
893 assert(j < ARG_CTRL_CNT_MAX);
894 config->arg_ctrls[j][0] = key;
895 config->arg_ctrls[j][1] = arg_parse_enum_or_int(arg);
896
897 if (key == AOME_SET_ENABLEAUTOALTREF && config->arg_ctrls[j][1] > 1) {
898 aom_tools_warn(
899 "auto-alt-ref > 1 is deprecated... setting auto-alt-ref=1\n");
900 config->arg_ctrls[j][1] = 1;
901 }
902
903 if (j == config->arg_ctrl_cnt) config->arg_ctrl_cnt++;
904}
905
906 static void set_config_arg_key_vals(struct stream_config *config,
907 const char *name, const struct arg *arg) {
908 int j;
909 const char *val = arg->val;
910 // For target level, the settings should accumulate rather than overwrite,
911 // so we simply append it.
912 if (strcmp(name, "target-seq-level-idx") == 0) {
913 j = config->arg_key_val_cnt;
914 assert(j < ARG_KEY_VAL_CNT_MAX);
915 config->arg_key_vals[j][0] = name;
916 config->arg_key_vals[j][1] = val;
917 ++config->arg_key_val_cnt;
918 return;
919 }
920
921 /* Point either to the next free element or the first instance of this
922 * option.
923 */
924 for (j = 0; j < config->arg_key_val_cnt; j++)
925 if (strcmp(name, config->arg_key_vals[j][0]) == 0) break;
926
927 /* Update/insert */
928 assert(j < ARG_KEY_VAL_CNT_MAX);
929 config->arg_key_vals[j][0] = name;
930 config->arg_key_vals[j][1] = val;
931
932 if (strcmp(name, g_av1_codec_arg_defs.auto_altref.long_name) == 0) {
933 int auto_altref = arg_parse_int(arg);
934 if (auto_altref > 1) {
935 aom_tools_warn(
936 "auto-alt-ref > 1 is deprecated... setting auto-alt-ref=1\n");
937 config->arg_key_vals[j][1] = "1";
938 }
939 }
940
941 if (j == config->arg_key_val_cnt) config->arg_key_val_cnt++;
942}
943
944 static int parse_stream_params(struct AvxEncoderConfig *global,
945 struct stream_state *stream, char **argv) {
946 char **argi, **argj;
947 struct arg arg;
948 const arg_def_t *const *ctrl_args = no_args;
949 const arg_def_t *const *key_val_args = no_args;
950 const int *ctrl_args_map = NULL;
951 struct stream_config *config = &stream->config;
952 int eos_mark_found = 0;
953 int webm_forced = 0;
954
955 // Handle codec specific options
956 if (0) {
957#if CONFIG_AV1_ENCODER
958 } else if (strcmp(get_short_name_by_aom_encoder(global->codec), "av1") == 0) {
959 // TODO(jingning): Reuse AV1 specific encoder configuration parameters.
960 // Consider to expand this set for AV1 encoder control.
961#if __STDC_VERSION__ >= 201112L
962 _Static_assert(NELEMENTS(av1_ctrl_args) == NELEMENTS(av1_arg_ctrl_map),
963 "The av1_ctrl_args and av1_arg_ctrl_map arrays must be of "
964 "the same size.");
965#else
966 assert(NELEMENTS(av1_ctrl_args) == NELEMENTS(av1_arg_ctrl_map));
967#endif
968 ctrl_args = av1_ctrl_args;
969 ctrl_args_map = av1_arg_ctrl_map;
970 key_val_args = av1_key_val_args;
971#endif
972 }
973
974 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
975 arg.argv_step = 1;
976
977 /* Once we've found an end-of-stream marker (--) we want to continue
978 * shifting arguments but not consuming them.
979 */
980 if (eos_mark_found) {
981 argj++;
982 continue;
983 } else if (!strcmp(*argj, "--")) {
984 eos_mark_found = 1;
985 continue;
986 }
987
988 if (arg_match(&arg, &g_av1_codec_arg_defs.outputfile, argi)) {
989 config->out_fn = arg.val;
990 if (!webm_forced) {
991 const size_t out_fn_len = strlen(config->out_fn);
992 if (out_fn_len >= 4 &&
993 !strcmp(config->out_fn + out_fn_len - 4, ".ivf")) {
994 config->write_webm = 0;
995 config->write_ivf = 1;
996 } else if (out_fn_len >= 4 &&
997 !strcmp(config->out_fn + out_fn_len - 4, ".obu")) {
998 config->write_webm = 0;
999 config->write_ivf = 0;
1000 }
1001 }
1002 } else if (arg_match(&arg, &g_av1_codec_arg_defs.fpf_name, argi)) {
1003 config->stats_fn = arg.val;
1004 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_webm, argi)) {
1005#if CONFIG_WEBM_IO
1006 config->write_webm = 1;
1007 webm_forced = 1;
1008#else
1009 die("Error: --webm specified but webm is disabled.");
1010#endif
1011 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_ivf, argi)) {
1012 config->write_webm = 0;
1013 config->write_ivf = 1;
1014 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_obu, argi)) {
1015 config->write_webm = 0;
1016 config->write_ivf = 0;
1017 } else if (arg_match(&arg, &g_av1_codec_arg_defs.threads, argi)) {
1018 config->cfg.g_threads = arg_parse_uint(&arg);
1019 } else if (arg_match(&arg, &g_av1_codec_arg_defs.profile, argi)) {
1020 config->cfg.g_profile = arg_parse_uint(&arg);
1021 } else if (arg_match(&arg, &g_av1_codec_arg_defs.width, argi)) {
1022 config->cfg.g_w = arg_parse_uint(&arg);
1023 } else if (arg_match(&arg, &g_av1_codec_arg_defs.height, argi)) {
1024 config->cfg.g_h = arg_parse_uint(&arg);
1025 } else if (arg_match(&arg, &g_av1_codec_arg_defs.forced_max_frame_width,
1026 argi)) {
1027 config->cfg.g_forced_max_frame_width = arg_parse_uint(&arg);
1028 } else if (arg_match(&arg, &g_av1_codec_arg_defs.forced_max_frame_height,
1029 argi)) {
1030 config->cfg.g_forced_max_frame_height = arg_parse_uint(&arg);
1031 } else if (arg_match(&arg, &g_av1_codec_arg_defs.bitdeptharg, argi)) {
1032 config->cfg.g_bit_depth = arg_parse_enum_or_int(&arg);
1033 } else if (arg_match(&arg, &g_av1_codec_arg_defs.inbitdeptharg, argi)) {
1034 config->cfg.g_input_bit_depth = arg_parse_uint(&arg);
1035 } else if (arg_match(&arg, &g_av1_codec_arg_defs.input_chroma_subsampling_x,
1036 argi)) {
1037 stream->chroma_subsampling_x = arg_parse_uint(&arg);
1038 } else if (arg_match(&arg, &g_av1_codec_arg_defs.input_chroma_subsampling_y,
1039 argi)) {
1040 stream->chroma_subsampling_y = arg_parse_uint(&arg);
1041#if CONFIG_WEBM_IO
1042 } else if (arg_match(&arg, &g_av1_codec_arg_defs.stereo_mode, argi)) {
1043 config->stereo_fmt = arg_parse_enum_or_int(&arg);
1044#endif
1045 } else if (arg_match(&arg, &g_av1_codec_arg_defs.timebase, argi)) {
1046 config->cfg.g_timebase = arg_parse_rational(&arg);
1047 validate_positive_rational(arg.name, &config->cfg.g_timebase);
1048 } else if (arg_match(&arg, &g_av1_codec_arg_defs.global_error_resilient,
1049 argi)) {
1050 config->cfg.g_error_resilient = arg_parse_uint(&arg);
1051 } else if (arg_match(&arg, &g_av1_codec_arg_defs.lag_in_frames, argi)) {
1052 config->cfg.g_lag_in_frames = arg_parse_uint(&arg);
1053 } else if (arg_match(&arg, &g_av1_codec_arg_defs.large_scale_tile, argi)) {
1054 config->cfg.large_scale_tile = arg_parse_uint(&arg);
1055 if (config->cfg.large_scale_tile) {
1056 global->codec = get_aom_encoder_by_short_name("av1");
1057 }
1058 } else if (arg_match(&arg, &g_av1_codec_arg_defs.monochrome, argi)) {
1059 config->cfg.monochrome = 1;
1060 } else if (arg_match(&arg, &g_av1_codec_arg_defs.full_still_picture_hdr,
1061 argi)) {
1062 config->cfg.full_still_picture_hdr = 1;
1063 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_16bit_internal,
1064 argi)) {
1065 config->use_16bit_internal = CONFIG_AV1_HIGHBITDEPTH;
1066 if (!config->use_16bit_internal) {
1067 aom_tools_warn("%s option ignored with CONFIG_AV1_HIGHBITDEPTH=0.\n",
1068 arg.name);
1069 }
1070 } else if (arg_match(&arg, &g_av1_codec_arg_defs.dropframe_thresh, argi)) {
1071 config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
1072 } else if (arg_match(&arg, &g_av1_codec_arg_defs.resize_mode, argi)) {
1073 config->cfg.rc_resize_mode = arg_parse_uint(&arg);
1074 } else if (arg_match(&arg, &g_av1_codec_arg_defs.resize_denominator,
1075 argi)) {
1076 config->cfg.rc_resize_denominator = arg_parse_uint(&arg);
1077 } else if (arg_match(&arg, &g_av1_codec_arg_defs.resize_kf_denominator,
1078 argi)) {
1079 config->cfg.rc_resize_kf_denominator = arg_parse_uint(&arg);
1080 } else if (arg_match(&arg, &g_av1_codec_arg_defs.superres_mode, argi)) {
1081 config->cfg.rc_superres_mode = arg_parse_uint(&arg);
1082 } else if (arg_match(&arg, &g_av1_codec_arg_defs.superres_denominator,
1083 argi)) {
1084 config->cfg.rc_superres_denominator = arg_parse_uint(&arg);
1085 } else if (arg_match(&arg, &g_av1_codec_arg_defs.superres_kf_denominator,
1086 argi)) {
1087 config->cfg.rc_superres_kf_denominator = arg_parse_uint(&arg);
1088 } else if (arg_match(&arg, &g_av1_codec_arg_defs.superres_qthresh, argi)) {
1089 config->cfg.rc_superres_qthresh = arg_parse_uint(&arg);
1090 } else if (arg_match(&arg, &g_av1_codec_arg_defs.superres_kf_qthresh,
1091 argi)) {
1092 config->cfg.rc_superres_kf_qthresh = arg_parse_uint(&arg);
1093 } else if (arg_match(&arg, &g_av1_codec_arg_defs.end_usage, argi)) {
1094 config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg);
1095 } else if (arg_match(&arg, &g_av1_codec_arg_defs.target_bitrate, argi)) {
1096 config->cfg.rc_target_bitrate = arg_parse_uint(&arg);
1097 } else if (arg_match(&arg, &g_av1_codec_arg_defs.min_quantizer, argi)) {
1098 config->cfg.rc_min_quantizer = arg_parse_uint(&arg);
1099 } else if (arg_match(&arg, &g_av1_codec_arg_defs.max_quantizer, argi)) {
1100 config->cfg.rc_max_quantizer = arg_parse_uint(&arg);
1101 } else if (arg_match(&arg, &g_av1_codec_arg_defs.undershoot_pct, argi)) {
1102 config->cfg.rc_undershoot_pct = arg_parse_uint(&arg);
1103 } else if (arg_match(&arg, &g_av1_codec_arg_defs.overshoot_pct, argi)) {
1104 config->cfg.rc_overshoot_pct = arg_parse_uint(&arg);
1105 } else if (arg_match(&arg, &g_av1_codec_arg_defs.buf_sz, argi)) {
1106 config->cfg.rc_buf_sz = arg_parse_uint(&arg);
1107 } else if (arg_match(&arg, &g_av1_codec_arg_defs.buf_initial_sz, argi)) {
1108 config->cfg.rc_buf_initial_sz = arg_parse_uint(&arg);
1109 } else if (arg_match(&arg, &g_av1_codec_arg_defs.buf_optimal_sz, argi)) {
1110 config->cfg.rc_buf_optimal_sz = arg_parse_uint(&arg);
1111 } else if (arg_match(&arg, &g_av1_codec_arg_defs.bias_pct, argi)) {
1112 config->cfg.rc_2pass_vbr_bias_pct = arg_parse_uint(&arg);
1113 if (global->passes < 2)
1114 aom_tools_warn("option %s ignored in one-pass mode.\n", arg.name);
1115 } else if (arg_match(&arg, &g_av1_codec_arg_defs.minsection_pct, argi)) {
1116 config->cfg.rc_2pass_vbr_minsection_pct = arg_parse_uint(&arg);
1117
1118 if (global->passes < 2)
1119 aom_tools_warn("option %s ignored in one-pass mode.\n", arg.name);
1120 } else if (arg_match(&arg, &g_av1_codec_arg_defs.maxsection_pct, argi)) {
1121 config->cfg.rc_2pass_vbr_maxsection_pct = arg_parse_uint(&arg);
1122
1123 if (global->passes < 2)
1124 aom_tools_warn("option %s ignored in one-pass mode.\n", arg.name);
1125 } else if (arg_match(&arg, &g_av1_codec_arg_defs.fwd_kf_enabled, argi)) {
1126 config->cfg.fwd_kf_enabled = arg_parse_uint(&arg);
1127 } else if (arg_match(&arg, &g_av1_codec_arg_defs.kf_min_dist, argi)) {
1128 config->cfg.kf_min_dist = arg_parse_uint(&arg);
1129 } else if (arg_match(&arg, &g_av1_codec_arg_defs.kf_max_dist, argi)) {
1130 config->cfg.kf_max_dist = arg_parse_uint(&arg);
1131 } else if (arg_match(&arg, &g_av1_codec_arg_defs.kf_disabled, argi)) {
1132 config->cfg.kf_mode = AOM_KF_DISABLED;
1133 } else if (arg_match(&arg, &g_av1_codec_arg_defs.sframe_dist, argi)) {
1134 config->cfg.sframe_dist = arg_parse_uint(&arg);
1135 } else if (arg_match(&arg, &g_av1_codec_arg_defs.sframe_mode, argi)) {
1136 config->cfg.sframe_mode = arg_parse_uint(&arg);
1137 } else if (arg_match(&arg, &g_av1_codec_arg_defs.save_as_annexb, argi)) {
1138 config->cfg.save_as_annexb = arg_parse_uint(&arg);
1139 } else if (arg_match(&arg, &g_av1_codec_arg_defs.tile_width, argi)) {
1140 config->cfg.tile_width_count =
1141 arg_parse_list(&arg, config->cfg.tile_widths, MAX_TILE_WIDTHS);
1142 } else if (arg_match(&arg, &g_av1_codec_arg_defs.tile_height, argi)) {
1143 config->cfg.tile_height_count =
1144 arg_parse_list(&arg, config->cfg.tile_heights, MAX_TILE_HEIGHTS);
1145#if CONFIG_TUNE_VMAF
1146 } else if (arg_match(&arg, &g_av1_codec_arg_defs.vmaf_model_path, argi)) {
1147 config->vmaf_model_path = arg.val;
1148#endif
1149 } else if (arg_match(&arg, &g_av1_codec_arg_defs.partition_info_path,
1150 argi)) {
1151 config->partition_info_path = arg.val;
1152 } else if (arg_match(&arg, &g_av1_codec_arg_defs.enable_rate_guide_deltaq,
1153 argi)) {
1154 config->enable_rate_guide_deltaq = arg_parse_uint(&arg);
1155 } else if (arg_match(&arg, &g_av1_codec_arg_defs.rate_distribution_info,
1156 argi)) {
1157 config->rate_distribution_info = arg.val;
1158 } else if (arg_match(&arg,
1159 &g_av1_codec_arg_defs.enable_low_complexity_decode,
1160 argi)) {
1161 config->enable_low_complexity_decode = arg_parse_uint(&arg);
1162 } else if (arg_match(&arg, &g_av1_codec_arg_defs.use_fixed_qp_offsets,
1163 argi)) {
1164 config->cfg.use_fixed_qp_offsets = arg_parse_uint(&arg);
1165 } else if (arg_match(&arg, &g_av1_codec_arg_defs.fixed_qp_offsets, argi)) {
1166 config->cfg.use_fixed_qp_offsets = 1;
1167 } else if (global->usage == AOM_USAGE_REALTIME &&
1168 arg_match(&arg, &g_av1_codec_arg_defs.enable_restoration,
1169 argi)) {
1170 if (arg_parse_uint(&arg) == 1) {
1171 aom_tools_warn("non-zero %s option ignored in realtime mode.\n",
1172 arg.name);
1173 }
1174 } else if (arg_match(&arg, &g_av1_codec_arg_defs.two_pass_input, argi)) {
1175 config->two_pass_input = arg.val;
1176 } else if (arg_match(&arg, &g_av1_codec_arg_defs.two_pass_output, argi)) {
1177 config->two_pass_output = arg.val;
1178 } else if (arg_match(&arg, &g_av1_codec_arg_defs.two_pass_width, argi)) {
1179 config->two_pass_width = arg_parse_int(&arg);
1180 } else if (arg_match(&arg, &g_av1_codec_arg_defs.two_pass_height, argi)) {
1181 config->two_pass_height = arg_parse_int(&arg);
1182 } else {
1183 int i, match = 0;
1184 // check if the control ID API supports this arg
1185 if (ctrl_args_map) {
1186 for (i = 0; ctrl_args[i]; i++) {
1187 if (arg_match(&arg, ctrl_args[i], argi)) {
1188 match = 1;
1189 set_config_arg_ctrls(config, ctrl_args_map[i], &arg);
1190 break;
1191 }
1192 }
1193 }
1194 if (!match) {
1195 // check if the key & value API supports this arg
1196 for (i = 0; key_val_args[i]; i++) {
1197 if (arg_match(&arg, key_val_args[i], argi)) {
1198 match = 1;
1199 set_config_arg_key_vals(config, key_val_args[i]->long_name, &arg);
1200 break;
1201 }
1202 }
1203 }
1204 if (!match) argj++;
1205 }
1206 }
1207 config->use_16bit_internal |= config->cfg.g_bit_depth > AOM_BITS_8;
1208
1209 if (global->usage == AOM_USAGE_REALTIME && config->cfg.g_lag_in_frames != 0) {
1210 aom_tools_warn("non-zero lag-in-frames option ignored in realtime mode.\n");
1211 config->cfg.g_lag_in_frames = 0;
1212 }
1213
1214 if (global->usage == AOM_USAGE_ALL_INTRA) {
1215 if (config->cfg.g_lag_in_frames != 0) {
1216 aom_tools_warn(
1217 "non-zero lag-in-frames option ignored in all intra mode.\n");
1218 config->cfg.g_lag_in_frames = 0;
1219 }
1220 if (config->cfg.kf_max_dist != 0) {
1221 aom_tools_warn(
1222 "non-zero max key frame distance option ignored in all intra "
1223 "mode.\n");
1224 config->cfg.kf_max_dist = 0;
1225 }
1226 }
1227
1228 // set the passes field using key & val API
1229 if (config->arg_key_val_cnt >= ARG_KEY_VAL_CNT_MAX) {
1230 die("Not enough buffer for the key & value API.");
1231 }
1232 config->arg_key_vals[config->arg_key_val_cnt][0] = "passes";
1233 switch (global->passes) {
1234 case 0: config->arg_key_vals[config->arg_key_val_cnt][1] = "0"; break;
1235 case 1: config->arg_key_vals[config->arg_key_val_cnt][1] = "1"; break;
1236 case 2: config->arg_key_vals[config->arg_key_val_cnt][1] = "2"; break;
1237 case 3: config->arg_key_vals[config->arg_key_val_cnt][1] = "3"; break;
1238 default: die("Invalid value of --passes.");
1239 }
1240 config->arg_key_val_cnt++;
1241
1242 // set the two_pass_output field
1243 if (!config->two_pass_output && global->passes == 3) {
1244 // If not specified, set the name of two_pass_output file here.
1245 snprintf(stream->tmp_out_fn, sizeof(stream->tmp_out_fn),
1246 "%.980s_pass2_%d.ivf", stream->config.out_fn, stream->index);
1247 stream->config.two_pass_output = stream->tmp_out_fn;
1248 }
1249 if (config->two_pass_output) {
1250 config->arg_key_vals[config->arg_key_val_cnt][0] = "two-pass-output";
1251 config->arg_key_vals[config->arg_key_val_cnt][1] = config->two_pass_output;
1252 config->arg_key_val_cnt++;
1253 }
1254
1255 return eos_mark_found;
1256}
1257
1258#define FOREACH_STREAM(iterator, list) \
1259 for (struct stream_state *iterator = list; iterator; \
1260 iterator = iterator->next)
1261
1262 static void validate_stream_config(const struct stream_state *stream,
1263 const struct AvxEncoderConfig *global) {
1264 const struct stream_state *streami;
1265 (void)global;
1266
1267 if (!stream->config.cfg.g_w || !stream->config.cfg.g_h)
1268 fatal(
1269 "Stream %d: Specify stream dimensions with --width (-w) "
1270 " and --height (-h)",
1271 stream->index);
1272
1273 /* Even if bit depth is set on the command line flag to be lower,
1274 * it is upgraded to at least match the input bit depth.
1275 */
1276 assert(stream->config.cfg.g_input_bit_depth <=
1277 (unsigned int)stream->config.cfg.g_bit_depth);
1278
1279 for (streami = stream; streami; streami = streami->next) {
1280 /* All streams require output files */
1281 if (!streami->config.out_fn)
1282 fatal("Stream %d: Output file is required (specify with -o)",
1283 streami->index);
1284
1285 /* Check for two streams outputting to the same file */
1286 if (streami != stream) {
1287 const char *a = stream->config.out_fn;
1288 const char *b = streami->config.out_fn;
1289 if (!strcmp(a, b) && strcmp(a, "/dev/null") && strcmp(a, ":nul"))
1290 fatal("Stream %d: duplicate output file (from stream %d)",
1291 streami->index, stream->index);
1292 }
1293
1294 /* Check for two streams sharing a stats file. */
1295 if (streami != stream) {
1296 const char *a = stream->config.stats_fn;
1297 const char *b = streami->config.stats_fn;
1298 if (a && b && !strcmp(a, b))
1299 fatal("Stream %d: duplicate stats file (from stream %d)",
1300 streami->index, stream->index);
1301 }
1302 }
1303}
1304
1305 static void set_stream_dimensions(struct stream_state *stream, unsigned int w,
1306 unsigned int h) {
1307 if (!stream->config.cfg.g_w) {
1308 if (!stream->config.cfg.g_h)
1309 stream->config.cfg.g_w = w;
1310 else
1311 stream->config.cfg.g_w = w * stream->config.cfg.g_h / h;
1312 }
1313 if (!stream->config.cfg.g_h) {
1314 stream->config.cfg.g_h = h * stream->config.cfg.g_w / w;
1315 }
1316}
1317
1318 static const char *file_type_to_string(enum VideoFileType t) {
1319 switch (t) {
1320 case FILE_TYPE_RAW: return "RAW";
1321 case FILE_TYPE_Y4M: return "Y4M";
1322 default: return "Other";
1323 }
1324}
1325
1326 static void show_stream_config(struct stream_state *stream,
1327 struct AvxEncoderConfig *global,
1328 struct AvxInputContext *input) {
1329#define SHOW(field) \
1330 fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field)
1331
1332 if (stream->index == 0) {
1333 fprintf(stderr, "Codec: %s\n", aom_codec_iface_name(global->codec));
1334 fprintf(stderr, "Source file: %s File Type: %s Format: %s\n",
1335 input->filename, file_type_to_string(input->file_type),
1336 image_format_to_string(input->fmt));
1337 }
1338 if (stream->next || stream->index)
1339 fprintf(stderr, "\nStream Index: %d\n", stream->index);
1340 fprintf(stderr, "Destination file: %s\n", stream->config.out_fn);
1341 fprintf(stderr, "Coding path: %s\n",
1342 stream->config.use_16bit_internal ? "HBD" : "LBD");
1343 fprintf(stderr, "Encoder parameters:\n");
1344
1345 SHOW(g_usage);
1346 SHOW(g_threads);
1347 SHOW(g_profile);
1348 SHOW(g_w);
1349 SHOW(g_h);
1350 SHOW(g_bit_depth);
1351 SHOW(g_input_bit_depth);
1352 SHOW(g_timebase.num);
1353 SHOW(g_timebase.den);
1354 SHOW(g_error_resilient);
1355 SHOW(g_pass);
1356 SHOW(g_lag_in_frames);
1357 SHOW(large_scale_tile);
1358 SHOW(rc_dropframe_thresh);
1359 SHOW(rc_resize_mode);
1360 SHOW(rc_resize_denominator);
1361 SHOW(rc_resize_kf_denominator);
1362 SHOW(rc_superres_mode);
1363 SHOW(rc_superres_denominator);
1364 SHOW(rc_superres_kf_denominator);
1365 SHOW(rc_superres_qthresh);
1366 SHOW(rc_superres_kf_qthresh);
1367 SHOW(rc_end_usage);
1368 SHOW(rc_target_bitrate);
1369 SHOW(rc_min_quantizer);
1370 SHOW(rc_max_quantizer);
1371 SHOW(rc_undershoot_pct);
1372 SHOW(rc_overshoot_pct);
1373 SHOW(rc_buf_sz);
1374 SHOW(rc_buf_initial_sz);
1375 SHOW(rc_buf_optimal_sz);
1376 SHOW(rc_2pass_vbr_bias_pct);
1377 SHOW(rc_2pass_vbr_minsection_pct);
1378 SHOW(rc_2pass_vbr_maxsection_pct);
1379 SHOW(fwd_kf_enabled);
1380 SHOW(kf_mode);
1381 SHOW(kf_min_dist);
1382 SHOW(kf_max_dist);
1383
1384#define SHOW_PARAMS(field) \
1385 fprintf(stderr, " %-28s = %d\n", #field, \
1386 stream->config.cfg.encoder_cfg.field)
1387 if (global->encoder_config.init_by_cfg_file) {
1388 SHOW_PARAMS(super_block_size);
1389 SHOW_PARAMS(max_partition_size);
1390 SHOW_PARAMS(min_partition_size);
1391 SHOW_PARAMS(disable_ab_partition_type);
1392 SHOW_PARAMS(disable_rect_partition_type);
1393 SHOW_PARAMS(disable_1to4_partition_type);
1394 SHOW_PARAMS(disable_flip_idtx);
1395 SHOW_PARAMS(disable_cdef);
1396 SHOW_PARAMS(disable_lr);
1397 SHOW_PARAMS(disable_obmc);
1398 SHOW_PARAMS(disable_warp_motion);
1399 SHOW_PARAMS(disable_global_motion);
1400 SHOW_PARAMS(disable_dist_wtd_comp);
1401 SHOW_PARAMS(disable_diff_wtd_comp);
1402 SHOW_PARAMS(disable_inter_intra_comp);
1403 SHOW_PARAMS(disable_masked_comp);
1404 SHOW_PARAMS(disable_one_sided_comp);
1405 SHOW_PARAMS(disable_palette);
1406 SHOW_PARAMS(disable_intrabc);
1407 SHOW_PARAMS(disable_cfl);
1408 SHOW_PARAMS(disable_smooth_intra);
1409 SHOW_PARAMS(disable_filter_intra);
1410 SHOW_PARAMS(disable_dual_filter);
1411 SHOW_PARAMS(disable_intra_angle_delta);
1412 SHOW_PARAMS(disable_intra_edge_filter);
1413 SHOW_PARAMS(disable_tx_64x64);
1414 SHOW_PARAMS(disable_smooth_inter_intra);
1415 SHOW_PARAMS(disable_inter_inter_wedge);
1416 SHOW_PARAMS(disable_inter_intra_wedge);
1417 SHOW_PARAMS(disable_paeth_intra);
1418 SHOW_PARAMS(disable_trellis_quant);
1419 SHOW_PARAMS(disable_ref_frame_mv);
1420 SHOW_PARAMS(reduced_reference_set);
1421 SHOW_PARAMS(reduced_tx_type_set);
1422 }
1423}
1424
1425 static void open_output_file(struct stream_state *stream,
1426 struct AvxEncoderConfig *global,
1427 const struct AvxRational *pixel_aspect_ratio,
1428 const char *encoder_settings) {
1429 const char *fn = stream->config.out_fn;
1430 const struct aom_codec_enc_cfg *const cfg = &stream->config.cfg;
1431
1432 if (cfg->g_pass == AOM_RC_FIRST_PASS) return;
1433
1434 stream->file = strcmp(fn, "-") ? fopen(fn, "wb") : set_binary_mode(stdout);
1435
1436 if (!stream->file) fatal("Failed to open output file");
1437
1438 if (stream->config.write_webm && fseek(stream->file, 0, SEEK_CUR))
1439 fatal("WebM output to pipes not supported.");
1440
1441#if CONFIG_WEBM_IO
1442 if (stream->config.write_webm) {
1443 stream->webm_ctx.stream = stream->file;
1444 if (write_webm_file_header(&stream->webm_ctx, &stream->encoder, cfg,
1445 stream->config.stereo_fmt,
1446 get_fourcc_by_aom_encoder(global->codec),
1447 pixel_aspect_ratio, encoder_settings) != 0) {
1448 fatal("WebM writer initialization failed.");
1449 }
1450 }
1451#else
1452 (void)pixel_aspect_ratio;
1453 (void)encoder_settings;
1454#endif
1455
1456 if (!stream->config.write_webm && stream->config.write_ivf) {
1457 ivf_write_file_header(stream->file, cfg,
1458 get_fourcc_by_aom_encoder(global->codec), 0);
1459 }
1460}
1461
1462 static void close_output_file(struct stream_state *stream,
1463 unsigned int fourcc) {
1464 const struct aom_codec_enc_cfg *const cfg = &stream->config.cfg;
1465
1466 if (cfg->g_pass == AOM_RC_FIRST_PASS) return;
1467
1468#if CONFIG_WEBM_IO
1469 if (stream->config.write_webm) {
1470 if (write_webm_file_footer(&stream->webm_ctx) != 0) {
1471 fatal("WebM writer finalization failed.");
1472 }
1473 }
1474#endif
1475
1476 if (!stream->config.write_webm && stream->config.write_ivf) {
1477 if (!fseek(stream->file, 0, SEEK_SET))
1478 ivf_write_file_header(stream->file, &stream->config.cfg, fourcc,
1479 stream->frames_out);
1480 }
1481
1482 fclose(stream->file);
1483}
1484
1485 static void setup_pass(struct stream_state *stream,
1486 struct AvxEncoderConfig *global, int pass) {
1487 if (stream->config.stats_fn) {
1488 if (!stats_open_file(&stream->stats, stream->config.stats_fn, pass))
1489 fatal("Failed to open statistics store");
1490 } else {
1491 if (!stats_open_mem(&stream->stats, pass))
1492 fatal("Failed to open statistics store");
1493 }
1494
1495 if (global->passes == 1) {
1496 stream->config.cfg.g_pass = AOM_RC_ONE_PASS;
1497 } else {
1498 switch (pass) {
1499 case 0: stream->config.cfg.g_pass = AOM_RC_FIRST_PASS; break;
1500 case 1: stream->config.cfg.g_pass = AOM_RC_SECOND_PASS; break;
1501 case 2: stream->config.cfg.g_pass = AOM_RC_THIRD_PASS; break;
1502 default: fatal("Failed to set pass");
1503 }
1504 }
1505
1506 if (pass) {
1507 stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats);
1508 }
1509
1510 stream->cx_time = 0;
1511 stream->nbytes = 0;
1512 stream->frames_out = 0;
1513}
1514
1515 static void initialize_encoder(struct stream_state *stream,
1516 struct AvxEncoderConfig *global) {
1517 int i;
1518 int flags = 0;
1519
1520 flags |= (global->show_psnr >= 1) ? AOM_CODEC_USE_PSNR : 0;
1521 flags |= stream->config.use_16bit_internal ? AOM_CODEC_USE_HIGHBITDEPTH : 0;
1522
1523 /* Construct Encoder Context */
1524 aom_codec_enc_init(&stream->encoder, global->codec, &stream->config.cfg,
1525 flags);
1526 ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder");
1527
1528 for (i = 0; i < stream->config.arg_ctrl_cnt; i++) {
1529 int ctrl = stream->config.arg_ctrls[i][0];
1530 int value = stream->config.arg_ctrls[i][1];
1531 if (aom_codec_control(&stream->encoder, ctrl, value))
1532 fprintf(stderr, "Error: Tried to set control %d = %d\n", ctrl, value);
1533
1534 ctx_exit_on_error(&stream->encoder, "Failed to control codec");
1535 }
1536
1537 for (i = 0; i < stream->config.arg_key_val_cnt; i++) {
1538 const char *name = stream->config.arg_key_vals[i][0];
1539 const char *val = stream->config.arg_key_vals[i][1];
1540 if (aom_codec_set_option(&stream->encoder, name, val))
1541 fprintf(stderr, "Error: Tried to set option %s = %s\n", name, val);
1542
1543 ctx_exit_on_error(&stream->encoder, "Failed to set codec option");
1544 }
1545
1546#if CONFIG_TUNE_VMAF
1547 if (stream->config.vmaf_model_path) {
1548 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1E_SET_VMAF_MODEL_PATH,
1549 stream->config.vmaf_model_path);
1550 ctx_exit_on_error(&stream->encoder, "Failed to set vmaf model path");
1551 }
1552#endif
1553 if (stream->config.partition_info_path) {
1554 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
1555 AV1E_SET_PARTITION_INFO_PATH,
1556 stream->config.partition_info_path);
1557 ctx_exit_on_error(&stream->encoder, "Failed to set partition info path");
1558 }
1559 if (stream->config.enable_rate_guide_deltaq) {
1560 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
1561 AV1E_ENABLE_RATE_GUIDE_DELTAQ,
1562 stream->config.enable_rate_guide_deltaq);
1563 ctx_exit_on_error(&stream->encoder, "Failed to enable rate guide deltaq");
1564 }
1565 if (stream->config.rate_distribution_info) {
1566 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
1567 AV1E_SET_RATE_DISTRIBUTION_INFO,
1568 stream->config.rate_distribution_info);
1569 ctx_exit_on_error(&stream->encoder, "Failed to set rate distribution info");
1570 }
1571
1572 if (stream->config.enable_low_complexity_decode) {
1573 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
1574 AV1E_SET_ENABLE_LOW_COMPLEXITY_DECODE,
1575 stream->config.enable_low_complexity_decode);
1576 ctx_exit_on_error(&stream->encoder,
1577 "Failed to enable low complexity decode");
1578 }
1579
1580 if (stream->config.film_grain_filename) {
1581 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1E_SET_FILM_GRAIN_TABLE,
1582 stream->config.film_grain_filename);
1583 ctx_exit_on_error(&stream->encoder, "Failed to set film grain table");
1584 }
1585 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1E_SET_COLOR_RANGE,
1586 stream->config.color_range);
1587 ctx_exit_on_error(&stream->encoder, "Failed to set color range");
1588
1589#if CONFIG_AV1_DECODER
1590 if (global->test_decode != TEST_DECODE_OFF) {
1591 aom_codec_iface_t *decoder = get_aom_decoder_by_short_name(
1592 get_short_name_by_aom_encoder(global->codec));
1593 aom_codec_dec_cfg_t cfg = { 0, 0, 0, !stream->config.use_16bit_internal };
1594 aom_codec_dec_init(&stream->decoder, decoder, &cfg, 0);
1595
1596 if (strcmp(get_short_name_by_aom_encoder(global->codec), "av1") == 0) {
1597 AOM_CODEC_CONTROL_TYPECHECKED(&stream->decoder, AV1_SET_TILE_MODE,
1598 stream->config.cfg.large_scale_tile);
1599 ctx_exit_on_error(&stream->decoder, "Failed to set decode_tile_mode");
1600
1601 AOM_CODEC_CONTROL_TYPECHECKED(&stream->decoder, AV1D_SET_IS_ANNEXB,
1602 stream->config.cfg.save_as_annexb);
1603 ctx_exit_on_error(&stream->decoder, "Failed to set is_annexb");
1604
1605 AOM_CODEC_CONTROL_TYPECHECKED(&stream->decoder, AV1_SET_DECODE_TILE_ROW,
1606 -1);
1607 ctx_exit_on_error(&stream->decoder, "Failed to set decode_tile_row");
1608
1609 AOM_CODEC_CONTROL_TYPECHECKED(&stream->decoder, AV1_SET_DECODE_TILE_COL,
1610 -1);
1611 ctx_exit_on_error(&stream->decoder, "Failed to set decode_tile_col");
1612 }
1613 }
1614#endif
1615}
1616
1617// Convert the input image 'img' to a monochrome image. The Y plane of the
1618// output image is a shallow copy of the Y plane of the input image, therefore
1619// the input image must remain valid for the lifetime of the output image. The U
1620// and V planes of the output image are set to null pointers. The output image
1621// format is AOM_IMG_FMT_I420 because libaom does not have AOM_IMG_FMT_I400.
1622 static void convert_image_to_monochrome(const struct aom_image *img,
1623 struct aom_image *monochrome_img) {
1624 *monochrome_img = *img;
1625 monochrome_img->fmt = AOM_IMG_FMT_I420;
1626 if (img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
1627 monochrome_img->fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
1628 }
1629 monochrome_img->monochrome = 1;
1630 monochrome_img->csp = AOM_CSP_UNKNOWN;
1631 monochrome_img->x_chroma_shift = 1;
1632 monochrome_img->y_chroma_shift = 1;
1633 monochrome_img->planes[AOM_PLANE_U] = NULL;
1634 monochrome_img->planes[AOM_PLANE_V] = NULL;
1635 monochrome_img->stride[AOM_PLANE_U] = 0;
1636 monochrome_img->stride[AOM_PLANE_V] = 0;
1637 monochrome_img->sz = 0;
1638 monochrome_img->bps = (img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
1639 monochrome_img->img_data = NULL;
1640 monochrome_img->img_data_owner = 0;
1641 monochrome_img->self_allocd = 0;
1642}
1643
1644 static void encode_frame(struct stream_state *stream,
1645 struct AvxEncoderConfig *global, struct aom_image *img,
1646 unsigned int frames_in) {
1647 aom_codec_pts_t frame_start, next_frame_start;
1648 struct aom_codec_enc_cfg *cfg = &stream->config.cfg;
1649 struct aom_usec_timer timer;
1650
1651 frame_start =
1652 (cfg->g_timebase.den * (int64_t)(frames_in - 1) * global->framerate.den) /
1653 cfg->g_timebase.num / global->framerate.num;
1654 next_frame_start =
1655 (cfg->g_timebase.den * (int64_t)(frames_in)*global->framerate.den) /
1656 cfg->g_timebase.num / global->framerate.num;
1657
1658 /* Scale if necessary */
1659 if (img) {
1660 if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) &&
1661 (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) {
1662 if (img->fmt != AOM_IMG_FMT_I42016) {
1663 fprintf(stderr, "%s can only scale 4:2:0 inputs\n", exec_name);
1664 exit(EXIT_FAILURE);
1665 }
1666#if CONFIG_LIBYUV
1667 if (!stream->img) {
1668 stream->img =
1669 aom_img_alloc(NULL, AOM_IMG_FMT_I42016, cfg->g_w, cfg->g_h, 16);
1670 }
1671 I420Scale_16(
1672 (uint16_t *)img->planes[AOM_PLANE_Y], img->stride[AOM_PLANE_Y] / 2,
1673 (uint16_t *)img->planes[AOM_PLANE_U], img->stride[AOM_PLANE_U] / 2,
1674 (uint16_t *)img->planes[AOM_PLANE_V], img->stride[AOM_PLANE_V] / 2,
1675 img->d_w, img->d_h, (uint16_t *)stream->img->planes[AOM_PLANE_Y],
1676 stream->img->stride[AOM_PLANE_Y] / 2,
1677 (uint16_t *)stream->img->planes[AOM_PLANE_U],
1678 stream->img->stride[AOM_PLANE_U] / 2,
1679 (uint16_t *)stream->img->planes[AOM_PLANE_V],
1680 stream->img->stride[AOM_PLANE_V] / 2, stream->img->d_w,
1681 stream->img->d_h, kFilterBox);
1682 img = stream->img;
1683#else
1684 stream->encoder.err = 1;
1685 ctx_exit_on_error(&stream->encoder,
1686 "Stream %d: Failed to encode frame.\n"
1687 "libyuv is required for scaling but is currently "
1688 "disabled.\n"
1689 "Be sure to specify -DCONFIG_LIBYUV=1 when running "
1690 "cmake.\n",
1691 stream->index);
1692#endif
1693 }
1694 }
1695 if (img && (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) {
1696 if (img->fmt != AOM_IMG_FMT_I420 && img->fmt != AOM_IMG_FMT_YV12) {
1697 fprintf(stderr, "%s can only scale 4:2:0 8bpp inputs\n", exec_name);
1698 exit(EXIT_FAILURE);
1699 }
1700#if CONFIG_LIBYUV
1701 if (!stream->img)
1702 stream->img =
1703 aom_img_alloc(NULL, AOM_IMG_FMT_I420, cfg->g_w, cfg->g_h, 16);
1704 I420Scale(
1705 img->planes[AOM_PLANE_Y], img->stride[AOM_PLANE_Y],
1706 img->planes[AOM_PLANE_U], img->stride[AOM_PLANE_U],
1707 img->planes[AOM_PLANE_V], img->stride[AOM_PLANE_V], img->d_w, img->d_h,
1708 stream->img->planes[AOM_PLANE_Y], stream->img->stride[AOM_PLANE_Y],
1709 stream->img->planes[AOM_PLANE_U], stream->img->stride[AOM_PLANE_U],
1710 stream->img->planes[AOM_PLANE_V], stream->img->stride[AOM_PLANE_V],
1711 stream->img->d_w, stream->img->d_h, kFilterBox);
1712 img = stream->img;
1713#else
1714 stream->encoder.err = 1;
1715 ctx_exit_on_error(&stream->encoder,
1716 "Stream %d: Failed to encode frame.\n"
1717 "Scaling disabled in this configuration. \n"
1718 "To enable, configure with --enable-libyuv\n",
1719 stream->index);
1720#endif
1721 }
1722
1723 struct aom_image monochrome_img;
1724 if (img && cfg->monochrome) {
1725 convert_image_to_monochrome(img, &monochrome_img);
1726 img = &monochrome_img;
1727 }
1728
1729 aom_usec_timer_start(&timer);
1730 aom_codec_encode(&stream->encoder, img, frame_start,
1731 (uint32_t)(next_frame_start - frame_start), 0);
1732 aom_usec_timer_mark(&timer);
1733 stream->cx_time += aom_usec_timer_elapsed(&timer);
1734 ctx_exit_on_error(&stream->encoder, "Stream %d: Failed to encode frame",
1735 stream->index);
1736}
1737
1738 static void update_quantizer_histogram(struct stream_state *stream) {
1739 if (stream->config.cfg.g_pass != AOM_RC_FIRST_PASS) {
1740 int q;
1741
1742 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AOME_GET_LAST_QUANTIZER_64,
1743 &q);
1744 ctx_exit_on_error(&stream->encoder, "Failed to read quantizer");
1745 stream->counts[q]++;
1746 }
1747}
1748
1749 static void get_cx_data(struct stream_state *stream,
1750 struct AvxEncoderConfig *global, int *got_data) {
1751 const aom_codec_cx_pkt_t *pkt;
1752 const struct aom_codec_enc_cfg *cfg = &stream->config.cfg;
1753 aom_codec_iter_t iter = NULL;
1754
1755 *got_data = 0;
1756 while ((pkt = aom_codec_get_cx_data(&stream->encoder, &iter))) {
1757 static size_t fsize = 0;
1758 static FileOffset ivf_header_pos = 0;
1759
1760 switch (pkt->kind) {
1761 case AOM_CODEC_CX_FRAME_PKT:
1762 ++stream->frames_out;
1763 if (!global->quiet)
1764 fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz);
1765
1766 update_rate_histogram(stream->rate_hist, cfg, pkt);
1767#if CONFIG_WEBM_IO
1768 if (stream->config.write_webm) {
1769 if (write_webm_block(&stream->webm_ctx, cfg, pkt) != 0) {
1770 fatal("WebM writer failed.");
1771 }
1772 }
1773#endif
1774 if (!stream->config.write_webm) {
1775 if (stream->config.write_ivf) {
1776 if (pkt->data.frame.partition_id <= 0) {
1777 ivf_header_pos = ftello(stream->file);
1778 fsize = pkt->data.frame.sz;
1779
1780 ivf_write_frame_header(stream->file, pkt->data.frame.pts, fsize);
1781 } else {
1782 fsize += pkt->data.frame.sz;
1783
1784 const FileOffset currpos = ftello(stream->file);
1785 fseeko(stream->file, ivf_header_pos, SEEK_SET);
1786 ivf_write_frame_size(stream->file, fsize);
1787 fseeko(stream->file, currpos, SEEK_SET);
1788 }
1789 }
1790
1791 (void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
1792 stream->file);
1793 }
1794 stream->nbytes += pkt->data.raw.sz;
1795
1796 *got_data = 1;
1797#if CONFIG_AV1_DECODER
1798 if (global->test_decode != TEST_DECODE_OFF && !stream->mismatch_seen) {
1799 aom_codec_decode(&stream->decoder, pkt->data.frame.buf,
1800 pkt->data.frame.sz, NULL);
1801 if (stream->decoder.err) {
1802 warn_or_exit_on_error(&stream->decoder,
1803 global->test_decode == TEST_DECODE_FATAL,
1804 "Failed to decode frame %d in stream %d",
1805 stream->frames_out + 1, stream->index);
1806 stream->mismatch_seen = stream->frames_out + 1;
1807 }
1808 }
1809#endif
1810 break;
1811 case AOM_CODEC_STATS_PKT:
1812 stream->frames_out++;
1813 stats_write(&stream->stats, pkt->data.twopass_stats.buf,
1814 pkt->data.twopass_stats.sz);
1815 stream->nbytes += pkt->data.raw.sz;
1816 break;
1817 case AOM_CODEC_PSNR_PKT:
1818
1819 if (global->show_psnr >= 1) {
1820 int i;
1821
1822 stream->psnr_sse_total[0] += pkt->data.psnr.sse[0];
1823 stream->psnr_samples_total[0] += pkt->data.psnr.samples[0];
1824 for (i = 0; i < 4; i++) {
1825 if (!global->quiet)
1826 fprintf(stderr, "%.3f ", pkt->data.psnr.psnr[i]);
1827 stream->psnr_totals[0][i] += pkt->data.psnr.psnr[i];
1828 }
1829 stream->psnr_count[0]++;
1830
1831#if CONFIG_AV1_HIGHBITDEPTH
1832 if (stream->config.cfg.g_input_bit_depth <
1833 (unsigned int)stream->config.cfg.g_bit_depth) {
1834 stream->psnr_sse_total[1] += pkt->data.psnr.sse_hbd[0];
1835 stream->psnr_samples_total[1] += pkt->data.psnr.samples_hbd[0];
1836 for (i = 0; i < 4; i++) {
1837 if (!global->quiet)
1838 fprintf(stderr, "%.3f ", pkt->data.psnr.psnr_hbd[i]);
1839 stream->psnr_totals[1][i] += pkt->data.psnr.psnr_hbd[i];
1840 }
1841 stream->psnr_count[1]++;
1842 }
1843#endif
1844 }
1845
1846 break;
1847 default: break;
1848 }
1849 }
1850}
1851
1852 static void show_psnr(struct stream_state *stream, double peak, int64_t bps) {
1853 int i;
1854 double ovpsnr;
1855
1856 if (!stream->psnr_count[0]) return;
1857
1858 fprintf(stderr, "Stream %d PSNR (Overall/Avg/Y/U/V)", stream->index);
1859 ovpsnr = sse_to_psnr((double)stream->psnr_samples_total[0], peak,
1860 (double)stream->psnr_sse_total[0]);
1861 fprintf(stderr, " %.3f", ovpsnr);
1862
1863 for (i = 0; i < 4; i++) {
1864 fprintf(stderr, " %.3f", stream->psnr_totals[0][i] / stream->psnr_count[0]);
1865 }
1866 if (bps > 0) {
1867 fprintf(stderr, " %7" PRId64 " bps", bps);
1868 }
1869 fprintf(stderr, " %7" PRId64 " ms", stream->cx_time / 1000);
1870 fprintf(stderr, "\n");
1871}
1872
1873#if CONFIG_AV1_HIGHBITDEPTH
1874 static void show_psnr_hbd(struct stream_state *stream, double peak,
1875 int64_t bps) {
1876 int i;
1877 double ovpsnr;
1878 // Compute PSNR based on stream bit depth
1879 if (!stream->psnr_count[1]) return;
1880
1881 fprintf(stderr, "Stream %d PSNR (Overall/Avg/Y/U/V)", stream->index);
1882 ovpsnr = sse_to_psnr((double)stream->psnr_samples_total[1], peak,
1883 (double)stream->psnr_sse_total[1]);
1884 fprintf(stderr, " %.3f", ovpsnr);
1885
1886 for (i = 0; i < 4; i++) {
1887 fprintf(stderr, " %.3f", stream->psnr_totals[1][i] / stream->psnr_count[1]);
1888 }
1889 if (bps > 0) {
1890 fprintf(stderr, " %7" PRId64 " bps", bps);
1891 }
1892 fprintf(stderr, " %7" PRId64 " ms", stream->cx_time / 1000);
1893 fprintf(stderr, "\n");
1894}
1895#endif
1896
1897 static float usec_to_fps(uint64_t usec, unsigned int frames) {
1898 return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0);
1899}
1900
1901 static void test_decode(struct stream_state *stream,
1902 enum TestDecodeFatality fatal) {
1903 aom_image_t enc_img, dec_img;
1904
1905 if (stream->mismatch_seen) return;
1906
1907 /* Get the internal reference frame */
1908 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1_GET_NEW_FRAME_IMAGE,
1909 &enc_img);
1910 AOM_CODEC_CONTROL_TYPECHECKED(&stream->decoder, AV1_GET_NEW_FRAME_IMAGE,
1911 &dec_img);
1912
1913 if ((enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) !=
1914 (dec_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH)) {
1915 if (enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
1916 aom_image_t enc_hbd_img;
1917 aom_img_alloc(&enc_hbd_img, enc_img.fmt - AOM_IMG_FMT_HIGHBITDEPTH,
1918 enc_img.d_w, enc_img.d_h, 16);
1919 aom_img_truncate_16_to_8(&enc_hbd_img, &enc_img);
1920 enc_img = enc_hbd_img;
1921 }
1922 if (dec_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
1923 aom_image_t dec_hbd_img;
1924 aom_img_alloc(&dec_hbd_img, dec_img.fmt - AOM_IMG_FMT_HIGHBITDEPTH,
1925 dec_img.d_w, dec_img.d_h, 16);
1926 aom_img_truncate_16_to_8(&dec_hbd_img, &dec_img);
1927 dec_img = dec_hbd_img;
1928 }
1929 }
1930
1931 ctx_exit_on_error(&stream->encoder, "Failed to get encoder reference frame");
1932 ctx_exit_on_error(&stream->decoder, "Failed to get decoder reference frame");
1933
1934 if (!aom_compare_img(&enc_img, &dec_img)) {
1935 int y[4], u[4], v[4];
1936 if (enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
1937 aom_find_mismatch_high(&enc_img, &dec_img, y, u, v);
1938 } else {
1939 aom_find_mismatch(&enc_img, &dec_img, y, u, v);
1940 }
1941 stream->decoder.err = 1;
1942 warn_or_exit_on_error(&stream->decoder, fatal == TEST_DECODE_FATAL,
1943 "Stream %d: Encode/decode mismatch on frame %d at"
1944 " Y[%d, %d] {%d/%d},"
1945 " U[%d, %d] {%d/%d},"
1946 " V[%d, %d] {%d/%d}",
1947 stream->index, stream->frames_out, y[0], y[1], y[2],
1948 y[3], u[0], u[1], u[2], u[3], v[0], v[1], v[2], v[3]);
1949 stream->mismatch_seen = stream->frames_out;
1950 }
1951
1952 aom_img_free(&enc_img);
1953 aom_img_free(&dec_img);
1954}
1955
1956 static void print_time(const char *label, int64_t etl) {
1957 int64_t hours;
1958 int64_t mins;
1959 int64_t secs;
1960
1961 if (etl >= 0) {
1962 hours = etl / 3600;
1963 etl -= hours * 3600;
1964 mins = etl / 60;
1965 etl -= mins * 60;
1966 secs = etl;
1967
1968 fprintf(stderr, "[%3s %2" PRId64 ":%02" PRId64 ":%02" PRId64 "] ", label,
1969 hours, mins, secs);
1970 } else {
1971 fprintf(stderr, "[%3s unknown] ", label);
1972 }
1973}
1974
1975 static void clear_stream_count_state(struct stream_state *stream) {
1976 // PSNR counters
1977 for (int k = 0; k < 2; k++) {
1978 stream->psnr_sse_total[k] = 0;
1979 stream->psnr_samples_total[k] = 0;
1980 for (int i = 0; i < 4; i++) {
1981 stream->psnr_totals[k][i] = 0;
1982 }
1983 stream->psnr_count[k] = 0;
1984 }
1985 // q hist
1986 memset(stream->counts, 0, sizeof(stream->counts));
1987}
1988
1989// aomenc will downscale the second pass if:
1990// 1. the specific pass is not given by commandline (aomenc will perform all
1991// passes)
1992// 2. there are more than 2 passes in total
1993// 3. current pass is the second pass (the parameter pass starts with 0 so
1994// pass == 1)
1995 static int pass_need_downscale(int global_pass, int global_passes, int pass) {
1996 return !global_pass && global_passes > 2 && pass == 1;
1997}
1998
1999 int main(int argc, const char **argv_) {
2000 int pass;
2001 aom_image_t raw;
2002 aom_image_t raw_shift;
2003 int allocated_raw_shift = 0;
2004 int do_16bit_internal = 0;
2005 int input_shift = 0;
2006 int frame_avail, got_data;
2007
2008 struct AvxInputContext input;
2009 struct AvxEncoderConfig global;
2010 struct stream_state *streams = NULL;
2011 char **argv, **argi;
2012 uint64_t cx_time = 0;
2013 int stream_cnt = 0;
2014 int res = 0;
2015 int profile_updated = 0;
2016
2017 memset(&input, 0, sizeof(input));
2018 memset(&raw, 0, sizeof(raw));
2019 exec_name = argv_[0];
2020
2021 /* Setup default input stream settings */
2022 input.framerate.numerator = 30;
2023 input.framerate.denominator = 1;
2024 input.only_i420 = 1;
2025 input.bit_depth = 0;
2026
2027 /* First parse the global configuration values, because we want to apply
2028 * other parameters on top of the default configuration provided by the
2029 * codec.
2030 */
2031 argv = argv_dup(argc - 1, argv_ + 1);
2032 if (!argv) {
2033 fprintf(stderr, "Error allocating argument list\n");
2034 return EXIT_FAILURE;
2035 }
2036 parse_global_config(&global, &argv);
2037
2038 if (argc < 2) usage_exit();
2039
2040 switch (global.color_type) {
2041 case I420: input.fmt = AOM_IMG_FMT_I420; break;
2042 case I422: input.fmt = AOM_IMG_FMT_I422; break;
2043 case I444: input.fmt = AOM_IMG_FMT_I444; break;
2044 case YV12: input.fmt = AOM_IMG_FMT_YV12; break;
2045 case NV12: input.fmt = AOM_IMG_FMT_NV12; break;
2046 }
2047
2048 {
2049 /* Now parse each stream's parameters. Using a local scope here
2050 * due to the use of 'stream' as loop variable in FOREACH_STREAM
2051 * loops
2052 */
2053 struct stream_state *stream = NULL;
2054
2055 do {
2056 stream = new_stream(&global, stream);
2057 stream_cnt++;
2058 if (!streams) streams = stream;
2059 } while (parse_stream_params(&global, stream, argv));
2060 }
2061
2062 /* Check for unrecognized options */
2063 for (argi = argv; *argi; argi++)
2064 if (argi[0][0] == '-' && argi[0][1])
2065 die("Error: Unrecognized option %s\n", *argi);
2066
2067 FOREACH_STREAM(stream, streams) {
2068 check_encoder_config(global.disable_warning_prompt, &global,
2069 &stream->config.cfg);
2070
2071 // If large_scale_tile = 1, only support to output to ivf format.
2072 if (stream->config.cfg.large_scale_tile && !stream->config.write_ivf)
2073 die("only support ivf output format while large-scale-tile=1\n");
2074 }
2075
2076 /* Handle non-option arguments */
2077 input.filename = argv[0];
2078 const char *orig_input_filename = input.filename;
2079 FOREACH_STREAM(stream, streams) {
2080 stream->orig_out_fn = stream->config.out_fn;
2081 stream->orig_width = stream->config.cfg.g_w;
2082 stream->orig_height = stream->config.cfg.g_h;
2083 stream->orig_write_ivf = stream->config.write_ivf;
2084 stream->orig_write_webm = stream->config.write_webm;
2085 }
2086
2087 if (!input.filename) {
2088 fprintf(stderr, "No input file specified!\n");
2089 usage_exit();
2090 }
2091
2092 /* Decide if other chroma subsamplings than 4:2:0 are supported */
2093 if (get_fourcc_by_aom_encoder(global.codec) == AV1_FOURCC)
2094 input.only_i420 = 0;
2095
2096 for (pass = global.pass ? global.pass - 1 : 0; pass < global.passes; pass++) {
2097 if (pass > 1) {
2098 FOREACH_STREAM(stream, streams) { clear_stream_count_state(stream); }
2099 }
2100
2101 int frames_in = 0, seen_frames = 0;
2102 int64_t estimated_time_left = -1;
2103 int64_t average_rate = -1;
2104 int64_t lagged_count = 0;
2105 const int need_downscale =
2106 pass_need_downscale(global.pass, global.passes, pass);
2107
2108 // Set the output to the specified two-pass output file, and
2109 // restore the width and height to the original values.
2110 FOREACH_STREAM(stream, streams) {
2111 if (need_downscale) {
2112 stream->config.out_fn = stream->config.two_pass_output;
2113 // Libaom currently only supports the ivf format for the third pass.
2114 stream->config.write_ivf = 1;
2115 stream->config.write_webm = 0;
2116 } else {
2117 stream->config.out_fn = stream->orig_out_fn;
2118 stream->config.write_ivf = stream->orig_write_ivf;
2119 stream->config.write_webm = stream->orig_write_webm;
2120 }
2121 stream->config.cfg.g_w = stream->orig_width;
2122 stream->config.cfg.g_h = stream->orig_height;
2123 }
2124
2125 // For second pass in three-pass encoding, set the input to
2126 // the given two-pass-input file if available. If the scaled input is not
2127 // given, we will attempt to re-scale the original input.
2128 input.filename = orig_input_filename;
2129 const char *two_pass_input = NULL;
2130 if (need_downscale) {
2131 FOREACH_STREAM(stream, streams) {
2132 if (stream->config.two_pass_input) {
2133 two_pass_input = stream->config.two_pass_input;
2134 input.filename = two_pass_input;
2135 break;
2136 }
2137 }
2138 }
2139
2140 open_input_file(&input, global.csp);
2141
2142 /* If the input file doesn't specify its w/h (raw files), try to get
2143 * the data from the first stream's configuration.
2144 */
2145 if (!input.width || !input.height) {
2146 if (two_pass_input) {
2147 FOREACH_STREAM(stream, streams) {
2148 if (stream->config.two_pass_width && stream->config.two_pass_height) {
2149 input.width = stream->config.two_pass_width;
2150 input.height = stream->config.two_pass_height;
2151 break;
2152 }
2153 }
2154 } else {
2155 FOREACH_STREAM(stream, streams) {
2156 if (stream->config.cfg.g_w && stream->config.cfg.g_h) {
2157 input.width = stream->config.cfg.g_w;
2158 input.height = stream->config.cfg.g_h;
2159 break;
2160 }
2161 }
2162 }
2163 }
2164
2165 /* Update stream configurations from the input file's parameters */
2166 if (!input.width || !input.height) {
2167 if (two_pass_input) {
2168 fatal(
2169 "Specify downscaled stream dimensions with --two-pass-width "
2170 " and --two-pass-height");
2171 } else {
2172 fatal(
2173 "Specify stream dimensions with --width (-w) "
2174 " and --height (-h)");
2175 }
2176 }
2177
2178 if (need_downscale) {
2179 FOREACH_STREAM(stream, streams) {
2180 if (stream->config.two_pass_width && stream->config.two_pass_height) {
2181 stream->config.cfg.g_w = stream->config.two_pass_width;
2182 stream->config.cfg.g_h = stream->config.two_pass_height;
2183 } else if (two_pass_input) {
2184 stream->config.cfg.g_w = input.width;
2185 stream->config.cfg.g_h = input.height;
2186 } else if (stream->orig_width && stream->orig_height) {
2187#if CONFIG_BITRATE_ACCURACY || CONFIG_BITRATE_ACCURACY_BL
2188 stream->config.cfg.g_w = stream->orig_width;
2189 stream->config.cfg.g_h = stream->orig_height;
2190#else // CONFIG_BITRATE_ACCURACY || CONFIG_BITRATE_ACCURACY_BL
2191 stream->config.cfg.g_w = (stream->orig_width + 1) / 2;
2192 stream->config.cfg.g_h = (stream->orig_height + 1) / 2;
2193#endif // CONFIG_BITRATE_ACCURACY || CONFIG_BITRATE_ACCURACY_BL
2194 } else {
2195#if CONFIG_BITRATE_ACCURACY || CONFIG_BITRATE_ACCURACY_BL
2196 stream->config.cfg.g_w = input.width;
2197 stream->config.cfg.g_h = input.height;
2198#else // CONFIG_BITRATE_ACCURACY || CONFIG_BITRATE_ACCURACY_BL
2199 stream->config.cfg.g_w = (input.width + 1) / 2;
2200 stream->config.cfg.g_h = (input.height + 1) / 2;
2201#endif // CONFIG_BITRATE_ACCURACY || CONFIG_BITRATE_ACCURACY_BL
2202 }
2203 }
2204 }
2205
2206 /* If input file does not specify bit-depth but input-bit-depth parameter
2207 * exists, assume that to be the input bit-depth. However, if the
2208 * input-bit-depth paramter does not exist, assume the input bit-depth
2209 * to be the same as the codec bit-depth.
2210 */
2211 if (!input.bit_depth) {
2212 FOREACH_STREAM(stream, streams) {
2213 if (stream->config.cfg.g_input_bit_depth)
2214 input.bit_depth = stream->config.cfg.g_input_bit_depth;
2215 else
2216 input.bit_depth = stream->config.cfg.g_input_bit_depth =
2217 (int)stream->config.cfg.g_bit_depth;
2218 }
2219 if (input.bit_depth > 8) input.fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
2220 } else {
2221 FOREACH_STREAM(stream, streams) {
2222 stream->config.cfg.g_input_bit_depth = input.bit_depth;
2223 }
2224 }
2225
2226 FOREACH_STREAM(stream, streams) {
2227 if (input.fmt != AOM_IMG_FMT_I420 && input.fmt != AOM_IMG_FMT_I42016 &&
2228 input.fmt != AOM_IMG_FMT_NV12) {
2229 /* Automatically upgrade if input is non-4:2:0 but a 4:2:0 profile
2230 was selected. */
2231 switch (stream->config.cfg.g_profile) {
2232 case 0:
2233 if (input.bit_depth < 12 && (input.fmt == AOM_IMG_FMT_I444 ||
2234 input.fmt == AOM_IMG_FMT_I44416)) {
2235 if (!stream->config.cfg.monochrome) {
2236 stream->config.cfg.g_profile = 1;
2237 profile_updated = 1;
2238 }
2239 } else if (input.bit_depth == 12 ||
2240 ((input.fmt == AOM_IMG_FMT_I422 ||
2241 input.fmt == AOM_IMG_FMT_I42216) &&
2242 !stream->config.cfg.monochrome)) {
2243 stream->config.cfg.g_profile = 2;
2244 profile_updated = 1;
2245 }
2246 break;
2247 case 1:
2248 if (input.bit_depth == 12 || input.fmt == AOM_IMG_FMT_I422 ||
2249 input.fmt == AOM_IMG_FMT_I42216) {
2250 stream->config.cfg.g_profile = 2;
2251 profile_updated = 1;
2252 } else if (input.bit_depth < 12 &&
2253 (input.fmt == AOM_IMG_FMT_I420 ||
2254 input.fmt == AOM_IMG_FMT_I42016)) {
2255 stream->config.cfg.g_profile = 0;
2256 profile_updated = 1;
2257 }
2258 break;
2259 case 2:
2260 if (input.bit_depth < 12 && (input.fmt == AOM_IMG_FMT_I444 ||
2261 input.fmt == AOM_IMG_FMT_I44416)) {
2262 stream->config.cfg.g_profile = 1;
2263 profile_updated = 1;
2264 } else if (input.bit_depth < 12 &&
2265 (input.fmt == AOM_IMG_FMT_I420 ||
2266 input.fmt == AOM_IMG_FMT_I42016)) {
2267 stream->config.cfg.g_profile = 0;
2268 profile_updated = 1;
2269 } else if (input.bit_depth == 12 &&
2270 input.file_type == FILE_TYPE_Y4M) {
2271 // Note that here the input file values for chroma subsampling
2272 // are used instead of those from the command line.
2273 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
2274 AV1E_SET_CHROMA_SUBSAMPLING_X,
2275 input.y4m.dst_c_dec_h >> 1);
2276 ctx_exit_on_error(&stream->encoder,
2277 "Failed to set chroma subsampling x");
2278 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
2279 AV1E_SET_CHROMA_SUBSAMPLING_Y,
2280 input.y4m.dst_c_dec_v >> 1);
2281 ctx_exit_on_error(&stream->encoder,
2282 "Failed to set chroma subsampling y");
2283 } else if (input.bit_depth == 12 &&
2284 input.file_type == FILE_TYPE_RAW) {
2285 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
2286 AV1E_SET_CHROMA_SUBSAMPLING_X,
2287 stream->chroma_subsampling_x);
2288 ctx_exit_on_error(&stream->encoder,
2289 "Failed to set chroma subsampling x");
2290 AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder,
2291 AV1E_SET_CHROMA_SUBSAMPLING_Y,
2292 stream->chroma_subsampling_y);
2293 ctx_exit_on_error(&stream->encoder,
2294 "Failed to set chroma subsampling y");
2295 }
2296 break;
2297 default: break;
2298 }
2299 }
2300 /* Automatically set the codec bit depth to match the input bit depth.
2301 * Upgrade the profile if required. */
2302 if (stream->config.cfg.g_input_bit_depth >
2303 (unsigned int)stream->config.cfg.g_bit_depth) {
2304 stream->config.cfg.g_bit_depth = stream->config.cfg.g_input_bit_depth;
2305 if (!global.quiet) {
2306 fprintf(stderr,
2307 "Warning: automatically updating bit depth to %d to "
2308 "match input format.\n",
2309 stream->config.cfg.g_input_bit_depth);
2310 }
2311 }
2312#if !CONFIG_AV1_HIGHBITDEPTH
2313 if (stream->config.cfg.g_bit_depth > 8) {
2314 fatal("Unsupported bit-depth with CONFIG_AV1_HIGHBITDEPTH=0\n");
2315 }
2316#endif // CONFIG_AV1_HIGHBITDEPTH
2317 if (stream->config.cfg.g_bit_depth > 10) {
2318 switch (stream->config.cfg.g_profile) {
2319 case 0:
2320 case 1:
2321 stream->config.cfg.g_profile = 2;
2322 profile_updated = 1;
2323 break;
2324 default: break;
2325 }
2326 }
2327 if (stream->config.cfg.g_bit_depth > 8) {
2328 stream->config.use_16bit_internal = 1;
2329 }
2330 if (profile_updated && !global.quiet) {
2331 fprintf(stderr,
2332 "Warning: automatically updating to profile %d to "
2333 "match input format.\n",
2334 stream->config.cfg.g_profile);
2335 }
2336 if (global.show_psnr == 2 &&
2337 stream->config.cfg.g_input_bit_depth ==
2338 (unsigned int)stream->config.cfg.g_bit_depth) {
2339 fprintf(stderr,
2340 "Warning: --psnr==2 and --psnr==1 will provide same "
2341 "results when input bit-depth == stream bit-depth, "
2342 "falling back to default psnr value\n");
2343 global.show_psnr = 1;
2344 }
2345 if (global.show_psnr < 0 || global.show_psnr > 2) {
2346 fprintf(stderr,
2347 "Warning: --psnr can take only 0,1,2 as values,"
2348 "falling back to default psnr value\n");
2349 global.show_psnr = 1;
2350 }
2351 /* Set limit */
2352 stream->config.cfg.g_limit = global.limit;
2353 }
2354
2355 FOREACH_STREAM(stream, streams) {
2356 set_stream_dimensions(stream, input.width, input.height);
2357 stream->config.color_range = input.color_range;
2358 }
2359 FOREACH_STREAM(stream, streams) { validate_stream_config(stream, &global); }
2360
2361 /* Ensure that --passes and --pass are consistent. If --pass is set and
2362 * --passes >= 2, ensure --fpf was set.
2363 */
2364 if (global.pass > 0 && global.pass <= 3 && global.passes >= 2) {
2365 FOREACH_STREAM(stream, streams) {
2366 if (!stream->config.stats_fn)
2367 die("Stream %d: Must specify --fpf when --pass=%d"
2368 " and --passes=%d\n",
2369 stream->index, global.pass, global.passes);
2370 }
2371 }
2372
2373#if !CONFIG_WEBM_IO
2374 FOREACH_STREAM(stream, streams) {
2375 if (stream->config.write_webm) {
2376 stream->config.write_webm = 0;
2377 stream->config.write_ivf = 0;
2378 aom_tools_warn("aomenc compiled w/o WebM support. Writing OBU stream.");
2379 }
2380 }
2381#endif
2382
2383 /* Use the frame rate from the file only if none was specified
2384 * on the command-line.
2385 */
2386 if (!global.have_framerate) {
2387 global.framerate.num = input.framerate.numerator;
2388 global.framerate.den = input.framerate.denominator;
2389 }
2390 FOREACH_STREAM(stream, streams) {
2391 stream->config.cfg.g_timebase.den = global.framerate.num;
2392 stream->config.cfg.g_timebase.num = global.framerate.den;
2393 }
2394 /* Show configuration */
2395 if (global.verbose && pass == 0) {
2396 FOREACH_STREAM(stream, streams) {
2397 show_stream_config(stream, &global, &input);
2398 }
2399 }
2400
2401 if (pass == (global.pass ? global.pass - 1 : 0)) {
2402 // The Y4M reader does its own allocation.
2403 if (input.file_type != FILE_TYPE_Y4M) {
2404 aom_img_alloc(&raw, input.fmt, input.width, input.height, 32);
2405 }
2406 FOREACH_STREAM(stream, streams) {
2407 stream->rate_hist =
2408 init_rate_histogram(&stream->config.cfg, &global.framerate);
2409 }
2410 }
2411
2412 FOREACH_STREAM(stream, streams) { setup_pass(stream, &global, pass); }
2413 FOREACH_STREAM(stream, streams) { initialize_encoder(stream, &global); }
2414 FOREACH_STREAM(stream, streams) {
2415 char *encoder_settings = NULL;
2416#if CONFIG_WEBM_IO
2417 // Test frameworks may compare outputs from different versions, but only
2418 // wish to check for bitstream changes. The encoder-settings tag, however,
2419 // can vary if the version is updated, even if no encoder algorithm
2420 // changes were made. To work around this issue, do not output
2421 // the encoder-settings tag when --debug is enabled (which is the flag
2422 // that test frameworks should use, when they want deterministic output
2423 // from the container format).
2424 if (stream->config.write_webm && !stream->webm_ctx.debug) {
2425 encoder_settings = extract_encoder_settings(
2426 aom_codec_version_str(), argv_, argc, input.filename);
2427 if (encoder_settings == NULL) {
2428 fprintf(
2429 stderr,
2430 "Warning: unable to extract encoder settings. Continuing...\n");
2431 }
2432 }
2433#endif
2434 open_output_file(stream, &global, &input.pixel_aspect_ratio,
2435 encoder_settings);
2436 free(encoder_settings);
2437 }
2438
2439 if (strcmp(get_short_name_by_aom_encoder(global.codec), "av1") == 0) {
2440 // Check to see if at least one stream uses 16 bit internal.
2441 // Currently assume that the bit_depths for all streams using
2442 // highbitdepth are the same.
2443 FOREACH_STREAM(stream, streams) {
2444 if (stream->config.use_16bit_internal) {
2445 do_16bit_internal = 1;
2446 }
2447 input_shift = (int)stream->config.cfg.g_bit_depth -
2448 stream->config.cfg.g_input_bit_depth;
2449 }
2450 }
2451
2452 frame_avail = 1;
2453 got_data = 0;
2454
2455 while (frame_avail || got_data) {
2456 struct aom_usec_timer timer;
2457
2458 if (!global.limit || frames_in < global.limit) {
2459 frame_avail = read_frame(&input, &raw);
2460
2461 if (frame_avail) frames_in++;
2462 seen_frames =
2463 frames_in > global.skip_frames ? frames_in - global.skip_frames : 0;
2464
2465 if (!global.quiet) {
2466 float fps = usec_to_fps(cx_time, seen_frames);
2467 fprintf(stderr, "\rPass %d/%d ", pass + 1, global.passes);
2468
2469 if (stream_cnt == 1)
2470 fprintf(stderr, "frame %4d/%-4d %7" PRId64 "B ", frames_in,
2471 streams->frames_out, (int64_t)streams->nbytes);
2472 else
2473 fprintf(stderr, "frame %4d ", frames_in);
2474
2475 fprintf(stderr, "%7" PRId64 " %s %.2f %s ",
2476 cx_time > 9999999 ? cx_time / 1000 : cx_time,
2477 cx_time > 9999999 ? "ms" : "us", fps >= 1.0 ? fps : fps * 60,
2478 fps >= 1.0 ? "fps" : "fpm");
2479 print_time("ETA", estimated_time_left);
2480 // mingw-w64 gcc does not match msvc for stderr buffering behavior
2481 // and uses line buffering, thus the progress output is not
2482 // real-time. The fflush() is here to make sure the progress output
2483 // is sent out while the clip is being processed.
2484 fflush(stderr);
2485 }
2486
2487 } else {
2488 frame_avail = 0;
2489 }
2490
2491 if (frames_in > global.skip_frames) {
2492 aom_image_t *frame_to_encode;
2493 if (input_shift || (do_16bit_internal && input.bit_depth == 8)) {
2494 assert(do_16bit_internal);
2495 // Input bit depth and stream bit depth do not match, so up
2496 // shift frame to stream bit depth
2497 if (!allocated_raw_shift) {
2498 aom_img_alloc(&raw_shift, raw.fmt | AOM_IMG_FMT_HIGHBITDEPTH,
2499 input.width, input.height, 32);
2500 allocated_raw_shift = 1;
2501 }
2502 aom_img_upshift(&raw_shift, &raw, input_shift);
2503 frame_to_encode = &raw_shift;
2504 } else {
2505 frame_to_encode = &raw;
2506 }
2507 aom_usec_timer_start(&timer);
2508 if (do_16bit_internal) {
2509 assert(frame_to_encode->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
2510 FOREACH_STREAM(stream, streams) {
2511 if (stream->config.use_16bit_internal)
2512 encode_frame(stream, &global,
2513 frame_avail ? frame_to_encode : NULL, frames_in);
2514 else
2515 assert(0);
2516 }
2517 } else {
2518 assert((frame_to_encode->fmt & AOM_IMG_FMT_HIGHBITDEPTH) == 0);
2519 FOREACH_STREAM(stream, streams) {
2520 encode_frame(stream, &global, frame_avail ? frame_to_encode : NULL,
2521 frames_in);
2522 }
2523 }
2524 aom_usec_timer_mark(&timer);
2525 cx_time += aom_usec_timer_elapsed(&timer);
2526
2527 FOREACH_STREAM(stream, streams) { update_quantizer_histogram(stream); }
2528
2529 got_data = 0;
2530 FOREACH_STREAM(stream, streams) {
2531 get_cx_data(stream, &global, &got_data);
2532 }
2533
2534 if (!got_data && input.length && streams != NULL &&
2535 !streams->frames_out) {
2536 lagged_count = global.limit ? seen_frames : ftello(input.file);
2537 } else if (input.length) {
2538 int64_t remaining;
2539 int64_t rate;
2540
2541 if (global.limit) {
2542 const int64_t frame_in_lagged = (seen_frames - lagged_count) * 1000;
2543
2544 rate = cx_time ? frame_in_lagged * (int64_t)1000000 / cx_time : 0;
2545 remaining = 1000 * (global.limit - global.skip_frames -
2546 seen_frames + lagged_count);
2547 } else {
2548 const int64_t input_pos = ftello(input.file);
2549 const int64_t input_pos_lagged = input_pos - lagged_count;
2550 const int64_t input_limit = input.length;
2551
2552 rate = cx_time ? input_pos_lagged * (int64_t)1000000 / cx_time : 0;
2553 remaining = input_limit - input_pos + lagged_count;
2554 }
2555
2556 average_rate =
2557 (average_rate <= 0) ? rate : (average_rate * 7 + rate) / 8;
2558 estimated_time_left = average_rate ? remaining / average_rate : -1;
2559 }
2560
2561 if (got_data && global.test_decode != TEST_DECODE_OFF) {
2562 FOREACH_STREAM(stream, streams) {
2563 test_decode(stream, global.test_decode);
2564 }
2565 }
2566 }
2567
2568 fflush(stdout);
2569 if (!global.quiet) fprintf(stderr, "\033[K");
2570 }
2571
2572 if (stream_cnt > 1) fprintf(stderr, "\n");
2573
2574 if (!global.quiet) {
2575 FOREACH_STREAM(stream, streams) {
2576 const int64_t bpf =
2577 seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0;
2578 const int64_t bps = bpf * global.framerate.num / global.framerate.den;
2579 fprintf(stderr,
2580 "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64
2581 "b/f %7" PRId64
2582 "b/s"
2583 " %7" PRId64 " %s (%.2f fps)\033[K\n",
2584 pass + 1, global.passes, frames_in, stream->frames_out,
2585 (int64_t)stream->nbytes, bpf, bps,
2586 stream->cx_time > 9999999 ? stream->cx_time / 1000
2587 : stream->cx_time,
2588 stream->cx_time > 9999999 ? "ms" : "us",
2589 usec_to_fps(stream->cx_time, seen_frames));
2590 // This instance of cr does not need fflush as it is followed by a
2591 // newline in the same string.
2592 }
2593 }
2594
2595 if (global.show_psnr >= 1) {
2596 if (get_fourcc_by_aom_encoder(global.codec) == AV1_FOURCC) {
2597 FOREACH_STREAM(stream, streams) {
2598 int64_t bps = 0;
2599 if (global.show_psnr == 1) {
2600 if (stream->psnr_count[0] && seen_frames && global.framerate.den) {
2601 bps = (int64_t)stream->nbytes * 8 *
2602 (int64_t)global.framerate.num / global.framerate.den /
2603 seen_frames;
2604 }
2605 show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1,
2606 bps);
2607 }
2608 if (global.show_psnr == 2) {
2609#if CONFIG_AV1_HIGHBITDEPTH
2610 if (stream->config.cfg.g_input_bit_depth <
2611 (unsigned int)stream->config.cfg.g_bit_depth)
2612 show_psnr_hbd(stream, (1 << stream->config.cfg.g_bit_depth) - 1,
2613 bps);
2614#endif
2615 }
2616 }
2617 } else {
2618 FOREACH_STREAM(stream, streams) { show_psnr(stream, 255.0, 0); }
2619 }
2620 }
2621
2622 if (pass == global.passes - 1) {
2623 FOREACH_STREAM(stream, streams) {
2624 int num_operating_points;
2625 int levels[32];
2626 int target_levels[32];
2627 aom_codec_control(&stream->encoder, AV1E_GET_NUM_OPERATING_POINTS,
2628 &num_operating_points);
2629 aom_codec_control(&stream->encoder, AV1E_GET_SEQ_LEVEL_IDX, levels);
2630 aom_codec_control(&stream->encoder, AV1E_GET_TARGET_SEQ_LEVEL_IDX,
2631 target_levels);
2632
2633 for (int i = 0; i < num_operating_points; i++) {
2634 if (levels[i] > target_levels[i]) {
2635 if (levels[i] == 31) {
2636 aom_tools_warn(
2637 "Failed to encode to target level %d.%d for operating point "
2638 "%d. The output level is SEQ_LEVEL_MAX",
2639 2 + (target_levels[i] >> 2), target_levels[i] & 3, i);
2640 } else {
2641 aom_tools_warn(
2642 "Failed to encode to target level %d.%d for operating point "
2643 "%d. The output level is %d.%d",
2644 2 + (target_levels[i] >> 2), target_levels[i] & 3, i,
2645 2 + (levels[i] >> 2), levels[i] & 3);
2646 }
2647 }
2648 }
2649 }
2650 }
2651
2652 FOREACH_STREAM(stream, streams) { aom_codec_destroy(&stream->encoder); }
2653
2654 if (global.test_decode != TEST_DECODE_OFF) {
2655 FOREACH_STREAM(stream, streams) { aom_codec_destroy(&stream->decoder); }
2656 }
2657
2658 close_input_file(&input);
2659
2660 if (global.test_decode == TEST_DECODE_FATAL) {
2661 FOREACH_STREAM(stream, streams) { res |= stream->mismatch_seen; }
2662 }
2663 FOREACH_STREAM(stream, streams) {
2664 close_output_file(stream, get_fourcc_by_aom_encoder(global.codec));
2665 }
2666
2667 FOREACH_STREAM(stream, streams) {
2668 stats_close(&stream->stats, global.passes - 1);
2669 }
2670
2671 if (global.pass) break;
2672 }
2673
2674 if (global.show_q_hist_buckets) {
2675 FOREACH_STREAM(stream, streams) {
2676 show_q_histogram(stream->counts, global.show_q_hist_buckets);
2677 }
2678 }
2679
2680 if (global.show_rate_hist_buckets) {
2681 FOREACH_STREAM(stream, streams) {
2682 show_rate_histogram(stream->rate_hist, &stream->config.cfg,
2683 global.show_rate_hist_buckets);
2684 }
2685 }
2686 FOREACH_STREAM(stream, streams) { destroy_rate_histogram(stream->rate_hist); }
2687
2688#if CONFIG_INTERNAL_STATS
2689 /* TODO(jkoleszar): This doesn't belong in this executable. Do it for now,
2690 * to match some existing utilities.
2691 */
2692 if (!(global.pass == 1 && global.passes == 2)) {
2693 FOREACH_STREAM(stream, streams) {
2694 FILE *f = fopen("opsnr.stt", "a");
2695 if (stream->mismatch_seen) {
2696 fprintf(f, "First mismatch occurred in frame %d\n",
2697 stream->mismatch_seen);
2698 } else {
2699 fprintf(f, "No mismatch detected in recon buffers\n");
2700 }
2701 fclose(f);
2702 }
2703 }
2704#endif
2705
2706 if (allocated_raw_shift) aom_img_free(&raw_shift);
2707 aom_img_free(&raw);
2708 free(argv);
2709 free(streams);
2710 return res ? EXIT_FAILURE : EXIT_SUCCESS;
2711}
aom_decoder.h
Describes the decoder algorithm interface to applications.
aom_encoder.h
Describes the encoder algorithm interface to applications.
MAX_TILE_WIDTHS
#define MAX_TILE_WIDTHS
Maximum number of tile widths in tile widths array.
Definition aom_encoder.h:868
MAX_TILE_HEIGHTS
#define MAX_TILE_HEIGHTS
Maximum number of tile heights in tile heights array.
Definition aom_encoder.h:881
AOM_PLANE_U
#define AOM_PLANE_U
Definition aom_image.h:211
AOM_CSP_UNKNOWN
@ AOM_CSP_UNKNOWN
Definition aom_image.h:143
aom_chroma_sample_position_t
enum aom_chroma_sample_position aom_chroma_sample_position_t
List of chroma sample positions.
AOM_PLANE_Y
#define AOM_PLANE_Y
Definition aom_image.h:210
AOM_PLANE_V
#define AOM_PLANE_V
Definition aom_image.h:212
aom_color_range_t
enum aom_color_range aom_color_range_t
List of supported color range.
AOM_IMG_FMT_HIGHBITDEPTH
#define AOM_IMG_FMT_HIGHBITDEPTH
Definition aom_image.h:38
aom_img_alloc
aom_image_t * aom_img_alloc(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
AOM_IMG_FMT_I42216
@ AOM_IMG_FMT_I42216
Definition aom_image.h:58
AOM_IMG_FMT_I42016
@ AOM_IMG_FMT_I42016
Definition aom_image.h:56
AOM_IMG_FMT_I444
@ AOM_IMG_FMT_I444
Definition aom_image.h:50
AOM_IMG_FMT_I422
@ AOM_IMG_FMT_I422
Definition aom_image.h:49
AOM_IMG_FMT_I44416
@ AOM_IMG_FMT_I44416
Definition aom_image.h:59
AOM_IMG_FMT_I420
@ AOM_IMG_FMT_I420
Definition aom_image.h:45
AOM_IMG_FMT_NV12
@ AOM_IMG_FMT_NV12
Definition aom_image.h:54
AOM_IMG_FMT_YV12
@ AOM_IMG_FMT_YV12
Definition aom_image.h:43
aom_image_t
struct aom_image aom_image_t
Image Descriptor.
aom_img_free
void aom_img_free(aom_image_t *img)
Close an image descriptor.
aomcx.h
Provides definitions for using AOM or AV1 encoder algorithm within the aom Codec Interface.
aomdx.h
Provides definitions for using AOM or AV1 within the aom Decoder interface.
AV1_SET_TILE_MODE
@ AV1_SET_TILE_MODE
Codec control function to set the tile coding mode, unsigned int parameter.
Definition aomdx.h:316
AV1D_SET_IS_ANNEXB
@ AV1D_SET_IS_ANNEXB
Codec control function to indicate whether bitstream is in Annex-B format, unsigned int parameter.
Definition aomdx.h:352
AV1_SET_DECODE_TILE_ROW
@ AV1_SET_DECODE_TILE_ROW
Codec control function to set the range of tile decoding, int parameter.
Definition aomdx.h:307
AV1E_SET_MATRIX_COEFFICIENTS
@ AV1E_SET_MATRIX_COEFFICIENTS
Codec control function to set transfer function info, int parameter.
Definition aomcx.h:583
AV1E_SET_ENABLE_INTERINTER_WEDGE
@ AV1E_SET_ENABLE_INTERINTER_WEDGE
Codec control function to turn on / off interinter wedge compound, int parameter.
Definition aomcx.h:1021
AV1E_SET_ENABLE_DIAGONAL_INTRA
@ AV1E_SET_ENABLE_DIAGONAL_INTRA
Codec control function to turn on / off D45 to D203 intra mode usage, int parameter.
Definition aomcx.h:1364
AV1E_SET_MAX_GF_INTERVAL
@ AV1E_SET_MAX_GF_INTERVAL
Codec control function to set minimum interval between GF/ARF frames, unsigned int parameter.
Definition aomcx.h:604
AV1E_SET_ROW_MT
@ AV1E_SET_ROW_MT
Codec control function to enable the row based multi-threading of the encoder, unsigned int parameter...
Definition aomcx.h:371
AV1E_SET_ENABLE_SMOOTH_INTRA
@ AV1E_SET_ENABLE_SMOOTH_INTRA
Codec control function to turn on / off smooth intra modes usage, int parameter.
Definition aomcx.h:1081
AV1E_GET_TARGET_SEQ_LEVEL_IDX
@ AV1E_GET_TARGET_SEQ_LEVEL_IDX
Codec control function to get the target sequence level index for each operating point....
Definition aomcx.h:1472
AV1E_SET_RATE_DISTRIBUTION_INFO
@ AV1E_SET_RATE_DISTRIBUTION_INFO
Codec control to set the input file for rate distribution used in all intra mode, const char * parame...
Definition aomcx.h:1531
AV1E_SET_ENABLE_TPL_MODEL
@ AV1E_SET_ENABLE_TPL_MODEL
Codec control function to enable RDO modulated by frame temporal dependency, unsigned int parameter.
Definition aomcx.h:418
AOME_GET_LAST_QUANTIZER_64
@ AOME_GET_LAST_QUANTIZER_64
Codec control function to get last quantizer chosen by the encoder, int* parameter.
Definition aomcx.h:269
AV1E_SET_AQ_MODE
@ AV1E_SET_AQ_MODE
Codec control function to set adaptive quantization mode, unsigned int parameter.
Definition aomcx.h:478
AV1E_SET_REDUCED_REFERENCE_SET
@ AV1E_SET_REDUCED_REFERENCE_SET
Control to use reduced set of single and compound references, int parameter.
Definition aomcx.h:1241
AV1E_GET_NUM_OPERATING_POINTS
@ AV1E_GET_NUM_OPERATING_POINTS
Codec control function to get the number of operating points. int* parameter.
Definition aomcx.h:1477
AV1E_SET_GF_MIN_PYRAMID_HEIGHT
@ AV1E_SET_GF_MIN_PYRAMID_HEIGHT
Control to select minimum height for the GF group pyramid structure, unsigned int parameter.
Definition aomcx.h:1336
AV1E_SET_ENABLE_PAETH_INTRA
@ AV1E_SET_ENABLE_PAETH_INTRA
Codec control function to turn on / off Paeth intra mode usage, int parameter.
Definition aomcx.h:1089
AV1E_SET_TUNE_CONTENT
@ AV1E_SET_TUNE_CONTENT
Codec control function to set content type, aom_tune_content parameter.
Definition aomcx.h:507
AV1E_SET_CDF_UPDATE_MODE
@ AV1E_SET_CDF_UPDATE_MODE
Codec control function to set CDF update mode, unsigned int parameter.
Definition aomcx.h:516
AV1E_SET_CHROMA_SUBSAMPLING_X
@ AV1E_SET_CHROMA_SUBSAMPLING_X
Sets the chroma subsampling x value, unsigned int parameter.
Definition aomcx.h:1204
AV1E_SET_COLOR_RANGE
@ AV1E_SET_COLOR_RANGE
Codec control function to set color range bit, int parameter.
Definition aomcx.h:616
AV1E_SET_ENABLE_RESTORATION
@ AV1E_SET_ENABLE_RESTORATION
Codec control function to encode with Loop Restoration Filter, unsigned int parameter.
Definition aomcx.h:691
AV1E_SET_ENABLE_ANGLE_DELTA
@ AV1E_SET_ENABLE_ANGLE_DELTA
Codec control function to turn on/off intra angle delta, int parameter.
Definition aomcx.h:1128
AV1E_SET_MIN_GF_INTERVAL
@ AV1E_SET_MIN_GF_INTERVAL
Codec control function to set minimum interval between GF/ARF frames, unsigned int parameter.
Definition aomcx.h:597
AOME_SET_ARNR_MAXFRAMES
@ AOME_SET_ARNR_MAXFRAMES
Codec control function to set the max no of frames to create arf, unsigned int parameter.
Definition aomcx.h:274
AV1E_SET_MV_COST_UPD_FREQ
@ AV1E_SET_MV_COST_UPD_FREQ
Control to set frequency of the cost updates for motion vectors, unsigned int parameter.
Definition aomcx.h:1271
AV1E_SET_INTRA_DEFAULT_TX_ONLY
@ AV1E_SET_INTRA_DEFAULT_TX_ONLY
Control to use default tx type only for intra modes, int parameter.
Definition aomcx.h:1220
AV1E_SET_TRANSFER_CHARACTERISTICS
@ AV1E_SET_TRANSFER_CHARACTERISTICS
Codec control function to set transfer function info, int parameter.
Definition aomcx.h:562
AV1E_SET_MTU
@ AV1E_SET_MTU
Codec control function to set an MTU size for a tile group, unsigned int parameter.
Definition aomcx.h:811
AV1E_SET_DISABLE_TRELLIS_QUANT
@ AV1E_SET_DISABLE_TRELLIS_QUANT
Codec control function to encode without trellis quantization, unsigned int parameter.
Definition aomcx.h:718
AV1E_SET_ENABLE_INTRABC
@ AV1E_SET_ENABLE_INTRABC
Codec control function to turn on/off intra block copy mode, int parameter.
Definition aomcx.h:1124
AV1E_SET_ENABLE_AB_PARTITIONS
@ AV1E_SET_ENABLE_AB_PARTITIONS
Codec control function to enable/disable AB partitions, int parameter.
Definition aomcx.h:829
AV1E_SET_ENABLE_INTERINTRA_COMP
@ AV1E_SET_ENABLE_INTERINTRA_COMP
Codec control function to turn on / off interintra compound for a sequence, int parameter.
Definition aomcx.h:997
AV1E_SET_FILM_GRAIN_TEST_VECTOR
@ AV1E_SET_FILM_GRAIN_TEST_VECTOR
Codec control function to add film grain parameters (one of several preset types) info in the bitstre...
Definition aomcx.h:1190
AV1E_SET_ENABLE_CHROMA_DELTAQ
@ AV1E_SET_ENABLE_CHROMA_DELTAQ
Codec control function to turn on / off delta quantization in chroma planes for a sequence,...
Definition aomcx.h:973
AV1E_SET_ENABLE_DUAL_FILTER
@ AV1E_SET_ENABLE_DUAL_FILTER
Codec control function to turn on / off dual interpolation filter for a sequence, int parameter.
Definition aomcx.h:965
AV1E_SET_FRAME_PARALLEL_DECODING
@ AV1E_SET_FRAME_PARALLEL_DECODING
Codec control function to enable frame parallel decoding feature, unsigned int parameter.
Definition aomcx.h:441
AV1E_SET_MIN_PARTITION_SIZE
@ AV1E_SET_MIN_PARTITION_SIZE
Codec control function to set min partition size, int parameter.
Definition aomcx.h:848
AV1E_SET_ENABLE_WARPED_MOTION
@ AV1E_SET_ENABLE_WARPED_MOTION
Codec control function to turn on / off warped motion usage at sequence level, int parameter.
Definition aomcx.h:1049
AV1E_SET_FORCE_VIDEO_MODE
@ AV1E_SET_FORCE_VIDEO_MODE
Codec control function to force video mode, unsigned int parameter.
Definition aomcx.h:698
AV1E_SET_CHROMA_SUBSAMPLING_Y
@ AV1E_SET_CHROMA_SUBSAMPLING_Y
Sets the chroma subsampling y value, unsigned int parameter.
Definition aomcx.h:1207
AV1E_SET_ENABLE_INTRA_EDGE_FILTER
@ AV1E_SET_ENABLE_INTRA_EDGE_FILTER
Codec control function to turn on / off intra edge filter at sequence level, int parameter.
Definition aomcx.h:867
AV1E_SET_COEFF_COST_UPD_FREQ
@ AV1E_SET_COEFF_COST_UPD_FREQ
Control to set frequency of the cost updates for coefficients, unsigned int parameter.
Definition aomcx.h:1251
AV1E_SET_ENABLE_DIRECTIONAL_INTRA
@ AV1E_SET_ENABLE_DIRECTIONAL_INTRA
Codec control function to turn on / off directional intra mode usage, int parameter.
Definition aomcx.h:1393
AV1E_SET_MAX_INTER_BITRATE_PCT
@ AV1E_SET_MAX_INTER_BITRATE_PCT
Codec control function to set max data rate for inter frames, unsigned int parameter.
Definition aomcx.h:335
AV1E_SET_DENOISE_NOISE_LEVEL
@ AV1E_SET_DENOISE_NOISE_LEVEL
Sets the noise level, int parameter.
Definition aomcx.h:1198
AV1E_SET_INTRA_DCT_ONLY
@ AV1E_SET_INTRA_DCT_ONLY
Control to use dct only for intra modes, int parameter.
Definition aomcx.h:1213
AV1E_SET_TILE_ROWS
@ AV1E_SET_TILE_ROWS
Codec control function to set number of tile rows, unsigned int parameter.
Definition aomcx.h:408
AV1E_SET_ENABLE_REF_FRAME_MVS
@ AV1E_SET_ENABLE_REF_FRAME_MVS
Codec control function to turn on / off ref frame mvs (mfmv) usage at sequence level,...
Definition aomcx.h:946
AV1E_SET_FP_MT
@ AV1E_SET_FP_MT
Codec control function to enable frame parallel multi-threading of the encoder, unsigned int paramete...
Definition aomcx.h:1452
AV1E_SET_ENABLE_MASKED_COMP
@ AV1E_SET_ENABLE_MASKED_COMP
Codec control function to turn on / off masked compound usage (wedge and diff-wtd compound modes) for...
Definition aomcx.h:981
AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP
@ AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP
Control to set average complexity of the corpus in the case of single pass vbr based on LAP,...
Definition aomcx.h:1341
AV1E_SET_GF_MAX_PYRAMID_HEIGHT
@ AV1E_SET_GF_MAX_PYRAMID_HEIGHT
Control to select maximum height for the GF group pyramid structure, unsigned int parameter.
Definition aomcx.h:1230
AV1E_SET_ENABLE_CDEF
@ AV1E_SET_ENABLE_CDEF
Codec control function to encode with CDEF, unsigned int parameter.
Definition aomcx.h:681
AV1E_SET_ENABLE_FLIP_IDTX
@ AV1E_SET_ENABLE_FLIP_IDTX
Codec control function to turn on / off flip and identity transforms, int parameter.
Definition aomcx.h:911
AV1E_GET_SEQ_LEVEL_IDX
@ AV1E_GET_SEQ_LEVEL_IDX
Codec control function to get sequence level index for each operating point. int* parameter....
Definition aomcx.h:653
AV1E_SET_FRAME_PERIODIC_BOOST
@ AV1E_SET_FRAME_PERIODIC_BOOST
Codec control function to enable/disable periodic Q boost, unsigned int parameter.
Definition aomcx.h:490
AV1E_SET_DV_COST_UPD_FREQ
@ AV1E_SET_DV_COST_UPD_FREQ
Control to set frequency of the cost updates for intrabc motion vectors, unsigned int parameter.
Definition aomcx.h:1374
AV1E_SET_AUTO_INTRA_TOOLS_OFF
@ AV1E_SET_AUTO_INTRA_TOOLS_OFF
Codec control to automatically turn off several intra coding tools, unsigned int parameter.
Definition aomcx.h:1436
AV1E_SET_ENABLE_RECT_TX
@ AV1E_SET_ENABLE_RECT_TX
Codec control function to turn on / off rectangular transforms, int parameter.
Definition aomcx.h:923
AV1E_SET_ENABLE_DIST_WTD_COMP
@ AV1E_SET_ENABLE_DIST_WTD_COMP
Codec control function to turn on / off dist-wtd compound mode at sequence level, int parameter.
Definition aomcx.h:935
AV1E_SET_TIMING_INFO_TYPE
@ AV1E_SET_TIMING_INFO_TYPE
Codec control function to signal picture timing info in the bitstream, aom_timing_info_type_t paramet...
Definition aomcx.h:1183
AV1E_SET_SUPERBLOCK_SIZE
@ AV1E_SET_SUPERBLOCK_SIZE
Codec control function to set intended superblock size, unsigned int parameter.
Definition aomcx.h:661
AV1E_SET_TIER_MASK
@ AV1E_SET_TIER_MASK
Control to set bit mask that specifies which tier each of the 32 possible operating points conforms t...
Definition aomcx.h:1279
AV1E_SET_ENABLE_INTERINTRA_WEDGE
@ AV1E_SET_ENABLE_INTERINTRA_WEDGE
Codec control function to turn on / off interintra wedge compound, int parameter.
Definition aomcx.h:1029
AV1E_SET_NOISE_SENSITIVITY
@ AV1E_SET_NOISE_SENSITIVITY
Codec control function to set noise sensitivity, unsigned int parameter.
Definition aomcx.h:498
AV1E_SET_ENABLE_DIFF_WTD_COMP
@ AV1E_SET_ENABLE_DIFF_WTD_COMP
Codec control function to turn on / off difference weighted compound, int parameter.
Definition aomcx.h:1013
AV1E_SET_QUANT_B_ADAPT
@ AV1E_SET_QUANT_B_ADAPT
Control to use adaptive quantize_b, int parameter.
Definition aomcx.h:1223
AV1E_SET_ENABLE_FILTER_INTRA
@ AV1E_SET_ENABLE_FILTER_INTRA
Codec control function to turn on / off filter intra usage at sequence level, int parameter.
Definition aomcx.h:1070
AV1E_SET_ENABLE_PALETTE
@ AV1E_SET_ENABLE_PALETTE
Codec control function to turn on/off palette mode, int parameter.
Definition aomcx.h:1120
AV1E_SET_ENABLE_CFL_INTRA
@ AV1E_SET_ENABLE_CFL_INTRA
Codec control function to turn on / off CFL uv intra mode usage, int parameter.
Definition aomcx.h:1099
AV1E_SET_ENABLE_KEYFRAME_FILTERING
@ AV1E_SET_ENABLE_KEYFRAME_FILTERING
Codec control function to enable temporal filtering on key frame, unsigned int parameter.
Definition aomcx.h:427
AV1E_SET_NUM_TG
@ AV1E_SET_NUM_TG
Codec control function to set a maximum number of tile groups, unsigned int parameter.
Definition aomcx.h:800
AOME_SET_MAX_INTRA_BITRATE_PCT
@ AOME_SET_MAX_INTRA_BITRATE_PCT
Codec control function to set max data rate for intra frames, unsigned int parameter.
Definition aomcx.h:312
AV1E_SET_ERROR_RESILIENT_MODE
@ AV1E_SET_ERROR_RESILIENT_MODE
Codec control function to enable error_resilient_mode, int parameter.
Definition aomcx.h:452
AV1E_SET_ENABLE_SMOOTH_INTERINTRA
@ AV1E_SET_ENABLE_SMOOTH_INTERINTRA
Codec control function to turn on / off smooth inter-intra mode for a sequence, int parameter.
Definition aomcx.h:1005
AOME_SET_STATIC_THRESHOLD
@ AOME_SET_STATIC_THRESHOLD
Codec control function to set the threshold for MBs treated static, unsigned int parameter.
Definition aomcx.h:252
AV1E_SET_ENABLE_OBMC
@ AV1E_SET_ENABLE_OBMC
Codec control function to predict with OBMC mode, unsigned int parameter.
Definition aomcx.h:708
AV1E_SET_PARTITION_INFO_PATH
@ AV1E_SET_PARTITION_INFO_PATH
Codec control to set the path for partition stats read and write. const char * parameter.
Definition aomcx.h:1379
AV1E_SET_ENABLE_LOW_COMPLEXITY_DECODE
@ AV1E_SET_ENABLE_LOW_COMPLEXITY_DECODE
Codec control to enable the low complexity decode mode, unsigned int parameter. Value of zero means t...
Definition aomcx.h:1593
AV1E_SET_MAX_PARTITION_SIZE
@ AV1E_SET_MAX_PARTITION_SIZE
Codec control function to set max partition size, int parameter.
Definition aomcx.h:859
AV1E_SET_ENABLE_1TO4_PARTITIONS
@ AV1E_SET_ENABLE_1TO4_PARTITIONS
Codec control function to enable/disable 1:4 and 4:1 partitions, int parameter.
Definition aomcx.h:837
AV1E_SET_DELTALF_MODE
@ AV1E_SET_DELTALF_MODE
Codec control function to turn on/off loopfilter modulation when delta q modulation is enabled,...
Definition aomcx.h:1156
AV1E_SET_ENABLE_TX64
@ AV1E_SET_ENABLE_TX64
Codec control function to turn on / off 64-length transforms, int parameter.
Definition aomcx.h:887
AOME_SET_TUNING
@ AOME_SET_TUNING
Codec control function to set visual tuning, aom_tune_metric (int) parameter.
Definition aomcx.h:288
AV1E_SET_TARGET_SEQ_LEVEL_IDX
@ AV1E_SET_TARGET_SEQ_LEVEL_IDX
Control to set target sequence level index for a certain operating point (OP), int parameter Possible...
Definition aomcx.h:646
AV1E_SET_CHROMA_SAMPLE_POSITION
@ AV1E_SET_CHROMA_SAMPLE_POSITION
Codec control function to set chroma 4:2:0 sample position info, aom_chroma_sample_position_t paramet...
Definition aomcx.h:590
AV1E_SET_REDUCED_TX_TYPE_SET
@ AV1E_SET_REDUCED_TX_TYPE_SET
Control to use a reduced tx type set, int parameter.
Definition aomcx.h:1210
AV1E_SET_DELTAQ_STRENGTH
@ AV1E_SET_DELTAQ_STRENGTH
Set –deltaq-mode strength, where the value is a percentage, unsigned int parameter.
Definition aomcx.h:1415
AV1E_SET_INTER_DCT_ONLY
@ AV1E_SET_INTER_DCT_ONLY
Control to use dct only for inter modes, int parameter.
Definition aomcx.h:1216
AV1E_SET_LOOPFILTER_CONTROL
@ AV1E_SET_LOOPFILTER_CONTROL
Codec control to control loop filter.
Definition aomcx.h:1424
AOME_SET_ENABLEAUTOALTREF
@ AOME_SET_ENABLEAUTOALTREF
Codec control function to enable automatic set and use alf frames, unsigned int parameter.
Definition aomcx.h:228
AV1E_ENABLE_RATE_GUIDE_DELTAQ
@ AV1E_ENABLE_RATE_GUIDE_DELTAQ
Codec control to enable the rate distribution guided delta quantization in all intra mode,...
Definition aomcx.h:1519
AV1E_SET_TILE_COLUMNS
@ AV1E_SET_TILE_COLUMNS
Codec control function to set number of tile columns. unsigned int parameter.
Definition aomcx.h:390
AV1E_SET_ENABLE_ORDER_HINT
@ AV1E_SET_ENABLE_ORDER_HINT
Codec control function to turn on / off frame order hint (int parameter). Affects: joint compound mod...
Definition aomcx.h:876
AV1E_SET_DELTAQ_MODE
@ AV1E_SET_DELTAQ_MODE
Codec control function to set the delta q mode, unsigned int parameter.
Definition aomcx.h:1148
AV1E_SET_ENABLE_GLOBAL_MOTION
@ AV1E_SET_ENABLE_GLOBAL_MOTION
Codec control function to turn on / off global motion usage for a sequence, int parameter.
Definition aomcx.h:1039
AV1E_SET_FILM_GRAIN_TABLE
@ AV1E_SET_FILM_GRAIN_TABLE
Codec control function to set the path to the film grain parameters, const char* parameter.
Definition aomcx.h:1195
AV1E_SET_QM_MAX
@ AV1E_SET_QM_MAX
Codec control function to set the max quant matrix flatness, unsigned int parameter.
Definition aomcx.h:754
AV1E_SET_MAX_REFERENCE_FRAMES
@ AV1E_SET_MAX_REFERENCE_FRAMES
Control to select maximum reference frames allowed per frame, int parameter.
Definition aomcx.h:1237
AOME_SET_CPUUSED
@ AOME_SET_CPUUSED
Codec control function to set encoder internal speed settings, int parameter.
Definition aomcx.h:220
AV1E_SET_GF_CBR_BOOST_PCT
@ AV1E_SET_GF_CBR_BOOST_PCT
Boost percentage for Golden Frame in CBR mode, unsigned int parameter.
Definition aomcx.h:349
AV1E_SET_ENABLE_ONESIDED_COMP
@ AV1E_SET_ENABLE_ONESIDED_COMP
Codec control function to turn on / off one sided compound usage for a sequence, int parameter.
Definition aomcx.h:989
AV1E_SET_DENOISE_BLOCK_SIZE
@ AV1E_SET_DENOISE_BLOCK_SIZE
Sets the denoisers block size, unsigned int parameter.
Definition aomcx.h:1201
AV1E_SET_VMAF_MODEL_PATH
@ AV1E_SET_VMAF_MODEL_PATH
Codec control function to set the path to the VMAF model used when tuning the encoder for VMAF,...
Definition aomcx.h:1308
AV1E_SET_QM_MIN
@ AV1E_SET_QM_MIN
Codec control function to set the min quant matrix flatness, unsigned int parameter.
Definition aomcx.h:742
AV1E_SET_ENABLE_QM
@ AV1E_SET_ENABLE_QM
Codec control function to encode with quantisation matrices, unsigned int parameter.
Definition aomcx.h:729
AV1E_SET_ENABLE_OVERLAY
@ AV1E_SET_ENABLE_OVERLAY
Codec control function to turn on / off overlay frames for filtered ALTREF frames,...
Definition aomcx.h:1117
AV1E_SET_ENABLE_RECT_PARTITIONS
@ AV1E_SET_ENABLE_RECT_PARTITIONS
Codec control function to enable/disable rectangular partitions, int parameter.
Definition aomcx.h:821
AV1E_SET_COLOR_PRIMARIES
@ AV1E_SET_COLOR_PRIMARIES
Codec control function to set color space info, int parameter.
Definition aomcx.h:537
AOME_SET_CQ_LEVEL
@ AOME_SET_CQ_LEVEL
Codec control function to set constrained / constant quality level, unsigned int parameter.
Definition aomcx.h:298
AV1E_SET_ENABLE_TX_SIZE_SEARCH
@ AV1E_SET_ENABLE_TX_SIZE_SEARCH
Control to turn on / off transform size search. Note: it can not work with non RD pick mode in real-t...
Definition aomcx.h:1403
AV1E_SET_MODE_COST_UPD_FREQ
@ AV1E_SET_MODE_COST_UPD_FREQ
Control to set frequency of the cost updates for mode, unsigned int parameter.
Definition aomcx.h:1261
AV1E_SET_MIN_CR
@ AV1E_SET_MIN_CR
Control to set minimum compression ratio, unsigned int parameter Take integer values....
Definition aomcx.h:1286
AV1E_SET_LOSSLESS
@ AV1E_SET_LOSSLESS
Codec control function to set lossless encoding mode, unsigned int parameter.
Definition aomcx.h:363
AOME_SET_ARNR_STRENGTH
@ AOME_SET_ARNR_STRENGTH
Codec control function to set the filter strength for the arf, unsigned int parameter.
Definition aomcx.h:279
AV1_GET_NEW_FRAME_IMAGE
@ AV1_GET_NEW_FRAME_IMAGE
Codec control function to get a pointer to the new frame.
Definition aom.h:70
aom_codec_iface_name
const char * aom_codec_iface_name(aom_codec_iface_t *iface)
Return the name for a given interface.
aom_codec_control
aom_codec_err_t aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id,...)
Algorithm Control.
aom_codec_ctx_t
struct aom_codec_ctx aom_codec_ctx_t
Codec context structure.
aom_codec_iface_t
const struct aom_codec_iface aom_codec_iface_t
Codec interface structure.
Definition aom_codec.h:271
aom_codec_version_str
const char * aom_codec_version_str(void)
Return the version information (as a string)
aom_codec_set_option
aom_codec_err_t aom_codec_set_option(aom_codec_ctx_t *ctx, const char *name, const char *value)
Key & Value API.
aom_codec_pts_t
int64_t aom_codec_pts_t
Time Stamp Type.
Definition aom_codec.h:252
aom_codec_destroy
aom_codec_err_t aom_codec_destroy(aom_codec_ctx_t *ctx)
Destroy a codec instance.
aom_codec_err_to_string
const char * aom_codec_err_to_string(aom_codec_err_t err)
Convert error number to printable string.
aom_codec_err_t
aom_codec_err_t
Algorithm return codes.
Definition aom_codec.h:155
AOM_CODEC_CONTROL_TYPECHECKED
#define AOM_CODEC_CONTROL_TYPECHECKED(ctx, id, data)
aom_codec_control wrapper macro (adds type-checking, less flexible)
Definition aom_codec.h:542
aom_codec_iter_t
const void * aom_codec_iter_t
Iterator.
Definition aom_codec.h:305
AOM_BITS_8
@ AOM_BITS_8
Definition aom_codec.h:336
aom_codec_decode
aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data, size_t data_sz, void *user_priv)
Decode data.
aom_codec_dec_cfg_t
struct aom_codec_dec_cfg aom_codec_dec_cfg_t
Initialization Configurations.
aom_codec_dec_init
#define aom_codec_dec_init(ctx, iface, cfg, flags)
Convenience macro for aom_codec_dec_init_ver()
Definition aom_decoder.h:129
AOM_USAGE_GOOD_QUALITY
#define AOM_USAGE_GOOD_QUALITY
usage parameter analogous to AV1 GOOD QUALITY mode.
Definition aom_encoder.h:1016
AOM_USAGE_ALL_INTRA
#define AOM_USAGE_ALL_INTRA
usage parameter analogous to AV1 all intra mode.
Definition aom_encoder.h:1020
aom_codec_get_cx_data
const aom_codec_cx_pkt_t * aom_codec_get_cx_data(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter)
Encoded data iterator.
aom_codec_cx_pkt_t
struct aom_codec_cx_pkt aom_codec_cx_pkt_t
Encoder output packet.
aom_codec_encode
aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, aom_codec_pts_t pts, unsigned long duration, aom_enc_frame_flags_t flags)
Encode a frame.
aom_codec_enc_init
#define aom_codec_enc_init(ctx, iface, cfg, flags)
Convenience macro for aom_codec_enc_init_ver()
Definition aom_encoder.h:945
aom_codec_enc_config_default
aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface, aom_codec_enc_cfg_t *cfg, unsigned int usage)
Get the default configuration for a usage.
cfg_options_t
struct cfg_options cfg_options_t
Encoder Config Options.
AOM_USAGE_REALTIME
#define AOM_USAGE_REALTIME
usage parameter analogous to AV1 REALTIME mode.
Definition aom_encoder.h:1018
AOM_CODEC_USE_HIGHBITDEPTH
#define AOM_CODEC_USE_HIGHBITDEPTH
Definition aom_encoder.h:80
AOM_CODEC_USE_PSNR
#define AOM_CODEC_USE_PSNR
Initialization-time Feature Enabling.
Definition aom_encoder.h:79
AOM_RC_ONE_PASS
@ AOM_RC_ONE_PASS
Definition aom_encoder.h:177
AOM_RC_SECOND_PASS
@ AOM_RC_SECOND_PASS
Definition aom_encoder.h:179
AOM_RC_THIRD_PASS
@ AOM_RC_THIRD_PASS
Definition aom_encoder.h:180
AOM_RC_FIRST_PASS
@ AOM_RC_FIRST_PASS
Definition aom_encoder.h:178
AOM_KF_DISABLED
@ AOM_KF_DISABLED
Definition aom_encoder.h:203
AOM_CODEC_PSNR_PKT
@ AOM_CODEC_PSNR_PKT
Definition aom_encoder.h:113
AOM_CODEC_CX_FRAME_PKT
@ AOM_CODEC_CX_FRAME_PKT
Definition aom_encoder.h:110
AOM_CODEC_STATS_PKT
@ AOM_CODEC_STATS_PKT
Definition aom_encoder.h:111
aom_codec_cx_pkt::sz
size_t sz
Definition aom_encoder.h:127
aom_codec_cx_pkt::kind
enum aom_codec_cx_pkt_kind kind
Definition aom_encoder.h:123
aom_codec_cx_pkt::psnr
double psnr[4]
Definition aom_encoder.h:145
aom_codec_cx_pkt::twopass_stats
aom_fixed_buf_t twopass_stats
Definition aom_encoder.h:140
aom_codec_cx_pkt::data
union aom_codec_cx_pkt::@202210014045072156205127107315337341215221351166 data
aom_codec_cx_pkt::raw
aom_fixed_buf_t raw
Definition aom_encoder.h:156
aom_codec_cx_pkt::pts
aom_codec_pts_t pts
time stamp to show frame (in timebase units)
Definition aom_encoder.h:129
aom_codec_cx_pkt::frame
struct aom_codec_cx_pkt::@202210014045072156205127107315337341215221351166::@052232317104146204273007241322037340334334344046 frame
aom_codec_cx_pkt::partition_id
int partition_id
the partition id defines the decoding order of the partitions. Only applicable when "output partition...
Definition aom_encoder.h:136
aom_codec_cx_pkt::buf
void * buf
Definition aom_encoder.h:126
aom_codec_enc_cfg
Encoder configuration structure.
Definition aom_encoder.h:389
aom_codec_enc_cfg::g_timebase
struct aom_rational g_timebase
Stream timebase units.
Definition aom_encoder.h:491
aom_codec_enc_cfg::g_pass
enum aom_enc_pass g_pass
Multi-pass Encoding Mode.
Definition aom_encoder.h:506
aom_fixed_buf::sz
size_t sz
Definition aom_encoder.h:90
aom_fixed_buf::buf
void * buf
Definition aom_encoder.h:89
aom_image
Image Descriptor.
Definition aom_image.h:182
aom_image::csp
aom_chroma_sample_position_t csp
Definition aom_image.h:188
aom_image::y_chroma_shift
unsigned int y_chroma_shift
Definition aom_image.h:206
aom_image::fmt
aom_img_fmt_t fmt
Definition aom_image.h:183
aom_image::stride
int stride[3]
Definition aom_image.h:216
aom_image::img_data
unsigned char * img_data
Definition aom_image.h:230
aom_image::x_chroma_shift
unsigned int x_chroma_shift
Definition aom_image.h:205
aom_image::d_w
unsigned int d_w
Definition aom_image.h:197
aom_image::bps
int bps
Definition aom_image.h:219
aom_image::monochrome
int monochrome
Definition aom_image.h:187
aom_image::d_h
unsigned int d_h
Definition aom_image.h:198
aom_image::planes
unsigned char * planes[3]
Definition aom_image.h:215
aom_image::img_data_owner
int img_data_owner
Definition aom_image.h:231
aom_image::self_allocd
int self_allocd
Definition aom_image.h:232
aom_image::sz
size_t sz
Definition aom_image.h:217
aom_rational
Rational Number.
Definition aom_encoder.h:164
aom_rational::num
int num
Definition aom_encoder.h:165
aom_rational::den
int den
Definition aom_encoder.h:166
cfg_options::min_partition_size
unsigned int min_partition_size
min partition size 8, 16, 32, 64, 128
Definition aom_encoder.h:243
cfg_options::max_partition_size
unsigned int max_partition_size
max partition size 8, 16, 32, 64, 128
Definition aom_encoder.h:239
cfg_options::disable_trellis_quant
unsigned int disable_trellis_quant
disable trellis quantization
Definition aom_encoder.h:355
cfg_options::super_block_size
unsigned int super_block_size
Superblock size 0, 64 or 128.
Definition aom_encoder.h:235