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