mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
mpegts: Add custom mapping for vp9
This is a custom mapping. There isn't much needed apart from that to store vp9 in mpeg-ts since the bitstream is self contained. Since there are no official specification we don't want people to be mistaken in believing that. Therefore that mapping is only used in the muxer if the (new) property `enable-custom-mappings` is set to TRUE. * The MPEG-TS Stream Type is Private Data (0x6) with the registration descriptor set to `VP09`. * The Access Unit are VP9 frames stored in PES packets * As there is no emulation prevention byte in VP9 elementary stream, the can be misdetection of PES start code. To avoid this, the start of a PES packet must be signalled using the Payload Unit Start Indicator in the transport packet header Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7707>
This commit is contained in:
parent
23ce0d2901
commit
244b00ac08
8 changed files with 65 additions and 3 deletions
|
@ -222936,7 +222936,7 @@
|
||||||
"presence": "sometimes"
|
"presence": "sometimes"
|
||||||
},
|
},
|
||||||
"video_%%01x_%%05x": {
|
"video_%%01x_%%05x": {
|
||||||
"caps": "video/mpeg:\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\nvideo/x-h264:\n stream-format: byte-stream\nvideo/x-h265:\n stream-format: byte-stream\nvideo/x-dirac:\nvideo/x-cavs:\nvideo/x-wmv:\n wmvversion: 3\n format: WVC1\nimage/x-jpc:\nimage/x-jxsc:\n",
|
"caps": "video/mpeg:\n mpegversion: { (int)1, (int)2, (int)4 }\n systemstream: false\nvideo/x-h264:\n stream-format: byte-stream\nvideo/x-h265:\n stream-format: byte-stream\nvideo/x-vp9:\nvideo/x-dirac:\nvideo/x-cavs:\nvideo/x-wmv:\n wmvversion: 3\n format: WVC1\nimage/x-jpc:\nimage/x-jxsc:\n",
|
||||||
"direction": "src",
|
"direction": "src",
|
||||||
"presence": "sometimes"
|
"presence": "sometimes"
|
||||||
}
|
}
|
||||||
|
@ -223194,7 +223194,7 @@
|
||||||
"long-name": "MPEG Transport Stream Muxer",
|
"long-name": "MPEG Transport Stream Muxer",
|
||||||
"pad-templates": {
|
"pad-templates": {
|
||||||
"sink_%%d": {
|
"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 ]\naudio/x-smpte-302m:\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",
|
"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 ]\naudio/x-smpte-302m:\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\nvideo/x-vp9:\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",
|
"direction": "sink",
|
||||||
"presence": "request",
|
"presence": "request",
|
||||||
"type": "GstBaseTsMuxPad"
|
"type": "GstBaseTsMuxPad"
|
||||||
|
@ -223265,6 +223265,18 @@
|
||||||
"type": "guint64",
|
"type": "guint64",
|
||||||
"writable": true
|
"writable": true
|
||||||
},
|
},
|
||||||
|
"enable-custom-mappings": {
|
||||||
|
"blurb": "Enable custom mappings for which there are no official specifications",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gboolean",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
"pat-interval": {
|
"pat-interval": {
|
||||||
"blurb": "Set the interval (in ticks of the 90kHz clock) for writing out the PAT table",
|
"blurb": "Set the interval (in ticks of the 90kHz clock) for writing out the PAT table",
|
||||||
"conditionally-available": false,
|
"conditionally-available": false,
|
||||||
|
|
|
@ -241,5 +241,6 @@
|
||||||
#define DRF_ID_AC4 0x41432D34 /* defined in ETSI TS 103 190-2 Annex D */
|
#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_ID3 0x49443320 /* defined in SMPTE registration authority */
|
||||||
#define DRF_ID_VANC 0x56414e43 /* defined in SMPTE ST-2038 */
|
#define DRF_ID_VANC 0x56414e43 /* defined in SMPTE ST-2038 */
|
||||||
|
#define DRF_ID_VP09 0x56503039 /* Custom GStreamer vp9 */
|
||||||
|
|
||||||
#endif /* __GST_MPEG_DESC_H__ */
|
#endif /* __GST_MPEG_DESC_H__ */
|
||||||
|
|
|
@ -229,6 +229,7 @@ struct _TSDemuxStream
|
||||||
"systemstream = (boolean) FALSE; " \
|
"systemstream = (boolean) FALSE; " \
|
||||||
"video/x-h264,stream-format=(string)byte-stream;" \
|
"video/x-h264,stream-format=(string)byte-stream;" \
|
||||||
"video/x-h265,stream-format=(string)byte-stream;" \
|
"video/x-h265,stream-format=(string)byte-stream;" \
|
||||||
|
"video/x-vp9;" \
|
||||||
"video/x-dirac;" \
|
"video/x-dirac;" \
|
||||||
"video/x-cavs;" \
|
"video/x-cavs;" \
|
||||||
"video/x-wmv," \
|
"video/x-wmv," \
|
||||||
|
@ -1674,6 +1675,10 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
|
||||||
is_audio = TRUE;
|
is_audio = TRUE;
|
||||||
caps = gst_caps_new_empty_simple ("audio/x-ac4");
|
caps = gst_caps_new_empty_simple ("audio/x-ac4");
|
||||||
break;
|
break;
|
||||||
|
case DRF_ID_VP09:
|
||||||
|
is_video = TRUE;
|
||||||
|
caps = gst_caps_new_empty_simple ("video/x-vp9");
|
||||||
|
break;
|
||||||
case DRF_ID_VANC:
|
case DRF_ID_VANC:
|
||||||
is_private = TRUE;
|
is_private = TRUE;
|
||||||
caps =
|
caps =
|
||||||
|
|
|
@ -256,10 +256,12 @@ enum
|
||||||
PROP_BITRATE,
|
PROP_BITRATE,
|
||||||
PROP_PCR_INTERVAL,
|
PROP_PCR_INTERVAL,
|
||||||
PROP_SCTE_35_PID,
|
PROP_SCTE_35_PID,
|
||||||
PROP_SCTE_35_NULL_INTERVAL
|
PROP_SCTE_35_NULL_INTERVAL,
|
||||||
|
PROP_ENABLE_CUSTOM_MAPPINGS
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_SCTE_35_PID 0
|
#define DEFAULT_SCTE_35_PID 0
|
||||||
|
#define DEFAULT_ENABLE_CUSTOM_MAPPINGS FALSE
|
||||||
|
|
||||||
#define BASETSMUX_DEFAULT_ALIGNMENT -1
|
#define BASETSMUX_DEFAULT_ALIGNMENT -1
|
||||||
|
|
||||||
|
@ -624,6 +626,13 @@ gst_base_ts_mux_create_or_update_stream (GstBaseTsMux * mux,
|
||||||
st = TSMUX_ST_VIDEO_H264;
|
st = TSMUX_ST_VIDEO_H264;
|
||||||
} else if (strcmp (mt, "video/x-h265") == 0) {
|
} else if (strcmp (mt, "video/x-h265") == 0) {
|
||||||
st = TSMUX_ST_VIDEO_HEVC;
|
st = TSMUX_ST_VIDEO_HEVC;
|
||||||
|
} else if (strcmp (mt, "video/x-vp9") == 0) {
|
||||||
|
if (mux->enable_custom_mappings) {
|
||||||
|
st = TSMUX_ST_PS_VP9;
|
||||||
|
} else {
|
||||||
|
GST_ERROR_OBJECT (mux,
|
||||||
|
"VP9 requires enabling custom mapping which does not have a public specification");
|
||||||
|
}
|
||||||
} else if (strcmp (mt, "audio/mpeg") == 0) {
|
} else if (strcmp (mt, "audio/mpeg") == 0) {
|
||||||
gint mpegversion;
|
gint mpegversion;
|
||||||
|
|
||||||
|
@ -2880,6 +2889,9 @@ gst_base_ts_mux_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_SCTE_35_NULL_INTERVAL:
|
case PROP_SCTE_35_NULL_INTERVAL:
|
||||||
mux->scte35_null_interval = g_value_get_uint (value);
|
mux->scte35_null_interval = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENABLE_CUSTOM_MAPPINGS:
|
||||||
|
mux->enable_custom_mappings = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -2920,6 +2932,9 @@ gst_base_ts_mux_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_SCTE_35_NULL_INTERVAL:
|
case PROP_SCTE_35_NULL_INTERVAL:
|
||||||
g_value_set_uint (value, mux->scte35_null_interval);
|
g_value_set_uint (value, mux->scte35_null_interval);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENABLE_CUSTOM_MAPPINGS:
|
||||||
|
g_value_set_boolean (value, mux->enable_custom_mappings);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -3074,6 +3089,20 @@ gst_base_ts_mux_class_init (GstBaseTsMuxClass * klass)
|
||||||
TSMUX_DEFAULT_SCTE_35_NULL_INTERVAL,
|
TSMUX_DEFAULT_SCTE_35_NULL_INTERVAL,
|
||||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstBaseTsMux:enable-custom-mappings:
|
||||||
|
*
|
||||||
|
* Enable custom mappings for which there are no official specifications
|
||||||
|
*
|
||||||
|
* Since: 1.26
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
||||||
|
PROP_ENABLE_CUSTOM_MAPPINGS,
|
||||||
|
g_param_spec_boolean ("enable-custom-mappings", "Enable custom mappings",
|
||||||
|
"Enable custom mappings for which there are no official specifications",
|
||||||
|
DEFAULT_ENABLE_CUSTOM_MAPPINGS,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
|
||||||
&gst_base_ts_mux_src_factory, GST_TYPE_AGGREGATOR_PAD);
|
&gst_base_ts_mux_src_factory, GST_TYPE_AGGREGATOR_PAD);
|
||||||
|
|
||||||
|
@ -3095,6 +3124,7 @@ gst_base_ts_mux_init (GstBaseTsMux * mux)
|
||||||
mux->bitrate = TSMUX_DEFAULT_BITRATE;
|
mux->bitrate = TSMUX_DEFAULT_BITRATE;
|
||||||
mux->scte35_pid = DEFAULT_SCTE_35_PID;
|
mux->scte35_pid = DEFAULT_SCTE_35_PID;
|
||||||
mux->scte35_null_interval = TSMUX_DEFAULT_SCTE_35_NULL_INTERVAL;
|
mux->scte35_null_interval = TSMUX_DEFAULT_SCTE_35_NULL_INTERVAL;
|
||||||
|
mux->enable_custom_mappings = DEFAULT_ENABLE_CUSTOM_MAPPINGS;
|
||||||
|
|
||||||
mux->packet_size = GST_BASE_TS_MUX_NORMAL_PACKET_LENGTH;
|
mux->packet_size = GST_BASE_TS_MUX_NORMAL_PACKET_LENGTH;
|
||||||
mux->automatic_alignment = 0;
|
mux->automatic_alignment = 0;
|
||||||
|
|
|
@ -164,6 +164,7 @@ struct GstBaseTsMux {
|
||||||
guint scte35_pid;
|
guint scte35_pid;
|
||||||
guint scte35_null_interval;
|
guint scte35_null_interval;
|
||||||
guint32 last_scte35_event_seqnum;
|
guint32 last_scte35_event_seqnum;
|
||||||
|
gboolean enable_custom_mappings;
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
gboolean first;
|
gboolean first;
|
||||||
|
|
|
@ -128,6 +128,7 @@ static GstStaticPadTemplate gst_mpeg_ts_mux_sink_factory =
|
||||||
"subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true;"
|
"subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true;"
|
||||||
"meta/x-id3, parsed=true;"
|
"meta/x-id3, parsed=true;"
|
||||||
"meta/x-st-2038, alignment = (string) line;"
|
"meta/x-st-2038, alignment = (string) line;"
|
||||||
|
"video/x-vp9;"
|
||||||
"image/x-jpc, alignment = (string) frame, profile = (int)[0, 49151];"
|
"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 };"));
|
"image/x-jxsc, alignment = (string) frame, sampling = { YCbCr-4:2:2, YCbCr-4:4:4 };"));
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,12 @@ tsmux_stream_new (guint16 pid, guint stream_type, guint stream_number)
|
||||||
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
||||||
stream->gst_stream_type = GST_STREAM_TYPE_VIDEO;
|
stream->gst_stream_type = GST_STREAM_TYPE_VIDEO;
|
||||||
break;
|
break;
|
||||||
|
case TSMUX_ST_PS_VP9:
|
||||||
|
stream->id = 0xBD; /* Private Stream 1 */
|
||||||
|
stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
|
||||||
|
stream->stream_type = TSMUX_ST_PRIVATE_DATA;
|
||||||
|
stream->gst_stream_type = GST_STREAM_TYPE_VIDEO;
|
||||||
|
break;
|
||||||
case TSMUX_ST_AUDIO_AAC:
|
case TSMUX_ST_AUDIO_AAC:
|
||||||
case TSMUX_ST_AUDIO_MPEG1:
|
case TSMUX_ST_AUDIO_MPEG1:
|
||||||
case TSMUX_ST_AUDIO_MPEG2:
|
case TSMUX_ST_AUDIO_MPEG2:
|
||||||
|
@ -1034,6 +1040,11 @@ tsmux_stream_default_get_es_descrs (TsMuxStream * stream,
|
||||||
GST_DEBUG ("adding SMPTE 302M registration descriptor");
|
GST_DEBUG ("adding SMPTE 302M registration descriptor");
|
||||||
g_ptr_array_add (pmt_stream->descriptors, descriptor);
|
g_ptr_array_add (pmt_stream->descriptors, descriptor);
|
||||||
}
|
}
|
||||||
|
if (stream->internal_stream_type == TSMUX_ST_PS_VP9) {
|
||||||
|
descriptor = gst_mpegts_descriptor_from_registration ("VP09", NULL, 0);
|
||||||
|
GST_DEBUG ("adding VP09 registration descriptor");
|
||||||
|
g_ptr_array_add (pmt_stream->descriptors, descriptor);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ enum TsMuxStreamType {
|
||||||
TSMUX_ST_PS_ID3 = 0x90, /* only used internally */
|
TSMUX_ST_PS_ID3 = 0x90, /* only used internally */
|
||||||
TSMUX_ST_PS_ST_2038 = 0x91, /* only used internally */
|
TSMUX_ST_PS_ST_2038 = 0x91, /* only used internally */
|
||||||
TSMUX_ST_PS_S302M = 0x92, /* only used internally */
|
TSMUX_ST_PS_S302M = 0x92, /* only used internally */
|
||||||
|
TSMUX_ST_PS_VP9 = 0x93, /* only used internally */
|
||||||
TSMUX_ST_PS_DVD_SUBPICTURE = 0xff,
|
TSMUX_ST_PS_DVD_SUBPICTURE = 0xff,
|
||||||
|
|
||||||
/* Non-standard definitions */
|
/* Non-standard definitions */
|
||||||
|
|
Loading…
Reference in a new issue