@@ -60,6 +60,7 @@ struct avifCodecInternal
6060#if defined(AVIF_CODEC_AOM_ENCODE )
6161 avifBool encoderInitialized ;
6262 aom_codec_ctx_t encoder ;
63+ struct aom_codec_enc_cfg cfg ;
6364 avifPixelFormatInfo formatInfo ;
6465 aom_img_fmt_t aomFormat ;
6566 avifBool monochromeEnabled ;
@@ -526,10 +527,11 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
526527 avifEncoder * encoder ,
527528 const avifImage * image ,
528529 avifBool alpha ,
530+ avifBool updateConfig ,
529531 avifAddImageFlags addImageFlags ,
530532 avifCodecEncodeOutput * output )
531533{
532- if (!codec -> internal -> encoderInitialized ) {
534+ if (!codec -> internal -> encoderInitialized || updateConfig ) {
533535 // Map encoder speed to AOM usage + CpuUsed:
534536 // Speed 0: GoodQuality CpuUsed 0
535537 // Speed 1: GoodQuality CpuUsed 1
@@ -587,37 +589,41 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
587589 }
588590 }
589591
590- codec -> internal -> aomFormat = avifImageCalcAOMFmt (image , alpha );
591- if (codec -> internal -> aomFormat == AOM_IMG_FMT_NONE ) {
592- return AVIF_RESULT_UNKNOWN_ERROR ;
593- }
592+ struct aom_codec_enc_cfg * cfg = & codec -> internal -> cfg ;
594593
595- avifGetPixelFormatInfo (image -> yuvFormat , & codec -> internal -> formatInfo );
594+ aom_codec_iface_t * encoderInterface = NULL ;
595+ if (!codec -> internal -> encoderInitialized ) {
596+ codec -> internal -> aomFormat = avifImageCalcAOMFmt (image , alpha );
597+ if (codec -> internal -> aomFormat == AOM_IMG_FMT_NONE ) {
598+ return AVIF_RESULT_UNKNOWN_ERROR ;
599+ }
596600
597- aom_codec_iface_t * encoderInterface = aom_codec_av1_cx ();
598- struct aom_codec_enc_cfg cfg ;
599- aom_codec_err_t err = aom_codec_enc_config_default (encoderInterface , & cfg , aomUsage );
600- if (err != AOM_CODEC_OK ) {
601- avifDiagnosticsPrintf (codec -> diag , "aom_codec_enc_config_default() failed: %s" , aom_codec_err_to_string (err ));
602- return AVIF_RESULT_UNKNOWN_ERROR ;
601+ avifGetPixelFormatInfo (image -> yuvFormat , & codec -> internal -> formatInfo );
602+
603+ encoderInterface = aom_codec_av1_cx ();
604+ aom_codec_err_t err = aom_codec_enc_config_default (encoderInterface , cfg , aomUsage );
605+ if (err != AOM_CODEC_OK ) {
606+ avifDiagnosticsPrintf (codec -> diag , "aom_codec_enc_config_default() failed: %s" , aom_codec_err_to_string (err ));
607+ return AVIF_RESULT_UNKNOWN_ERROR ;
608+ }
603609 }
604610
605- // Set our own default cfg. rc_end_usage value, which may differ from libaom's default.
611+ // Set our own default cfg-> rc_end_usage value, which may differ from libaom's default.
606612 switch (aomUsage ) {
607613 case AOM_USAGE_GOOD_QUALITY :
608614 // libaom's default is AOM_VBR. Change the default to AOM_Q since we don't need to
609615 // hit a certain target bit rate. It's easier to control the worst quality in Q
610616 // mode.
611- cfg . rc_end_usage = AOM_Q ;
617+ cfg -> rc_end_usage = AOM_Q ;
612618 break ;
613619 case AOM_USAGE_REALTIME :
614620 // For real-time mode we need to use CBR rate control mode. AOM_Q doesn't fit the
615621 // rate control requirements for real-time mode. CBR does.
616- cfg . rc_end_usage = AOM_CBR ;
622+ cfg -> rc_end_usage = AOM_CBR ;
617623 break ;
618624#if defined(AOM_USAGE_ALL_INTRA )
619625 case AOM_USAGE_ALL_INTRA :
620- cfg . rc_end_usage = AOM_Q ;
626+ cfg -> rc_end_usage = AOM_Q ;
621627 break ;
622628#endif
623629 }
@@ -657,31 +663,31 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
657663 }
658664 }
659665
660- cfg . g_profile = seqProfile ;
661- cfg . g_bit_depth = image -> depth ;
662- cfg . g_input_bit_depth = image -> depth ;
663- cfg . g_w = image -> width ;
664- cfg . g_h = image -> height ;
666+ cfg -> g_profile = seqProfile ;
667+ cfg -> g_bit_depth = image -> depth ;
668+ cfg -> g_input_bit_depth = image -> depth ;
669+ cfg -> g_w = image -> width ;
670+ cfg -> g_h = image -> height ;
665671 if (addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE ) {
666672 // Set the maximum number of frames to encode to 1. This instructs
667673 // libaom to set still_picture and reduced_still_picture_header to
668674 // 1 in AV1 sequence headers.
669- cfg . g_limit = 1 ;
675+ cfg -> g_limit = 1 ;
670676
671677 // Use the default settings of the new AOM_USAGE_ALL_INTRA (added in
672678 // https://crbug.com/aomedia/2959).
673679 //
674680 // Set g_lag_in_frames to 0 to reduce the number of frame buffers
675681 // (from 20 to 2) in libaom's lookahead structure. This reduces
676682 // memory consumption when encoding a single image.
677- cfg . g_lag_in_frames = 0 ;
683+ cfg -> g_lag_in_frames = 0 ;
678684 // Disable automatic placement of key frames by the encoder.
679- cfg . kf_mode = AOM_KF_DISABLED ;
685+ cfg -> kf_mode = AOM_KF_DISABLED ;
680686 // Tell libaom that all frames will be key frames.
681- cfg . kf_max_dist = 0 ;
687+ cfg -> kf_max_dist = 0 ;
682688 }
683689 if (encoder -> maxThreads > 1 ) {
684- cfg . g_threads = encoder -> maxThreads ;
690+ cfg -> g_threads = encoder -> maxThreads ;
685691 }
686692
687693 int minQuantizer = AVIF_CLAMP (encoder -> minQuantizer , 0 , 63 );
@@ -691,41 +697,52 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
691697 maxQuantizer = AVIF_CLAMP (encoder -> maxQuantizerAlpha , 0 , 63 );
692698 }
693699 avifBool lossless = ((minQuantizer == AVIF_QUANTIZER_LOSSLESS ) && (maxQuantizer == AVIF_QUANTIZER_LOSSLESS ));
694- cfg . rc_min_quantizer = minQuantizer ;
695- cfg . rc_max_quantizer = maxQuantizer ;
700+ cfg -> rc_min_quantizer = minQuantizer ;
701+ cfg -> rc_max_quantizer = maxQuantizer ;
696702
697703 codec -> internal -> monochromeEnabled = AVIF_FALSE ;
698704 if (aomVersion > aomVersion_2_0_0 ) {
699705 // There exists a bug in libaom's chroma_check() function where it will attempt to
700706 // access nonexistent UV planes when encoding monochrome at faster libavif "speeds". It
701707 // was fixed shortly after the 2.0.0 libaom release, and the fix exists in both the
702708 // master and applejack branches. This ensures that the next version *after* 2.0.0 will
703- // have the fix, and we must avoid cfg. monochrome until then.
709+ // have the fix, and we must avoid cfg-> monochrome until then.
704710 //
705711 // Bugfix Change-Id: https://aomedia-review.googlesource.com/q/I26a39791f820b4d4e1d63ff7141f594c3c7181f5
706712
707713 if (alpha || (image -> yuvFormat == AVIF_PIXEL_FORMAT_YUV400 )) {
708714 codec -> internal -> monochromeEnabled = AVIF_TRUE ;
709- cfg . monochrome = 1 ;
715+ cfg -> monochrome = 1 ;
710716 }
711717 }
712718
713- if (!avifProcessAOMOptionsPreInit (codec , alpha , & cfg )) {
719+ if (!avifProcessAOMOptionsPreInit (codec , alpha , cfg )) {
714720 return AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION ;
715721 }
716722
717- aom_codec_flags_t encoderFlags = 0 ;
718- if (image -> depth > 8 ) {
719- encoderFlags |= AOM_CODEC_USE_HIGHBITDEPTH ;
720- }
721- if (aom_codec_enc_init (& codec -> internal -> encoder , encoderInterface , & cfg , encoderFlags ) != AOM_CODEC_OK ) {
722- avifDiagnosticsPrintf (codec -> diag ,
723- "aom_codec_enc_init() failed: %s: %s" ,
724- aom_codec_error (& codec -> internal -> encoder ),
725- aom_codec_error_detail (& codec -> internal -> encoder ));
726- return AVIF_RESULT_UNKNOWN_ERROR ;
723+ if (!codec -> internal -> encoderInitialized ) {
724+ aom_codec_flags_t encoderFlags = 0 ;
725+ if (image -> depth > 8 ) {
726+ encoderFlags |= AOM_CODEC_USE_HIGHBITDEPTH ;
727+ }
728+
729+ if (aom_codec_enc_init (& codec -> internal -> encoder , encoderInterface , cfg , encoderFlags ) != AOM_CODEC_OK ) {
730+ avifDiagnosticsPrintf (codec -> diag ,
731+ "aom_codec_enc_init() failed: %s: %s" ,
732+ aom_codec_error (& codec -> internal -> encoder ),
733+ aom_codec_error_detail (& codec -> internal -> encoder ));
734+ return AVIF_RESULT_UNKNOWN_ERROR ;
735+ }
736+ codec -> internal -> encoderInitialized = AVIF_TRUE ;
737+ } else {
738+ if (aom_codec_enc_config_set (& codec -> internal -> encoder , cfg ) != AOM_CODEC_OK ) {
739+ avifDiagnosticsPrintf (codec -> diag ,
740+ "aom_codec_enc_config_set() failed: %s: %s" ,
741+ aom_codec_error (& codec -> internal -> encoder ),
742+ aom_codec_error_detail (& codec -> internal -> encoder ));
743+ return AVIF_RESULT_UNKNOWN_ERROR ;
744+ }
727745 }
728- codec -> internal -> encoderInitialized = AVIF_TRUE ;
729746
730747 if (lossless ) {
731748 aom_codec_control (& codec -> internal -> encoder , AV1E_SET_LOSSLESS , 1 );
@@ -756,8 +773,8 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
756773 // set the min and max quantizers in the avifEncoder struct. If this is the case, set
757774 // cq-level to a reasonable value for the user, otherwise the default cq-level
758775 // (currently 10) will be unknowingly used.
759- assert (cfg . rc_end_usage == AOM_Q );
760- unsigned int cqLevel = (cfg . rc_min_quantizer + cfg . rc_max_quantizer ) / 2 ;
776+ assert (cfg -> rc_end_usage == AOM_Q );
777+ unsigned int cqLevel = (cfg -> rc_min_quantizer + cfg -> rc_max_quantizer ) / 2 ;
761778 aom_codec_control (& codec -> internal -> encoder , AOME_SET_CQ_LEVEL , cqLevel );
762779 }
763780#endif
0 commit comments