Eliminate the libYUVUsage enum, and simply document when libyuv fast paths will / will not be exercised
diff --git a/apps/avifdec.c b/apps/avifdec.c
index efe31e0..4f1c362 100644
--- a/apps/avifdec.c
+++ b/apps/avifdec.c
@@ -94,7 +94,6 @@
     avifBool infoOnly = AVIF_FALSE;
     avifChromaUpsampling chromaUpsampling = AVIF_CHROMA_UPSAMPLING_AUTOMATIC;
     avifBool ignoreICC = AVIF_FALSE;
-    avifLibYUVUsage libYUVUsage = AVIF_LIBYUV_USAGE_DISABLED; // Use built-in paths by default for consistency and control over subsampling
 
     if (argc < 2) {
         syntax();
@@ -152,8 +151,6 @@
             infoOnly = AVIF_TRUE;
         } else if (!strcmp(arg, "--ignore-icc")) {
             ignoreICC = AVIF_TRUE;
-        } else if (!strcmp(arg, "--libyuv")) {
-            libYUVUsage = AVIF_LIBYUV_USAGE_AUTOMATIC;
         } else {
             // Positional argument
             if (!inputFilename) {
@@ -214,11 +211,11 @@
                 returnCode = 1;
             }
         } else if (outputFormat == AVIF_APP_FILE_FORMAT_JPEG) {
-            if (!avifJPEGWrite(avif, outputFilename, jpegQuality, chromaUpsampling, libYUVUsage)) {
+            if (!avifJPEGWrite(avif, outputFilename, jpegQuality, chromaUpsampling)) {
                 returnCode = 1;
             }
         } else if (outputFormat == AVIF_APP_FILE_FORMAT_PNG) {
-            if (!avifPNGWrite(avif, outputFilename, requestedDepth, chromaUpsampling, libYUVUsage)) {
+            if (!avifPNGWrite(avif, outputFilename, requestedDepth, chromaUpsampling)) {
                 returnCode = 1;
             }
         } else {
diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c
index 3f13da1..e3719a8 100644
--- a/apps/shared/avifjpeg.c
+++ b/apps/shared/avifjpeg.c
@@ -111,7 +111,7 @@
     return ret;
 }
 
-avifBool avifJPEGWrite(avifImage * avif, const char * outputFilename, int jpegQuality, avifChromaUpsampling chromaUpsampling, avifLibYUVUsage libYUVUsage)
+avifBool avifJPEGWrite(avifImage * avif, const char * outputFilename, int jpegQuality, avifChromaUpsampling chromaUpsampling)
 {
     avifBool ret = AVIF_FALSE;
     FILE * f = NULL;
@@ -126,7 +126,6 @@
     avifRGBImageSetDefaults(&rgb, avif);
     rgb.format = AVIF_RGB_FORMAT_RGB;
     rgb.chromaUpsampling = chromaUpsampling;
-    rgb.libYUVUsage = libYUVUsage;
     rgb.depth = 8;
     avifRGBImageAllocatePixels(&rgb);
     if (avifImageYUVToRGB(avif, &rgb) != AVIF_RESULT_OK) {
diff --git a/apps/shared/avifjpeg.h b/apps/shared/avifjpeg.h
index 8b41e82..4eefa90 100644
--- a/apps/shared/avifjpeg.h
+++ b/apps/shared/avifjpeg.h
@@ -7,6 +7,6 @@
 #include "avif/avif.h"
 
 avifBool avifJPEGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth);
-avifBool avifJPEGWrite(avifImage * avif, const char * outputFilename, int jpegQuality, avifChromaUpsampling chromaUpsampling, avifLibYUVUsage libYUVUsage);
+avifBool avifJPEGWrite(avifImage * avif, const char * outputFilename, int jpegQuality, avifChromaUpsampling chromaUpsampling);
 
 #endif // ifndef LIBAVIF_APPS_SHARED_AVIFJPEG_H
diff --git a/apps/shared/avifpng.c b/apps/shared/avifpng.c
index ae7ecbd..9cb1113 100644
--- a/apps/shared/avifpng.c
+++ b/apps/shared/avifpng.c
@@ -155,7 +155,7 @@
     return readResult;
 }
 
-avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, uint32_t requestedDepth, avifChromaUpsampling chromaUpsampling, avifLibYUVUsage libYUVUsage)
+avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, uint32_t requestedDepth, avifChromaUpsampling chromaUpsampling)
 {
     volatile avifBool writeResult = AVIF_FALSE;
     png_structp png = NULL;
@@ -178,7 +178,6 @@
     avifRGBImageSetDefaults(&rgb, avif);
     rgb.depth = rgbDepth;
     rgb.chromaUpsampling = chromaUpsampling;
-    rgb.libYUVUsage = libYUVUsage;
     avifRGBImageAllocatePixels(&rgb);
     if (avifImageYUVToRGB(avif, &rgb) != AVIF_RESULT_OK) {
         fprintf(stderr, "Conversion to RGB failed: %s\n", outputFilename);
diff --git a/apps/shared/avifpng.h b/apps/shared/avifpng.h
index 246d6c2..38f87e0 100644
--- a/apps/shared/avifpng.h
+++ b/apps/shared/avifpng.h
@@ -8,10 +8,6 @@
 
 // if (requestedDepth == 0), do best-fit
 avifBool avifPNGRead(avifImage * avif, const char * inputFilename, avifPixelFormat requestedFormat, uint32_t requestedDepth, uint32_t * outPNGDepth);
-avifBool avifPNGWrite(avifImage * avif,
-                      const char * outputFilename,
-                      uint32_t requestedDepth,
-                      avifChromaUpsampling chromaUpsampling,
-                      avifLibYUVUsage libYUVUsage);
+avifBool avifPNGWrite(avifImage * avif, const char * outputFilename, uint32_t requestedDepth, avifChromaUpsampling chromaUpsampling);
 
 #endif // ifndef LIBAVIF_APPS_SHARED_AVIFPNG_H
diff --git a/include/avif/avif.h b/include/avif/avif.h
index 35ca8e2..a2aca7a 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -379,6 +379,19 @@
 // conversion, if necessary. Pixels in an avifRGBImage buffer are always full range, and conversion
 // routines will fail if the width and height don't match the associated avifImage.
 
+// If libavif is built with libyuv fast paths enabled, libavif will use libyuv for conversion from
+// YUV to RGB if the following requirements are met:
+//
+// * YUV depth: 8
+// * RGB depth: 8
+// * rgb.chromaUpsampling: AVIF_CHROMA_UPSAMPLING_AUTOMATIC (and upsampling is required: 420/422)
+// * rgb.format: AVIF_RGB_FORMAT_RGBA, AVIF_RGB_FORMAT_BGRA (420/422 support for AVIF_RGB_FORMAT_ABGR, AVIF_RGB_FORMAT_ARGB)
+// * CICP is one of the following combinations (CP/TC/MC/Range):
+//   * x/x/[2|5|6]/Full
+//   * [5|6]/x/12/Full
+//   * x/x/[1|2|5|6|9]/Limited
+//   * [1|2|5|6|9]/x/12/Limited
+
 typedef enum avifRGBFormat
 {
     AVIF_RGB_FORMAT_RGB = 0,
@@ -393,18 +406,11 @@
 
 typedef enum avifChromaUpsampling
 {
-    AVIF_CHROMA_UPSAMPLING_AUTOMATIC = 0, // Chooses the best quality upsampling given the settings (currently bilinear always)
+    AVIF_CHROMA_UPSAMPLING_AUTOMATIC = 0, // Chooses the best quality upsampling (given the settings)
     AVIF_CHROMA_UPSAMPLING_NEAREST = 1,   // Faster and uglier
     AVIF_CHROMA_UPSAMPLING_BILINEAR = 2   // Slower and prettier
 } avifChromaUpsampling;
 
-typedef enum avifLibYUVUsage
-{
-    AVIF_LIBYUV_USAGE_AUTOMATIC = 0, // Use libyuv if compiled-in and possible with the current settings (default)
-    AVIF_LIBYUV_USAGE_DISABLED,      // Avoid libyuv conversion, even if it is available
-    AVIF_LIBYUV_USAGE_REQUIRED       // If libyuv is unavailable or if the current combination cannot use it, fail
-} avifLibYUVUsage;
-
 typedef struct avifRGBImage
 {
     uint32_t width;                        // must match associated avifImage
@@ -416,9 +422,6 @@
     avifBool ignoreAlpha; // Used for XRGB formats, treats formats containing alpha (such as ARGB) as if they were
                           // RGB, treating the alpha bits as if they were all 1.
 
-    avifLibYUVUsage libYUVUsage; // Defaults to "automatic", but can be forced on or off for easy testing,
-                                 // or avoiding unexpected (slower) YUV paths.
-
     uint8_t * pixels;
     uint32_t rowBytes;
 } avifRGBImage;
diff --git a/src/avif.c b/src/avif.c
index 08ae313..f8efe91 100644
--- a/src/avif.c
+++ b/src/avif.c
@@ -356,7 +356,6 @@
     rgb->format = AVIF_RGB_FORMAT_RGBA;
     rgb->chromaUpsampling = AVIF_CHROMA_UPSAMPLING_AUTOMATIC;
     rgb->ignoreAlpha = AVIF_FALSE;
-    rgb->libYUVUsage = AVIF_LIBYUV_USAGE_AUTOMATIC;
     rgb->pixels = NULL;
     rgb->rowBytes = 0;
 }
diff --git a/src/reformat.c b/src/reformat.c
index 2eba3a5..795ad9f 100644
--- a/src/reformat.c
+++ b/src/reformat.c
@@ -957,18 +957,12 @@
     }
 
     avifBool convertedWithLibYUV = AVIF_FALSE;
-    if (rgb->libYUVUsage != AVIF_LIBYUV_USAGE_DISABLED) {
-        avifResult libyuvResult = avifImageYUVToRGBLibYUV(image, rgb);
-        if (libyuvResult == AVIF_RESULT_OK) {
-            convertedWithLibYUV = AVIF_TRUE;
-        } else {
-            if (libyuvResult != AVIF_RESULT_NO_CONTENT) {
-                return libyuvResult;
-            }
-            if (rgb->libYUVUsage == AVIF_LIBYUV_USAGE_REQUIRED) {
-                // libyuv was required, and the current combination couldn't be done with libyuv
-                return AVIF_RESULT_REFORMAT_FAILED;
-            }
+    avifResult libyuvResult = avifImageYUVToRGBLibYUV(image, rgb);
+    if (libyuvResult == AVIF_RESULT_OK) {
+        convertedWithLibYUV = AVIF_TRUE;
+    } else {
+        if (libyuvResult != AVIF_RESULT_NO_CONTENT) {
+            return libyuvResult;
         }
     }
 
diff --git a/src/reformat_libyuv.c b/src/reformat_libyuv.c
index e8b94a1..6fa5291 100644
--- a/src/reformat_libyuv.c
+++ b/src/reformat_libyuv.c
@@ -36,6 +36,13 @@
         return AVIF_RESULT_NO_CONTENT;
     }
 
+    if ((image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420) || (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV422)) {
+        if (rgb->chromaUpsampling != AVIF_CHROMA_UPSAMPLING_AUTOMATIC) {
+            // libyuv uses its own upsampling filter. If the enduser chose a specific one, avoid using libyuv.
+            return AVIF_RESULT_NO_CONTENT;
+        }
+    }
+
     // Find the correct libyuv YuvConstants, based on range and CP/MC
     const struct YuvConstants * matrixYUV = NULL;
     const struct YuvConstants * matrixYVU = NULL;
@@ -51,11 +58,11 @@
                 switch (image->colorPrimaries) {
                     case AVIF_COLOR_PRIMARIES_BT470BG:
                     case AVIF_COLOR_PRIMARIES_BT601:
-                    case AVIF_COLOR_PRIMARIES_UNSPECIFIED:
                         matrixYUV = &kYuvJPEGConstants;
                         matrixYVU = &kYvuJPEGConstants;
                         break;
 
+                    case AVIF_COLOR_PRIMARIES_UNSPECIFIED:
                     case AVIF_COLOR_PRIMARIES_UNKNOWN:
                     case AVIF_COLOR_PRIMARIES_BT709:
                     case AVIF_COLOR_PRIMARIES_BT470M:
@@ -101,12 +108,12 @@
             case AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL:
                 switch (image->colorPrimaries) {
                     case AVIF_COLOR_PRIMARIES_BT709:
+                    case AVIF_COLOR_PRIMARIES_UNSPECIFIED:
                         matrixYUV = &kYuvH709Constants;
                         matrixYVU = &kYvuH709Constants;
                         break;
                     case AVIF_COLOR_PRIMARIES_BT470BG:
                     case AVIF_COLOR_PRIMARIES_BT601:
-                    case AVIF_COLOR_PRIMARIES_UNSPECIFIED:
                         matrixYUV = &kYuvI601Constants;
                         matrixYVU = &kYvuI601Constants;
                         break;