dvb: Switch to MPEG-TS SI library

Also serves as an example of using mpegts library from a plugin

https://bugzilla.gnome.org/show_bug.cgi?id=702724
This commit is contained in:
Edward Hervey 2013-06-23 08:44:08 +02:00
parent 92edd82c86
commit 10c929c795
10 changed files with 109 additions and 169 deletions

View file

@ -18,7 +18,9 @@ libgstdvb_la_SOURCES = \
parsechannels.c parsechannels.c
libgstdvb_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_CFLAGS) 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_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstdvb_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) libgstdvb_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
@ -36,4 +38,3 @@ noinst_HEADERS = \
camapplicationinfo.h \ camapplicationinfo.h \
camconditionalaccess.h \ camconditionalaccess.h \
parsechannels.h parsechannels.h

View file

@ -70,7 +70,7 @@ cam_conditional_access_destroy (CamConditionalAccess * cas)
} }
static CamReturn static CamReturn
send_ca_pmt (CamConditionalAccess * cas, GstStructure * pmt, send_ca_pmt (CamConditionalAccess * cas, GstMpegTSPMT * pmt,
guint8 list_management, guint8 cmd_id) guint8 list_management, guint8 cmd_id)
{ {
CamReturn ret; CamReturn ret;
@ -108,7 +108,7 @@ send_ca_pmt (CamConditionalAccess * cas, GstStructure * pmt,
CamReturn CamReturn
cam_conditional_access_set_pmt (CamConditionalAccess * cas, 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 */ ); return send_ca_pmt (cas, pmt, flag, 0x01 /* ok_descrambling */ );
} }

View file

@ -50,6 +50,6 @@ CamConditionalAccess *cam_conditional_access_new (void);
void cam_conditional_access_destroy (CamConditionalAccess *cas); void cam_conditional_access_destroy (CamConditionalAccess *cas);
CamReturn cam_conditional_access_set_pmt (CamConditionalAccess *cas, CamReturn cam_conditional_access_set_pmt (CamConditionalAccess *cas,
GstStructure *pmt, CamConditionalAccessPmtFlag flag); GstMpegTSPMT *pmt, CamConditionalAccessPmtFlag flag);
#endif /* CAM_CONDITIONAL_ACCESS_H */ #endif /* CAM_CONDITIONAL_ACCESS_H */

View file

@ -217,7 +217,7 @@ cam_device_ready (CamDevice * device)
void void
cam_device_set_pmt (CamDevice * device, 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 != NULL);
g_return_if_fail (device->state == CAM_DEVICE_STATE_OPEN); g_return_if_fail (device->state == CAM_DEVICE_STATE_OPEN);

View file

@ -64,6 +64,6 @@ void cam_device_close (CamDevice *device);
gboolean cam_device_ready (CamDevice *device); gboolean cam_device_ready (CamDevice *device);
void cam_device_poll (CamDevice *device); void cam_device_poll (CamDevice *device);
void cam_device_set_pmt (CamDevice *device, void cam_device_set_pmt (CamDevice *device,
GstStructure *pmt, CamConditionalAccessPmtFlag flag); GstMpegTSPMT *pmt, CamConditionalAccessPmtFlag flag);
#endif /* CAM_DEVICE_H */ #endif /* CAM_DEVICE_H */

View file

@ -32,7 +32,6 @@
#include "camswclient.h" #include "camswclient.h"
#include "cam.h" #include "cam.h"
#include "camutils.h"
#define GST_CAT_DEFAULT cam_debug_cat #define GST_CAT_DEFAULT cam_debug_cat
#define UNIX_PATH_MAX 108 #define UNIX_PATH_MAX 108
@ -111,7 +110,7 @@ cam_sw_client_close (CamSwClient * client)
} }
static void static void
send_ca_pmt (CamSwClient * client, GstStructure * pmt, send_ca_pmt (CamSwClient * client, GstMpegTSPMT * pmt,
guint8 list_management, guint8 cmd_id) guint8 list_management, guint8 cmd_id)
{ {
guint8 *buffer; guint8 *buffer;
@ -146,7 +145,7 @@ send_ca_pmt (CamSwClient * client, GstStructure * pmt,
} }
void 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 (client != NULL);
g_return_if_fail (pmt != NULL); g_return_if_fail (pmt != NULL);
@ -156,7 +155,7 @@ cam_sw_client_set_pmt (CamSwClient * client, GstStructure * pmt)
} }
void 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 (client != NULL);
g_return_if_fail (pmt != NULL); g_return_if_fail (pmt != NULL);

