AOMedia AV1 Codec: aomenc

| AOMedia AV1 Codec

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