diff --git a/girs/GstPbutils-1.0.gir b/girs/GstPbutils-1.0.gir
index 312faed9df..61b5f4a26c 100644
--- a/girs/GstPbutils-1.0.gir
+++ b/girs/GstPbutils-1.0.gir
@@ -3147,6 +3147,34 @@ rate.</doc>
         </parameter>
       </parameters>
     </function>
+    <function name="codec_utils_av1_get_level" c:identifier="gst_codec_utils_av1_get_level" version="1.26">
+      <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">Transform a seq_level_idx into the level string</doc>
+      <source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.h"/>
+      <return-value transfer-ownership="none" nullable="1">
+        <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">the level string or %NULL if the seq_level_idx is unknown</doc>
+        <type name="utf8" c:type="const gchar*"/>
+      </return-value>
+      <parameters>
+        <parameter name="seq_level_idx" transfer-ownership="none">
+          <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">A seq_level_idx</doc>
+          <type name="guint8" c:type="guint8"/>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="codec_utils_av1_get_seq_level_idx" c:identifier="gst_codec_utils_av1_get_seq_level_idx" version="1.26">
+      <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">Transform a level string from the caps into the seq_level_idx</doc>
+      <source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.h"/>
+      <return-value transfer-ownership="none">
+        <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">the seq_level_idx or 31 (max-level) if the level is unknown</doc>
+        <type name="guint8" c:type="guint8"/>
+      </return-value>
+      <parameters>
+        <parameter name="level" transfer-ownership="none">
+          <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">A level string from caps</doc>
+          <type name="utf8" c:type="const gchar*"/>
+        </parameter>
+      </parameters>
+    </function>
     <function name="codec_utils_caps_from_mime_codec" c:identifier="gst_codec_utils_caps_from_mime_codec" version="1.22">
       <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c">Converts a RFC 6381 compatible codec string to #GstCaps. More than one codec
 string can be present (separated by `,`).
diff --git a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c
index 71d918034d..e62d9eb31c 100644
--- a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c
+++ b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.c
@@ -41,6 +41,7 @@
 #include <gst/base/gstbitreader.h>
 #include <gst/tag/tag.h>
 
+#include <stdio.h>
 #include <string.h>
 
 #ifndef GST_DISABLE_GST_DEBUG
@@ -1543,6 +1544,142 @@ gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
   return (level != NULL && tier != NULL && profile != NULL);
 }
 
