1 /* GStreamer DVB source
2  * Copyright (C) 2006 Zaheer Abbas Merali <zaheerabbas at merali
3  *                                         dot org>
4  * Copyright (C) 2014 Samsung Electronics. All rights reserved.
5  *     @Author: Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
6  *
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.
11  *
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.
16  *
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., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 /**
23  * SECTION:element-dvbsrc
24  * @title: dvbsrc
25  *
26  * dvbsrc can be used to capture media from DVB cards. Supported DTV
27  * broadcasting standards include DVB-T/C/S, ATSC, ISDB-T and DTMB.
28  *
29  * ## Example launch line
30  * |[
31  * gst-launch-1.0 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 ! mpegvideoparse ! mpegvideoparse ! mpeg2dec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! mpegaudioparse ! mpg123audiodec ! audioconvert ! pulsesink
32  * ]| Captures a full transport stream from DVB card 0 that is a DVB-T card at tuned frequency 514000000 Hz with other parameters as seen in the pipeline and renders the first TV program on the transport stream.
33  * |[
34  * gst-launch-1.0 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 ! mpegvideoparse ! mpeg2dec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! mpegaudioparse ! mpg123audiodec ! audioconvert ! pulsesink
35  * ]| Captures and renders a transport stream from DVB card 0 that is a DVB-T card for a program at tuned frequency 514000000 Hz with PMT PID 100 and elementary stream PIDs of 256, 257 with other parameters as seen in the pipeline.
36  * |[
37  * gst-launch-1.0 dvbsrc polarity="h" frequency=11302000 symbol-rate=27500 diseqc-source=0 pids=50:102:103 ! mpegtsdemux name=demux ! queue max-size-buffers=0 max-size-time=0 ! mpegvideoparse ! mpeg2dec ! xvimagesink demux. ! queue max-size-buffers=0 max-size-time=0 ! mpegaudioparse ! mpg123audiodec ! audioconvert ! pulsesink
38  * ]| Captures and renders a transport stream from DVB card 0 that is a DVB-S card for a program at tuned frequency 11302000 kHz, symbol rate of 27500 kBd (kilo bauds) with PMT PID of 50 and elementary stream PIDs of 102 and 103.
39  * |[
40  * gst-launch-1.0 dvbsrc frequency=515142857 guard=16 trans-mode="8k" isdbt-layer-enabled=7 isdbt-partial-reception=1 isdbt-layera-fec="2/3" isdbt-layera-modulation="QPSK" isdbt-layera-segment-count=1 isdbt-layera-time-interleaving=4 isdbt-layerb-fec="3/4" isdbt-layerb-modulation="qam-64" isdbt-layerb-segment-count=12 isdbt-layerb-time-interleaving=2 isdbt-layerc-fec="1/2" isdbt-layerc-modulation="qam-64" isdbt-layerc-segment-count=0 isdbt-layerc-time-interleaving=0 delsys="isdb-t" ! tsdemux ! "video/x-h264" ! h264parse ! queue ! avdec_h264 ! videoconvert ! queue ! autovideosink
41  * ]| Captures and renders the video track of TV Paraíba HD (Globo affiliate) in Campina Grande, Brazil. This is an ISDB-T (Brazilian ISDB-Tb variant) broadcast.
42  * |[
43  *  gst-launch-1.0 dvbsrc frequency=503000000 delsys="atsc" modulation="8vsb" pids=48:49:52 ! decodebin name=dec dec. ! videoconvert ! autovideosink dec. ! audioconvert ! autoaudiosink
44  * ]| Captures and renders KOFY-HD in San Jose, California. This is an ATSC broadcast, PMT ID 48, Audio/Video elementary stream PIDs 49 and 52 respectively.
45  *
46  */
47 
48 /*
49  * History of DVB_API_VERSION 5 minor changes
50  *
51  * API Addition/changes in reverse order (most recent first)
52  *
53  * Minor 10 (statistics properties)
54  *   DTV_STAT_*
55  *   FE_SCALE_*
56  *
57  * Minor 9
58  *   DTV_LNA
59  *   LNA_AUTO
60  *
61  * Minor 8
62  *   FE_CAN_MULTISTREAM
63  *   DTV_ISDBS_TS_ID_LEGACY (was DVB_ISDBS_TS_ID)
64  *   DTV_DVBT2_PLP_ID_LEGACY (was DVB_DVBT2_PLP_ID)
65  *   NO_STREAM_ID_FILTER
66  *   DTV_STREAM_ID
67  *   INTERLEAVING_AUTO
68  *
69  * Minor 7 (DTMB Support)
70  *   FEC_2_5
71  *   QAM_4_NR
72  *   TRANSMISSION_MODE_C1 / _C3780
73  *   GUARD_INTERVAL_PN420 / _PN595 / _PN945
74  *   INTERLEAVING_NONE / _240 / _720
75  *   DTV_INTERLEAVING
76  *   SYS_DTMB (Renamed from SYS_DMBTH but has safety #define)
77  *
78  * Minor 6 (ATSC-MH)
79  *   DTV_ATSCMH_* (for those not defined in later versions)
80  *
81  * Somewhere in between 5 and 6:
82  *   SYS_DVBC_ANNEX_A / _C (Safety #define for _AC => A)
83  *
84  * Minor 5 (Note : minimum version we support according to configure.ac)
85  *   DTV_ENUM_DELSYS
86  */
87 
88 /* We know we have at least DVB_API_VERSION >= 5 (minor 5) */
89 #define HAVE_V5_MINOR(minor) ((DVB_API_VERSION > 5) || \
90 			      (DVB_API_VERSION_MINOR >= (minor)))
91 
92 #ifdef HAVE_CONFIG_H
93 #include "config.h"
94 #endif
95 
96 #include "gstdvbsrc.h"
97 #include <gst/gst.h>
98 #include <gst/glib-compat-private.h>
99 #include <sys/ioctl.h>
100 #include <sys/poll.h>
101 #include <fcntl.h>
102 #include <errno.h>
103 #include <stdio.h>
104 #include <stdlib.h>
105 #include <string.h>
106 
107 #include <unistd.h>
108 
109 #include <linux/dvb/version.h>
110 #include <linux/dvb/frontend.h>
111 #include <linux/dvb/dmx.h>
112 
113 #include <gst/gst-i18n-plugin.h>
114 
115 /* Before 5.6 we map A to AC */
116 #if !HAVE_V5_MINOR(6)
117 #define SYS_DVBC_ANNEX_A SYS_DVBC_ANNEX_AC
118 #endif
119 
120 /* NO_STREAM_ID_FILTER & DTV_STREAMID introduced in minor 8 */
121 #ifndef NO_STREAM_ID_FILTER
122 #define NO_STREAM_ID_FILTER    (~0U)
123 #endif
124 #ifndef DTV_STREAM_ID
125 #define DTV_STREAM_ID DTV_ISDBS_TS_ID
126 #endif
127 
128 GST_DEBUG_CATEGORY_STATIC (gstdvbsrc_debug);
129 #define GST_CAT_DEFAULT (gstdvbsrc_debug)
130 
131 /**
132  * NUM_DTV_PROPS:
133  *
134  * Can't be greater than DTV_IOCTL_MAX_MSGS but we are
135  * not using more than 25 for the largest use case (ISDB-T).
136  *
137  * Bump as needed.
138  */
139 #define NUM_DTV_PROPS 25
140 
141 /* Signals */
142 enum
143 {
144   SIGNAL_TUNING_START,
145   SIGNAL_TUNING_DONE,
146   SIGNAL_TUNING_FAIL,
147   SIGNAL_TUNE,
148   LAST_SIGNAL
149 };
150 
151 /* Arguments */
152 enum
153 {
154   ARG_0,
155   ARG_DVBSRC_ADAPTER,
156   ARG_DVBSRC_FRONTEND,
157   ARG_DVBSRC_DISEQC_SRC,
158   ARG_DVBSRC_FREQUENCY,
159   ARG_DVBSRC_POLARITY,
160   ARG_DVBSRC_PIDS,
161   ARG_DVBSRC_SYM_RATE,
162   ARG_DVBSRC_BANDWIDTH,
163   ARG_DVBSRC_CODE_RATE_HP,
164   ARG_DVBSRC_CODE_RATE_LP,
165   ARG_DVBSRC_GUARD,
166   ARG_DVBSRC_MODULATION,
167   ARG_DVBSRC_TRANSMISSION_MODE,
168   ARG_DVBSRC_HIERARCHY_INF,
169   ARG_DVBSRC_TUNE,
170   ARG_DVBSRC_INVERSION,
171   ARG_DVBSRC_STATS_REPORTING_INTERVAL,
172   ARG_DVBSRC_TIMEOUT,
173   ARG_DVBSRC_TUNING_TIMEOUT,
174   ARG_DVBSRC_DVB_BUFFER_SIZE,
175   ARG_DVBSRC_DELSYS,
176   ARG_DVBSRC_PILOT,
177   ARG_DVBSRC_ROLLOFF,
178   ARG_DVBSRC_STREAM_ID,
179   ARG_DVBSRC_BANDWIDTH_HZ,
180   ARG_DVBSRC_ISDBT_LAYER_ENABLED,
181   ARG_DVBSRC_ISDBT_PARTIAL_RECEPTION,
182   ARG_DVBSRC_ISDBT_SOUND_BROADCASTING,
183   ARG_DVBSRC_ISDBT_SB_SUBCHANNEL_ID,
184   ARG_DVBSRC_ISDBT_SB_SEGMENT_IDX,
185   ARG_DVBSRC_ISDBT_SB_SEGMENT_COUNT,
186   ARG_DVBSRC_ISDBT_LAYERA_FEC,
187   ARG_DVBSRC_ISDBT_LAYERA_MODULATION,
188   ARG_DVBSRC_ISDBT_LAYERA_SEGMENT_COUNT,
189   ARG_DVBSRC_ISDBT_LAYERA_TIME_INTERLEAVING,
190   ARG_DVBSRC_ISDBT_LAYERB_FEC,
191   ARG_DVBSRC_ISDBT_LAYERB_MODULATION,
192   ARG_DVBSRC_ISDBT_LAYERB_SEGMENT_COUNT,
193   ARG_DVBSRC_ISDBT_LAYERB_TIME_INTERLEAVING,
194   ARG_DVBSRC_ISDBT_LAYERC_FEC,
195   ARG_DVBSRC_ISDBT_LAYERC_MODULATION,
196   ARG_DVBSRC_ISDBT_LAYERC_SEGMENT_COUNT,
197   ARG_DVBSRC_ISDBT_LAYERC_TIME_INTERLEAVING,
198   ARG_DVBSRC_LNB_SLOF,
199   ARG_DVBSRC_LNB_LOF1,
200   ARG_DVBSRC_LNB_LOF2,
201   ARG_DVBSRC_INTERLEAVING
202 };
203 
204 #define DEFAULT_ADAPTER 0
205 #define DEFAULT_FRONTEND 0
206 #define DEFAULT_DISEQC_SRC -1   /* disabled */
207 #define DEFAULT_FREQUENCY 0
208 #define DEFAULT_POLARITY "H"
209 #define DEFAULT_PIDS "8192"     /* Special value meaning 'all' PIDs */
210 #define DEFAULT_SYMBOL_RATE 0
211 #define DEFAULT_BANDWIDTH_HZ 8000000
212 #define DEFAULT_BANDWIDTH BANDWIDTH_8_MHZ
213 #define DEFAULT_CODE_RATE_HP FEC_AUTO
214 #define DEFAULT_CODE_RATE_LP FEC_1_2
215 #define DEFAULT_GUARD GUARD_INTERVAL_1_16
216 #define DEFAULT_MODULATION QAM_16
217 #define DEFAULT_TRANSMISSION_MODE TRANSMISSION_MODE_8K
218 #define DEFAULT_HIERARCHY HIERARCHY_1
219 #define DEFAULT_INVERSION INVERSION_ON
220 #define DEFAULT_STATS_REPORTING_INTERVAL 100
221 #define DEFAULT_TIMEOUT 1000000 /* 1 second */
222 #define DEFAULT_TUNING_TIMEOUT 10 * GST_SECOND  /* 10 seconds */
223 #define DEFAULT_DVB_BUFFER_SIZE (10*188*1024)   /* kernel default is 8192 */
224 #define DEFAULT_BUFFER_SIZE 8192        /* not a property */
225 #define DEFAULT_DELSYS SYS_UNDEFINED
226 #define DEFAULT_PILOT PILOT_AUTO
227 #define DEFAULT_ROLLOFF ROLLOFF_AUTO
228 #define DEFAULT_STREAM_ID NO_STREAM_ID_FILTER
229 #define DEFAULT_ISDBT_LAYER_ENABLED 7
230 #define DEFAULT_ISDBT_PARTIAL_RECEPTION 1
231 #define DEFAULT_ISDBT_SOUND_BROADCASTING 0
232 #define DEFAULT_ISDBT_SB_SUBCHANNEL_ID -1
233 #define DEFAULT_ISDBT_SB_SEGMENT_IDX 0
234 #define DEFAULT_ISDBT_SB_SEGMENT_COUNT 1
235 #define DEFAULT_ISDBT_LAYERA_FEC FEC_AUTO
236 #define DEFAULT_ISDBT_LAYERA_MODULATION QAM_AUTO
237 #define DEFAULT_ISDBT_LAYERA_SEGMENT_COUNT -1
238 #define DEFAULT_ISDBT_LAYERA_TIME_INTERLEAVING -1
239 #define DEFAULT_ISDBT_LAYERB_FEC FEC_AUTO
240 #define DEFAULT_ISDBT_LAYERB_MODULATION QAM_AUTO
241 #define DEFAULT_ISDBT_LAYERB_SEGMENT_COUNT -1
242 #define DEFAULT_ISDBT_LAYERB_TIME_INTERLEAVING -1
243 #define DEFAULT_ISDBT_LAYERC_FEC FEC_AUTO
244 #define DEFAULT_ISDBT_LAYERC_MODULATION QAM_AUTO
245 #define DEFAULT_ISDBT_LAYERC_SEGMENT_COUNT -1
246 #define DEFAULT_ISDBT_LAYERC_TIME_INTERLEAVING -1
247 #define DEFAULT_LNB_SLOF (11700*1000UL)
248 #define DEFAULT_LNB_LOF1 (9750*1000UL)
249 #define DEFAULT_LNB_LOF2 (10600*1000UL)
250 #if HAVE_V5_MINOR(7)
251 #define DEFAULT_INTERLEAVING INTERLEAVING_AUTO
252 #else
253 #define DEFAULT_INTERLEAVING 0
254 #endif
255 
256 static gboolean gst_dvbsrc_output_frontend_stats (GstDvbSrc * src,
257     fe_status_t * status);
258 
259 #define GST_TYPE_DVBSRC_CODE_RATE (gst_dvbsrc_code_rate_get_type ())
260 static GType
gst_dvbsrc_code_rate_get_type(void)261 gst_dvbsrc_code_rate_get_type (void)
262 {
263   static GType dvbsrc_code_rate_type = 0;
264   static const GEnumValue code_rate_types[] = {
265     {FEC_NONE, "NONE", "none"},
266     {FEC_1_2, "1/2", "1/2"},
267     {FEC_2_3, "2/3", "2/3"},
268     {FEC_3_4, "3/4", "3/4"},
269     {FEC_4_5, "4/5", "4/5"},
270     {FEC_5_6, "5/6", "5/6"},
271     {FEC_6_7, "6/7", "6/7"},
272     {FEC_7_8, "7/8", "7/8"},
273     {FEC_8_9, "8/9", "8/9"},
274     {FEC_AUTO, "AUTO", "auto"},
275     {FEC_3_5, "3/5", "3/5"},
276     {FEC_9_10, "9/10", "9/10"},
277 #if HAVE_V5_MINOR(7)
278     {FEC_2_5, "2/5", "2/5"},
279 #endif
280     {0, NULL, NULL},
281   };
282 
283   if (!dvbsrc_code_rate_type) {
284     dvbsrc_code_rate_type =
285         g_enum_register_static ("GstDvbSrcCode_Rate", code_rate_types);
286   }
287   return dvbsrc_code_rate_type;
288 }
289 
290 #define GST_TYPE_DVBSRC_MODULATION (gst_dvbsrc_modulation_get_type ())
291 static GType
gst_dvbsrc_modulation_get_type(void)292 gst_dvbsrc_modulation_get_type (void)
293 {
294   static GType dvbsrc_modulation_type = 0;
295   static const GEnumValue modulation_types[] = {
296     {QPSK, "QPSK", "qpsk"},
297     {QAM_16, "QAM 16", "qam-16"},
298     {QAM_32, "QAM 32", "qam-32"},
299     {QAM_64, "QAM 64", "qam-64"},
300     {QAM_128, "QAM 128", "qam-128"},
301     {QAM_256, "QAM 256", "qam-256"},
302     {QAM_AUTO, "AUTO", "auto"},
303     {VSB_8, "8VSB", "8vsb"},
304     {VSB_16, "16VSB", "16vsb"},
305     {PSK_8, "8PSK", "8psk"},
306     {APSK_16, "16APSK", "16apsk"},
307     {APSK_32, "32APSK", "32apsk"},
308     {DQPSK, "DQPSK", "dqpsk"},
309     {QAM_4_NR, "QAM 4 NR", "qam-4-nr"},
310     {0, NULL, NULL},
311   };
312 
313   if (!dvbsrc_modulation_type) {
314     dvbsrc_modulation_type =
315         g_enum_register_static ("GstDvbSrcModulation", modulation_types);
316   }
317   return dvbsrc_modulation_type;
318 }
319 
320 #define GST_TYPE_DVBSRC_TRANSMISSION_MODE (gst_dvbsrc_transmission_mode_get_type ())
321 static GType
gst_dvbsrc_transmission_mode_get_type(void)322 gst_dvbsrc_transmission_mode_get_type (void)
323 {
324   static GType dvbsrc_transmission_mode_type = 0;
325   static const GEnumValue transmission_mode_types[] = {
326     {TRANSMISSION_MODE_2K, "2K", "2k"},
327     {TRANSMISSION_MODE_8K, "8K", "8k"},
328     {TRANSMISSION_MODE_AUTO, "AUTO", "auto"},
329     {TRANSMISSION_MODE_4K, "4K", "4k"},
330     {TRANSMISSION_MODE_1K, "1K", "1k"},
331     {TRANSMISSION_MODE_16K, "16K", "16k"},
332     {TRANSMISSION_MODE_32K, "32K", "32k"},
333 #if HAVE_V5_MINOR(7)
334     {TRANSMISSION_MODE_C1, "C1", "c1"},
335     {TRANSMISSION_MODE_C3780, "C3780", "c3780"},
336 #endif
337     {0, NULL, NULL},
338   };
339 
340   if (!dvbsrc_transmission_mode_type) {
341     dvbsrc_transmission_mode_type =
342         g_enum_register_static ("GstDvbSrcTransmission_Mode",
343         transmission_mode_types);
344   }
345   return dvbsrc_transmission_mode_type;
346 }
347 
348 #define GST_TYPE_DVBSRC_BANDWIDTH (gst_dvbsrc_bandwidth_get_type ())
349 static GType
gst_dvbsrc_bandwidth_get_type(void)350 gst_dvbsrc_bandwidth_get_type (void)
351 {
352   static GType dvbsrc_bandwidth_type = 0;
353   static const GEnumValue bandwidth_types[] = {
354     {BANDWIDTH_8_MHZ, "8", "8"},
355     {BANDWIDTH_7_MHZ, "7", "7"},
356     {BANDWIDTH_6_MHZ, "6", "6"},
357     {BANDWIDTH_AUTO, "AUTO", "AUTO"},
358     {BANDWIDTH_5_MHZ, "5", "5"},
359     {BANDWIDTH_10_MHZ, "10", "10"},
360     {BANDWIDTH_1_712_MHZ, "1.712", "1.712"},
361     {0, NULL, NULL},
362   };
363 
364   if (!dvbsrc_bandwidth_type) {
365     dvbsrc_bandwidth_type =
366         g_enum_register_static ("GstDvbSrcBandwidth", bandwidth_types);
367   }
368   return dvbsrc_bandwidth_type;
369 }
370 
371 #define GST_TYPE_DVBSRC_GUARD (gst_dvbsrc_guard_get_type ())
372 static GType
gst_dvbsrc_guard_get_type(void)373 gst_dvbsrc_guard_get_type (void)
374 {
375   static GType dvbsrc_guard_type = 0;
376   static const GEnumValue guard_types[] = {
377     {GUARD_INTERVAL_1_32, "32", "32"},
378     {GUARD_INTERVAL_1_16, "16", "16"},
379     {GUARD_INTERVAL_1_8, "8", "8"},
380     {GUARD_INTERVAL_1_4, "4", "4"},
381     {GUARD_INTERVAL_AUTO, "AUTO", "auto"},
382     {GUARD_INTERVAL_1_128, "128", "128"},
383     {GUARD_INTERVAL_19_128, "19/128", "19/128"},
384     {GUARD_INTERVAL_19_256, "19/256", "19/256"},
385 #if HAVE_V5_MINOR(7)
386     {GUARD_INTERVAL_PN420, "PN420", "pn420"},
387     {GUARD_INTERVAL_PN595, "PN595", "pn595"},
388     {GUARD_INTERVAL_PN945, "PN945", "pn945"},
389 #endif
390     {0, NULL, NULL},
391   };
392 
393   if (!dvbsrc_guard_type) {
394     dvbsrc_guard_type = g_enum_register_static ("GstDvbSrcGuard", guard_types);
395   }
396   return dvbsrc_guard_type;
397 }
398 
399 #define GST_TYPE_DVBSRC_HIERARCHY (gst_dvbsrc_hierarchy_get_type ())
400 static GType
gst_dvbsrc_hierarchy_get_type(void)401 gst_dvbsrc_hierarchy_get_type (void)
402 {
403   static GType dvbsrc_hierarchy_type = 0;
404   static const GEnumValue hierarchy_types[] = {
405     {HIERARCHY_NONE, "NONE", "none"},
406     {HIERARCHY_1, "1", "1"},
407     {HIERARCHY_2, "2", "2"},
408     {HIERARCHY_4, "4", "4"},
409     {HIERARCHY_AUTO, "AUTO", "auto"},
410     {0, NULL, NULL},
411   };
412 
413   if (!dvbsrc_hierarchy_type) {
414     dvbsrc_hierarchy_type =
415         g_enum_register_static ("GstDvbSrcHierarchy", hierarchy_types);
416   }
417   return dvbsrc_hierarchy_type;
418 }
419 
420 #define GST_TYPE_DVBSRC_INVERSION (gst_dvbsrc_inversion_get_type ())
421 static GType
gst_dvbsrc_inversion_get_type(void)422 gst_dvbsrc_inversion_get_type (void)
423 {
424   static GType dvbsrc_inversion_type = 0;
425   static const GEnumValue inversion_types[] = {
426     {INVERSION_OFF, "OFF", "off"},
427     {INVERSION_ON, "ON", "on"},
428     {INVERSION_AUTO, "AUTO", "auto"},
429     {0, NULL, NULL},
430   };
431 
432   if (!dvbsrc_inversion_type) {
433     dvbsrc_inversion_type =
434         g_enum_register_static ("GstDvbSrcInversion", inversion_types);
435   }
436   return dvbsrc_inversion_type;
437 }
438 
439 #define GST_TYPE_DVBSRC_DELSYS (gst_dvbsrc_delsys_get_type ())
440 static GType
gst_dvbsrc_delsys_get_type(void)441 gst_dvbsrc_delsys_get_type (void)
442 {
443   static GType dvbsrc_delsys_type = 0;
444   static const GEnumValue delsys_types[] = {
445     {SYS_UNDEFINED, "UNDEFINED", "undefined"},
446     {SYS_DVBC_ANNEX_A, "DVB-C-A", "dvb-c-a"},
447     {SYS_DVBC_ANNEX_B, "DVB-C-B", "dvb-c-b"},
448     {SYS_DVBT, "DVB-T", "dvb-t"},
449     {SYS_DSS, "DSS", "dss"},
450     {SYS_DVBS, "DVB-S", "dvb-s"},
451     {SYS_DVBS2, "DVB-S2", "dvb-s2"},
452     {SYS_DVBH, "DVB-H", "dvb-h"},
453     {SYS_ISDBT, "ISDB-T", "isdb-t"},
454     {SYS_ISDBS, "ISDB-S", "isdb-s"},
455     {SYS_ISDBC, "ISDB-C", "isdb-c"},
456     {SYS_ATSC, "ATSC", "atsc"},
457     {SYS_ATSCMH, "ATSC-MH", "atsc-mh"},
458 #if HAVE_V5_MINOR(7)
459     {SYS_DTMB, "DTMB", "dtmb"},
460 #endif
461     {SYS_CMMB, "CMMB", "cmmb"},
462     {SYS_DAB, "DAB", "dab"},
463     {SYS_DVBT2, "DVB-T2", "dvb-t2"},
464     {SYS_TURBO, "TURBO", "turbo"},
465 #if HAVE_V5_MINOR(6)
466     {SYS_DVBC_ANNEX_C, "DVB-C-C", "dvb-c-c"},
467 #endif
468     {0, NULL, NULL},
469   };
470 
471   if (!dvbsrc_delsys_type) {
472     dvbsrc_delsys_type =
473         g_enum_register_static ("GstDvbSrcDelsys", delsys_types);
474   }
475   return dvbsrc_delsys_type;
476 }
477 
478 #define GST_TYPE_DVBSRC_PILOT (gst_dvbsrc_pilot_get_type ())
479 static GType
gst_dvbsrc_pilot_get_type(void)480 gst_dvbsrc_pilot_get_type (void)
481 {
482   static GType dvbsrc_pilot_type = 0;
483   static const GEnumValue pilot_types[] = {
484     {PILOT_ON, "ON", "on"},
485     {PILOT_OFF, "OFF", "off"},
486     {PILOT_AUTO, "AUTO", "auto"},
487     {0, NULL, NULL},
488   };
489 
490   if (!dvbsrc_pilot_type) {
491     dvbsrc_pilot_type = g_enum_register_static ("GstDvbSrcPilot", pilot_types);
492   }
493   return dvbsrc_pilot_type;
494 }
495 
496 #define GST_TYPE_DVBSRC_ROLLOFF (gst_dvbsrc_rolloff_get_type ())
497 static GType
gst_dvbsrc_rolloff_get_type(void)498 gst_dvbsrc_rolloff_get_type (void)
499 {
500   static GType dvbsrc_rolloff_type = 0;
501   static const GEnumValue rolloff_types[] = {
502     {ROLLOFF_35, "35", "35"},
503     {ROLLOFF_20, "20", "20"},
504     {ROLLOFF_25, "25", "25"},
505     {ROLLOFF_AUTO, "auto", "auto"},
506     {0, NULL, NULL},
507   };
508 
509   if (!dvbsrc_rolloff_type) {
510     dvbsrc_rolloff_type =
511         g_enum_register_static ("GstDvbSrcRolloff", rolloff_types);
512   }
513   return dvbsrc_rolloff_type;
514 }
515 
516 #define GST_TYPE_INTERLEAVING (gst_dvbsrc_interleaving_get_type ())
517 static GType
gst_dvbsrc_interleaving_get_type(void)518 gst_dvbsrc_interleaving_get_type (void)
519 {
520   static GType dvbsrc_interleaving_type = 0;
521   static const GEnumValue interleaving_types[] = {
522 #if HAVE_V5_MINOR(7)
523     {INTERLEAVING_NONE, "NONE", "none"},
524     {INTERLEAVING_AUTO, "AUTO", "auto"},
525     {INTERLEAVING_240, "240", "240"},
526     {INTERLEAVING_720, "720", "720"},
527 #endif
528     {0, NULL, NULL},
529   };
530 
531   if (!dvbsrc_interleaving_type) {
532     dvbsrc_interleaving_type =
533         g_enum_register_static ("GstDvbSrcInterleaving", interleaving_types);
534   }
535   return dvbsrc_interleaving_type;
536 }
537 
538 static void gst_dvbsrc_finalize (GObject * object);
539 static void gst_dvbsrc_set_property (GObject * object, guint prop_id,
540     const GValue * value, GParamSpec * pspec);
541 static void gst_dvbsrc_get_property (GObject * object, guint prop_id,
542     GValue * value, GParamSpec * pspec);
543 
544 static GstFlowReturn gst_dvbsrc_create (GstPushSrc * element,
545     GstBuffer ** buffer);
546 
547 static gboolean gst_dvbsrc_start (GstBaseSrc * bsrc);
548 static gboolean gst_dvbsrc_stop (GstBaseSrc * bsrc);
549 static GstStateChangeReturn gst_dvbsrc_change_state (GstElement * element,
550     GstStateChange transition);
551 
552 static gboolean gst_dvbsrc_unlock (GstBaseSrc * bsrc);
553 static gboolean gst_dvbsrc_unlock_stop (GstBaseSrc * bsrc);
554 static gboolean gst_dvbsrc_is_seekable (GstBaseSrc * bsrc);
555 static gboolean gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size);
556 
557 static void gst_dvbsrc_do_tune (GstDvbSrc * src);
558 static gboolean gst_dvbsrc_tune (GstDvbSrc * object);
559 static gboolean gst_dvbsrc_set_fe_params (GstDvbSrc * object,
560     struct dtv_properties *props);
561 static void gst_dvbsrc_guess_delsys (GstDvbSrc * object);
562 static gboolean gst_dvbsrc_tune_fe (GstDvbSrc * object);
563 
564 static void gst_dvbsrc_set_pes_filters (GstDvbSrc * object);
565 static void gst_dvbsrc_unset_pes_filters (GstDvbSrc * object);
566 static gboolean gst_dvbsrc_is_valid_modulation (guint delsys, guint mod);
567 static gboolean gst_dvbsrc_is_valid_trans_mode (guint delsys, guint mode);
568 static gboolean gst_dvbsrc_is_valid_bandwidth (guint delsys, guint bw);
569 
570 /**
571  * LOOP_WHILE_EINTR:
572  *
573  * This loop should be safe enough considering:
574  *
575  * 1.- EINTR suggest the next ioctl might succeed
576  * 2.- It's highly unlikely you will end up spining
577  *     before your entire system goes nuts due to
578  *     the massive number of interrupts.
579  *
580  * We don't check for EAGAIN here cause we are opening
581  * the frontend in blocking mode.
582  */
583 #define LOOP_WHILE_EINTR(v,func) do { (v) = (func); } \
584 		while ((v) == -1 && errno == EINTR);
585 
586 static GstStaticPadTemplate ts_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
587     GST_PAD_SRC,
588     GST_PAD_ALWAYS,
589     GST_STATIC_CAPS
590     ("video/mpegts, "
591         "mpegversion = (int) 2," "systemstream = (boolean) TRUE"));
592 
593 /*
594  ******************************
595  *                            *
596  *      GObject Related       *
597  *            	              *
598  *                            *
599  ******************************
600  */
601 
602 #define gst_dvbsrc_parent_class parent_class
603 G_DEFINE_TYPE (GstDvbSrc, gst_dvbsrc, GST_TYPE_PUSH_SRC);
604 
605 static guint gst_dvbsrc_signals[LAST_SIGNAL] = { 0 };
606 
607 /* initialize the plugin's class */
608 static void
gst_dvbsrc_class_init(GstDvbSrcClass * klass)609 gst_dvbsrc_class_init (GstDvbSrcClass * klass)
610 {
611   GObjectClass *gobject_class;
612   GstElementClass *gstelement_class;
613   GstBaseSrcClass *gstbasesrc_class;
614   GstPushSrcClass *gstpushsrc_class;
615   GstDvbSrcClass *gstdvbsrc_class;
616 
617   gobject_class = (GObjectClass *) klass;
618   gstelement_class = (GstElementClass *) klass;
619   gstbasesrc_class = (GstBaseSrcClass *) klass;
620   gstpushsrc_class = (GstPushSrcClass *) klass;
621   gstdvbsrc_class = (GstDvbSrcClass *) klass;
622 
623   gobject_class->set_property = gst_dvbsrc_set_property;
624   gobject_class->get_property = gst_dvbsrc_get_property;
625   gobject_class->finalize = gst_dvbsrc_finalize;
626 
627   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_dvbsrc_change_state);
628 
629   gst_element_class_add_static_pad_template (gstelement_class, &ts_src_factory);
630 
631   gst_element_class_set_static_metadata (gstelement_class, "DVB Source",
632       "Source/Video",
633       "Digital Video Broadcast Source",
634       "P2P-VCR, C-Lab, University of Paderborn, "
635       "Zaheer Abbas Merali <zaheerabbas at merali dot org>\n"
636       "Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>");
637 
638   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dvbsrc_start);
639   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dvbsrc_stop);
640   gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_dvbsrc_unlock);
641   gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_dvbsrc_unlock_stop);
642   gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_dvbsrc_is_seekable);
643   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_dvbsrc_get_size);
644 
645   gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_dvbsrc_create);
646 
647   gstdvbsrc_class->do_tune = GST_DEBUG_FUNCPTR (gst_dvbsrc_do_tune);
648 
649   g_object_class_install_property (gobject_class, ARG_DVBSRC_ADAPTER,
650       g_param_spec_int ("adapter", "The adapter device number",
651           "The DVB adapter device number (eg. 0 for adapter0)",
652           0, 16, DEFAULT_ADAPTER, G_PARAM_READWRITE));
653 
654   g_object_class_install_property (gobject_class, ARG_DVBSRC_FRONTEND,
655       g_param_spec_int ("frontend", "The frontend device number",
656           "The frontend device number (eg. 0 for frontend0)",
657           0, 16, DEFAULT_FRONTEND, G_PARAM_READWRITE));
658 
659   g_object_class_install_property (gobject_class, ARG_DVBSRC_FREQUENCY,
660       g_param_spec_uint ("frequency", "Center frequency",
661           "Center frequency to tune into. Measured in kHz for the satellite "
662           "distribution standars and Hz for all the rest",
663           0, G_MAXUINT, DEFAULT_FREQUENCY,
664           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
665 
666   g_object_class_install_property (gobject_class, ARG_DVBSRC_POLARITY,
667       g_param_spec_string ("polarity", "polarity",
668           "(DVB-S/S2) Polarity [vhHV] (eg. V for Vertical)",
669           DEFAULT_POLARITY,
670           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
671 
672   g_object_class_install_property (gobject_class, ARG_DVBSRC_PIDS,
673       g_param_spec_string ("pids", "pids",
674           "Colon-separated list of PIDs (eg. 110:120) to capture. ACT and CAT "
675           "are automatically included but PMT should be added explicitly. "
676           "Special value 8192 gets full MPEG-TS",
677           DEFAULT_PIDS, GST_PARAM_MUTABLE_PLAYING | G_PARAM_WRITABLE));
678 
679   g_object_class_install_property (gobject_class, ARG_DVBSRC_SYM_RATE,
680       g_param_spec_uint ("symbol-rate",
681           "symbol rate",
682           "(DVB-S/S2, DVB-C) Symbol rate in kBd (kilo bauds)",
683           0, G_MAXUINT, DEFAULT_SYMBOL_RATE,
684           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
685 
686   g_object_class_install_property (gobject_class, ARG_DVBSRC_TUNE,
687       g_param_spec_pointer ("tune",
688           "tune", "Atomically tune to channel. (For Apps)", G_PARAM_WRITABLE));
689 
690   g_object_class_install_property (gobject_class, ARG_DVBSRC_DISEQC_SRC,
691       g_param_spec_int ("diseqc-source",
692           "diseqc source",
693           "(DVB-S/S2) Selected DiSEqC source. Only needed if you have a "
694           "DiSEqC switch. Otherwise leave at -1 (disabled)", -1, 7,
695           DEFAULT_DISEQC_SRC, GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
696 
697   g_object_class_install_property (gobject_class, ARG_DVBSRC_BANDWIDTH_HZ,
698       g_param_spec_uint ("bandwidth-hz", "bandwidth-hz",
699           "Channel bandwidth in Hz", 0, G_MAXUINT, DEFAULT_BANDWIDTH_HZ,
700           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
701 
702 #ifndef GST_REMOVE_DEPRECATED
703   g_object_class_install_property (gobject_class, ARG_DVBSRC_BANDWIDTH,
704       g_param_spec_enum ("bandwidth", "bandwidth",
705           "(DVB-T) Bandwidth. Deprecated", GST_TYPE_DVBSRC_BANDWIDTH,
706           DEFAULT_BANDWIDTH,
707           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE | G_PARAM_DEPRECATED));
708 #endif
709 
710   /* FIXME: DVB-C, DVB-S, DVB-S2 named it as innerFEC */
711   g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_HP,
712       g_param_spec_enum ("code-rate-hp",
713           "code-rate-hp",
714           "(DVB-T, DVB-S/S2 and DVB-C) High priority code rate",
715           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_CODE_RATE_HP,
716           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
717 
718   g_object_class_install_property (gobject_class, ARG_DVBSRC_CODE_RATE_LP,
719       g_param_spec_enum ("code-rate-lp",
720           "code-rate-lp",
721           "(DVB-T) Low priority code rate",
722           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_CODE_RATE_LP,
723           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
724 
725   /* FIXME: should the property be called 'guard-interval' then? */
726   g_object_class_install_property (gobject_class, ARG_DVBSRC_GUARD,
727       g_param_spec_enum ("guard",
728           "guard",
729           "(DVB-T) Guard Interval",
730           GST_TYPE_DVBSRC_GUARD, DEFAULT_GUARD,
731           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
732 
733   g_object_class_install_property (gobject_class, ARG_DVBSRC_MODULATION,
734       g_param_spec_enum ("modulation", "modulation",
735           "(DVB-T/T2/C/S2, TURBO and ATSC) Modulation type",
736           GST_TYPE_DVBSRC_MODULATION, DEFAULT_MODULATION,
737           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
738 
739   /* FIXME: property should be named 'transmission-mode' */
740   g_object_class_install_property (gobject_class,
741       ARG_DVBSRC_TRANSMISSION_MODE,
742       g_param_spec_enum ("trans-mode", "trans-mode",
743           "(DVB-T) Transmission mode",
744           GST_TYPE_DVBSRC_TRANSMISSION_MODE, DEFAULT_TRANSMISSION_MODE,
745           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
746 
747   g_object_class_install_property (gobject_class, ARG_DVBSRC_HIERARCHY_INF,
748       g_param_spec_enum ("hierarchy", "hierarchy",
749           "(DVB-T) Hierarchy information",
750           GST_TYPE_DVBSRC_HIERARCHY, DEFAULT_HIERARCHY,
751           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
752 
753   g_object_class_install_property (gobject_class, ARG_DVBSRC_INVERSION,
754       g_param_spec_enum ("inversion", "inversion",
755           "(DVB-T and DVB-C) Inversion information",
756           GST_TYPE_DVBSRC_INVERSION, DEFAULT_INVERSION,
757           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
758 
759   g_object_class_install_property (gobject_class,
760       ARG_DVBSRC_STATS_REPORTING_INTERVAL,
761       g_param_spec_uint ("stats-reporting-interval",
762           "stats-reporting-interval",
763           "The number of reads before reporting frontend stats",
764           0, G_MAXUINT, DEFAULT_STATS_REPORTING_INTERVAL,
765           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
766 
767   g_object_class_install_property (gobject_class, ARG_DVBSRC_TIMEOUT,
768       g_param_spec_uint64 ("timeout", "Timeout",
769           "Post a message after timeout microseconds (0 = disabled)",
770           0, G_MAXUINT64, DEFAULT_TIMEOUT, G_PARAM_READWRITE));
771 
772   g_object_class_install_property (gobject_class, ARG_DVBSRC_TUNING_TIMEOUT,
773       g_param_spec_uint64 ("tuning-timeout", "Tuning Timeout",
774           "Microseconds to wait before giving up tuning/locking on a signal",
775           0, G_MAXUINT64, DEFAULT_TUNING_TIMEOUT,
776           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
777 
778   g_object_class_install_property (gobject_class,
779       ARG_DVBSRC_DVB_BUFFER_SIZE,
780       g_param_spec_uint ("dvb-buffer-size",
781           "dvb-buffer-size",
782           "The kernel buffer size used by the DVB api",
783           0, G_MAXUINT, DEFAULT_DVB_BUFFER_SIZE, G_PARAM_READWRITE));
784 
785   g_object_class_install_property (gobject_class, ARG_DVBSRC_DELSYS,
786       g_param_spec_enum ("delsys", "delsys", "Delivery System",
787           GST_TYPE_DVBSRC_DELSYS, DEFAULT_DELSYS, G_PARAM_READWRITE));
788 
789   g_object_class_install_property (gobject_class, ARG_DVBSRC_PILOT,
790       g_param_spec_enum ("pilot", "pilot", "Pilot (DVB-S2)",
791           GST_TYPE_DVBSRC_PILOT, DEFAULT_PILOT,
792           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
793 
794   g_object_class_install_property (gobject_class, ARG_DVBSRC_ROLLOFF,
795       g_param_spec_enum ("rolloff", "rolloff", "Rolloff (DVB-S2)",
796           GST_TYPE_DVBSRC_ROLLOFF, DEFAULT_ROLLOFF,
797           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
798 
799   g_object_class_install_property (gobject_class, ARG_DVBSRC_STREAM_ID,
800       g_param_spec_int ("stream-id", "stream-id",
801           "(DVB-T2 and DVB-S2 max 255, ISDB max 65535) Stream ID "
802           "(-1 = disabled)", -1, 65535, DEFAULT_STREAM_ID,
803           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
804 
805   /* Additional ISDB-T properties */
806 
807   /* Valid values are 0x1 0x2 0x4 |-ables */
808   g_object_class_install_property (gobject_class,
809       ARG_DVBSRC_ISDBT_LAYER_ENABLED,
810       g_param_spec_uint ("isdbt-layer-enabled",
811           "ISDB-T layer enabled",
812           "(ISDB-T) Layer Enabled (7 = All layers)", 1, 7,
813           DEFAULT_ISDBT_LAYER_ENABLED,
814           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
815 
816   g_object_class_install_property (gobject_class,
817       ARG_DVBSRC_ISDBT_PARTIAL_RECEPTION,
818       g_param_spec_int ("isdbt-partial-reception",
819           "ISDB-T partial reception",
820           "(ISDB-T) Partial Reception (-1 = AUTO)", -1, 1,
821           DEFAULT_ISDBT_PARTIAL_RECEPTION,
822           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
823 
824   g_object_class_install_property (gobject_class,
825       ARG_DVBSRC_ISDBT_SOUND_BROADCASTING,
826       g_param_spec_int ("isdbt-sound-broadcasting",
827           "ISDB-T sound broadcasting",
828           "(ISDB-T) Sound Broadcasting", 0, 1,
829           DEFAULT_ISDBT_SOUND_BROADCASTING,
830           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
831 
832   g_object_class_install_property (gobject_class,
833       ARG_DVBSRC_ISDBT_SB_SUBCHANNEL_ID,
834       g_param_spec_int ("isdbt-sb-subchannel-id",
835           "ISDB-T SB subchannel ID",
836           "(ISDB-T) SB Subchannel ID (-1 = AUTO)", -1, 41,
837           DEFAULT_ISDBT_SB_SEGMENT_IDX,
838           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
839 
840   g_object_class_install_property (gobject_class,
841       ARG_DVBSRC_ISDBT_SB_SEGMENT_IDX,
842       g_param_spec_int ("isdbt-sb-segment-idx",
843           "ISDB-T SB segment IDX",
844           "(ISDB-T) SB segment IDX", 0, 12,
845           DEFAULT_ISDBT_SB_SEGMENT_IDX,
846           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
847 
848   g_object_class_install_property (gobject_class,
849       ARG_DVBSRC_ISDBT_SB_SEGMENT_COUNT,
850       g_param_spec_uint ("isdbt-sb-segment-count",
851           "ISDB-T SB segment count",
852           "(ISDB-T) SB segment count", 1, 13,
853           DEFAULT_ISDBT_SB_SEGMENT_COUNT,
854           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
855 
856   g_object_class_install_property (gobject_class, ARG_DVBSRC_ISDBT_LAYERA_FEC,
857       g_param_spec_enum ("isdbt-layera-fec",
858           "ISDB-T layer A FEC", "(ISDB-T) layer A Forward Error Correction",
859           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_ISDBT_LAYERA_FEC,
860           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
861 
862   g_object_class_install_property (gobject_class, ARG_DVBSRC_ISDBT_LAYERB_FEC,
863       g_param_spec_enum ("isdbt-layerb-fec",
864           "ISDB-T layer B FEC", "(ISDB-T) layer B Forward Error Correction",
865           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_ISDBT_LAYERB_FEC,
866           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
867 
868   g_object_class_install_property (gobject_class, ARG_DVBSRC_ISDBT_LAYERC_FEC,
869       g_param_spec_enum ("isdbt-layerc-fec",
870           "ISDB-T layer A FEC", "(ISDB-T) layer C Forward Error Correction",
871           GST_TYPE_DVBSRC_CODE_RATE, DEFAULT_ISDBT_LAYERC_FEC,
872           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
873 
874   g_object_class_install_property (gobject_class,
875       ARG_DVBSRC_ISDBT_LAYERA_MODULATION,
876       g_param_spec_enum ("isdbt-layera-modulation", "ISDBT layer A modulation",
877           "(ISDB-T) Layer A modulation type",
878           GST_TYPE_DVBSRC_MODULATION, DEFAULT_ISDBT_LAYERA_MODULATION,
879           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
880 
881   g_object_class_install_property (gobject_class,
882       ARG_DVBSRC_ISDBT_LAYERB_MODULATION,
883       g_param_spec_enum ("isdbt-layerb-modulation", "ISDBT layer B modulation",
884           "(ISDB-T) Layer B modulation type",
885           GST_TYPE_DVBSRC_MODULATION, DEFAULT_ISDBT_LAYERB_MODULATION,
886           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
887 
888   g_object_class_install_property (gobject_class,
889       ARG_DVBSRC_ISDBT_LAYERC_MODULATION,
890       g_param_spec_enum ("isdbt-layerc-modulation", "ISDBT layer C modulation",
891           "(ISDB-T) Layer C modulation type",
892           GST_TYPE_DVBSRC_MODULATION, DEFAULT_ISDBT_LAYERC_MODULATION,
893           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
894 
895   g_object_class_install_property (gobject_class,
896       ARG_DVBSRC_ISDBT_LAYERA_SEGMENT_COUNT,
897       g_param_spec_int ("isdbt-layera-segment-count",
898           "ISDB-T layer A segment count",
899           "(ISDB-T) Layer A segment count (-1 = AUTO)", -1, 13,
900           DEFAULT_ISDBT_LAYERA_SEGMENT_COUNT,
901           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
902 
903   g_object_class_install_property (gobject_class,
904       ARG_DVBSRC_ISDBT_LAYERB_SEGMENT_COUNT,
905       g_param_spec_int ("isdbt-layerb-segment-count",
906           "ISDB-T layer B segment count",
907           "(ISDB-T) Layer B segment count (-1 = AUTO)", -1, 13,
908           DEFAULT_ISDBT_LAYERB_SEGMENT_COUNT,
909           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
910 
911   g_object_class_install_property (gobject_class,
912       ARG_DVBSRC_ISDBT_LAYERC_SEGMENT_COUNT,
913       g_param_spec_int ("isdbt-layerc-segment-count",
914           "ISDB-T layer C segment count",
915           "(ISDB-T) Layer C segment count (-1 = AUTO)", -1, 13,
916           DEFAULT_ISDBT_LAYERC_SEGMENT_COUNT,
917           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
918 
919   g_object_class_install_property (gobject_class,
920       ARG_DVBSRC_ISDBT_LAYERA_TIME_INTERLEAVING,
921       g_param_spec_int ("isdbt-layera-time-interleaving",
922           "ISDB-T layer A time interleaving",
923           "(ISDB-T) Layer A time interleaving (-1 = AUTO)", -1, 8,
924           DEFAULT_ISDBT_LAYERA_TIME_INTERLEAVING,
925           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
926 
927   g_object_class_install_property (gobject_class,
928       ARG_DVBSRC_ISDBT_LAYERB_TIME_INTERLEAVING,
929       g_param_spec_int ("isdbt-layerb-time-interleaving",
930           "ISDB-T layer B time interleaving",
931           "(ISDB-T) Layer B time interleaving (-1 = AUTO)", -1, 8,
932           DEFAULT_ISDBT_LAYERB_TIME_INTERLEAVING,
933           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
934 
935   g_object_class_install_property (gobject_class,
936       ARG_DVBSRC_ISDBT_LAYERC_TIME_INTERLEAVING,
937       g_param_spec_int ("isdbt-layerc-time-interleaving",
938           "ISDB-T layer C time interleaving",
939           "(ISDB-T) Layer C time interleaving (-1 = AUTO)", -1, 8,
940           DEFAULT_ISDBT_LAYERC_TIME_INTERLEAVING,
941           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
942 
943   /* LNB properties (Satellite distribution standards) */
944 
945   g_object_class_install_property (gobject_class, ARG_DVBSRC_LNB_SLOF,
946       g_param_spec_uint ("lnb-slof", "Tuning Timeout",
947           "LNB's Upper bound for low band reception (kHz)",
948           0, G_MAXUINT, DEFAULT_LNB_SLOF,
949           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
950 
951   g_object_class_install_property (gobject_class, ARG_DVBSRC_LNB_LOF1,
952       g_param_spec_uint ("lnb-lof1", "Low band local oscillator frequency",
953           "LNB's Local oscillator frequency used for low band reception (kHz)",
954           0, G_MAXUINT, DEFAULT_LNB_LOF1,
955           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
956 
957   g_object_class_install_property (gobject_class, ARG_DVBSRC_LNB_LOF2,
958       g_param_spec_uint ("lnb-lof2", "High band local oscillator frequency",
959           "LNB's Local oscillator frequency used for high band reception (kHz)",
960           0, G_MAXUINT, DEFAULT_LNB_LOF2,
961           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
962 
963   /* Additional DTMB properties */
964 
965   g_object_class_install_property (gobject_class,
966       ARG_DVBSRC_INTERLEAVING,
967       g_param_spec_enum ("interleaving", "DTMB Interleaving",
968           "(DTMB) Interleaving type",
969           GST_TYPE_INTERLEAVING, DEFAULT_INTERLEAVING,
970           GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE));
971 
972   /**
973    * GstDvbSrc::tuning-start:
974    * @gstdvbsrc: the element on which the signal is emitted
975    *
976    * Signal emited when the element first attempts to tune the
977    * frontend tunner to a given frequency.
978    */
979   gst_dvbsrc_signals[SIGNAL_TUNING_START] =
980       g_signal_new ("tuning-start", G_TYPE_FROM_CLASS (klass),
981       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
982   /**
983    * GstDvbSrc::tuning-done:
984    * @gstdvbsrc: the element on which the signal is emitted
985    *
986    * Signal emited when the tunner has successfully got a lock on a signal.
987    */
988   gst_dvbsrc_signals[SIGNAL_TUNING_DONE] =
989       g_signal_new ("tuning-done", G_TYPE_FROM_CLASS (klass),
990       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
991   /**
992    * GstDvbSrc::tuning-fail:
993    * @gstdvbsrc: the element on which the signal is emitted
994    *
995    * Signal emited when the tunner failed to get a lock on the
996    * signal.
997    */
998   gst_dvbsrc_signals[SIGNAL_TUNING_FAIL] =
999       g_signal_new ("tuning-fail", G_TYPE_FROM_CLASS (klass),
1000       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
1001 
1002   /**
1003    * GstDvbSrc::tune:
1004    * @gstdvbsrc: the element on which the signal is emitted
1005    *
1006    * Signal emited from the application to the element, instructing it
1007    * to tune.
1008    */
1009   gst_dvbsrc_signals[SIGNAL_TUNE] =
1010       g_signal_new ("tune", G_TYPE_FROM_CLASS (klass),
1011       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1012       G_STRUCT_OFFSET (GstDvbSrcClass, do_tune),
1013       NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
1014 
1015 }
1016 
1017 /* initialize the new element
1018  * instantiate pads and add them to element
1019  * set functions
1020  * initialize structure
1021  */
1022 static void
gst_dvbsrc_init(GstDvbSrc * object)1023 gst_dvbsrc_init (GstDvbSrc * object)
1024 {
1025   int i = 0;
1026   const gchar *adapter;
1027 
1028   GST_DEBUG_OBJECT (object, "Kernel DVB API version %d.%d", DVB_API_VERSION,
1029       DVB_API_VERSION_MINOR);
1030 
1031   /* We are a live source */
1032   gst_base_src_set_live (GST_BASE_SRC (object), TRUE);
1033   /* And we wanted timestamped output */
1034   gst_base_src_set_do_timestamp (GST_BASE_SRC (object), TRUE);
1035   gst_base_src_set_format (GST_BASE_SRC (object), GST_FORMAT_TIME);
1036 
1037   object->fd_frontend = -1;
1038   object->fd_dvr = -1;
1039   object->supported_delsys = NULL;
1040 
1041   for (i = 0; i < MAX_FILTERS; i++) {
1042     object->fd_filters[i] = -1;
1043   }
1044 
1045   /* PID 8192 on DVB gets the whole transport stream */
1046   object->pids[0] = 8192;
1047   object->pids[1] = G_MAXUINT16;
1048   object->dvb_buffer_size = DEFAULT_DVB_BUFFER_SIZE;
1049 
1050   adapter = g_getenv ("GST_DVB_ADAPTER");
1051   if (adapter)
1052     object->adapter_number = atoi (adapter);
1053   else
1054     object->adapter_number = DEFAULT_ADAPTER;
1055 
1056   object->frontend_number = DEFAULT_FRONTEND;
1057   object->diseqc_src = DEFAULT_DISEQC_SRC;
1058   object->send_diseqc = (DEFAULT_DISEQC_SRC != -1);
1059   object->tone = SEC_TONE_OFF;
1060   /* object->pol = DVB_POL_H; *//* set via G_PARAM_CONSTRUCT */
1061   object->sym_rate = DEFAULT_SYMBOL_RATE;
1062   object->bandwidth = DEFAULT_BANDWIDTH;
1063   object->code_rate_hp = DEFAULT_CODE_RATE_HP;
1064   object->code_rate_lp = DEFAULT_CODE_RATE_LP;
1065   object->guard_interval = DEFAULT_GUARD;
1066   object->modulation = DEFAULT_MODULATION;
1067   object->transmission_mode = DEFAULT_TRANSMISSION_MODE;
1068   object->hierarchy_information = DEFAULT_HIERARCHY;
1069   object->inversion = DEFAULT_INVERSION;
1070   object->stats_interval = DEFAULT_STATS_REPORTING_INTERVAL;
1071   object->delsys = DEFAULT_DELSYS;
1072   object->pilot = DEFAULT_PILOT;
1073   object->rolloff = DEFAULT_ROLLOFF;
1074   object->stream_id = DEFAULT_STREAM_ID;
1075 
1076   object->isdbt_layer_enabled = DEFAULT_ISDBT_LAYER_ENABLED;
1077   object->isdbt_partial_reception = DEFAULT_ISDBT_PARTIAL_RECEPTION;
1078   object->isdbt_sound_broadcasting = DEFAULT_ISDBT_SOUND_BROADCASTING;
1079   object->isdbt_sb_subchannel_id = DEFAULT_ISDBT_SB_SUBCHANNEL_ID;
1080   object->isdbt_sb_segment_idx = DEFAULT_ISDBT_SB_SEGMENT_IDX;
1081   object->isdbt_sb_segment_count = DEFAULT_ISDBT_SB_SEGMENT_COUNT;
1082   object->isdbt_layera_fec = DEFAULT_ISDBT_LAYERA_FEC;
1083   object->isdbt_layera_modulation = DEFAULT_ISDBT_LAYERA_MODULATION;
1084   object->isdbt_layera_segment_count = DEFAULT_ISDBT_LAYERA_SEGMENT_COUNT;
1085   object->isdbt_layera_time_interleaving =
1086       DEFAULT_ISDBT_LAYERA_TIME_INTERLEAVING;
1087   object->isdbt_layerb_fec = DEFAULT_ISDBT_LAYERB_FEC;
1088   object->isdbt_layerb_modulation = DEFAULT_ISDBT_LAYERB_MODULATION;
1089   object->isdbt_layerb_segment_count = DEFAULT_ISDBT_LAYERB_SEGMENT_COUNT;
1090   object->isdbt_layerb_time_interleaving =
1091       DEFAULT_ISDBT_LAYERB_TIME_INTERLEAVING;
1092   object->isdbt_layerc_fec = DEFAULT_ISDBT_LAYERC_FEC;
1093   object->isdbt_layerc_modulation = DEFAULT_ISDBT_LAYERC_MODULATION;
1094   object->isdbt_layerc_segment_count = DEFAULT_ISDBT_LAYERC_SEGMENT_COUNT;
1095   object->isdbt_layerc_time_interleaving =
1096       DEFAULT_ISDBT_LAYERC_TIME_INTERLEAVING;
1097 
1098   object->lnb_slof = DEFAULT_LNB_SLOF;
1099   object->lnb_lof1 = DEFAULT_LNB_LOF1;
1100   object->lnb_lof2 = DEFAULT_LNB_LOF2;
1101 
1102   object->interleaving = DEFAULT_INTERLEAVING;
1103 
1104   g_mutex_init (&object->tune_mutex);
1105   object->timeout = DEFAULT_TIMEOUT;
1106   object->tuning_timeout = DEFAULT_TUNING_TIMEOUT;
1107 }
1108 
1109 static void
gst_dvbsrc_set_pids(GstDvbSrc * dvbsrc,const gchar * pid_string)1110 gst_dvbsrc_set_pids (GstDvbSrc * dvbsrc, const gchar * pid_string)
1111 {
1112   int pid = 0;
1113   int pid_count;
1114   gchar **pids;
1115   char **tmp;
1116 
1117   if (!strcmp (pid_string, "8192")) {
1118     /* get the whole TS */
1119     dvbsrc->pids[0] = 8192;
1120     dvbsrc->pids[1] = G_MAXUINT16;
1121     goto done;
1122   }
1123 
1124   /* always add the PAT and CAT pids */
1125   dvbsrc->pids[0] = 0;
1126   dvbsrc->pids[1] = 1;
1127   pid_count = 2;
1128 
1129   tmp = pids = g_strsplit (pid_string, ":", MAX_FILTERS);
1130 
1131   while (*pids != NULL && pid_count < MAX_FILTERS) {
1132     pid = strtol (*pids, NULL, 0);
1133     if (pid > 1 && pid <= 8192) {
1134       GST_INFO_OBJECT (dvbsrc, "Parsed PID: %d", pid);
1135       dvbsrc->pids[pid_count] = pid;
1136       pid_count++;
1137     }
1138     pids++;
1139   }
1140 
1141   g_strfreev (tmp);
1142 
1143   if (pid_count < MAX_FILTERS)
1144     dvbsrc->pids[pid_count] = G_MAXUINT16;
1145 
1146 done:
1147   if (GST_ELEMENT (dvbsrc)->current_state > GST_STATE_READY) {
1148     GST_INFO_OBJECT (dvbsrc, "Setting PES filters now");
1149     gst_dvbsrc_set_pes_filters (dvbsrc);
1150   } else
1151     GST_INFO_OBJECT (dvbsrc, "Not setting PES filters because state < PAUSED");
1152 }
1153 
1154 static void
gst_dvbsrc_set_property(GObject * _object,guint prop_id,const GValue * value,GParamSpec * pspec)1155 gst_dvbsrc_set_property (GObject * _object, guint prop_id,
1156     const GValue * value, GParamSpec * pspec)
1157 {
1158   GstDvbSrc *object;
1159 
1160   g_return_if_fail (GST_IS_DVBSRC (_object));
1161   object = GST_DVBSRC (_object);
1162 
1163   switch (prop_id) {
1164     case ARG_DVBSRC_ADAPTER:
1165       object->adapter_number = g_value_get_int (value);
1166       break;
1167     case ARG_DVBSRC_FRONTEND:
1168       object->frontend_number = g_value_get_int (value);
1169       break;
1170     case ARG_DVBSRC_DISEQC_SRC:
1171       if (object->diseqc_src != g_value_get_int (value)) {
1172         object->diseqc_src = g_value_get_int (value);
1173         object->send_diseqc = TRUE;
1174       }
1175       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_DISEQC_ID");
1176       break;
1177     case ARG_DVBSRC_FREQUENCY:
1178       object->freq = g_value_get_uint (value);
1179       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_FREQUENCY (%d Hz)",
1180           object->freq);
1181       break;
1182     case ARG_DVBSRC_POLARITY:
1183     {
1184       const char *s = NULL;
1185 
1186       s = g_value_get_string (value);
1187       if (s != NULL) {
1188         object->pol = (s[0] == 'h' || s[0] == 'H') ? DVB_POL_H : DVB_POL_V;
1189         GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_POLARITY to %s",
1190             object->pol ? "Vertical" : "Horizontal");
1191       }
1192       break;
1193     }
1194     case ARG_DVBSRC_PIDS:
1195     {
1196       const gchar *pid_string;
1197 
1198       pid_string = g_value_get_string (value);
1199       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_PIDS %s", pid_string);
1200       if (pid_string)
1201         gst_dvbsrc_set_pids (object, pid_string);
1202       break;
1203     }
1204     case ARG_DVBSRC_SYM_RATE:
1205       object->sym_rate = g_value_get_uint (value);
1206       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_SYM_RATE to value %d",
1207           object->sym_rate);
1208       break;
1209 
1210     case ARG_DVBSRC_BANDWIDTH_HZ:
1211       object->bandwidth = g_value_get_uint (value);
1212       break;
1213     case ARG_DVBSRC_BANDWIDTH:
1214       switch (g_value_get_enum (value)) {
1215         case BANDWIDTH_8_MHZ:
1216           object->bandwidth = 8000000;
1217           break;
1218         case BANDWIDTH_7_MHZ:
1219           object->bandwidth = 7000000;
1220           break;
1221         case BANDWIDTH_6_MHZ:
1222           object->bandwidth = 6000000;
1223           break;
1224         case BANDWIDTH_5_MHZ:
1225           object->bandwidth = 5000000;
1226           break;
1227         case BANDWIDTH_10_MHZ:
1228           object->bandwidth = 10000000;
1229           break;
1230         case BANDWIDTH_1_712_MHZ:
1231           object->bandwidth = 1712000;
1232           break;
1233         default:
1234           /* we don't know which bandwidth is set */
1235           object->bandwidth = 0;
1236           break;
1237       }
1238       break;
1239     case ARG_DVBSRC_CODE_RATE_HP:
1240       object->code_rate_hp = g_value_get_enum (value);
1241       break;
1242     case ARG_DVBSRC_CODE_RATE_LP:
1243       object->code_rate_lp = g_value_get_enum (value);
1244       break;
1245     case ARG_DVBSRC_GUARD:
1246       object->guard_interval = g_value_get_enum (value);
1247       break;
1248     case ARG_DVBSRC_MODULATION:
1249       object->modulation = g_value_get_enum (value);
1250       break;
1251     case ARG_DVBSRC_TRANSMISSION_MODE:
1252       object->transmission_mode = g_value_get_enum (value);
1253       break;
1254     case ARG_DVBSRC_HIERARCHY_INF:
1255       object->hierarchy_information = g_value_get_enum (value);
1256       break;
1257     case ARG_DVBSRC_INVERSION:
1258       object->inversion = g_value_get_enum (value);
1259       break;
1260     case ARG_DVBSRC_TUNE:
1261       GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_TUNE");
1262       gst_dvbsrc_do_tune (object);
1263       break;
1264     case ARG_DVBSRC_STATS_REPORTING_INTERVAL:
1265       object->stats_interval = g_value_get_uint (value);
1266       object->stats_counter = 0;
1267       break;
1268     case ARG_DVBSRC_TIMEOUT:
1269       object->timeout = g_value_get_uint64 (value);
1270       break;
1271     case ARG_DVBSRC_TUNING_TIMEOUT:
1272       object->tuning_timeout = g_value_get_uint64 (value);
1273       break;
1274     case ARG_DVBSRC_DVB_BUFFER_SIZE:
1275       object->dvb_buffer_size = g_value_get_uint (value);
1276       break;
1277     case ARG_DVBSRC_DELSYS:
1278       object->delsys = g_value_get_enum (value);
1279       break;
1280     case ARG_DVBSRC_PILOT:
1281       object->pilot = g_value_get_enum (value);
1282       break;
1283     case ARG_DVBSRC_ROLLOFF:
1284       object->rolloff = g_value_get_enum (value);
1285       break;
1286     case ARG_DVBSRC_STREAM_ID:
1287       object->stream_id = g_value_get_int (value);
1288       break;
1289     case ARG_DVBSRC_ISDBT_LAYER_ENABLED:
1290       object->isdbt_layer_enabled = g_value_get_uint (value);
1291       break;
1292     case ARG_DVBSRC_ISDBT_PARTIAL_RECEPTION:
1293       object->isdbt_partial_reception = g_value_get_int (value);
1294       break;
1295     case ARG_DVBSRC_ISDBT_SOUND_BROADCASTING:
1296       object->isdbt_sound_broadcasting = g_value_get_int (value);
1297       break;
1298     case ARG_DVBSRC_ISDBT_SB_SUBCHANNEL_ID:
1299       object->isdbt_sb_subchannel_id = g_value_get_int (value);
1300       break;
1301     case ARG_DVBSRC_ISDBT_SB_SEGMENT_IDX:
1302       object->isdbt_sb_segment_idx = g_value_get_int (value);
1303       break;
1304     case ARG_DVBSRC_ISDBT_SB_SEGMENT_COUNT:
1305       object->isdbt_sb_segment_count = g_value_get_uint (value);
1306       break;
1307     case ARG_DVBSRC_ISDBT_LAYERA_FEC:
1308       object->isdbt_layera_fec = g_value_get_enum (value);
1309       break;
1310     case ARG_DVBSRC_ISDBT_LAYERA_MODULATION:
1311       object->isdbt_layera_modulation = g_value_get_enum (value);
1312       break;
1313     case ARG_DVBSRC_ISDBT_LAYERA_SEGMENT_COUNT:
1314       object->isdbt_layera_segment_count = g_value_get_int (value);
1315       break;
1316     case ARG_DVBSRC_ISDBT_LAYERA_TIME_INTERLEAVING:
1317       object->isdbt_layera_time_interleaving = g_value_get_int (value);
1318       break;
1319     case ARG_DVBSRC_ISDBT_LAYERB_FEC:
1320       object->isdbt_layerb_fec = g_value_get_enum (value);
1321       break;
1322     case ARG_DVBSRC_ISDBT_LAYERB_MODULATION:
1323       object->isdbt_layerb_modulation = g_value_get_enum (value);
1324       break;
1325     case ARG_DVBSRC_ISDBT_LAYERB_SEGMENT_COUNT:
1326       object->isdbt_layerb_segment_count = g_value_get_int (value);
1327       break;
1328     case ARG_DVBSRC_ISDBT_LAYERB_TIME_INTERLEAVING:
1329       object->isdbt_layerb_time_interleaving = g_value_get_int (value);
1330       break;
1331     case ARG_DVBSRC_ISDBT_LAYERC_FEC:
1332       object->isdbt_layerc_fec = g_value_get_enum (value);
1333       break;
1334     case ARG_DVBSRC_ISDBT_LAYERC_MODULATION:
1335       object->isdbt_layerc_modulation = g_value_get_enum (value);
1336       break;
1337     case ARG_DVBSRC_ISDBT_LAYERC_SEGMENT_COUNT:
1338       object->isdbt_layerc_segment_count = g_value_get_int (value);
1339       break;
1340     case ARG_DVBSRC_ISDBT_LAYERC_TIME_INTERLEAVING:
1341       object->isdbt_layerc_time_interleaving = g_value_get_int (value);
1342       break;
1343     case ARG_DVBSRC_LNB_SLOF:
1344       object->lnb_slof = g_value_get_uint (value);
1345       break;
1346     case ARG_DVBSRC_LNB_LOF1:
1347       object->lnb_lof1 = g_value_get_uint (value);
1348       break;
1349     case ARG_DVBSRC_LNB_LOF2:
1350       object->lnb_lof2 = g_value_get_uint (value);
1351       break;
1352     case ARG_DVBSRC_INTERLEAVING:
1353       object->interleaving = g_value_get_enum (value);
1354       break;
1355     default:
1356       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1357   }
1358 }
1359 
1360 static void
gst_dvbsrc_get_property(GObject * _object,guint prop_id,GValue * value,GParamSpec * pspec)1361 gst_dvbsrc_get_property (GObject * _object, guint prop_id,
1362     GValue * value, GParamSpec * pspec)
1363 {
1364   GstDvbSrc *object;
1365 
1366   g_return_if_fail (GST_IS_DVBSRC (_object));
1367   object = GST_DVBSRC (_object);
1368 
1369   switch (prop_id) {
1370     case ARG_DVBSRC_ADAPTER:
1371       g_value_set_int (value, object->adapter_number);
1372       break;
1373     case ARG_DVBSRC_FRONTEND:
1374       g_value_set_int (value, object->frontend_number);
1375       break;
1376     case ARG_DVBSRC_FREQUENCY:
1377       g_value_set_uint (value, object->freq);
1378       break;
1379     case ARG_DVBSRC_POLARITY:
1380       if (object->pol == DVB_POL_H)
1381         g_value_set_static_string (value, "H");
1382       else
1383         g_value_set_static_string (value, "V");
1384       break;
1385     case ARG_DVBSRC_SYM_RATE:
1386       g_value_set_uint (value, object->sym_rate);
1387       break;
1388     case ARG_DVBSRC_DISEQC_SRC:
1389       g_value_set_int (value, object->diseqc_src);
1390       break;
1391     case ARG_DVBSRC_BANDWIDTH_HZ:
1392       g_value_set_uint (value, object->bandwidth);
1393       break;
1394     case ARG_DVBSRC_BANDWIDTH:{
1395       int tmp;
1396       if (!object->bandwidth)
1397         tmp = BANDWIDTH_AUTO;
1398       else if (object->bandwidth <= 1712000)
1399         tmp = BANDWIDTH_1_712_MHZ;
1400       else if (object->bandwidth <= 5000000)
1401         tmp = BANDWIDTH_5_MHZ;
1402       else if (object->bandwidth <= 6000000)
1403         tmp = BANDWIDTH_6_MHZ;
1404       else if (object->bandwidth <= 7000000)
1405         tmp = BANDWIDTH_7_MHZ;
1406       else if (object->bandwidth <= 8000000)
1407         tmp = BANDWIDTH_8_MHZ;
1408       else if (object->bandwidth <= 10000000)
1409         tmp = BANDWIDTH_10_MHZ;
1410       else
1411         tmp = BANDWIDTH_AUTO;
1412 
1413       g_value_set_enum (value, tmp);
1414       break;
1415     }
1416     case ARG_DVBSRC_CODE_RATE_HP:
1417       g_value_set_enum (value, object->code_rate_hp);
1418       break;
1419     case ARG_DVBSRC_CODE_RATE_LP:
1420       g_value_set_enum (value, object->code_rate_lp);
1421       break;
1422     case ARG_DVBSRC_GUARD:
1423       g_value_set_enum (value, object->guard_interval);
1424       break;
1425     case ARG_DVBSRC_MODULATION:
1426       g_value_set_enum (value, object->modulation);
1427       break;
1428     case ARG_DVBSRC_TRANSMISSION_MODE:
1429       g_value_set_enum (value, object->transmission_mode);
1430       break;
1431     case ARG_DVBSRC_HIERARCHY_INF:
1432       g_value_set_enum (value, object->hierarchy_information);
1433       break;
1434     case ARG_DVBSRC_INVERSION:
1435       g_value_set_enum (value, object->inversion);
1436       break;
1437     case ARG_DVBSRC_STATS_REPORTING_INTERVAL:
1438       g_value_set_uint (value, object->stats_interval);
1439       break;
1440     case ARG_DVBSRC_TIMEOUT:
1441       g_value_set_uint64 (value, object->timeout);
1442       break;
1443     case ARG_DVBSRC_TUNING_TIMEOUT:
1444       g_value_set_uint64 (value, object->tuning_timeout);
1445       break;
1446     case ARG_DVBSRC_DVB_BUFFER_SIZE:
1447       g_value_set_uint (value, object->dvb_buffer_size);
1448       break;
1449     case ARG_DVBSRC_DELSYS:
1450       g_value_set_enum (value, object->delsys);
1451       break;
1452     case ARG_DVBSRC_PILOT:
1453       g_value_set_enum (value, object->pilot);
1454       break;
1455     case ARG_DVBSRC_ROLLOFF:
1456       g_value_set_enum (value, object->rolloff);
1457       break;
1458     case ARG_DVBSRC_STREAM_ID:
1459       g_value_set_int (value, object->stream_id);
1460       break;
1461     case ARG_DVBSRC_ISDBT_LAYER_ENABLED:
1462       g_value_set_uint (value, object->isdbt_layer_enabled);
1463       break;
1464     case ARG_DVBSRC_ISDBT_PARTIAL_RECEPTION:
1465       g_value_set_int (value, object->isdbt_partial_reception);
1466       break;
1467     case ARG_DVBSRC_ISDBT_SOUND_BROADCASTING:
1468       g_value_set_int (value, object->isdbt_sound_broadcasting);
1469       break;
1470     case ARG_DVBSRC_ISDBT_SB_SUBCHANNEL_ID:
1471       g_value_set_int (value, object->isdbt_sb_subchannel_id);
1472       break;
1473     case ARG_DVBSRC_ISDBT_SB_SEGMENT_IDX:
1474       g_value_set_int (value, object->isdbt_sb_segment_idx);
1475       break;
1476     case ARG_DVBSRC_ISDBT_SB_SEGMENT_COUNT:
1477       g_value_set_uint (value, object->isdbt_sb_segment_count);
1478       break;
1479     case ARG_DVBSRC_ISDBT_LAYERA_FEC:
1480       g_value_set_enum (value, object->isdbt_layera_fec);
1481       break;
1482     case ARG_DVBSRC_ISDBT_LAYERA_MODULATION:
1483       g_value_set_enum (value, object->isdbt_layera_modulation);
1484       break;
1485     case ARG_DVBSRC_ISDBT_LAYERA_SEGMENT_COUNT:
1486       g_value_set_int (value, object->isdbt_layera_segment_count);
1487       break;
1488     case ARG_DVBSRC_ISDBT_LAYERA_TIME_INTERLEAVING:
1489       g_value_set_int (value, object->isdbt_layera_time_interleaving);
1490       break;
1491     case ARG_DVBSRC_ISDBT_LAYERB_FEC:
1492       g_value_set_enum (value, object->isdbt_layerb_fec);
1493       break;
1494     case ARG_DVBSRC_ISDBT_LAYERB_MODULATION:
1495       g_value_set_enum (value, object->isdbt_layerb_modulation);
1496       break;
1497     case ARG_DVBSRC_ISDBT_LAYERB_SEGMENT_COUNT:
1498       g_value_set_int (value, object->isdbt_layerb_segment_count);
1499       break;
1500     case ARG_DVBSRC_ISDBT_LAYERB_TIME_INTERLEAVING:
1501       g_value_set_int (value, object->isdbt_layerb_time_interleaving);
1502       break;
1503     case ARG_DVBSRC_ISDBT_LAYERC_FEC:
1504       g_value_set_enum (value, object->isdbt_layerc_fec);
1505       break;
1506     case ARG_DVBSRC_ISDBT_LAYERC_MODULATION:
1507       g_value_set_enum (value, object->isdbt_layerc_modulation);
1508       break;
1509     case ARG_DVBSRC_ISDBT_LAYERC_SEGMENT_COUNT:
1510       g_value_set_int (value, object->isdbt_layerc_segment_count);
1511       break;
1512     case ARG_DVBSRC_ISDBT_LAYERC_TIME_INTERLEAVING:
1513       g_value_set_int (value, object->isdbt_layerc_time_interleaving);
1514       break;
1515     case ARG_DVBSRC_LNB_SLOF:
1516       g_value_set_uint (value, object->lnb_slof);
1517       break;
1518     case ARG_DVBSRC_LNB_LOF1:
1519       g_value_set_uint (value, object->lnb_lof1);
1520       break;
1521     case ARG_DVBSRC_LNB_LOF2:
1522       g_value_set_uint (value, object->lnb_lof2);
1523       break;
1524     case ARG_DVBSRC_INTERLEAVING:
1525       g_value_set_enum (value, object->interleaving);
1526       break;
1527     default:
1528       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1529   }
1530 }
1531 
1532 static gboolean
gst_dvbsrc_close_devices(GstDvbSrc * object)1533 gst_dvbsrc_close_devices (GstDvbSrc * object)
1534 {
1535   gst_dvbsrc_unset_pes_filters (object);
1536 
1537   close (object->fd_dvr);
1538   object->fd_dvr = -1;
1539   close (object->fd_frontend);
1540   object->fd_frontend = -1;
1541 
1542   return TRUE;
1543 }
1544 
1545 static gboolean
gst_dvbsrc_check_delsys(struct dtv_property * prop,guchar delsys)1546 gst_dvbsrc_check_delsys (struct dtv_property *prop, guchar delsys)
1547 {
1548   int i;
1549 
1550   for (i = 0; i < prop->u.buffer.len; i++) {
1551     if (prop->u.buffer.data[i] == delsys)
1552       return TRUE;
1553   }
1554   GST_LOG ("Adapter does not support delsys: %d", delsys);
1555   return FALSE;
1556 }
1557 
1558 static gboolean
gst_dvbsrc_open_frontend(GstDvbSrc * object,gboolean writable)1559 gst_dvbsrc_open_frontend (GstDvbSrc * object, gboolean writable)
1560 {
1561   struct dvb_frontend_info fe_info;
1562   struct dtv_properties props;
1563   struct dtv_property dvb_prop[1];
1564   gchar *frontend_dev;
1565   GstStructure *adapter_structure;
1566   char *adapter_name = NULL;
1567   gint err;
1568 
1569   frontend_dev = g_strdup_printf ("/dev/dvb/adapter%d/frontend%d",
1570       object->adapter_number, object->frontend_number);
1571   GST_INFO_OBJECT (object, "Using frontend device: %s", frontend_dev);
1572 
1573   /* open frontend */
1574   LOOP_WHILE_EINTR (object->fd_frontend,
1575       open (frontend_dev, writable ? O_RDWR : O_RDONLY));
1576   if (object->fd_frontend < 0) {
1577     switch (errno) {
1578       case ENOENT:
1579         GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
1580             (_("Device \"%s\" does not exist."), frontend_dev), (NULL));
1581         break;
1582       default:
1583         GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ_WRITE,
1584             (_("Could not open frontend device \"%s\"."), frontend_dev),
1585             GST_ERROR_SYSTEM);
1586         break;
1587     }
1588 
1589     g_free (frontend_dev);
1590     return FALSE;
1591   }
1592 
1593   if (object->supported_delsys)
1594     goto delsys_detection_done;
1595 
1596   /* Perform delivery system autodetection */
1597 
1598   GST_DEBUG_OBJECT (object, "Device opened, querying information");
1599 
1600   LOOP_WHILE_EINTR (err, ioctl (object->fd_frontend, FE_GET_INFO, &fe_info));
1601   if (err) {
1602     GST_ELEMENT_ERROR (object, RESOURCE, SETTINGS,
1603         (_("Could not get settings from frontend device \"%s\"."),
1604             frontend_dev), GST_ERROR_SYSTEM);
1605 
1606     close (object->fd_frontend);
1607     g_free (frontend_dev);
1608     return FALSE;
1609   }
1610 
1611   GST_DEBUG_OBJECT (object, "Get list of supported delivery systems");
1612 
1613   dvb_prop[0].cmd = DTV_ENUM_DELSYS;
1614   props.num = 1;
1615   props.props = dvb_prop;
1616 
1617   LOOP_WHILE_EINTR (err, ioctl (object->fd_frontend, FE_GET_PROPERTY, &props));
1618   if (err) {
1619     GST_ELEMENT_ERROR (object, RESOURCE, SETTINGS,
1620         (_("Cannot enumerate delivery systems from frontend device \"%s\"."),
1621             frontend_dev), GST_ERROR_SYSTEM);
1622 
1623     close (object->fd_frontend);
1624     g_free (frontend_dev);
1625     return FALSE;
1626   }
1627 
1628   GST_INFO_OBJECT (object, "Got information about adapter: %s", fe_info.name);
1629 
1630   adapter_name = g_strdup (fe_info.name);
1631 
1632   adapter_structure = gst_structure_new ("dvb-adapter",
1633       "name", G_TYPE_STRING, adapter_name,
1634       /* Capability supported auto params */
1635       "auto-inversion", G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_INVERSION_AUTO,
1636       "auto-qam", G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_QAM_AUTO,
1637       "auto-transmission-mode", G_TYPE_BOOLEAN,
1638       fe_info.caps & FE_CAN_TRANSMISSION_MODE_AUTO, "auto-guard-interval",
1639       G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_GUARD_INTERVAL_AUTO,
1640       "auto-hierarchy", G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_HIERARCHY_AUTO,
1641       "auto-fec", G_TYPE_BOOLEAN, fe_info.caps & FE_CAN_FEC_AUTO, NULL);
1642 
1643   /* Capability delivery systems */
1644   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBC_ANNEX_A)) {
1645     object->supported_delsys = g_list_append (object->supported_delsys,
1646         GINT_TO_POINTER (SYS_DVBC_ANNEX_A));
1647     gst_structure_set (adapter_structure, "dvb-c-a", G_TYPE_STRING,
1648         "DVB-C ANNEX A", NULL);
1649   }
1650 
1651   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBC_ANNEX_B)) {
1652     object->supported_delsys = g_list_append (object->supported_delsys,
1653         GINT_TO_POINTER (SYS_DVBC_ANNEX_B));
1654     gst_structure_set (adapter_structure, "dvb-c-b", G_TYPE_STRING,
1655         "DVB-C ANNEX B", NULL);
1656   }
1657 
1658   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBT)) {
1659     object->supported_delsys = g_list_append (object->supported_delsys,
1660         GINT_TO_POINTER (SYS_DVBT));
1661     gst_structure_set (adapter_structure, "dvb-t", G_TYPE_STRING, "DVB-T",
1662         NULL);
1663   }
1664 
1665   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DSS)) {
1666     object->supported_delsys = g_list_append (object->supported_delsys,
1667         GINT_TO_POINTER (SYS_DSS));
1668     gst_structure_set (adapter_structure, "dss", G_TYPE_STRING, "DSS", NULL);
1669   }
1670 
1671   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBS)) {
1672     object->supported_delsys = g_list_append (object->supported_delsys,
1673         GINT_TO_POINTER (SYS_DVBS));
1674     gst_structure_set (adapter_structure, "dvb-s", G_TYPE_STRING, "DVB-S",
1675         NULL);
1676   }
1677 
1678   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBS2)) {
1679     object->supported_delsys = g_list_append (object->supported_delsys,
1680         GINT_TO_POINTER (SYS_DVBS2));
1681     gst_structure_set (adapter_structure, "dvb-s2", G_TYPE_STRING, "DVB-S2",
1682         NULL);
1683   }
1684 
1685   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBH)) {
1686     object->supported_delsys = g_list_append (object->supported_delsys,
1687         GINT_TO_POINTER (SYS_DVBH));
1688     gst_structure_set (adapter_structure, "dvb-h", G_TYPE_STRING, "DVB-H",
1689         NULL);
1690   }
1691 
1692   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_ISDBT)) {
1693     object->supported_delsys = g_list_append (object->supported_delsys,
1694         GINT_TO_POINTER (SYS_ISDBT));
1695     gst_structure_set (adapter_structure, "isdb-t", G_TYPE_STRING, "ISDB-T",
1696         NULL);
1697   }
1698 
1699   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_ISDBS)) {
1700     object->supported_delsys = g_list_append (object->supported_delsys,
1701         GINT_TO_POINTER (SYS_ISDBS));
1702     gst_structure_set (adapter_structure, "isdb-s", G_TYPE_STRING, "ISDB-S",
1703         NULL);
1704   }
1705 
1706   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_ISDBC)) {
1707     object->supported_delsys = g_list_append (object->supported_delsys,
1708         GINT_TO_POINTER (SYS_ISDBC));
1709     gst_structure_set (adapter_structure, "isdb-c", G_TYPE_STRING, "ISDB-C",
1710         NULL);
1711   }
1712 
1713   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_ATSC)) {
1714     object->supported_delsys = g_list_append (object->supported_delsys,
1715         GINT_TO_POINTER (SYS_ATSC));
1716     gst_structure_set (adapter_structure, "atsc", G_TYPE_STRING, "ATSC", NULL);
1717   }
1718 
1719   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_ATSCMH)) {
1720     object->supported_delsys = g_list_append (object->supported_delsys,
1721         GINT_TO_POINTER (SYS_ATSCMH));
1722     gst_structure_set (adapter_structure, "atsc-mh", G_TYPE_STRING, "ATSC-MH",
1723         NULL);
1724   }
1725 #if HAVE_V5_MINOR(7)
1726   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DTMB)) {
1727     object->supported_delsys = g_list_append (object->supported_delsys,
1728         GINT_TO_POINTER (SYS_DTMB));
1729     gst_structure_set (adapter_structure, "dtmb", G_TYPE_STRING, "DTMB", NULL);
1730   }
1731 #endif
1732 
1733   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_CMMB)) {
1734     object->supported_delsys = g_list_append (object->supported_delsys,
1735         GINT_TO_POINTER (SYS_CMMB));
1736     gst_structure_set (adapter_structure, "cmmb", G_TYPE_STRING, "CMMB", NULL);
1737   }
1738 
1739   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DAB)) {
1740     object->supported_delsys = g_list_append (object->supported_delsys,
1741         GINT_TO_POINTER (SYS_DAB));
1742     gst_structure_set (adapter_structure, "dab", G_TYPE_STRING, "DAB", NULL);
1743   }
1744 
1745   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBT2)) {
1746     object->supported_delsys = g_list_append (object->supported_delsys,
1747         GINT_TO_POINTER (SYS_DVBT2));
1748     gst_structure_set (adapter_structure, "dvb-t2", G_TYPE_STRING, "DVB-T2",
1749         NULL);
1750   }
1751 
1752   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_TURBO)) {
1753     object->supported_delsys = g_list_append (object->supported_delsys,
1754         GINT_TO_POINTER (SYS_TURBO));
1755     gst_structure_set (adapter_structure, "turbo", G_TYPE_STRING, "TURBO",
1756         NULL);
1757   }
1758 #if HAVE_V5_MINOR(6)
1759   if (gst_dvbsrc_check_delsys (&dvb_prop[0], SYS_DVBC_ANNEX_C)) {
1760     object->supported_delsys = g_list_append (object->supported_delsys,
1761         GINT_TO_POINTER (SYS_DVBC_ANNEX_C));
1762     gst_structure_set (adapter_structure, "dvb-c-c", G_TYPE_STRING,
1763         "DVB-C ANNEX C", NULL);
1764   }
1765 #endif
1766 
1767   GST_TRACE_OBJECT (object, "%s description: %" GST_PTR_FORMAT, adapter_name,
1768       adapter_structure);
1769   gst_element_post_message (GST_ELEMENT_CAST (object), gst_message_new_element
1770       (GST_OBJECT (object), adapter_structure));
1771   g_free (adapter_name);
1772 
1773 delsys_detection_done:
1774   g_free (frontend_dev);
1775 
1776   return TRUE;
1777 }
1778 
1779 static gboolean
gst_dvbsrc_open_dvr(GstDvbSrc * object)1780 gst_dvbsrc_open_dvr (GstDvbSrc * object)
1781 {
1782   gchar *dvr_dev;
1783   gint err;
1784 
1785   dvr_dev = g_strdup_printf ("/dev/dvb/adapter%d/dvr%d",
1786       object->adapter_number, object->frontend_number);
1787   GST_INFO_OBJECT (object, "Using DVR device: %s", dvr_dev);
1788 
1789   /* open DVR */
1790   if ((object->fd_dvr = open (dvr_dev, O_RDONLY | O_NONBLOCK)) < 0) {
1791     switch (errno) {
1792       case ENOENT:
1793         GST_ELEMENT_ERROR (object, RESOURCE, NOT_FOUND,
1794             (_("Device \"%s\" does not exist."), dvr_dev), (NULL));
1795         break;
1796       default:
1797         GST_ELEMENT_ERROR (object, RESOURCE, OPEN_READ,
1798             (_("Could not open file \"%s\" for reading."), dvr_dev),
1799             GST_ERROR_SYSTEM);
1800         break;
1801     }
1802     g_free (dvr_dev);
1803     return FALSE;
1804   }
1805   g_free (dvr_dev);
1806 
1807   GST_INFO_OBJECT (object, "Setting DVB kernel buffer size to %d",
1808       object->dvb_buffer_size);
1809   LOOP_WHILE_EINTR (err, ioctl (object->fd_dvr, DMX_SET_BUFFER_SIZE,
1810           object->dvb_buffer_size));
1811   if (err) {
1812     GST_INFO_OBJECT (object, "ioctl DMX_SET_BUFFER_SIZE failed (%d)", errno);
1813     return FALSE;
1814   }
1815   return TRUE;
1816 }
1817 
1818 static void
gst_dvbsrc_finalize(GObject * _object)1819 gst_dvbsrc_finalize (GObject * _object)
1820 {
1821   GstDvbSrc *object;
1822 
1823   GST_DEBUG_OBJECT (_object, "gst_dvbsrc_finalize");
1824 
1825   g_return_if_fail (GST_IS_DVBSRC (_object));
1826   object = GST_DVBSRC (_object);
1827 
1828   /* freeing the mutex segfaults somehow */
1829   g_mutex_clear (&object->tune_mutex);
1830 
1831   if (G_OBJECT_CLASS (parent_class)->finalize)
1832     G_OBJECT_CLASS (parent_class)->finalize (_object);
1833 }
1834 
1835 
1836 /*
1837  ******************************
1838  *                            *
1839  *      Plugin Realization    *
1840  *                            *
1841  ******************************
1842  */
1843 
1844 
1845 
1846 /* entry point to initialize the plug-in
1847  * initialize the plug-in itself
1848  * register the element factories and pad templates
1849  * register the features
1850  */
1851 gboolean
gst_dvbsrc_plugin_init(GstPlugin * plugin)1852 gst_dvbsrc_plugin_init (GstPlugin * plugin)
1853 {
1854   GST_DEBUG_CATEGORY_INIT (gstdvbsrc_debug, "dvbsrc", 0, "DVB Source Element");
1855 
1856   return gst_element_register (plugin, "dvbsrc", GST_RANK_NONE,
1857       GST_TYPE_DVBSRC);
1858 }
1859 
1860 static GstFlowReturn
gst_dvbsrc_read_device(GstDvbSrc * object,int size,GstBuffer ** buffer)1861 gst_dvbsrc_read_device (GstDvbSrc * object, int size, GstBuffer ** buffer)
1862 {
1863   gint count = 0;
1864   gint ret_val = 0;
1865   GstBuffer *buf = gst_buffer_new_and_alloc (size);
1866   GstClockTime timeout = object->timeout * GST_USECOND;
1867   GstMapInfo map;
1868 
1869   g_return_val_if_fail (GST_IS_BUFFER (buf), GST_FLOW_ERROR);
1870 
1871   if (object->fd_dvr < 0)
1872     return GST_FLOW_ERROR;
1873 
1874   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1875   while (count < size) {
1876     ret_val = gst_poll_wait (object->poll, timeout);
1877     GST_LOG_OBJECT (object, "select returned %d", ret_val);
1878     if (G_UNLIKELY (ret_val < 0)) {
1879       if (errno == EBUSY)
1880         goto stopped;
1881       else if (errno == EINTR)
1882         continue;
1883       else
1884         goto select_error;
1885     } else if (G_UNLIKELY (!ret_val)) {
1886       /* timeout, post element message */
1887       gst_element_post_message (GST_ELEMENT_CAST (object),
1888           gst_message_new_element (GST_OBJECT (object),
1889               gst_structure_new_empty ("dvb-read-failure")));
1890     } else {
1891       int nread = read (object->fd_dvr, map.data + count, size - count);
1892 
1893       if (G_UNLIKELY (nread < 0)) {
1894         GST_WARNING_OBJECT
1895             (object,
1896             "Unable to read from device: /dev/dvb/adapter%d/dvr%d (%d)",
1897             object->adapter_number, object->frontend_number, errno);
1898         gst_element_post_message (GST_ELEMENT_CAST (object),
1899             gst_message_new_element (GST_OBJECT (object),
1900                 gst_structure_new_empty ("dvb-read-failure")));
1901       } else
1902         count = count + nread;
1903     }
1904   }
1905   gst_buffer_unmap (buf, &map);
1906   gst_buffer_resize (buf, 0, count);
1907 
1908   *buffer = buf;
1909 
1910   return GST_FLOW_OK;
1911 
1912 stopped:
1913   {
1914     GST_DEBUG_OBJECT (object, "stop called");
1915     gst_buffer_unmap (buf, &map);
1916     gst_buffer_unref (buf);
1917     return GST_FLOW_FLUSHING;
1918   }
1919 select_error:
1920   {
1921     GST_ELEMENT_ERROR (object, RESOURCE, READ, (NULL),
1922         ("select error %d: %s (%d)", ret_val, g_strerror (errno), errno));
1923     gst_buffer_unmap (buf, &map);
1924     gst_buffer_unref (buf);
1925     return GST_FLOW_ERROR;
1926   }
1927 }
1928 
1929 static GstFlowReturn
gst_dvbsrc_create(GstPushSrc * element,GstBuffer ** buf)1930 gst_dvbsrc_create (GstPushSrc * element, GstBuffer ** buf)
1931 {
1932   gint buffer_size;
1933   GstFlowReturn retval = GST_FLOW_ERROR;
1934   GstDvbSrc *object;
1935   fe_status_t status;
1936 
1937   object = GST_DVBSRC (element);
1938   GST_LOG ("fd_dvr: %d", object->fd_dvr);
1939 
1940   buffer_size = DEFAULT_BUFFER_SIZE;
1941 
1942   /* device can not be tuned during read */
1943   g_mutex_lock (&object->tune_mutex);
1944 
1945 
1946   if (object->fd_dvr > -1) {
1947     /* --- Read TS from DVR device --- */
1948     GST_DEBUG_OBJECT (object, "Reading from DVR device");
1949     retval = gst_dvbsrc_read_device (object, buffer_size, buf);
1950 
1951     if (object->stats_interval &&
1952         ++object->stats_counter == object->stats_interval) {
1953       gst_dvbsrc_output_frontend_stats (object, &status);
1954       object->stats_counter = 0;
1955     }
1956   }
1957 
1958   g_mutex_unlock (&object->tune_mutex);
1959 
1960   return retval;
1961 
1962 }
1963 
1964 static GstStateChangeReturn
gst_dvbsrc_change_state(GstElement * element,GstStateChange transition)1965 gst_dvbsrc_change_state (GstElement * element, GstStateChange transition)
1966 {
1967   GstDvbSrc *src;
1968   GstStateChangeReturn ret;
1969 
1970   src = GST_DVBSRC (element);
1971   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1972 
1973   switch (transition) {
1974     case GST_STATE_CHANGE_NULL_TO_READY:
1975       /* open frontend then close it again, just so caps sent */
1976       if (!gst_dvbsrc_open_frontend (src, FALSE)) {
1977         GST_ERROR_OBJECT (src, "Could not open frontend device");
1978         ret = GST_STATE_CHANGE_FAILURE;
1979       }
1980       if (src->fd_frontend) {
1981         close (src->fd_frontend);
1982       }
1983       break;
1984     default:
1985       break;
1986   }
1987 
1988   return ret;
1989 }
1990 
1991 
1992 static gboolean
gst_dvbsrc_start(GstBaseSrc * bsrc)1993 gst_dvbsrc_start (GstBaseSrc * bsrc)
1994 {
1995   GstDvbSrc *src = GST_DVBSRC (bsrc);
1996 
1997   if (!gst_dvbsrc_open_frontend (src, TRUE)) {
1998     GST_ERROR_OBJECT (src, "Could not open frontend device");
1999     return FALSE;
2000   }
2001   if (!gst_dvbsrc_tune (src)) {
2002     GST_ERROR_OBJECT (src, "Not able to lock on channel");
2003     goto fail;
2004   }
2005   if (!gst_dvbsrc_open_dvr (src)) {
2006     GST_ERROR_OBJECT (src, "Not able to open DVR device");
2007     goto fail;
2008   }
2009   if (!(src->poll = gst_poll_new (TRUE))) {
2010     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
2011         ("Could not create an fd set: %s (%d)", g_strerror (errno), errno));
2012     goto fail;
2013   }
2014 
2015   gst_poll_fd_init (&src->poll_fd_dvr);
2016   src->poll_fd_dvr.fd = src->fd_dvr;
2017   gst_poll_add_fd (src->poll, &src->poll_fd_dvr);
2018   gst_poll_fd_ctl_read (src->poll, &src->poll_fd_dvr, TRUE);
2019 
2020   return TRUE;
2021 
2022 fail:
2023   gst_dvbsrc_unset_pes_filters (src);
2024   close (src->fd_frontend);
2025   return FALSE;
2026 }
2027 
2028 static gboolean
gst_dvbsrc_stop(GstBaseSrc * bsrc)2029 gst_dvbsrc_stop (GstBaseSrc * bsrc)
2030 {
2031   GstDvbSrc *src = GST_DVBSRC (bsrc);
2032 
2033   gst_dvbsrc_close_devices (src);
2034   g_list_free (src->supported_delsys);
2035   src->supported_delsys = NULL;
2036   if (src->poll) {
2037     gst_poll_free (src->poll);
2038     src->poll = NULL;
2039   }
2040 
2041   return TRUE;
2042 }
2043 
2044 static gboolean
gst_dvbsrc_unlock(GstBaseSrc * bsrc)2045 gst_dvbsrc_unlock (GstBaseSrc * bsrc)
2046 {
2047   GstDvbSrc *src = GST_DVBSRC (bsrc);
2048 
2049   gst_poll_set_flushing (src->poll, TRUE);
2050   return TRUE;
2051 }
2052 
2053 static gboolean
gst_dvbsrc_unlock_stop(GstBaseSrc * bsrc)2054 gst_dvbsrc_unlock_stop (GstBaseSrc * bsrc)
2055 {
2056   GstDvbSrc *src = GST_DVBSRC (bsrc);
2057 
2058   gst_poll_set_flushing (src->poll, FALSE);
2059   return TRUE;
2060 }
2061 
2062 static gboolean
gst_dvbsrc_is_seekable(GstBaseSrc * bsrc)2063 gst_dvbsrc_is_seekable (GstBaseSrc * bsrc)
2064 {
2065   return FALSE;
2066 }
2067 
2068 static gboolean
gst_dvbsrc_is_valid_trans_mode(guint delsys,guint mode)2069 gst_dvbsrc_is_valid_trans_mode (guint delsys, guint mode)
2070 {
2071   /* FIXME: check valid transmission modes for other broadcast standards */
2072   switch (delsys) {
2073     case SYS_DVBT:
2074       if (mode == TRANSMISSION_MODE_AUTO || mode == TRANSMISSION_MODE_2K ||
2075           mode == TRANSMISSION_MODE_8K) {
2076         return TRUE;
2077       }
2078       break;
2079     case SYS_DVBT2:
2080       if (mode == TRANSMISSION_MODE_AUTO || mode == TRANSMISSION_MODE_1K ||
2081           mode == TRANSMISSION_MODE_2K || mode == TRANSMISSION_MODE_4K ||
2082           mode == TRANSMISSION_MODE_8K || mode == TRANSMISSION_MODE_16K ||
2083           mode == TRANSMISSION_MODE_32K) {
2084         return TRUE;
2085       }
2086       break;
2087 #if HAVE_V5_MINOR(7)
2088     case SYS_DTMB:
2089       if (mode == TRANSMISSION_MODE_AUTO || mode == TRANSMISSION_MODE_C1 ||
2090           mode == TRANSMISSION_MODE_C3780) {
2091         return TRUE;
2092       }
2093       break;
2094 #endif
2095     default:
2096       GST_FIXME ("No transmission-mode sanity checks implemented for this "
2097           "delivery system");
2098       return TRUE;
2099   }
2100   GST_WARNING ("Invalid transmission-mode '%d' for delivery system '%d'", mode,
2101       delsys);
2102   return FALSE;
2103 }
2104 
2105 static gboolean
gst_dvbsrc_is_valid_modulation(guint delsys,guint mod)2106 gst_dvbsrc_is_valid_modulation (guint delsys, guint mod)
2107 {
2108   /* FIXME: check valid modulations for other broadcast standards */
2109   switch (delsys) {
2110     case SYS_ISDBT:
2111       if (mod == QAM_AUTO || mod == QPSK || mod == QAM_16 ||
2112           mod == QAM_64 || mod == DQPSK)
2113         return TRUE;
2114       break;
2115     case SYS_ATSC:
2116       if (mod == VSB_8 || mod == VSB_16)
2117         return TRUE;
2118       break;
2119     case SYS_DVBT:
2120       if (mod == QPSK || mod == QAM_16 || mod == QAM_64)
2121         return TRUE;
2122       break;
2123     case SYS_DVBT2:
2124       if (mod == QPSK || mod == QAM_16 || mod == QAM_64 || mod == QAM_256)
2125         return TRUE;
2126       break;
2127     default:
2128       GST_FIXME ("No modulation sanity-checks implemented for delivery "
2129           "system: '%d'", delsys);
2130       return TRUE;
2131   }
2132   GST_WARNING ("Invalid modulation '%d' for delivery system '%d'", mod, delsys);
2133   return FALSE;
2134 }
2135 
2136 static gboolean
gst_dvbsrc_is_valid_bandwidth(guint delsys,guint bw)2137 gst_dvbsrc_is_valid_bandwidth (guint delsys, guint bw)
2138 {
2139   /* FIXME: check valid bandwidth values for other broadcast standards */
2140 
2141   /* Bandwidth == 0 means auto, this should be valid for every delivery system
2142    * for which the bandwidth parameter makes sense */
2143 
2144   switch (delsys) {
2145     case SYS_DVBT:
2146       if (bw == 6000000 || bw == 7000000 || bw == 8000000 || bw == 0)
2147         return TRUE;
2148       break;
2149     case SYS_DVBT2:
2150       if (bw == 1172000 || bw == 5000000 || bw == 6000000 || bw == 0 ||
2151           bw == 7000000 || bw == 8000000 || bw == 10000000) {
2152         return TRUE;
2153       }
2154       break;
2155     case SYS_ISDBT:
2156       if (bw == 6000000 || bw == 0)
2157         return TRUE;
2158       break;
2159     default:
2160       GST_FIXME ("No bandwidth sanity checks implemented for this "
2161           "delivery system");
2162       return TRUE;
2163   }
2164   GST_WARNING ("Invalid bandwidth '%d' for delivery system '%d'", bw, delsys);
2165   return FALSE;
2166 }
2167 
2168 static gboolean
gst_dvbsrc_get_size(GstBaseSrc * src,guint64 * size)2169 gst_dvbsrc_get_size (GstBaseSrc * src, guint64 * size)
2170 {
2171   return FALSE;
2172 }
2173 
2174 static void
gst_dvbsrc_do_tune(GstDvbSrc * src)2175 gst_dvbsrc_do_tune (GstDvbSrc * src)
2176 {
2177   /* if we are in paused/playing state tune now, otherwise in ready
2178    * to paused state change */
2179   if (GST_STATE (src) > GST_STATE_READY)
2180     gst_dvbsrc_tune (src);
2181 }
2182 
2183 static gboolean
gst_dvbsrc_output_frontend_stats(GstDvbSrc * src,fe_status_t * status)2184 gst_dvbsrc_output_frontend_stats (GstDvbSrc * src, fe_status_t * status)
2185 {
2186   guint16 snr, signal;
2187   guint32 ber, bad_blks;
2188   GstMessage *message;
2189   GstStructure *structure;
2190   gint err;
2191 
2192   errno = 0;
2193 
2194   LOOP_WHILE_EINTR (err, ioctl (src->fd_frontend, FE_READ_STATUS, status));
2195   if (err) {
2196     GST_ERROR_OBJECT (src, "Failed querying frontend for tuning status"
2197         " %s (%d)", g_strerror (errno), errno);
2198     return FALSE;
2199   }
2200 
2201   structure = gst_structure_new ("dvb-frontend-stats",
2202       "status", G_TYPE_INT, status,
2203       "lock", G_TYPE_BOOLEAN, *status & FE_HAS_LOCK, NULL);
2204 
2205   LOOP_WHILE_EINTR (err, ioctl (src->fd_frontend, FE_READ_SIGNAL_STRENGTH,
2206           &signal));
2207   if (!err)
2208     gst_structure_set (structure, "signal", G_TYPE_INT, signal, NULL);
2209 
2210   LOOP_WHILE_EINTR (err, ioctl (src->fd_frontend, FE_READ_SNR, &snr));
2211   if (!err)
2212     gst_structure_set (structure, "snr", G_TYPE_INT, snr, NULL);
2213 
2214   LOOP_WHILE_EINTR (err, ioctl (src->fd_frontend, FE_READ_BER, &ber));
2215   if (!err)
2216     gst_structure_set (structure, "ber", G_TYPE_INT, ber, NULL);
2217 
2218   LOOP_WHILE_EINTR (err, ioctl (src->fd_frontend, FE_READ_UNCORRECTED_BLOCKS,
2219           &bad_blks));
2220   if (!err)
2221     gst_structure_set (structure, "unc", G_TYPE_INT, bad_blks, NULL);
2222 
2223   if (errno) {
2224     GST_WARNING_OBJECT (src,
2225         "There were errors getting frontend status information: '%s'",
2226         g_strerror (errno));
2227   }
2228 
2229   GST_INFO_OBJECT (src, "Frontend stats: %" GST_PTR_FORMAT, structure);
2230   message = gst_message_new_element (GST_OBJECT (src), structure);
2231   gst_element_post_message (GST_ELEMENT (src), message);
2232 
2233   return TRUE;
2234 }
2235 
2236 
2237 static void
diseqc_send_msg(int fd,fe_sec_voltage_t v,struct dvb_diseqc_master_cmd * cmd,fe_sec_tone_mode_t t,fe_sec_mini_cmd_t b)2238 diseqc_send_msg (int fd, fe_sec_voltage_t v, struct dvb_diseqc_master_cmd *cmd,
2239     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
2240 {
2241   gint err;
2242 
2243   LOOP_WHILE_EINTR (err, ioctl (fd, FE_SET_TONE, SEC_TONE_OFF));
2244   if (err) {
2245     GST_ERROR ("Setting tone to off failed");
2246     return;
2247   }
2248 
2249   LOOP_WHILE_EINTR (err, ioctl (fd, FE_SET_VOLTAGE, v));
2250   if (err) {
2251     GST_ERROR ("Setting voltage failed");
2252     return;
2253   }
2254 
2255   g_usleep (15 * 1000);
2256   GST_LOG ("diseqc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", cmd->msg[0],
2257       cmd->msg[1], cmd->msg[2], cmd->msg[3], cmd->msg[4], cmd->msg[5]);
2258 
2259   LOOP_WHILE_EINTR (err, ioctl (fd, FE_DISEQC_SEND_MASTER_CMD, cmd));
2260   if (err) {
2261     GST_ERROR ("Sending DiSEqC command failed");
2262     return;
2263   }
2264 
2265   g_usleep (15 * 1000);
2266 
2267   LOOP_WHILE_EINTR (err, ioctl (fd, FE_DISEQC_SEND_BURST, b));
2268   if (err) {
2269     GST_ERROR ("Sending burst failed");
2270     return;
2271   }
2272 
2273   g_usleep (15 * 1000);
2274 
2275   LOOP_WHILE_EINTR (err, ioctl (fd, FE_SET_TONE, t));
2276   if (err) {
2277     GST_ERROR ("Setting tone failed");
2278     return;
2279   }
2280 }
2281 
2282 
2283 /* digital satellite equipment control,
2284  * specification is available from http://www.eutelsat.com/
2285  */
2286 static void
diseqc(int secfd,int sat_no,int voltage,int tone)2287 diseqc (int secfd, int sat_no, int voltage, int tone)
2288 {
2289   struct dvb_diseqc_master_cmd cmd =
2290       { {0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4 };
2291 
2292   /* param: high nibble: reset bits, low nibble set bits,
2293    * bits are: option, position, polarizaion, band
2294    */
2295   cmd.msg[3] =
2296       0xf0 | (((sat_no * 4) & 0x0f) | (tone == SEC_TONE_ON ? 1 : 0) |
2297       (voltage == SEC_VOLTAGE_13 ? 0 : 2));
2298   /* send twice because some DiSEqC switches do not respond correctly the
2299    * first time */
2300   diseqc_send_msg (secfd, voltage, &cmd, tone,
2301       sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
2302   diseqc_send_msg (secfd, voltage, &cmd, tone,
2303       sat_no % 2 ? SEC_MINI_B : SEC_MINI_A);
2304 
2305 }
2306 
2307 inline static void
set_prop(struct dtv_property * props,int * n,guint32 cmd,guint32 data)2308 set_prop (struct dtv_property *props, int *n, guint32 cmd, guint32 data)
2309 {
2310   if (*n == NUM_DTV_PROPS) {
2311     g_critical ("Index out of bounds");
2312   } else {
2313     props[*n].cmd = cmd;
2314     props[(*n)++].u.data = data;
2315   }
2316 }
2317 
2318 static gboolean
gst_dvbsrc_tune_fe(GstDvbSrc * object)2319 gst_dvbsrc_tune_fe (GstDvbSrc * object)
2320 {
2321   fe_status_t status;
2322   struct dtv_properties props;
2323   struct dtv_property dvb_prop[NUM_DTV_PROPS];
2324   GstClockTimeDiff elapsed_time;
2325   GstClockTime start;
2326   gint err;
2327 
2328   GST_DEBUG_OBJECT (object, "Starting the frontend tuning process");
2329 
2330   if (object->fd_frontend < 0) {
2331     GST_INFO_OBJECT (object, "Frontend not open: tuning later");
2332     return FALSE;
2333   }
2334 
2335   /* If set, confirm the choosen delivery system is actually
2336    * supported by the hardware */
2337   if (object->delsys != SYS_UNDEFINED) {
2338     GST_DEBUG_OBJECT (object, "Confirming delivery system '%u' is supported",
2339         object->delsys);
2340     if (!g_list_find (object->supported_delsys,
2341             GINT_TO_POINTER (object->delsys))) {
2342       GST_WARNING_OBJECT (object, "Adapter does not support delivery system "
2343           "'%u'", object->delsys);
2344       return FALSE;
2345     }
2346   }
2347 
2348   gst_dvbsrc_unset_pes_filters (object);
2349 
2350   g_mutex_lock (&object->tune_mutex);
2351 
2352   memset (dvb_prop, 0, sizeof (dvb_prop));
2353   dvb_prop[0].cmd = DTV_CLEAR;
2354   props.num = 1;
2355   props.props = dvb_prop;
2356 
2357   LOOP_WHILE_EINTR (err, ioctl (object->fd_frontend, FE_SET_PROPERTY, &props));
2358   if (err) {
2359     GST_WARNING_OBJECT (object, "Error resetting tuner: %s",
2360         g_strerror (errno));
2361   }
2362 
2363   memset (dvb_prop, 0, sizeof (dvb_prop));
2364   if (!gst_dvbsrc_set_fe_params (object, &props)) {
2365     GST_WARNING_OBJECT (object, "Could not set frontend params");
2366     goto fail;
2367   }
2368 
2369   GST_DEBUG_OBJECT (object, "Setting %d properties", props.num);
2370 
2371   LOOP_WHILE_EINTR (err, ioctl (object->fd_frontend, FE_SET_PROPERTY, &props));
2372   if (err) {
2373     GST_WARNING_OBJECT (object, "Error tuning channel: %s (%d)",
2374         g_strerror (errno), errno);
2375     goto fail;
2376   }
2377 
2378   g_signal_emit (object, gst_dvbsrc_signals[SIGNAL_TUNING_START], 0);
2379   elapsed_time = 0;
2380   start = gst_util_get_timestamp ();
2381 
2382   /* signal locking loop */
2383   do {
2384 
2385     if (!gst_dvbsrc_output_frontend_stats (object, &status))
2386       goto fail_with_signal;
2387 
2388     /* keep retrying forever if tuning_timeout = 0 */
2389     if (object->tuning_timeout)
2390       elapsed_time = GST_CLOCK_DIFF (start, gst_util_get_timestamp ());
2391     GST_LOG_OBJECT (object,
2392         "Tuning. Time elapsed %" GST_STIME_FORMAT " Limit %" GST_TIME_FORMAT,
2393         GST_STIME_ARGS (elapsed_time), GST_TIME_ARGS (object->tuning_timeout));
2394   } while (!(status & FE_HAS_LOCK) && elapsed_time <= object->tuning_timeout);
2395 
2396   if (!(status & FE_HAS_LOCK)) {
2397     GST_WARNING_OBJECT (object,
2398         "Unable to lock on signal at desired frequency");
2399     goto fail_with_signal;
2400   }
2401 
2402   GST_LOG_OBJECT (object, "status == 0x%02x", status);
2403 
2404   g_signal_emit (object, gst_dvbsrc_signals[SIGNAL_TUNING_DONE], 0);
2405   GST_DEBUG_OBJECT (object, "Successfully set frontend tuning params");
2406 
2407   g_mutex_unlock (&object->tune_mutex);
2408   return TRUE;
2409 
2410 fail_with_signal:
2411   g_signal_emit (object, gst_dvbsrc_signals[SIGNAL_TUNING_FAIL], 0);
2412 fail:
2413   GST_WARNING_OBJECT (object, "Could not tune to desired frequency");
2414   g_mutex_unlock (&object->tune_mutex);
2415   return FALSE;
2416 }
2417 
2418 static void
gst_dvbsrc_guess_delsys(GstDvbSrc * object)2419 gst_dvbsrc_guess_delsys (GstDvbSrc * object)
2420 {
2421   GList *valid, *candidate;
2422   guint alternatives;
2423 
2424   if (g_list_length (object->supported_delsys) == 1) {
2425     object->delsys = GPOINTER_TO_INT (object->supported_delsys->data);
2426     GST_DEBUG_OBJECT (object, "Adapter supports a single delsys: '%u'",
2427         object->delsys);
2428     goto autoselection_done;
2429   }
2430 
2431   /* Automatic delivery system selection based on known-correct
2432    * parameter combinations */
2433 
2434   valid = g_list_copy (object->supported_delsys);
2435 
2436   candidate = valid;
2437   while (candidate) {
2438     GList *next = candidate->next;
2439     if (!gst_dvbsrc_is_valid_modulation (GPOINTER_TO_INT (candidate->data),
2440             object->modulation) ||
2441         !gst_dvbsrc_is_valid_trans_mode (GPOINTER_TO_INT (candidate->data),
2442             object->transmission_mode) ||
2443         !gst_dvbsrc_is_valid_bandwidth (GPOINTER_TO_INT (candidate->data),
2444             object->bandwidth)) {
2445       valid = g_list_delete_link (valid, candidate);
2446     }
2447     candidate = next;
2448   }
2449 
2450   alternatives = g_list_length (valid);
2451 
2452   switch (alternatives) {
2453     case 0:
2454       GST_WARNING_OBJECT (object, "Delivery system autodetection provided no "
2455           "valid alternative");
2456       candidate = g_list_last (object->supported_delsys);
2457       break;
2458     case 1:
2459       candidate = g_list_last (valid);
2460       GST_DEBUG_OBJECT (object, "Delivery system autodetection provided only "
2461           "one valid alternative: '%d'", GPOINTER_TO_INT (candidate->data));
2462       break;
2463     default:
2464       /* More than one alternative. Selection based on best guess */
2465       if (g_list_find (valid, GINT_TO_POINTER (SYS_DVBT)) &&
2466           g_list_find (valid, GINT_TO_POINTER (SYS_DVBT2))) {
2467         /* There is no way to tell one over the other when parameters seem valid
2468          * for DVB-T and DVB-T2 and the adapter supports both. Reason to go with
2469          * the former here is that, from experience, most DVB-T2 channels out
2470          * there seem to use parameters that are not valid for DVB-T, like
2471          * QAM_256 */
2472         GST_WARNING_OBJECT (object, "Channel parameters valid for DVB-T and "
2473             "DVB-T2. Choosing DVB-T");
2474         candidate = g_list_find (valid, GINT_TO_POINTER (SYS_DVBT));
2475       } else {
2476         candidate = g_list_last (valid);
2477       }
2478   }
2479 
2480   object->delsys = GPOINTER_TO_INT (candidate->data);
2481   g_list_free (valid);
2482 
2483 autoselection_done:
2484   GST_INFO_OBJECT (object, "Automatically selecting delivery system '%u'",
2485       object->delsys);
2486 }
2487 
2488 static gboolean
gst_dvbsrc_set_fe_params(GstDvbSrc * object,struct dtv_properties * props)2489 gst_dvbsrc_set_fe_params (GstDvbSrc * object, struct dtv_properties *props)
2490 {
2491   fe_sec_voltage_t voltage;
2492   unsigned int freq = object->freq;
2493   unsigned int sym_rate = object->sym_rate * 1000;
2494   int inversion = object->inversion;
2495   int n;
2496   gint err;
2497 
2498   /* If delsys hasn't been set, ask for it to be automatically selected */
2499   if (object->delsys == SYS_UNDEFINED)
2500     gst_dvbsrc_guess_delsys (object);
2501 
2502   /* first 3 entries are reserved */
2503   n = 3;
2504 
2505   /* We are not dropping out but issuing a warning in case of wrong
2506    * parameter combinations as failover behavior should be mandated
2507    * by the driver. Worst case scenario it will just fail at tuning. */
2508 
2509   switch (object->delsys) {
2510     case SYS_DVBS:
2511     case SYS_DVBS2:
2512     case SYS_TURBO:
2513       if (freq > 2200000) {
2514         /* this must be an absolute frequency */
2515         if (freq < object->lnb_slof) {
2516           freq -= object->lnb_lof1;
2517           object->tone = SEC_TONE_OFF;
2518         } else {
2519           freq -= object->lnb_lof2;
2520           object->tone = SEC_TONE_ON;
2521         }
2522       }
2523 
2524       inversion = INVERSION_AUTO;
2525       set_prop (props->props, &n, DTV_SYMBOL_RATE, sym_rate);
2526       set_prop (props->props, &n, DTV_INNER_FEC, object->code_rate_hp);
2527 
2528       GST_INFO_OBJECT (object,
2529           "Tuning DVB-S/DVB-S2/Turbo to L-Band:%u, Pol:%d, srate=%u, 22kHz=%s",
2530           freq, object->pol, sym_rate,
2531           object->tone == SEC_TONE_ON ? "on" : "off");
2532 
2533       if (object->pol == DVB_POL_H)
2534         voltage = SEC_VOLTAGE_18;
2535       else
2536         voltage = SEC_VOLTAGE_13;
2537 
2538       if (object->diseqc_src == -1 || object->send_diseqc == FALSE) {
2539         set_prop (props->props, &n, DTV_VOLTAGE, voltage);
2540 
2541         /* DTV_TONE not yet implemented
2542          * set_prop (fe_props_array, &n, DTV_TONE, object->tone) */
2543         LOOP_WHILE_EINTR (err, ioctl (object->fd_frontend, FE_SET_TONE,
2544                 object->tone));
2545         if (err) {
2546           GST_WARNING_OBJECT (object, "Couldn't set tone: %s",
2547               g_strerror (errno));
2548         }
2549       } else {
2550         GST_DEBUG_OBJECT (object, "Sending DiSEqC");
2551         diseqc (object->fd_frontend, object->diseqc_src, voltage, object->tone);
2552         /* Once DiSEqC source is set, do not set it again until
2553          * app decides to change it
2554          * object->send_diseqc = FALSE; */
2555       }
2556 
2557       if ((object->delsys == SYS_DVBS2) || (object->delsys == SYS_TURBO))
2558         set_prop (props->props, &n, DTV_MODULATION, object->modulation);
2559 
2560       if (object->delsys == SYS_DVBS2) {
2561         if (object->stream_id > 255) {
2562           GST_WARNING_OBJECT (object, "Invalid (> 255) DVB-S2 stream ID '%d'. "
2563               "Disabling sub-stream filtering", object->stream_id);
2564           object->stream_id = NO_STREAM_ID_FILTER;
2565         }
2566         set_prop (props->props, &n, DTV_PILOT, object->pilot);
2567         set_prop (props->props, &n, DTV_ROLLOFF, object->rolloff);
2568         set_prop (props->props, &n, DTV_STREAM_ID, object->stream_id);
2569       }
2570       break;
2571     case SYS_DVBT:
2572     case SYS_DVBT2:
2573       set_prop (props->props, &n, DTV_BANDWIDTH_HZ, object->bandwidth);
2574       set_prop (props->props, &n, DTV_CODE_RATE_HP, object->code_rate_hp);
2575       set_prop (props->props, &n, DTV_CODE_RATE_LP, object->code_rate_lp);
2576       set_prop (props->props, &n, DTV_MODULATION, object->modulation);
2577       set_prop (props->props, &n, DTV_TRANSMISSION_MODE,
2578           object->transmission_mode);
2579       set_prop (props->props, &n, DTV_GUARD_INTERVAL, object->guard_interval);
2580       set_prop (props->props, &n, DTV_HIERARCHY, object->hierarchy_information);
2581 
2582       if (object->delsys == SYS_DVBT2) {
2583         if (object->stream_id > 255) {
2584           GST_WARNING_OBJECT (object, "Invalid (> 255) DVB-T2 stream ID '%d'. "
2585               "Disabling sub-stream filtering", object->stream_id);
2586           object->stream_id = NO_STREAM_ID_FILTER;
2587         }
2588         set_prop (props->props, &n, DTV_STREAM_ID, object->stream_id);
2589       }
2590 
2591       GST_INFO_OBJECT (object, "Tuning DVB-T/DVB_T2 to %d Hz", freq);
2592       break;
2593     case SYS_DVBC_ANNEX_A:
2594     case SYS_DVBC_ANNEX_B:
2595 #if HAVE_V5_MINOR(6)
2596     case SYS_DVBC_ANNEX_C:
2597 #endif
2598       GST_INFO_OBJECT (object, "Tuning DVB-C/ClearCable to %d, srate=%d",
2599           freq, sym_rate);
2600 
2601       set_prop (props->props, &n, DTV_MODULATION, object->modulation);
2602       if (object->delsys != SYS_DVBC_ANNEX_B) {
2603         set_prop (props->props, &n, DTV_INNER_FEC, object->code_rate_hp);
2604         set_prop (props->props, &n, DTV_SYMBOL_RATE, sym_rate);
2605       }
2606       break;
2607     case SYS_ATSC:
2608       GST_INFO_OBJECT (object, "Tuning ATSC to %d", freq);
2609 
2610       set_prop (props->props, &n, DTV_MODULATION, object->modulation);
2611       break;
2612     case SYS_ISDBT:
2613 
2614       if (object->isdbt_partial_reception == 1 &&
2615           object->isdbt_layera_segment_count != 1) {
2616         GST_WARNING_OBJECT (object, "Wrong ISDB-T parameter combination: "
2617             "partial reception is set but layer A segment count is not 1");
2618       }
2619 
2620       if (!object->isdbt_sound_broadcasting) {
2621         GST_INFO_OBJECT (object, "ISDB-T sound broadcasting is not set. "
2622             "Driver will likely ignore values set for isdbt-sb-subchannel-id, "
2623             "isdbt-sb-segment-idx and isdbt-sb-segment-count");
2624       }
2625 
2626       if (object->isdbt_layerc_modulation == DQPSK &&
2627           object->isdbt_layerb_modulation != DQPSK) {
2628         GST_WARNING_OBJECT (object, "Wrong ISDB-T parameter combination: "
2629             "layer C modulation is DQPSK but layer B modulation is different");
2630       }
2631 
2632       GST_INFO_OBJECT (object, "Tuning ISDB-T to %d", freq);
2633       set_prop (props->props, &n, DTV_BANDWIDTH_HZ, object->bandwidth);
2634       set_prop (props->props, &n, DTV_GUARD_INTERVAL, object->guard_interval);
2635       set_prop (props->props, &n, DTV_TRANSMISSION_MODE,
2636           object->transmission_mode);
2637       set_prop (props->props, &n, DTV_ISDBT_LAYER_ENABLED,
2638           object->isdbt_layer_enabled);
2639       set_prop (props->props, &n, DTV_ISDBT_PARTIAL_RECEPTION,
2640           object->isdbt_partial_reception);
2641       set_prop (props->props, &n, DTV_ISDBT_SOUND_BROADCASTING,
2642           object->isdbt_sound_broadcasting);
2643       set_prop (props->props, &n, DTV_ISDBT_SB_SUBCHANNEL_ID,
2644           object->isdbt_sb_subchannel_id);
2645       set_prop (props->props, &n, DTV_ISDBT_SB_SEGMENT_IDX,
2646           object->isdbt_sb_segment_idx);
2647       set_prop (props->props, &n, DTV_ISDBT_SB_SEGMENT_COUNT,
2648           object->isdbt_sb_segment_count);
2649       set_prop (props->props, &n, DTV_ISDBT_LAYERA_FEC,
2650           object->isdbt_layera_fec);
2651       set_prop (props->props, &n, DTV_ISDBT_LAYERA_MODULATION,
2652           object->isdbt_layera_modulation);
2653       set_prop (props->props, &n, DTV_ISDBT_LAYERA_SEGMENT_COUNT,
2654           object->isdbt_layera_segment_count);
2655       set_prop (props->props, &n, DTV_ISDBT_LAYERA_TIME_INTERLEAVING,
2656           object->isdbt_layera_time_interleaving);
2657       set_prop (props->props, &n, DTV_ISDBT_LAYERB_FEC,
2658           object->isdbt_layerb_fec);
2659       set_prop (props->props, &n, DTV_ISDBT_LAYERB_MODULATION,
2660           object->isdbt_layerb_modulation);
2661       set_prop (props->props, &n, DTV_ISDBT_LAYERB_SEGMENT_COUNT,
2662           object->isdbt_layerb_segment_count);
2663       set_prop (props->props, &n, DTV_ISDBT_LAYERB_TIME_INTERLEAVING,
2664           object->isdbt_layerb_time_interleaving);
2665       set_prop (props->props, &n, DTV_ISDBT_LAYERC_FEC,
2666           object->isdbt_layerc_fec);
2667       set_prop (props->props, &n, DTV_ISDBT_LAYERC_MODULATION,
2668           object->isdbt_layerc_modulation);
2669       set_prop (props->props, &n, DTV_ISDBT_LAYERC_SEGMENT_COUNT,
2670           object->isdbt_layerc_segment_count);
2671       set_prop (props->props, &n, DTV_ISDBT_LAYERC_TIME_INTERLEAVING,
2672           object->isdbt_layerc_time_interleaving);
2673       break;
2674 #if HAVE_V5_MINOR(7)
2675     case SYS_DTMB:
2676       set_prop (props->props, &n, DTV_BANDWIDTH_HZ, object->bandwidth);
2677       set_prop (props->props, &n, DTV_MODULATION, object->modulation);
2678       set_prop (props->props, &n, DTV_INVERSION, object->inversion);
2679       set_prop (props->props, &n, DTV_INNER_FEC, object->code_rate_hp);
2680       set_prop (props->props, &n, DTV_TRANSMISSION_MODE,
2681           object->transmission_mode);
2682       set_prop (props->props, &n, DTV_GUARD_INTERVAL, object->guard_interval);
2683       set_prop (props->props, &n, DTV_INTERLEAVING, object->interleaving);
2684       /* FIXME: Make the LNA on/off switch a property and proxy on dvbbasebin */
2685       /* FIXME: According to v4l advice (see libdvbv5 implementation) this
2686        * property should be set separately as not all drivers will ignore it
2687        * if unsupported. An alternative would be to get the dvb API contract
2688        * revised on this regard */
2689       set_prop (props->props, &n, DTV_LNA, LNA_AUTO);
2690       GST_INFO_OBJECT (object, "Tuning DTMB to %d Hz", freq);
2691       break;
2692 #endif
2693     default:
2694       GST_ERROR_OBJECT (object, "Unknown frontend type %u", object->delsys);
2695       return FALSE;
2696   }
2697 
2698   /* Informative checks */
2699   if (!gst_dvbsrc_is_valid_modulation (object->delsys, object->modulation)) {
2700     GST_WARNING_OBJECT (object,
2701         "Attempting invalid modulation '%u' for delivery system '%u'",
2702         object->modulation, object->delsys);
2703   }
2704   if (!gst_dvbsrc_is_valid_trans_mode (object->delsys,
2705           object->transmission_mode)) {
2706     GST_WARNING_OBJECT (object,
2707         "Attempting invalid transmission mode '%u' for delivery system '%u'",
2708         object->transmission_mode, object->delsys);
2709   }
2710   if (!gst_dvbsrc_is_valid_bandwidth (object->delsys, object->bandwidth)) {
2711     GST_WARNING_OBJECT (object,
2712         "Attempting invalid bandwidth '%u' for delivery system '%u'",
2713         object->bandwidth, object->delsys);
2714   }
2715 
2716   set_prop (props->props, &n, DTV_TUNE, 0);
2717   props->num = n;
2718   /* set first three entries */
2719   n = 0;
2720   set_prop (props->props, &n, DTV_DELIVERY_SYSTEM, object->delsys);
2721   set_prop (props->props, &n, DTV_FREQUENCY, freq);
2722   set_prop (props->props, &n, DTV_INVERSION, inversion);
2723 
2724   return TRUE;
2725 }
2726 
2727 static gboolean
gst_dvbsrc_tune(GstDvbSrc * object)2728 gst_dvbsrc_tune (GstDvbSrc * object)
2729 {
2730   /* found in mail archive on linuxtv.org
2731    * What works well for us is:
2732    * - first establish a TS feed (i.e. tune the frontend and check for success)
2733    * - then set filters (PES/sections)
2734    * - then tell the MPEG decoder to start
2735    * - before tuning: first stop the MPEG decoder, then stop all filters
2736    */
2737   if (!gst_dvbsrc_tune_fe (object)) {
2738     GST_WARNING_OBJECT (object, "Unable to tune frontend");
2739     return FALSE;
2740   }
2741 
2742   gst_dvbsrc_set_pes_filters (object);
2743 
2744   return TRUE;
2745 }
2746 
2747 
2748 static void
gst_dvbsrc_unset_pes_filters(GstDvbSrc * object)2749 gst_dvbsrc_unset_pes_filters (GstDvbSrc * object)
2750 {
2751   int i = 0;
2752 
2753   GST_INFO_OBJECT (object, "clearing PES filter");
2754 
2755   for (i = 0; i < MAX_FILTERS; i++) {
2756     if (object->fd_filters[i] == -1)
2757       continue;
2758     close (object->fd_filters[i]);
2759     object->fd_filters[i] = -1;
2760   }
2761 }
2762 
2763 static void
gst_dvbsrc_set_pes_filters(GstDvbSrc * object)2764 gst_dvbsrc_set_pes_filters (GstDvbSrc * object)
2765 {
2766   int *fd;
2767   int pid, i;
2768   struct dmx_pes_filter_params pes_filter;
2769   gint err;
2770   gchar *demux_dev = g_strdup_printf ("/dev/dvb/adapter%d/demux%d",
2771       object->adapter_number, object->frontend_number);
2772 
2773   GST_INFO_OBJECT (object, "Setting PES filter");
2774 
2775   /* Set common params for all filters */
2776   pes_filter.input = DMX_IN_FRONTEND;
2777   pes_filter.output = DMX_OUT_TS_TAP;
2778   pes_filter.pes_type = DMX_PES_OTHER;
2779   pes_filter.flags = DMX_IMMEDIATE_START;
2780 
2781   for (i = 0; i < MAX_FILTERS; i++) {
2782     if (object->pids[i] == G_MAXUINT16)
2783       break;
2784 
2785     fd = &object->fd_filters[i];
2786     pid = object->pids[i];
2787 
2788     if (*fd >= 0)
2789       close (*fd);
2790     if ((*fd = open (demux_dev, O_RDWR)) < 0) {
2791       GST_ERROR_OBJECT (object, "Error opening demuxer: %s (%s)",
2792           g_strerror (errno), demux_dev);
2793       continue;
2794     }
2795     g_return_if_fail (*fd != -1);
2796 
2797     pes_filter.pid = pid;
2798 
2799     GST_INFO_OBJECT (object, "Setting PES filter: pid = %d, type = %d",
2800         pes_filter.pid, pes_filter.pes_type);
2801 
2802     LOOP_WHILE_EINTR (err, ioctl (*fd, DMX_SET_PES_FILTER, &pes_filter));
2803     if (err)
2804       GST_WARNING_OBJECT (object, "Error setting PES filter on %s: %s",
2805           demux_dev, g_strerror (errno));
2806   }
2807 
2808   g_free (demux_dev);
2809 }
2810