From 15e7928c8a8012e14941f97e67889a462dda79ad Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 6 Sep 2024 10:44:46 +0200 Subject: [PATCH] mpegts: Add support for SMPTE ST-2038 ANC Part-of: --- .../docs/plugins/gst_plugins_cache.json | 2 +- .../gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h | 1 + .../gst-plugins-bad/gst/mpegtsdemux/tsdemux.c | 6 ++++++ .../gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c | 2 ++ .../gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c | 1 + .../gst/mpegtsmux/tsmux/tsmuxstream.c | 15 +++++++++++++++ .../gst/mpegtsmux/tsmux/tsmuxstream.h | 1 + 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json index 44c8fedc0b..5d1f20fea4 100644 --- a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json @@ -220863,7 +220863,7 @@ "long-name": "MPEG Transport Stream Muxer", "pad-templates": { "sink_%%d": { - "caps": "video/mpeg:\n parsed: true\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\nvideo/x-dirac:\nimage/x-jpc:\n alignment: frame\nvideo/x-h264:\n stream-format: byte-stream\n alignment: { (string)au, (string)nal }\nvideo/x-h265:\n stream-format: byte-stream\n alignment: { (string)au, (string)nal }\naudio/mpeg:\n parsed: true\n mpegversion: 1\naudio/mpeg:\n framed: true\n mpegversion: { (int)2, (int)4 }\n stream-format: { (string)adts, (string)raw }\naudio/x-lpcm:\n width: { (int)16, (int)20, (int)24 }\n rate: { (int)48000, (int)96000 }\n channels: [ 1, 8 ]\n dynamic_range: [ 0, 255 ]\n emphasis: { (boolean)false, (boolean)true }\n mute: { (boolean)false, (boolean)true }\naudio/x-ac3:\n framed: true\naudio/x-dts:\n framed: true\naudio/x-opus:\n channels: [ 1, 255 ]\nsubpicture/x-dvb:\napplication/x-teletext:\nmeta/x-klv:\n parsed: true\nmeta/x-id3:\n parsed: true\nimage/x-jpc:\n alignment: frame\n profile: [ 0, 49151 ]\nimage/x-jxsc:\n alignment: frame\n sampling: { (string)YCbCr-4:2:2, (string)YCbCr-4:4:4 }\n", + "caps": "video/mpeg:\n parsed: true\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\nvideo/x-dirac:\nimage/x-jpc:\n alignment: frame\nvideo/x-h264:\n stream-format: byte-stream\n alignment: { (string)au, (string)nal }\nvideo/x-h265:\n stream-format: byte-stream\n alignment: { (string)au, (string)nal }\naudio/mpeg:\n parsed: true\n mpegversion: 1\naudio/mpeg:\n framed: true\n mpegversion: { (int)2, (int)4 }\n stream-format: { (string)adts, (string)raw }\naudio/x-lpcm:\n width: { (int)16, (int)20, (int)24 }\n rate: { (int)48000, (int)96000 }\n channels: [ 1, 8 ]\n dynamic_range: [ 0, 255 ]\n emphasis: { (boolean)false, (boolean)true }\n mute: { (boolean)false, (boolean)true }\naudio/x-ac3:\n framed: true\naudio/x-dts:\n framed: true\naudio/x-opus:\n channels: [ 1, 255 ]\nsubpicture/x-dvb:\napplication/x-teletext:\nmeta/x-klv:\n parsed: true\nmeta/x-id3:\n parsed: true\nmeta/x-st-2038:\n alignment: line\nimage/x-jpc:\n alignment: frame\n profile: [ 0, 49151 ]\nimage/x-jxsc:\n alignment: frame\n sampling: { (string)YCbCr-4:2:2, (string)YCbCr-4:4:4 }\n", "direction": "sink", "presence": "request", "type": "GstBaseTsMuxPad" diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h b/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h index 92b7b7f51d..a5570aadf2 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h @@ -240,5 +240,6 @@ #define DRF_ID_EAC3 0x45414333 /* defined in A/52 Annex G */ #define DRF_ID_AC4 0x41432D34 /* defined in ETSI TS 103 190-2 Annex D */ #define DRF_ID_ID3 0x49443320 /* defined in SMPTE registration authority */ +#define DRF_ID_VANC 0x56414e43 /* defined in SMPTE ST-2038 */ #endif /* __GST_MPEG_DESC_H__ */ diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c b/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c index 5367ba331a..927f643b5e 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/tsdemux.c @@ -1695,6 +1695,12 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, is_audio = TRUE; caps = gst_caps_new_empty_simple ("audio/x-ac4"); break; + case DRF_ID_VANC: + is_private = TRUE; + caps = + gst_caps_new_simple ("meta/x-st-2038", "alignment", G_TYPE_STRING, + "line", NULL); + break; } if (caps) break; diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c index 0985882fe8..2f6c0089ac 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c @@ -810,6 +810,8 @@ gst_base_ts_mux_create_or_update_stream (GstBaseTsMux * mux, ts_pad->prepare_func = gst_base_ts_mux_prepare_opus; } else if (strcmp (mt, "meta/x-klv") == 0) { st = TSMUX_ST_PS_KLV; + } else if (strcmp (mt, "meta/x-st-2038") == 0) { + st = TSMUX_ST_PS_ST_2038; } else if (strcmp (mt, "meta/x-id3") == 0) { st = TSMUX_ST_PS_ID3; } else if (strcmp (mt, "image/x-jxsc") == 0) { diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c index 199565e6ec..792a3e340c 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c @@ -126,6 +126,7 @@ static GstStaticPadTemplate gst_mpeg_ts_mux_sink_factory = "channels = (int) [1, 255];" "subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true;" "meta/x-id3, parsed=true;" + "meta/x-st-2038, alignment = (string) line;" "image/x-jpc, alignment = (string) frame, profile = (int)[0, 49151];" "image/x-jxsc, alignment = (string) frame, sampling = { YCbCr-4:2:2, YCbCr-4:4:4 };")); diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c index a96ba24909..0a7c66e82d 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c @@ -224,6 +224,14 @@ tsmux_stream_new (guint16 pid, guint stream_type, guint stream_number) TSMUX_PACKET_FLAG_PES_FULL_HEADER | TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT; break; + case TSMUX_ST_PS_ST_2038: + /* FIXME: assign sequential extended IDs? */ + stream->id = 0xBD; + stream->stream_type = TSMUX_ST_PRIVATE_DATA; + stream->pi.flags |= + TSMUX_PACKET_FLAG_PES_FULL_HEADER | + TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT; + break; case TSMUX_ST_PS_ID3: stream->id = 0xBD; // private stream stream->stream_type = TSMUX_ST_PES_METADATA; @@ -1007,6 +1015,13 @@ tsmux_stream_default_get_es_descrs (TsMuxStream * stream, GST_DEBUG ("adding KLVA registration descriptor"); g_ptr_array_add (pmt_stream->descriptors, descriptor); } + if (stream->internal_stream_type == TSMUX_ST_PS_ST_2038) { + descriptor = gst_mpegts_descriptor_from_registration ("VANC", NULL, 0); + GST_DEBUG ("adding VANC registration descriptor"); + g_ptr_array_add (pmt_stream->descriptors, descriptor); + descriptor = gst_mpegts_descriptor_from_custom (0xc4, NULL, 0); + g_ptr_array_add (pmt_stream->descriptors, descriptor); + } default: break; } diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h index b0449a7f15..322cc5d886 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h @@ -133,6 +133,7 @@ enum TsMuxStreamType { TSMUX_ST_PS_KLV = 0x8e, /* only used internally */ TSMUX_ST_PS_OPUS = 0x8f, /* only used internally */ TSMUX_ST_PS_ID3 = 0x90, /* only used internally */ + TSMUX_ST_PS_ST_2038 = 0x91, /* only used internally */ TSMUX_ST_PS_DVD_SUBPICTURE = 0xff, /* Non-standard definitions */