mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
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:
parent
92edd82c86
commit
10c929c795
10 changed files with 109 additions and 169 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */ );
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 < 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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue