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