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