avifEncoder now has a speed setting, codec_aom only flushes encoder when necessary (avoids lost frame packets), minor cleanup
diff --git a/src/codec_aom.c b/src/codec_aom.c
index fee504f..790f57f 100644
--- a/src/codec_aom.c
+++ b/src/codec_aom.c
@@ -234,6 +234,30 @@
     aom_codec_iface_t * encoder_interface = aom_codec_av1_cx();
     aom_codec_ctx_t aomEncoder;
 
+    // Map encoder speed to AOM usage + CpuUsed:
+    // Speed  0: GoodQuality CpuUsed 0
+    // Speed  1: GoodQuality CpuUsed 1
+    // Speed  2: GoodQuality CpuUsed 2
+    // Speed  3: GoodQuality CpuUsed 3
+    // Speed  4: GoodQuality CpuUsed 4
+    // Speed  5: GoodQuality CpuUsed 5
+    // Speed  6: RealTime    CpuUsed 4
+    // Speed  7: RealTime    CpuUsed 5
+    // Speed  8: RealTime    CpuUsed 6
+    // Speed  9: RealTime    CpuUsed 7
+    // Speed 10: RealTime    CpuUsed 8
+    unsigned int aomUsage = AOM_USAGE_GOOD_QUALITY;
+    int aomCpuUsed = -1;
+    if (encoder->speed != AVIF_SPEED_DEFAULT) {
+        if (encoder->speed < 6) {
+            aomUsage = AOM_USAGE_GOOD_QUALITY;
+            aomCpuUsed = AVIF_CLAMP(encoder->speed, 0, 5);
+        } else {
+            aomUsage = AOM_USAGE_REALTIME;
+            aomCpuUsed = AVIF_CLAMP(encoder->speed - 2, 4, 8);
+        }
+    }
+
     int yShift = 0;
     aom_img_fmt_t aomFormat = avifImageCalcAOMFmt(image, alpha, &yShift);
     if (aomFormat == AOM_IMG_FMT_NONE) {
@@ -244,7 +268,7 @@
     avifGetPixelFormatInfo(image->yuvFormat, &formatInfo);
 
     struct aom_codec_enc_cfg cfg;
-    aom_codec_enc_config_default(encoder_interface, &cfg, 0);
+    aom_codec_enc_config_default(encoder_interface, &cfg, aomUsage);
 
     cfg.g_profile = codec->configBox.seqProfile;
     cfg.g_bit_depth = image->depth;
@@ -287,6 +311,9 @@
         int tileColsLog2 = AVIF_CLAMP(encoder->tileColsLog2, 0, 6);
         aom_codec_control(&aomEncoder, AV1E_SET_TILE_COLUMNS, tileColsLog2);
     }
+    if (aomCpuUsed != -1) {
+        aom_codec_control(&aomEncoder, AOME_SET_CPUUSED, aomCpuUsed);
+    }
 
     uint32_t uvHeight = image->height >> yShift;
     aom_image_t * aomImage = aom_img_alloc(NULL, aomFormat, image->width, image->height, 16);
@@ -338,13 +365,19 @@
     }
 
     aom_codec_encode(&aomEncoder, aomImage, 0, 1, 0);
-    aom_codec_encode(&aomEncoder, NULL, 0, 1, 0); // flush
 
+    avifBool flushed = AVIF_FALSE;
     aom_codec_iter_t iter = NULL;
     for (;;) {
         const aom_codec_cx_pkt_t * pkt = aom_codec_get_cx_data(&aomEncoder, &iter);
-        if (pkt == NULL)
-            break;
+        if (pkt == NULL) {
+            if (flushed)
+                break;
+
+            aom_codec_encode(&aomEncoder, NULL, 0, 1, 0); // flush
+            flushed = AVIF_TRUE;
+            continue;
+        }
         if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
             avifRWDataSet(obu, pkt->data.frame.buf, pkt->data.frame.sz);
             success = AVIF_TRUE;
diff --git a/src/codec_rav1e.c b/src/codec_rav1e.c
index 920fbc2..adaa2e5 100644
--- a/src/codec_rav1e.c
+++ b/src/codec_rav1e.c
@@ -91,7 +91,6 @@
     if (rav1e_config_parse_int(rav1eConfig, "quantizer", maxQuantizer) == -1) {
         goto cleanup;
     }
-
     if (encoder->tileRowsLog2 != 0) {
         int tileRowsLog2 = AVIF_CLAMP(encoder->tileRowsLog2, 0, 6);
         if (rav1e_config_parse_int(rav1eConfig, "tile_rows", 1 << tileRowsLog2) == -1) {
@@ -104,6 +103,12 @@
             goto cleanup;
         }
     }
+    if (encoder->speed != AVIF_SPEED_DEFAULT) {
+        int speed = AVIF_CLAMP(encoder->speed, 0, 10);
+        if (rav1e_config_parse_int(rav1eConfig, "speed", speed) == -1) {
+            goto cleanup;
+        }
+    }
 
     if (image->profileFormat == AVIF_PROFILE_FORMAT_NCLX) {
         rav1e_config_set_color_description(rav1eConfig,
diff --git a/src/write.c b/src/write.c
index b9c6447..35a11ce 100644
--- a/src/write.c
+++ b/src/write.c
@@ -31,6 +31,9 @@
     encoder->maxThreads = 1;
     encoder->minQuantizer = AVIF_QUANTIZER_LOSSLESS;
     encoder->maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
+    encoder->tileRowsLog2 = 0;
+    encoder->tileColsLog2 = 0;
+    encoder->speed = AVIF_SPEED_DEFAULT;
     return encoder;
 }
 
@@ -106,11 +109,6 @@
     // -----------------------------------------------------------------------
     // Encode AV1 OBUs
 
-    // avifRWData * alphaOBUPtr = &alphaOBU;
-    // if (avifImageIsOpaque(image)) {
-    //     alphaOBUPtr = NULL;
-    // }
-
     if (!codec[AVIF_CODEC_PLANES_COLOR]->encodeImage(codec[AVIF_CODEC_PLANES_COLOR], image, encoder, &colorOBU, AVIF_FALSE)) {
         result = AVIF_RESULT_ENCODE_COLOR_FAILED;
         goto writeCleanup;