diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index 88e4e30b02..f0dd856dd6 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -9869,7 +9869,7 @@ "type": "GstMatroskaMuxPad" }, "video_%%u": { - "caps": "video/mpeg:\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h264:\n stream-format: { (string)avc, (string)avc3 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h265:\n stream-format: { (string)hvc1, (string)hev1 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-divx:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-huffyuv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-dv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h263:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-msmpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nimage/jpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-theora:\nvideo/x-dirac:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-pn-realvideo:\n rmversion: [ 1, 4 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp8:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp9:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-raw:\n format: { YUY2, I420, YV12, UYVY, AYUV, GRAY8, GRAY10_LE32, GRAY16_LE, BGR, RGB, RGBA64_LE, BGRA64_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-prores:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-wmv:\n wmvversion: [ 1, 3 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-av1:\n stream-format: obu-stream\n alignment: tu\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-ffv:\n ffversion: 1\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n", + "caps": "video/mpeg:\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h264:\n stream-format: { (string)avc, (string)avc3 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h265:\n stream-format: { (string)hvc1, (string)hev1 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h266:\n stream-format: { (string)vvc1, (string)vvi1 }\n alignment: au\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-divx:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-huffyuv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-dv:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-h263:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-msmpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nimage/jpeg:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-theora:\nvideo/x-dirac:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-pn-realvideo:\n rmversion: [ 1, 4 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp8:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-vp9:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-raw:\n format: { YUY2, I420, YV12, UYVY, AYUV, GRAY8, GRAY10_LE32, GRAY16_LE, BGR, RGB, RGBA64_LE, BGRA64_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-prores:\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-wmv:\n wmvversion: [ 1, 3 ]\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-av1:\n stream-format: obu-stream\n alignment: tu\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\nvideo/x-ffv:\n ffversion: 1\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n", "direction": "sink", "presence": "request", "type": "GstMatroskaMuxPad" diff --git a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c index a3251c196d..e2436d6c0c 100644 --- a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c +++ b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c @@ -120,6 +120,8 @@ static GstStaticPadTemplate videosink_templ = COMMON_VIDEO_CAPS "; " "video/x-h265, stream-format = (string) { hvc1, hev1 }, alignment=au, " COMMON_VIDEO_CAPS "; " + "video/x-h266, stream-format = (string) { vvc1, vvi1 }, alignment=au, " + COMMON_VIDEO_CAPS "; " "video/x-divx, " COMMON_VIDEO_CAPS "; " "video/x-huffyuv, " @@ -931,22 +933,32 @@ gst_matroska_mux_set_codec_id (GstMatroskaTrackContext * context, context->codec_id = g_strdup (id); } +static gboolean +has_h26x_in_band_codec_data (GstStructure * structure) +{ + const gchar *name = gst_structure_get_name (structure); + + return (g_strcmp0 (name, "video/x-h264") == 0 + && !g_strcmp0 (gst_structure_get_string (structure, "stream-format"), + "avc3")) + || (g_strcmp0 (name, "video/x-h265") == 0 + && !g_strcmp0 (gst_structure_get_string (structure, "stream-format"), + "hev1")) + || (g_strcmp0 (name, "video/x-h266") == 0 + && !g_strcmp0 (gst_structure_get_string (structure, "stream-format"), + "vvi1")); +} + static gboolean check_field (const GstIdStr * fieldname, const GValue * value, gpointer user_data) { GstStructure *structure = (GstStructure *) user_data; - const gchar *name = gst_structure_get_name (structure); - if ((g_strcmp0 (name, "video/x-h264") == 0 && - !g_strcmp0 (gst_structure_get_string (structure, "stream-format"), - "avc3")) || (g_strcmp0 (name, "video/x-h265") == 0 - && !g_strcmp0 (gst_structure_get_string (structure, "stream-format"), - "hev1")) - ) { - /* While in theory, matroska only supports avc1 / hvc1, and doesn't support codec_data - * changes, in practice most decoders will use in-band SPS / PPS (avc3 / hev1), if the - * input stream is avc3 / hev1 we let the new codec_data slide to support "smart" encoding. + if (has_h26x_in_band_codec_data (structure)) { + /* While in theory, matroska only supports avc1 / hvc1 / vvc1, and doesn't support codec_data + * changes, in practice most decoders will use in-band SPS / PPS (avc3 / hev1 / vvi1), if the + * input stream is avc3 / hev1 / vvi1 we let the new codec_data slide to support "smart" encoding. * * We don't warn here as we already warned elsewhere. */ @@ -1341,6 +1353,23 @@ skip_details: context->codec_priv = g_malloc0 (context->codec_priv_size); gst_buffer_extract (codec_buf, 0, context->codec_priv, -1); } + } else if (!strcmp (mimetype, "video/x-h266")) { + gst_matroska_mux_set_codec_id (context, + GST_MATROSKA_CODEC_ID_VIDEO_MPEGI_VVC); + gst_matroska_mux_free_codec_priv (context); + + if (!g_strcmp0 (gst_structure_get_string (structure, "stream-format"), + "vvi1")) { + GST_WARNING_OBJECT (mux, + "vvi1 is not officially supported, only use this format for smart encoding"); + } + + /* Create CodecPrivate with VVCDecoderConfigurationRecord */ + if (codec_buf != NULL) { + context->codec_priv_size = gst_buffer_get_size (codec_buf); + context->codec_priv = g_malloc0 (context->codec_priv_size); + gst_buffer_extract (codec_buf, 0, context->codec_priv, -1); + } } else if (!strcmp (mimetype, "video/x-theora")) { const GValue *streamheader;