dvb: Switch to MPEG-TS SI library
authorEdward Hervey <edward@collabora.com>
Sun, 23 Jun 2013 06:44:08 +0000 (08:44 +0200)
committerEdward Hervey <edward@collabora.com>
Wed, 3 Jul 2013 07:17:25 +0000 (09:17 +0200)
Also serves as an example of using mpegts library from a plugin

https://bugzilla.gnome.org/show_bug.cgi?id=702724

sys/dvb/Makefile.am
sys/dvb/camconditionalaccess.c
sys/dvb/camconditionalaccess.h
sys/dvb/camdevice.c
sys/dvb/camdevice.h
sys/dvb/camswclient.c
sys/dvb/camswclient.h
sys/dvb/camutils.c
sys/dvb/camutils.h
sys/dvb/dvbbasebin.c

index 2369652..8ff9edd 100644 (file)
@@ -18,7 +18,9 @@ libgstdvb_la_SOURCES = \
        parsechannels.c
 
 libgstdvb_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_CFLAGS)
-libgstdvb_la_LIBADD = $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS)
+libgstdvb_la_LIBADD = \
+       $(top_builddir)/gst-libs/gst/mpegts/libgstmpegts-$(GST_API_VERSION).la \
+       $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS)
 libgstdvb_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstdvb_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
@@ -36,4 +38,3 @@ noinst_HEADERS = \
        camapplicationinfo.h \
        camconditionalaccess.h \
        parsechannels.h
-       
index 6d8bf29..d61c83b 100644 (file)
@@ -70,7 +70,7 @@ cam_conditional_access_destroy (CamConditionalAccess * cas)
 }
 
 static CamReturn
-send_ca_pmt (CamConditionalAccess * cas, GstStructure * pmt,
+send_ca_pmt (CamConditionalAccess * cas, GstMpegTSPMT * pmt,
     guint8 list_management, guint8 cmd_id)
 {
   CamReturn ret;
@@ -108,7 +108,7 @@ send_ca_pmt (CamConditionalAccess * cas, GstStructure * pmt,
 
 CamReturn
 cam_conditional_access_set_pmt (CamConditionalAccess * cas,
-    GstStructure * pmt, CamConditionalAccessPmtFlag flag)
+    GstMpegTSPMT * pmt, CamConditionalAccessPmtFlag flag)
 {
   return send_ca_pmt (cas, pmt, flag, 0x01 /* ok_descrambling */ );
 }
index b01701f..c3ba492 100644 (file)
@@ -50,6 +50,6 @@ CamConditionalAccess *cam_conditional_access_new (void);
 void cam_conditional_access_destroy (CamConditionalAccess *cas);
 
 CamReturn cam_conditional_access_set_pmt (CamConditionalAccess *cas,
-  GstStructure *pmt, CamConditionalAccessPmtFlag flag);
+  GstMpegTSPMT *pmt, CamConditionalAccessPmtFlag flag);
 
 #endif /* CAM_CONDITIONAL_ACCESS_H */
index f1e061a..049fc0f 100644 (file)
@@ -217,7 +217,7 @@ cam_device_ready (CamDevice * device)
 
 void
 cam_device_set_pmt (CamDevice * device,
-    GstStructure * pmt, CamConditionalAccessPmtFlag flag)
+    GstMpegTSPMT * pmt, CamConditionalAccessPmtFlag flag)
 {
   g_return_if_fail (device != NULL);
   g_return_if_fail (device->state == CAM_DEVICE_STATE_OPEN);
index fb65f15..06933bc 100644 (file)
@@ -64,6 +64,6 @@ void cam_device_close (CamDevice *device);
 gboolean cam_device_ready (CamDevice *device);
 void cam_device_poll (CamDevice *device);
 void cam_device_set_pmt (CamDevice *device,
-  GstStructure *pmt, CamConditionalAccessPmtFlag flag);
+  GstMpegTSPMT *pmt, CamConditionalAccessPmtFlag flag);
 
 #endif /* CAM_DEVICE_H */
index 330dc25..a8fb4ff 100644 (file)
@@ -32,7 +32,6 @@
 
 #include "camswclient.h"
 #include "cam.h"
