diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h b/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h index be491d5c27..92b7b7f51d 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/gstmpegdesc.h @@ -239,5 +239,6 @@ #define DRF_ID_OPUS 0x4f707573 #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 */ #endif /* __GST_MPEG_DESC_H__ */ diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c index 3729884314..785cf5c902 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c @@ -674,6 +674,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-id3") == 0) { + st = TSMUX_ST_PS_ID3; } else if (strcmp (mt, "image/x-jpc") == 0) { /* * See this document for more details on standard: diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c index 9d17088866..744f34213b 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstmpegtsmux.c @@ -125,6 +125,7 @@ static GstStaticPadTemplate gst_mpeg_ts_mux_sink_factory = "audio/x-opus, " "channels = (int) [1, 255];" "subpicture/x-dvb; application/x-teletext; meta/x-klv, parsed=true;" + "meta/x-id3, parsed=true;" "image/x-jpc, alignment = (string) frame, profile = (int)[0, 49151];")); static GstStaticPadTemplate gst_mpeg_ts_mux_src_factory = diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c index 36bde52d53..36bd177ad2 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c @@ -67,7 +67,9 @@ #include +#include #include +#include #include "tsmux.h" #include "tsmuxstream.h" @@ -1853,6 +1855,27 @@ tsmux_write_pmt (TsMux * mux, TsMuxProgram * program) g_ptr_array_add (pmt->descriptors, descriptor); } + /* Scan the streams looking for metadata streams */ + for (i = 0; i < program->streams->len; i++) { + TsMuxStream *stream = g_ptr_array_index (program->streams, i); + + if (stream->is_id3_metadata == TRUE) { + GstMpegtsMetadataPointerDescriptor metadata_pointer_descriptor; + metadata_pointer_descriptor.metadata_application_format = + GST_MPEGTS_METADATA_APPLICATION_FORMAT_IDENTIFIER_FIELD; + metadata_pointer_descriptor.metadata_format = + GST_MPEGTS_METADATA_FORMAT_IDENTIFIER_FIELD; + metadata_pointer_descriptor.metadata_format_identifier = DRF_ID_ID3; + metadata_pointer_descriptor.metadata_service_id = 0; + metadata_pointer_descriptor.program_number = program->pgm_number; + + descriptor = + gst_mpegts_descriptor_from_metadata_pointer + (&metadata_pointer_descriptor); + g_ptr_array_add (pmt->descriptors, descriptor); + } + } + /* Write out the entries */ for (i = 0; i < program->streams->len; i++) { GstMpegtsPMTStream *pmt_stream; diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c index 7a78392a15..250a1d7d21 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.c @@ -69,6 +69,7 @@ #include #include +#include #include "tsmuxcommon.h" #include "tsmuxstream.h" @@ -218,6 +219,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_ID3: + stream->id = 0xBD; // private stream + stream->stream_type = TSMUX_ST_PES_METADATA; + stream->is_meta = TRUE; + stream->is_id3_metadata = TRUE; + stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER | + TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT; + break; case TSMUX_ST_PS_OPUS: /* FIXME: assign sequential extended IDs? */ stream->id = 0xBD; @@ -494,6 +503,12 @@ tsmux_stream_initialize_pes_packet (TsMuxStream * stream) if ((stream->cur_pes_payload_size + hdr_len - 6) > G_MAXUINT16) stream->cur_pes_payload_size = 0; } + // stream_type specific flags + switch (stream->stream_type) { + case TSMUX_ST_PES_METADATA: + stream->pi.flags |= TSMUX_PACKET_FLAG_PES_DATA_ALIGNMENT; + break; + } return TRUE; } @@ -910,6 +925,35 @@ tsmux_stream_default_get_es_descrs (TsMuxStream * stream, g_ptr_array_add (pmt_stream->descriptors, descriptor); break; + + case TSMUX_ST_PES_METADATA: + + if (stream->is_id3_metadata) { + // metadata_descriptor + GstMpegtsMetadataDescriptor metadata_descriptor; + + metadata_descriptor.metadata_application_format = + GST_MPEGTS_METADATA_APPLICATION_FORMAT_IDENTIFIER_FIELD; + metadata_descriptor.metadata_format = + GST_MPEGTS_METADATA_FORMAT_IDENTIFIER_FIELD; + metadata_descriptor.metadata_format_identifier = DRF_ID_ID3; + metadata_descriptor.metadata_service_id = 0; + metadata_descriptor.decoder_config_flags = 0x00; + metadata_descriptor.dsm_cc_flag = FALSE; + + descriptor = gst_mpegts_descriptor_from_metadata (&metadata_descriptor); + g_ptr_array_add (pmt_stream->descriptors, descriptor); + + // registration_descriptor + guint32 format_identifier = 0; + GST_WRITE_UINT32_BE (&format_identifier, + metadata_descriptor.metadata_format_identifier); + + descriptor = gst_mpegts_descriptor_from_registration ((const char *) + &format_identifier, NULL, 0); + g_ptr_array_add (pmt_stream->descriptors, descriptor); + } + break; case TSMUX_ST_PS_DVB_SUBPICTURE: /* fallthrough ... * that should never happen anyway as diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h index 3461f2b00d..cce8e49a2e 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmuxstream.h @@ -118,6 +118,7 @@ enum TsMuxStreamType { /* later extensions */ TSMUX_ST_AUDIO_AAC = 0x0f, TSMUX_ST_VIDEO_MPEG4 = 0x10, + TSMUX_ST_PES_METADATA = 0x15, TSMUX_ST_VIDEO_H264 = 0x1b, TSMUX_ST_VIDEO_HEVC = 0x24, TSMUX_ST_VIDEO_JP2K = 0x21, @@ -130,6 +131,7 @@ enum TsMuxStreamType { TSMUX_ST_PS_TELETEXT = 0x8d, 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_DVD_SUBPICTURE = 0xff, /* Non-standard definitions */ @@ -226,6 +228,8 @@ struct TsMuxStream { guint16 profile_and_level; gboolean interlace_mode; guint8 color_spec; + + gboolean is_id3_metadata; }; /* stream management */