+/**
+ * gst_codec_utils_av1_get_seq_level_idx:
+ * @level: A level string from caps
+ *
+ * Transform a level string from the caps into the seq_level_idx
+ *
+ * Returns: the seq_level_idx or 31 (max-level) if the level is unknown
+ *
+ * Since: 1.26
+ */
+guint8
+gst_codec_utils_av1_get_seq_level_idx (const gchar * level)
+{
+  g_return_val_if_fail (level != NULL, 0);
+
+  if (!strcmp (level, "2.0"))
+    return 0;
+  else if (!strcmp (level, "2.1"))
+    return 1;
+  else if (!strcmp (level, "2.2"))
+    return 2;
+  else if (!strcmp (level, "2.3"))
+    return 3;
+  else if (!strcmp (level, "3.0"))
+    return 4;
+  else if (!strcmp (level, "3.1"))
+    return 5;
+  else if (!strcmp (level, "3.2"))
+    return 6;
+  else if (!strcmp (level, "3.3"))
+    return 7;
+  else if (!strcmp (level, "4.0"))
+    return 8;
+  else if (!strcmp (level, "4.1"))
+    return 9;
+  else if (!strcmp (level, "4.2"))
+    return 10;
+  else if (!strcmp (level, "4.3"))
+    return 11;
+  else if (!strcmp (level, "5.0"))
+    return 12;
+  else if (!strcmp (level, "5.1"))
+    return 13;
+  else if (!strcmp (level, "5.2"))
+    return 14;
+  else if (!strcmp (level, "5.3"))
+    return 15;
+  else if (!strcmp (level, "6.0"))
+    return 16;
+  else if (!strcmp (level, "6.1"))
+    return 17;
+  else if (!strcmp (level, "6.2"))
+    return 18;
+  else if (!strcmp (level, "6.3"))
+    return 19;
+  else if (!strcmp (level, "7.0"))
+    return 20;
+  else if (!strcmp (level, "7.1"))
+    return 21;
+  else if (!strcmp (level, "7.2"))
+    return 22;
+  else if (!strcmp (level, "7.3"))
+    return 23;
+
+  GST_WARNING ("Invalid level %s", level);
+  return 31;
+}
+
+/**
+ * gst_codec_utils_av1_get_level:
+ * @seq_level_idx: A seq_level_idx
+ *
+ * Transform a seq_level_idx into the level string
+ *
+ * Returns: (nullable): the level string or %NULL if the seq_level_idx is unknown
+ *
+ * Since: 1.26
+ */
+const gchar *
+gst_codec_utils_av1_get_level (guint8 seq_level_idx)
+{
+  switch (seq_level_idx) {
+    case 0:
+      return "2.0";
+    case 1:
+      return "2.1";
+    case 2:
+      return "2.2";
+    case 3:
+      return "2.3";
+    case 4:
+      return "3.0";
+    case 5:
+      return "3.1";
+    case 6:
+      return "3.2";
+    case 7:
+      return "3.3";
+    case 8:
+      return "4.0";
+    case 9:
+      return "4.1";
+    case 10:
+      return "4.2";
+    case 11:
+      return "4.3";
+    case 12:
+      return "5.0";
+    case 13:
+      return "5.1";
+    case 14:
+      return "5.2";
+    case 15:
+      return "5.3";
+    case 16:
+      return "6.0";
+    case 17:
+      return "6.1";
+    case 18:
+      return "6.2";
+    case 19:
+      return "6.3";
+    case 20:
+      return "7.0";
+    case 21:
+      return "7.1";
+    case 22:
+      return "7.2";
+    case 23:
+      return "7.3";
+    default:
+      return NULL;
+  }
+}
+
+
 /**
  * gst_codec_utils_mpeg4video_get_profile:
  * @vis_obj_seq: (array length=len): Pointer to the visual object
@@ -2555,6 +2692,256 @@ done:
   return g_string_free (codec_string, FALSE);
 }
 
+static GstCaps *
+av1_caps_from_mime_codec (gchar ** subcodec)
+{
+  GstCaps *caps = NULL;
+  gchar tier;
+  guint seq_level_idx_0;
+  guint bit_depth, seq_profile, chroma_sample_position,
+      monochrome, chroma_subsampling_x, chroma_subsampling_y, primaries,
+      transfer, matrix, full_range, chroma_sampling;
+  const gchar *level_str;
+  const gchar *tier_str;
+  const gchar *profile_str;
+  const gchar *chroma_format_str;
+  gchar *colorimetry_str;
+  GstVideoColorimetry cinfo = { 0, };
+
+  caps = gst_caps_new_empty_simple ("video/x-av1");
+
+  if (!subcodec[1])
+    goto done;
+
+  seq_profile = g_ascii_strtoull (subcodec[1], NULL, 10);
+  if (seq_profile == 0) {
+    profile_str = "main";
+  } else if (seq_profile == 1) {
+    profile_str = "high";
+  } else if (seq_profile == 2) {
+    profile_str = "professional";
+  } else {
+    GST_WARNING ("Unknown AV1 profile %d", seq_profile);
+    goto done;
+  }
+  gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile_str, NULL);
+
+  if (subcodec[2]) {
+    if (sscanf (subcodec[2], "%02u%c", &seq_level_idx_0, &tier) != 2) {
+      GST_WARNING ("Failed to parse level and tier from %s", subcodec[2]);
+      goto done;
+    }
+  } else {
+    seq_level_idx_0 = 1;
+    tier = 'M';
+  }
+
+  if (tier == 'H') {
+    tier_str = "high";
+  } else if (tier == 'M') {
+    tier_str = "main";
+  } else {
+    GST_WARNING ("Unknown AV1 tier %c", tier);
+    goto done;
+  }
+  gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier_str, NULL);
+
+  level_str = gst_codec_utils_av1_get_level (seq_level_idx_0);
+  if (level_str) {
+    gst_caps_set_simple (caps, "level", G_TYPE_STRING, level_str, NULL);
+  } else {
+    GST_WARNING ("Unknown AV1 level %d", seq_level_idx_0);
+    goto done;
+  }
+
+  if (subcodec[3]) {
+    bit_depth = g_ascii_strtoull (subcodec[3], NULL, 10);
+    gst_caps_set_simple (caps, "bit-depth-luma", G_TYPE_UINT, bit_depth,
+        "bit-depth-chroma", G_TYPE_UINT, bit_depth, NULL);
+  } else {
+    GST_WARNING ("Failed to parse bit-depth from %s", subcodec[3]);
+    goto done;
+  }
+
+  /* Verify if all values necessary to continue are present in the subcodec */
+  if (subcodec[4] && subcodec[5] && subcodec[6]
+      && subcodec[7] && subcodec[8] && subcodec[9]) {
+
+    monochrome = g_ascii_strtoull (subcodec[4], NULL, 10);
+    chroma_sampling = g_ascii_strtoull (subcodec[5], NULL, 10);
+    chroma_subsampling_x = chroma_sampling / 100;
+    chroma_subsampling_y = (chroma_sampling % 100) / 10;
+    chroma_sample_position = chroma_sampling % 10;
+    if (monochrome) {
+      chroma_format_str = "4:0:0";
+    } else if (chroma_subsampling_x == 1 && chroma_subsampling_y == 1) {
+      chroma_format_str = "4:2:0";
+    } else if (chroma_subsampling_x == 1 && chroma_subsampling_y == 0) {
+      chroma_format_str = "4:2:2";
+    } else if (chroma_subsampling_x == 0 && chroma_subsampling_y == 0) {
+      chroma_format_str = "4:4:4";
+    } else {
+      GST_WARNING ("Unknown chroma subsampling %d:%d:%d", chroma_subsampling_x,
+          chroma_subsampling_y, monochrome);
+      goto done;
+    }
+
+    primaries = g_ascii_strtoull (subcodec[6], NULL, 10);
+    transfer = g_ascii_strtoull (subcodec[7], NULL, 10);
+    matrix = g_ascii_strtoull (subcodec[8], NULL, 10);
+    full_range = g_ascii_strtoull (subcodec[9], NULL, 10);
+  } else {
+    GST_DEBUG
+        ("Using default values for chroma_format, chroma_sample_position, "
+        "primaries, transfer, matrix, and full_range");
+
+    chroma_format_str = "4:2:0";
+    chroma_sample_position = 0;
+    primaries = 1;
+    transfer = 1;
+    matrix = 1;
+    full_range = 0;
+  }
+
+  gst_caps_set_simple (caps, "chroma-format", G_TYPE_STRING, chroma_format_str,
+      NULL);
+  if (chroma_sample_position == 1) {
+    gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING, "v-cosited", NULL);
+  } else if (chroma_sample_position == 2) {
+    gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING,
+        "v-cosited+h-cosited", NULL);
+  }
+
+  cinfo.range =
+      full_range ? GST_VIDEO_COLOR_RANGE_0_255 : GST_VIDEO_COLOR_RANGE_16_235;
+  cinfo.primaries = gst_video_color_primaries_from_iso (primaries);
+  cinfo.transfer = gst_video_transfer_function_from_iso (transfer);
+  cinfo.matrix = gst_video_color_matrix_from_iso (matrix);
+  colorimetry_str = gst_video_colorimetry_to_string (&cinfo);
+  if (colorimetry_str) {
+    gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry_str,
+        NULL);
+  } else {
+    GST_WARNING ("Failed to parse colorimetry from %u %u %u %u", full_range,
+        matrix, transfer, primaries);
+  }
+  g_free (colorimetry_str);
+
+done:
+  return caps;
+}
+
+/* https://aomediacodec.github.io/av1-isobmff/#codecsparam */
+static char *
+av1_caps_get_mime_codec (GstCaps * caps)
+{
+  gchar tier_mime;
+  guint8 seq_level_idx_0;
+  guint bit_depth, seq_profile, chroma_sample_position,
+      monochrome, chroma_subsampling_x, chroma_subsampling_y, primaries,
+      transfer, matrix, full_range;
+  GstStructure *caps_st;
+  GString *codec_string;
+  const gchar *level_str;
+  const gchar *tier_str;
+  const gchar *profile_str;
+  const gchar *chroma_format_str;
+  const gchar *chroma_site_str;
+  const gchar *colorimetry_str;
+  GstVideoColorimetry cinfo = { 0, };
+
+  caps_st = gst_caps_get_structure (caps, 0);
+  codec_string = g_string_new ("av01");
+
+  tier_str = gst_structure_get_string (caps_st, "tier");
+  if (g_strcmp0 (tier_str, "main") == 0) {
+    tier_mime = 'M';
+  } else if (g_strcmp0 (tier_str, "high") == 0) {
+    tier_mime = 'H';
+  } else {
+    GST_WARNING ("Unknown AV1 tier %s, using default 'M'", tier_str);
+    tier_mime = 'M';
+  }
+
+  level_str = gst_structure_get_string (caps_st, "level");
+  if (level_str) {
+    seq_level_idx_0 = gst_codec_utils_av1_get_seq_level_idx (level_str);
+  } else {
+    seq_level_idx_0 = 1;
+  }
+
+  profile_str = gst_structure_get_string (caps_st, "profile");
+  if (g_strcmp0 (profile_str, "main") == 0) {
+    seq_profile = 0;
+  } else if (g_strcmp0 (profile_str, "high") == 0) {
+    seq_profile = 1;
+  } else if (g_strcmp0 (profile_str, "professional") == 0) {
+    seq_profile = 2;
+  } else {
+    goto done;
+  }
+
+  if (!gst_structure_get_uint (caps_st, "bit-depth-luma", &bit_depth))
+    goto done;
+
+  /* We have all information to compute a minimal mime */
+  g_string_append_printf (codec_string, ".%d.%02u%c.%02u",
+      seq_profile, seq_level_idx_0, tier_mime, bit_depth);
+
+  chroma_format_str = gst_structure_get_string (caps_st, "chroma-format");
+  if (g_strcmp0 (chroma_format_str, "4:0:0") == 0) {
+    monochrome = 1;
+    chroma_subsampling_x = 1;
+    chroma_subsampling_y = 1;
+  } else if (g_strcmp0 (chroma_format_str, "4:2:0") == 0) {
+    monochrome = 0;
+    chroma_subsampling_x = 1;
+    chroma_subsampling_y = 1;
+  } else if (g_strcmp0 (chroma_format_str, "4:2:2") == 0) {
+    monochrome = 0;
+    chroma_subsampling_x = 1;
+    chroma_subsampling_y = 0;
+  } else if (g_strcmp0 (chroma_format_str, "4:4:4") == 0) {
+    monochrome = 0;
+    chroma_subsampling_x = 0;
+    chroma_subsampling_y = 0;
+  } else {
+    goto done;
+  }
+
+  chroma_sample_position = 0;
+  chroma_site_str = gst_structure_get_string (caps_st, "chroma-site");
+  if (g_strcmp0 (chroma_site_str, "v-cosited") == 0) {
+    chroma_sample_position = 1;
+  } else if (g_strcmp0 (chroma_site_str, "v-cosited+h-cosited") == 0) {
+    chroma_sample_position = 2;
+  }
+
+  colorimetry_str = gst_structure_get_string (caps_st, "colorimetry");
+  if (!colorimetry_str)
+    goto done;
+  if (!gst_video_colorimetry_from_string (&cinfo, colorimetry_str))
+    goto done;
+  full_range = cinfo.range == GST_VIDEO_COLOR_RANGE_0_255;
+
+  primaries = gst_video_color_primaries_to_iso (cinfo.primaries);
+  transfer = gst_video_transfer_function_to_iso (cinfo.transfer);
+  matrix = gst_video_color_matrix_to_iso (cinfo.matrix);
+
+  if (chroma_subsampling_x != 1 || chroma_subsampling_y != 1
+      || chroma_sample_position != 0 || primaries != 1 || transfer != 1
+      || matrix != 1 || full_range != 0) {
+    g_string_append_printf (codec_string,
+        ".%u.%u%u%u.%02u.%02u.%02u.%u", monochrome, chroma_subsampling_x,
+        chroma_subsampling_y, chroma_sample_position, primaries, transfer,
+        matrix, full_range);
+  }
+
+done:
+  return g_string_free (codec_string, FALSE);
+}
+
+
 /**
  * gst_codec_utils_caps_get_mime_codec:
  * @caps: A #GstCaps to convert to mime codec
@@ -2612,10 +2999,7 @@ gst_codec_utils_caps_get_mime_codec (GstCaps * caps)
       mime_codec = g_strdup ("hev1");
     }
   } else if (g_strcmp0 (media_type, "video/x-av1") == 0) {
-    /* TODO: Some browsers won't play the video unless more codec information is
-     * available in the mime codec for av1. This is documented in
-     * https://aomediacodec.github.io/av1-isobmff/#codecsparam */
-    mime_codec = g_strdup ("av01");
+    mime_codec = av1_caps_get_mime_codec (caps);
   } else if (g_strcmp0 (media_type, "video/x-vp8") == 0) {
     /* TODO: most browsers won't play the video unless more codec information is
      * available in the mime codec for vp8. */
@@ -2812,9 +3196,11 @@ gst_codec_utils_caps_from_mime_codec_single (const gchar * codec)
       caps = gst_caps_new_empty_simple ("video/x-vp9");
       break;
     case GST_MAKE_FOURCC ('a', 'v', '0', '1'):
+    {
       /* AV1 */
-      caps = gst_caps_new_empty_simple ("video/x-av1");
+      caps = av1_caps_from_mime_codec (subcodec);
       break;
+    }
     case GST_MAKE_FOURCC ('o', 'p', 'u', 's'):
       /* Opus */
       caps = gst_caps_new_empty_simple ("audio/x-opus");
diff --git a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.h b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.h
index 43398c4eaa..87127e43a6 100644
--- a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.h
+++ b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/codec-utils.h
@@ -96,6 +96,15 @@ GST_PBUTILS_API
 gboolean      gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps      * caps,
                                                                     const guint8 * profile_tier_level,
                                                                     guint          len);
