AOMedia AV1 Codec: aomenc

| AOMedia AV1 Codec

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