Use global configs for keyframe interval

Instead of computing the required keyframe interval in libavif
code and passing the "force keyframe" flag on individual frames,
use each encoder's global configuration parameter to set the
maximum keyframe interval.

For libaom: `kf_max_dist`.
For rav1e: `key_frame_interval`.
For svt-av1: `intra_period_length` and `force_key_frames`.

Here's the output obtained from various encoders for encoding an
animated file with 10 frames with different values for
--keyframe. Each line is read as follows:
--keyframe value: list of key frames before => list of keyframes after.

aom:
 --keyframe 0: same before and after.
 --keyframe 1: same before and after.
 --keyframe 2: 1,2,3,4,5,6,7,8,9,10 => 1,3,5,7,9 (the old behavior was not incorrect, but new one is exact).
 --keyframe 5: 1,2,6,7 =>1,6 (the old behavior was not incorrect, but new one is exact).

rav1e:
  * no changes. same output before and after.

svt-av1:
 --keyframe 0: same before and after.
 --keyframe 1: 1 => 1,2,3,4,5,6,7,8,9,10 (old behavior was incorrect).
 --keyframe 2: 1 => 1,3,5,7,9 (old behavior was incorrect).
 --keyframe 5: 1 => 1,6 (old behavior was incorrect).

To sum up:
 * svt-av1 was not producing the intended output with --keyframe
   before this change.
 * libaom had some weirdness in keyframe spacing when using the
   force keyframe flag on each frame and that weirdness goes away
   when using the kf_max_dist configuration (see:
   https://bugs.chromium.org/p/aomedia/issues/detail?id=3445).

The `AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME` flag is retained in the
codebase since there are some follow-up changes that will make
use of the flag to synchronize keyframe placement between the
color and alpha plane encoders (Issue #841).
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3688d14..40d9311 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@
 * Check the return value of avifEncoderSetCodecSpecificOption().
 * The maxThreads member was added to the avifRGBImage struct.
 * Check the return value of avifRGBImageAllocatePixels().
+* The meaning of the keyframeInterval member of avifEncoder struct has changed
+  slightly. When set to a value of "n",
+    * Before: It forces a keyframe on every nth frame.
+    * After: Any set of "n" consecutive frame will have atleast one keyframe (every nth frame may or may not be a keyframe).
 
 ### Added
 * Add STATIC library target avif_internal to allow tests to access functions
diff --git a/apps/avifenc.c b/apps/avifenc.c
index 9d06223..7586ba1 100644
--- a/apps/avifenc.c
+++ b/apps/avifenc.c
@@ -111,7 +111,7 @@
     printf("    --duration D                      : Set all following frame durations (in timescales) to D; default 1. Can be set multiple times (before supplying each filename)\n");
     printf("    --timescale,--fps V               : Set the timescale to V. If all frames are 1 timescale in length, this is equivalent to frames per second (Default: 30)\n");
     printf("                                        If neither duration nor timescale are set, avifenc will attempt to use the framerate stored in a y4m header, if present.\n");
-    printf("    -k,--keyframe INTERVAL            : Set the forced keyframe interval (maximum frames between keyframes). Set to 0 to disable (default).\n");
+    printf("    -k,--keyframe INTERVAL            : Set the keyframe interval (Aany set of INTERVAL consecutive frames will have at least one keyframe). Set to 0 to disable (default).\n");
     printf("    --ignore-exif                     : If the input file contains embedded Exif metadata, ignore it (no-op if absent)\n");
     printf("    --ignore-xmp                      : If the input file contains embedded XMP metadata, ignore it (no-op if absent)\n");
     printf("    --ignore-icc                      : If the input file contains an embedded ICC profile, ignore it (no-op if absent)\n");
diff --git a/include/avif/avif.h b/include/avif/avif.h
index 6e86aa2..c610528 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -1138,7 +1138,8 @@
     // settings (see Notes above)
     int maxThreads;
     int speed;
-    int keyframeInterval;     // How many frames between automatic forced keyframes; 0 to disable (default).
+    int keyframeInterval;     // Any set of |keyframeInterval| consecutive frames will have at least one keyframe. When it is 0,
+                              // there is no such restriction.
     uint64_t timescale;       // timescale of the media (Hz)
     int repetitionCount;      // Number of times the image sequence should be repeated. This can also be set to
                               // AVIF_REPETITION_COUNT_INFINITE for infinite repetitions.  Only applicable for image sequences.
diff --git a/src/codec_aom.c b/src/codec_aom.c
index 26b780a..6c7cbcb 100644
--- a/src/codec_aom.c
+++ b/src/codec_aom.c
@@ -705,6 +705,10 @@
             cfg->kf_mode = AOM_KF_DISABLED;
             // Tell libaom that all frames will be key frames.
             cfg->kf_max_dist = 0;
+        } else {
+            if (encoder->keyframeInterval > 0) {
+                cfg->kf_max_dist = encoder->keyframeInterval;
+            }
         }
         if (encoder->extraLayerCount > 0) {
             cfg->g_limit = encoder->extraLayerCount + 1;
diff --git a/src/codec_rav1e.c b/src/codec_rav1e.c
index 534dd5d..febce2d 100644
--- a/src/codec_rav1e.c
+++ b/src/codec_rav1e.c
@@ -172,6 +172,12 @@
                 goto cleanup;
             }
         }