-#include "camutils.h"
 
 #define GST_CAT_DEFAULT cam_debug_cat
 #define UNIX_PATH_MAX 108
@@ -111,7 +110,7 @@ cam_sw_client_close (CamSwClient * client)
 }
 
 static void
-send_ca_pmt (CamSwClient * client, GstStructure * pmt,
+send_ca_pmt (CamSwClient * client, GstMpegTSPMT * pmt,
     guint8 list_management, guint8 cmd_id)
 {
   guint8 *buffer;
@@ -146,7 +145,7 @@ send_ca_pmt (CamSwClient * client, GstStructure * pmt,
 }
 
 void
-cam_sw_client_set_pmt (CamSwClient * client, GstStructure * pmt)
+cam_sw_client_set_pmt (CamSwClient * client, GstMpegTSPMT * pmt)
 {
   g_return_if_fail (client != NULL);
   g_return_if_fail (pmt != NULL);
@@ -156,7 +155,7 @@ cam_sw_client_set_pmt (CamSwClient * client, GstStructure * pmt)
 }
 
 void
-cam_sw_client_update_pmt (CamSwClient * client, GstStructure * pmt)
+cam_sw_client_update_pmt (CamSwClient * client, GstMpegTSPMT * pmt)
 {
   g_return_if_fail (client != NULL);
   g_return_if_fail (pmt != NULL);
index 12ecb06..199d9b8 100644 (file)
@@ -25,6 +25,7 @@
 #define CAM_SW_CLIENT_H
 
 #include <glib.h>
+#include "camutils.h"
 
 typedef enum
 {
@@ -47,7 +48,7 @@ void cam_sw_client_free (CamSwClient *sw_client);
 gboolean cam_sw_client_open (CamSwClient *sw_client, const char *sock_path);
 void cam_sw_client_close (CamSwClient *sw_client);
 
-void cam_sw_client_set_pmt (CamSwClient *sw_client, GstStructure *pmt);
-void cam_sw_client_update_pmt (CamSwClient *sw_client, GstStructure *pmt);
+void cam_sw_client_set_pmt (CamSwClient *sw_client, GstMpegTSPMT *pmt);
+void cam_sw_client_update_pmt (CamSwClient *sw_client, GstMpegTSPMT *pmt);
 
 #endif /* CAM_SW_CLIENT_H */
index 2a530c4..8d5e20f 100644 (file)
@@ -171,42 +171,34 @@ cam_read_length_field (guint8 * buff, guint * length)
  */
 
 static guint
-get_ca_descriptors_length (GValueArray * descriptors)
+get_ca_descriptors_length (GArray * descriptors)
 {
   guint i;
+  guint nb_desc = descriptors->len;
   guint len = 0;
-  GValue *value;
-  GString *desc;
 
-  if (descriptors != NULL) {
-    for (i = 0; i < descriptors->n_values; ++i) {
-      value = g_value_array_get_nth (descriptors, i);
-      desc = (GString *) g_value_get_boxed (value);
-
-      if (desc->str[0] == 0x09)
-        len += desc->len;
-    }
+  for (i = 0; i < nb_desc; i++) {
+    GstMpegTSDescriptor *desc =
+        &g_array_index (descriptors, GstMpegTSDescriptor, i);
+    if (desc->descriptor_tag == 0x09)
+      len += desc->descriptor_length;
   }
 
   return len;
 }
 
 static guint8 *
-write_ca_descriptors (guint8 * body, GValueArray * descriptors)
+write_ca_descriptors (guint8 * body, GArray * descriptors)
 {
-  guint i;
-  GValue *value;
-  GString *desc;
-
-  if (descriptors != NULL) {
-    for (i = 0; i < descriptors->n_values; ++i) {
-      value = g_value_array_get_nth (descriptors, i);
-      desc = (GString *) g_value_get_boxed (value);
-
-      if (desc->str[0] == 0x09) {
-        memcpy (body, desc->str, desc->len);
-        body += desc->len;
-      }
+  guint i, nb_desc;
+
+  nb_desc = descriptors->len;
+  for (i = 0; i < nb_desc; i++) {
+    GstMpegTSDescriptor *desc =
+        &g_array_index (descriptors, GstMpegTSDescriptor, i);
+    if (desc->descriptor_tag == 0x09) {
+      memcpy (body, desc->descriptor_data, desc->descriptor_length);
+      body += desc->descriptor_length;
     }
   }
 
@@ -214,59 +206,36 @@ write_ca_descriptors (guint8 * body, GValueArray * descriptors)
 }
 
 guint8 *
-cam_build_ca_pmt (GstStructure * pmt, guint8 list_management, guint8 cmd_id,
+cam_build_ca_pmt (GstMpegTSPMT * pmt, guint8 list_management, guint8 cmd_id,
     guint * size)
 {
+  GstMpegTSSection *section = (GstMpegTSSection *) pmt;
   guint body_size = 0;
   guint8 *buffer;
   guint8 *body;
   GList *lengths = NULL;
   guint len = 0;
-  const GValue *streams;
-  guint program_number;
-  guint version_number;
   guint i;
-  const GValue *value;
-  GstStructure *stream;
-  GValueArray *program_descriptors = NULL;
-  GValueArray *stream_descriptors = NULL;
-
-  gst_structure_get_uint (pmt, "program-number", &program_number);
-  gst_structure_get_uint (pmt, "version-number", &version_number);
-  streams = gst_structure_get_value (pmt, "streams");
-  value = gst_structure_get_value (pmt, "descriptors");
-  if (value != NULL) {
-    program_descriptors = g_value_get_boxed (value);
-    /* get the length of program level CA_descriptor()s */
-    len = get_ca_descriptors_length (program_descriptors);
-    if (len > 0)
-      /* add one byte for the program level cmd_id */
-      len += 1;
-  }
-  lengths = g_list_append (lengths, GINT_TO_POINTER (len));
-  body_size += 6 + len;
 
-  /* get the length of stream level CA_descriptor()s */
-  if (streams != NULL) {
-    for (i = 0; i < gst_value_list_get_size (streams); ++i) {
-      value = gst_value_list_get_value (streams, i);
-      stream = g_value_get_boxed (value);
+  /* get the length of program level CA_descriptor()s */
+  len = get_ca_descriptors_length (pmt->descriptors);
+  if (len > 0)
+    /* add one byte for the program level cmd_id */
+    len += 1;
 
-      value = gst_structure_get_value (stream, "descriptors");
-      len = 0;
-      if (value != NULL) {
-        stream_descriptors = g_value_get_boxed (value);
+  lengths = g_list_append (lengths, GINT_TO_POINTER (len));
+  body_size += 6 + len;
 
-        len = get_ca_descriptors_length (stream_descriptors);
-        if (len > 0)
-          /* one byte for the stream level cmd_id */
-          len += 1;
-      }
+  for (i = 0; i < pmt->streams->len; i++) {
+    GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
 
-      lengths = g_list_append (lengths, GINT_TO_POINTER (len));
-      body_size += 5 + len;
+    len = get_ca_descriptors_length (pmtstream->descriptors);
+    if (len > 0)
+      /* one byte for the stream level cmd_id */
+      len += 1;
 
-    }
+    lengths = g_list_append (lengths, GINT_TO_POINTER (len));
+    body_size += 5 + len;
   }
 
   GST_DEBUG ("Body Size %d", body_size);
@@ -278,14 +247,14 @@ cam_build_ca_pmt (GstStructure * pmt, guint8 list_management, guint8 cmd_id,
   *body++ = list_management;
 
   /* program_number 16 uimsbf */
-  GST_WRITE_UINT16_BE (body, program_number);
+  GST_WRITE_UINT16_BE (body, section->subtable_extension);
   body += 2;
 
   /* reserved 2
    * version_number 5
    * current_next_indicator 1
    */
-  *body++ = (version_number << 1) | 0x01;
+  *body++ = (section->version_number << 1) | 0x01;
 
   /* Reserved 4
    * program_info_length 12
@@ -298,22 +267,14 @@ cam_build_ca_pmt (GstStructure * pmt, guint8 list_management, guint8 cmd_id,
   if (len != 0) {
     *body++ = cmd_id;
 
-    body = write_ca_descriptors (body, program_descriptors);
+    body = write_ca_descriptors (body, pmt->descriptors);
   }
 
-  for (i = 0; i < gst_value_list_get_size (streams); ++i) {
-    guint stream_type;
-    guint stream_pid;
-
-    value = gst_value_list_get_value (streams, i);
-    stream = g_value_get_boxed (value);
-
-    gst_structure_get_uint (stream, "stream-type", &stream_type);
-    gst_structure_get_uint (stream, "pid", &stream_pid);
-    value = gst_structure_get_value (stream, "descriptors");
+  for (i = 0; i < pmt->streams->len; i++) {
+    GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
 
-    *body++ = stream_type;
-    GST_WRITE_UINT16_BE (body, stream_pid);
+    *body++ = pmtstream->stream_type;
+    GST_WRITE_UINT16_BE (body, pmtstream->pid);
     body += 2;
     len = GPOINTER_TO_INT (lengths->data);
     lengths = g_list_delete_link (lengths, lengths);
@@ -322,8 +283,7 @@ cam_build_ca_pmt (GstStructure * pmt, guint8 list_management, guint8 cmd_id,
 
     if (len != 0) {
       *body++ = cmd_id;
-      stream_descriptors = g_value_get_boxed (value);
-      body = write_ca_descriptors (body, stream_descriptors);
+      body = write_ca_descriptors (body, pmtstream->descriptors);
     }
   }
 
index 324b504..10227e4 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <glib.h>
 #include <gst/gst.h>
+#include <gst/mpegts/mpegts.h>
 
 #define TPDU_HEADER_SIZE_INDICATOR 0x80
 
@@ -54,6 +55,6 @@ typedef enum
 guint8 cam_calc_length_field_size (guint length);
 guint8 cam_write_length_field (guint8 *buff, guint length);
 guint8 cam_read_length_field (guint8 *buff, guint *length);
-guint8 *cam_build_ca_pmt (GstStructure *pmt, guint8 list_management, guint8 cmd_id, guint *size);
+guint8 *cam_build_ca_pmt (GstMpegTSPMT *pmt, guint8 list_management, guint8 cmd_id, guint *size);
 
 #endif /* CAM_UTILS_H */
index 5361a0b..3df70f1 100644 (file)
@@ -27,6 +27,7 @@
 #endif
 #include <stdlib.h>
 #include <string.h>
+#include <gst/mpegts/mpegts.h>
 #include "dvbbasebin.h"
 #include "parsechannels.h"
 
@@ -84,8 +85,8 @@ typedef struct
   gint program_number;
   guint16 pmt_pid;
   guint16 pcr_pid;
-  GstStructure *pmt;
-  GstStructure *old_pmt;
+  GstMpegTSPMT *pmt;
+  GstMpegTSPMT *old_pmt;
   gboolean selected;
   gboolean pmt_active;
   gboolean active;
@@ -105,9 +106,9 @@ static GstStateChangeReturn dvb_base_bin_change_state (GstElement * element,
     GstStateChange transition);
 static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message);
 static void dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin,
-    const GstStructure * pat);
+    GstMpegTSSection * pat);
 static void dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin,
-    const GstStructure * pmt);
+    GstMpegTSSection * pmt);
 static GstPad *dvb_base_bin_request_new_pad (GstElement * element,
     GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad);
@@ -540,7 +541,7 @@ dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin)
 {
   CamConditionalAccessPmtFlag flag;
   GList *walk;
-  GstStructure *pmt;
+  GstMpegTSPMT *pmt;
 
   walk = dvbbasebin->pmtlist;
   while (walk) {
@@ -556,7 +557,7 @@ dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin)
         flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_MORE;
     }
 
-    pmt = GST_STRUCTURE (walk->data);
+    pmt = (GstMpegTSPMT *) walk->data;
     cam_device_set_pmt (dvbbasebin->hwcam, pmt, flag);
 
     walk = walk->next;
@@ -660,30 +661,18 @@ dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin)
 }
 
 static void
-dvb_base_bin_remove_pmt_streams (DvbBaseBin * dvbbasebin, GstStructure * pmt)
+dvb_base_bin_remove_pmt_streams (DvbBaseBin * dvbbasebin, GstMpegTSPMT * pmt)
 {
-  const GValue *streams;
-  guint program_number;
   gint i;
-  const GValue *value;
-  GstStructure *stream_info;
   DvbBaseBinStream *stream;
-  guint pid;
-  guint stream_type;
-
-  gst_structure_get_uint (pmt, "program-number", &program_number);
-  streams = gst_structure_get_value (pmt, "streams");
 
-  for (i = 0; i < gst_value_list_get_size (streams); ++i) {
-    value = gst_value_list_get_value (streams, i);
-    stream_info = g_value_get_boxed (value);
+  for (i = 0; i < pmt->streams->len; i++) {
+    GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
 
-    gst_structure_get_uint (stream_info, "pid", &pid);
-    gst_structure_get_uint (stream_info, "stream-type", &stream_type);
-
-    stream = dvb_base_bin_get_stream (dvbbasebin, (guint16) pid);
+    stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
     if (stream == NULL) {
-      GST_WARNING_OBJECT (dvbbasebin, "removing unknown stream %d ??", pid);
+      GST_WARNING_OBJECT (dvbbasebin, "removing unknown stream %d ??",
+          pmtstream->pid);
       continue;
     }
 
@@ -692,32 +681,20 @@ dvb_base_bin_remove_pmt_streams (DvbBaseBin * dvbbasebin, GstStructure * pmt)
 }
 
 static void
-dvb_base_bin_add_pmt_streams (DvbBaseBin * dvbbasebin, GstStructure * pmt)
+dvb_base_bin_add_pmt_streams (DvbBaseBin * dvbbasebin, GstMpegTSPMT * pmt)
 {
   DvbBaseBinStream *stream;
-  const GValue *streams;
-  guint program_number;
   gint i;
-  const GValue *value;
-  GstStructure *stream_info;
-  guint pid;
-  guint stream_type;
 
-  gst_structure_get_uint (pmt, "program-number", &program_number);
-  streams = gst_structure_get_value (pmt, "streams");
+  for (i = 0; i < pmt->streams->len; i++) {
+    GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
 
-  for (i = 0; i < gst_value_list_get_size (streams); ++i) {
-    value = gst_value_list_get_value (streams, i);
-    stream_info = g_value_get_boxed (value);
+    GST_DEBUG ("filtering stream %d stream_type %d", pmtstream->pid,
+        pmtstream->stream_type);
 
-    gst_structure_get_uint (stream_info, "pid", &pid);
-    gst_structure_get_uint (stream_info, "stream-type", &stream_type);
-    GST_DEBUG ("filtering stream %d stream_type %d", pid, stream_type);
-
-    stream = dvb_base_bin_get_stream (dvbbasebin, (guint16) pid);
+    stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
     if (stream == NULL)
-      stream = dvb_base_bin_add_stream (dvbbasebin, (guint16) pid);
-
+      stream = dvb_base_bin_add_stream (dvbbasebin, pmtstream->pid);
     ++stream->usecount;
   }
 }
@@ -727,7 +704,6 @@ dvb_base_bin_activate_program (DvbBaseBin * dvbbasebin,
     DvbBaseBinProgram * program)
 {
   DvbBaseBinStream *stream;
-  guint pid;
 
   if (program->old_pmt) {
     dvb_base_bin_remove_pmt_streams (dvbbasebin, program->old_pmt);
@@ -749,8 +725,7 @@ dvb_base_bin_activate_program (DvbBaseBin * dvbbasebin,
     guint16 old_pcr_pid;
 
     old_pcr_pid = program->pcr_pid;
-    gst_structure_get_uint (program->pmt, "pcr-pid", &pid);
-    program->pcr_pid = pid;
+    program->pcr_pid = program->pmt->pcr_pid;
     if (old_pcr_pid != G_MAXUINT16 && old_pcr_pid != program->pcr_pid)
       dvb_base_bin_get_stream (dvbbasebin, old_pcr_pid)->usecount--;
 
@@ -800,15 +775,22 @@ dvb_base_bin_handle_message (GstBin * bin, GstMessage * message)
 
   dvbbasebin = GST_DVB_BASE_BIN (bin);
 
-  if (message->type == GST_MESSAGE_ELEMENT &&
-      GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) {
-    const GstStructure *s = gst_message_get_structure (message);
-    const gchar *structure_name = gst_structure_get_name (s);
-
-    if (strcmp (structure_name, "pat") == 0)
-      dvb_base_bin_pat_info_cb (dvbbasebin, s);
-    else if (strcmp (structure_name, "pmt") == 0)
-      dvb_base_bin_pmt_info_cb (dvbbasebin, s);
+  if (GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) {
+    GstMpegTSSection *section = gst_message_parse_mpegts_section (message);
+
+    if (section) {
+      switch (GST_MPEGTS_SECTION_TYPE (section)) {
+        case GST_MPEGTS_SECTION_PAT:
+          dvb_base_bin_pat_info_cb (dvbbasebin, section);
+          break;
+        case GST_MPEGTS_SECTION_PMT:
+          dvb_base_bin_pmt_info_cb (dvbbasebin, section);
+          break;
+        default:
+          break;
+      }
+      gst_mpegts_section_unref (section);
+    }
   }
 
   /* chain up */
@@ -818,34 +800,29 @@ dvb_base_bin_handle_message (GstBin * bin, GstMessage * message)
 
 
 static void
-dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin,
-    const GstStructure * pat_info)
+dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin, GstMpegTSSection * section)
 {
+  GArray *pat;
   DvbBaseBinProgram *program;
   DvbBaseBinStream *stream;
-  const GValue *value;
-  GstStructure *program_info;
-  guint program_number;
-  guint pid;
   guint old_pmt_pid;
   gint i;
   gboolean rebuild_filter = FALSE;
-  const GValue *programs;
 
-  programs = gst_structure_get_value (pat_info, "programs");
-  for (i = 0; i < gst_value_list_get_size (programs); ++i) {
-    value = gst_value_list_get_value (programs, i);
-    program_info = g_value_get_boxed (value);
+  if (!(pat = gst_mpegts_section_get_pat (section))) {
+    GST_WARNING_OBJECT (dvbbasebin, "got invalid PAT");
+    return;
+  }
 
-    gst_structure_get_uint (program_info, "program-number", &program_number);
-    gst_structure_get_uint (program_info, "pid", &pid);
+  for (i = 0; i < pat->len; i++) {
+    GstMpegTSPatProgram *patp = &g_array_index (pat, GstMpegTSPatProgram, i);
 
-    program = dvb_base_bin_get_program (dvbbasebin, program_number);
+    program = dvb_base_bin_get_program (dvbbasebin, patp->program_number);
     if (program == NULL)
-      program = dvb_base_bin_add_program (dvbbasebin, program_number);
+      program = dvb_base_bin_add_program (dvbbasebin, patp->program_number);
 
     old_pmt_pid = program->pmt_pid;
-    program->pmt_pid = pid;
+    program->pmt_pid = patp->network_or_program_map_PID;
 
     if (program->selected) {
       /* PAT update */
@@ -867,12 +844,13 @@ dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin,
 }
 
 static void
-dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, const GstStructure * pmt)
+dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, GstMpegTSSection * section)
 {
+  GstMpegTSPMT *pmt = (GstMpegTSPMT *) section;
   DvbBaseBinProgram *program;
   guint program_number;
 
-  gst_structure_get_uint (pmt, "program-number", &program_number);
+  program_number = section->subtable_extension;
 
   program = dvb_base_bin_get_program (dvbbasebin, program_number);
   if (program == NULL) {
@@ -882,7 +860,7 @@ dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, const GstStructure * pmt)
   }
 
   program->old_pmt = program->pmt;
-  program->pmt = gst_structure_copy (pmt);
+  program->pmt = (GstMpegTSPMT *) gst_mpegts_section_ref (pmt);
 
   /* activate the program if it's selected and either it's not active or its pmt
    * changed */
@@ -890,7 +868,7 @@ dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, const GstStructure * pmt)
     dvb_base_bin_activate_program (dvbbasebin, program);
 
   if (program->old_pmt) {
-    gst_structure_free (program->old_pmt);
+    gst_mpegts_section_unref (program->old_pmt);
     program->old_pmt = NULL;
   }
 }
@@ -987,7 +965,7 @@ dvb_base_bin_program_destroy (gpointer data)
   program = (DvbBaseBinProgram *) data;
 
   if (program->pmt)
-    gst_structure_free (program->pmt);
+    gst_mpegts_section_unref (program->pmt);
 
   g_free (program);
 }