AOMedia AV1 Codec: aomenc

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