AOMedia AV1 Codec: aomenc

| AOMedia AV1 Codec

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