4
* Copyright (C) 2006 Zaheer Abbas Merali <zaheerabbas at merali
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
17
* You should have received a copy of the GNU Library General Public
18
* License along with this library; if not, write to the
19
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
* Boston, MA 02111-1307, USA.
27
#include "gstdvbsrc.h"
29
#include <sys/ioctl.h>
37
#define _XOPEN_SOURCE 500
40
#include <linux/dvb/frontend.h>
41
#include <linux/dvb/dmx.h>
43
#include "../../gst-libs/gst/gst-i18n-plugin.h"
45
GST_DEBUG_CATEGORY_STATIC (gstdvbsrc_debug);
46
#define GST_CAT_DEFAULT (gstdvbsrc_debug)
48
#define SLOF (11700*1000UL)
49
#define LOF1 (9750*1000UL)
50
#define LOF2 (10600*1000UL)
53
static GstElementDetails dvbsrc_details = {
56
"Digital Video Broadcast Source",
57
"P2P-VCR, C-Lab, University of Paderborn\n"
58
"Zaheer Abbas Merali <zaheerabbas at merali dot org>"
62
* SECTION:element-dvbsrc
65
* dvbsrc can be used to capture video from DVB cards, DVB-T, DVB-S or DVB-T.
66
* <title>Example launch line</title>
69
* gst-launch dvbsrc modulation="QAM 64" trans-mode=8k bandwidth=8MHz freq=514000000 code-rate-lp=AUTO code-rate-hp=2/3 guard=4 hierarchy=0 ! flutsdemux crc-check=false name=demux ! queue max-size-buffers=0 max-size-time=0 ! flumpeg2vdec ! xvimagesink sync=false demux. ! queue max-size-buffers=0 max-size-time=0 ! flump3dec ! alsasink sync=false
71
* This pipeline captures a full transport stream from dvb card 0 that is a DVB-T card at tuned frequency 514000000 with other parameters as seen in the
72
* pipeline and outputs the first tv program on the transport stream. The reason the sinks have to be set to have sync=false is due to bug #340482.
76
* gst-launch dvbsrc modulation="QAM 64" trans-mode=8k bandwidth=8 freq=514000000 code-rate-lp=AUTO code-rate-hp=2/3 guard=4 hierarchy=0 pids=256:257 ! flutsdemux crc-check=false name=demux es-pids=256:257 ! queue max-size-buffers=0 max-size-time=0 ! flumpeg2vdec ! xvimagesink sync=false demux. ! queue max-size-buffers=0 max-size-time=0 ! flump3dec ! alsasink sync=false
78
* This pipeline captures a partial transport stream from dvb card 0 that is a DVB-T card for a program at tuned frequency 514000000 and pids of 256:257 with other parameters as seen in the pipeline and outputs the program with the pids 256 and 257. The reason the sinks have to be set to
79
* have sync=false is due to bug #340482.
83
* gst-launch dvbsrc polarity="h" freq=11302000 srate=27500 diseqc-src=0 pids=102:103 ! queue max-size-buffers=0 max-size-time=0 ! flumpeg2vdec ! xvimagesink sync=false demux. ! queue max-size-buffers=0 max-size-time=0 ! flump3dec ! alsasink sync=false
85
* This pipeline captures a partial transport stream from dvb card 0 that is a DVB-S card for a program at tuned frequency 11302000 Hz, symbol rate of 27500 kHz and pids of 256:257 and outputs the program with the pids 256 and 257. The reason the sinks have to be set to have sync=false is due to bug #340482.
95
ARG_DVBSRC_DISEQC_SRC,
100
ARG_DVBSRC_BANDWIDTH,
101
ARG_DVBSRC_CODE_RATE_HP,
102
ARG_DVBSRC_CODE_RATE_LP,
104
ARG_DVBSRC_MODULATION,
105
ARG_DVBSRC_TRANSMISSION_MODE,
106
ARG_DVBSRC_HIERARCHY_INF,
111
static void gst_dvbsrc_output_frontend_stats (GstDvbSrc * src);
113
#define GST_TYPE_DVBSRC_CODE_RATE (gst_dvbsrc_code_rate_get_type ())
115
gst_dvbsrc_code_rate_get_type (void)
117
static GType dvbsrc_code_rate_type = 0;
118
static GEnumValue code_rate_types[] = {
119
{FEC_NONE, "NONE", "NONE"},
120
{FEC_1_2, "1/2", "1/2"},
121
{FEC_2_3, "2/3", "2/3"},
122
{FEC_3_4, "3/4", "3/4"},
123
{FEC_4_5, "4/5", "4/5"},
124
{FEC_5_6, "5/6", "5/6"},
125
{FEC_6_7, "6/7", "6/7"},
126
{FEC_7_8, "7/8", "7/8"},
127
{FEC_8_9, "8/9", "8/9"},
128
{FEC_AUTO, "AUTO", ""},
132
if (!dvbsrc_code_rate_type) {
133
dvbsrc_code_rate_type =
134
g_enum_register_static ("GstDvbSrcCode_Rate", code_rate_types);
136
return dvbsrc_code_rate_type;
139
#define GST_TYPE_DVBSRC_MODULATION (gst_dvbsrc_modulation_get_type ())
141
gst_dvbsrc_modulation_get_type (void)
143
static GType dvbsrc_modulation_type = 0;
144
static GEnumValue modulation_types[] = {
145
{QPSK, "QPSK", "QPSK"},
146
{QAM_16, "QAM 16", "QAM 16"},
147
{QAM_32, "QAM 32", "QAM 32"},
148
{QAM_64, "QAM 64", "QAM 64"},
149
{QAM_128, "QAM 128", "QAM 128"},
150
{QAM_256, "QAM 256", "QAM 256"},
151
{QAM_AUTO, "AUTO", "AUTO"},
155
if (!dvbsrc_modulation_type) {
156
dvbsrc_modulation_type =
157
g_enum_register_static ("GstDvbSrcModulation", modulation_types);
159
return dvbsrc_modulation_type;
162
#define GST_TYPE_DVBSRC_TRANSMISSION_MODE (gst_dvbsrc_transmission_mode_get_type ())
164
gst_dvbsrc_transmission_mode_get_type (void)
166
static GType dvbsrc_transmission_mode_type = 0;
167
static GEnumValue transmission_mode_types[] = {
168
{TRANSMISSION_MODE_2K, "2k", "2k"},
169
{TRANSMISSION_MODE_8K, "8k", "8k"},
170
{TRANSMISSION_MODE_AUTO, "AUTO", "AUTO"},
174
if (!dvbsrc_transmission_mode_type) {
175
dvbsrc_transmission_mode_type =
176
g_enum_register_static ("GstDvbSrcTransmission_Mode",
177
transmission_mode_types);
179
return dvbsrc_transmission_mode_type;
182
#define GST_TYPE_DVBSRC_BANDWIDTH (gst_dvbsrc_bandwidth_get_type ())
184
gst_dvbsrc_bandwidth_get_type (void)
186
static GType dvbsrc_bandwidth_type = 0;
187
static GEnumValue bandwidth_types[] = {
188
{BANDWIDTH_8_MHZ, "8", "8"},
189
{BANDWIDTH_7_MHZ, "7", "7"},
190
{BANDWIDTH_6_MHZ, "6", "6"},
191
{BANDWIDTH_AUTO, "AUTO", "AUTO"},
195
if (!dvbsrc_bandwidth_type) {
196
dvbsrc_bandwidth_type =
197
g_enum_register_static ("GstDvbSrcBandwidth", bandwidth_types);
199
return dvbsrc_bandwidth_type;
202
#define GST_TYPE_DVBSRC_GUARD (gst_dvbsrc_guard_get_type ())
204
gst_dvbsrc_guard_get_type (void)
206
static GType dvbsrc_guard_type = 0;
207
static GEnumValue guard_types[] = {
208
{GUARD_INTERVAL_1_32, "32", "32"},
209
{GUARD_INTERVAL_1_16, "16", "16"},
210
{GUARD_INTERVAL_1_8, "8", "8"},
211
{GUARD_INTERVAL_1_4, "4", "4"},
212
{GUARD_INTERVAL_AUTO, "AUTO", "AUTO"},
216
if (!dvbsrc_guard_type) {
217
dvbsrc_guard_type = g_enum_register_static ("GstDvbSrcGuard", guard_types);
219
return dvbsrc_guard_type;
222
#define GST_TYPE_DVBSRC_HIERARCHY (gst_dvbsrc_hierarchy_get_type ())
224
gst_dvbsrc_hierarchy_get_type (void)
226
static GType dvbsrc_hierarchy_type = 0;
227
static GEnumValue hierarchy_types[] = {
228
{HIERARCHY_NONE, "NONE", "NONE"},
229
{HIERARCHY_1, "1", "1"},
230
{HIERARCHY_2, "2", "2"},
231
{HIERARCHY_4, "4", "4"},
232
{HIERARCHY_AUTO, "AUTO", "AUTO"},
236
if (!dvbsrc_hierarchy_type) {
237
dvbsrc_hierarchy_type =
238
g_enum_register_static ("GstDvbSrcHierarchy", hierarchy_types);
240
return dvbsrc_hierarchy_type;
243
#define GST_TYPE_DVBSRC_INVERSION (gst_dvbsrc_inversion_get_type ())
245
gst_dvbsrc_inversion_get_type (void)
247
static GType dvbsrc_inversion_type = 0;
248
static GEnumValue inversion_types[] = {
249
{INVERSION_AUTO, "AUTO", "AUTO"},
250
{INVERSION_ON, "ON", "ON"},
251
{INVERSION_AUTO, "OFF", "OFF"},
255
if (!dvbsrc_inversion_type) {
256
dvbsrc_inversion_type =
257
g_enum_register_static ("GstDvbSrcInversion", inversion_types);
259
return dvbsrc_inversion_type;
262
static void gst_dvbsrc_finalize (GObject * object);
263
static void gst_dvbsrc_set_property (GObject * object, guint prop_id,
264
const GValue * value, GParamSpec * pspec);
265
static void gst_dvbsrc_get_property (GObject * object, guint prop_id,
266
GValue * value, GParamSpec * pspec);
268
static GstFlowReturn gst_dvbsrc_create (GstPushSrc * element,
269
GstBuffer ** buffer);
271
static gboolean gst_dvbsrc_start (GstBaseSrc * bsrc);
272
static gboolean gst_dvbsrc_stop (GstBaseSrc * bsrc);
273
static gboolean gst_dvbsrc_unlock (GstBaseSrc * bsrc);
274
static gboolean gst_dvbsrc_is_seekable (GstBaseSrc * bsrc);
275
static gboolean gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size);
277
static gboolean gst_dvbsrc_tune (GstDvbSrc * object);
278
static void gst_dvbsrc_set_pes_filters (GstDvbSrc * object);
279
static void gst_dvbsrc_unset_pes_filters (GstDvbSrc * object);
281
static gboolean gst_dvbsrc_frontend_status (GstDvbSrc * object);
283
static GstStaticPadTemplate ts_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
288
"mpegversion = (int) 2," "systemstream = (boolean) TRUE"));
291
******************************
296
******************************
299
#define _do_init(bla) \
300
GST_DEBUG_CATEGORY_INIT (gstdvbsrc_debug, "dvbsrc", 0, "DVB Source Element");
302
GST_BOILERPLATE_FULL (GstDvbSrc, gst_dvbsrc, GstPushSrc,
303
GST_TYPE_PUSH_SRC, _do_init);
306
gst_dvbsrc_base_init (gpointer gclass)
308
GstDvbSrcClass *klass = (GstDvbSrcClass *) gclass;
309
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
311
gst_element_class_add_pad_template (element_class,
312
gst_static_pad_template_get (&ts_src_factory));
314
gst_element_class_set_details (element_class, &dvbsrc_details);
318
/* initialize the plugin's class */
320
gst_dvbsrc_class_init (GstDvbSrcClass * klass)
322
GObjectClass *gobject_class;
323
GstElementClass *gstelement_class;
324
GstBaseSrcClass *gstbasesrc_class;
325
GstPushSrcClass *gstpushsrc_class;
327
gobject_class = (GObjectClass *) klass;
328
gstelement_class = (GstElementClass *) klass;
329
gstbasesrc_class = (GstBaseSrcClass *) klass;
330
gstpushsrc_class = (GstPushSrcClass *) klass;
332
gobject_class->set_property = gst_dvbsrc_set_property;
333
gobject_class->get_property = gst_dvbsrc_get_property;
334
gobject_class->finalize = gst_dvbsrc_finalize;
336
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dvbsrc_start);
337
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dvbsrc_stop);
338
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_dvbsrc_unlock);
339
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_dvbsrc_is_seekable);
340
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_dvbsrc_get_size);
342
gstpushsrc_class->create = gst_dvbsrc_create;
344
g_object_class_install_property (gobject_class, ARG_DVBSRC_DEVICE,
345
g_param_spec_string ("device",
347
"The device directory", "/dev/dvb/adapter0", G_PARAM_READWRITE));
349
g_object_class_install_property (gobject_class, ARG_DVBSRC_FREQ,
350
g_param_spec_int ("freq",
351
"freq", "Frequency", 0, G_MAXINT, 0, G_PARAM_READWRITE));
353
g_object_class_install_property (gobject_class, ARG_DVBSRC_POL,
354
g_param_spec_string ("pol",
355
"pol", "Polarity [vhHV] (DVB-S)", "h", G_PARAM_READWRITE));
358
g_object_class_install_property (gobject_class, ARG_DVBSRC_PIDS,
359
g_param_spec_string ("pids",
361
"Colon seperated list of pids (eg. 110:120)",
362
"8192", G_PARAM_WRITABLE));
364
g_object_class_install_property (gobject_class, ARG_DVBSRC_SYM_RATE,
365
g_param_spec_int ("srate",
367
"Symbol Rate (DVB-S, DVB-C)",
368
0, G_MAXINT, DEFAULT_SYMBOL_RATE, G_PARAM_READWRITE));
370
g_object_class_install_property (gobject_class, ARG_DVBSRC_TUNE,
371
g_param_spec_pointer ("tune",
372
"tune", "Atomically tune to channel. (For Apps)", G_PARAM_WRITABLE));
374
g_object_class_install_property (gobject_class, ARG_DVBSRC_DISEQC_SRC,
375
g_param_spec_int ("diseqc_src",
377
"DISEqC selected source (-1 disabled) (DVB-S)",
378
-1, 7, DEFAULT_DISEQC_SRC, G_PARAM_READWRITE));
380
/* DVB-T, additional properties */
382
g_object_class_install_property (gobject_class, ARG_DVBSRC_BANDWIDTH,
383
g_param_spec_enum ("bandwidth",
385
"Bandwidth (DVB-T)", GST_TYPE_DVBSRC_BANDWIDTH, 1, G_PARAM_WRITABLE));
387
g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_HP,
388
g_param_spec_enum ("code-rate-hp",
390
"High Priority Code Rate (DVB-T)",
391
GST_TYPE_DVBSRC_CODE_RATE, 1, G_PARAM_WRITABLE));
393
g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_LP,
394
g_param_spec_enum ("code-rate-lp",
396
"Low Priority Code Rate (DVB-T)",
397
GST_TYPE_DVBSRC_CODE_RATE, 1, G_PARAM_WRITABLE));
399
g_object_class_install_property (gobject_class, ARG_DVBSRC_GUARD,
400
g_param_spec_enum ("guard",
402
"Guard Interval (DVB-T)",
403
GST_TYPE_DVBSRC_GUARD, 1, G_PARAM_WRITABLE));
405
g_object_class_install_property (gobject_class, ARG_DVBSRC_MODULATION,
406
g_param_spec_enum ("modulation",
408
"Modulation (DVB-T)",
409
GST_TYPE_DVBSRC_MODULATION, 1, G_PARAM_WRITABLE));
411
g_object_class_install_property (gobject_class,
412
ARG_DVBSRC_TRANSMISSION_MODE,
413
g_param_spec_enum ("trans-mode",
415
"Transmission Mode (DVB-T)",
416
GST_TYPE_DVBSRC_TRANSMISSION_MODE, 1, G_PARAM_WRITABLE));
418
g_object_class_install_property (gobject_class, ARG_DVBSRC_HIERARCHY_INF,
419
g_param_spec_enum ("hierarchy",
421
"Hierarchy Information (DVB-T)",
422
GST_TYPE_DVBSRC_HIERARCHY, 1, G_PARAM_WRITABLE));
423
g_object_class_install_property (gobject_class, ARG_DVBSRC_INVERSION,
424
g_param_spec_enum ("inversion",
426
"Inversion Information (DVB-T)",
427
GST_TYPE_DVBSRC_INVERSION, 1, G_PARAM_WRITABLE));
431
/* initialize the new element
432
* instantiate pads and add them to element
434
* initialize structure
437
gst_dvbsrc_init (GstDvbSrc * object, GstDvbSrcClass * klass)
441
GST_INFO_OBJECT (object, "gst_dvbsrc_init");
443
/* We are a live source */
444
gst_base_src_set_live (GST_BASE_SRC (object), TRUE);
446
object->fd_frontend = -1;
449
for (i = 0; i < MAX_FILTERS; i++) {
451
object->fd_filters[i] = -1;
453
/* Pid 8192 on DVB gets the whole transport stream */
454
object->pids[0] = 8192;
456
/* Setting standard devices */
457
object->device = g_strdup (DEFAULT_DEVICE);
458
object->frontend_dev = g_strconcat (object->device, "/frontend0", NULL);
459
object->demux_dev = g_strconcat (object->device, "/demux0", NULL);
460
object->dvr_dev = g_strconcat (object->device, "/dvr0", NULL);
462
object->sym_rate = DEFAULT_SYMBOL_RATE;
463
object->diseqc_src = DEFAULT_DISEQC_SRC;
464
object->send_diseqc = FALSE;
466
object->tune_mutex = g_mutex_new ();
471
gst_dvbsrc_set_property (GObject * _object, guint prop_id,
472
const GValue * value, GParamSpec * pspec)
476
g_return_if_fail (GST_IS_DVBSRC (_object));
477
object = GST_DVBSRC (_object);
480
case ARG_DVBSRC_DEVICE:
482
char delim_str[] = "/\0";
484
if (object->device != NULL)
485
g_free (object->device);
486
object->device = g_value_dup_string (value);
488
if (g_str_has_suffix (object->device, "/"))
491
object->frontend_dev =
492
g_strconcat (object->device, delim_str, "frontend0", NULL);
494
g_strconcat (object->device, delim_str, "demux0", NULL);
495
object->dvr_dev = g_strconcat (object->device, delim_str, "dvr0", NULL);
497
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_DEVICE");
499
case ARG_DVBSRC_DISEQC_SRC:
500
if (object->diseqc_src != g_value_get_int (value)) {
501
object->diseqc_src = g_value_get_int (value);
502
object->send_diseqc = TRUE;
504
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_DISEQC_ID");
506
case ARG_DVBSRC_FREQ:
507
object->freq = g_value_get_int (value);
508
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_FREQ");
512
const char *s = NULL;
514
s = g_value_get_string (value);
516
object->pol = (s[0] == 'h' || s[0] == 'H') ? DVB_POL_H : DVB_POL_V;
518
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_POL");
520
case ARG_DVBSRC_PIDS:
528
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_PIDS");
529
pid_string = g_value_dup_string (value);
530
tmp = pids = g_strsplit (pid_string, ":", MAX_FILTERS);
531
while (*pids != NULL && pid_count < MAX_FILTERS) {
532
pid = strtol (*pids, NULL, 0);
533
if (pid > 0 && pid <= 8192) {
534
GST_INFO_OBJECT (object, "Parsed Pid: %d\n", pid);
535
object->pids[pid_count] = pid;
541
/* if we are in playing, then set filters now */
542
GST_INFO_OBJECT (object, "checking if playing for setting pes filters");
543
if (GST_ELEMENT (object)->current_state == GST_STATE_PLAYING) {
544
GST_INFO_OBJECT (object, "Setting pes filters now");
545
gst_dvbsrc_set_pes_filters (object);
550
case ARG_DVBSRC_SYM_RATE:
551
object->sym_rate = g_value_get_int (value);
552
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_SYM_RATE to value %d",
553
g_value_get_int (value));
556
case ARG_DVBSRC_BANDWIDTH:
557
object->bandwidth = g_value_get_enum (value);
559
case ARG_DVBSRC_CODE_RATE_HP:
560
object->code_rate_hp = g_value_get_enum (value);
562
case ARG_DVBSRC_CODE_RATE_LP:
563
object->code_rate_lp = g_value_get_enum (value);
565
case ARG_DVBSRC_GUARD:
566
object->guard_interval = g_value_get_enum (value);
568
case ARG_DVBSRC_MODULATION:
569
object->modulation = g_value_get_enum (value);
571
case ARG_DVBSRC_TRANSMISSION_MODE:
572
object->transmission_mode = g_value_get_enum (value);
574
case ARG_DVBSRC_HIERARCHY_INF:
575
object->hierarchy_information = g_value_get_enum (value);
577
case ARG_DVBSRC_INVERSION:
578
object->inversion = g_value_get_enum (value);
580
case ARG_DVBSRC_TUNE:
581
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_TUNE");
582
/* if we are in paused/playing state tune now, otherwise in ready to paused state change */
583
if (gst_element_get_state
584
(GST_ELEMENT (object), NULL, NULL,
585
GST_CLOCK_TIME_NONE) > GST_STATE_READY) {
586
g_mutex_lock (object->tune_mutex);
587
gst_dvbsrc_tune (object);
588
g_mutex_unlock (object->tune_mutex);
592
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
599
gst_dvbsrc_get_property (GObject * _object, guint prop_id,
600
GValue * value, GParamSpec * pspec)
604
g_return_if_fail (GST_IS_DVBSRC (_object));
605
object = GST_DVBSRC (_object);
608
case ARG_DVBSRC_DEVICE:
609
g_value_set_string (value, object->device);
611
case ARG_DVBSRC_FREQ:
612
g_value_set_int (value, object->freq);
615
if (object->pol == DVB_POL_H)
616
g_value_set_string (value, "H");
618
g_value_set_string (value, "V");
620
case ARG_DVBSRC_SYM_RATE:
621
g_value_set_int (value, object->sym_rate);
623
case ARG_DVBSRC_DISEQC_SRC:
624
g_value_set_int (value, object->diseqc_src);
627
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
632
gst_dvbsrc_close_devices (GstDvbSrc * object)
634
gst_dvbsrc_unset_pes_filters (object);
636
close (object->fd_dvr);
638
close (object->fd_frontend);
639
object->fd_frontend = -1;
645
gst_dvbsrc_open_frontend (GstDvbSrc * object)
647
struct dvb_frontend_info fe_info;
648
char *adapter_desc = NULL;
650
GST_INFO_OBJECT (object, "Using frontend device: %s", object->frontend_dev);
651
GST_INFO_OBJECT (object, "Using dvr device: %s", object->dvr_dev);
654
if ((object->fd_frontend = open (object->frontend_dev, O_RDWR)) < 0) {
657
GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
658
(_("Device \"%s\" does not exist."), object->frontend_dev), (NULL));
661
GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ_WRITE,
662
(_("Could not open frontend device \"%s\"."), object->frontend_dev),
667
close (object->fd_dvr);
672
if (ioctl (object->fd_frontend, FE_GET_INFO, &fe_info) < 0) {
673
GST_ELEMENT_ERROR (object, RESOURCE, SETTINGS,
674
(_("Could not get settings from frontend device \"%s\"."),
675
object->frontend_dev), GST_ERROR_SYSTEM);
677
close (object->fd_dvr);
678
close (object->fd_frontend);
683
object->adapter_type = fe_info.type;
684
switch (object->adapter_type) {
686
adapter_desc = "DVB-S";
689
adapter_desc = "DVB-C";
692
adapter_desc = "DVB-T";
695
g_error ("Unknown frontend type: %d", object->adapter_type);
698
/*g_signal_emit (G_OBJECT (object), gst_dvbsrc_signals[ADAPTER_TYPE_SIGNAL],
699
0, object->adapter_type); */
701
GST_INFO_OBJECT (object, "DVB card: %s ", fe_info.name);
706
gst_dvbsrc_open_dvr (GstDvbSrc * object)
709
if ((object->fd_dvr = open (object->dvr_dev, O_RDONLY | O_NONBLOCK)) < 0) {
712
GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
713
(_("Device \"%s\" does not exist."), object->dvr_dev), (NULL));
716
GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ,
717
(_("Could not open file \"%s\" for reading."), object->dvr_dev),
723
GST_INFO_OBJECT (object, "Setting buffer size");
724
if (ioctl (object->fd_dvr, DMX_SET_BUFFER_SIZE, 1024 * 1024) < 0) {
725
GST_INFO_OBJECT (object, "DMX_SET_BUFFER_SIZE failed");
732
gst_dvbsrc_finalize (GObject * _object)
736
GST_DEBUG_OBJECT (_object, "gst_dvbsrc_finalize");
738
g_return_if_fail (GST_IS_DVBSRC (_object));
739
object = GST_DVBSRC (_object);
741
g_free (object->frontend_dev);
742
g_free (object->demux_dev);
744
/* freeing the mutex segfaults somehow */
745
g_mutex_free (object->tune_mutex);
750
******************************
752
* Plugin Realisation *
754
******************************
759
/* entry point to initialize the plug-in
760
* initialize the plug-in itself
761
* register the element factories and pad templates
762
* register the features
765
plugin_init (GstPlugin * plugin)
767
return gst_element_register (plugin, "dvbsrc", GST_RANK_NONE,
771
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
774
"DVB Source", plugin_init, VERSION, "LGPL", "", "University of Paderborn");
778
read_device (int fd, const char *fd_name, int size)
781
struct pollfd pfd[1];
784
const int TIMEOUT = 100;
786
GstBuffer *buf = gst_buffer_new_and_alloc (size);
788
g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
795
pfd[0].events = POLLIN;
797
while (count < size) {
798
ret_val = poll (pfd, 1, TIMEOUT);
800
if (pfd[0].revents & POLLIN) {
803
tmp = read (fd, GST_BUFFER_DATA (buf) + count, size - count);
805
GST_WARNING ("Unable to read from device: %s (%d)", fd_name, errno);
807
if (attempts % 10 == 0) {
809
("Unable to read from device after %u attempts: %s",
816
fprintf (stderr, "revents = %d\n", pfd[0].revents);
818
} else if (ret_val == 0) { // poll timeout
820
GST_INFO ("Reading from device %s timedout (%d)", fd_name, attempts);
822
if (attempts % 10 == 0) {
823
GST_WARNING ("Unable to read after %u attempts from device: %s (%d)",
824
attempts, fd_name, errno);
826
} else if (errno == -EINTR) { // poll interrupted
832
GST_BUFFER_SIZE (buf) = count;
833
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
838
gst_dvbsrc_create (GstPushSrc * element, GstBuffer ** buf)
840
static int quality_signal_rate = 0; /* FIXME: move into object struct? */
842
GstFlowReturn retval = GST_FLOW_ERROR;
845
object = GST_DVBSRC (element);
846
GST_LOG ("fd_dvr: %d", object->fd_dvr);
848
//g_object_get(G_OBJECT(object), "blocksize", &buffer_size, NULL);
849
buffer_size = DEFAULT_BUFFER_SIZE;
851
/* device can not be tuned during read */
852
g_mutex_lock (object->tune_mutex);
855
if (object->fd_dvr > -1) {
856
/* --- Read TS from DVR device --- */
857
GST_DEBUG_OBJECT (object, "Reading from DVR device");
858
*buf = read_device (object->fd_dvr, object->dvr_dev, buffer_size);
862
retval = GST_FLOW_OK;
864
caps = gst_pad_get_caps (GST_BASE_SRC_PAD (object));
865
gst_buffer_set_caps (*buf, caps);
866
gst_caps_unref (caps);
868
/* Every now and then signal signal quality */
869
if (quality_signal_rate == 100) {
870
gst_dvbsrc_output_frontend_stats (object);
871
quality_signal_rate = 0;
873
quality_signal_rate++;
876
GST_DEBUG_OBJECT (object, "Failed to read from device");
880
g_mutex_unlock (object->tune_mutex);
886
gst_dvbsrc_start (GstBaseSrc * bsrc)
888
GstDvbSrc *src = GST_DVBSRC (bsrc);
890
gst_dvbsrc_open_frontend (src);
891
gst_dvbsrc_tune (src);
892
if (!gst_dvbsrc_frontend_status (src)) {
895
if (!gst_dvbsrc_open_dvr (src)) {
896
GST_ERROR_OBJECT (src, "Not able to open dvr_device");
904
gst_dvbsrc_stop (GstBaseSrc * bsrc)
906
GstDvbSrc *src = GST_DVBSRC (bsrc);
908
gst_dvbsrc_close_devices (src);
913
gst_dvbsrc_unlock (GstBaseSrc * bsrc)
919
gst_dvbsrc_is_seekable (GstBaseSrc * bsrc)
925
gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size)
931
gst_dvbsrc_output_frontend_stats (GstDvbSrc * src)
934
uint16_t snr, _signal;
935
uint32_t ber, uncorrected_blocks;
937
GstStructure *structure;
938
int fe_fd = src->fd_frontend;
940
ioctl (fe_fd, FE_READ_STATUS, &status);
941
ioctl (fe_fd, FE_READ_SIGNAL_STRENGTH, &_signal);
942
ioctl (fe_fd, FE_READ_SNR, &snr);
943
ioctl (fe_fd, FE_READ_BER, &ber);
944
ioctl (fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
946
structure = gst_structure_new ("dvb-frontend-stats", "status", G_TYPE_INT,
947
status, "signal", G_TYPE_INT, _signal, "snr", G_TYPE_INT, snr,
948
"ber", G_TYPE_INT, ber, "unc", G_TYPE_INT, uncorrected_blocks,
949
"lock", G_TYPE_BOOLEAN, status & FE_HAS_LOCK, NULL);
950
message = gst_message_new_element (GST_OBJECT (src), structure);
951
gst_element_post_message (GST_ELEMENT (src), message);
955
gst_dvbsrc_frontend_status (GstDvbSrc * object)
957
fe_status_t status = 0;
960
GST_INFO_OBJECT (object, "gst_dvbsrc_frontend_status\n");
962
if (object->fd_frontend < 0) {
963
GST_ERROR_OBJECT (object,
964
"Trying to get frontend status from not opened device!");
967
GST_INFO_OBJECT (object, "fd-frontend: %d", object->fd_frontend);
969
for (i = 0; i < 15; i++) {
971
GST_INFO_OBJECT (object, ".");
972
if (ioctl (object->fd_frontend, FE_READ_STATUS, &status) == -1) {
973
GST_ERROR_OBJECT (object, "Failed reading frontend status.");
976
gst_dvbsrc_output_frontend_stats (object);
977
if (status & FE_HAS_LOCK) {
982
if (!(status & FE_HAS_LOCK)) {
983
GST_INFO_OBJECT (object,
984
"Not able to lock to the signal on the given frequency.\n");
992
struct dvb_diseqc_master_cmd cmd;
997
diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
998
fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
1000
if (ioctl (fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
1001
perror ("FE_SET_TONE failed");
1003
if (ioctl (fd, FE_SET_VOLTAGE, v) == -1)
1004
perror ("FE_SET_VOLTAGE failed");
1008
if (ioctl (fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1)
1009
perror ("FE_DISEQC_SEND_MASTER_CMD failed");
1011
usleep (cmd->wait * 1000);
1014
if (ioctl (fd, FE_DISEQC_SEND_BURST, b) == -1)
1015
perror ("FE_DISEQC_SEND_BURST failed");
1019
if (ioctl (fd, FE_SET_TONE, t) == -1)
1020
perror ("FE_SET_TONE failed");
1024
/* digital satellite equipment control,
1025
* specification is available from http://www.eutelsat.com/
1028
diseqc (int secfd, int sat_no, int voltage, int tone)
1030
struct diseqc_cmd cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
1032
/* param: high nibble: reset bits, low nibble set bits,
1033
* bits are: option, position, polarizaion, band
1036
0xf0 | (((sat_no * 4) & 0x0f) | (tone == SEC_TONE_ON ? 1 : 0) |
1037
(voltage == SEC_VOLTAGE_13 ? 0 : 2));
1039
diseqc_send_msg (secfd, voltage, &cmd, tone,
1040
(sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
1046
gst_dvbsrc_tune (GstDvbSrc * object)
1048
struct dvb_frontend_parameters feparams;
1049
fe_sec_voltage_t voltage;
1051
unsigned int freq = object->freq;
1052
unsigned int sym_rate = object->sym_rate * 1000;
1054
/* found in mail archive on linuxtv.org
1055
* What works well for us is:
1056
* - first establish a TS feed (i.e. tune the frontend and check for success)
1057
* - then set filters (PES/sections)
1058
* - then tell the MPEG decoder to start
1059
* - before tuning: first stop the MPEG decoder, then stop all filters
1061
GST_INFO_OBJECT (object, "gst_dvbsrc_tune");
1063
if (object->fd_frontend < 0) {
1064
/* frontend not opened yet, tune later */
1065
GST_INFO_OBJECT (object, "Frontend not open: tuning later");
1069
gst_dvbsrc_unset_pes_filters (object);
1071
switch (object->adapter_type) {
1074
object->tone = SEC_TONE_OFF;
1075
if (freq > 2200000) {
1076
// this must be an absolute frequency
1078
feparams.frequency = (freq - LOF1);
1080
feparams.frequency = (freq - LOF2);
1081
object->tone = SEC_TONE_ON;
1084
// this is an L-Band frequency
1085
feparams.frequency = freq;
1087
GST_INFO_OBJECT (object,
1088
"tuning DVB-S to L-Band:%u, Pol:%d, srate=%u, 22kHz=%s",
1089
feparams.frequency, object->pol, sym_rate,
1090
object->tone == SEC_TONE_ON ? "on" : "off");
1092
feparams.inversion = INVERSION_AUTO;
1093
feparams.u.qpsk.symbol_rate = sym_rate;
1094
feparams.u.qpsk.fec_inner = FEC_AUTO;
1096
if (object->pol == DVB_POL_H)
1097
voltage = SEC_VOLTAGE_18;
1099
voltage = SEC_VOLTAGE_13;
1101
if (object->diseqc_src == -1 || object->send_diseqc == FALSE) {
1102
if (ioctl (object->fd_frontend, FE_SET_VOLTAGE, voltage) < 0) {
1103
g_warning ("Unable to set voltage on dvb frontend device");
1106
if (ioctl (object->fd_frontend, FE_SET_TONE, object->tone) < 0) {
1107
g_warning ("Error setting tone: %s", strerror (errno));
1110
GST_DEBUG_OBJECT (object, "Sending DISEqC");
1111
diseqc (object->fd_frontend, object->diseqc_src, voltage, object->tone);
1112
/* Once diseqc source is set, do not set it again until
1113
* app decides to change it */
1114
object->send_diseqc = FALSE;
1119
feparams.frequency = freq;
1120
feparams.u.ofdm.bandwidth = object->bandwidth;
1121
feparams.u.ofdm.code_rate_HP = object->code_rate_hp;
1122
feparams.u.ofdm.code_rate_LP = object->code_rate_lp;
1123
feparams.u.ofdm.constellation = object->modulation;
1124
feparams.u.ofdm.transmission_mode = object->transmission_mode;
1125
feparams.u.ofdm.guard_interval = object->guard_interval;
1126
feparams.u.ofdm.hierarchy_information = object->hierarchy_information;
1127
feparams.inversion = object->inversion;
1129
GST_INFO_OBJECT (object, "tuning DVB-T to %d Hz\n", freq);
1132
GST_INFO_OBJECT (object, "Tuning DVB-C to %d, srate=%d", freq, sym_rate);
1133
feparams.frequency = freq;
1134
feparams.inversion = INVERSION_OFF;
1135
feparams.u.qam.fec_inner = FEC_AUTO;
1136
feparams.u.qam.modulation = object->modulation;
1137
feparams.u.qam.symbol_rate = sym_rate;
1140
g_error ("Unknown frontend type: %d", object->adapter_type);
1145
/* now tune the frontend */
1146
if (ioctl (object->fd_frontend, FE_SET_FRONTEND, &feparams) < 0) {
1147
g_warning ("Error tuning channel: %s", strerror (errno));
1150
/* set pid filters */
1151
gst_dvbsrc_set_pes_filters (object);
1158
gst_dvbsrc_unset_pes_filters (GstDvbSrc * object)
1162
GST_INFO_OBJECT (object, "clearing PES filter");
1164
for (i = 0; i < MAX_FILTERS; i++) {
1165
if (object->fd_filters[i] == -1)
1167
close (object->fd_filters[i]);
1168
object->fd_filters[i] = -1;
1173
gst_dvbsrc_set_pes_filters (GstDvbSrc * object)
1177
struct dmx_pes_filter_params pes_filter;
1179
GST_INFO_OBJECT (object, "Setting PES filter");
1181
for (i = 0; i < MAX_FILTERS; i++) {
1182
if (object->pids[i] == 0)
1185
fd = &object->fd_filters[i];
1186
pid = object->pids[i];
1189
if ((*fd = open (object->demux_dev, O_RDWR)) < 0)
1190
g_error ("Error opening demuxer: %s (%s)", strerror (errno),
1193
g_return_if_fail (*fd != -1);
1195
pes_filter.pid = pid;
1196
pes_filter.input = DMX_IN_FRONTEND;
1197
pes_filter.output = DMX_OUT_TS_TAP;
1198
pes_filter.pes_type = DMX_PES_OTHER;
1199
pes_filter.flags = DMX_IMMEDIATE_START;
1201
GST_INFO_OBJECT (object, "Setting pes-filter, pid = %d, type = %d",
1202
pes_filter.pid, pes_filter.pes_type);
1204
if (ioctl (*fd, DMX_SET_PES_FILTER, &pes_filter) < 0)
1205
GST_WARNING_OBJECT (object, "Error setting PES filter on %s: %s",
1206
object->demux_dev, strerror (errno));
1208
/* always have PAT in the filter if we haven't used all our filter slots */
1209
if (object->pids[0] != 8192 && i < MAX_FILTERS) {
1210
/* pid 8192 means get whole ts */
1212
pes_filter.input = DMX_IN_FRONTEND;
1213
pes_filter.output = DMX_OUT_TS_TAP;
1214
pes_filter.pes_type = DMX_PES_OTHER;
1215
pes_filter.flags = DMX_IMMEDIATE_START;
1217
fd = &object->fd_filters[i];
1219
if ((*fd = open (object->demux_dev, O_RDWR)) < 0) {
1220
GST_WARNING_OBJECT ("Error opening demuxer: %s (%s)",
1221
strerror (errno), object->demux_dev);
1223
GST_INFO_OBJECT (object, "Setting pes-filter, pid = %d, type = %d",
1224
pes_filter.pid, pes_filter.pes_type);
1226
if (ioctl (*fd, DMX_SET_PES_FILTER, &pes_filter) < 0)
1227
GST_WARNING_OBJECT (object, "Error setting PES filter on %s: %s",
1228
object->demux_dev, strerror (errno));