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