static GstMpegtsSCTESpliceEvent *
_gst_mpegts_scte_splice_event_copy (GstMpegtsSCTESpliceEvent * event)
{
- return g_slice_dup (GstMpegtsSCTESpliceEvent, event);
+ GstMpegtsSCTESpliceEvent *copy =
+ g_slice_dup (GstMpegtsSCTESpliceEvent, event);
+
+ copy->components = g_ptr_array_ref (event->components);
+
+ return copy;
}
static void
_gst_mpegts_scte_splice_event_free (GstMpegtsSCTESpliceEvent * event)
{
+ g_ptr_array_unref (event->components);
g_slice_free (GstMpegtsSCTESpliceEvent, event);
}
(GBoxedCopyFunc) _gst_mpegts_scte_splice_event_copy,
(GFreeFunc) _gst_mpegts_scte_splice_event_free);
+static GstMpegtsSCTESpliceComponent *
+_gst_mpegts_scte_splice_component_copy (GstMpegtsSCTESpliceComponent *
+ component)
+{
+ return g_slice_dup (GstMpegtsSCTESpliceComponent, component);
+}
+
+static void
+_gst_mpegts_scte_splice_component_free (GstMpegtsSCTESpliceComponent *
+ component)
+{
+ g_slice_free (GstMpegtsSCTESpliceComponent, component);
+}
+
+G_DEFINE_BOXED_TYPE (GstMpegtsSCTESpliceComponent,
+ gst_mpegts_scte_splice_component,
+ (GBoxedCopyFunc) _gst_mpegts_scte_splice_component_copy,
+ (GFreeFunc) _gst_mpegts_scte_splice_component_free);
+
+static GstMpegtsSCTESpliceComponent *
+_parse_splice_component (GstMpegtsSCTESpliceEvent * event, guint8 ** orig_data,
+ guint8 * end)
+{
+ GstMpegtsSCTESpliceComponent *component =
+ g_slice_new0 (GstMpegtsSCTESpliceComponent);
+ guint8 *data = *orig_data;
+
+ if (data + 1 + 6 > end)
+ goto error;
+
+ component->tag = *data;
+ data += 1;
+
+ if (event->insert_event && event->splice_immediate_flag == 0) {
+ component->splice_time_specified = *data >> 7;
+ if (component->splice_time_specified) {
+ component->splice_time = ((guint64) (*data & 0x01)) << 32;
+ data += 1;
+ component->splice_time += GST_READ_UINT32_BE (data);
+ data += 4;
+ GST_LOG ("component %u splice_time %" G_GUINT64_FORMAT " (%"
+ GST_TIME_FORMAT ")", component->tag, component->splice_time,
+ GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (component->splice_time)));
+ } else {
+ data += 1;
+ }
+ } else if (!event->insert_event) {
+ component->utc_splice_time = GST_READ_UINT32_BE (data);
+ GST_LOG ("component %u utc_splice_time %u", component->tag,
+ component->utc_splice_time);
+ data += 4;
+ }
+
+ *orig_data = data;
+
+ return component;
+
+error:
+ {
+ if (event)
+ _gst_mpegts_scte_splice_event_free (event);
+ return NULL;
+ }
+}
+
static GstMpegtsSCTESpliceEvent *
_parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
{
if (data + 5 + 6 > end)
goto error;
+ event->components = g_ptr_array_new_with_free_func ((GDestroyNotify)
+ _gst_mpegts_scte_splice_component_free);
+
event->insert_event = insert_event;
event->splice_event_id = GST_READ_UINT32_BE (data);
GST_LOG ("splice_event_id: 0x%08x", event->splice_event_id);
data += 1;
if (event->program_splice_flag == 0) {
- GST_ERROR ("Component splice flag not supported !");
- goto error;
- }
+ guint component_count = *data;
+ guint i;
- if (insert_event && event->splice_immediate_flag == 0) {
- event->program_splice_time_specified = *data >> 7;
- if (event->program_splice_time_specified) {
- event->program_splice_time = ((guint64) (*data & 0x01)) << 32;
- data += 1;
- event->program_splice_time += GST_READ_UINT32_BE (data);
+ data += 1;
+
+ for (i = 0; i < component_count; i++) {
+ GstMpegtsSCTESpliceComponent *component =
+ _parse_splice_component (event, &data, end);
+ if (component == NULL)
+ goto error;
+ g_ptr_array_add (event->components, component);
+ }
+ } else {
+ if (insert_event && event->splice_immediate_flag == 0) {
+ event->program_splice_time_specified = *data >> 7;
+ if (event->program_splice_time_specified) {
+ event->program_splice_time = ((guint64) (*data & 0x01)) << 32;
+ data += 1;
+ event->program_splice_time += GST_READ_UINT32_BE (data);
+ data += 4;
+ GST_LOG ("program_splice_time %" G_GUINT64_FORMAT " (%"
+ GST_TIME_FORMAT ")", event->program_splice_time,
+ GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (event->program_splice_time)));
+ } else
+ data += 1;
+ } else if (!insert_event) {
+ event->utc_splice_time = GST_READ_UINT32_BE (data);
+ GST_LOG ("utc_splice_time %u", event->utc_splice_time);
data += 4;
- GST_LOG ("program_splice_time %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT
- ")", event->program_splice_time,
- GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (event->program_splice_time)));
- } else
- data += 1;
- } else if (!insert_event) {
- event->utc_splice_time = GST_READ_UINT32_BE (data);
- GST_LOG ("utc_splice_time %u", event->utc_splice_time);
- data += 4;
+ }
}
if (event->duration_flag) {
/* Non-0 Default values */
event->program_splice_flag = TRUE;
+ event->components = g_ptr_array_new_with_free_func ((GDestroyNotify)
+ _gst_mpegts_scte_splice_component_free);
+
return event;
}
+/**
+ * gst_mpegts_scte_splice_component_new:
+ * tag: the elementary PID stream identifier
+ *
+ * Allocates and initializes a #GstMpegtsSCTESpliceComponent.
+ *
+ * Returns: (transfer full): A newly allocated #GstMpegtsSCTESpliceComponent
+ * Since: 1.20
+ */
+GstMpegtsSCTESpliceComponent *
+gst_mpegts_scte_splice_component_new (guint8 tag)
+{
+ GstMpegtsSCTESpliceComponent *component =
+ g_slice_new0 (GstMpegtsSCTESpliceComponent);
+
+ component->tag = tag;
+
+ return component;
+}
+
static gboolean
_packetize_sit (GstMpegtsSection * section)
{
} GstMpegtsSectionSCTETableID;
+#define GST_TYPE_MPEGTS_SCTE_SPLICE_COMPONENT (gst_mpegts_scte_splice_component_get_type())
+typedef struct _GstMpegtsSCTESpliceComponent GstMpegtsSCTESpliceComponent;
+
+struct _GstMpegtsSCTESpliceComponent {
+ guint8 tag;
+
+ gboolean splice_time_specified; /* Only valid for insert_event */
+ guint64 splice_time; /* Only valid for insert_event */
+
+ guint32 utc_splice_time; /* Only valid for !insert_event (schedule) */
+};
+
/* Splice Information Table (SIT) */
#define GST_TYPE_MPEGTS_SCTE_SPLICE_EVENT (gst_mpegts_scte_splice_event_get_type())
typedef struct _GstMpegtsSCTESpliceEvent GstMpegtsSCTESpliceEvent;
/* If splice_event_cancel_indicator == 0 */
gboolean out_of_network_indicator;
- gboolean program_splice_flag; /* NOTE: Only program splice are supported */
+ gboolean program_splice_flag;
gboolean duration_flag;
gboolean splice_immediate_flag; /* Only valid for insert_event */
- gboolean program_splice_time_specified; /* Only valid for insert_event */
- guint64 program_splice_time; /* Only valid for insert_event */
- guint32 utc_splice_time; /* Only valid for !insert_event (schedule) */
+ gboolean program_splice_time_specified; /* Only valid for insert_event && program_splice */
+ guint64 program_splice_time; /* Only valid for insert_event && program_splice */
+
+ guint32 utc_splice_time; /* Only valid for !insert_event (schedule) && program_splice */
+
+ GPtrArray *components; /* Only valid for !program_splice */
gboolean break_duration_auto_return;
guint64 break_duration;
GST_MPEGTS_API
GstMpegtsSection *gst_mpegts_section_from_scte_sit (GstMpegtsSCTESIT * sit, guint16 pid);
+GST_MPEGTS_API
+GType gst_mpegts_scte_splice_component_get_type (void);
+
+GST_MPEGTS_API
+GstMpegtsSCTESpliceComponent *gst_mpegts_scte_splice_component_new (guint8 tag);
+
G_END_DECLS