1
/* GStreamer DVB source
2
* Copyright (C) 2006 Zaheer Abbas Merali <zaheerabbas at merali
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
21
* SECTION:element-dvbsrc
23
* dvbsrc can be used to capture video from DVB cards, DVB-T, DVB-S or DVB-T.
26
* <title>Example launch line</title>
28
* gst-launch dvbsrc modulation="QAM 64" trans-mode=8k bandwidth=8MHz frequency=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 demux. ! queue max-size-buffers=0 max-size-time=0 ! flump3dec ! alsasink sync
29
* ]| 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
30
* pipeline and outputs the first tv program on the transport stream.
32
* gst-launch dvbsrc modulation="QAM 64" trans-mode=8k bandwidth=8 frequency=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 demux. ! queue max-size-buffers=0 max-size-time=0 ! flump3dec ! alsasink
33
* ]| 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.
35
* gst-launch dvbsrc polarity="h" frequency=11302000 srate=27500 diseqc-src=0 pids=102:103 ! queue max-size-buffers=0 max-size-time=0 ! flumpeg2vdec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! flump3dec ! alsasink
36
* ]| 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.
44
#include "gstdvbsrc.h"
46
#include <sys/ioctl.h>
55
#define _XOPEN_SOURCE 500
58
#include <linux/dvb/version.h>
59
#include <linux/dvb/frontend.h>
60
#include <linux/dvb/dmx.h>
62
#include <gst/gst-i18n-plugin.h>
64
GST_DEBUG_CATEGORY_STATIC (gstdvbsrc_debug);
65
#define GST_CAT_DEFAULT (gstdvbsrc_debug)
67
#define SLOF (11700*1000UL)
68
#define LOF1 (9750*1000UL)
69
#define LOF2 (10600*1000UL)
72
static GstElementDetails dvbsrc_details = {
75
"Digital Video Broadcast Source",
76
"P2P-VCR, C-Lab, University of Paderborn\n"
77
"Zaheer Abbas Merali <zaheerabbas at merali dot org>"
86
ARG_DVBSRC_DISEQC_SRC,
92
ARG_DVBSRC_CODE_RATE_HP,
93
ARG_DVBSRC_CODE_RATE_LP,
95
ARG_DVBSRC_MODULATION,
96
ARG_DVBSRC_TRANSMISSION_MODE,
97
ARG_DVBSRC_HIERARCHY_INF,
100
ARG_DVBSRC_STATS_REPORTING_INTERVAL
103
static void gst_dvbsrc_output_frontend_stats (GstDvbSrc * src);
105
#define GST_TYPE_DVBSRC_CODE_RATE (gst_dvbsrc_code_rate_get_type ())
107
gst_dvbsrc_code_rate_get_type (void)
109
static GType dvbsrc_code_rate_type = 0;
110
static GEnumValue code_rate_types[] = {
111
{FEC_NONE, "NONE", "NONE"},
112
{FEC_1_2, "1/2", "1/2"},
113
{FEC_2_3, "2/3", "2/3"},
114
{FEC_3_4, "3/4", "3/4"},
115
{FEC_4_5, "4/5", "4/5"},
116
{FEC_5_6, "5/6", "5/6"},
117
{FEC_6_7, "6/7", "6/7"},
118
{FEC_7_8, "7/8", "7/8"},
119
{FEC_8_9, "8/9", "8/9"},
120
{FEC_AUTO, "AUTO", ""},
124
if (!dvbsrc_code_rate_type) {
125
dvbsrc_code_rate_type =
126
g_enum_register_static ("GstDvbSrcCode_Rate", code_rate_types);
128
return dvbsrc_code_rate_type;
131
#define GST_TYPE_DVBSRC_MODULATION (gst_dvbsrc_modulation_get_type ())
133
gst_dvbsrc_modulation_get_type (void)
135
static GType dvbsrc_modulation_type = 0;
136
static GEnumValue modulation_types[] = {
137
{QPSK, "QPSK", "QPSK"},
138
{QAM_16, "QAM 16", "QAM 16"},
139
{QAM_32, "QAM 32", "QAM 32"},
140
{QAM_64, "QAM 64", "QAM 64"},
141
{QAM_128, "QAM 128", "QAM 128"},
142
{QAM_256, "QAM 256", "QAM 256"},
143
{QAM_AUTO, "AUTO", "AUTO"},
144
{VSB_8, "8VSB", "8VSB"},
145
{VSB_16, "16VSB", "16VSB"},
149
if (!dvbsrc_modulation_type) {
150
dvbsrc_modulation_type =
151
g_enum_register_static ("GstDvbSrcModulation", modulation_types);
153
return dvbsrc_modulation_type;
156
#define GST_TYPE_DVBSRC_TRANSMISSION_MODE (gst_dvbsrc_transmission_mode_get_type ())
158
gst_dvbsrc_transmission_mode_get_type (void)
160
static GType dvbsrc_transmission_mode_type = 0;
161
static GEnumValue transmission_mode_types[] = {
162
{TRANSMISSION_MODE_2K, "2k", "2k"},
163
{TRANSMISSION_MODE_8K, "8k", "8k"},
164
{TRANSMISSION_MODE_AUTO, "AUTO", "AUTO"},
168
if (!dvbsrc_transmission_mode_type) {
169
dvbsrc_transmission_mode_type =
170
g_enum_register_static ("GstDvbSrcTransmission_Mode",
171
transmission_mode_types);
173
return dvbsrc_transmission_mode_type;
176
#define GST_TYPE_DVBSRC_BANDWIDTH (gst_dvbsrc_bandwidth_get_type ())
178
gst_dvbsrc_bandwidth_get_type (void)
180
static GType dvbsrc_bandwidth_type = 0;
181
static GEnumValue bandwidth_types[] = {
182
{BANDWIDTH_8_MHZ, "8", "8"},
183
{BANDWIDTH_7_MHZ, "7", "7"},
184
{BANDWIDTH_6_MHZ, "6", "6"},
185
{BANDWIDTH_AUTO, "AUTO", "AUTO"},
189
if (!dvbsrc_bandwidth_type) {
190
dvbsrc_bandwidth_type =
191
g_enum_register_static ("GstDvbSrcBandwidth", bandwidth_types);
193
return dvbsrc_bandwidth_type;
196
#define GST_TYPE_DVBSRC_GUARD (gst_dvbsrc_guard_get_type ())
198
gst_dvbsrc_guard_get_type (void)
200
static GType dvbsrc_guard_type = 0;
201
static GEnumValue guard_types[] = {
202
{GUARD_INTERVAL_1_32, "32", "32"},
203
{GUARD_INTERVAL_1_16, "16", "16"},
204
{GUARD_INTERVAL_1_8, "8", "8"},
205
{GUARD_INTERVAL_1_4, "4", "4"},
206
{GUARD_INTERVAL_AUTO, "AUTO", "AUTO"},
210
if (!dvbsrc_guard_type) {
211
dvbsrc_guard_type = g_enum_register_static ("GstDvbSrcGuard", guard_types);
213
return dvbsrc_guard_type;
216
#define GST_TYPE_DVBSRC_HIERARCHY (gst_dvbsrc_hierarchy_get_type ())
218
gst_dvbsrc_hierarchy_get_type (void)
220
static GType dvbsrc_hierarchy_type = 0;
221
static GEnumValue hierarchy_types[] = {
222
{HIERARCHY_NONE, "NONE", "NONE"},
223
{HIERARCHY_1, "1", "1"},
224
{HIERARCHY_2, "2", "2"},
225
{HIERARCHY_4, "4", "4"},
226
{HIERARCHY_AUTO, "AUTO", "AUTO"},
230
if (!dvbsrc_hierarchy_type) {
231
dvbsrc_hierarchy_type =
232
g_enum_register_static ("GstDvbSrcHierarchy", hierarchy_types);
234
return dvbsrc_hierarchy_type;
237
#define GST_TYPE_DVBSRC_INVERSION (gst_dvbsrc_inversion_get_type ())
239
gst_dvbsrc_inversion_get_type (void)
241
static GType dvbsrc_inversion_type = 0;
242
static GEnumValue inversion_types[] = {
243
{INVERSION_OFF, "OFF", "OFF"},
244
{INVERSION_ON, "ON", "ON"},
245
{INVERSION_AUTO, "AUTO", "AUTO"},
249
if (!dvbsrc_inversion_type) {
250
dvbsrc_inversion_type =
251
g_enum_register_static ("GstDvbSrcInversion", inversion_types);
253
return dvbsrc_inversion_type;
256
static void gst_dvbsrc_finalize (GObject * object);
257
static void gst_dvbsrc_set_property (GObject * object, guint prop_id,
258
const GValue * value, GParamSpec * pspec);
259
static void gst_dvbsrc_get_property (GObject * object, guint prop_id,
260
GValue * value, GParamSpec * pspec);
262
static GstFlowReturn gst_dvbsrc_create (GstPushSrc * element,
263
GstBuffer ** buffer);
265
static gboolean gst_dvbsrc_start (GstBaseSrc * bsrc);
266
static gboolean gst_dvbsrc_stop (GstBaseSrc * bsrc);
267
static GstStateChangeReturn gst_dvbsrc_change_state (GstElement * element,
268
GstStateChange transition);
270
static gboolean gst_dvbsrc_unlock (GstBaseSrc * bsrc);
271
static gboolean gst_dvbsrc_is_seekable (GstBaseSrc * bsrc);
272
static gboolean gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size);
274
static gboolean gst_dvbsrc_tune (GstDvbSrc * object);
275
static void gst_dvbsrc_set_pes_filters (GstDvbSrc * object);
276
static void gst_dvbsrc_unset_pes_filters (GstDvbSrc * object);
278
static gboolean gst_dvbsrc_frontend_status (GstDvbSrc * object);
280
static GstStaticPadTemplate ts_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
285
"mpegversion = (int) 2," "systemstream = (boolean) TRUE"));
288
******************************
293
******************************
296
GST_BOILERPLATE (GstDvbSrc, gst_dvbsrc, GstPushSrc, GST_TYPE_PUSH_SRC);
299
gst_dvbsrc_base_init (gpointer gclass)
301
GstDvbSrcClass *klass = (GstDvbSrcClass *) gclass;
302
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
304
gst_element_class_add_pad_template (element_class,
305
gst_static_pad_template_get (&ts_src_factory));
307
gst_element_class_set_details (element_class, &dvbsrc_details);
311
/* initialize the plugin's class */
313
gst_dvbsrc_class_init (GstDvbSrcClass * klass)
315
GObjectClass *gobject_class;
316
GstElementClass *gstelement_class;
317
GstBaseSrcClass *gstbasesrc_class;
318
GstPushSrcClass *gstpushsrc_class;
320
gobject_class = (GObjectClass *) klass;
321
gstelement_class = (GstElementClass *) klass;
322
gstbasesrc_class = (GstBaseSrcClass *) klass;
323
gstpushsrc_class = (GstPushSrcClass *) klass;
325
gobject_class->set_property = gst_dvbsrc_set_property;
326
gobject_class->get_property = gst_dvbsrc_get_property;
327
gobject_class->finalize = gst_dvbsrc_finalize;
329
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_dvbsrc_change_state);
330
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dvbsrc_start);
331
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dvbsrc_stop);
332
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_dvbsrc_unlock);
333
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_dvbsrc_is_seekable);
334
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_dvbsrc_get_size);
336
gstpushsrc_class->create = gst_dvbsrc_create;
337
g_object_class_install_property (gobject_class, ARG_DVBSRC_ADAPTER,
338
g_param_spec_int ("adapter",
339
"The adapter device number",
340
"The adapter device number (eg. 0 for adapter0)", 0, 16, 0,
343
g_object_class_install_property (gobject_class, ARG_DVBSRC_FRONTEND,
344
g_param_spec_int ("frontend",
345
"The frontend device number",
346
"The frontend device number (eg. 0 for frontend0)", 0, 16, 0,
349
g_object_class_install_property (gobject_class, ARG_DVBSRC_FREQUENCY,
350
g_param_spec_int ("frequency",
351
"frequency", "Frequency", 0, G_MAXINT, 0, G_PARAM_READWRITE));
353
g_object_class_install_property (gobject_class, ARG_DVBSRC_POLARITY,
354
g_param_spec_string ("polarity",
355
"polarity", "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 ("symbol-rate",
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-source",
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,
388
g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_HP,
389
g_param_spec_enum ("code-rate-hp",
391
"High Priority Code Rate (DVB-T, DVB-S and DVB-C)",
392
GST_TYPE_DVBSRC_CODE_RATE, FEC_AUTO, G_PARAM_READWRITE));
394
g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_LP,
395
g_param_spec_enum ("code-rate-lp",
397
"Low Priority Code Rate (DVB-T)",
398
GST_TYPE_DVBSRC_CODE_RATE, 1, G_PARAM_READWRITE));
400
g_object_class_install_property (gobject_class, ARG_DVBSRC_GUARD,
401
g_param_spec_enum ("guard",
403
"Guard Interval (DVB-T)",
404
GST_TYPE_DVBSRC_GUARD, 1, G_PARAM_READWRITE));
406
g_object_class_install_property (gobject_class, ARG_DVBSRC_MODULATION,
407
g_param_spec_enum ("modulation",
409
"Modulation (DVB-T and DVB-C)",
410
GST_TYPE_DVBSRC_MODULATION, 1, G_PARAM_READWRITE));
412
g_object_class_install_property (gobject_class,
413
ARG_DVBSRC_TRANSMISSION_MODE,
414
g_param_spec_enum ("trans-mode",
416
"Transmission Mode (DVB-T)",
417
GST_TYPE_DVBSRC_TRANSMISSION_MODE, 1, G_PARAM_READWRITE));
419
g_object_class_install_property (gobject_class, ARG_DVBSRC_HIERARCHY_INF,
420
g_param_spec_enum ("hierarchy",
422
"Hierarchy Information (DVB-T)",
423
GST_TYPE_DVBSRC_HIERARCHY, 1, G_PARAM_READWRITE));
424
g_object_class_install_property (gobject_class, ARG_DVBSRC_INVERSION,
425
g_param_spec_enum ("inversion",
427
"Inversion Information (DVB-T and DVB-C)",
428
GST_TYPE_DVBSRC_INVERSION, 1, G_PARAM_READWRITE));
430
g_object_class_install_property (gobject_class,
431
ARG_DVBSRC_STATS_REPORTING_INTERVAL,
432
g_param_spec_uint ("stats-reporting-interval",
433
"stats-reporting-interval",
434
"The number of reads before reporting frontend stats",
435
0, G_MAXUINT, 100, G_PARAM_READWRITE));
438
/* initialize the new element
439
* instantiate pads and add them to element
441
* initialize structure
444
gst_dvbsrc_init (GstDvbSrc * object, GstDvbSrcClass * klass)
448
GST_INFO_OBJECT (object, "gst_dvbsrc_init");
450
/* We are a live source */
451
gst_base_src_set_live (GST_BASE_SRC (object), TRUE);
453
object->fd_frontend = -1;
456
for (i = 0; i < MAX_FILTERS; i++) {
457
object->pids[i] = G_MAXUINT16;
458
object->fd_filters[i] = -1;
460
/* Pid 8192 on DVB gets the whole transport stream */
461
object->pids[0] = 8192;
463
object->adapter_number = 0;
464
object->frontend_number = 0;
465
object->sym_rate = DEFAULT_SYMBOL_RATE;
466
object->diseqc_src = DEFAULT_DISEQC_SRC;
467
object->send_diseqc = FALSE;
468
object->code_rate_hp = FEC_AUTO;
469
object->tune_mutex = g_mutex_new ();
474
gst_dvbsrc_set_property (GObject * _object, guint prop_id,
475
const GValue * value, GParamSpec * pspec)
479
g_return_if_fail (GST_IS_DVBSRC (_object));
480
object = GST_DVBSRC (_object);
483
case ARG_DVBSRC_ADAPTER:
484
object->adapter_number = g_value_get_int (value);
486
case ARG_DVBSRC_FRONTEND:
487
object->frontend_number = g_value_get_int (value);
489
case ARG_DVBSRC_DISEQC_SRC:
490
if (object->diseqc_src != g_value_get_int (value)) {
491
object->diseqc_src = g_value_get_int (value);
492
object->send_diseqc = TRUE;
494
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_DISEQC_ID");
496
case ARG_DVBSRC_FREQUENCY:
497
object->freq = g_value_get_int (value);
498
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_FREQUENCY");
500
case ARG_DVBSRC_POLARITY:
502
const char *s = NULL;
504
s = g_value_get_string (value);
506
object->pol = (s[0] == 'h' || s[0] == 'H') ? DVB_POL_H : DVB_POL_V;
508
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_POLARITY");
510
case ARG_DVBSRC_PIDS:
514
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_PIDS");
515
pid_string = g_value_dup_string (value);
516
if (!strcmp (pid_string, "8192")) {
517
/* get the whole ts */
518
object->pids[0] = 8192;
525
tmp = pids = g_strsplit (pid_string, ":", MAX_FILTERS);
529
/* always add the PAT and CAT pids */
534
while (*pids != NULL && pid_count < MAX_FILTERS) {
535
pid = strtol (*pids, NULL, 0);
536
if (pid > 1 && pid <= 8192) {
537
GST_INFO_OBJECT (object, "Parsed Pid: %d\n", pid);
538
object->pids[pid_count] = pid;
546
/* if we are in playing or paused, then set filters now */
547
GST_INFO_OBJECT (object, "checking if playing for setting pes filters");
548
if (GST_ELEMENT (object)->current_state == GST_STATE_PLAYING ||
549
GST_ELEMENT (object)->current_state == GST_STATE_PAUSED) {
550
GST_INFO_OBJECT (object, "Setting pes filters now");
551
gst_dvbsrc_set_pes_filters (object);
555
case ARG_DVBSRC_SYM_RATE:
556
object->sym_rate = g_value_get_int (value);
557
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_SYM_RATE to value %d",
558
g_value_get_int (value));
561
case ARG_DVBSRC_BANDWIDTH:
562
object->bandwidth = g_value_get_enum (value);
564
case ARG_DVBSRC_CODE_RATE_HP:
565
object->code_rate_hp = g_value_get_enum (value);
567
case ARG_DVBSRC_CODE_RATE_LP:
568
object->code_rate_lp = g_value_get_enum (value);
570
case ARG_DVBSRC_GUARD:
571
object->guard_interval = g_value_get_enum (value);
573
case ARG_DVBSRC_MODULATION:
574
object->modulation = g_value_get_enum (value);
576
case ARG_DVBSRC_TRANSMISSION_MODE:
577
object->transmission_mode = g_value_get_enum (value);
579
case ARG_DVBSRC_HIERARCHY_INF:
580
object->hierarchy_information = g_value_get_enum (value);
582
case ARG_DVBSRC_INVERSION:
583
object->inversion = g_value_get_enum (value);
585
case ARG_DVBSRC_TUNE:
586
GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_TUNE");
587
/* if we are in paused/playing state tune now, otherwise in ready to paused state change */
588
if (gst_element_get_state
589
(GST_ELEMENT (object), NULL, NULL,
590
GST_CLOCK_TIME_NONE) > GST_STATE_READY) {
591
g_mutex_lock (object->tune_mutex);
592
gst_dvbsrc_tune (object);
593
g_mutex_unlock (object->tune_mutex);
596
case ARG_DVBSRC_STATS_REPORTING_INTERVAL:
597
object->stats_interval = g_value_get_uint (value);
598
object->stats_counter = 0;
601
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
607
gst_dvbsrc_get_property (GObject * _object, guint prop_id,
608
GValue * value, GParamSpec * pspec)
612
g_return_if_fail (GST_IS_DVBSRC (_object));
613
object = GST_DVBSRC (_object);
616
case ARG_DVBSRC_ADAPTER:
617
g_value_set_int (value, object->adapter_number);
619
case ARG_DVBSRC_FRONTEND:
620
g_value_set_int (value, object->frontend_number);
622
case ARG_DVBSRC_FREQUENCY:
623
g_value_set_int (value, object->freq);
625
case ARG_DVBSRC_POLARITY:
626
if (object->pol == DVB_POL_H)
627
g_value_set_string (value, "H");
629
g_value_set_string (value, "V");
631
case ARG_DVBSRC_SYM_RATE:
632
g_value_set_int (value, object->sym_rate);
634
case ARG_DVBSRC_DISEQC_SRC:
635
g_value_set_int (value, object->diseqc_src);
637
case ARG_DVBSRC_BANDWIDTH:
638
g_value_set_enum (value, object->bandwidth);
640
case ARG_DVBSRC_CODE_RATE_HP:
641
g_value_set_enum (value, object->code_rate_hp);
643
case ARG_DVBSRC_CODE_RATE_LP:
644
g_value_set_enum (value, object->code_rate_lp);
646
case ARG_DVBSRC_GUARD:
647
g_value_set_enum (value, object->guard_interval);
649
case ARG_DVBSRC_MODULATION:
650
g_value_set_enum (value, object->modulation);
652
case ARG_DVBSRC_TRANSMISSION_MODE:
653
g_value_set_enum (value, object->transmission_mode);
655
case ARG_DVBSRC_HIERARCHY_INF:
656
g_value_set_enum (value, object->hierarchy_information);
658
case ARG_DVBSRC_INVERSION:
659
g_value_set_enum (value, object->inversion);
661
case ARG_DVBSRC_STATS_REPORTING_INTERVAL:
662
g_value_set_uint (value, object->stats_interval);
665
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
670
gst_dvbsrc_close_devices (GstDvbSrc * object)
672
gst_dvbsrc_unset_pes_filters (object);
674
close (object->fd_dvr);
676
close (object->fd_frontend);
677
object->fd_frontend = -1;
683
gst_dvbsrc_open_frontend (GstDvbSrc * object)
685
struct dvb_frontend_info fe_info;
686
char *adapter_desc = NULL;
688
GstStructure *adapter_structure;
689
char *adapter_name = NULL;
691
frontend_dev = g_strdup_printf ("/dev/dvb/adapter%d/frontend%d",
692
object->adapter_number, object->frontend_number);
693
GST_INFO_OBJECT (object, "Using frontend device: %s", frontend_dev);
696
if ((object->fd_frontend = open (frontend_dev, O_RDWR)) < 0) {
699
GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
700
(_("Device \"%s\" does not exist."), frontend_dev), (NULL));
703
GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ_WRITE,
704
(_("Could not open frontend device \"%s\"."), frontend_dev),
709
close (object->fd_frontend);
710
g_free (frontend_dev);
714
if (ioctl (object->fd_frontend, FE_GET_INFO, &fe_info) < 0) {
715
GST_ELEMENT_ERROR (object, RESOURCE, SETTINGS,
716
(_("Could not get settings from frontend device \"%s\"."),
717
frontend_dev), GST_ERROR_SYSTEM);
719
close (object->fd_frontend);
720
g_free (frontend_dev);
724
adapter_name = g_strdup (fe_info.name);
726
object->adapter_type = fe_info.type;
727
switch (object->adapter_type) {
729
adapter_desc = "DVB-S";
730
adapter_structure = gst_structure_new ("dvb-adapter",
731
"type", G_TYPE_STRING, adapter_desc,
732
"name", G_TYPE_STRING, adapter_name,
733
"auto-fec", G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_FEC_AUTO, NULL);
736
adapter_desc = "DVB-C";
737
adapter_structure = gst_structure_new ("dvb-adapter",
738
"type", G_TYPE_STRING, adapter_desc,
739
"name", G_TYPE_STRING, adapter_name,
740
"auto-inversion", G_TYPE_BOOLEAN,
741
fe_info.caps & FE_CAN_INVERSION_AUTO, "auto-qam", G_TYPE_BOOLEAN,
742
fe_info.caps & FE_CAN_QAM_AUTO, "auto-fec", G_TYPE_BOOLEAN,
743
fe_info.caps & FE_CAN_FEC_AUTO, NULL);
746
adapter_desc = "DVB-T";
747
adapter_structure = gst_structure_new ("dvb-adapter",
748
"type", G_TYPE_STRING, adapter_desc,
749
"name", G_TYPE_STRING, adapter_name,
750
"auto-inversion", G_TYPE_BOOLEAN,
751
fe_info.caps & FE_CAN_INVERSION_AUTO, "auto-qam", G_TYPE_BOOLEAN,
752
fe_info.caps & FE_CAN_QAM_AUTO, "auto-transmission-mode",
753
G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_TRANSMISSION_MODE_AUTO,
754
"auto-guard-interval", G_TYPE_BOOLEAN,
755
fe_info.caps & FE_CAN_GUARD_INTERVAL_AUTO, "auto-hierarchy",
756
G_TYPE_BOOLEAN, fe_info.caps % FE_CAN_HIERARCHY_AUTO, "auto-fec",
757
G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_FEC_AUTO, NULL);
760
adapter_desc = "ATSC";
761
adapter_structure = gst_structure_new ("dvb-adapter",
762
"type", G_TYPE_STRING, adapter_desc,
763
"name", G_TYPE_STRING, adapter_name, NULL);
766
g_error ("Unknown frontend type: %d", object->adapter_type);
767
adapter_structure = gst_structure_new ("dvb-adapter",
768
"type", G_TYPE_STRING, "unknown", NULL);
771
GST_INFO_OBJECT (object, "DVB card: %s ", adapter_name);
772
gst_element_post_message (GST_ELEMENT_CAST (object), gst_message_new_element
773
(GST_OBJECT (object), adapter_structure));
774
g_free (frontend_dev);
775
g_free (adapter_name);
780
gst_dvbsrc_open_dvr (GstDvbSrc * object)
784
dvr_dev = g_strdup_printf ("/dev/dvb/adapter%d/dvr%d",
785
object->adapter_number, object->frontend_number);
786
GST_INFO_OBJECT (object, "Using dvr device: %s", dvr_dev);
789
if ((object->fd_dvr = open (dvr_dev, O_RDONLY | O_NONBLOCK)) < 0) {
792
GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
793
(_("Device \"%s\" does not exist."), dvr_dev), (NULL));
796
GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ,
797
(_("Could not open file \"%s\" for reading."), dvr_dev),
805
GST_INFO_OBJECT (object, "Setting buffer size");
806
if (ioctl (object->fd_dvr, DMX_SET_BUFFER_SIZE, 1024 * 1024) < 0) {
807
GST_INFO_OBJECT (object, "DMX_SET_BUFFER_SIZE failed");
814
gst_dvbsrc_finalize (GObject * _object)
818
GST_DEBUG_OBJECT (_object, "gst_dvbsrc_finalize");
820
g_return_if_fail (GST_IS_DVBSRC (_object));
821
object = GST_DVBSRC (_object);
823
/* freeing the mutex segfaults somehow */
824
g_mutex_free (object->tune_mutex);
826
if (G_OBJECT_CLASS (parent_class)->finalize)
827
G_OBJECT_CLASS (parent_class)->finalize (_object);
832
******************************
834
* Plugin Realisation *
836
******************************
841
/* entry point to initialize the plug-in
842
* initialize the plug-in itself
843
* register the element factories and pad templates
844
* register the features
847
gst_dvbsrc_plugin_init (GstPlugin * plugin)
849
GST_DEBUG_CATEGORY_INIT (gstdvbsrc_debug, "dvbsrc", 0, "DVB Source Element");
852
GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
854
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
855
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
856
#endif /* ENABLE_NLS */
858
return gst_element_register (plugin, "dvbsrc", GST_RANK_NONE,
863
read_device (int fd, int adapter_number, int frontend_number, int size,
867
struct pollfd pfd[1];
870
const int TIMEOUT = 100;
872
GstBuffer *buf = gst_buffer_new_and_alloc (size);
874
g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
881
pfd[0].events = POLLIN;
883
while (count < size) {
884
ret_val = poll (pfd, 1, TIMEOUT);
886
if (pfd[0].revents & POLLIN) {
889
tmp = read (fd, GST_BUFFER_DATA (buf) + count, size - count);
892
("Unable to read from device: /dev/dvb/adapter%d/dvr%d (%d)",
893
adapter_number, frontend_number, errno);
895
if (attempts % 10 == 0) {
897
("Unable to read from device after %u attempts: /dev/dvb/adapter%d/dvr%d",
898
attempts, adapter_number, frontend_number);
904
GST_LOG ("revents = %d\n", pfd[0].revents);
906
} else if (ret_val == 0) { // poll timeout
908
GST_INFO ("Reading from device /dev/dvb/adapter%d/dvr%d timedout (%d)",
909
adapter_number, frontend_number, attempts);
911
if (attempts % 10 == 0) {
913
("Unable to read after %u attempts from device: /dev/dvb/adapter%d/dvr%d (%d)",
914
attempts, adapter_number, frontend_number, errno);
915
gst_element_post_message (GST_ELEMENT_CAST (object),
916
gst_message_new_element (GST_OBJECT (object),
917
gst_structure_empty_new ("dvb-read-failure")));
920
} else if (errno == -EINTR) { // poll interrupted
921
if (attempts % 50 == 0) {
922
gst_buffer_unref (buf);
929
GST_BUFFER_SIZE (buf) = count;
930
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
935
gst_dvbsrc_create (GstPushSrc * element, GstBuffer ** buf)
938
GstFlowReturn retval = GST_FLOW_ERROR;
941
object = GST_DVBSRC (element);
942
GST_LOG ("fd_dvr: %d", object->fd_dvr);
944
//g_object_get(G_OBJECT(object), "blocksize", &buffer_size, NULL);
945
buffer_size = DEFAULT_BUFFER_SIZE;
947
/* device can not be tuned during read */
948
g_mutex_lock (object->tune_mutex);
951
if (object->fd_dvr > -1) {
952
/* --- Read TS from DVR device --- */
953
GST_DEBUG_OBJECT (object, "Reading from DVR device");
954
*buf = read_device (object->fd_dvr, object->adapter_number,
955
object->frontend_number, buffer_size, object);
959
retval = GST_FLOW_OK;
961
caps = gst_pad_get_caps (GST_BASE_SRC_PAD (object));
962
gst_buffer_set_caps (*buf, caps);
963
gst_caps_unref (caps);
965
GST_DEBUG_OBJECT (object, "Failed to read from device");
966
gst_element_post_message (GST_ELEMENT_CAST (object),
967
gst_message_new_element (GST_OBJECT (object),
968
gst_structure_empty_new ("dvb-read-failure")));
971
if (object->stats_interval != 0 &&
972
++object->stats_counter == object->stats_interval) {
973
gst_dvbsrc_output_frontend_stats (object);
974
object->stats_counter = 0;
978
g_mutex_unlock (object->tune_mutex);
983
static GstStateChangeReturn
984
gst_dvbsrc_change_state (GstElement * element, GstStateChange transition)
987
GstStateChangeReturn ret;
989
src = GST_DVBSRC (element);
990
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
992
switch (transition) {
993
case GST_STATE_CHANGE_NULL_TO_READY:
994
/* open frontend then close it again, just so caps sent */
995
gst_dvbsrc_open_frontend (src);
996
if (src->fd_frontend) {
997
close (src->fd_frontend);
1009
gst_dvbsrc_start (GstBaseSrc * bsrc)
1011
GstDvbSrc *src = GST_DVBSRC (bsrc);
1013
gst_dvbsrc_open_frontend (src);
1014
if (!gst_dvbsrc_tune (src)) {
1015
GST_ERROR_OBJECT (src, "Not able to lock on to the dvb channel");
1016
close (src->fd_frontend);
1019
if (!gst_dvbsrc_frontend_status (src)) {
1020
/* unset filters also */
1021
gst_dvbsrc_unset_pes_filters (src);
1022
close (src->fd_frontend);
1025
if (!gst_dvbsrc_open_dvr (src)) {
1026
GST_ERROR_OBJECT (src, "Not able to open dvr_device");
1027
/* unset filters also */
1028
gst_dvbsrc_unset_pes_filters (src);
1029
close (src->fd_frontend);
1037
gst_dvbsrc_stop (GstBaseSrc * bsrc)
1039
GstDvbSrc *src = GST_DVBSRC (bsrc);
1041
gst_dvbsrc_close_devices (src);
1046
gst_dvbsrc_unlock (GstBaseSrc * bsrc)
1052
gst_dvbsrc_is_seekable (GstBaseSrc * bsrc)
1058
gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size)
1064
gst_dvbsrc_output_frontend_stats (GstDvbSrc * src)
1067
uint16_t snr, _signal;
1068
uint32_t ber, uncorrected_blocks;
1069
GstMessage *message;
1070
GstStructure *structure;
1071
int fe_fd = src->fd_frontend;
1073
ioctl (fe_fd, FE_READ_STATUS, &status);
1074
ioctl (fe_fd, FE_READ_SIGNAL_STRENGTH, &_signal);
1075
ioctl (fe_fd, FE_READ_SNR, &snr);
1076
ioctl (fe_fd, FE_READ_BER, &ber);
1077
ioctl (fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
1079
structure = gst_structure_new ("dvb-frontend-stats", "status", G_TYPE_INT,
1080
status, "signal", G_TYPE_INT, _signal, "snr", G_TYPE_INT, snr,
1081
"ber", G_TYPE_INT, ber, "unc", G_TYPE_INT, uncorrected_blocks,
1082
"lock", G_TYPE_BOOLEAN, status & FE_HAS_LOCK, NULL);
1083
message = gst_message_new_element (GST_OBJECT (src), structure);
1084
gst_element_post_message (GST_ELEMENT (src), message);
1088
gst_dvbsrc_frontend_status (GstDvbSrc * object)
1090
fe_status_t status = 0;
1093
GST_INFO_OBJECT (object, "gst_dvbsrc_frontend_status\n");
1095
if (object->fd_frontend < 0) {
1096
GST_ERROR_OBJECT (object,
1097
"Trying to get frontend status from not opened device!");
1100
GST_INFO_OBJECT (object, "fd-frontend: %d", object->fd_frontend);
1102
for (i = 0; i < 15; i++) {
1104
GST_INFO_OBJECT (object, ".");
1105
if (ioctl (object->fd_frontend, FE_READ_STATUS, &status) == -1) {
1106
GST_ERROR_OBJECT (object, "Failed reading frontend status.");
1109
gst_dvbsrc_output_frontend_stats (object);
1110
if (status & FE_HAS_LOCK) {
1115
if (!(status & FE_HAS_LOCK)) {
1116
GST_INFO_OBJECT (object,
1117
"Not able to lock to the signal on the given frequency.\n");
1125
struct dvb_diseqc_master_cmd cmd;
1130
diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
1131
fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
1133
if (ioctl (fd, FE_SET_TONE, SEC_TONE_OFF) == -1) {
1134
GST_ERROR ("Setting tone to off failed");
1138
if (ioctl (fd, FE_SET_VOLTAGE, v) == -1) {
1139
GST_ERROR ("Setting voltage failed");
1144
GST_LOG ("diseqc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", cmd->cmd.msg[0],
1145
cmd->cmd.msg[1], cmd->cmd.msg[2], cmd->cmd.msg[3], cmd->cmd.msg[4],
1147
if (ioctl (fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1) {
1148
GST_ERROR ("Sending diseqc command failed");
1152
usleep (cmd->wait * 1000);
1155
if (ioctl (fd, FE_DISEQC_SEND_BURST, b) == -1) {
1156
GST_ERROR ("Sending burst failed");
1162
if (ioctl (fd, FE_SET_TONE, t) == -1) {
1163
GST_ERROR ("Setting tone failed");
1169
/* digital satellite equipment control,
1170
* specification is available from http://www.eutelsat.com/
1173
diseqc (int secfd, int sat_no, int voltage, int tone)
1175
struct diseqc_cmd cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
1177
/* param: high nibble: reset bits, low nibble set bits,
1178
* bits are: option, position, polarizaion, band
1181
0xf0 | (((sat_no * 4) & 0x0f) | (tone == SEC_TONE_ON ? 1 : 0) |
1182
(voltage == SEC_VOLTAGE_13 ? 0 : 2));
1183
/* send twice because some diseqc switches do not respond correctly the
1185
diseqc_send_msg (secfd, voltage, &cmd, tone,
1186
sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
1187
diseqc_send_msg (secfd, voltage, &cmd, tone,
1188
sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
1194
gst_dvbsrc_tune (GstDvbSrc * object)
1196
#if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1197
struct dvbfe_params feparams;
1199
struct dvb_frontend_parameters feparams;
1201
fe_sec_voltage_t voltage;
1205
unsigned int freq = object->freq;
1206
unsigned int sym_rate = object->sym_rate * 1000;
1208
/* found in mail archive on linuxtv.org
1209
* What works well for us is:
1210
* - first establish a TS feed (i.e. tune the frontend and check for success)
1211
* - then set filters (PES/sections)
1212
* - then tell the MPEG decoder to start
1213
* - before tuning: first stop the MPEG decoder, then stop all filters
1215
GST_INFO_OBJECT (object, "gst_dvbsrc_tune");
1217
if (object->fd_frontend < 0) {
1218
/* frontend not opened yet, tune later */
1219
GST_INFO_OBJECT (object, "Frontend not open: tuning later");
1223
gst_dvbsrc_unset_pes_filters (object);
1224
for (j = 0; j < 5; j++) {
1225
switch (object->adapter_type) {
1227
object->tone = SEC_TONE_OFF;
1228
if (freq > 2200000) {
1229
// this must be an absolute frequency
1231
feparams.frequency = (freq - LOF1);
1233
feparams.frequency = (freq - LOF2);
1234
object->tone = SEC_TONE_ON;
1237
// this is an L-Band frequency
1238
feparams.frequency = freq;
1240
feparams.inversion = INVERSION_AUTO;
1241
GST_DEBUG_OBJECT (object, "api version %d.%d", DVB_API_VERSION,
1242
DVB_API_VERSION_MINOR);
1243
#if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1244
GST_DEBUG_OBJECT (object, "using multiproto driver");
1245
feparams.delsys.dvbs.symbol_rate = sym_rate;
1246
feparams.delsys.dvbs.fec = object->code_rate_hp;
1248
feparams.u.qpsk.symbol_rate = sym_rate;
1249
feparams.u.qpsk.fec_inner = object->code_rate_hp;
1251
GST_INFO_OBJECT (object,
1252
"tuning DVB-S to L-Band:%u, Pol:%d, srate=%u, 22kHz=%s",
1253
feparams.frequency, object->pol, sym_rate,
1254
object->tone == SEC_TONE_ON ? "on" : "off");
1256
if (object->pol == DVB_POL_H)
1257
voltage = SEC_VOLTAGE_18;
1259
voltage = SEC_VOLTAGE_13;
1261
if (object->diseqc_src == -1 || object->send_diseqc == FALSE) {
1262
if (ioctl (object->fd_frontend, FE_SET_VOLTAGE, voltage) < 0) {
1263
g_warning ("Unable to set voltage on dvb frontend device");
1266
if (ioctl (object->fd_frontend, FE_SET_TONE, object->tone) < 0) {
1267
g_warning ("Error setting tone: %s", strerror (errno));
1270
GST_DEBUG_OBJECT (object, "Sending DISEqC");
1271
diseqc (object->fd_frontend, object->diseqc_src, voltage,
1273
/* Once diseqc source is set, do not set it again until
1274
* app decides to change it */
1275
//object->send_diseqc = FALSE;
1281
feparams.frequency = freq;
1282
#if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1284
feparams.u.ofdm.bandwidth = object->bandwidth;
1285
feparams.u.ofdm.code_rate_HP = object->code_rate_hp;
1286
feparams.u.ofdm.code_rate_LP = object->code_rate_lp;
1287
feparams.u.ofdm.constellation = object->modulation;
1288
feparams.u.ofdm.transmission_mode = object->transmission_mode;
1289
feparams.u.ofdm.guard_interval = object->guard_interval;
1290
feparams.u.ofdm.hierarchy_information = object->hierarchy_information;
1292
feparams.inversion = object->inversion;
1294
GST_INFO_OBJECT (object, "tuning DVB-T to %d Hz\n", freq);
1297
GST_INFO_OBJECT (object, "Tuning DVB-C to %d, srate=%d", freq,
1299
feparams.frequency = freq;
1300
feparams.inversion = object->inversion;
1301
feparams.u.qam.fec_inner = object->code_rate_hp;
1302
feparams.u.qam.modulation = object->modulation;
1303
feparams.u.qam.symbol_rate = sym_rate;
1306
GST_INFO_OBJECT (object, "Tuning ATSC to %d", freq);
1307
feparams.frequency = freq;
1308
feparams.u.vsb.modulation = object->modulation;
1311
g_error ("Unknown frontend type: %d", object->adapter_type);
1315
/* now tune the frontend */
1316
#if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1317
if (ioctl (object->fd_frontend, DVBFE_SET_PARAMS, &feparams) < 0) {
1319
if (ioctl (object->fd_frontend, FE_SET_FRONTEND, &feparams) < 0) {
1321
g_warning ("Error tuning channel: %s", strerror (errno));
1323
for (i = 0; i < 5; i++) {
1325
if (ioctl (object->fd_frontend, FE_READ_STATUS, &status) == -1) {
1326
perror ("FE_READ_STATUS");
1329
GST_LOG_OBJECT (object, "status == 0x%02x", status);
1331
if (status & FE_HAS_LOCK)
1334
if (!(status & FE_HAS_LOCK))
1336
/* set pid filters */
1337
gst_dvbsrc_set_pes_filters (object);
1344
gst_dvbsrc_unset_pes_filters (GstDvbSrc * object)
1348
GST_INFO_OBJECT (object, "clearing PES filter");
1350
for (i = 0; i < MAX_FILTERS; i++) {
1351
if (object->fd_filters[i] == -1)
1353
close (object->fd_filters[i]);
1354
object->fd_filters[i] = -1;
1359
gst_dvbsrc_set_pes_filters (GstDvbSrc * object)
1363
struct dmx_pes_filter_params pes_filter;
1364
gchar *demux_dev = g_strdup_printf ("/dev/dvb/adapter%d/demux%d",
1365
object->adapter_number, object->frontend_number);
1367
GST_INFO_OBJECT (object, "Setting PES filter");
1369
for (i = 0; i < MAX_FILTERS; i++) {
1370
if (object->pids[i] == G_MAXUINT16)
1373
fd = &object->fd_filters[i];
1374
pid = object->pids[i];
1377
if ((*fd = open (demux_dev, O_RDWR)) < 0) {
1378
g_error ("Error opening demuxer: %s (%s)", strerror (errno), demux_dev);
1381
g_return_if_fail (*fd != -1);
1383
pes_filter.pid = pid;
1384
pes_filter.input = DMX_IN_FRONTEND;
1385
pes_filter.output = DMX_OUT_TS_TAP;
1386
pes_filter.pes_type = DMX_PES_OTHER;
1387
pes_filter.flags = DMX_IMMEDIATE_START;
1389
GST_INFO_OBJECT (object, "Setting pes-filter, pid = %d, type = %d",
1390
pes_filter.pid, pes_filter.pes_type);
1392
if (ioctl (*fd, DMX_SET_PES_FILTER, &pes_filter) < 0)
1393
GST_WARNING_OBJECT (object, "Error setting PES filter on %s: %s",
1394
demux_dev, strerror (errno));