28 #define AOM_DISABLE_CTRL_TYPECHECKS 1
29 #include <aom/aom_encoder.h>
30 #include <aom/aomcx.h>
147 #define OFFSET(x) offsetof(AOMContext, x)
150 [AOME_SET_CPUUSED] =
"AOME_SET_CPUUSED",
151 [AOME_SET_CQ_LEVEL] =
"AOME_SET_CQ_LEVEL",
152 [AOME_SET_ENABLEAUTOALTREF] =
"AOME_SET_ENABLEAUTOALTREF",
153 [AOME_SET_ARNR_MAXFRAMES] =
"AOME_SET_ARNR_MAXFRAMES",
154 [AOME_SET_ARNR_STRENGTH] =
"AOME_SET_ARNR_STRENGTH",
155 [AOME_SET_STATIC_THRESHOLD] =
"AOME_SET_STATIC_THRESHOLD",
156 [AV1E_SET_COLOR_RANGE] =
"AV1E_SET_COLOR_RANGE",
157 [AV1E_SET_COLOR_PRIMARIES] =
"AV1E_SET_COLOR_PRIMARIES",
158 [AV1E_SET_MATRIX_COEFFICIENTS] =
"AV1E_SET_MATRIX_COEFFICIENTS",
159 [AV1E_SET_TRANSFER_CHARACTERISTICS] =
"AV1E_SET_TRANSFER_CHARACTERISTICS",
160 [AV1E_SET_AQ_MODE] =
"AV1E_SET_AQ_MODE",
161 [AV1E_SET_FRAME_PARALLEL_DECODING] =
"AV1E_SET_FRAME_PARALLEL_DECODING",
162 [AV1E_SET_SUPERBLOCK_SIZE] =
"AV1E_SET_SUPERBLOCK_SIZE",
163 [AV1E_SET_TILE_COLUMNS] =
"AV1E_SET_TILE_COLUMNS",
164 [AV1E_SET_TILE_ROWS] =
"AV1E_SET_TILE_ROWS",
165 [AV1E_SET_ENABLE_RESTORATION] =
"AV1E_SET_ENABLE_RESTORATION",
166 [AV1E_SET_ROW_MT] =
"AV1E_SET_ROW_MT",
167 [AV1E_SET_DENOISE_NOISE_LEVEL] =
"AV1E_SET_DENOISE_NOISE_LEVEL",
168 [AV1E_SET_DENOISE_BLOCK_SIZE] =
"AV1E_SET_DENOISE_BLOCK_SIZE",
169 [AV1E_SET_MAX_REFERENCE_FRAMES] =
"AV1E_SET_MAX_REFERENCE_FRAMES",
170 [AV1E_SET_ENABLE_GLOBAL_MOTION] =
"AV1E_SET_ENABLE_GLOBAL_MOTION",
171 [AV1E_SET_ENABLE_INTRABC] =
"AV1E_SET_ENABLE_INTRABC",
172 [AV1E_SET_ENABLE_CDEF] =
"AV1E_SET_ENABLE_CDEF",
173 [AOME_SET_TUNING] =
"AOME_SET_TUNING",
174 [AV1E_SET_ENABLE_1TO4_PARTITIONS] =
"AV1E_SET_ENABLE_1TO4_PARTITIONS",
175 [AV1E_SET_ENABLE_AB_PARTITIONS] =
"AV1E_SET_ENABLE_AB_PARTITIONS",
176 [AV1E_SET_ENABLE_RECT_PARTITIONS] =
"AV1E_SET_ENABLE_RECT_PARTITIONS",
177 [AV1E_SET_ENABLE_ANGLE_DELTA] =
"AV1E_SET_ENABLE_ANGLE_DELTA",
178 [AV1E_SET_ENABLE_CFL_INTRA] =
"AV1E_SET_ENABLE_CFL_INTRA",
179 [AV1E_SET_ENABLE_FILTER_INTRA] =
"AV1E_SET_ENABLE_FILTER_INTRA",
180 [AV1E_SET_ENABLE_INTRA_EDGE_FILTER] =
"AV1E_SET_ENABLE_INTRA_EDGE_FILTER",
181 [AV1E_SET_ENABLE_PAETH_INTRA] =
"AV1E_SET_ENABLE_PAETH_INTRA",
182 [AV1E_SET_ENABLE_SMOOTH_INTRA] =
"AV1E_SET_ENABLE_SMOOTH_INTRA",
183 [AV1E_SET_ENABLE_PALETTE] =
"AV1E_SET_ENABLE_PALETTE",
184 [AV1E_SET_ENABLE_FLIP_IDTX] =
"AV1E_SET_ENABLE_FLIP_IDTX",
185 [AV1E_SET_ENABLE_TX64] =
"AV1E_SET_ENABLE_TX64",
186 [AV1E_SET_INTRA_DCT_ONLY] =
"AV1E_SET_INTRA_DCT_ONLY",
187 [AV1E_SET_INTER_DCT_ONLY] =
"AV1E_SET_INTER_DCT_ONLY",
188 [AV1E_SET_INTRA_DEFAULT_TX_ONLY] =
"AV1E_SET_INTRA_DEFAULT_TX_ONLY",
189 [AV1E_SET_REDUCED_TX_TYPE_SET] =
"AV1E_SET_REDUCED_TX_TYPE_SET",
190 [AV1E_SET_ENABLE_DIFF_WTD_COMP] =
"AV1E_SET_ENABLE_DIFF_WTD_COMP",
191 [AV1E_SET_ENABLE_DIST_WTD_COMP] =
"AV1E_SET_ENABLE_DIST_WTD_COMP",
192 [AV1E_SET_ENABLE_DUAL_FILTER] =
"AV1E_SET_ENABLE_DUAL_FILTER",
193 [AV1E_SET_ENABLE_INTERINTER_WEDGE] =
"AV1E_SET_ENABLE_INTERINTER_WEDGE",
194 [AV1E_SET_ENABLE_INTERINTRA_WEDGE] =
"AV1E_SET_ENABLE_INTERINTRA_WEDGE",
195 [AV1E_SET_ENABLE_MASKED_COMP] =
"AV1E_SET_ENABLE_MASKED_COMP",
196 [AV1E_SET_ENABLE_INTERINTRA_COMP] =
"AV1E_SET_ENABLE_INTERINTRA_COMP",
197 [AV1E_SET_ENABLE_OBMC] =
"AV1E_SET_ENABLE_OBMC",
198 [AV1E_SET_ENABLE_ONESIDED_COMP] =
"AV1E_SET_ENABLE_ONESIDED_COMP",
199 [AV1E_SET_REDUCED_REFERENCE_SET] =
"AV1E_SET_REDUCED_REFERENCE_SET",
200 [AV1E_SET_ENABLE_SMOOTH_INTERINTRA] =
"AV1E_SET_ENABLE_SMOOTH_INTERINTRA",
201 [AV1E_SET_ENABLE_REF_FRAME_MVS] =
"AV1E_SET_ENABLE_REF_FRAME_MVS",
202 #ifdef AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS
203 [AV1E_GET_NUM_OPERATING_POINTS] =
"AV1E_GET_NUM_OPERATING_POINTS",
205 [AV1E_GET_SEQ_LEVEL_IDX] =
"AV1E_GET_SEQ_LEVEL_IDX",
206 #ifdef AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX
207 [AV1E_GET_TARGET_SEQ_LEVEL_IDX] =
"AV1E_GET_TARGET_SEQ_LEVEL_IDX",
209 [AV1_GET_NEW_FRAME_IMAGE] =
"AV1_GET_NEW_FRAME_IMAGE",
215 const char *
error = aom_codec_error(&
ctx->encoder);
216 const char *detail = aom_codec_error_detail(&
ctx->encoder);
224 const struct aom_codec_enc_cfg *
cfg,
231 " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
233 " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n",
235 width,
"g_threads:",
cfg->g_threads,
236 width,
"g_profile:",
cfg->g_profile,
239 width,
"g_bit_depth:",
cfg->g_bit_depth,
240 width,
"g_input_bit_depth:",
cfg->g_input_bit_depth,
241 width,
"g_timebase:",
cfg->g_timebase.num,
cfg->g_timebase.den,
242 width,
"g_error_resilient:",
cfg->g_error_resilient,
244 width,
"g_lag_in_frames:",
cfg->g_lag_in_frames);
246 " %*s%u\n %*s%d\n %*s%p(%zu)\n %*s%u\n",
247 width,
"rc_dropframe_thresh:",
cfg->rc_dropframe_thresh,
248 width,
"rc_end_usage:",
cfg->rc_end_usage,
249 width,
"rc_twopass_stats_in:",
cfg->rc_twopass_stats_in.buf,
cfg->rc_twopass_stats_in.sz,
250 width,
"rc_target_bitrate:",
cfg->rc_target_bitrate);
253 width,
"rc_min_quantizer:",
cfg->rc_min_quantizer,
254 width,
"rc_max_quantizer:",
cfg->rc_max_quantizer);
257 width,
"rc_undershoot_pct:",
cfg->rc_undershoot_pct,
258 width,
"rc_overshoot_pct:",
cfg->rc_overshoot_pct);
260 " %*s%u\n %*s%u\n %*s%u\n",
261 width,
"rc_buf_sz:",
cfg->rc_buf_sz,
262 width,
"rc_buf_initial_sz:",
cfg->rc_buf_initial_sz,
263 width,
"rc_buf_optimal_sz:",
cfg->rc_buf_optimal_sz);
264 av_log(avctx,
level,
"2 pass rate control settings\n"
265 " %*s%u\n %*s%u\n %*s%u\n",
266 width,
"rc_2pass_vbr_bias_pct:",
cfg->rc_2pass_vbr_bias_pct,
267 width,
"rc_2pass_vbr_minsection_pct:",
cfg->rc_2pass_vbr_minsection_pct,
268 width,
"rc_2pass_vbr_maxsection_pct:",
cfg->rc_2pass_vbr_maxsection_pct);
270 " %*s%d\n %*s%u\n %*s%u\n",
272 width,
"kf_min_dist:",
cfg->kf_min_dist,
273 width,
"kf_max_dist:",
cfg->kf_max_dist);
276 width,
"tile_width_count:",
cfg->tile_width_count,
277 width,
"tile_height_count:",
cfg->tile_height_count);
320 res = aom_codec_control(&
ctx->encoder,
id,
val);
321 if (res != AOM_CODEC_OK) {
347 uint8_t *hdr_plus_buf;
349 const size_t hdr_plus_buf_size = payload_size + 6;
350 hdr_plus_buf =
av_malloc(hdr_plus_buf_size);
354 uint8_t *payload = hdr_plus_buf;
358 bytestream_put_be16(&payload, 0x0001);
359 bytestream_put_byte(&payload, 0x04);
368 res = aom_img_add_metadata(
img, OBU_METADATA_TYPE_ITUT_T35,
369 hdr_plus_buf, hdr_plus_buf_size, AOM_MIF_ANY_FRAME);
396 const size_t hdr_buf_size = payload_size + 5;
401 uint8_t *payload = hdr_buf;
404 bytestream_put_be16(&payload, 0x0001);
413 res = aom_img_add_metadata(
img, OBU_METADATA_TYPE_ITUT_T35,
414 hdr_buf, hdr_buf_size, AOM_MIF_ANY_FRAME);
423 #if defined(AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS) && \
424 defined(AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX) && \
425 defined(AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX)
435 res = aom_codec_control(&
ctx->encoder,
id, ptr);
436 if (res != AOM_CODEC_OK) {
452 struct aom_image *
img)
460 res = aom_codec_control(&
ctx->encoder,
id,
img);
461 if (res != AOM_CODEC_OK) {
475 #if defined(AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS) && \
476 defined(AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX) && \
477 defined(AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX)
479 int num_operating_points;
481 int target_levels[32];
483 if (!codecctl_intp(avctx, AV1E_GET_NUM_OPERATING_POINTS,
484 &num_operating_points) &&
485 !codecctl_intp(avctx, AV1E_GET_SEQ_LEVEL_IDX, levels) &&
486 !codecctl_intp(avctx, AV1E_GET_TARGET_SEQ_LEVEL_IDX,
488 for (
int i = 0;
i < num_operating_points;
i++) {
489 if (levels[
i] > target_levels[
i]) {
492 "Could not encode to target level %d.%d for "
493 "operating point %d. The output level is %d.%d.\n",
494 2 + (target_levels[
i] >> 2), target_levels[
i] & 3,
495 i, 2 + (levels[
i] >> 2), levels[
i] & 3);
496 }
else if (target_levels[
i] < 31) {
499 "Output level for operating point %d is %d.%d.\n",
500 i, 2 + (levels[
i] >> 2), levels[
i] & 3);
507 aom_codec_destroy(&
ctx->encoder);
508 aom_img_remove_metadata(&
ctx->rawimg);
518 struct aom_codec_enc_cfg *enccfg, aom_codec_flags_t *
flags,
519 aom_img_fmt_t *img_fmt)
522 enccfg->g_bit_depth = enccfg->g_input_bit_depth =
desc->comp[0].depth;
525 enccfg->monochrome = 1;
529 *img_fmt = AOM_IMG_FMT_I420;
533 *img_fmt = AOM_IMG_FMT_I422;
538 *img_fmt = AOM_IMG_FMT_I444;
542 enccfg->monochrome = 1;
546 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
549 *img_fmt = AOM_IMG_FMT_I42016;
550 *
flags |= AOM_CODEC_USE_HIGHBITDEPTH;
556 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
558 *img_fmt = AOM_IMG_FMT_I42216;
559 *
flags |= AOM_CODEC_USE_HIGHBITDEPTH;
567 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
570 *img_fmt = AOM_IMG_FMT_I44416;
571 *
flags |= AOM_CODEC_USE_HIGHBITDEPTH;
584 aom_color_range_t aom_cr;
600 int sb_dim = (
dim + sb_size - 1) / sb_size;
601 int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2;
603 return (sb_dim + tile_dim - 1) / tile_dim;
607 struct aom_codec_enc_cfg *enccfg)
610 int sb_128x128_possible, sb_size, sb_width, sb_height;
611 int uniform_rows, uniform_cols;
612 int uniform_64x64_possible, uniform_128x128_possible;
613 int tile_size, rounding,
i;
615 if (
ctx->tile_cols_log2 >= 0)
616 ctx->tile_cols = 1 <<
ctx->tile_cols_log2;
617 if (
ctx->tile_rows_log2 >= 0)
618 ctx->tile_rows = 1 <<
ctx->tile_rows_log2;
620 if (
ctx->tile_cols == 0) {
623 if (
ctx->tile_cols > 1) {
625 "columns to fill width.\n",
ctx->tile_cols);
629 if (
ctx->tile_rows == 0) {
632 ctx->tile_cols - 1) /
ctx->tile_cols, 128);
636 if (
ctx->tile_rows > 1) {
638 "rows to fill area.\n",
ctx->tile_rows);
643 if ((avctx->
width + 63) / 64 <
ctx->tile_cols ||
644 (avctx->
height + 63) / 64 <
ctx->tile_rows) {
646 "large enough to fit specified tile arrangement.\n");
652 "not allow more than %dx%d tiles.\n",
658 "not allow tiles of width greater than %d.\n",
663 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC;
665 if (
ctx->tile_cols == 1 &&
ctx->tile_rows == 1) {
670 sb_128x128_possible =
671 (avctx->
width + 127) / 128 >=
ctx->tile_cols &&
672 (avctx->
height + 127) / 128 >=
ctx->tile_rows;
674 ctx->tile_cols_log2 =
ctx->tile_cols == 1 ? 0 :
676 ctx->tile_rows_log2 =
ctx->tile_rows == 1 ? 0 :
680 64,
ctx->tile_cols_log2);
682 64,
ctx->tile_rows_log2);
684 "-> %dx%d tiles.\n", uniform_cols, uniform_rows);
685 uniform_64x64_possible = uniform_cols ==
ctx->tile_cols &&
686 uniform_rows ==
ctx->tile_rows;
688 if (sb_128x128_possible) {
690 128,
ctx->tile_cols_log2);
692 128,
ctx->tile_rows_log2);
694 "-> %dx%d tiles.\n", uniform_cols, uniform_rows);
695 uniform_128x128_possible = uniform_cols ==
ctx->tile_cols &&
696 uniform_rows ==
ctx->tile_rows;
699 uniform_128x128_possible = 0;
702 ctx->uniform_tiles = 1;
703 if (uniform_64x64_possible && uniform_128x128_possible) {
705 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n",
706 ctx->tile_cols_log2,
ctx->tile_rows_log2);
709 if (uniform_64x64_possible && !sb_128x128_possible) {
711 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n",
712 ctx->tile_cols_log2,
ctx->tile_rows_log2);
713 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
716 if (uniform_128x128_possible) {
718 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n",
719 ctx->tile_cols_log2,
ctx->tile_rows_log2);
720 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_128X128;
723 ctx->uniform_tiles = 0;
725 if (sb_128x128_possible) {
727 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_128X128;
730 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
733 "superblocks (tile_cols = %d, tile_rows = %d).\n",
734 sb_size, sb_size,
ctx->tile_cols,
ctx->tile_rows);
736 enccfg->tile_width_count =
ctx->tile_cols;
737 enccfg->tile_height_count =
ctx->tile_rows;
739 sb_width = (avctx->
width + sb_size - 1) / sb_size;
740 sb_height = (avctx->
height + sb_size - 1) / sb_size;
742 tile_size = sb_width /
ctx->tile_cols;
743 rounding = sb_width %
ctx->tile_cols;
744 for (
i = 0;
i <
ctx->tile_cols;
i++) {
745 enccfg->tile_widths[
i] = tile_size +
747 i >
ctx->tile_cols - 1 - (rounding + 1) / 2);
750 tile_size = sb_height /
ctx->tile_rows;
751 rounding = sb_height %
ctx->tile_rows;
752 for (
i = 0;
i <
ctx->tile_rows;
i++) {
753 enccfg->tile_heights[
i] = tile_size +
755 i >
ctx->tile_rows - 1 - (rounding + 1) / 2);
761 static const struct {
765 { AOME_SET_ENABLEAUTOALTREF,
OFFSET(auto_alt_ref) },
766 { AOME_SET_ARNR_MAXFRAMES,
OFFSET(arnr_max_frames) },
767 { AOME_SET_ARNR_STRENGTH,
OFFSET(arnr_strength) },
768 { AV1E_SET_ENABLE_CDEF,
OFFSET(enable_cdef) },
769 { AV1E_SET_ENABLE_RESTORATION,
OFFSET(enable_restoration) },
770 { AV1E_SET_ENABLE_RECT_PARTITIONS,
OFFSET(enable_rect_partitions) },
771 { AV1E_SET_ENABLE_1TO4_PARTITIONS,
OFFSET(enable_1to4_partitions) },
772 { AV1E_SET_ENABLE_AB_PARTITIONS,
OFFSET(enable_ab_partitions) },
773 { AV1E_SET_ENABLE_ANGLE_DELTA,
OFFSET(enable_angle_delta) },
774 { AV1E_SET_ENABLE_CFL_INTRA,
OFFSET(enable_cfl_intra) },
775 { AV1E_SET_ENABLE_FILTER_INTRA,
OFFSET(enable_filter_intra) },
776 { AV1E_SET_ENABLE_INTRA_EDGE_FILTER,
OFFSET(enable_intra_edge_filter) },
777 { AV1E_SET_ENABLE_PAETH_INTRA,
OFFSET(enable_paeth_intra) },
778 { AV1E_SET_ENABLE_SMOOTH_INTRA,
OFFSET(enable_smooth_intra) },
779 { AV1E_SET_ENABLE_PALETTE,
OFFSET(enable_palette) },
780 { AV1E_SET_ENABLE_TX64,
OFFSET(enable_tx64) },
781 { AV1E_SET_ENABLE_FLIP_IDTX,
OFFSET(enable_flip_idtx) },
782 { AV1E_SET_INTRA_DCT_ONLY,
OFFSET(use_intra_dct_only) },
783 { AV1E_SET_INTER_DCT_ONLY,
OFFSET(use_inter_dct_only) },
784 { AV1E_SET_INTRA_DEFAULT_TX_ONLY,
OFFSET(use_intra_default_tx_only) },
785 { AV1E_SET_REDUCED_TX_TYPE_SET,
OFFSET(reduced_tx_type_set) },
786 { AV1E_SET_ENABLE_REF_FRAME_MVS,
OFFSET(enable_ref_frame_mvs) },
787 { AV1E_SET_REDUCED_REFERENCE_SET,
OFFSET(enable_reduced_reference_set) },
788 { AV1E_SET_ENABLE_DIFF_WTD_COMP,
OFFSET(enable_diff_wtd_comp) },
789 { AV1E_SET_ENABLE_DIST_WTD_COMP,
OFFSET(enable_dist_wtd_comp) },
790 { AV1E_SET_ENABLE_DUAL_FILTER,
OFFSET(enable_dual_filter) },
791 { AV1E_SET_ENABLE_INTERINTER_WEDGE,
OFFSET(enable_interinter_wedge) },
792 { AV1E_SET_ENABLE_MASKED_COMP,
OFFSET(enable_masked_comp) },
793 { AV1E_SET_ENABLE_INTERINTRA_COMP,
OFFSET(enable_interintra_comp) },
794 { AV1E_SET_ENABLE_INTERINTRA_WEDGE,
OFFSET(enable_interintra_wedge) },
795 { AV1E_SET_ENABLE_OBMC,
OFFSET(enable_obmc) },
796 { AV1E_SET_ENABLE_ONESIDED_COMP,
OFFSET(enable_onesided_comp) },
797 { AV1E_SET_ENABLE_SMOOTH_INTERINTRA,
OFFSET(enable_smooth_interintra) },
801 const struct aom_codec_iface *iface)
805 aom_codec_caps_t codec_caps = aom_codec_get_caps(iface);
809 if ((res = aom_codec_enc_config_default(iface, &
ctx->enccfg,
ctx->usage)) != AOM_CODEC_OK) {
811 aom_codec_err_to_string(res));
828 ctx->enccfg.g_threads =
831 if (
ctx->lag_in_frames >= 0)
832 ctx->enccfg.g_lag_in_frames =
ctx->lag_in_frames;
836 ctx->enccfg.rc_end_usage = AOM_CBR;
837 }
else if (
ctx->crf >= 0) {
838 ctx->enccfg.rc_end_usage = AOM_CQ;
840 ctx->enccfg.rc_end_usage = AOM_Q;
846 }
else if (
ctx->enccfg.rc_end_usage != AOM_Q) {
847 ctx->enccfg.rc_end_usage = AOM_Q;
850 "Neither bitrate nor constrained quality specified, using default CRF of %d\n",
854 if (avctx->
qmin >= 0)
855 ctx->enccfg.rc_min_quantizer = avctx->
qmin;
856 if (avctx->
qmax >= 0) {
857 ctx->enccfg.rc_max_quantizer = avctx->
qmax;
858 }
else if (!
ctx->crf) {
859 ctx->enccfg.rc_max_quantizer = 0;
862 if (
ctx->enccfg.rc_end_usage == AOM_CQ ||
ctx->enccfg.rc_end_usage == AOM_Q) {
863 if (
ctx->crf <
ctx->enccfg.rc_min_quantizer ||
ctx->crf >
ctx->enccfg.rc_max_quantizer) {
865 "CQ level %d must be between minimum and maximum quantizer value (%d-%d)\n",
866 ctx->crf,
ctx->enccfg.rc_min_quantizer,
ctx->enccfg.rc_max_quantizer);
871 ctx->enccfg.rc_dropframe_thresh =
ctx->drop_threshold;
875 if (
ctx->minsection_pct >= 0)
876 ctx->enccfg.rc_2pass_vbr_minsection_pct =
ctx->minsection_pct;
878 ctx->enccfg.rc_2pass_vbr_minsection_pct =
880 if (
ctx->maxsection_pct >= 0)
881 ctx->enccfg.rc_2pass_vbr_maxsection_pct =
ctx->maxsection_pct;
883 ctx->enccfg.rc_2pass_vbr_maxsection_pct =
887 ctx->enccfg.rc_buf_sz =
890 ctx->enccfg.rc_buf_initial_sz =
892 ctx->enccfg.rc_buf_optimal_sz =
ctx->enccfg.rc_buf_sz * 5 / 6;
894 if (
ctx->rc_undershoot_pct >= 0)
895 ctx->enccfg.rc_undershoot_pct =
ctx->rc_undershoot_pct;
896 if (
ctx->rc_overshoot_pct >= 0)
897 ctx->enccfg.rc_overshoot_pct =
ctx->rc_overshoot_pct;
911 ctx->enccfg.g_error_resilient =
ctx->error_resilient;
917 if (
ctx->still_picture) {
921 ctx->enccfg.g_limit = 1;
923 ctx->enccfg.g_lag_in_frames = 0;
925 ctx->enccfg.kf_max_dist = 0;
926 ctx->enccfg.kf_mode = AOM_KF_DISABLED;
936 aom_codec_caps_t codec_caps = aom_codec_get_caps(
ctx->encoder.iface);
962 if (
ctx->aq_mode >= 0)
964 if (
ctx->frame_parallel >= 0)
965 codecctl_int(avctx, AV1E_SET_FRAME_PARALLEL_DECODING,
ctx->frame_parallel);
969 if (
ctx->uniform_tiles) {
974 if (
ctx->denoise_noise_level >= 0)
975 codecctl_int(avctx, AV1E_SET_DENOISE_NOISE_LEVEL,
ctx->denoise_noise_level);
976 if (
ctx->denoise_block_size >= 0)
977 codecctl_int(avctx, AV1E_SET_DENOISE_BLOCK_SIZE,
ctx->denoise_block_size);
978 if (
ctx->enable_global_motion >= 0)
979 codecctl_int(avctx, AV1E_SET_ENABLE_GLOBAL_MOTION,
ctx->enable_global_motion);
980 if (avctx->
refs >= 3) {
983 if (
ctx->row_mt >= 0)
985 if (
ctx->enable_intrabc >= 0)
988 #if AOM_ENCODER_ABI_VERSION >= 23
993 int ret = aom_codec_set_option(&
ctx->encoder, en->
key, en->
value);
994 if (
ret != AOM_CODEC_OK) {
1006 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
1007 ctx->rawimg.bit_depth =
ctx->enccfg.g_bit_depth;
1013 const struct aom_codec_iface *iface)
1026 ctx->enccfg.g_pass = AOM_RC_FIRST_PASS;
1028 ctx->enccfg.g_pass = AOM_RC_LAST_PASS;
1030 ctx->enccfg.g_pass = AOM_RC_ONE_PASS;
1032 if (
ctx->enccfg.g_pass == AOM_RC_FIRST_PASS)
1033 ctx->enccfg.g_lag_in_frames = 0;
1034 else if (
ctx->enccfg.g_pass == AOM_RC_LAST_PASS) {
1035 int decode_size,
ret;
1042 ctx->twopass_stats.sz = strlen(avctx->
stats_in) * 3 / 4;
1046 "Stat buffer alloc (%zu bytes) failed\n",
1047 ctx->twopass_stats.sz);
1048 ctx->twopass_stats.sz = 0;
1052 ctx->twopass_stats.sz);
1053 if (decode_size < 0) {
1058 ctx->twopass_stats.sz = decode_size;
1059 ctx->enccfg.rc_twopass_stats_in =
ctx->twopass_stats;
1063 res = aom_codec_enc_init(&
ctx->encoder, iface, &
ctx->enccfg,
ctx->
flags);
1064 if (res != AOM_CODEC_OK) {
1075 ctx->dovi.logctx = avctx;
1085 "not found. This is a bug, please report it.\n");
1105 if (
ctx->enccfg.rc_end_usage == AOM_CBR ||
1106 ctx->enccfg.g_pass != AOM_RC_ONE_PASS) {
1118 const struct aom_codec_cx_pkt *
src)
1120 dst->pts =
src->data.frame.pts;
1121 dst->duration =
src->data.frame.duration;
1122 dst->flags =
src->data.frame.flags;
1123 dst->sz =
src->data.frame.sz;
1124 dst->buf =
src->data.frame.buf;
1125 dst->frame_number = ++
ctx->frame_number;
1126 dst->have_sse =
ctx->have_sse;
1127 if (
ctx->have_sse) {
1130 memcpy(
dst->sse,
ctx->sse,
sizeof(
dst->sse));
1150 "Error getting output packet of size %zu.\n", cx_frame->
sz);
1157 if (!!(cx_frame->
flags & AOM_FRAME_IS_KEY)) {
1160 }
else if (cx_frame->
flags & AOM_FRAME_IS_INTRAONLY) {
1167 cx_frame->
have_sse ? 3 : 0, pict_type);
1171 for (
i = 0;
i < 3; ++
i) {
1181 "failed to send input packet\n");
1188 "failed to receive output packet\n");
1206 const struct aom_codec_cx_pkt *
pkt;
1207 const void *iter =
NULL;
1210 if (
ctx->coded_frame_list) {
1216 ctx->coded_frame_list = cx_frame->
next;
1222 while ((
pkt = aom_codec_get_cx_data(&
ctx->encoder, &iter))) {
1223 switch (
pkt->kind) {
1224 case AOM_CODEC_CX_FRAME_PKT:
1241 "Frame queue element alloc failed\n");
1247 if (!cx_frame->
buf) {
1249 "Data buffer alloc (%zu bytes) failed\n",
1258 case AOM_CODEC_STATS_PKT:
1260 struct aom_fixed_buf *
stats = &
ctx->twopass_stats;
1262 &
ctx->twopass_stats_size,
1277 case AOM_CODEC_PSNR_PKT:
1287 case AOM_CODEC_CUSTOM_PKT:
1299 case AOM_IMG_FMT_I420:
1300 case AOM_IMG_FMT_I42016:
1301 if (
img->bit_depth == 8)
1303 else if (
img->bit_depth == 10)
1307 case AOM_IMG_FMT_I422:
1308 case AOM_IMG_FMT_I42216:
1309 if (
img->bit_depth == 8)
1311 else if (
img->bit_depth == 10)
1315 case AOM_IMG_FMT_I444:
1316 case AOM_IMG_FMT_I44416:
1317 if (
img->bit_depth == 8)
1319 else if (
img->bit_depth == 10)
1331 struct aom_image *rawimg =
NULL;
1334 int res, coded_size;
1335 aom_enc_frame_flags_t
flags = 0;
1339 rawimg = &
ctx->rawimg;
1340 aom_img_remove_metadata(rawimg);
1341 rawimg->planes[AOM_PLANE_Y] =
frame->data[0];
1342 rawimg->planes[AOM_PLANE_U] =
frame->data[1];
1343 rawimg->planes[AOM_PLANE_V] =
frame->data[2];
1344 rawimg->stride[AOM_PLANE_Y] =
frame->linesize[0];
1345 rawimg->stride[AOM_PLANE_U] =
frame->linesize[1];
1346 rawimg->stride[AOM_PLANE_V] =
frame->linesize[2];
1347 timestamp =
frame->pts;
1349 if (
frame->duration > ULONG_MAX) {
1351 "Frame duration too large: %"PRId64
"\n",
frame->duration);
1352 }
else if (
frame->duration)
1360 switch (
frame->color_range) {
1362 rawimg->range = AOM_CR_STUDIO_RANGE;
1365 rawimg->range = AOM_CR_FULL_RANGE;
1369 aom_img_remove_metadata(rawimg);
1371 if (
ctx->dovi.cfg.dv_profile && sd) {
1378 res = aom_img_add_metadata(rawimg, OBU_METADATA_TYPE_ITUT_T35,
1379 t35,
size, AOM_MIF_ANY_FRAME);
1381 if (res != AOM_CODEC_OK)
1383 }
else if (
ctx->dovi.cfg.dv_profile) {
1385 "without AV_FRAME_DATA_DOVI_METADATA\n");
1390 flags |= AOM_EFLAG_FORCE_KF;
1402 if (res != AOM_CODEC_OK) {
1420 ctx->twopass_stats.sz);
1423 *got_packet = !!coded_size;
1427 struct aom_image
img;
1438 "Unhandled reconstructed frame colorspace: %d\n",
1450 if ((
img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) &&
img.bit_depth == 8)
1453 const uint8_t *
planes[4] = {
img.planes[0],
img.planes[1],
img.planes[2] };
1454 const int stride[4] = {
img.stride[0],
img.stride[1],
img.stride[2] };
1523 int supports_monochrome = aom_codec_version() >= 20001;
1524 aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
1525 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
1526 if (supports_monochrome) {
1534 if (supports_monochrome) {
1550 return aom_init(avctx, aom_codec_av1_cx());
1567 res = aom_codec_enc_config_set(&
ctx->encoder, &
ctx->enccfg);
1569 av_log(avctx, loglevel,
"Reconfigure options:\n");
1571 if (res != AOM_CODEC_OK) {
1583 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1584 #define VER VE | AV_OPT_FLAG_RUNTIME_PARAM
1587 {
"auto-alt-ref",
"Enable use of alternate reference "
1589 {
"lag-in-frames",
"Number of frames to look ahead at for "
1591 {
"arnr-max-frames",
"altref noise reduction max frame count",
OFFSET(arnr_max_frames),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
VE},
1592 {
"arnr-strength",
"altref noise reduction filter strength",
OFFSET(arnr_strength),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6,
VE},
1593 {
"aq-mode",
"adaptive quantization mode",
OFFSET(aq_mode),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 4,
VE, .unit =
"aq_mode"},
1595 {
"variance",
"Variance based Aq", 0,
AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0,
VE, .unit =
"aq_mode"},
1596 {
"complexity",
"Complexity based Aq", 0,
AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0,
VE, .unit =
"aq_mode"},
1597 {
"cyclic",
"Cyclic Refresh Aq", 0,
AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0,
VE, .unit =
"aq_mode"},
1598 {
"error-resilience",
"Error resilience configuration",
OFFSET(error_resilient),
AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX,
VE, .unit =
"er"},
1599 {
"default",
"Improve resiliency against losses of whole frames", 0,
AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0,
VE, .unit =
"er"},
1600 {
"crf",
"Select the quality for constant quality mode", offsetof(AOMContext, crf),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63,
VER },
1601 {
"static-thresh",
"A change threshold on blocks below which they will be skipped by the encoder",
OFFSET(static_thresh),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
VE },
1602 {
"drop-threshold",
"Frame drop threshold", offsetof(AOMContext, drop_threshold),
AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX,
VE },
1603 {
"denoise-noise-level",
"Amount of noise to be removed",
OFFSET(denoise_noise_level),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
VE},
1604 {
"denoise-block-size",
"Denoise block size ",
OFFSET(denoise_block_size),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
VE},
1605 {
"undershoot-pct",
"Datarate undershoot (min) target (%)",
OFFSET(rc_undershoot_pct),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100,
VE},
1606 {
"overshoot-pct",
"Datarate overshoot (max) target (%)",
OFFSET(rc_overshoot_pct),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1000,
VE},
1607 {
"minsection-pct",
"GOP min bitrate (% of target)",
OFFSET(minsection_pct),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100,
VE},
1608 {
"maxsection-pct",
"GOP max bitrate (% of target)",
OFFSET(maxsection_pct),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 5000,
VE},
1609 {
"frame-parallel",
"Enable frame parallel decodability features",
OFFSET(frame_parallel),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1611 {
"tile-columns",
"Log2 of number of tile columns to use",
OFFSET(tile_cols_log2),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6,
VE},
1612 {
"tile-rows",
"Log2 of number of tile rows to use",
OFFSET(tile_rows_log2),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6,
VE},
1615 {
"enable-global-motion",
"Enable global motion",
OFFSET(enable_global_motion),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1616 {
"enable-intrabc",
"Enable intra block copy prediction mode",
OFFSET(enable_intrabc),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1617 {
"enable-restoration",
"Enable Loop Restoration filtering",
OFFSET(enable_restoration),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1618 {
"usage",
"Quality and compression efficiency vs speed trade-off",
OFFSET(
usage),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX,
VE, .unit =
"usage"},
1620 {
"realtime",
"Realtime encoding", 0,
AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0,
VE, .unit =
"usage"},
1621 {
"allintra",
"All Intra encoding", 0,
AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0,
VE, .unit =
"usage"},
1622 {
"tune",
"The metric that the encoder tunes for. Automatically chosen by the encoder by default",
OFFSET(tune),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM,
VE, .unit =
"tune"},
1626 {
"still-picture",
"Encode in single frame mode (typically used for still AVIF images).",
OFFSET(still_picture),
AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1,
VE },
1629 {
"enable-rect-partitions",
"Enable rectangular partitions",
OFFSET(enable_rect_partitions),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1630 {
"enable-1to4-partitions",
"Enable 1:4/4:1 partitions",
OFFSET(enable_1to4_partitions),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1631 {
"enable-ab-partitions",
"Enable ab shape partitions",
OFFSET(enable_ab_partitions),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1632 {
"enable-angle-delta",
"Enable angle delta intra prediction",
OFFSET(enable_angle_delta),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1633 {
"enable-cfl-intra",
"Enable chroma predicted from luma intra prediction",
OFFSET(enable_cfl_intra),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1634 {
"enable-filter-intra",
"Enable filter intra predictor",
OFFSET(enable_filter_intra),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1635 {
"enable-intra-edge-filter",
"Enable intra edge filter",
OFFSET(enable_intra_edge_filter),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1636 {
"enable-smooth-intra",
"Enable smooth intra prediction mode",
OFFSET(enable_smooth_intra),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1637 {
"enable-paeth-intra",
"Enable paeth predictor in intra prediction",
OFFSET(enable_paeth_intra),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1638 {
"enable-palette",
"Enable palette prediction mode",
OFFSET(enable_palette),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1639 {
"enable-flip-idtx",
"Enable extended transform type",
OFFSET(enable_flip_idtx),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1641 {
"reduced-tx-type-set",
"Use reduced set of transform types",
OFFSET(reduced_tx_type_set),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1642 {
"use-intra-dct-only",
"Use DCT only for INTRA modes",
OFFSET(use_intra_dct_only),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1643 {
"use-inter-dct-only",
"Use DCT only for INTER modes",
OFFSET(use_inter_dct_only),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1644 {
"use-intra-default-tx-only",
"Use default-transform only for INTRA modes",
OFFSET(use_intra_default_tx_only),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1645 {
"enable-ref-frame-mvs",
"Enable temporal mv prediction",
OFFSET(enable_ref_frame_mvs),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1646 {
"enable-reduced-reference-set",
"Use reduced set of single and compound references",
OFFSET(enable_reduced_reference_set),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1648 {
"enable-dual-filter",
"Enable dual filter",
OFFSET(enable_dual_filter),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1649 {
"enable-diff-wtd-comp",
"Enable difference-weighted compound",
OFFSET(enable_diff_wtd_comp),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1650 {
"enable-dist-wtd-comp",
"Enable distance-weighted compound",
OFFSET(enable_dist_wtd_comp),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1651 {
"enable-onesided-comp",
"Enable one sided compound",
OFFSET(enable_onesided_comp),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1652 {
"enable-interinter-wedge",
"Enable interinter wedge compound",
OFFSET(enable_interinter_wedge),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1653 {
"enable-interintra-wedge",
"Enable interintra wedge compound",
OFFSET(enable_interintra_wedge),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1654 {
"enable-masked-comp",
"Enable masked compound",
OFFSET(enable_masked_comp),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1655 {
"enable-interintra-comp",
"Enable interintra compound",
OFFSET(enable_interintra_comp),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1656 {
"enable-smooth-interintra",
"Enable smooth interintra mode",
OFFSET(enable_smooth_interintra),
AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1,
VE},
1657 #if AOM_ENCODER_ABI_VERSION >= 23
1658 {
"aom-params",
"Set libaom options using a :-separated list of key=value pairs",
OFFSET(aom_params),
AV_OPT_TYPE_DICT, { 0 }, 0, 0,
VE },
1672 {
"keyint_min",
"-1" },
1684 .
p.
name =
"libaom-av1",
1695 .p.wrapper_name =
"libaom",
1696 .priv_data_size =
sizeof(AOMContext),