mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-06-28 19:00:42 +00:00
tsdemux: Expose send-scte35-events property
When enabled, SCTE 35 sections (eg ad placement opportunities) are forwarded as events donwstream. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/913>
This commit is contained in:
parent
b2718ed6cf
commit
1ca08bff57
|
@ -210818,6 +210818,18 @@
|
||||||
"readable": true,
|
"readable": true,
|
||||||
"type": "gint",
|
"type": "gint",
|
||||||
"writable": true
|
"writable": true
|
||||||
|
},
|
||||||
|
"send-scte35-events": {
|
||||||
|
"blurb": "Whether SCTE 35 sections should be forwarded as events",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "gboolean",
|
||||||
|
"writable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rank": "primary",
|
"rank": "primary",
|
||||||
|
|
|
@ -297,6 +297,7 @@ enum
|
||||||
PROP_PROGRAM_NUMBER,
|
PROP_PROGRAM_NUMBER,
|
||||||
PROP_EMIT_STATS,
|
PROP_EMIT_STATS,
|
||||||
PROP_LATENCY,
|
PROP_LATENCY,
|
||||||
|
PROP_SEND_SCTE35_EVENTS,
|
||||||
/* FILL ME */
|
/* FILL ME */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -340,6 +341,7 @@ static gboolean push_event (MpegTSBase * base, GstEvent * event);
|
||||||
static gboolean sink_query (MpegTSBase * base, GstQuery * query);
|
static gboolean sink_query (MpegTSBase * base, GstQuery * query);
|
||||||
static void gst_ts_demux_check_and_sync_streams (GstTSDemux * demux,
|
static void gst_ts_demux_check_and_sync_streams (GstTSDemux * demux,
|
||||||
GstClockTime time);
|
GstClockTime time);
|
||||||
|
static void handle_psi (MpegTSBase * base, GstMpegtsSection * section);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_extra_init (void)
|
_extra_init (void)
|
||||||
|
@ -395,6 +397,22 @@ gst_ts_demux_class_init (GstTSDemuxClass * klass)
|
||||||
"Emit messages for every pcr/opcr/pts/dts", FALSE,
|
"Emit messages for every pcr/opcr/pts/dts", FALSE,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mpegtsdemux:send-scte35-events:
|
||||||
|
*
|
||||||
|
* Whether SCTE 35 sections should be forwarded as events.
|
||||||
|
*
|
||||||
|
* When forwarding those, potential splice times are converted
|
||||||
|
* to running time, and can be used by a downstream muxer to reinject
|
||||||
|
* the sections.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class, PROP_SEND_SCTE35_EVENTS,
|
||||||
|
g_param_spec_boolean ("send-scte35-events", "Send SCTE 35 events",
|
||||||
|
"Whether SCTE 35 sections should be forwarded as events", FALSE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_LATENCY,
|
g_object_class_install_property (gobject_class, PROP_LATENCY,
|
||||||
g_param_spec_int ("latency", "Latency",
|
g_param_spec_int ("latency", "Latency",
|
||||||
"Latency to add for smooth demuxing (in ms)", -1,
|
"Latency to add for smooth demuxing (in ms)", -1,
|
||||||
|
@ -422,6 +440,7 @@ gst_ts_demux_class_init (GstTSDemuxClass * klass)
|
||||||
ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
|
ts_class->reset = GST_DEBUG_FUNCPTR (gst_ts_demux_reset);
|
||||||
ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
|
ts_class->push = GST_DEBUG_FUNCPTR (gst_ts_demux_push);
|
||||||
ts_class->push_event = GST_DEBUG_FUNCPTR (push_event);
|
ts_class->push_event = GST_DEBUG_FUNCPTR (push_event);
|
||||||
|
ts_class->handle_psi = GST_DEBUG_FUNCPTR (handle_psi);
|
||||||
ts_class->sink_query = GST_DEBUG_FUNCPTR (sink_query);
|
ts_class->sink_query = GST_DEBUG_FUNCPTR (sink_query);
|
||||||
ts_class->program_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
|
ts_class->program_started = GST_DEBUG_FUNCPTR (gst_ts_demux_program_started);
|
||||||
ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
|
ts_class->program_stopped = GST_DEBUG_FUNCPTR (gst_ts_demux_program_stopped);
|
||||||
|
@ -495,6 +514,9 @@ gst_ts_demux_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_EMIT_STATS:
|
case PROP_EMIT_STATS:
|
||||||
demux->emit_statistics = g_value_get_boolean (value);
|
demux->emit_statistics = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_SEND_SCTE35_EVENTS:
|
||||||
|
demux->send_scte35_events = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
case PROP_LATENCY:
|
case PROP_LATENCY:
|
||||||
demux->latency = g_value_get_int (value);
|
demux->latency = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
@ -516,6 +538,9 @@ gst_ts_demux_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_EMIT_STATS:
|
case PROP_EMIT_STATS:
|
||||||
g_value_set_boolean (value, demux->emit_statistics);
|
g_value_set_boolean (value, demux->emit_statistics);
|
||||||
break;
|
break;
|
||||||
|
case PROP_SEND_SCTE35_EVENTS:
|
||||||
|
g_value_set_boolean (value, demux->send_scte35_events);
|
||||||
|
break;
|
||||||
case PROP_LATENCY:
|
case PROP_LATENCY:
|
||||||
g_value_set_int (value, demux->latency);
|
g_value_set_int (value, demux->latency);
|
||||||
break;
|
break;
|
||||||
|
@ -1055,6 +1080,96 @@ push_event (MpegTSBase * base, GstEvent * event)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstMpegtsSCTESpliceEvent *
|
||||||
|
copy_splice (GstMpegtsSCTESpliceEvent * splice)
|
||||||
|
{
|
||||||
|
return g_boxed_copy (GST_TYPE_MPEGTS_SCTE_SPLICE_EVENT, splice);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstMpegtsSCTESIT *
|
||||||
|
deep_copy_sit (const GstMpegtsSCTESIT * sit)
|
||||||
|
{
|
||||||
|
GstMpegtsSCTESIT *sit_copy = g_boxed_copy (GST_TYPE_MPEGTS_SCTE_SIT, sit);
|
||||||
|
GPtrArray *splices_copy =
|
||||||
|
g_ptr_array_copy (sit_copy->splices, (GCopyFunc) copy_splice, NULL);
|
||||||
|
|
||||||
|
g_ptr_array_unref (sit_copy->splices);
|
||||||
|
sit_copy->splices = splices_copy;
|
||||||
|
|
||||||
|
return sit_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_psi (MpegTSBase * base, GstMpegtsSection * section)
|
||||||
|
{
|
||||||
|
GstTSDemux *demux = (GstTSDemux *) base;
|
||||||
|
|
||||||
|
if (section->section_type == GST_MPEGTS_SECTION_SCTE_SIT) {
|
||||||
|
GList *tmp;
|
||||||
|
gboolean forward = FALSE;
|
||||||
|
|
||||||
|
if (demux->send_scte35_events) {
|
||||||
|
for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
|
||||||
|
TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
|
||||||
|
|
||||||
|
if (stream->stream.pid == section->pid) {
|
||||||
|
forward = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new section to travel through the pipeline, with splice
|
||||||
|
* times translated from local time to running time */
|
||||||
|
if (forward) {
|
||||||
|
GstEvent *event;
|
||||||
|
GstClockTime pts;
|
||||||
|
guint i = 0;
|
||||||
|
const GstMpegtsSCTESIT *sit = gst_mpegts_section_get_scte_sit (section);
|
||||||
|
GstMpegtsSCTESIT *sit_copy = deep_copy_sit (sit);
|
||||||
|
GstMpegtsSection *new_section;
|
||||||
|
|
||||||
|
if (sit_copy->splice_time_specified) {
|
||||||
|
pts =
|
||||||
|
mpegts_packetizer_pts_to_ts (base->packetizer,
|
||||||
|
MPEGTIME_TO_GSTTIME (sit_copy->splice_time +
|
||||||
|
sit_copy->pts_adjustment), demux->program->pcr_pid);
|
||||||
|
sit_copy->splice_time =
|
||||||
|
gst_segment_to_running_time (&base->out_segment, GST_FORMAT_TIME,
|
||||||
|
pts);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sit_copy->splices->len; i++) {
|
||||||
|
GstMpegtsSCTESpliceEvent *sevent =
|
||||||
|
g_ptr_array_index (sit_copy->splices, i);
|
||||||
|
if (sevent->program_splice_time_specified) {
|
||||||
|
pts =
|
||||||
|
mpegts_packetizer_pts_to_ts (base->packetizer,
|
||||||
|
MPEGTIME_TO_GSTTIME (sevent->program_splice_time),
|
||||||
|
demux->program->pcr_pid);
|
||||||
|
sevent->program_splice_time =
|
||||||
|
gst_segment_to_running_time (&base->out_segment, GST_FORMAT_TIME,
|
||||||
|
pts);
|
||||||
|
if (sevent->duration_flag) {
|
||||||
|
sevent->break_duration =
|
||||||
|
MPEGTIME_TO_GSTTIME (sevent->break_duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sit_copy->pts_adjustment = 0;
|
||||||
|
|
||||||
|
new_section = gst_mpegts_section_from_scte_sit (sit_copy, section->pid);
|
||||||
|
|
||||||
|
event = gst_event_new_mpegts_section (new_section);
|
||||||
|
|
||||||
|
gst_mpegts_section_unref (new_section);
|
||||||
|
|
||||||
|
push_event (base, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
sink_query (MpegTSBase * base, GstQuery * query)
|
sink_query (MpegTSBase * base, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct _GstTSDemux
|
||||||
gint requested_program_number; /* Required program number (ignore:-1) */
|
gint requested_program_number; /* Required program number (ignore:-1) */
|
||||||
guint program_number;
|
guint program_number;
|
||||||
gboolean emit_statistics;
|
gboolean emit_statistics;
|
||||||
|
gboolean send_scte35_events;
|
||||||
gint latency; /* latency in ms */
|
gint latency; /* latency in ms */
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
Loading…
Reference in a new issue