+
+/* AV1 */
+
+GST_PBUTILS_API
+guint8        gst_codec_utils_av1_get_seq_level_idx                (const gchar  * level);
+
+GST_PBUTILS_API
+const gchar * gst_codec_utils_av1_get_level                        (guint8 seq_level_idx);
+
 /* MPEG-4 part 2 */
 
 GST_PBUTILS_API
diff --git a/subprojects/gst-plugins-base/tests/check/libs/pbutils.c b/subprojects/gst-plugins-base/tests/check/libs/pbutils.c
index 1e14c9d7c0..ae52205ca0 100644
--- a/subprojects/gst-plugins-base/tests/check/libs/pbutils.c
+++ b/subprojects/gst-plugins-base/tests/check/libs/pbutils.c
@@ -1475,6 +1475,50 @@ GST_START_TEST (test_pb_utils_caps_mime_codec)
   g_free (mime_codec);
   gst_caps_unref (caps);
 
+  /* av1 with default chroma subsampling, color primaries, color transfer,
+   * color matrix and luma/chroma encoded*/
+  caps =
+      gst_caps_from_string
+      ("video/x-av1, stream-format=(string)obu-stream, alignment=(string)tu, profile=(string)main, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, colorimetry=(string)bt709");
+  mime_codec = gst_codec_utils_caps_get_mime_codec (caps);
+  fail_unless_equals_string (mime_codec, "av01.0.01M.08");
+  g_free (mime_codec);
+  gst_caps_unref (caps);
+
+  /* av1 with non-default chroma subsampling */
+  caps =
+      gst_caps_from_string
+      ("video/x-av1, stream-format=(string)obu-stream, alignment=(string)tu, profile=(string)main, width=(int)640, height=(int)480, "
+      "pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, chroma-format=(string)4:2:2, bit-depth-luma=(uint)8, "
+      "colorimetry=(string)bt709");
+  mime_codec = gst_codec_utils_caps_get_mime_codec (caps);
+  fail_unless_equals_string (mime_codec, "av01.0.01M.08.0.100.01.01.01.0");
+  g_free (mime_codec);
+  gst_caps_unref (caps);
+
+  /* av1 with non-default level and tier */
+  caps =
+      gst_caps_from_string
+      ("video/x-av1, stream-format=(string)obu-stream, alignment=(string)tu, profile=(string)main, width=(int)640, height=(int)480, "
+      "pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, chroma-format=(string)4:2:2, bit-depth-luma=(uint)8, "
+      "colorimetry=(string)bt709, tier=(string)high, level=(string)3.0");
+  mime_codec = gst_codec_utils_caps_get_mime_codec (caps);
+  fail_unless_equals_string (mime_codec, "av01.0.04H.08.0.100.01.01.01.0");
+  g_free (mime_codec);
+  gst_caps_unref (caps);
+
+  /* av1 with missing colorimetry */
+  caps =
+      gst_caps_from_string
+      ("video/x-av1, stream-format=(string)obu-stream, alignment=(string)tu, profile=(string)main, width=(int)640, height=(int)480, "
+      "pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, "
+      "chroma-format=(string)4:2:2, bit-depth-luma=(uint)8, "
+      "bit-depth-chroma=(uint)8, tier=(string)main, level=(string)5.0");
+  mime_codec = gst_codec_utils_caps_get_mime_codec (caps);
+  fail_unless_equals_string (mime_codec, "av01.0.12M.08");
+  g_free (mime_codec);
+  gst_caps_unref (caps);
+
   /* vp8 */
   caps = gst_caps_new_empty_simple ("video/x-vp8");
   mime_codec = gst_codec_utils_caps_get_mime_codec (caps);
