mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
scte-section: add support for parsing splice components
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/913>
This commit is contained in:
parent
66533ea77d
commit
e272fb3444
2 changed files with 151 additions and 23 deletions
|
@ -43,12 +43,18 @@
|
||||||
static GstMpegtsSCTESpliceEvent *
|
static GstMpegtsSCTESpliceEvent *
|
||||||
_gst_mpegts_scte_splice_event_copy (GstMpegtsSCTESpliceEvent * event)
|
_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
|
static void
|
||||||
_gst_mpegts_scte_splice_event_free (GstMpegtsSCTESpliceEvent * event)
|
_gst_mpegts_scte_splice_event_free (GstMpegtsSCTESpliceEvent * event)
|
||||||
{
|
{
|
||||||
|
g_ptr_array_unref (event->components);
|
||||||
g_slice_free (GstMpegtsSCTESpliceEvent, event);
|
g_slice_free (GstMpegtsSCTESpliceEvent, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +62,71 @@ G_DEFINE_BOXED_TYPE (GstMpegtsSCTESpliceEvent, gst_mpegts_scte_splice_event,
|
||||||
(GBoxedCopyFunc) _gst_mpegts_scte_splice_event_copy,
|
(GBoxedCopyFunc) _gst_mpegts_scte_splice_event_copy,
|
||||||
(GFreeFunc) _gst_mpegts_scte_splice_event_free);
|
(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 *
|
static GstMpegtsSCTESpliceEvent *
|
||||||
_parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
|
_parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
|
||||||
{
|
{
|
||||||
|
@ -66,6 +137,9 @@ _parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
|
||||||
if (data + 5 + 6 > end)
|
if (data + 5 + 6 > end)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
event->components = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||||
|
_gst_mpegts_scte_splice_component_free);
|
||||||
|
|
||||||
event->insert_event = insert_event;
|
event->insert_event = insert_event;
|
||||||
event->splice_event_id = GST_READ_UINT32_BE (data);
|
event->splice_event_id = GST_READ_UINT32_BE (data);
|
||||||
GST_LOG ("splice_event_id: 0x%08x", event->splice_event_id);
|
GST_LOG ("splice_event_id: 0x%08x", event->splice_event_id);
|
||||||
|
@ -97,10 +171,19 @@ _parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
|
||||||
data += 1;
|
data += 1;
|
||||||
|
|
||||||
if (event->program_splice_flag == 0) {
|
if (event->program_splice_flag == 0) {
|
||||||
GST_ERROR ("Component splice flag not supported !");
|
guint component_count = *data;
|
||||||
goto error;
|
guint i;
|
||||||
}
|
|
||||||
|
|
||||||
|
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) {
|
if (insert_event && event->splice_immediate_flag == 0) {
|
||||||
event->program_splice_time_specified = *data >> 7;
|
event->program_splice_time_specified = *data >> 7;
|
||||||
if (event->program_splice_time_specified) {
|
if (event->program_splice_time_specified) {
|
||||||
|
@ -108,8 +191,8 @@ _parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
|
||||||
data += 1;
|
data += 1;
|
||||||
event->program_splice_time += GST_READ_UINT32_BE (data);
|
event->program_splice_time += GST_READ_UINT32_BE (data);
|
||||||
data += 4;
|
data += 4;
|
||||||
GST_LOG ("program_splice_time %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT
|
GST_LOG ("program_splice_time %" G_GUINT64_FORMAT " (%"
|
||||||
")", event->program_splice_time,
|
GST_TIME_FORMAT ")", event->program_splice_time,
|
||||||
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (event->program_splice_time)));
|
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (event->program_splice_time)));
|
||||||
} else
|
} else
|
||||||
data += 1;
|
data += 1;
|
||||||
|
@ -118,6 +201,7 @@ _parse_splice_event (guint8 ** orig_data, guint8 * end, gboolean insert_event)
|
||||||
GST_LOG ("utc_splice_time %u", event->utc_splice_time);
|
GST_LOG ("utc_splice_time %u", event->utc_splice_time);
|
||||||
data += 4;
|
data += 4;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (event->duration_flag) {
|
if (event->duration_flag) {
|
||||||
event->break_duration_auto_return = *data >> 7;
|
event->break_duration_auto_return = *data >> 7;
|
||||||
|
@ -513,10 +597,33 @@ gst_mpegts_scte_splice_event_new (void)
|
||||||
|
|
||||||
/* Non-0 Default values */
|
/* Non-0 Default values */
|
||||||
event->program_splice_flag = TRUE;
|
event->program_splice_flag = TRUE;
|
||||||
|
event->components = g_ptr_array_new_with_free_func ((GDestroyNotify)
|
||||||
|
_gst_mpegts_scte_splice_component_free);
|
||||||
|
|
||||||
|
|
||||||
return event;
|
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
|
static gboolean
|
||||||
_packetize_sit (GstMpegtsSection * section)
|
_packetize_sit (GstMpegtsSection * section)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,6 +103,18 @@ typedef enum {
|
||||||
|
|
||||||
} GstMpegtsSectionSCTETableID;
|
} 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) */
|
/* Splice Information Table (SIT) */
|
||||||
#define GST_TYPE_MPEGTS_SCTE_SPLICE_EVENT (gst_mpegts_scte_splice_event_get_type())
|
#define GST_TYPE_MPEGTS_SCTE_SPLICE_EVENT (gst_mpegts_scte_splice_event_get_type())
|
||||||
typedef struct _GstMpegtsSCTESpliceEvent GstMpegtsSCTESpliceEvent;
|
typedef struct _GstMpegtsSCTESpliceEvent GstMpegtsSCTESpliceEvent;
|
||||||
|
@ -116,14 +128,17 @@ struct _GstMpegtsSCTESpliceEvent {
|
||||||
|
|
||||||
/* If splice_event_cancel_indicator == 0 */
|
/* If splice_event_cancel_indicator == 0 */
|
||||||
gboolean out_of_network_indicator;
|
gboolean out_of_network_indicator;
|
||||||
gboolean program_splice_flag; /* NOTE: Only program splice are supported */
|
gboolean program_splice_flag;
|
||||||
gboolean duration_flag;
|
gboolean duration_flag;
|
||||||
|
|
||||||
gboolean splice_immediate_flag; /* Only valid for insert_event */
|
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;
|
gboolean break_duration_auto_return;
|
||||||
guint64 break_duration;
|
guint64 break_duration;
|
||||||
|
@ -219,6 +234,12 @@ const GstMpegtsSCTESIT *gst_mpegts_section_get_scte_sit (GstMpegtsSection *secti
|
||||||
GST_MPEGTS_API
|
GST_MPEGTS_API
|
||||||
GstMpegtsSection *gst_mpegts_section_from_scte_sit (GstMpegtsSCTESIT * sit, guint16 pid);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue