mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 08:41:07 +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
|
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
|
||||||
|
|
||||||
|
|
|
@ -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 */ );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue