2007-10-16 17:38:05 +00:00
|
|
|
/*
|
|
|
|
* dvbbasebin.c -
|
|
|
|
* Copyright (C) 2007 Alessandro Decina
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Alessandro Decina <alessandro@nnva.org>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
2012-11-03 20:38:00 +00:00
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2007-10-16 17:38:05 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
2007-10-30 20:55:27 +00:00
|
|
|
#include <stdlib.h>
|
2007-10-16 17:38:05 +00:00
|
|
|
#include <string.h>
|
2013-06-23 06:44:08 +00:00
|
|
|
#include <gst/mpegts/mpegts.h>
|
2007-10-16 17:38:05 +00:00
|
|
|
#include "dvbbasebin.h"
|
2008-02-08 18:22:08 +00:00
|
|
|
#include "parsechannels.h"
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2013-04-21 13:13:45 +00:00
|
|
|
GST_DEBUG_CATEGORY (dvb_base_bin_debug);
|
2007-10-16 17:38:05 +00:00
|
|
|
#define GST_CAT_DEFAULT dvb_base_bin_debug
|
|
|
|
|
|
|
|
static GstStaticPadTemplate src_template =
|
2012-06-29 16:00:41 +00:00
|
|
|
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC,
|
|
|
|
GST_PAD_ALWAYS,
|
2007-10-16 17:38:05 +00:00
|
|
|
GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ")
|
|
|
|
);
|
|
|
|
|
|
|
|
static GstStaticPadTemplate program_template =
|
2011-11-04 11:22:37 +00:00
|
|
|
GST_STATIC_PAD_TEMPLATE ("program_%u", GST_PAD_SRC,
|
2012-06-29 16:00:41 +00:00
|
|
|
GST_PAD_REQUEST,
|
2007-10-16 17:38:05 +00:00
|
|
|
GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ")
|
|
|
|
);
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
/* FILL ME */
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
ARG_0,
|
|
|
|
PROP_ADAPTER,
|
|
|
|
PROP_FRONTEND,
|
2007-10-19 16:20:53 +00:00
|
|
|
PROP_DISEQC_SRC,
|
2007-10-16 17:38:05 +00:00
|
|
|
PROP_FREQUENCY,
|
|
|
|
PROP_POLARITY,
|
|
|
|
PROP_SYMBOL_RATE,
|
|
|
|
PROP_BANDWIDTH,
|
|
|
|
PROP_CODE_RATE_HP,
|
|
|
|
PROP_CODE_RATE_LP,
|
|
|
|
PROP_GUARD,
|
|
|
|
PROP_MODULATION,
|
|
|
|
PROP_TRANS_MODE,
|
|
|
|
PROP_HIERARCHY,
|
|
|
|
PROP_INVERSION,
|
|
|
|
PROP_PROGRAM_NUMBERS,
|
|
|
|
PROP_STATS_REPORTING_INTERVAL
|
|
|
|
/* FILL ME */
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
guint16 pid;
|
|
|
|
guint usecount;
|
|
|
|
} DvbBaseBinStream;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
gint program_number;
|
|
|
|
guint16 pmt_pid;
|
|
|
|
guint16 pcr_pid;
|
2013-07-05 11:53:06 +00:00
|
|
|
GstMpegTsSection *section;
|
|
|
|
GstMpegTsSection *old_section;
|
|
|
|
const GstMpegTsPMT *pmt;
|
|
|
|
const GstMpegTsPMT *old_pmt;
|
2007-10-16 17:38:05 +00:00
|
|
|
gboolean selected;
|
|
|
|
gboolean pmt_active;
|
|
|
|
gboolean active;
|
|
|
|
GstPad *ghost;
|
|
|
|
} DvbBaseBinProgram;
|
|
|
|
|
|
|
|
static void dvb_base_bin_set_property (GObject * object, guint prop_id,
|
|
|
|
const GValue * value, GParamSpec * pspec);
|
|
|
|
static void dvb_base_bin_get_property (GObject * object, guint prop_id,
|
|
|
|
GValue * value, GParamSpec * pspec);
|
|
|
|
static void dvb_base_bin_dispose (GObject * object);
|
|
|
|
static void dvb_base_bin_finalize (GObject * object);
|
|
|
|
|
2013-03-31 10:11:48 +00:00
|
|
|
static void dvb_base_bin_task (DvbBaseBin * basebin);
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
static GstStateChangeReturn dvb_base_bin_change_state (GstElement * element,
|
|
|
|
GstStateChange transition);
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message);
|
|
|
|
static void dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin,
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsSection * pat);
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
static void dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin,
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsSection * pmt);
|
2007-10-16 17:38:05 +00:00
|
|
|
static GstPad *dvb_base_bin_request_new_pad (GstElement * element,
|
2011-10-10 09:41:33 +00:00
|
|
|
GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
|
2007-10-16 17:38:05 +00:00
|
|
|
static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad);
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
static void dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin);
|
2012-06-29 16:00:41 +00:00
|
|
|
static void
|
|
|
|
dvb_base_bin_deactivate_program (DvbBaseBin * dvbbasebin,
|
|
|
|
DvbBaseBinProgram * program);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2008-02-08 18:22:08 +00:00
|
|
|
static void dvb_base_bin_uri_handler_init (gpointer g_iface,
|
|
|
|
gpointer iface_data);
|
|
|
|
|
2009-01-04 11:11:06 +00:00
|
|
|
static void dvb_base_bin_program_destroy (gpointer data);
|
|
|
|
|
2012-07-11 06:10:18 +00:00
|
|
|
#define dvb_base_bin_parent_class parent_class
|
|
|
|
G_DEFINE_TYPE_EXTENDED (DvbBaseBin, dvb_base_bin, GST_TYPE_BIN,
|
|
|
|
0,
|
|
|
|
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
|
|
|
|
dvb_base_bin_uri_handler_init));
|
|
|
|
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
static DvbBaseBinStream *
|
|
|
|
dvb_base_bin_add_stream (DvbBaseBin * dvbbasebin, guint16 pid)
|
|
|
|
{
|
|
|
|
DvbBaseBinStream *stream;
|
|
|
|
|
|
|
|
stream = g_new0 (DvbBaseBinStream, 1);
|
|
|
|
stream->pid = pid;
|
|
|
|
stream->usecount = 0;
|
|
|
|
|
|
|
|
g_hash_table_insert (dvbbasebin->streams,
|
|
|
|
GINT_TO_POINTER ((gint) pid), stream);
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DvbBaseBinStream *
|
|
|
|
dvb_base_bin_get_stream (DvbBaseBin * dvbbasebin, guint16 pid)
|
|
|
|
{
|
|
|
|
return (DvbBaseBinStream *) g_hash_table_lookup (dvbbasebin->streams,
|
|
|
|
GINT_TO_POINTER ((gint) pid));
|
|
|
|
}
|
|
|
|
|
|
|
|
static DvbBaseBinProgram *
|
|
|
|
dvb_base_bin_add_program (DvbBaseBin * dvbbasebin, gint program_number)
|
|
|
|
{
|
|
|
|
DvbBaseBinProgram *program;
|
|
|
|
|
|
|
|
program = g_new0 (DvbBaseBinProgram, 1);
|
|
|
|
program->program_number = program_number;
|
|
|
|
program->selected = FALSE;
|
|
|
|
program->active = FALSE;
|
|
|
|
program->pmt_pid = G_MAXUINT16;
|
|
|
|
program->pcr_pid = G_MAXUINT16;
|
|
|
|
program->pmt = NULL;
|
|
|
|
program->old_pmt = NULL;
|
|
|
|
|
|
|
|
g_hash_table_insert (dvbbasebin->programs,
|
|
|
|
GINT_TO_POINTER (program_number), program);
|
|
|
|
|
|
|
|
return program;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DvbBaseBinProgram *
|
|
|
|
dvb_base_bin_get_program (DvbBaseBin * dvbbasebin, gint program_number)
|
|
|
|
{
|
|
|
|
return (DvbBaseBinProgram *) g_hash_table_lookup (dvbbasebin->programs,
|
|
|
|
GINT_TO_POINTER (program_number));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
static guint signals [LAST_SIGNAL] = { 0 };
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_class_init (DvbBaseBinClass * klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class;
|
|
|
|
GstElementClass *element_class;
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
GstBinClass *bin_class;
|
2007-10-16 17:38:05 +00:00
|
|
|
GstElementFactory *dvbsrc_factory;
|
|
|
|
GObjectClass *dvbsrc_class;
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
guint prop_id;
|
|
|
|
const gchar *prop_name;
|
|
|
|
} ProxyedProperty;
|
|
|
|
ProxyedProperty *walk;
|
|
|
|
ProxyedProperty proxyed_properties[] = {
|
|
|
|
{PROP_ADAPTER, "adapter"},
|
|
|
|
{PROP_FRONTEND, "frontend"},
|
2007-10-19 16:20:53 +00:00
|
|
|
{PROP_DISEQC_SRC, "diseqc-source"},
|
2007-10-16 17:38:05 +00:00
|
|
|
{PROP_FREQUENCY, "frequency"},
|
|
|
|
{PROP_POLARITY, "polarity"},
|
|
|
|
{PROP_SYMBOL_RATE, "symbol-rate"},
|
|
|
|
{PROP_BANDWIDTH, "bandwidth"},
|
|
|
|
{PROP_CODE_RATE_HP, "code-rate-hp"},
|
|
|
|
{PROP_CODE_RATE_LP, "code-rate-lp"},
|
|
|
|
{PROP_GUARD, "guard"},
|
|
|
|
{PROP_MODULATION, "modulation"},
|
|
|
|
{PROP_TRANS_MODE, "trans-mode"},
|
|
|
|
{PROP_HIERARCHY, "hierarchy"},
|
|
|
|
{PROP_INVERSION, "inversion"},
|
|
|
|
{PROP_STATS_REPORTING_INTERVAL, "stats-reporting-interval"},
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
bin_class = GST_BIN_CLASS (klass);
|
|
|
|
bin_class->handle_message = dvb_base_bin_handle_message;
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
element_class = GST_ELEMENT_CLASS (klass);
|
2012-07-11 06:10:18 +00:00
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
element_class->change_state = dvb_base_bin_change_state;
|
2011-10-10 09:41:33 +00:00
|
|
|
element_class->request_new_pad = dvb_base_bin_request_new_pad;
|
|
|
|
element_class->release_pad = dvb_base_bin_release_pad;
|
|
|
|
|
|
|
|
gst_element_class_add_pad_template (element_class,
|
|
|
|
gst_static_pad_template_get (&program_template));
|
|
|
|
gst_element_class_add_pad_template (element_class,
|
|
|
|
gst_static_pad_template_get (&src_template));
|
|
|
|
|
2012-10-17 16:34:26 +00:00
|
|
|
gst_element_class_set_static_metadata (element_class, "DVB bin",
|
2011-10-10 09:41:33 +00:00
|
|
|
"Source/Bin/Video",
|
|
|
|
"Access descramble and split DVB streams",
|
|
|
|
"Alessandro Decina <alessandro@nnva.org>");
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
gobject_class->set_property = dvb_base_bin_set_property;
|
|
|
|
gobject_class->get_property = dvb_base_bin_get_property;
|
|
|
|
gobject_class->dispose = dvb_base_bin_dispose;
|
|
|
|
gobject_class->finalize = dvb_base_bin_finalize;
|
|
|
|
|
|
|
|
/* install dvbsrc properties */
|
|
|
|
dvbsrc_factory = gst_element_factory_find ("dvbsrc");
|
2012-05-22 17:11:29 +00:00
|
|
|
dvbsrc_class =
|
|
|
|
g_type_class_ref (gst_element_factory_get_element_type (dvbsrc_factory));
|
2007-10-16 17:38:05 +00:00
|
|
|
walk = proxyed_properties;
|
|
|
|
while (walk->prop_name != NULL) {
|
|
|
|
GParamSpec *pspec;
|
|
|
|
GParamSpec *our_pspec;
|
|
|
|
|
|
|
|
pspec = g_object_class_find_property (dvbsrc_class, walk->prop_name);
|
|
|
|
if (pspec != NULL) {
|
|
|
|
GType param_type = G_PARAM_SPEC_TYPE (pspec);
|
|
|
|
|
|
|
|
if (param_type == G_TYPE_PARAM_INT) {
|
|
|
|
GParamSpecInt *src_pspec = G_PARAM_SPEC_INT (pspec);
|
|
|
|
|
|
|
|
our_pspec = g_param_spec_int (g_param_spec_get_name (pspec),
|
|
|
|
g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
|
|
|
|
src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
|
|
|
|
pspec->flags);
|
|
|
|
} else if (param_type == G_TYPE_PARAM_UINT) {
|
|
|
|
GParamSpecUInt *src_pspec = G_PARAM_SPEC_UINT (pspec);
|
|
|
|
|
|
|
|
our_pspec = g_param_spec_uint (g_param_spec_get_name (pspec),
|
|
|
|
g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
|
|
|
|
src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
|
|
|
|
pspec->flags);
|
|
|
|
} else if (param_type == G_TYPE_PARAM_STRING) {
|
|
|
|
GParamSpecString *src_pspec = G_PARAM_SPEC_STRING (pspec);
|
|
|
|
|
|
|
|
our_pspec = g_param_spec_string (g_param_spec_get_name (pspec),
|
|
|
|
g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
|
|
|
|
src_pspec->default_value, pspec->flags);
|
|
|
|
} else if (param_type == G_TYPE_PARAM_ENUM) {
|
|
|
|
GParamSpecEnum *src_pspec = G_PARAM_SPEC_ENUM (pspec);
|
|
|
|
|
|
|
|
our_pspec = g_param_spec_enum (g_param_spec_get_name (pspec),
|
|
|
|
g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
|
|
|
|
pspec->value_type, src_pspec->default_value, pspec->flags);
|
|
|
|
} else {
|
2009-11-05 21:45:07 +00:00
|
|
|
GST_ERROR ("Unsupported property type %s for property %s",
|
|
|
|
g_type_name (param_type), g_param_spec_get_name (pspec));
|
2007-12-29 17:31:49 +00:00
|
|
|
++walk;
|
|
|
|
continue;
|
2007-10-16 17:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_object_class_install_property (gobject_class, walk->prop_id, our_pspec);
|
|
|
|
} else {
|
|
|
|
g_warning ("dvbsrc has no property named %s", walk->prop_name);
|
|
|
|
}
|
|
|
|
++walk;
|
|
|
|
}
|
|
|
|
g_type_class_unref (dvbsrc_class);
|
|
|
|
|
|
|
|
g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBERS,
|
|
|
|
g_param_spec_string ("program-numbers",
|
|
|
|
"Program Numbers",
|
|
|
|
"Colon separated list of programs", "", G_PARAM_READWRITE));
|
2011-10-10 09:41:33 +00:00
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_reset (DvbBaseBin * dvbbasebin)
|
|
|
|
{
|
|
|
|
if (dvbbasebin->hwcam) {
|
|
|
|
cam_device_close (dvbbasebin->hwcam);
|
|
|
|
cam_device_free (dvbbasebin->hwcam);
|
|
|
|
dvbbasebin->hwcam = NULL;
|
|
|
|
}
|
2013-03-31 10:11:48 +00:00
|
|
|
dvbbasebin->trycam = TRUE;
|
2007-10-16 17:38:05 +00:00
|
|
|
}
|
|
|
|
|
2010-11-18 17:42:38 +00:00
|
|
|
static gint16 initial_pids[] = { 0, 1, 0x10, 0x11, 0x12, 0x14, -1 };
|
2007-12-05 12:40:05 +00:00
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
static void
|
2011-10-10 09:41:33 +00:00
|
|
|
dvb_base_bin_init (DvbBaseBin * dvbbasebin)
|
2007-10-16 17:38:05 +00:00
|
|
|
{
|
2007-12-05 12:40:05 +00:00
|
|
|
DvbBaseBinStream *stream;
|
2012-06-29 16:00:41 +00:00
|
|
|
GstPad *ghost, *pad;
|
2007-12-05 12:40:05 +00:00
|
|
|
int i;
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
dvbbasebin->dvbsrc = gst_element_factory_make ("dvbsrc", NULL);
|
|
|
|
dvbbasebin->buffer_queue = gst_element_factory_make ("queue", NULL);
|
2012-06-29 16:00:41 +00:00
|
|
|
dvbbasebin->tsparse = gst_element_factory_make ("tsparse", NULL);
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
|
2012-06-29 16:00:41 +00:00
|
|
|
g_object_set (dvbbasebin->buffer_queue, "max-size-buffers", 0,
|
|
|
|
"max-size-bytes", 0, "max-size-time", 0, NULL);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
gst_bin_add_many (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc,
|
2012-06-29 16:00:41 +00:00
|
|
|
dvbbasebin->buffer_queue, dvbbasebin->tsparse, NULL);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
gst_element_link_many (dvbbasebin->dvbsrc,
|
2012-06-29 16:00:41 +00:00
|
|
|
dvbbasebin->buffer_queue, dvbbasebin->tsparse, NULL);
|
|
|
|
|
|
|
|
/* Expose tsparse source pad */
|
|
|
|
pad = gst_element_get_static_pad (dvbbasebin->tsparse, "src");
|
|
|
|
ghost = gst_ghost_pad_new ("src", pad);
|
|
|
|
gst_element_add_pad (GST_ELEMENT (dvbbasebin), ghost);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
dvbbasebin->programs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
2009-01-04 11:11:06 +00:00
|
|
|
NULL, dvb_base_bin_program_destroy);
|
2007-10-16 17:38:05 +00:00
|
|
|
dvbbasebin->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
|
|
|
NULL, g_free);
|
|
|
|
|
|
|
|
dvbbasebin->pmtlist = NULL;
|
|
|
|
dvbbasebin->pmtlist_changed = FALSE;
|
|
|
|
|
|
|
|
dvbbasebin->disposed = FALSE;
|
|
|
|
dvb_base_bin_reset (dvbbasebin);
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
|
2010-11-18 17:42:38 +00:00
|
|
|
/* add PAT, CAT, NIT, SDT, EIT, TDT to pids filter for dvbsrc */
|
2007-12-05 12:40:05 +00:00
|
|
|
i = 0;
|
|
|
|
while (initial_pids[i] >= 0) {
|
|
|
|
stream = dvb_base_bin_add_stream (dvbbasebin, (guint16) initial_pids[i]);
|
|
|
|
++stream->usecount;
|
|
|
|
i++;
|
|
|
|
}
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
dvb_base_bin_rebuild_filter (dvbbasebin);
|
2013-03-31 10:11:48 +00:00
|
|
|
|
|
|
|
g_rec_mutex_init (&dvbbasebin->lock);
|
|
|
|
dvbbasebin->task =
|
|
|
|
gst_task_new ((GstTaskFunction) dvb_base_bin_task, dvbbasebin, NULL);
|
|
|
|
gst_task_set_lock (dvbbasebin->task, &dvbbasebin->lock);
|
|
|
|
dvbbasebin->poll = gst_poll_new_timer ();
|
2007-10-16 17:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_dispose (GObject * object)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);
|
|
|
|
|
|
|
|
if (!dvbbasebin->disposed) {
|
|
|
|
/* remove mpegtsparse BEFORE dvbsrc, since the mpegtsparse::pad-removed
|
|
|
|
* signal handler uses dvbsrc */
|
|
|
|
dvb_base_bin_reset (dvbbasebin);
|
2012-06-29 16:00:41 +00:00
|
|
|
gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->tsparse);
|
2007-10-16 17:38:05 +00:00
|
|
|
gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc);
|
|
|
|
gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->buffer_queue);
|
|
|
|
dvbbasebin->disposed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (G_OBJECT_CLASS (parent_class)->dispose)
|
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_finalize (GObject * object)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);
|
|
|
|
|
|
|
|
g_hash_table_destroy (dvbbasebin->streams);
|
|
|
|
g_hash_table_destroy (dvbbasebin->programs);
|
2009-01-04 11:11:06 +00:00
|
|
|
g_list_free (dvbbasebin->pmtlist);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
if (G_OBJECT_CLASS (parent_class)->finalize)
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2012-06-29 16:00:41 +00:00
|
|
|
static void
|
|
|
|
dvb_base_bin_set_program_numbers (DvbBaseBin * dvbbasebin, const gchar * pn)
|
|
|
|
{
|
|
|
|
gchar **strv, **walk;
|
|
|
|
DvbBaseBinProgram *program;
|
|
|
|
|
|
|
|
/* Split up and update programs */
|
|
|
|
strv = g_strsplit (pn, ":", 0);
|
|
|
|
|
|
|
|
for (walk = strv; *walk; walk++) {
|
|
|
|
gint program_number = strtol (*walk, NULL, 0);
|
|
|
|
|
|
|
|
program = dvb_base_bin_get_program (dvbbasebin, program_number);
|
|
|
|
if (program == NULL) {
|
|
|
|
program = dvb_base_bin_add_program (dvbbasebin, program_number);
|
|
|
|
program->selected = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev (strv);
|
|
|
|
|
|
|
|
/* FIXME : Deactivate programs no longer selected */
|
|
|
|
|
|
|
|
if (dvbbasebin->program_numbers)
|
|
|
|
g_free (dvbbasebin->program_numbers);
|
|
|
|
dvbbasebin->program_numbers = g_strdup (pn);
|
|
|
|
|
|
|
|
if (0)
|
|
|
|
dvb_base_bin_deactivate_program (dvbbasebin, NULL);
|
|
|
|
}
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
static void
|
|
|
|
dvb_base_bin_set_property (GObject * object, guint prop_id,
|
|
|
|
const GValue * value, GParamSpec * pspec)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
case PROP_ADAPTER:
|
2007-10-19 16:20:53 +00:00
|
|
|
case PROP_DISEQC_SRC:
|
2007-10-16 17:38:05 +00:00
|
|
|
case PROP_FRONTEND:
|
|
|
|
case PROP_FREQUENCY:
|
|
|
|
case PROP_POLARITY:
|
|
|
|
case PROP_SYMBOL_RATE:
|
|
|
|
case PROP_BANDWIDTH:
|
|
|
|
case PROP_CODE_RATE_HP:
|
|
|
|
case PROP_CODE_RATE_LP:
|
|
|
|
case PROP_GUARD:
|
|
|
|
case PROP_MODULATION:
|
|
|
|
case PROP_TRANS_MODE:
|
|
|
|
case PROP_HIERARCHY:
|
|
|
|
case PROP_INVERSION:
|
|
|
|
case PROP_STATS_REPORTING_INTERVAL:
|
|
|
|
/* FIXME: check if we can tune (state < PLAYING || program-numbers == "") */
|
|
|
|
g_object_set_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value);
|
|
|
|
break;
|
|
|
|
case PROP_PROGRAM_NUMBERS:
|
2012-06-29 16:00:41 +00:00
|
|
|
dvb_base_bin_set_program_numbers (dvbbasebin, g_value_get_string (value));
|
2007-10-16 17:38:05 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_get_property (GObject * object, guint prop_id,
|
|
|
|
GValue * value, GParamSpec * pspec)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
case PROP_ADAPTER:
|
|
|
|
case PROP_FRONTEND:
|
2007-10-19 16:20:53 +00:00
|
|
|
case PROP_DISEQC_SRC:
|
2007-10-16 17:38:05 +00:00
|
|
|
case PROP_FREQUENCY:
|
|
|
|
case PROP_POLARITY:
|
|
|
|
case PROP_SYMBOL_RATE:
|
|
|
|
case PROP_BANDWIDTH:
|
|
|
|
case PROP_CODE_RATE_HP:
|
|
|
|
case PROP_CODE_RATE_LP:
|
|
|
|
case PROP_GUARD:
|
|
|
|
case PROP_MODULATION:
|
|
|
|
case PROP_TRANS_MODE:
|
|
|
|
case PROP_HIERARCHY:
|
|
|
|
case PROP_INVERSION:
|
|
|
|
case PROP_STATS_REPORTING_INTERVAL:
|
|
|
|
g_object_get_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value);
|
|
|
|
break;
|
|
|
|
case PROP_PROGRAM_NUMBERS:
|
2012-06-29 16:00:41 +00:00
|
|
|
g_value_set_string (value, dvbbasebin->program_numbers);
|
2007-10-16 17:38:05 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static GstPad *
|
|
|
|
dvb_base_bin_request_new_pad (GstElement * element,
|
2011-10-10 09:41:33 +00:00
|
|
|
GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
|
2007-10-16 17:38:05 +00:00
|
|
|
{
|
|
|
|
GstPad *pad;
|
|
|
|
GstPad *ghost;
|
|
|
|
gchar *pad_name;
|
|
|
|
|
2012-06-29 16:00:41 +00:00
|
|
|
GST_DEBUG ("New pad requested %s", name);
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
if (name == NULL)
|
|
|
|
name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
|
|
|
|
|
2012-06-29 16:00:41 +00:00
|
|
|
pad = gst_element_get_request_pad (GST_DVB_BASE_BIN (element)->tsparse, name);
|
2007-10-16 17:38:05 +00:00
|
|
|
if (pad == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
pad_name = gst_pad_get_name (pad);
|
|
|
|
ghost = gst_ghost_pad_new (pad_name, pad);
|
|
|
|
g_free (pad_name);
|
|
|
|
gst_element_add_pad (element, ghost);
|
|
|
|
|
|
|
|
return ghost;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_release_pad (GstElement * element, GstPad * pad)
|
|
|
|
{
|
|
|
|
GstGhostPad *ghost;
|
|
|
|
GstPad *target;
|
|
|
|
|
|
|
|
g_return_if_fail (GST_IS_DVB_BASE_BIN (element));
|
|
|
|
|
|
|
|
ghost = GST_GHOST_PAD (pad);
|
|
|
|
target = gst_ghost_pad_get_target (ghost);
|
2009-01-04 11:11:06 +00:00
|
|
|
gst_element_release_request_pad (GST_ELEMENT (GST_DVB_BASE_BIN
|
2012-06-29 16:00:41 +00:00
|
|
|
(element)->tsparse), target);
|
2007-10-16 17:38:05 +00:00
|
|
|
gst_object_unref (target);
|
|
|
|
|
|
|
|
gst_element_remove_pad (element, pad);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin)
|
|
|
|
{
|
|
|
|
CamConditionalAccessPmtFlag flag;
|
|
|
|
GList *walk;
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsPMT *pmt;
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
walk = dvbbasebin->pmtlist;
|
|
|
|
while (walk) {
|
|
|
|
if (walk->prev == NULL) {
|
|
|
|
if (walk->next == NULL)
|
|
|
|
flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_ONLY;
|
|
|
|
else
|
|
|
|
flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_FIRST;
|
|
|
|
} else {
|
|
|
|
if (walk->next == NULL)
|
|
|
|
flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_LAST;
|
|
|
|
else
|
|
|
|
flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_MORE;
|
|
|
|
}
|
|
|
|
|
2013-07-03 11:57:57 +00:00
|
|
|
pmt = (GstMpegTsPMT *) walk->data;
|
2007-10-16 17:38:05 +00:00
|
|
|
cam_device_set_pmt (dvbbasebin->hwcam, pmt, flag);
|
|
|
|
|
|
|
|
walk = walk->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
dvbbasebin->pmtlist_changed = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_init_cam (DvbBaseBin * dvbbasebin)
|
|
|
|
{
|
|
|
|
gint adapter;
|
|
|
|
gchar *ca_file;
|
|
|
|
|
|
|
|
g_object_get (dvbbasebin->dvbsrc, "adapter", &adapter, NULL);
|
|
|
|
/* TODO: handle multiple cams */
|
|
|
|
ca_file = g_strdup_printf ("/dev/dvb/adapter%d/ca0", adapter);
|
|
|
|
if (g_file_test (ca_file, G_FILE_TEST_EXISTS)) {
|
|
|
|
dvbbasebin->hwcam = cam_device_new ();
|
2012-06-29 16:00:41 +00:00
|
|
|
/* device_open() can block up to 5s ! */
|
|
|
|
if (!cam_device_open (dvbbasebin->hwcam, ca_file)) {
|
2007-10-16 17:38:05 +00:00
|
|
|
GST_ERROR_OBJECT (dvbbasebin, "could not open %s", ca_file);
|
|
|
|
cam_device_free (dvbbasebin->hwcam);
|
|
|
|
dvbbasebin->hwcam = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-31 10:11:48 +00:00
|
|
|
dvbbasebin->trycam = FALSE;
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
g_free (ca_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GstStateChangeReturn
|
|
|
|
dvb_base_bin_change_state (GstElement * element, GstStateChange transition)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin;
|
|
|
|
GstStateChangeReturn ret;
|
|
|
|
|
|
|
|
dvbbasebin = GST_DVB_BASE_BIN (element);
|
|
|
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
|
|
|
|
|
|
|
switch (transition) {
|
|
|
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
2013-03-31 10:11:48 +00:00
|
|
|
gst_poll_set_flushing (dvbbasebin->poll, FALSE);
|
|
|
|
g_rec_mutex_lock (&dvbbasebin->lock);
|
|
|
|
gst_task_start (dvbbasebin->task);
|
|
|
|
g_rec_mutex_unlock (&dvbbasebin->lock);
|
2007-10-16 17:38:05 +00:00
|
|
|
break;
|
|
|
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
2013-03-31 10:11:48 +00:00
|
|
|
gst_poll_set_flushing (dvbbasebin->poll, TRUE);
|
|
|
|
g_rec_mutex_lock (&dvbbasebin->lock);
|
|
|
|
gst_task_stop (dvbbasebin->task);
|
|
|
|
g_rec_mutex_unlock (&dvbbasebin->lock);
|
2007-10-16 17:38:05 +00:00
|
|
|
dvb_base_bin_reset (dvbbasebin);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
foreach_stream_build_filter (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (user_data);
|
|
|
|
DvbBaseBinStream *stream = (DvbBaseBinStream *) value;
|
|
|
|
gchar *tmp, *pid;
|
|
|
|
|
|
|
|
g_assert (stream->usecount >= 0);
|
|
|
|
|
|
|
|
GST_DEBUG ("stream %d usecount %d", stream->pid, stream->usecount);
|
|
|
|
|
|
|
|
if (stream->usecount > 0) {
|
|
|
|
/* TODO: use g_strjoinv FTW */
|
|
|
|
tmp = dvbbasebin->filter;
|
|
|
|
pid = g_strdup_printf ("%d", stream->pid);
|
|
|
|
dvbbasebin->filter = g_strjoin (":", pid, dvbbasebin->filter, NULL);
|
|
|
|
|
|
|
|
g_free (pid);
|
|
|
|
g_free (tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin)
|
|
|
|
{
|
|
|
|
g_hash_table_foreach (dvbbasebin->streams,
|
|
|
|
foreach_stream_build_filter, dvbbasebin);
|
|
|
|
|
|
|
|
if (dvbbasebin->filter == NULL)
|
|
|
|
/* fix dvbsrc to handle NULL filter */
|
|
|
|
dvbbasebin->filter = g_strdup ("");
|
|
|
|
|
|
|
|
GST_INFO_OBJECT (dvbbasebin, "rebuilt filter %s", dvbbasebin->filter);
|
|
|
|
|
2007-10-29 15:54:04 +00:00
|
|
|
/* FIXME: find a way to not add unwanted pids controlled by app */
|
|
|
|
g_object_set (dvbbasebin->dvbsrc, "pids", dvbbasebin->filter, NULL);
|
2007-10-16 17:38:05 +00:00
|
|
|
g_free (dvbbasebin->filter);
|
|
|
|
dvbbasebin->filter = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-07-05 11:53:06 +00:00
|
|
|
dvb_base_bin_remove_pmt_streams (DvbBaseBin * dvbbasebin,
|
|
|
|
const GstMpegTsPMT * pmt)
|
2007-10-16 17:38:05 +00:00
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
DvbBaseBinStream *stream;
|
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
for (i = 0; i < pmt->streams->len; i++) {
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
|
2007-10-16 17:38:05 +00:00
|
|
|
if (stream == NULL) {
|
2013-06-23 06:44:08 +00:00
|
|
|
GST_WARNING_OBJECT (dvbbasebin, "removing unknown stream %d ??",
|
|
|
|
pmtstream->pid);
|
2007-10-16 17:38:05 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
--stream->usecount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-07-05 11:53:06 +00:00
|
|
|
dvb_base_bin_add_pmt_streams (DvbBaseBin * dvbbasebin, const GstMpegTsPMT * pmt)
|
2007-10-16 17:38:05 +00:00
|
|
|
{
|
|
|
|
DvbBaseBinStream *stream;
|
|
|
|
gint i;
|
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
for (i = 0; i < pmt->streams->len; i++) {
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
GST_DEBUG ("filtering stream %d stream_type %d", pmtstream->pid,
|
|
|
|
pmtstream->stream_type);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
|
2007-10-16 17:38:05 +00:00
|
|
|
if (stream == NULL)
|
2013-06-23 06:44:08 +00:00
|
|
|
stream = dvb_base_bin_add_stream (dvbbasebin, pmtstream->pid);
|
2007-10-16 17:38:05 +00:00
|
|
|
++stream->usecount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_activate_program (DvbBaseBin * dvbbasebin,
|
|
|
|
DvbBaseBinProgram * program)
|
|
|
|
{
|
|
|
|
DvbBaseBinStream *stream;
|
|
|
|
|
|
|
|
if (program->old_pmt) {
|
|
|
|
dvb_base_bin_remove_pmt_streams (dvbbasebin, program->old_pmt);
|
|
|
|
dvbbasebin->pmtlist = g_list_remove (dvbbasebin->pmtlist, program->old_pmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* activate the PMT and PCR streams. If the PCR stream is in the PMT its
|
|
|
|
* usecount will be incremented by 2 here and decremented by 2 when the
|
|
|
|
* program is deactivated */
|
|
|
|
if (!program->pmt_active) {
|
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, program->pmt_pid);
|
|
|
|
if (stream == NULL)
|
|
|
|
stream = dvb_base_bin_add_stream (dvbbasebin, program->pmt_pid);
|
|
|
|
stream->usecount += 1;
|
|
|
|
program->pmt_active = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (program->pmt) {
|
|
|
|
guint16 old_pcr_pid;
|
|
|
|
|
|
|
|
old_pcr_pid = program->pcr_pid;
|
2013-06-23 06:44:08 +00:00
|
|
|
program->pcr_pid = program->pmt->pcr_pid;
|
2007-10-16 17:38:05 +00:00
|
|
|
if (old_pcr_pid != G_MAXUINT16 && old_pcr_pid != program->pcr_pid)
|
|
|
|
dvb_base_bin_get_stream (dvbbasebin, old_pcr_pid)->usecount--;
|
|
|
|
|
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, program->pcr_pid);
|
|
|
|
if (stream == NULL)
|
|
|
|
stream = dvb_base_bin_add_stream (dvbbasebin, program->pcr_pid);
|
|
|
|
stream->usecount += 1;
|
|
|
|
|
|
|
|
dvb_base_bin_add_pmt_streams (dvbbasebin, program->pmt);
|
2013-07-05 11:53:06 +00:00
|
|
|
dvbbasebin->pmtlist =
|
|
|
|
g_list_append (dvbbasebin->pmtlist, (gpointer) program->pmt);
|
2007-10-16 17:38:05 +00:00
|
|
|
dvbbasebin->pmtlist_changed = TRUE;
|
|
|
|
program->active = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dvb_base_bin_rebuild_filter (dvbbasebin);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_deactivate_program (DvbBaseBin * dvbbasebin,
|
|
|
|
DvbBaseBinProgram * program)
|
|
|
|
{
|
|
|
|
DvbBaseBinStream *stream;
|
|
|
|
|
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, program->pmt_pid);
|
|
|
|
if (stream != NULL)
|
|
|
|
stream->usecount -= 1;
|
|
|
|
|
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, program->pcr_pid);
|
|
|
|
if (stream != NULL)
|
|
|
|
stream->usecount -= 1;
|
|
|
|
|
|
|
|
if (program->pmt) {
|
|
|
|
dvb_base_bin_remove_pmt_streams (dvbbasebin, program->pmt);
|
|
|
|
dvbbasebin->pmtlist = g_list_remove (dvbbasebin->pmtlist, program->pmt);
|
|
|
|
dvbbasebin->pmtlist_changed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dvb_base_bin_rebuild_filter (dvbbasebin);
|
|
|
|
program->pmt_active = FALSE;
|
|
|
|
program->active = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
dvb_base_bin_handle_message (GstBin * bin, GstMessage * message)
|
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin;
|
|
|
|
|
|
|
|
dvbbasebin = GST_DVB_BASE_BIN (bin);
|
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
if (GST_ELEMENT (message->src) == GST_ELEMENT (dvbbasebin->tsparse)) {
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsSection *section = gst_message_parse_mpegts_section (message);
|
2013-06-23 06:44:08 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
}
|
|
|
|
|
2012-06-29 16:00:41 +00:00
|
|
|
/* chain up */
|
|
|
|
GST_BIN_CLASS (parent_class)->handle_message (bin, message);
|
gst/mpegtsparse/: Remove signals for pat, pmt, nit, eit, sdt. Replace with bus messages.
Original commit message from CVS:
* gst/mpegtsparse/Makefile.am:
* gst/mpegtsparse/mpegtspacketizer.c:
* gst/mpegtsparse/mpegtsparse.c:
Remove signals for pat, pmt, nit, eit, sdt. Replace with bus
messages.
* sys/dvb/dvbbasebin.c:
Instead of attaching to signals, use the bus messages.
Also fix up so the dvbsrc starts only outputting the info tables
like PAT, CAT, NIT, SDT, EIT instead of the whole ts.
2007-12-03 18:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2013-07-03 11:57:57 +00:00
|
|
|
dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin, GstMpegTsSection * section)
|
2007-10-16 17:38:05 +00:00
|
|
|
{
|
2013-06-23 06:44:08 +00:00
|
|
|
GArray *pat;
|
2007-10-16 17:38:05 +00:00
|
|
|
DvbBaseBinProgram *program;
|
|
|
|
DvbBaseBinStream *stream;
|
2007-11-23 17:53:37 +00:00
|
|
|
guint old_pmt_pid;
|
2007-10-16 17:38:05 +00:00
|
|
|
gint i;
|
|
|
|
gboolean rebuild_filter = FALSE;
|
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
if (!(pat = gst_mpegts_section_get_pat (section))) {
|
|
|
|
GST_WARNING_OBJECT (dvbbasebin, "got invalid PAT");
|
|
|
|
return;
|
|
|
|
}
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
for (i = 0; i < pat->len; i++) {
|
2013-07-03 11:57:57 +00:00
|
|
|
GstMpegTsPatProgram *patp = &g_array_index (pat, GstMpegTsPatProgram, i);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
program = dvb_base_bin_get_program (dvbbasebin, patp->program_number);
|
2007-10-16 17:38:05 +00:00
|
|
|
if (program == NULL)
|
2013-06-23 06:44:08 +00:00
|
|
|
program = dvb_base_bin_add_program (dvbbasebin, patp->program_number);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
old_pmt_pid = program->pmt_pid;
|
2013-06-23 06:44:08 +00:00
|
|
|
program->pmt_pid = patp->network_or_program_map_PID;
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
if (program->selected) {
|
|
|
|
/* PAT update */
|
|
|
|
if (old_pmt_pid != G_MAXUINT16 && old_pmt_pid != program->pmt_pid)
|
|
|
|
dvb_base_bin_get_stream (dvbbasebin, old_pmt_pid)->usecount -= 1;
|
|
|
|
|
|
|
|
stream = dvb_base_bin_get_stream (dvbbasebin, program->pmt_pid);
|
|
|
|
if (stream == NULL)
|
|
|
|
stream = dvb_base_bin_add_stream (dvbbasebin, program->pmt_pid);
|
|
|
|
|
|
|
|
stream->usecount += 1;
|
|
|
|
|
|
|
|
rebuild_filter = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rebuild_filter)
|
|
|
|
dvb_base_bin_rebuild_filter (dvbbasebin);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-07-03 11:57:57 +00:00
|
|
|
dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, GstMpegTsSection * section)
|
2007-10-16 17:38:05 +00:00
|
|
|
{
|
2013-07-05 11:53:06 +00:00
|
|
|
const GstMpegTsPMT *pmt;
|
2007-10-16 17:38:05 +00:00
|
|
|
DvbBaseBinProgram *program;
|
2007-11-23 17:53:37 +00:00
|
|
|
guint program_number;
|
|
|
|
|
2013-07-05 11:53:06 +00:00
|
|
|
pmt = gst_mpegts_section_get_pmt (section);
|
|
|
|
if (G_UNLIKELY (pmt == NULL)) {
|
|
|
|
GST_WARNING_OBJECT (dvbbasebin, "Received invalid PMT");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-23 06:44:08 +00:00
|
|
|
program_number = section->subtable_extension;
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
program = dvb_base_bin_get_program (dvbbasebin, program_number);
|
|
|
|
if (program == NULL) {
|
|
|
|
GST_WARNING ("got PMT for program %d but program not in PAT",
|
|
|
|
program_number);
|
|
|
|
program = dvb_base_bin_add_program (dvbbasebin, program_number);
|
|
|
|
}
|
|
|
|
|
|
|
|
program->old_pmt = program->pmt;
|
2013-07-05 11:53:06 +00:00
|
|
|
program->old_section = program->section;
|
|
|
|
program->pmt = pmt;
|
|
|
|
program->section = gst_mpegts_section_ref (section);
|
2007-10-16 17:38:05 +00:00
|
|
|
|
|
|
|
/* activate the program if it's selected and either it's not active or its pmt
|
|
|
|
* changed */
|
|
|
|
if (program->selected && (!program->active || program->old_pmt != NULL))
|
|
|
|
dvb_base_bin_activate_program (dvbbasebin, program);
|
|
|
|
|
|
|
|
if (program->old_pmt) {
|
2013-07-05 11:53:06 +00:00
|
|
|
gst_mpegts_section_unref (program->old_section);
|
2007-10-16 17:38:05 +00:00
|
|
|
program->old_pmt = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-08 18:22:08 +00:00
|
|
|
static guint
|
2011-10-10 09:41:33 +00:00
|
|
|
dvb_base_bin_uri_get_type (GType type)
|
2008-02-08 18:22:08 +00:00
|
|
|
{
|
|
|
|
return GST_URI_SRC;
|
|
|
|
}
|
|
|
|
|
2011-11-13 23:55:56 +00:00
|
|
|
static const gchar *const *
|
2011-10-10 09:41:33 +00:00
|
|
|
dvb_base_bin_uri_get_protocols (GType type)
|
2008-02-08 18:22:08 +00:00
|
|
|
{
|
2011-11-13 23:55:56 +00:00
|
|
|
static const gchar *protocols[] = { "dvb", NULL };
|
2008-02-08 18:22:08 +00:00
|
|
|
|
|
|
|
return protocols;
|
|
|
|
}
|
|
|
|
|
2011-11-13 23:55:56 +00:00
|
|
|
static gchar *
|
2008-02-08 18:22:08 +00:00
|
|
|
dvb_base_bin_uri_get_uri (GstURIHandler * handler)
|
|
|
|
{
|
2011-11-13 23:55:56 +00:00
|
|
|
return g_strdup ("dvb://");
|
2008-02-08 18:22:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2011-11-13 23:55:56 +00:00
|
|
|
dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri,
|
|
|
|
GError ** error)
|
2008-02-08 18:22:08 +00:00
|
|
|
{
|
|
|
|
DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler);
|
2013-04-21 17:28:52 +00:00
|
|
|
GError *err = NULL;
|
2011-11-13 23:55:56 +00:00
|
|
|
gchar *location;
|
2008-02-08 18:22:08 +00:00
|
|
|
|
2011-11-13 23:55:56 +00:00
|
|
|
location = gst_uri_get_location (uri);
|
2008-02-08 18:22:08 +00:00
|
|
|
|
2011-11-13 23:55:56 +00:00
|
|
|
if (location == NULL)
|
|
|
|
goto no_location;
|
2008-02-12 21:31:57 +00:00
|
|
|
|
2013-04-21 17:28:52 +00:00
|
|
|
if (!set_properties_for_channel (GST_ELEMENT (dvbbasebin), location, &err))
|
2011-11-13 23:55:56 +00:00
|
|
|
goto set_properties_failed;
|
2008-02-08 18:22:08 +00:00
|
|
|
|
2011-11-13 23:55:56 +00:00
|
|
|
/* FIXME: here is where we parse channels.conf */
|
2008-02-08 18:22:08 +00:00
|
|
|
|
2011-11-13 23:55:56 +00:00
|
|
|
g_free (location);
|
|
|
|
return TRUE;
|
|
|
|
/* ERRORS */
|
2013-04-21 17:28:52 +00:00
|
|
|
post_error_and_exit:
|
|
|
|
{
|
|
|
|
gst_element_message_full (GST_ELEMENT (dvbbasebin), GST_MESSAGE_ERROR,
|
|
|
|
err->domain, err->code, g_strdup (err->message), NULL, __FILE__,
|
|
|
|
GST_FUNCTION, __LINE__);
|
|
|
|
g_propagate_error (error, err);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-11-13 23:55:56 +00:00
|
|
|
no_location:
|
|
|
|
{
|
2013-04-21 17:28:52 +00:00
|
|
|
g_set_error (&err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
|
2011-11-13 23:55:56 +00:00
|
|
|
"No details to DVB URI");
|
2013-04-21 17:28:52 +00:00
|
|
|
goto post_error_and_exit;
|
2011-11-13 23:55:56 +00:00
|
|
|
}
|
|
|
|
set_properties_failed:
|
|
|
|
{
|
|
|
|
g_free (location);
|
2013-04-21 17:28:52 +00:00
|
|
|
goto post_error_and_exit;
|
2011-11-13 23:55:56 +00:00
|
|
|
}
|
2008-02-08 18:22:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_uri_handler_init (gpointer g_iface, gpointer iface_data)
|
|
|
|
{
|
|
|
|
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
|
|
|
|
|
|
|
|
iface->get_type = dvb_base_bin_uri_get_type;
|
|
|
|
iface->get_protocols = dvb_base_bin_uri_get_protocols;
|
|
|
|
iface->get_uri = dvb_base_bin_uri_get_uri;
|
|
|
|
iface->set_uri = dvb_base_bin_uri_set_uri;
|
|
|
|
}
|
|
|
|
|
2007-10-16 17:38:05 +00:00
|
|
|
gboolean
|
|
|
|
gst_dvb_base_bin_plugin_init (GstPlugin * plugin)
|
|
|
|
{
|
|
|
|
GST_DEBUG_CATEGORY_INIT (dvb_base_bin_debug, "dvbbasebin", 0, "DVB bin");
|
|
|
|
|
|
|
|
cam_init ();
|
|
|
|
|
|
|
|
return gst_element_register (plugin, "dvbbasebin",
|
|
|
|
GST_RANK_NONE, GST_TYPE_DVB_BASE_BIN);
|
|
|
|
}
|
2009-01-04 11:11:06 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_program_destroy (gpointer data)
|
|
|
|
{
|
|
|
|
DvbBaseBinProgram *program;
|
|
|
|
|
|
|
|
program = (DvbBaseBinProgram *) data;
|
|
|
|
|
2013-07-05 11:53:06 +00:00
|
|
|
if (program->pmt) {
|
|
|
|
program->pmt = NULL;
|
|
|
|
gst_mpegts_section_unref (program->section);
|
|
|
|
}
|
2009-01-04 11:11:06 +00:00
|
|
|
|
|
|
|
g_free (program);
|
|
|
|
}
|
2013-03-31 10:11:48 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
dvb_base_bin_task (DvbBaseBin * basebin)
|
|
|
|
{
|
|
|
|
gint pollres;
|
|
|
|
|
|
|
|
GST_DEBUG_OBJECT (basebin, "In task");
|
|
|
|
|
|
|
|
/* If we haven't tried to open the cam, try now */
|
|
|
|
if (G_UNLIKELY (basebin->trycam))
|
|
|
|
dvb_base_bin_init_cam (basebin);
|
|
|
|
|
|
|
|
/* poll with timeout */
|
|
|
|
pollres = gst_poll_wait (basebin->poll, GST_SECOND / 4);
|
|
|
|
|
|
|
|
if (G_UNLIKELY (pollres == -1)) {
|
|
|
|
gst_task_stop (basebin->task);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (basebin->hwcam) {
|
|
|
|
cam_device_poll (basebin->hwcam);
|
|
|
|
|
|
|
|
if (basebin->pmtlist_changed) {
|
|
|
|
if (cam_device_ready (basebin->hwcam)) {
|
|
|
|
GST_DEBUG_OBJECT (basebin, "pmt list changed");
|
|
|
|
dvb_base_bin_reset_pmtlist (basebin);
|
|
|
|
} else {
|
|
|
|
GST_DEBUG_OBJECT (basebin, "pmt list changed but CAM not ready");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|