+        if (encoder->keyframeInterval > 0) {
+            // "key_frame_interval" is the maximum interval between two keyframes.
+            if (rav1e_config_parse_int(rav1eConfig, "key_frame_interval", encoder->keyframeInterval) == -1) {
+                goto cleanup;
+            }
+        }
 
         rav1e_config_set_color_description(rav1eConfig,
                                            (RaMatrixCoefficients)image->matrixCoefficients,
diff --git a/src/codec_svt.c b/src/codec_svt.c
index 4e13450..f0e8aa1 100644
--- a/src/codec_svt.c
+++ b/src/codec_svt.c
@@ -161,6 +161,18 @@
             svt_config->profile = HIGH_PROFILE;
         }
 
+        // In order for SVT-AV1 to force keyframes by setting pic_type to
+        // EB_AV1_KEY_PICTURE on any frame, force_key_frames has to be set.
+        svt_config->force_key_frames = TRUE;
+
+        // keyframeInterval == 1 case is handled when encoding each frame by
+        // setting pic_type to EB_AV1_KEY_PICTURE. For keyframeInterval > 1,
+        // set the intra_period_length. Eventhough setting intra_period_length
+        // to 0 should work in this case, it does not.
+        if (encoder->keyframeInterval > 1) {
+            svt_config->intra_period_length = encoder->keyframeInterval - 1;
+        }
+
         res = svt_av1_enc_set_parameter(codec->internal->svt_encoder, svt_config);
         if (res == EB_ErrorBadParameter) {
             goto cleanup;
@@ -199,7 +211,7 @@
     input_buffer->pts = 0;
 
     EbAv1PictureType frame_type = EB_AV1_INVALID_PICTURE;
-    if (addImageFlags & AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME) {
+    if ((addImageFlags & AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME) || (encoder->keyframeInterval == 1)) {
         frame_type = EB_AV1_KEY_PICTURE;
     }
     input_buffer->pic_type = frame_type;
diff --git a/src/write.c b/src/write.c
index cb053e4..2ba6251 100644
--- a/src/write.c
+++ b/src/write.c
@@ -1209,10 +1209,6 @@
     // -----------------------------------------------------------------------
     // Encode AV1 OBUs
 
-    if (encoder->keyframeInterval && ((encoder->data->frames.count % encoder->keyframeInterval) == 0)) {
-        addImageFlags |= AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME;
-    }
-
     for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
         avifEncoderItem * item = &encoder->data->items.item[itemIndex];
         if (item->codec) {