@@ -1581,6 +1625,40 @@ GST_START_TEST (test_pb_utils_caps_mime_codec)
 
 GST_END_TEST;
 
+GST_START_TEST (test_pb_utils_caps_from_mime_codec)
+{
+  GstCaps *caps = NULL;
+  gchar *caps_str = NULL;
+
+  /* AV1 minimal caps */
+  caps = gst_codec_utils_caps_from_mime_codec ("av01");
+  caps_str = gst_caps_to_string (caps);
+  fail_unless_equals_string (caps_str, "video/x-av1");
+  gst_caps_unref (caps);
+  g_free (caps_str);
+
+  /* AV1 with default chroma subsampling, color primaries, color transfer,
+   * color matrix and luma/chroma encoded */
+  caps = gst_codec_utils_caps_from_mime_codec ("av01.0.01M.08");
+  caps_str = gst_caps_to_string (caps);
+  fail_unless_equals_string (caps_str,
+      "video/x-av1, profile=(string)main, tier=(string)main, level=(string)2.1, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, chroma-format=(string)4:2:0, colorimetry=(string)bt709");
+  gst_caps_unref (caps);
+  g_free (caps_str);
+
+  /* av1 with non-default chroma subsampling */
+  caps =
+      gst_codec_utils_caps_from_mime_codec ("av01.0.01M.08.0.100.01.01.01.0");
+  caps_str = gst_caps_to_string (caps);
+  fail_unless_equals_string (caps_str,
+      ("video/x-av1, profile=(string)main, tier=(string)main, level=(string)2.1, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, chroma-format=(string)4:2:2, colorimetry=(string)bt709"));
+  gst_caps_unref (caps);
+  g_free (caps_str);
+
+};
+
+GST_END_TEST;
+
 static Suite *
 libgstpbutils_suite (void)
 {
@@ -1603,6 +1681,7 @@ libgstpbutils_suite (void)
   tcase_add_test (tc_chain, test_pb_utils_h264_get_profile_flags_level);
   tcase_add_test (tc_chain, test_pb_utils_h265_profiles);
   tcase_add_test (tc_chain, test_pb_utils_caps_mime_codec);
+  tcase_add_test (tc_chain, test_pb_utils_caps_from_mime_codec);
   return s;
 }