Added avifCodecVersions() for getting version strings of internal AV1 codecs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46322b0..879cf38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
 ## [Unreleased]
 ### Added
 - Added `containerDepth` to avifDecoder for surfacing 10bpc/12bpc flags from av1C boxes, if present
+- Added `avifCodecVersions()` for getting version strings of internal AV1 codecs
 
 ### Changed
 - Fixed warning with CHECK macro (additional semicolon)
diff --git a/include/avif/avif.h b/include/avif/avif.h
index 73e71ec..8b946a8 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -56,6 +56,7 @@
 // Version
 
 const char * avifVersion(void);
+void avifCodecVersions(char outBuffer[256]);
 
 // ---------------------------------------------------------------------------
 // Memory management
diff --git a/include/avif/internal.h b/include/avif/internal.h
index adbc554..846a91d 100644
--- a/include/avif/internal.h
+++ b/include/avif/internal.h
@@ -145,8 +145,10 @@
     avifCodecDestroyInternalFunc destroyInternal;
 } avifCodec;
 
-avifCodec * avifCodecCreateAOM(void);   // requires AVIF_CODEC_AOM
-avifCodec * avifCodecCreateDav1d(void); // requires AVIF_CODEC_DAV1D
+const char * avifCodecVersionAOM(void);   // requires AVIF_CODEC_AOM
+avifCodec * avifCodecCreateAOM(void);     // requires AVIF_CODEC_AOM
+const char * avifCodecVersionDav1d(void); // requires AVIF_CODEC_DAV1D
+avifCodec * avifCodecCreateDav1d(void);   // requires AVIF_CODEC_DAV1D
 void avifCodecDestroy(avifCodec * codec);
 
 // ---------------------------------------------------------------------------
diff --git a/src/avif.c b/src/avif.c
index bd9e8db..7aa0255 100644
--- a/src/avif.c
+++ b/src/avif.c
@@ -14,6 +14,53 @@
     return AVIF_VERSION_STRING;
 }
 
+void avifCodecVersions(char outBuffer[256])
+{
+    const char * encodeCodec = NULL;
+    const char * encodeVersion = NULL;
+    const char * decodeCodec = NULL;
+    const char * decodeVersion = NULL;
+
+#if defined(AVIF_CODEC_AOM)
+    encodeCodec = "aom";
+    encodeVersion = avifCodecVersionAOM();
+    decodeCodec = encodeCodec;
+    decodeVersion = encodeVersion;
+#endif
+#if defined(AVIF_CODEC_DAV1D)
+    decodeCodec = "dav1d";
+    decodeVersion = avifCodecVersionDav1d();
+#endif
+
+    if (decodeCodec == NULL) {
+        strcpy(outBuffer, "encode/decode: none");
+    } else if (encodeCodec == decodeCodec) {
+        strcpy(outBuffer, "encode/decode: ");
+        strcat(outBuffer, decodeCodec);
+        strcat(outBuffer, " ");
+        strcat(outBuffer, decodeVersion);
+    } else {
+        outBuffer[0] = 0;
+        if (encodeCodec) {
+            strcat(outBuffer, "encode: ");
+            strcat(outBuffer, encodeCodec);
+            strcat(outBuffer, " ");
+            strcat(outBuffer, encodeVersion);
+        } else {
+            strcat(outBuffer, "encode: none");
+        }
+        strcat(outBuffer, ", ");
+        if (decodeCodec) {
+            strcat(outBuffer, "decode: ");
+            strcat(outBuffer, decodeCodec);
+            strcat(outBuffer, " ");
+            strcat(outBuffer, decodeVersion);
+        } else {
+            strcat(outBuffer, "decode: none");
+        }
+    }
+}
+
 const char * avifPixelFormatToString(avifPixelFormat format)
 {
     switch (format) {
diff --git a/src/codec_aom.c b/src/codec_aom.c
index 166d61c..b2d29a1 100644
--- a/src/codec_aom.c
+++ b/src/codec_aom.c
@@ -27,6 +27,11 @@
 
 #include <string.h>
 
+const char * avifCodecVersionAOM(void)
+{
+    return aom_codec_version_str();
+}
+
 struct avifCodecInternal
 {
     avifBool decoderInitialized;
diff --git a/src/codec_dav1d.c b/src/codec_dav1d.c
index 273c1aa..57fbdcf 100644
--- a/src/codec_dav1d.c
+++ b/src/codec_dav1d.c
@@ -12,6 +12,11 @@
 #define DAV1D_ERR(e) (-(e))
 #endif
 
+const char * avifCodecVersionDav1d(void)
+{
+    return dav1d_version();
+}
+
 struct avifCodecInternal
 {
     Dav1dSettings dav1dSettings;