diff --git a/sys/dvb/Makefile.am b/sys/dvb/Makefile.am index 2369652e26..8ff9eddf6a 100644 --- a/sys/dvb/Makefile.am +++ b/sys/dvb/Makefile.am @@ -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 - diff --git a/sys/dvb/camconditionalaccess.c b/sys/dvb/camconditionalaccess.c index 6d8bf2974c..d61c83b928 100644 --- a/sys/dvb/camconditionalaccess.c +++ b/sys/dvb/camconditionalaccess.c @@ -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 */ ); } diff --git a/sys/dvb/camconditionalaccess.h b/sys/dvb/camconditionalaccess.h index b01701fbb7..c3ba492cea 100644 --- a/sys/dvb/camconditionalaccess.h +++ b/sys/dvb/camconditionalaccess.h @@ -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 */ diff --git a/sys/dvb/camdevice.c b/sys/dvb/camdevice.c index f1e061aa39..049fc0f31e 100644 --- a/sys/dvb/camdevice.c +++ b/sys/dvb/camdevice.c @@ -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); diff --git a/sys/dvb/camdevice.h b/sys/dvb/camdevice.h index fb65f15a47..06933bc14f 100644 --- a/sys/dvb/camdevice.h +++ b/sys/dvb/camdevice.h @@ -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 */ diff --git a/sys/dvb/camswclient.c b/sys/dvb/camswclient.c index 330dc250f5..a8fb4ffd80 100644 --- a/sys/dvb/camswclient.c +++ b/sys/dvb/camswclient.c @@ -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); diff --git a/sys/dvb/camswclient.h b/sys/dvb/camswclient.h index 12ecb06688..199d9b8ced 100644 --- a/sys/dvb/camswclient.h +++ b/sys/dvb/camswclient.h @@ -25,6 +25,7 @@ #define CAM_SW_CLIENT_H #include +#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 */ diff --git a/sys/dvb/camutils.c b/sys/dvb/camutils.c index 2a530c48e7..8d5e20fab0 100644 --- a/sys/dvb/camutils.c +++ b/sys/dvb/camutils.c @@ -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; + guint i, nb_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; - } + 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; - } + /* 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; + 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); + for (i = 0; i < pmt->streams->len; i++) { + GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i); - value = gst_structure_get_value (stream, "descriptors"); - len = 0; - if (value != NULL) { - stream_descriptors = g_value_get_boxed (value); + len = get_ca_descriptors_length (pmtstream->descriptors); + if (len > 0) + /* one byte for the stream level cmd_id */ + len += 1; - len = get_ca_descriptors_length (stream_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; - - } + 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; + for (i = 0; i < pmt->streams->len; i++) { + GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i); - 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"); - - *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); } } diff --git a/sys/dvb/camutils.h b/sys/dvb/camutils.h index 324b504d02..10227e47b1 100644 --- a/sys/dvb/camutils.h +++ b/sys/dvb/camutils.h @@ -26,6 +26,7 @@ #include #include +#include #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 */ diff --git a/sys/dvb/dvbbasebin.c b/sys/dvb/dvbbasebin.c index 5361a0b354..3df70f18b4 100644 --- a/sys/dvb/dvbbasebin.c +++ b/sys/dvb/dvbbasebin.c @@ -27,6 +27,7 @@ #endif #include #include +#include #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 < 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_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 (GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) { + GstMpegTSSection *section = gst_message_parse_mpegts_section (message); - 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 (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); }