diff options
Diffstat (limited to 'gst/mpegtsparse/mpegtspacketizer.c')
-rw-r--r-- | gst/mpegtsparse/mpegtspacketizer.c | 659 |
1 files changed, 590 insertions, 69 deletions
diff --git a/gst/mpegtsparse/mpegtspacketizer.c b/gst/mpegtsparse/mpegtspacketizer.c index 1aac7991..af759eeb 100644 --- a/gst/mpegtsparse/mpegtspacketizer.c +++ b/gst/mpegtsparse/mpegtspacketizer.c @@ -22,8 +22,6 @@ */ #include "mpegtspacketizer.h" -#include "flutspatinfo.h" -#include "flutspmtinfo.h" GST_DEBUG_CATEGORY_STATIC (mpegts_packetizer_debug); #define GST_CAT_DEFAULT mpegts_packetizer_debug @@ -139,7 +137,8 @@ mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer * packetizer, { guint8 length; - length = *packet->data++; + length = *packet->data; + packet->data += 1; if (packet->adaptation_field_control == 0x02) { /* no payload, adaptation field of 183 bytes */ @@ -154,8 +153,9 @@ mpegts_packetizer_parse_adaptation_field_control (MpegTSPacketizer * packetizer, /* skip the adaptation field body for now */ if (packet->data + length > packet->data_end) { - GST_DEBUG ("PID %d afc length overflows the buffer %d", - packet->pid, length); + GST_DEBUG ("PID %d afc length %d overflows the buffer current %d max %d", + packet->pid, length, packet->data - packet->data_start, + packet->data_end - packet->data_start); return FALSE; } @@ -178,7 +178,7 @@ mpegts_packetizer_parse_packet (MpegTSPacketizer * packetizer, packet->pid = GST_READ_UINT16_BE (data) & 0x1FFF; data += 2; - packet->adaptation_field_control = *data >> 4 & 0x03; + packet->adaptation_field_control = (*data >> 4) & 0x03; packet->continuity_counter = *data & 0x0F; data += 1; @@ -236,21 +236,66 @@ not_applicable: return TRUE; } -GValueArray * +static gboolean +mpegts_packetizer_parse_descriptors (MpegTSPacketizer * packetizer, + guint8 ** buffer, guint8 * buffer_end, GValueArray * descriptors) +{ + guint8 tag, length; + guint8 *data; + GValue value = { 0 }; + GString *desc; + + data = *buffer; + + while (data < buffer_end) { + tag = *data++; + length = *data++; + + if (data + length > buffer_end) { + GST_WARNING ("invalid descriptor length %d now at %d max %d", + length, data - *buffer, buffer_end - *buffer); + goto error; + } + + /* include tag and length */ + desc = g_string_new_len ((gchar *) data - 2, length + 2); + data += length; + + g_value_init (&value, G_TYPE_GSTRING); + g_value_take_boxed (&value, desc); + g_value_array_append (descriptors, &value); + g_value_unset (&value); + } + + if (data != buffer_end) { + GST_WARNING ("descriptors size %d expected %d", + data - *buffer, buffer_end - *buffer); + goto error; + } + + *buffer = data; + + return TRUE; +error: + return FALSE; +} + +GstStructure * mpegts_packetizer_parse_pat (MpegTSPacketizer * packetizer, MpegTSPacketizerSection * section) { + GstStructure *pat_info = NULL; guint8 *data, *end; - guint16 transport_stream_id; + guint transport_stream_id; guint8 tmp; guint program_number; - guint16 pmt_pid; - MpegTSPatInfo *info; - GValueArray *pat; + guint pmt_pid; + GValue entries = { 0 }; GValue value = { 0 }; + GstStructure *entry = NULL; + gchar *struct_name; data = GST_BUFFER_DATA (section->buffer); - pat = g_value_array_new (0); section->table_id = *data++; section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; @@ -266,6 +311,9 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer * packetizer, /* skip section_number and last_section_number */ data += 2; + pat_info = gst_structure_new ("pat", + "transport-stream-id", G_TYPE_UINT, transport_stream_id, NULL); + g_value_init (&entries, GST_TYPE_LIST); /* stop at the CRC */ end = GST_BUFFER_DATA (section->buffer) + GST_BUFFER_SIZE (section->buffer); while (data < end - 4) { @@ -275,40 +323,50 @@ mpegts_packetizer_parse_pat (MpegTSPacketizer * packetizer, pmt_pid = GST_READ_UINT16_BE (data) & 0x1FFF; data += 2; - info = mpegts_pat_info_new (program_number, pmt_pid); + struct_name = g_strdup_printf ("program-%d", program_number); + entry = gst_structure_new (struct_name, + "program-number", G_TYPE_UINT, program_number, + "pid", G_TYPE_UINT, pmt_pid, NULL); + g_free (struct_name); - g_value_init (&value, G_TYPE_OBJECT); - g_value_take_object (&value, info); - g_value_array_append (pat, &value); + g_value_init (&value, GST_TYPE_STRUCTURE); + g_value_take_boxed (&value, entry); + gst_value_list_append_value (&entries, &value); g_value_unset (&value); } + gst_structure_set_value (pat_info, "programs", &entries); + g_value_unset (&entries); + if (data != end - 4) { /* FIXME: check the CRC before parsing the packet */ GST_ERROR ("at the end of PAT data != end - 4"); - g_value_array_free (pat); + gst_structure_free (pat_info); return NULL; } - return pat; + return pat_info; } -GObject * +GstStructure * mpegts_packetizer_parse_pmt (MpegTSPacketizer * packetizer, MpegTSPacketizerSection * section) { - MpegTSPmtInfo *pmt = NULL; - MpegTSPmtStreamInfo *stream_info; + GstStructure *pmt = NULL; guint8 *data, *end; guint16 program_number; guint8 tmp; - guint16 pcr_pid; + guint pcr_pid; guint program_info_length; - guint8 tag, length; guint8 stream_type; guint16 pid; guint stream_info_length; + GValueArray *descriptors; + GValue stream_value = { 0 }; + GValue programs = { 0 }; + GstStructure *stream_info = NULL; + gchar *struct_name; /* fixed header + CRC == 16 */ if (GST_BUFFER_SIZE (section->buffer) < 16) { @@ -340,35 +398,35 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer * packetizer, program_info_length = GST_READ_UINT16_BE (data) & 0x0FFF; data += 2; - /* check that the buffer is large enough to contain at least - * program_info_length bytes + CRC */ - if (data + program_info_length + 4 > end) { - GST_WARNING ("PID %d invalid program info length %d " - "left %d", section->pid, program_info_length, end - data); - goto error; - } - - pmt = mpegts_pmt_info_new (program_number, pcr_pid, section->version_number); - - /* parse program level descriptors */ - while (program_info_length > 0) { - tag = *data++; - length = *data++; - program_info_length -= 2; + struct_name = g_strdup_printf ("program-%d", program_number); + pmt = gst_structure_new (struct_name, + "program-number", G_TYPE_UINT, program_number, + "pcr-pid", G_TYPE_UINT, pcr_pid, + "version-number", G_TYPE_UINT, section->version_number, NULL); + g_free (struct_name); + + if (program_info_length) { + /* check that the buffer is large enough to contain at least + * program_info_length bytes + CRC */ + if (data + program_info_length + 4 > end) { + GST_WARNING ("PID %d invalid program info length %d " + "left %d", section->pid, program_info_length, end - data); + goto error; + } - if (length > program_info_length) { - GST_WARNING ("PID %d invalid descriptor length %d left %d", - section->pid, length, program_info_length); + descriptors = g_value_array_new (0); + if (!mpegts_packetizer_parse_descriptors (packetizer, + &data, data + program_info_length, descriptors)) { + g_value_array_free (descriptors); goto error; } - mpegts_pmt_info_add_descriptor (pmt, (const gchar *) data - 2, 2 + length); - data += length; - program_info_length -= length; + gst_structure_set (pmt, "descriptors", G_TYPE_VALUE_ARRAY, descriptors, + NULL); + g_value_array_free (descriptors); } - g_assert (program_info_length == 0); - + g_value_init (&programs, GST_TYPE_LIST); /* parse entries, cycle until there's space for another entry (at least 5 * bytes) plus the CRC */ while (data <= end - 4 - 5) { @@ -383,45 +441,507 @@ mpegts_packetizer_parse_pmt (MpegTSPacketizer * packetizer, if (data + stream_info_length + 4 > end) { GST_WARNING ("PID %d invalid stream info length %d " "left %d", section->pid, stream_info_length, end - data); + g_value_unset (&programs); + goto error; + } + + struct_name = g_strdup_printf ("pid-%d", pid); + stream_info = gst_structure_new (struct_name, + "pid", G_TYPE_UINT, pid, "stream-type", G_TYPE_UINT, stream_type, NULL); + g_free (struct_name); + + if (stream_info_length) { + descriptors = g_value_array_new (0); + if (!mpegts_packetizer_parse_descriptors (packetizer, + &data, data + stream_info_length, descriptors)) { + g_value_unset (&programs); + gst_structure_free (stream_info); + g_value_array_free (descriptors); + goto error; + } + + gst_structure_set (stream_info, + "descriptors", G_TYPE_VALUE_ARRAY, descriptors, NULL); + g_value_array_free (descriptors); + } + + g_value_init (&stream_value, GST_TYPE_STRUCTURE); + g_value_take_boxed (&stream_value, stream_info); + gst_value_list_append_value (&programs, &stream_value); + g_value_unset (&stream_value); + } + + gst_structure_set_value (pmt, "streams", &programs); + g_value_unset (&programs); + + g_assert (data == end - 4); + + return pmt; + +error: + if (pmt) + gst_structure_free (pmt); + + return NULL; +} + +GstStructure * +mpegts_packetizer_parse_nit (MpegTSPacketizer * packetizer, + MpegTSPacketizerSection * section) +{ + GstStructure *nit = NULL, *transport = NULL; + guint8 *data, *end, *entry_begin; + guint16 network_id, transport_stream_id, original_network_id; + guint tmp; + guint16 descriptors_loop_length, transport_stream_loop_length; + GValue transports = { 0 }; + GValue transport_value = { 0 }; + GValueArray *descriptors = NULL; + gchar *dbg_str; + + /* fixed header + CRC == 16 */ + if (GST_BUFFER_SIZE (section->buffer) < 23) { + GST_WARNING ("PID %d invalid NIT size %d", + section->pid, section->section_length); + goto error; + } + + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); + + section->table_id = *data++; + section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + if (data + section->section_length != end) { + GST_WARNING ("PID %d invalid NIT section length %d expected %d", + section->pid, section->section_length, end - data); + goto error; + } + + network_id = GST_READ_UINT16_BE (data); + data += 2; + + tmp = *data++; + section->version_number = (tmp >> 1) & 0x1F; + section->current_next_indicator = tmp & 0x01; + + /* skip section_number and last_section_number */ + data += 2; + + descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + nit = gst_structure_new ("nit", + "network-id", G_TYPE_UINT, network_id, + "version-number", G_TYPE_UINT, section->version_number, + "current-next-indicator", G_TYPE_UINT, section->current_next_indicator, + NULL); + + /* see if the buffer is large enough */ + if (descriptors_loop_length) { + if (data + descriptors_loop_length > end - 4) { + GST_WARNING ("PID %d invalid NIT descriptors loop length %d", + section->pid, descriptors_loop_length); + gst_structure_free (nit); + goto error; + } + + descriptors = g_value_array_new (0); + if (!mpegts_packetizer_parse_descriptors (packetizer, + &data, data + descriptors_loop_length, descriptors)) { + gst_structure_free (nit); + g_value_array_free (descriptors); + goto error; + } + + gst_structure_set (nit, "descriptors", G_TYPE_VALUE_ARRAY, descriptors, + NULL); + g_value_array_free (descriptors); + } + + transport_stream_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + g_value_init (&transports, GST_TYPE_LIST); + /* read up to the CRC */ + while (transport_stream_loop_length - 4 > 0) { + gchar *transport_name; + + entry_begin = data; + + if (transport_stream_loop_length < 10) { + /* each entry must be at least 6 bytes (+ 4bytes CRC) */ + GST_WARNING ("PID %d invalid NIT entry size %d", + section->pid, transport_stream_loop_length); goto error; } - GST_INFO ("PMT PID %d program_number %d pid %d", - section->pid, program_number, pid); + transport_stream_id = GST_READ_UINT16_BE (data); + data += 2; + + original_network_id = GST_READ_UINT16_BE (data); + data += 2; - stream_info = mpegts_pmt_stream_info_new (pid, stream_type); + descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; - /* parse stream level descriptors */ - while (stream_info_length > 0) { - tag = *data++; - length = *data++; - stream_info_length -= 2; + transport_name = g_strdup_printf ("transport-%d", transport_stream_id); + transport = gst_structure_new (transport_name, + "transport-stream-id", G_TYPE_UINT, transport_stream_id, + "original-network-id", G_TYPE_UINT, original_network_id, NULL); + g_free (transport_name); + + if (descriptors_loop_length) { + if (data + descriptors_loop_length > end - 4) { + GST_WARNING ("PID %d invalid NIT entry %d descriptors loop length %d", + section->pid, transport_stream_id, descriptors_loop_length); + gst_structure_free (transport); + goto error; + } - if (length > stream_info_length) { - GST_WARNING ("PID %d invalid descriptor length %d left %d", - section->pid, length, stream_info_length); - g_object_unref (stream_info); + descriptors = g_value_array_new (0); + if (!mpegts_packetizer_parse_descriptors (packetizer, + &data, data + descriptors_loop_length, descriptors)) { + gst_structure_free (transport); + g_value_array_free (descriptors); goto error; } - mpegts_pmt_stream_info_add_descriptor (stream_info, - (const gchar *) data - 2, 2 + length); - data += length; - stream_info_length -= length; + gst_structure_set (transport, "descriptors", G_TYPE_VALUE_ARRAY, + descriptors, NULL); + g_value_array_free (descriptors); } - /* adds a ref to stream_info */ - mpegts_pmt_info_add_stream (pmt, stream_info); - g_object_unref (stream_info); + g_value_init (&transport_value, GST_TYPE_STRUCTURE); + g_value_take_boxed (&transport_value, transport); + gst_value_list_append_value (&transports, &transport_value); + g_value_unset (&transport_value); + + transport_stream_loop_length -= data - entry_begin; } - g_assert (data == end - 4); + if (data != end - 4) { + GST_WARNING ("PID %d invalid NIT parsed %d length %d", + section->pid, data - GST_BUFFER_DATA (section->buffer), + GST_BUFFER_SIZE (section->buffer)); + goto error; + } + + gst_structure_set_value (nit, "transports", &transports); + g_value_unset (&transports); - return G_OBJECT (pmt); + dbg_str = gst_structure_to_string (nit); + GST_DEBUG ("NIT %s", dbg_str); + g_free (dbg_str); + + return nit; error: - if (pmt) - g_object_unref (pmt); + if (nit) + gst_structure_free (nit); + + if (GST_VALUE_HOLDS_LIST (&transports)) + g_value_unset (&transports); + + return NULL; +} + +GstStructure * +mpegts_packetizer_parse_sdt (MpegTSPacketizer * packetizer, + MpegTSPacketizerSection * section) +{ + GstStructure *sdt = NULL, *service = NULL; + guint8 *data, *end, *entry_begin; + guint16 transport_stream_id, original_network_id, service_id; + guint tmp; + guint sdt_info_length; + gboolean EIT_schedule, EIT_present_following; + guint8 running_status; + gboolean scrambled; + guint descriptors_loop_length; + GValue services = { 0 }; + GValueArray *descriptors = NULL; + GValue service_value = { 0 }; + gchar *dbg_str; + + /* fixed header + CRC == 16 */ + if (GST_BUFFER_SIZE (section->buffer) < 14) { + GST_WARNING ("PID %d invalid SDT size %d", + section->pid, section->section_length); + goto error; + } + + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); + + section->table_id = *data++; + section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + if (data + section->section_length != end) { + GST_WARNING ("PID %d invalid SDT section length %d expected %d", + section->pid, section->section_length, end - data); + goto error; + } + + transport_stream_id = GST_READ_UINT16_BE (data); + data += 2; + + tmp = *data++; + section->version_number = (tmp >> 1) & 0x1F; + section->current_next_indicator = tmp & 0x01; + + /* skip section_number and last_section_number */ + data += 2; + + original_network_id = GST_READ_UINT16_BE (data); + data += 2; + + /* skip reserved byte */ + data += 1; + + sdt = gst_structure_new ("sdt", + "transport-stream-id", G_TYPE_UINT, transport_stream_id, + "version-number", G_TYPE_UINT, section->version_number, + "current-next-indicator", G_TYPE_UINT, section->current_next_indicator, + "original-network-id", G_TYPE_UINT, original_network_id, NULL); + + sdt_info_length = section->section_length - 8; + g_value_init (&services, GST_TYPE_LIST); + /* read up to the CRC */ + while (sdt_info_length - 4 > 0) { + gchar *service_name; + + entry_begin = data; + + if (sdt_info_length < 9) { + /* each entry must be at least 5 bytes (+4 bytes for the CRC) */ + GST_WARNING ("PID %d invalid SDT entry size %d", + section->pid, sdt_info_length); + goto error; + } + + service_id = GST_READ_UINT16_BE (data); + data += 2; + + /* reserved */ + data += 1; + + tmp = GST_READ_UINT16_BE (data); + data += 2; + + EIT_schedule = (tmp >> 15); + EIT_present_following = (tmp >> 14) & 0x01; + running_status = (tmp >> 5) & 0x03; + scrambled = (tmp >> 4) & 0x01; + descriptors_loop_length = tmp & 0x0FFF; + + service_name = g_strdup_printf ("service-%d", service_id); + service = gst_structure_new (service_name, NULL); + g_free (service_name); + + if (descriptors_loop_length) { + if (data + descriptors_loop_length > end - 4) { + GST_WARNING ("PID %d invalid SDT entry %d descriptors loop length %d", + section->pid, service_id, descriptors_loop_length); + gst_structure_free (service); + goto error; + } + + descriptors = g_value_array_new (0); + if (!mpegts_packetizer_parse_descriptors (packetizer, + &data, data + descriptors_loop_length, descriptors)) { + gst_structure_free (service); + g_value_array_free (descriptors); + goto error; + } + + gst_structure_set (service, "descriptors", G_TYPE_VALUE_ARRAY, + descriptors, NULL); + g_value_array_free (descriptors); + } + + g_value_init (&service_value, GST_TYPE_STRUCTURE); + g_value_take_boxed (&service_value, service); + gst_value_list_append_value (&services, &service_value); + g_value_unset (&service_value); + + sdt_info_length -= data - entry_begin; + } + + if (data != end - 4) { + GST_WARNING ("PID %d invalid SDT parsed %d length %d", + section->pid, data - GST_BUFFER_DATA (section->buffer), + GST_BUFFER_SIZE (section->buffer)); + goto error; + } + + gst_structure_set_value (sdt, "services", &services); + g_value_unset (&services); + + dbg_str = gst_structure_to_string (sdt); + g_free (dbg_str); + + return sdt; + +error: + if (sdt) + gst_structure_free (sdt); + + if (GST_VALUE_HOLDS_LIST (&services)) + g_value_unset (&services); + + return NULL; +} + +GstStructure * +mpegts_packetizer_parse_eit (MpegTSPacketizer * packetizer, + MpegTSPacketizerSection * section) +{ + GstStructure *eit = NULL, *event = NULL; + guint service_id, last_table_id, segment_last_section_number; + guint transport_stream_id, original_network_id; + gboolean free_ca_mode; + guint event_id, running_status; + guint64 start_and_duration; + GstClockTime start_time, duration; + guint8 *data, *end; + guint16 descriptors_loop_length; + GValue events = { 0 }; + GValue event_value = { 0 }; + GValueArray *descriptors = NULL; + gchar *dbg_str, *event_name; + guint tmp; + + /* fixed header + CRC == 16 */ + if (GST_BUFFER_SIZE (section->buffer) < 18) { + GST_WARNING ("PID %d invalid EIT size %d", + section->pid, section->section_length); + goto error; + } + + data = GST_BUFFER_DATA (section->buffer); + end = data + GST_BUFFER_SIZE (section->buffer); + + section->table_id = *data++; + section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + if (data + section->section_length != end) { + GST_WARNING ("PID %d invalid EIT section length %d expected %d", + section->pid, section->section_length, end - data); + goto error; + } + + service_id = GST_READ_UINT16_BE (data); + data += 2; + + tmp = *data++; + section->version_number = (tmp >> 1) & 0x1F; + section->current_next_indicator = tmp & 0x01; + + /* skip section_number and last_section_number */ + data += 2; + + transport_stream_id = GST_READ_UINT16_BE (data); + data += 2; + original_network_id = GST_READ_UINT16_BE (data); + data += 2; + segment_last_section_number = *data; + data += 1; + last_table_id = *data; + data += 1; + + eit = gst_structure_new ("eit", + "version-number", G_TYPE_UINT, section->version_number, + "current-next-indicator", G_TYPE_UINT, section->current_next_indicator, + "service-id", G_TYPE_UINT, service_id, + "transport-stream-id", G_TYPE_UINT, transport_stream_id, + "original-network-id", G_TYPE_UINT, original_network_id, + "segment-last-section-number", G_TYPE_UINT, segment_last_section_number, + "last-table-id", G_TYPE_UINT, last_table_id, NULL); + + g_value_init (&events, GST_TYPE_LIST); + while (data < end - 4) { + /* 12 is the minimum entry size + CRC */ + if (end - data < 12 + 4) { + GST_WARNING ("PID %d invalid EIT entry length %d", + section->pid, end - 4 - data); + gst_structure_free (eit); + goto error; + } + + event_id = GST_READ_UINT16_BE (data); + data += 2; + start_and_duration = GST_READ_UINT64_BE (data); + start_time = start_and_duration >> 24; + duration = start_and_duration & 0xFFFFFF; + data += 8; + running_status = *data >> 5; + free_ca_mode = (*data >> 4) & 0x01; + descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + event_name = g_strdup_printf ("event-%d", event_id); + /* FIXME: parse the date */ + event = gst_structure_new (event_name, + "event-id", G_TYPE_UINT, event_id, + "start-time", G_TYPE_UINT, 0, + "duration", G_TYPE_UINT, 0, + "running-status", G_TYPE_UINT, running_status, + "free-ca-mode", G_TYPE_BOOLEAN, free_ca_mode, NULL); + g_free (event_name); + + if (descriptors_loop_length) { + if (data + descriptors_loop_length > end - 4) { + GST_WARNING ("PID %d invalid EIT descriptors loop length %d", + section->pid, descriptors_loop_length); + gst_structure_free (event); + goto error; + } + + descriptors = g_value_array_new (0); + if (!mpegts_packetizer_parse_descriptors (packetizer, + &data, data + descriptors_loop_length, descriptors)) { + gst_structure_free (event); + g_value_array_free (descriptors); + goto error; + } + gst_structure_set (event, "descriptors", G_TYPE_VALUE_ARRAY, descriptors, + NULL); + g_value_array_free (descriptors); + } + + g_value_init (&event_value, GST_TYPE_STRUCTURE); + g_value_take_boxed (&event_value, event); + gst_value_list_append_value (&events, &event_value); + g_value_unset (&event_value); + } + + if (data != end - 4) { + GST_WARNING ("PID %d invalid EIT parsed %d length %d", + section->pid, data - GST_BUFFER_DATA (section->buffer), + GST_BUFFER_SIZE (section->buffer)); + goto error; + } + + gst_structure_set_value (eit, "events", &events); + g_value_unset (&events); + + dbg_str = gst_structure_to_string (eit); + GST_DEBUG ("EIT %s", dbg_str); + g_free (dbg_str); + + return eit; + +error: + if (eit) + gst_structure_free (eit); + + if (GST_VALUE_HOLDS_LIST (&events)) + g_value_unset (&events); + return NULL; } @@ -611,6 +1131,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer, * section_length */ if (gst_adapter_available (stream->section_adapter) >= stream->section_length + 3) { + res = mpegts_packetizer_parse_section_header (packetizer, stream, section); |