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