dvb: better dvsrc polarity info
[platform/upstream/gstreamer.git] / sys / dvb / gstdvbsrc.c
1 /* GStreamer DVB source
2  * Copyright (C) 2006 Zaheer Abbas Merali <zaheerabbas at merali
3  *                                         dot org>
4  *
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.
9  *
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.
14  *
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.
19  */
20 /**
21  * SECTION:element-dvbsrc
22  *
23  * dvbsrc can be used to capture video from DVB cards, DVB-T, DVB-S or DVB-T.
24  * 
25  * <refsect2>
26  * <title>Example launch line</title>
27  * |[
28  * 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 ! mpegtsdemux name=demux ! queue max-size-buffers=0 max-size-time=0 ! mpeg2dec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! mad ! alsasink
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 pipeline and renders the first tv program on the transport stream.
30  * |[
31  * 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=100:256:257 ! mpegtsdemux name=demux ! queue max-size-buffers=0 max-size-time=0 ! mpeg2dec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! mad ! alsasink
32  * ]| Captures and renders a transport stream from dvb card 0 that is a DVB-T card for a program at tuned frequency 514000000 with PMT pid 100 and elementary stream pids of 256, 257 with other parameters as seen in the pipeline.
33  * |[
34  * gst-launch dvbsrc polarity="h" frequency=11302000 symbol-rate=27500 diseqc-src=0 pids=50:102:103 ! mpegtsdemux name=demux ! queue max-size-buffers=0 max-size-time=0 ! mpeg2dec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! mad ! alsasink
35  * ]| Captures and renders a 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 with PMT pid of 50 and elementary stream pids of 102 and 103.
36  * </refsect2>
37  */
38
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42
43 #include "gstdvbsrc.h"
44 #include <gst/gst.h>
45 #include <gst/glib-compat-private.h>
46 #include <sys/ioctl.h>
47 #include <sys/poll.h>
48 #include <fcntl.h>
49 #include <errno.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include "_stdint.h"
54
55 #define _XOPEN_SOURCE 500
56 #include <unistd.h>
57
58 #include <linux/dvb/version.h>
59 #include <linux/dvb/frontend.h>
60 #include <linux/dvb/dmx.h>
61
62 #include <gst/gst-i18n-plugin.h>
63
64 GST_DEBUG_CATEGORY_STATIC (gstdvbsrc_debug);
65 #define GST_CAT_DEFAULT (gstdvbsrc_debug)
66
67 #define SLOF (11700*1000UL)
68 #define LOF1 (9750*1000UL)
69 #define LOF2 (10600*1000UL)
70
71 /* Arguments */
72 enum
73 {
74   ARG_0,
75   ARG_DVBSRC_ADAPTER,
76   ARG_DVBSRC_FRONTEND,
77   ARG_DVBSRC_DISEQC_SRC,
78   ARG_DVBSRC_FREQUENCY,
79   ARG_DVBSRC_POLARITY,
80   ARG_DVBSRC_PIDS,
81   ARG_DVBSRC_SYM_RATE,
82   ARG_DVBSRC_BANDWIDTH,
83   ARG_DVBSRC_CODE_RATE_HP,
84   ARG_DVBSRC_CODE_RATE_LP,
85   ARG_DVBSRC_GUARD,
86   ARG_DVBSRC_MODULATION,
87   ARG_DVBSRC_TRANSMISSION_MODE,
88   ARG_DVBSRC_HIERARCHY_INF,
89   ARG_DVBSRC_TUNE,
90   ARG_DVBSRC_INVERSION,
91   ARG_DVBSRC_STATS_REPORTING_INTERVAL,
92   ARG_DVBSRC_TIMEOUT,
93 };
94
95 #define DEFAULT_ADAPTER 0
96 #define DEFAULT_FRONTEND 0
97 #define DEFAULT_DISEQC_SRC -1   /* disabled */
98 #define DEFAULT_FREQUENCY 0
99 #define DEFAULT_POLARITY "H"
100 #define DEFAULT_PIDS "8192"
101 #define DEFAULT_SYMBOL_RATE 0
102 #define DEFAULT_BANDWIDTH BANDWIDTH_7_MHZ
103 #define DEFAULT_CODE_RATE_HP FEC_AUTO
104 #define DEFAULT_CODE_RATE_LP FEC_1_2
105 #define DEFAULT_GUARD GUARD_INTERVAL_1_16
106 #define DEFAULT_MODULATION QAM_16
107 #define DEFAULT_TRANSMISSION_MODE TRANSMISSION_MODE_8K
108 #define DEFAULT_HIERARCHY HIERARCHY_1
109 #define DEFAULT_INVERSION INVERSION_ON
110 #define DEFAULT_STATS_REPORTING_INTERVAL 100
111 #define DEFAULT_TIMEOUT 1000000 /* 1 second */
112
113 #define DEFAULT_BUFFER_SIZE 8192        /* not a property */
114
115 static void gst_dvbsrc_output_frontend_stats (GstDvbSrc * src);
116
117 #define GST_TYPE_DVBSRC_CODE_RATE (gst_dvbsrc_code_rate_get_type ())
118 static GType
119 gst_dvbsrc_code_rate_get_type (void)
120 {
121   static GType dvbsrc_code_rate_type = 0;
122   static GEnumValue code_rate_types[] = {
123     {FEC_NONE, "NONE", "none"},
124     {FEC_1_2, "1/2", "1/2"},
125     {FEC_2_3, "2/3", "2/3"},
126     {FEC_3_4, "3/4", "3/4"},
127     {FEC_4_5, "4/5", "4/5"},
128     {FEC_5_6, "5/6", "5/6"},
129     {FEC_6_7, "6/7", "6/7"},
130     {FEC_7_8, "7/8", "7/8"},
131     {FEC_8_9, "8/9", "8/9"},
132     {FEC_AUTO, "AUTO", "auto"},
133     {0, NULL, NULL},
134   };
135
136   if (!dvbsrc_code_rate_type) {
137     dvbsrc_code_rate_type =
138         g_enum_register_static ("GstDvbSrcCode_Rate", code_rate_types);
139   }
140   return dvbsrc_code_rate_type;
141 }
142
143 #define GST_TYPE_DVBSRC_MODULATION (gst_dvbsrc_modulation_get_type ())
144 static GType
145 gst_dvbsrc_modulation_get_type (void)
146 {
147   static GType dvbsrc_modulation_type = 0;
148   static GEnumValue modulation_types[] = {
149     {QPSK, "QPSK", "qpsk"},
150     {QAM_16, "QAM 16", "qam-16"},
151     {QAM_32, "QAM 32", "qam-32"},
152     {QAM_64, "QAM 64", "qam-64"},
153     {QAM_128, "QAM 128", "qam-128"},
154     {QAM_256, "QAM 256", "qam-256"},
155     {QAM_AUTO, "AUTO", "auto"},
156     {VSB_8, "8VSB", "8vsb"},
157     {VSB_16, "16VSB", "16vsb"},
158     {0, NULL, NULL},
159   };
160
161   if (!dvbsrc_modulation_type) {
162     dvbsrc_modulation_type =
163         g_enum_register_static ("GstDvbSrcModulation", modulation_types);
164   }
165   return dvbsrc_modulation_type;
166 }
167
168 #define GST_TYPE_DVBSRC_TRANSMISSION_MODE (gst_dvbsrc_transmission_mode_get_type ())
169 static GType
170 gst_dvbsrc_transmission_mode_get_type (void)
171 {
172   static GType dvbsrc_transmission_mode_type = 0;
173   static GEnumValue transmission_mode_types[] = {
174     {TRANSMISSION_MODE_2K, "2K", "2k"},
175     {TRANSMISSION_MODE_8K, "8K", "8k"},
176     {TRANSMISSION_MODE_AUTO, "AUTO", "auto"},
177     {0, NULL, NULL},
178   };
179
180   if (!dvbsrc_transmission_mode_type) {
181     dvbsrc_transmission_mode_type =
182         g_enum_register_static ("GstDvbSrcTransmission_Mode",
183         transmission_mode_types);
184   }
185   return dvbsrc_transmission_mode_type;
186 }
187
188 #define GST_TYPE_DVBSRC_BANDWIDTH (gst_dvbsrc_bandwidth_get_type ())
189 static GType
190 gst_dvbsrc_bandwidth_get_type (void)
191 {
192   static GType dvbsrc_bandwidth_type = 0;
193   static GEnumValue bandwidth_types[] = {
194     {BANDWIDTH_8_MHZ, "8", "8"},
195     {BANDWIDTH_7_MHZ, "7", "7"},
196     {BANDWIDTH_6_MHZ, "6", "6"},
197     {BANDWIDTH_AUTO, "AUTO", "AUTO"},
198     {0, NULL, NULL},
199   };
200
201   if (!dvbsrc_bandwidth_type) {
202     dvbsrc_bandwidth_type =
203         g_enum_register_static ("GstDvbSrcBandwidth", bandwidth_types);
204   }
205   return dvbsrc_bandwidth_type;
206 }
207
208 #define GST_TYPE_DVBSRC_GUARD (gst_dvbsrc_guard_get_type ())
209 static GType
210 gst_dvbsrc_guard_get_type (void)
211 {
212   static GType dvbsrc_guard_type = 0;
213   static GEnumValue guard_types[] = {
214     {GUARD_INTERVAL_1_32, "32", "32"},
215     {GUARD_INTERVAL_1_16, "16", "16"},
216     {GUARD_INTERVAL_1_8, "8", "8"},
217     {GUARD_INTERVAL_1_4, "4", "4"},
218     {GUARD_INTERVAL_AUTO, "AUTO", "auto"},
219     {0, NULL, NULL},
220   };
221
222   if (!dvbsrc_guard_type) {
223     dvbsrc_guard_type = g_enum_register_static ("GstDvbSrcGuard", guard_types);
224   }
225   return dvbsrc_guard_type;
226 }
227
228 #define GST_TYPE_DVBSRC_HIERARCHY (gst_dvbsrc_hierarchy_get_type ())
229 static GType
230 gst_dvbsrc_hierarchy_get_type (void)
231 {
232   static GType dvbsrc_hierarchy_type = 0;
233   static GEnumValue hierarchy_types[] = {
234     {HIERARCHY_NONE, "NONE", "none"},
235     {HIERARCHY_1, "1", "1"},
236     {HIERARCHY_2, "2", "2"},
237     {HIERARCHY_4, "4", "4"},
238     {HIERARCHY_AUTO, "AUTO", "auto"},
239     {0, NULL, NULL},
240   };
241
242   if (!dvbsrc_hierarchy_type) {
243     dvbsrc_hierarchy_type =
244         g_enum_register_static ("GstDvbSrcHierarchy", hierarchy_types);
245   }
246   return dvbsrc_hierarchy_type;
247 }
248
249 #define GST_TYPE_DVBSRC_INVERSION (gst_dvbsrc_inversion_get_type ())
250 static GType
251 gst_dvbsrc_inversion_get_type (void)
252 {
253   static GType dvbsrc_inversion_type = 0;
254   static GEnumValue inversion_types[] = {
255     {INVERSION_OFF, "OFF", "off"},
256     {INVERSION_ON, "ON", "on"},
257     {INVERSION_AUTO, "AUTO", "auto"},
258     {0, NULL, NULL},
259   };
260
261   if (!dvbsrc_inversion_type) {
262     dvbsrc_inversion_type =
263         g_enum_register_static ("GstDvbSrcInversion", inversion_types);
264   }
265   return dvbsrc_inversion_type;
266 }
267
268 static void gst_dvbsrc_finalize (GObject * object);
269 static void gst_dvbsrc_set_property (GObject * object, guint prop_id,
270     const GValue * value, GParamSpec * pspec);
271 static void gst_dvbsrc_get_property (GObject * object, guint prop_id,
272     GValue * value, GParamSpec * pspec);
273
274 static GstFlowReturn gst_dvbsrc_create (GstPushSrc * element,
275     GstBuffer ** buffer);
276
277 static gboolean gst_dvbsrc_start (GstBaseSrc * bsrc);
278 static gboolean gst_dvbsrc_stop (GstBaseSrc * bsrc);
279 static GstStateChangeReturn gst_dvbsrc_change_state (GstElement * element,
280     GstStateChange transition);
281
282 static gboolean gst_dvbsrc_unlock (GstBaseSrc * bsrc);
283 static gboolean gst_dvbsrc_unlock_stop (GstBaseSrc * bsrc);
284 static gboolean gst_dvbsrc_is_seekable (GstBaseSrc * bsrc);
285 static gboolean gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size);
286
287 static gboolean gst_dvbsrc_tune (GstDvbSrc * object);
288 static void gst_dvbsrc_set_pes_filters (GstDvbSrc * object);
289 static void gst_dvbsrc_unset_pes_filters (GstDvbSrc * object);
290
291 static gboolean gst_dvbsrc_frontend_status (GstDvbSrc * object);
292
293 static GstStaticPadTemplate ts_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
294     GST_PAD_SRC,
295     GST_PAD_ALWAYS,
296     GST_STATIC_CAPS
297     ("video/mpegts, "
298         "mpegversion = (int) 2," "systemstream = (boolean) TRUE"));
299
300 /*
301  ******************************
302  *                            *
303  *      GObject Related       *
304  *                            *
305  *                            *
306  ******************************
307  */
308
309 #define gst_dvbsrc_parent_class parent_class
310 G_DEFINE_TYPE (GstDvbSrc, gst_dvbsrc, GST_TYPE_PUSH_SRC);
311
312 /* initialize the plugin's class */
313 static void
314 gst_dvbsrc_class_init (GstDvbSrcClass * klass)
315 {
316   GObjectClass *gobject_class;
317   GstElementClass *gstelement_class;
318   GstBaseSrcClass *gstbasesrc_class;
319   GstPushSrcClass *gstpushsrc_class;
320
321   gobject_class = (GObjectClass *) klass;
322   gstelement_class = (GstElementClass *) klass;
323   gstbasesrc_class = (GstBaseSrcClass *) klass;
324   gstpushsrc_class = (GstPushSrcClass *) klass;
325
326   gobject_class->set_property = gst_dvbsrc_set_property;
327   gobject_class->get_property = gst_dvbsrc_get_property;
328   gobject_class->finalize = gst_dvbsrc_finalize;
329
330   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_dvbsrc_change_state);
331
332   gst_element_class_add_pad_template (gstelement_class,
333       gst_static_pad_template_get (&ts_src_factory));
334
335   gst_element_class_set_details_simple (gstelement_class, "DVB Source",
336       "Source/Video",
337       "Digital Video Broadcast Source",
338       "P2P-VCR, C-Lab, University of Paderborn,"
339       "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
340
341   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dvbsrc_start);
342   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dvbsrc_stop);
343   gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_dvbsrc_unlock);
344   gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_dvbsrc_unlock_stop);
345   gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_dvbsrc_is_seekable);
346   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_dvbsrc_get_size);
347
348   gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_dvbsrc_create);
349
350   g_object_class_install_property (gobject_class, ARG_DVBSRC_ADAPTER,
351       g_param_spec_int ("adapter", "The adapter device number",
352           "The adapter device number (eg. 0 for adapter0)",
353           0, 16, DEFAULT_ADAPTER, G_PARAM_READWRITE));
354
355   g_object_class_install_property (gobject_class, ARG_DVBSRC_FRONTEND,
356       g_param_spec_int ("frontend", "The frontend device number",
357           "The frontend device number (eg. 0 for frontend0)",
358           0, 16, DEFAULT_FRONTEND, G_PARAM_READWRITE));
359
360   g_object_class_install_property (gobject_class, ARG_DVBSRC_FREQUENCY,
361       g_param_spec_uint ("frequency", "frequency", "Frequency",
362           0, G_MAXUINT, DEFAULT_FREQUENCY, G_PARAM_READWRITE));
363
364   g_object_class_install_property (gobject_class, ARG_DVBSRC_POLARITY,
365       g_param_spec_string ("polarity", "polarity", "Polarity [vhHV] (DVB-S)",
366           DEFAULT_POLARITY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
367
368   g_object_class_install_property (gobject_class, ARG_DVBSRC_PIDS,
369       g_param_spec_string ("pids", "pids",
370           "Colon seperated list of pids (eg. 110:120)",
371           DEFAULT_PIDS, G_PARAM_WRITABLE));
372
373   g_object_class_install_property (gobject_class, ARG_DVBSRC_SYM_RATE,
374       g_param_spec_uint ("symbol-rate",
375           "symbol rate",
376           "Symbol Rate (DVB-S, DVB-C)",
377           0, G_MAXUINT, DEFAULT_SYMBOL_RATE, G_PARAM_READWRITE));
378
379   g_object_class_install_property (gobject_class, ARG_DVBSRC_TUNE,
380       g_param_spec_pointer ("tune",
381           "tune", "Atomically tune to channel. (For Apps)", G_PARAM_WRITABLE));
382
383   g_object_class_install_property (gobject_class, ARG_DVBSRC_DISEQC_SRC,
384       g_param_spec_int ("diseqc-source",
385           "diseqc source",
386           "DISEqC selected source (-1 disabled) (DVB-S)",
387           -1, 7, DEFAULT_DISEQC_SRC, G_PARAM_READWRITE));
388
389   /* DVB-T, additional properties */
390
391   g_object_class_install_property (gobject_class, ARG_DVBSRC_BANDWIDTH,
392       g_param_spec_enum ("bandwidth",
393           "bandwidth",
394           "Bandwidth (DVB-T)", GST_TYPE_DVBSRC_BANDWIDTH, DEFAULT_BANDWIDTH,
395           G_PARAM_READWRITE));
396
397   g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_HP,
398       g_param_spec_enum ("code-rate-hp",
399           "code-rate-hp",
400           "High Priority Code Rate (DVB-T, DVB-S and DVB-C)",
401           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_CODE_RATE_HP, G_PARAM_READWRITE));
402
403   g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_LP,
404       g_param_spec_enum ("code-rate-lp",
405           "code-rate-lp",
406           "Low Priority Code Rate (DVB-T)",
407           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_CODE_RATE_LP, G_PARAM_READWRITE));
408
409   /* FIXME: should the property be called 'guard-interval' then? */
410   g_object_class_install_property (gobject_class, ARG_DVBSRC_GUARD,
411       g_param_spec_enum ("guard",
412           "guard",
413           "Guard Interval (DVB-T)",
414           GST_TYPE_DVBSRC_GUARD, DEFAULT_GUARD, G_PARAM_READWRITE));
415
416   g_object_class_install_property (gobject_class, ARG_DVBSRC_MODULATION,
417       g_param_spec_enum ("modulation", "modulation",
418           "Modulation (DVB-T and DVB-C)",
419           GST_TYPE_DVBSRC_MODULATION, DEFAULT_MODULATION, G_PARAM_READWRITE));
420
421   /* FIXME: property should be named 'transmission-mode' */
422   g_object_class_install_property (gobject_class,
423       ARG_DVBSRC_TRANSMISSION_MODE,
424       g_param_spec_enum ("trans-mode", "trans-mode",
425           "Transmission Mode (DVB-T)", GST_TYPE_DVBSRC_TRANSMISSION_MODE,
426           DEFAULT_TRANSMISSION_MODE, G_PARAM_READWRITE));
427
428   g_object_class_install_property (gobject_class, ARG_DVBSRC_HIERARCHY_INF,
429       g_param_spec_enum ("hierarchy", "hierarchy",
430           "Hierarchy Information (DVB-T)",
431           GST_TYPE_DVBSRC_HIERARCHY, DEFAULT_HIERARCHY, G_PARAM_READWRITE));
432
433   g_object_class_install_property (gobject_class, ARG_DVBSRC_INVERSION,
434       g_param_spec_enum ("inversion", "inversion",
435           "Inversion Information (DVB-T and DVB-C)",
436           GST_TYPE_DVBSRC_INVERSION, DEFAULT_INVERSION, G_PARAM_READWRITE));
437
438   g_object_class_install_property (gobject_class,
439       ARG_DVBSRC_STATS_REPORTING_INTERVAL,
440       g_param_spec_uint ("stats-reporting-interval",
441           "stats-reporting-interval",
442           "The number of reads before reporting frontend stats",
443           0, G_MAXUINT, DEFAULT_STATS_REPORTING_INTERVAL, G_PARAM_READWRITE));
444
445   g_object_class_install_property (gobject_class, ARG_DVBSRC_TIMEOUT,
446       g_param_spec_uint64 ("timeout", "Timeout",
447           "Post a message after timeout microseconds (0 = disabled)", 0,
448           G_MAXUINT64, DEFAULT_TIMEOUT, G_PARAM_READWRITE));
449 }
450
451 /* initialize the new element
452  * instantiate pads and add them to element
453  * set functions
454  * initialize structure
455  */
456 static void
457 gst_dvbsrc_init (GstDvbSrc * object)
458 {
459   int i = 0;
460
461   GST_INFO_OBJECT (object, "gst_dvbsrc_init");
462
463   /* We are a live source */
464   gst_base_src_set_live (GST_BASE_SRC (object), TRUE);
465   /* And we wanted timestamped output */
466   gst_base_src_set_do_timestamp (GST_BASE_SRC (object), TRUE);
467
468   object->fd_frontend = -1;
469   object->fd_dvr = -1;
470
471   for (i = 0; i < MAX_FILTERS; i++) {
472     object->pids[i] = G_MAXUINT16;
473     object->fd_filters[i] = -1;
474   }
475   /* Pid 8192 on DVB gets the whole transport stream */
476   object->pids[0] = 8192;
477
478   object->adapter_number = DEFAULT_ADAPTER;
479   object->frontend_number = DEFAULT_FRONTEND;
480   object->diseqc_src = DEFAULT_DISEQC_SRC;
481   object->send_diseqc = (DEFAULT_DISEQC_SRC != -1);
482   /* object->pol = DVB_POL_H; *//* set via G_PARAM_CONSTRUCT */
483   object->sym_rate = DEFAULT_SYMBOL_RATE;
484   object->bandwidth = DEFAULT_BANDWIDTH;
485   object->code_rate_hp = DEFAULT_CODE_RATE_HP;
486   object->code_rate_lp = DEFAULT_CODE_RATE_LP;
487   object->guard_interval = DEFAULT_GUARD;
488   object->modulation = DEFAULT_MODULATION;
489   object->transmission_mode = DEFAULT_TRANSMISSION_MODE;
490   object->hierarchy_information = DEFAULT_HIERARCHY;
491   object->inversion = DEFAULT_INVERSION;
492   object->stats_interval = DEFAULT_STATS_REPORTING_INTERVAL;
493
494   g_mutex_init (&object->tune_mutex);
495   object->timeout = DEFAULT_TIMEOUT;
496 }
497
498
499 static void
500 gst_dvbsrc_set_property (GObject * _object, guint prop_id,
501     const GValue * value, GParamSpec * pspec)
502 {
503   GstDvbSrc *object;
504
505   g_return_if_fail (GST_IS_DVBSRC (_object));
506   object = GST_DVBSRC (_object);
507
508   switch (prop_id) {
509     case ARG_DVBSRC_ADAPTER:
510       object->adapter_number = g_value_get_int (value);
511       break;
512     case ARG_DVBSRC_FRONTEND:
513       object->frontend_number = g_value_get_int (value);
514       break;
515     case ARG_DVBSRC_DISEQC_SRC:
516       if (object->diseqc_src != g_value_get_int (value)) {
517         object->diseqc_src = g_value_get_int (value);
518         object->send_diseqc = TRUE;
519       }
520       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_DISEQC_ID");
521       break;
522     case ARG_DVBSRC_FREQUENCY:
523       object->freq = g_value_get_uint (value);
524       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_FREQUENCY (%d Hz)",
525           object->freq);
526       break;
527     case ARG_DVBSRC_POLARITY:
528     {
529       const char *s = NULL;
530
531       s = g_value_get_string (value);
532       if (s != NULL) {
533         object->pol = (s[0] == 'h' || s[0] == 'H') ? DVB_POL_H : DVB_POL_V;
534         GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_POLARITY");
535         GST_INFO_OBJECT (object, "\t%s", (s[0] == 'h'
536                 || s[0] == 'H') ? "DVB_POL_H" : "DVB_POL_V");
537       }
538       break;
539     }
540     case ARG_DVBSRC_PIDS:
541     {
542       gchar *pid_string;
543
544       pid_string = g_value_dup_string (value);
545       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_PIDS %s", pid_string);
546       if (!strcmp (pid_string, "8192")) {
547         /* get the whole ts */
548         int pid_count = 1;
549         object->pids[0] = 8192;
550         while (pid_count < MAX_FILTERS) {
551           object->pids[pid_count++] = G_MAXUINT16;
552         }
553       } else {
554         int pid = 0;
555         int pid_count;
556         gchar **pids;
557         char **tmp;
558
559         tmp = pids = g_strsplit (pid_string, ":", MAX_FILTERS);
560         if (pid_string)
561           g_free (pid_string);
562
563         /* always add the PAT and CAT pids */
564         object->pids[0] = 0;
565         object->pids[1] = 1;
566
567         pid_count = 2;
568         while (*pids != NULL && pid_count < MAX_FILTERS) {
569           pid = strtol (*pids, NULL, 0);
570           if (pid > 1 && pid <= 8192) {
571             GST_INFO_OBJECT (object, "\tParsed Pid: %d", pid);
572             object->pids[pid_count] = pid;
573             pid_count++;
574           }
575           pids++;
576         }
577         while (pid_count < MAX_FILTERS) {
578           object->pids[pid_count++] = G_MAXUINT16;
579         }
580
581         g_strfreev (tmp);
582       }
583       /* if we are in playing or paused, then set filters now */
584       GST_INFO_OBJECT (object, "checking if playing for setting pes filters");
585       if (GST_ELEMENT (object)->current_state == GST_STATE_PLAYING ||
586           GST_ELEMENT (object)->current_state == GST_STATE_PAUSED) {
587         GST_INFO_OBJECT (object, "Setting pes filters now");
588         gst_dvbsrc_set_pes_filters (object);
589       }
590     }
591       break;
592     case ARG_DVBSRC_SYM_RATE:
593       object->sym_rate = g_value_get_uint (value);
594       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_SYM_RATE to value %d",
595           object->sym_rate);
596       break;
597
598     case ARG_DVBSRC_BANDWIDTH:
599       object->bandwidth = g_value_get_enum (value);
600       break;
601     case ARG_DVBSRC_CODE_RATE_HP:
602       object->code_rate_hp = g_value_get_enum (value);
603       break;
604     case ARG_DVBSRC_CODE_RATE_LP:
605       object->code_rate_lp = g_value_get_enum (value);
606       break;
607     case ARG_DVBSRC_GUARD:
608       object->guard_interval = g_value_get_enum (value);
609       break;
610     case ARG_DVBSRC_MODULATION:
611       object->modulation = g_value_get_enum (value);
612       break;
613     case ARG_DVBSRC_TRANSMISSION_MODE:
614       object->transmission_mode = g_value_get_enum (value);
615       break;
616     case ARG_DVBSRC_HIERARCHY_INF:
617       object->hierarchy_information = g_value_get_enum (value);
618       break;
619     case ARG_DVBSRC_INVERSION:
620       object->inversion = g_value_get_enum (value);
621       break;
622     case ARG_DVBSRC_TUNE:{
623       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_TUNE");
624
625       /* if we are in paused/playing state tune now, otherwise in ready to paused state change */
626       if (GST_STATE (object) > GST_STATE_READY) {
627         g_mutex_lock (&object->tune_mutex);
628         gst_dvbsrc_tune (object);
629         g_mutex_unlock (&object->tune_mutex);
630       }
631       break;
632     }
633     case ARG_DVBSRC_STATS_REPORTING_INTERVAL:
634       object->stats_interval = g_value_get_uint (value);
635       object->stats_counter = 0;
636       break;
637     case ARG_DVBSRC_TIMEOUT:
638       object->timeout = g_value_get_uint64 (value);
639       break;
640     default:
641       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
642   }
643 }
644
645 static void
646 gst_dvbsrc_get_property (GObject * _object, guint prop_id,
647     GValue * value, GParamSpec * pspec)
648 {
649   GstDvbSrc *object;
650
651   g_return_if_fail (GST_IS_DVBSRC (_object));
652   object = GST_DVBSRC (_object);
653
654   switch (prop_id) {
655     case ARG_DVBSRC_ADAPTER:
656       g_value_set_int (value, object->adapter_number);
657       break;
658     case ARG_DVBSRC_FRONTEND:
659       g_value_set_int (value, object->frontend_number);
660       break;
661     case ARG_DVBSRC_FREQUENCY:
662       g_value_set_uint (value, object->freq);
663       break;
664     case ARG_DVBSRC_POLARITY:
665       if (object->pol == DVB_POL_H)
666         g_value_set_static_string (value, "H");
667       else
668         g_value_set_static_string (value, "V");
669       break;
670     case ARG_DVBSRC_SYM_RATE:
671       g_value_set_uint (value, object->sym_rate);
672       break;
673     case ARG_DVBSRC_DISEQC_SRC:
674       g_value_set_int (value, object->diseqc_src);
675       break;
676     case ARG_DVBSRC_BANDWIDTH:
677       g_value_set_enum (value, object->bandwidth);
678       break;
679     case ARG_DVBSRC_CODE_RATE_HP:
680       g_value_set_enum (value, object->code_rate_hp);
681       break;
682     case ARG_DVBSRC_CODE_RATE_LP:
683       g_value_set_enum (value, object->code_rate_lp);
684       break;
685     case ARG_DVBSRC_GUARD:
686       g_value_set_enum (value, object->guard_interval);
687       break;
688     case ARG_DVBSRC_MODULATION:
689       g_value_set_enum (value, object->modulation);
690       break;
691     case ARG_DVBSRC_TRANSMISSION_MODE:
692       g_value_set_enum (value, object->transmission_mode);
693       break;
694     case ARG_DVBSRC_HIERARCHY_INF:
695       g_value_set_enum (value, object->hierarchy_information);
696       break;
697     case ARG_DVBSRC_INVERSION:
698       g_value_set_enum (value, object->inversion);
699       break;
700     case ARG_DVBSRC_STATS_REPORTING_INTERVAL:
701       g_value_set_uint (value, object->stats_interval);
702       break;
703     case ARG_DVBSRC_TIMEOUT:
704       g_value_set_uint64 (value, object->timeout);
705       break;
706     default:
707       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
708   }
709 }
710
711 static gboolean
712 gst_dvbsrc_close_devices (GstDvbSrc * object)
713 {
714   gst_dvbsrc_unset_pes_filters (object);
715
716   close (object->fd_dvr);
717   object->fd_dvr = -1;
718   close (object->fd_frontend);
719   object->fd_frontend = -1;
720
721   return TRUE;
722 }
723
724 static gboolean
725 gst_dvbsrc_open_frontend (GstDvbSrc * object, gboolean writable)
726 {
727   struct dvb_frontend_info fe_info;
728   const char *adapter_desc = NULL;
729   gchar *frontend_dev;
730   GstStructure *adapter_structure;
731   char *adapter_name = NULL;
732
733   frontend_dev = g_strdup_printf ("/dev/dvb/adapter%d/frontend%d",
734       object->adapter_number, object->frontend_number);
735   GST_INFO_OBJECT (object, "Using frontend device: %s", frontend_dev);
736
737   /* open frontend */
738   if ((object->fd_frontend =
739           open (frontend_dev, writable ? O_RDWR : O_RDONLY)) < 0) {
740     switch (errno) {
741       case ENOENT:
742         GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
743             (_("Device \"%s\" does not exist."), frontend_dev), (NULL));
744         break;
745       default:
746         GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ_WRITE,
747             (_("Could not open frontend device \"%s\"."), frontend_dev),
748             GST_ERROR_SYSTEM);
749         break;
750     }
751
752     close (object->fd_frontend);
753     g_free (frontend_dev);
754     return FALSE;
755   }
756
757   GST_DEBUG_OBJECT (object, "Device opened, querying information");
758
759   if (ioctl (object->fd_frontend, FE_GET_INFO, &fe_info) < 0) {
760     GST_ELEMENT_ERROR (object, RESOURCE, SETTINGS,
761         (_("Could not get settings from frontend device \"%s\"."),
762             frontend_dev), GST_ERROR_SYSTEM);
763
764     close (object->fd_frontend);
765     g_free (frontend_dev);
766     return FALSE;
767   }
768
769   GST_DEBUG_OBJECT (object, "Got information about adapter : %s", fe_info.name);
770
771   adapter_name = g_strdup (fe_info.name);
772
773   object->adapter_type = fe_info.type;
774   switch (object->adapter_type) {
775     case FE_QPSK:
776       adapter_desc = "DVB-S";
777       adapter_structure = gst_structure_new ("dvb-adapter",
778           "type", G_TYPE_STRING, adapter_desc,
779           "name", G_TYPE_STRING, adapter_name,
780           "auto-fec", G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_FEC_AUTO, NULL);
781       break;
782     case FE_QAM:
783       adapter_desc = "DVB-C";
784       adapter_structure = gst_structure_new ("dvb-adapter",
785           "type", G_TYPE_STRING, adapter_desc,
786           "name", G_TYPE_STRING, adapter_name,
787           "auto-inversion", G_TYPE_BOOLEAN,
788           fe_info.caps & FE_CAN_INVERSION_AUTO, "auto-qam", G_TYPE_BOOLEAN,
789           fe_info.caps & FE_CAN_QAM_AUTO, "auto-fec", G_TYPE_BOOLEAN,
790           fe_info.caps & FE_CAN_FEC_AUTO, NULL);
791       break;
792     case FE_OFDM:
793       adapter_desc = "DVB-T";
794       adapter_structure = gst_structure_new ("dvb-adapter",
795           "type", G_TYPE_STRING, adapter_desc,
796           "name", G_TYPE_STRING, adapter_name,
797           "auto-inversion", G_TYPE_BOOLEAN,
798           fe_info.caps & FE_CAN_INVERSION_AUTO, "auto-qam", G_TYPE_BOOLEAN,
799           fe_info.caps & FE_CAN_QAM_AUTO, "auto-transmission-mode",
800           G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_TRANSMISSION_MODE_AUTO,
801           "auto-guard-interval", G_TYPE_BOOLEAN,
802           fe_info.caps & FE_CAN_GUARD_INTERVAL_AUTO, "auto-hierarchy",
803           G_TYPE_BOOLEAN, fe_info.caps % FE_CAN_HIERARCHY_AUTO, "auto-fec",
804           G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_FEC_AUTO, NULL);
805       break;
806     case FE_ATSC:
807       adapter_desc = "ATSC";
808       adapter_structure = gst_structure_new ("dvb-adapter",
809           "type", G_TYPE_STRING, adapter_desc,
810           "name", G_TYPE_STRING, adapter_name, NULL);
811       break;
812     default:
813       g_error ("Unknown frontend type: %d", object->adapter_type);
814       adapter_structure = gst_structure_new ("dvb-adapter",
815           "type", G_TYPE_STRING, "unknown", NULL);
816   }
817
818   GST_INFO_OBJECT (object, "DVB card: %s ", adapter_name);
819   gst_element_post_message (GST_ELEMENT_CAST (object), gst_message_new_element
820       (GST_OBJECT (object), adapter_structure));
821   g_free (frontend_dev);
822   g_free (adapter_name);
823   return TRUE;
824 }
825
826 static gboolean
827 gst_dvbsrc_open_dvr (GstDvbSrc * object)
828 {
829   gchar *dvr_dev;
830
831   dvr_dev = g_strdup_printf ("/dev/dvb/adapter%d/dvr%d",
832       object->adapter_number, object->frontend_number);
833   GST_INFO_OBJECT (object, "Using dvr device: %s", dvr_dev);
834
835   /* open DVR */
836   if ((object->fd_dvr = open (dvr_dev, O_RDONLY | O_NONBLOCK)) < 0) {
837     switch (errno) {
838       case ENOENT:
839         GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
840             (_("Device \"%s\" does not exist."), dvr_dev), (NULL));
841         break;
842       default:
843         GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ,
844             (_("Could not open file \"%s\" for reading."), dvr_dev),
845             GST_ERROR_SYSTEM);
846         break;
847     }
848     g_free (dvr_dev);
849     return FALSE;
850   }
851   g_free (dvr_dev);
852   GST_INFO_OBJECT (object, "Setting buffer size");
853   if (ioctl (object->fd_dvr, DMX_SET_BUFFER_SIZE, 1024 * 1024) < 0) {
854     GST_INFO_OBJECT (object, "DMX_SET_BUFFER_SIZE failed");
855     return FALSE;
856   }
857   return TRUE;
858 }
859
860 static void
861 gst_dvbsrc_finalize (GObject * _object)
862 {
863   GstDvbSrc *object;
864
865   GST_DEBUG_OBJECT (_object, "gst_dvbsrc_finalize");
866
867   g_return_if_fail (GST_IS_DVBSRC (_object));
868   object = GST_DVBSRC (_object);
869
870   /* freeing the mutex segfaults somehow */
871   g_mutex_clear (&object->tune_mutex);
872
873   if (G_OBJECT_CLASS (parent_class)->finalize)
874     G_OBJECT_CLASS (parent_class)->finalize (_object);
875 }
876
877
878 /*
879  ******************************
880  *                            *
881  *      Plugin Realisation    *
882  *                            *
883  ******************************
884  */
885
886
887
888 /* entry point to initialize the plug-in
889  * initialize the plug-in itself
890  * register the element factories and pad templates
891  * register the features
892  */
893 gboolean
894 gst_dvbsrc_plugin_init (GstPlugin * plugin)
895 {
896   GST_DEBUG_CATEGORY_INIT (gstdvbsrc_debug, "dvbsrc", 0, "DVB Source Element");
897
898 #ifdef ENABLE_NLS
899   GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
900       LOCALEDIR);
901   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
902   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
903 #endif /* ENABLE_NLS */
904
905   return gst_element_register (plugin, "dvbsrc", GST_RANK_NONE,
906       GST_TYPE_DVBSRC);
907 }
908
909 static GstFlowReturn
910 gst_dvbsrc_read_device (GstDvbSrc * object, int size, GstBuffer ** buffer)
911 {
912   gint count = 0;
913   gint ret_val = 0;
914   GstBuffer *buf = gst_buffer_new_and_alloc (size);
915   GstClockTime timeout = object->timeout * GST_USECOND;
916   GstMapInfo map;
917
918   g_return_val_if_fail (GST_IS_BUFFER (buf), GST_FLOW_ERROR);
919
920   if (object->fd_dvr < 0)
921     return GST_FLOW_ERROR;
922
923   gst_buffer_map (buf, &map, GST_MAP_WRITE);
924   while (count < size) {
925     ret_val = gst_poll_wait (object->poll, timeout);
926     GST_LOG_OBJECT (object, "select returned %d", ret_val);
927     if (G_UNLIKELY (ret_val < 0)) {
928       if (errno == EBUSY)
929         goto stopped;
930       else
931         goto select_error;
932     } else if (G_UNLIKELY (ret_val == 0)) {
933       /* timeout, post element message */
934       gst_element_post_message (GST_ELEMENT_CAST (object),
935           gst_message_new_element (GST_OBJECT (object),
936               gst_structure_new_empty ("dvb-read-failure")));
937     } else {
938       int nread = read (object->fd_dvr, map.data + count, size - count);
939
940       if (G_UNLIKELY (nread < 0)) {
941         GST_WARNING_OBJECT
942             (object,
943             "Unable to read from device: /dev/dvb/adapter%d/dvr%d (%d)",
944             object->adapter_number, object->frontend_number, errno);
945         gst_element_post_message (GST_ELEMENT_CAST (object),
946             gst_message_new_element (GST_OBJECT (object),
947                 gst_structure_new_empty ("dvb-read-failure")));
948       } else
949         count = count + nread;
950     }
951   }
952   gst_buffer_unmap (buf, &map);
953   gst_buffer_resize (buf, 0, count);
954
955   *buffer = buf;
956
957   return GST_FLOW_OK;
958
959 stopped:
960   {
961     GST_DEBUG_OBJECT (object, "stop called");
962     gst_buffer_unmap (buf, &map);
963     gst_buffer_unref (buf);
964     return GST_FLOW_FLUSHING;
965   }
966 select_error:
967   {
968     GST_ELEMENT_ERROR (object, RESOURCE, READ, (NULL),
969         ("select error %d: %s (%d)", ret_val, g_strerror (errno), errno));
970     gst_buffer_unmap (buf, &map);
971     gst_buffer_unref (buf);
972     return GST_FLOW_ERROR;
973   }
974 }
975
976 static GstFlowReturn
977 gst_dvbsrc_create (GstPushSrc * element, GstBuffer ** buf)
978 {
979   gint buffer_size;
980   GstFlowReturn retval = GST_FLOW_ERROR;
981   GstDvbSrc *object;
982
983   object = GST_DVBSRC (element);
984   GST_LOG ("fd_dvr: %d", object->fd_dvr);
985
986   //g_object_get(G_OBJECT(object), "blocksize", &buffer_size, NULL);
987   buffer_size = DEFAULT_BUFFER_SIZE;
988
989   /* device can not be tuned during read */
990   g_mutex_lock (&object->tune_mutex);
991
992
993   if (object->fd_dvr > -1) {
994     /* --- Read TS from DVR device --- */
995     GST_DEBUG_OBJECT (object, "Reading from DVR device");
996     retval = gst_dvbsrc_read_device (object, buffer_size, buf);
997
998     if (object->stats_interval != 0 &&
999         ++object->stats_counter == object->stats_interval) {
1000       gst_dvbsrc_output_frontend_stats (object);
1001       object->stats_counter = 0;
1002     }
1003   }
1004
1005   g_mutex_unlock (&object->tune_mutex);
1006   return retval;
1007
1008 }
1009
1010 static GstStateChangeReturn
1011 gst_dvbsrc_change_state (GstElement * element, GstStateChange transition)
1012 {
1013   GstDvbSrc *src;
1014   GstStateChangeReturn ret;
1015
1016   src = GST_DVBSRC (element);
1017   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1018
1019   switch (transition) {
1020     case GST_STATE_CHANGE_NULL_TO_READY:
1021       /* open frontend then close it again, just so caps sent */
1022       gst_dvbsrc_open_frontend (src, FALSE);
1023       if (src->fd_frontend) {
1024         close (src->fd_frontend);
1025       }
1026       break;
1027     default:
1028       break;
1029   }
1030
1031   return ret;
1032 }
1033
1034
1035 static gboolean
1036 gst_dvbsrc_start (GstBaseSrc * bsrc)
1037 {
1038   GstDvbSrc *src = GST_DVBSRC (bsrc);
1039
1040   gst_dvbsrc_open_frontend (src, TRUE);
1041   if (!gst_dvbsrc_tune (src)) {
1042     GST_ERROR_OBJECT (src, "Not able to lock on to the dvb channel");
1043     close (src->fd_frontend);
1044     return FALSE;
1045   }
1046   if (!gst_dvbsrc_frontend_status (src)) {
1047     /* unset filters also */
1048     gst_dvbsrc_unset_pes_filters (src);
1049     close (src->fd_frontend);
1050     return FALSE;
1051   }
1052   if (!gst_dvbsrc_open_dvr (src)) {
1053     GST_ERROR_OBJECT (src, "Not able to open dvr_device");
1054     /* unset filters also */
1055     gst_dvbsrc_unset_pes_filters (src);
1056     close (src->fd_frontend);
1057     return FALSE;
1058   }
1059   if (!(src->poll = gst_poll_new (TRUE))) {
1060     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
1061         ("could not create an fdset: %s (%d)", g_strerror (errno), errno));
1062     /* unset filters also */
1063     gst_dvbsrc_unset_pes_filters (src);
1064     close (src->fd_frontend);
1065     return FALSE;
1066   } else {
1067     gst_poll_fd_init (&src->poll_fd_dvr);
1068     src->poll_fd_dvr.fd = src->fd_dvr;
1069     gst_poll_add_fd (src->poll, &src->poll_fd_dvr);
1070     gst_poll_fd_ctl_read (src->poll, &src->poll_fd_dvr, TRUE);
1071   }
1072
1073   return TRUE;
1074 }
1075
1076 static gboolean
1077 gst_dvbsrc_stop (GstBaseSrc * bsrc)
1078 {
1079   GstDvbSrc *src = GST_DVBSRC (bsrc);
1080
1081   gst_dvbsrc_close_devices (src);
1082   if (src->poll) {
1083     gst_poll_free (src->poll);
1084     src->poll = NULL;
1085   }
1086
1087   return TRUE;
1088 }
1089
1090 static gboolean
1091 gst_dvbsrc_unlock (GstBaseSrc * bsrc)
1092 {
1093   GstDvbSrc *src = GST_DVBSRC (bsrc);
1094
1095   gst_poll_set_flushing (src->poll, TRUE);
1096   return TRUE;
1097 }
1098
1099 static gboolean
1100 gst_dvbsrc_unlock_stop (GstBaseSrc * bsrc)
1101 {
1102   GstDvbSrc *src = GST_DVBSRC (bsrc);
1103
1104   gst_poll_set_flushing (src->poll, FALSE);
1105   return TRUE;
1106 }
1107
1108 static gboolean
1109 gst_dvbsrc_is_seekable (GstBaseSrc * bsrc)
1110 {
1111   return FALSE;
1112 }
1113
1114 static gboolean
1115 gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size)
1116 {
1117   return FALSE;
1118 }
1119
1120 static void
1121 gst_dvbsrc_output_frontend_stats (GstDvbSrc * src)
1122 {
1123   fe_status_t status;
1124   uint16_t snr, _signal;
1125   uint32_t ber, uncorrected_blocks;
1126   GstMessage *message;
1127   GstStructure *structure;
1128   int fe_fd = src->fd_frontend;
1129
1130   ioctl (fe_fd, FE_READ_STATUS, &status);
1131   ioctl (fe_fd, FE_READ_SIGNAL_STRENGTH, &_signal);
1132   ioctl (fe_fd, FE_READ_SNR, &snr);
1133   ioctl (fe_fd, FE_READ_BER, &ber);
1134   ioctl (fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
1135
1136   structure = gst_structure_new ("dvb-frontend-stats", "status", G_TYPE_INT,
1137       status, "signal", G_TYPE_INT, _signal, "snr", G_TYPE_INT, snr,
1138       "ber", G_TYPE_INT, ber, "unc", G_TYPE_INT, uncorrected_blocks,
1139       "lock", G_TYPE_BOOLEAN, status & FE_HAS_LOCK, NULL);
1140   message = gst_message_new_element (GST_OBJECT (src), structure);
1141   gst_element_post_message (GST_ELEMENT (src), message);
1142 }
1143
1144 static gboolean
1145 gst_dvbsrc_frontend_status (GstDvbSrc * object)
1146 {
1147   fe_status_t status = 0;
1148   gint i;
1149
1150   GST_INFO_OBJECT (object, "gst_dvbsrc_frontend_status");
1151
1152   if (object->fd_frontend < 0) {
1153     GST_ERROR_OBJECT (object,
1154         "Trying to get frontend status from not opened device!");
1155     return FALSE;
1156   } else
1157     GST_INFO_OBJECT (object, "fd-frontend: %d", object->fd_frontend);
1158
1159   for (i = 0; i < 15; i++) {
1160     usleep (1000000);
1161     GST_INFO_OBJECT (object, ".");
1162     if (ioctl (object->fd_frontend, FE_READ_STATUS, &status) == -1) {
1163       GST_ERROR_OBJECT (object, "Failed reading frontend status.");
1164       return FALSE;
1165     }
1166     gst_dvbsrc_output_frontend_stats (object);
1167     if (status & FE_HAS_LOCK) {
1168       break;
1169     }
1170   }
1171
1172   if (!(status & FE_HAS_LOCK)) {
1173     GST_INFO_OBJECT (object,
1174         "Not able to lock to the signal on the given frequency.");
1175     return FALSE;
1176   } else
1177     return TRUE;
1178 }
1179
1180 struct diseqc_cmd
1181 {
1182   struct dvb_diseqc_master_cmd cmd;
1183   uint32_t wait;
1184 };
1185
1186 static void
1187 diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
1188     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
1189 {
1190   if (ioctl (fd, FE_SET_TONE, SEC_TONE_OFF) == -1) {
1191     GST_ERROR ("Setting tone to off failed");
1192     return;
1193   }
1194
1195   if (ioctl (fd, FE_SET_VOLTAGE, v) == -1) {
1196     GST_ERROR ("Setting voltage failed");
1197     return;
1198   }
1199
1200   usleep (15 * 1000);
1201   GST_LOG ("diseqc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", cmd->cmd.msg[0],
1202       cmd->cmd.msg[1], cmd->cmd.msg[2], cmd->cmd.msg[3], cmd->cmd.msg[4],
1203       cmd->cmd.msg[5]);
1204   if (ioctl (fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1) {
1205     GST_ERROR ("Sending diseqc command failed");
1206     return;
1207   }
1208
1209   usleep (cmd->wait * 1000);
1210   usleep (15 * 1000);
1211
1212   if (ioctl (fd, FE_DISEQC_SEND_BURST, b) == -1) {
1213     GST_ERROR ("Sending burst failed");
1214     return;
1215   }
1216
1217   usleep (15 * 1000);
1218
1219   if (ioctl (fd, FE_SET_TONE, t) == -1) {
1220     GST_ERROR ("Setting tone failed");
1221     return;
1222   }
1223 }
1224
1225
1226 /* digital satellite equipment control,
1227  * specification is available from http://www.eutelsat.com/
1228  */
1229 static void
1230 diseqc (int secfd, int sat_no, int voltage, int tone)
1231 {
1232   struct diseqc_cmd cmd = { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
1233
1234   /* param: high nibble: reset bits, low nibble set bits,
1235    * bits are: option, position, polarizaion, band
1236    */
1237   cmd.cmd.msg[3] =
1238       0xf0 | (((sat_no * 4) & 0x0f) | (tone == SEC_TONE_ON ? 1 : 0) |
1239       (voltage == SEC_VOLTAGE_13 ? 0 : 2));
1240   /* send twice because some diseqc switches do not respond correctly the
1241    * first time */
1242   diseqc_send_msg (secfd, voltage, &cmd, tone,
1243       sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
1244   diseqc_send_msg (secfd, voltage, &cmd, tone,
1245       sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
1246
1247 }
1248
1249
1250 static gboolean
1251 gst_dvbsrc_tune (GstDvbSrc * object)
1252 {
1253 #if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1254   struct dvbfe_params feparams;
1255 #else
1256   struct dvb_frontend_parameters feparams;
1257 #endif
1258   fe_sec_voltage_t voltage;
1259   fe_status_t status;
1260   int i;
1261   int j;
1262   unsigned int freq = object->freq;
1263   unsigned int sym_rate = object->sym_rate * 1000;
1264
1265   /* found in mail archive on linuxtv.org
1266    * What works well for us is:
1267    * - first establish a TS feed (i.e. tune the frontend and check for success)
1268    * - then set filters (PES/sections)
1269    * - then tell the MPEG decoder to start
1270    * - before tuning: first stop the MPEG decoder, then stop all filters  
1271    */
1272   GST_INFO_OBJECT (object, "gst_dvbsrc_tune");
1273
1274   if (object->fd_frontend < 0) {
1275     /* frontend not opened yet, tune later */
1276     GST_INFO_OBJECT (object, "Frontend not open: tuning later");
1277     return FALSE;
1278   }
1279
1280   gst_dvbsrc_unset_pes_filters (object);
1281   for (j = 0; j < 5; j++) {
1282     switch (object->adapter_type) {
1283       case FE_QPSK:
1284         object->tone = SEC_TONE_OFF;
1285         if (freq > 2200000) {
1286           // this must be an absolute frequency
1287           if (freq < SLOF) {
1288             feparams.frequency = (freq - LOF1);
1289           } else {
1290             feparams.frequency = (freq - LOF2);
1291             object->tone = SEC_TONE_ON;
1292           }
1293         } else {
1294           // this is an L-Band frequency
1295           feparams.frequency = freq;
1296         }
1297         feparams.inversion = INVERSION_AUTO;
1298         GST_DEBUG_OBJECT (object, "api version %d.%d", DVB_API_VERSION,
1299             DVB_API_VERSION_MINOR);
1300 #if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1301         GST_DEBUG_OBJECT (object, "using multiproto driver");
1302         feparams.delsys.dvbs.symbol_rate = sym_rate;
1303         feparams.delsys.dvbs.fec = object->code_rate_hp;
1304 #else
1305         feparams.u.qpsk.symbol_rate = sym_rate;
1306         feparams.u.qpsk.fec_inner = object->code_rate_hp;
1307 #endif
1308         GST_INFO_OBJECT (object,
1309             "tuning DVB-S to L-Band:%u, Pol:%d, srate=%u, 22kHz=%s",
1310             feparams.frequency, object->pol, sym_rate,
1311             object->tone == SEC_TONE_ON ? "on" : "off");
1312
1313         if (object->pol == DVB_POL_H)
1314           voltage = SEC_VOLTAGE_18;
1315         else
1316           voltage = SEC_VOLTAGE_13;
1317
1318         if (object->diseqc_src == -1 || object->send_diseqc == FALSE) {
1319           if (ioctl (object->fd_frontend, FE_SET_VOLTAGE, voltage) < 0) {
1320             g_warning ("Unable to set voltage on dvb frontend device");
1321           }
1322
1323           if (ioctl (object->fd_frontend, FE_SET_TONE, object->tone) < 0) {
1324             g_warning ("Error setting tone: %s", strerror (errno));
1325           }
1326         } else {
1327           GST_DEBUG_OBJECT (object, "Sending DISEqC");
1328           diseqc (object->fd_frontend, object->diseqc_src, voltage,
1329               object->tone);
1330           /* Once diseqc source is set, do not set it again until
1331            * app decides to change it */
1332           //object->send_diseqc = FALSE;
1333         }
1334
1335         break;
1336       case FE_OFDM:
1337
1338         feparams.frequency = freq;
1339 #if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1340         feparams.delsys.dvbs.fec = object->code_rate_hp;
1341         feparams.delsys.dvbs.modulation = object->modulation;
1342         feparams.delsys.dvbs.symbol_rate = sym_rate;
1343 #else
1344         feparams.u.ofdm.bandwidth = object->bandwidth;
1345         feparams.u.ofdm.code_rate_HP = object->code_rate_hp;
1346         feparams.u.ofdm.code_rate_LP = object->code_rate_lp;
1347         feparams.u.ofdm.constellation = object->modulation;
1348         feparams.u.ofdm.transmission_mode = object->transmission_mode;
1349         feparams.u.ofdm.guard_interval = object->guard_interval;
1350         feparams.u.ofdm.hierarchy_information = object->hierarchy_information;
1351 #endif
1352         feparams.inversion = object->inversion;
1353
1354         GST_INFO_OBJECT (object, "tuning DVB-T to %d Hz", freq);
1355         break;
1356       case FE_QAM:
1357         GST_INFO_OBJECT (object, "Tuning DVB-C to %d, srate=%d", freq,
1358             sym_rate);
1359         feparams.frequency = freq;
1360         feparams.inversion = object->inversion;
1361 #if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1362         feparams.delsys.dvbs.fec = object->code_rate_hp;
1363         feparams.delsys.dvbs.modulation = object->modulation;
1364         feparams.delsys.dvbs.symbol_rate = sym_rate;
1365 #else
1366         feparams.u.qam.fec_inner = object->code_rate_hp;
1367         feparams.u.qam.modulation = object->modulation;
1368         feparams.u.qam.symbol_rate = sym_rate;
1369 #endif
1370         break;
1371       case FE_ATSC:
1372         GST_INFO_OBJECT (object, "Tuning ATSC to %d", freq);
1373         feparams.frequency = freq;
1374 #if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1375         feparams.delsys.atsc.modulation = object->modulation;
1376 #else
1377         feparams.u.vsb.modulation = object->modulation;
1378 #endif
1379         break;
1380       default:
1381         g_error ("Unknown frontend type: %d", object->adapter_type);
1382
1383     }
1384     usleep (100000);
1385     /* now tune the frontend */
1386 #if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR == 3
1387     if (ioctl (object->fd_frontend, DVBFE_SET_PARAMS, &feparams) < 0) {
1388 #else
1389     if (ioctl (object->fd_frontend, FE_SET_FRONTEND, &feparams) < 0) {
1390 #endif
1391       g_warning ("Error tuning channel: %s", strerror (errno));
1392     }
1393     for (i = 0; i < 50; i++) {
1394       usleep (100000);
1395       if (ioctl (object->fd_frontend, FE_READ_STATUS, &status) == -1) {
1396         perror ("FE_READ_STATUS");
1397         break;
1398       }
1399       GST_LOG_OBJECT (object, "status == 0x%02x", status);
1400       if (status & FE_HAS_LOCK)
1401         break;
1402     }
1403     if (status & FE_HAS_LOCK)
1404       break;
1405   }
1406   if (!(status & FE_HAS_LOCK))
1407     return FALSE;
1408   /* set pid filters */
1409   gst_dvbsrc_set_pes_filters (object);
1410
1411   return TRUE;
1412 }
1413
1414
1415 static void
1416 gst_dvbsrc_unset_pes_filters (GstDvbSrc * object)
1417 {
1418   int i = 0;
1419
1420   GST_INFO_OBJECT (object, "clearing PES filter");
1421
1422   for (i = 0; i < MAX_FILTERS; i++) {
1423     if (object->fd_filters[i] == -1)
1424       continue;
1425     close (object->fd_filters[i]);
1426     object->fd_filters[i] = -1;
1427   }
1428 }
1429
1430 static void
1431 gst_dvbsrc_set_pes_filters (GstDvbSrc * object)
1432 {
1433   int *fd;
1434   int pid, i;
1435   struct dmx_pes_filter_params pes_filter;
1436   gchar *demux_dev = g_strdup_printf ("/dev/dvb/adapter%d/demux%d",
1437       object->adapter_number, object->frontend_number);
1438
1439   GST_INFO_OBJECT (object, "Setting PES filter");
1440
1441   for (i = 0; i < MAX_FILTERS; i++) {
1442     if (object->pids[i] == G_MAXUINT16)
1443       break;
1444
1445     fd = &object->fd_filters[i];
1446     pid = object->pids[i];
1447
1448     close (*fd);
1449     if ((*fd = open (demux_dev, O_RDWR)) < 0) {
1450       g_error ("Error opening demuxer: %s (%s)", strerror (errno), demux_dev);
1451       g_free (demux_dev);
1452     }
1453     g_return_if_fail (*fd != -1);
1454
1455     pes_filter.pid = pid;
1456     pes_filter.input = DMX_IN_FRONTEND;
1457     pes_filter.output = DMX_OUT_TS_TAP;
1458     pes_filter.pes_type = DMX_PES_OTHER;
1459     pes_filter.flags = DMX_IMMEDIATE_START;
1460
1461     GST_INFO_OBJECT (object, "Setting pes-filter, pid = %d, type = %d",
1462         pes_filter.pid, pes_filter.pes_type);
1463
1464     if (ioctl (*fd, DMX_SET_PES_FILTER, &pes_filter) < 0)
1465       GST_WARNING_OBJECT (object, "Error setting PES filter on %s: %s",
1466           demux_dev, strerror (errno));
1467   }
1468
1469   g_free (demux_dev);
1470 }