matroskamux: add support for VVC/H.266 video

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8441>
This commit is contained in:
Carlos Bentzen 2025-02-08 16:32:31 +01:00 committed by GStreamer Marge Bot
parent 1be3d7f37b
commit 8cfbdd7cf6
2 changed files with 40 additions and 11 deletions

View File

@ -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"

View File

@ -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;