View file

@ -25,6 +25,7 @@
#define CAM_SW_CLIENT_H #define CAM_SW_CLIENT_H
#include <glib.h> #include <glib.h>
#include "camutils.h"
typedef enum 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); gboolean cam_sw_client_open (CamSwClient *sw_client, const char *sock_path);
void cam_sw_client_close (CamSwClient *sw_client); void cam_sw_client_close (CamSwClient *sw_client);
void cam_sw_client_set_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, GstStructure *pmt); void cam_sw_client_update_pmt (CamSwClient *sw_client, GstMpegTSPMT *pmt);
#endif /* CAM_SW_CLIENT_H */ #endif /* CAM_SW_CLIENT_H */

View file

@ -171,42 +171,34 @@ cam_read_length_field (guint8 * buff, guint * length)
*/ */
static guint static guint
get_ca_descriptors_length (GValueArray * descriptors) get_ca_descriptors_length (GArray * descriptors)
{ {
guint i; guint i;
guint nb_desc = descriptors->len;
guint len = 0; guint len = 0;
GValue *value;
GString *desc;
if (descriptors != NULL) { for (i = 0; i < nb_desc; i++) {
for (i = 0; i < descriptors->n_values; ++i) { GstMpegTSDescriptor *desc =
value = g_value_array_get_nth (descriptors, i); &g_array_index (descriptors, GstMpegTSDescriptor, i);
desc = (GString *) g_value_get_boxed (value); if (desc->descriptor_tag == 0x09)
len += desc->descriptor_length;
if (desc->str[0] == 0x09)
len += desc->len;
}
} }
return len; return len;
} }
static guint8 * static guint8 *
write_ca_descriptors (guint8 * body, GValueArray * descriptors) write_ca_descriptors (guint8 * body, GArray * descriptors)
{ {
guint i; guint i, nb_desc;
GValue *value;
GString *desc;
if (descriptors != NULL) { nb_desc = descriptors->len;
for (i = 0; i < descriptors->n_values; ++i) { for (i = 0; i < nb_desc; i++) {
value = g_value_array_get_nth (descriptors, i); GstMpegTSDescriptor *desc =
desc = (GString *) g_value_get_boxed (value); &g_array_index (descriptors, GstMpegTSDescriptor, i);
if (desc->descriptor_tag == 0x09) {
if (desc->str[0] == 0x09) { memcpy (body, desc->descriptor_data, desc->descriptor_length);
memcpy (body, desc->str, desc->len); body += desc->descriptor_length;
body += desc->len;
}
} }
} }
@ -214,59 +206,36 @@ write_ca_descriptors (guint8 * body, GValueArray * descriptors)
} }
guint8 * 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) guint * size)
{ {
GstMpegTSSection *section = (GstMpegTSSection *) pmt;
guint body_size = 0; guint body_size = 0;
guint8 *buffer; guint8 *buffer;
guint8 *body; guint8 *body;
GList *lengths = NULL; GList *lengths = NULL;
guint len = 0; guint len = 0;
const GValue *streams;
guint program_number;
guint version_number;
guint i; guint i;
const GValue *value;
GstStructure *stream;
GValueArray *program_descriptors = NULL;
GValueArray *stream_descriptors = NULL;
gst_structure_get_uint (pmt, "program-number", &program_number); /* get the length of program level CA_descriptor()s */
gst_structure_get_uint (pmt, "version-number", &version_number); len = get_ca_descriptors_length (pmt->descriptors);
streams = gst_structure_get_value (pmt, "streams"); if (len > 0)
value = gst_structure_get_value (pmt, "descriptors"); /* add one byte for the program level cmd_id */
if (value != NULL) { len += 1;
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)); lengths = g_list_append (lengths, GINT_TO_POINTER (len));
body_size += 6 + len; body_size += 6 + len;
/* get the length of stream level CA_descriptor()s */ for (i = 0; i < pmt->streams->len; i++) {
if (streams != NULL) { 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 = g_value_get_boxed (value);
value = gst_structure_get_value (stream, "descriptors"); len = get_ca_descriptors_length (pmtstream->descriptors);
len = 0; if (len > 0)
if (value != NULL) { /* one byte for the stream level cmd_id */
stream_descriptors = g_value_get_boxed (value); len += 1;
len = get_ca_descriptors_length (stream_descriptors); lengths = g_list_append (lengths, GINT_TO_POINTER (len));
if (len > 0) body_size += 5 + len;
/* 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); 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; *body++ = list_management;
/* program_number 16 uimsbf */ /* program_number 16 uimsbf */
GST_WRITE_UINT16_BE (body, program_number); GST_WRITE_UINT16_BE (body, section->subtable_extension);
body += 2; body += 2;
/* reserved 2 /* reserved 2
* version_number 5 * version_number 5
* current_next_indicator 1 * current_next_indicator 1
*/ */
*body++ = (version_number << 1) | 0x01; *body++ = (section->version_number << 1) | 0x01;
/* Reserved 4 /* Reserved 4
* program_info_length 12 * program_info_length 12
@ -298,22 +267,14 @@ cam_build_ca_pmt (GstStructure * pmt, guint8 list_management, guint8 cmd_id,
if (len != 0) { if (len != 0) {
*body++ = cmd_id; *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) { for (i = 0; i < pmt->streams->len; i++) {
guint stream_type; GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
guint stream_pid;
value = gst_value_list_get_value (streams, i); *body++ = pmtstream->stream_type;
stream = g_value_get_boxed (value); GST_WRITE_UINT16_BE (body, pmtstream->pid);
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 += 2; body += 2;
len = GPOINTER_TO_INT (lengths->data); len = GPOINTER_TO_INT (lengths->data);
lengths = g_list_delete_link (lengths, lengths); 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) { if (len != 0) {
*body++ = cmd_id; *body++ = cmd_id;
stream_descriptors = g_value_get_boxed (value); body = write_ca_descriptors (body, pmtstream->descriptors);
body = write_ca_descriptors (body, stream_descriptors);
} }
} }

View file

@ -26,6 +26,7 @@
#include <glib.h> #include <glib.h>
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/mpegts/mpegts.h>
#define TPDU_HEADER_SIZE_INDICATOR 0x80 #define TPDU_HEADER_SIZE_INDICATOR 0x80
@ -54,6 +55,6 @@ typedef enum
guint8 cam_calc_length_field_size (guint length); guint8 cam_calc_length_field_size (guint length);
guint8 cam_write_length_field (guint8 *buff, guint length); guint8 cam_write_length_field (guint8 *buff, guint length);
guint8 cam_read_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 */ #endif /* CAM_UTILS_H */

View file

@ -27,6 +27,7 @@
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <gst/mpegts/mpegts.h>
#include "dvbbasebin.h" #include "dvbbasebin.h"
#include "parsechannels.h" #include "parsechannels.h"
@ -84,8 +85,8 @@ typedef struct
gint program_number; gint program_number;
guint16 pmt_pid; guint16 pmt_pid;
guint16 pcr_pid; guint16 pcr_pid;
GstStructure *pmt; GstMpegTSPMT *pmt;
GstStructure *old_pmt; GstMpegTSPMT *old_pmt;
gboolean selected; gboolean selected;
gboolean pmt_active; gboolean pmt_active;
gboolean active; gboolean active;
@ -105,9 +106,9 @@ static GstStateChangeReturn dvb_base_bin_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message); static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message);
static void dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin, 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, 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, static GstPad *dvb_base_bin_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name, const GstCaps * caps); GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad); static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad);
@ -540,7 +541,7 @@ dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin)
{ {
CamConditionalAccessPmtFlag flag; CamConditionalAccessPmtFlag flag;
GList *walk; GList *walk;
GstStructure *pmt; GstMpegTSPMT *pmt;
walk = dvbbasebin->pmtlist; walk = dvbbasebin->pmtlist;
while (walk) { while (walk) {
@ -556,7 +557,7 @@ dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin)
flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_MORE; flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_MORE;
} }
pmt = GST_STRUCTURE (walk->data); pmt = (GstMpegTSPMT *) walk->data;
cam_device_set_pmt (dvbbasebin->hwcam, pmt, flag); cam_device_set_pmt (dvbbasebin->hwcam, pmt, flag);
walk = walk->next; walk = walk->next;
@ -660,30 +661,18 @@ dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin)
} }
static void 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; gint i;
const GValue *value;
GstStructure *stream_info;
DvbBaseBinStream *stream; DvbBaseBinStream *stream;
guint pid;
guint stream_type;
gst_structure_get_uint (pmt, "program-number", &program_number); for (i = 0; i < pmt->streams->len; i++) {
streams = gst_structure_get_value (pmt, "streams"); GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
for (i = 0; i < gst_value_list_get_size (streams); ++i) { stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
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);
if (stream == NULL) { if (stream == NULL) {
GST_WARNING_OBJECT (dvbbasebin, "removing unknown stream %d ??", pid); GST_WARNING_OBJECT (dvbbasebin, "removing unknown stream %d ??",
pmtstream->pid);
continue; continue;
} }
@ -692,32 +681,20 @@ dvb_base_bin_remove_pmt_streams (DvbBaseBin * dvbbasebin, GstStructure * pmt)
} }
static void static void
dvb_base_bin_add_pmt_streams (DvbBaseBin * dvbbasebin, GstStructure * pmt) dvb_base_bin_add_pmt_streams (DvbBaseBin * dvbbasebin, GstMpegTSPMT * pmt)
{ {
DvbBaseBinStream *stream; DvbBaseBinStream *stream;
const GValue *streams;
guint program_number;
gint i; gint i;
const GValue *value;
GstStructure *stream_info;
guint pid;
guint stream_type;
gst_structure_get_uint (pmt, "program-number", &program_number); for (i = 0; i < pmt->streams->len; i++) {
streams = gst_structure_get_value (pmt, "streams"); GstMpegTSPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
for (i = 0; i < gst_value_list_get_size (streams); ++i) { GST_DEBUG ("filtering stream %d stream_type %d", pmtstream->pid,
value = gst_value_list_get_value (streams, i); pmtstream->stream_type);
stream_info = g_value_get_boxed (value);
gst_structure_get_uint (stream_info, "pid", &pid); stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->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);
if (stream == NULL) if (stream == NULL)
stream = dvb_base_bin_add_stream (dvbbasebin, (guint16) pid); stream = dvb_base_bin_add_stream (dvbbasebin, pmtstream->pid);
++stream->usecount; ++stream->usecount;
} }
} }
@ -727,7 +704,6 @@ dvb_base_bin_activate_program (DvbBaseBin * dvbbasebin,
DvbBaseBinProgram * program) DvbBaseBinProgram * program)
{ {
DvbBaseBinStream *stream; DvbBaseBinStream *stream;
guint pid;
if (program->old_pmt) { if (program->old_pmt) {
dvb_base_bin_remove_pmt_streams (dvbbasebin, 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; guint16 old_pcr_pid;
old_pcr_pid = program->pcr_pid; old_pcr_pid = program->pcr_pid;
gst_structure_get_uint (program->pmt, "pcr-pid", &pid); program->pcr_pid = program->pmt->pcr_pid;
program->pcr_pid = pid;
if (old_pcr_pid != G_MAXUINT16 && old_pcr_pid != program->pcr_pid) if (old_pcr_pid != G_MAXUINT16 && old_pcr_pid != program->pcr_pid)
dvb_base_bin_get_stream (dvbbasebin, old_pcr_pid)->usecount--; 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); dvbbasebin = GST_DVB_BASE_BIN (bin);
if (message->type == GST_MESSAGE_ELEMENT && if (GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) {
GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) { GstMpegTSSection *section = gst_message_parse_mpegts_section (message);
const GstStructure *s = gst_message_get_structure (message);
const gchar *structure_name = gst_structure_get_name (s);
if (strcmp (structure_name, "pat") == 0) if (section) {
dvb_base_bin_pat_info_cb (dvbbasebin, s); switch (GST_MPEGTS_SECTION_TYPE (section)) {
else if (strcmp (structure_name, "pmt") == 0) case GST_MPEGTS_SECTION_PAT:
dvb_base_bin_pmt_info_cb (dvbbasebin, s); 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 */ /* chain up */
@ -818,34 +800,29 @@ dvb_base_bin_handle_message (GstBin * bin, GstMessage * message)
static void static void
dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin, dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin, GstMpegTSSection * section)
const GstStructure * pat_info)
{ {
GArray *pat;
DvbBaseBinProgram *program; DvbBaseBinProgram *program;
DvbBaseBinStream *stream; DvbBaseBinStream *stream;
const GValue *value;
GstStructure *program_info;
guint program_number;
guint pid;
guint old_pmt_pid; guint old_pmt_pid;
gint i; gint i;
gboolean rebuild_filter = FALSE; gboolean rebuild_filter = FALSE;
const GValue *programs;
programs = gst_structure_get_value (pat_info, "programs"); if (!(pat = gst_mpegts_section_get_pat (section))) {
for (i = 0; i < gst_value_list_get_size (programs); ++i) { GST_WARNING_OBJECT (dvbbasebin, "got invalid PAT");
value = gst_value_list_get_value (programs, i); return;
program_info = g_value_get_boxed (value); }
gst_structure_get_uint (program_info, "program-number", &program_number); for (i = 0; i < pat->len; i++) {
gst_structure_get_uint (program_info, "pid", &pid); 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) 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; old_pmt_pid = program->pmt_pid;
program->pmt_pid = pid; program->pmt_pid = patp->network_or_program_map_PID;
if (program->selected) { if (program->selected) {
/* PAT update */ /* PAT update */
@ -867,12 +844,13 @@ dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin,
} }
static void 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; DvbBaseBinProgram *program;
guint program_number; 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); program = dvb_base_bin_get_program (dvbbasebin, program_number);
if (program == NULL) { if (program == NULL) {
@ -882,7 +860,7 @@ dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, const GstStructure * pmt)
} }
program->old_pmt = program->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 /* activate the program if it's selected and either it's not active or its pmt
* changed */ * changed */
@ -890,7 +868,7 @@ dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, const GstStructure * pmt)
dvb_base_bin_activate_program (dvbbasebin, program); dvb_base_bin_activate_program (dvbbasebin, program);
if (program->old_pmt) { if (program->old_pmt) {
gst_structure_free (program->old_pmt); gst_mpegts_section_unref (program->old_pmt);
program->old_pmt = NULL; program->old_pmt = NULL;
} }
} }
@ -987,7 +965,7 @@ dvb_base_bin_program_destroy (gpointer data)
program = (DvbBaseBinProgram *) data; program = (DvbBaseBinProgram *) data;
if (program->pmt) if (program->pmt)
gst_structure_free (program->pmt); gst_mpegts_section_unref (program->pmt);
g_free (program); g_free (program);
} }