* * gst_mpegts_section_get_tot()
* * %GstMpegtsTOT
*
+ * ## Selection Information Table (SIT)
+ * See:
+ * * gst_mpegts_section_get_sit()
+ * * %GstMpegtsSIT
+ * * %GstMpegtsSITService
+ *
* # API
*/
return (const GstMpegtsTOT *) section->cached_parsed;
}
+
+
+/* Selection Information Table (SIT) */
+
+static GstMpegtsSITService *
+_gst_mpegts_sit_service_copy (GstMpegtsSITService * sit)
+{
+ GstMpegtsSITService *copy = g_slice_dup (GstMpegtsSITService, sit);
+
+ copy->service_id = sit->service_id;
+ copy->running_status = sit->running_status;
+ copy->descriptors = g_ptr_array_ref (sit->descriptors);
+
+ return copy;
+}
+
+static void
+_gst_mpegts_sit_service_free (GstMpegtsSITService * sit)
+{
+ if (sit->descriptors)
+ g_ptr_array_unref (sit->descriptors);
+ g_slice_free (GstMpegtsSITService, sit);
+}
+
+G_DEFINE_BOXED_TYPE (GstMpegtsSITService, gst_mpegts_sit_service,
+ (GBoxedCopyFunc) _gst_mpegts_sit_service_copy,
+ (GFreeFunc) _gst_mpegts_sit_service_free);
+
+static GstMpegtsSIT *
+_gst_mpegts_sit_copy (GstMpegtsSIT * sit)
+{
+ GstMpegtsSIT *copy = g_slice_dup (GstMpegtsSIT, sit);
+
+ copy->services = g_ptr_array_ref (sit->services);
+ copy->descriptors = g_ptr_array_ref (sit->descriptors);
+
+ return copy;
+}
+
+static void
+_gst_mpegts_sit_free (GstMpegtsSIT * sit)
+{
+ g_ptr_array_unref (sit->services);
+ g_ptr_array_unref (sit->descriptors);
+ g_slice_free (GstMpegtsSIT, sit);
+}
+
+G_DEFINE_BOXED_TYPE (GstMpegtsSIT, gst_mpegts_sit,
+ (GBoxedCopyFunc) _gst_mpegts_sit_copy, (GFreeFunc) _gst_mpegts_sit_free);
+
+
+static gpointer
+_parse_sit (GstMpegtsSection * section)
+{
+ GstMpegtsSIT *sit = NULL;
+ guint i = 0, allocated_services = 8;
+ guint8 *data, *end, *entry_begin;
+ guint sit_info_length;
+ guint descriptors_loop_length;
+
+ GST_DEBUG ("SIT");
+
+ sit = g_slice_new0 (GstMpegtsSIT);
+
+ data = section->data;
+ end = data + section->section_length;
+
+ /* Skip common fields */
+ data += 8;
+
+ descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0fff;
+ data += 2;
+ sit->descriptors =
+ gst_mpegts_parse_descriptors (data, descriptors_loop_length);
+ if (sit->descriptors == NULL)
+ goto error;
+ data += descriptors_loop_length;
+
+ sit_info_length = end - data;;
+ sit->services = g_ptr_array_new_full (allocated_services,
+ (GDestroyNotify) _gst_mpegts_sit_service_free);
+
+ /* read up to the CRC */
+ while (sit_info_length - 4 > 0) {
+ GstMpegtsSITService *service = g_slice_new0 (GstMpegtsSITService);
+ g_ptr_array_add (sit->services, service);
+
+ entry_begin = data;
+
+ if (sit_info_length - 4 < 4) {
+ /* each entry must be at least 4 bytes (+4 bytes for the CRC) */
+ GST_WARNING ("PID %d invalid SIT entry size %d",
+ section->pid, sit_info_length);
+ goto error;
+ }
+
+ service->service_id = GST_READ_UINT16_BE (data);
+ data += 2;
+
+ service->running_status = (*data >> 5) & 0x07;
+ descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0fff;
+ data += 2;
+
+ if (descriptors_loop_length && (data + descriptors_loop_length > end - 4)) {
+ GST_WARNING ("PID %d invalid SIT entry %d descriptors loop length %d",
+ section->pid, service->service_id, descriptors_loop_length);
+ goto error;
+ }
+ service->descriptors =
+ gst_mpegts_parse_descriptors (data, descriptors_loop_length);
+ if (!service->descriptors)
+ goto error;
+ data += descriptors_loop_length;
+
+ sit_info_length -= data - entry_begin;
+ i += 1;
+ }
+
+ if (data != end - 4) {
+ GST_WARNING ("PID %d invalid SIT parsed %d length %d",
+ section->pid, (gint) (data - section->data), section->section_length);
+ goto error;
+ }
+
+ return sit;
+
+error:
+ if (sit)
+ _gst_mpegts_sit_free (sit);
+
+ return NULL;
+}
+
+/**
+ * gst_mpegts_section_get_sit:
+ * @section: a #GstMpegtsSection of type %GST_MPEGTS_SECTION_SIT
+ *
+ * Returns the #GstMpegtsSIT contained in the @section.
+ *
+ * Returns: The #GstMpegtsSIT contained in the section, or %NULL if an error
+ * happened.
+ *
+ * Since: 1.20
+ */
+const GstMpegtsSIT *
+gst_mpegts_section_get_sit (GstMpegtsSection * section)
+{
+ g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_SIT, NULL);
+ g_return_val_if_fail (section->cached_parsed || section->data, NULL);
+
+ if (!section->cached_parsed)
+ section->cached_parsed =
+ __common_section_checks (section, 18, _parse_sit,
+ (GDestroyNotify) _gst_mpegts_sit_free);
+
+ return (const GstMpegtsSIT *) section->cached_parsed;
+}
GST_MPEGTS_API
const GstMpegtsTOT *gst_mpegts_section_get_tot (GstMpegtsSection *section);
+/* SIT */
+
+typedef struct _GstMpegtsSITService GstMpegtsSITService;
+/**
+ * GST_TYPE_MPEGTS_SIT_SERVICE:
+ *
+ * Since: 1.20
+ */
+#define GST_TYPE_MPEGTS_SIT_SERVICE (gst_mpegts_sit_service_get_type())
+
+typedef struct _GstMpegtsSIT GstMpegtsSIT;
+/**
+ * GST_TYPE_MPEGTS_SIT:
+ *
+ * Since: 1.20
+ */
+#define GST_TYPE_MPEGTS_SIT (gst_mpegts_sit_get_type())
+
+/**
+ * GstMpegtsSITService:
+ * @service_id: The Program number this table belongs to
+ * @running_status: Status of this service
+ * @descriptors: (element-type GstMpegtsDescriptor): List of descriptors
+ *
+ * SIT Service entry
+ *
+ * Since: 1.20
+ */
+struct _GstMpegtsSITService
+{
+ guint16 service_id;
+ GstMpegtsRunningStatus running_status;
+
+ GPtrArray *descriptors;
+};
+
+/**
+ * GstMpegtsSIT:
+ * @descriptors: (element-type GstMpegtsDescriptor): List of descriptors
+ * @services: (element-type GstMpegtsSITService): List of services
+ *
+ * Selection Information Table (EN 300 468)
+ *
+ * Since: 1.20
+ */
+struct _GstMpegtsSIT
+{
+ GPtrArray *descriptors;
+ GPtrArray *services;
+};
+
+
+GST_MPEGTS_API
+GType gst_mpegts_sit_get_type (void);
+
+GST_MPEGTS_API
+GType gst_mpegts_sit_service_get_type (void);
+
+GST_MPEGTS_API
+const GstMpegtsSIT *gst_mpegts_section_get_sit (GstMpegtsSection *section);
+
+
G_END_DECLS
#endif /* GST_MPEGTS_SECTION_H */
}
}
+
+static void
+dump_sit (GstMpegtsSection * section)
+{
+ const GstMpegtsSIT *sit = gst_mpegts_section_get_sit (section);
+ guint i, len;
+
+ g_assert (sit);
+
+ dump_descriptors (sit->descriptors, 7);
+ len = sit->services->len;
+ g_printf (" %d Services:\n", len);
+ for (i = 0; i < len; i++) {
+ GstMpegtsSITService *service = g_ptr_array_index (sit->services, i);
+ g_print
+ (" service_id:0x%04x, running_status:0x%02x (%s)\n",
+ service->service_id, service->running_status,
+ enum_name (GST_TYPE_MPEGTS_RUNNING_STATUS, service->running_status));
+ dump_descriptors (service->descriptors, 9);
+ }
+}
+
+
static void
dump_tdt (GstMpegtsSection * section)
{
case GST_MPEGTS_SECTION_EIT:
dump_eit (section);
break;
+ case GST_MPEGTS_SECTION_SIT:
+ dump_sit (section);
+ break;
case GST_MPEGTS_SECTION_ATSC_MGT:
dump_mgt (section);
break;