]>
Commit | Line | Data |
---|---|---|
1f9a7046 DA |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | ================================ | |
4 | vidtv: Virtual Digital TV driver | |
5 | ================================ | |
6 | ||
7 | Author: Daniel W. S. Almeida <dwlsalmeida@gmail.com>, June 2020. | |
8 | ||
9 | Background | |
10 | ---------- | |
11 | ||
12 | Vidtv is a virtual DVB driver that aims to serve as a reference for driver | |
13 | writers by serving as a template. It also validates the existing media DVB | |
14 | APIs, thus helping userspace application writers. | |
15 | ||
16 | Currently, it consists of: | |
17 | ||
18 | - A fake tuner driver, which will report a bad signal quality if the chosen | |
19 | frequency is too far away from a table of valid frequencies for a | |
20 | particular delivery system. | |
21 | ||
22 | - A fake demod driver, which will constantly poll the fake signal quality | |
23 | returned by the tuner, simulating a device that can lose/reacquire a lock | |
24 | on the signal depending on the CNR levels. | |
25 | ||
26 | - A fake bridge driver, which is the module responsible for modprobing the | |
27 | fake tuner and demod modules and implementing the demux logic. This module | |
28 | takes parameters at initialization that will dictate how the simulation | |
29 | behaves. | |
30 | ||
31 | - Code reponsible for encoding a valid MPEG Transport Stream, which is then | |
32 | passed to the bridge driver. This fake stream contains some hardcoded content. | |
33 | For now, we have a single, audio-only channel containing a single MPEG | |
34 | Elementary Stream, which in turn contains a SMPTE 302m encoded sine-wave. | |
35 | Note that this particular encoder was chosen because it is the easiest | |
36 | way to encode PCM audio data in a MPEG Transport Stream. | |
37 | ||
38 | Building vidtv | |
39 | -------------- | |
40 | vidtv is a test driver and thus is **not** enabled by default when | |
41 | compiling the kernel. | |
42 | ||
43 | In order to enable compilation of vidtv: | |
44 | ||
45 | - Enable **DVB_TEST_DRIVERS**, then | |
46 | - Enable **DVB_VIDTV** | |
47 | ||
48 | When compiled as a module, expect the following .ko files: | |
49 | ||
50 | - dvb_vidtv_tuner.ko | |
51 | ||
52 | - dvb_vidtv_demod.ko | |
53 | ||
54 | - dvb_vidtv_bridge.ko | |
55 | ||
56 | Running vidtv | |
57 | ------------- | |
58 | When compiled as a module, run:: | |
59 | ||
c9f968fa | 60 | modprobe vidtv |
1f9a7046 DA |
61 | |
62 | That's it! The bridge driver will initialize the tuner and demod drivers as | |
63 | part of its own initialization. | |
64 | ||
2cf846b1 MCC |
65 | By default, it will accept the following frequencies: |
66 | ||
67 | - 474 MHz for DVB-T/T2/C; | |
68 | - 11,362 GHz for DVB-S/S2. | |
69 | ||
70 | For satellite systems, the driver simulates an universal extended | |
71 | LNBf, with frequencies at Ku-Band, ranging from 10.7 GHz to 12.75 GHz. | |
72 | ||
1f9a7046 DA |
73 | You can optionally define some command-line arguments to vidtv. |
74 | ||
75 | Command-line arguments to vidtv | |
76 | ------------------------------- | |
77 | Below is a list of all arguments that can be supplied to vidtv: | |
78 | ||
79 | drop_tslock_prob_on_low_snr | |
80 | Probability of losing the TS lock if the signal quality is bad. | |
81 | This probability be used by the fake demodulator driver to | |
82 | eventually return a status of 0 when the signal quality is not | |
83 | good. | |
84 | ||
85 | recover_tslock_prob_on_good_snr: | |
86 | Probability recovering the TS lock when the signal improves. This | |
87 | probability be used by the fake demodulator driver to eventually | |
88 | return a status of 0x1f when/if the signal quality improves. | |
89 | ||
90 | mock_power_up_delay_msec | |
91 | Simulate a power up delay. Default: 0. | |
92 | ||
93 | mock_tune_delay_msec | |
94 | Simulate a tune delay. Default 0. | |
95 | ||
96 | vidtv_valid_dvb_t_freqs | |
2cf846b1 | 97 | Valid DVB-T frequencies to simulate, in Hz. |
1f9a7046 DA |
98 | |
99 | vidtv_valid_dvb_c_freqs | |
2cf846b1 | 100 | Valid DVB-C frequencies to simulate, in Hz. |
1f9a7046 DA |
101 | |
102 | vidtv_valid_dvb_s_freqs | |
2cf846b1 | 103 | Valid DVB-S/S2 frequencies to simulate at Ku-Band, in kHz. |
1f9a7046 DA |
104 | |
105 | max_frequency_shift_hz, | |
106 | Maximum shift in HZ allowed when tuning in a channel. | |
107 | ||
108 | si_period_msec | |
109 | How often to send SI packets. Default: 40ms. | |
110 | ||
111 | pcr_period_msec | |
112 | How often to send PCR packets. Default: 40ms. | |
113 | ||
114 | mux_rate_kbytes_sec | |
115 | Attempt to maintain this bit rate by inserting TS null packets, if | |
116 | necessary. Default: 4096. | |
117 | ||
118 | pcr_pid, | |
119 | PCR PID for all channels. Default: 0x200. | |
120 | ||
121 | mux_buf_sz_pkts, | |
122 | Size for the mux buffer in multiples of 188 bytes. | |
123 | ||
124 | vidtv internal structure | |
125 | ------------------------ | |
126 | The kernel modules are split in the following way: | |
127 | ||
128 | vidtv_tuner.[ch] | |
129 | Implements a fake tuner DVB driver. | |
130 | ||
131 | vidtv_demod.[ch] | |
132 | Implements a fake demodulator DVB driver. | |
133 | ||
134 | vidtv_bridge.[ch] | |
135 | Implements a bridge driver. | |
136 | ||
137 | The MPEG related code is split in the following way: | |
138 | ||
139 | vidtv_ts.[ch] | |
140 | Code to work with MPEG TS packets, such as TS headers, adaptation | |
141 | fields, PCR packets and NULL packets. | |
142 | ||
143 | vidtv_psi.[ch] | |
144 | This is the PSI generator. PSI packets contain general information | |
145 | about a MPEG Transport Stream. A PSI generator is needed so | |
146 | userspace apps can retrieve information about the Transport Stream | |
147 | and eventually tune into a (dummy) channel. | |
148 | ||
149 | Because the generator is implemented in a separate file, it can be | |
150 | reused elsewhere in the media subsystem. | |
151 | ||
7a7899f6 DA |
152 | Currently vidtv supports working with 5 PSI tables: PAT, PMT, |
153 | SDT, NIT and EIT. | |
1f9a7046 DA |
154 | |
155 | The specification for PAT and PMT can be found in *ISO 13818-1: | |
7a7899f6 | 156 | Systems*, while the specification for the SDT, NIT, EIT can be found in *ETSI |
1f9a7046 DA |
157 | EN 300 468: Specification for Service Information (SI) in DVB |
158 | systems*. | |
159 | ||
160 | It isn't strictly necessary, but using a real TS file helps when | |
161 | debugging PSI tables. Vidtv currently tries to replicate the PSI | |
162 | structure found in this file: `TS1Globo.ts | |
163 | <https://tsduck.io/streams/brazil-isdb-tb/TS1globo.ts>`_. | |
164 | ||
165 | A good way to visualize the structure of streams is by using | |
166 | `DVBInspector <https://sourceforge.net/projects/dvbinspector/>`_. | |
167 | ||
168 | vidtv_pes.[ch] | |
169 | Implements the PES logic to convert encoder data into MPEG TS | |
170 | packets. These can then be fed into a TS multiplexer and eventually | |
171 | into userspace. | |
172 | ||
173 | vidtv_encoder.h | |
174 | An interface for vidtv encoders. New encoders can be added to this | |
175 | driver by implementing the calls in this file. | |
176 | ||
177 | vidtv_s302m.[ch] | |
178 | Implements a S302M encoder to make it possible to insert PCM audio | |
179 | data in the generated MPEG Transport Stream. The relevant | |
180 | specification is available online as *SMPTE 302M-2007: Television - | |
181 | Mapping of AES3 Data into MPEG-2 Transport Stream*. | |
182 | ||
183 | ||
184 | The resulting MPEG Elementary Stream is conveyed in a private | |
185 | stream with a S302M registration descriptor attached. | |
186 | ||
187 | This shall enable passing an audio signal into userspace so it can | |
188 | be decoded and played by media software. The corresponding decoder | |
189 | in ffmpeg is located in 'libavcodec/s302m.c' and is experimental. | |
190 | ||
191 | vidtv_channel.[ch] | |
192 | Implements a 'channel' abstraction. | |
193 | ||
194 | When vidtv boots, it will create some hardcoded channels: | |
195 | ||
196 | #. Their services will be concatenated to populate the SDT. | |
197 | ||
198 | #. Their programs will be concatenated to populate the PAT | |
199 | ||
7a7899f6 DA |
200 | #. Their events will be concatenated to populate the EIT |
201 | ||
1f9a7046 DA |
202 | #. For each program in the PAT, a PMT section will be created |
203 | ||
204 | #. The PMT section for a channel will be assigned its streams. | |
205 | ||
206 | #. Every stream will have its corresponding encoder polled in a | |
207 | loop to produce TS packets. | |
208 | These packets may be interleaved by the muxer and then delivered | |
209 | to the bridge. | |
210 | ||
211 | vidtv_mux.[ch] | |
212 | Implements a MPEG TS mux, loosely based on the ffmpeg | |
213 | implementation in "libavcodec/mpegtsenc.c" | |
214 | ||
215 | The muxer runs a loop which is responsible for: | |
216 | ||
217 | #. Keeping track of the amount of time elapsed since the last | |
218 | iteration. | |
219 | ||
220 | #. Polling encoders in order to fetch 'elapsed_time' worth of data. | |
221 | ||
222 | #. Inserting PSI and/or PCR packets, if needed. | |
223 | ||
224 | #. Padding the resulting stream with NULL packets if | |
225 | necessary in order to maintain the chosen bit rate. | |
226 | ||
227 | #. Delivering the resulting TS packets to the bridge | |
228 | driver so it can pass them to the demux. | |
229 | ||
230 | Testing vidtv with v4l-utils | |
231 | ---------------------------- | |
232 | ||
233 | Using the tools in v4l-utils is a great way to test and inspect the output of | |
234 | vidtv. It is hosted here: `v4l-utils Documentation | |
235 | <https://linuxtv.org/wiki/index.php/V4l-utils>`_. | |
236 | ||
237 | From its webpage:: | |
238 | ||
239 | The v4l-utils are a series of packages for handling media devices. | |
240 | ||
241 | It is hosted at http://git.linuxtv.org/v4l-utils.git, and packaged | |
242 | on most distributions. | |
243 | ||
244 | It provides a series of libraries and utilities to be used to | |
245 | control several aspect of the media boards. | |
246 | ||
247 | ||
248 | Start by installing v4l-utils and then modprobing vidtv:: | |
249 | ||
250 | modprobe dvb_vidtv_bridge | |
251 | ||
252 | If the driver is OK, it should load and its probing code will run. This will | |
253 | pull in the tuner and demod drivers. | |
254 | ||
255 | Using dvb-fe-tool | |
256 | ~~~~~~~~~~~~~~~~~ | |
257 | ||
258 | The first step to check whether the demod loaded successfully is to run:: | |
259 | ||
260 | $ dvb-fe-tool | |
020120af MCC |
261 | Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities: |
262 | CAN_FEC_1_2 | |
263 | CAN_FEC_2_3 | |
264 | CAN_FEC_3_4 | |
265 | CAN_FEC_4_5 | |
266 | CAN_FEC_5_6 | |
267 | CAN_FEC_6_7 | |
268 | CAN_FEC_7_8 | |
269 | CAN_FEC_8_9 | |
270 | CAN_FEC_AUTO | |
271 | CAN_GUARD_INTERVAL_AUTO | |
272 | CAN_HIERARCHY_AUTO | |
273 | CAN_INVERSION_AUTO | |
274 | CAN_QAM_16 | |
275 | CAN_QAM_32 | |
276 | CAN_QAM_64 | |
277 | CAN_QAM_128 | |
278 | CAN_QAM_256 | |
279 | CAN_QAM_AUTO | |
280 | CAN_QPSK | |
281 | CAN_TRANSMISSION_MODE_AUTO | |
282 | DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A | |
283 | Supported delivery systems: | |
284 | DVBT | |
285 | DVBT2 | |
286 | [DVBC/ANNEX_A] | |
287 | DVBS | |
288 | DVBS2 | |
289 | Frequency range for the current standard: | |
290 | From: 51.0 MHz | |
291 | To: 2.15 GHz | |
292 | Step: 62.5 kHz | |
293 | Tolerance: 29.5 MHz | |
294 | Symbol rate ranges for the current standard: | |
295 | From: 1.00 MBauds | |
296 | To: 45.0 MBauds | |
1f9a7046 DA |
297 | |
298 | This should return what is currently set up at the demod struct, i.e.:: | |
299 | ||
300 | static const struct dvb_frontend_ops vidtv_demod_ops = { | |
301 | .delsys = { | |
302 | SYS_DVBT, | |
303 | SYS_DVBT2, | |
304 | SYS_DVBC_ANNEX_A, | |
305 | SYS_DVBS, | |
306 | SYS_DVBS2, | |
307 | }, | |
308 | ||
309 | .info = { | |
310 | .name = "Dummy demod for DVB-T/T2/C/S/S2", | |
311 | .frequency_min_hz = 51 * MHz, | |
312 | .frequency_max_hz = 2150 * MHz, | |
313 | .frequency_stepsize_hz = 62500, | |
314 | .frequency_tolerance_hz = 29500 * kHz, | |
315 | .symbol_rate_min = 1000000, | |
316 | .symbol_rate_max = 45000000, | |
317 | ||
318 | .caps = FE_CAN_FEC_1_2 | | |
319 | FE_CAN_FEC_2_3 | | |
320 | FE_CAN_FEC_3_4 | | |
321 | FE_CAN_FEC_4_5 | | |
322 | FE_CAN_FEC_5_6 | | |
323 | FE_CAN_FEC_6_7 | | |
324 | FE_CAN_FEC_7_8 | | |
325 | FE_CAN_FEC_8_9 | | |
326 | FE_CAN_QAM_16 | | |
327 | FE_CAN_QAM_64 | | |
328 | FE_CAN_QAM_32 | | |
329 | FE_CAN_QAM_128 | | |
330 | FE_CAN_QAM_256 | | |
331 | FE_CAN_QAM_AUTO | | |
332 | FE_CAN_QPSK | | |
333 | FE_CAN_FEC_AUTO | | |
334 | FE_CAN_INVERSION_AUTO | | |
335 | FE_CAN_TRANSMISSION_MODE_AUTO | | |
336 | FE_CAN_GUARD_INTERVAL_AUTO | | |
337 | FE_CAN_HIERARCHY_AUTO, | |
338 | } | |
339 | ||
340 | .... | |
341 | ||
342 | For more information on dvb-fe-tools check its online documentation here: | |
343 | `dvb-fe-tool Documentation | |
344 | <https://www.linuxtv.org/wiki/index.php/Dvb-fe-tool>`_. | |
345 | ||
346 | Using dvb-scan | |
347 | ~~~~~~~~~~~~~~ | |
348 | ||
349 | In order to tune into a channel and read the PSI tables, we can use dvb-scan. | |
350 | ||
351 | For this, one should provide a configuration file known as a 'scan file', | |
352 | here's an example:: | |
353 | ||
354 | [Channel] | |
020120af | 355 | FREQUENCY = 474000000 |
1f9a7046 DA |
356 | MODULATION = QAM/AUTO |
357 | SYMBOL_RATE = 6940000 | |
358 | INNER_FEC = AUTO | |
359 | DELIVERY_SYSTEM = DVBC/ANNEX_A | |
360 | ||
361 | .. note:: | |
362 | The parameters depend on the video standard you're testing. | |
363 | ||
364 | .. note:: | |
365 | Vidtv is a fake driver and does not validate much of the information | |
366 | in the scan file. Just specifying 'FREQUENCY' and 'DELIVERY_SYSTEM' | |
367 | should be enough for DVB-T/DVB-T2. For DVB-S/DVB-C however, you | |
368 | should also provide 'SYMBOL_RATE'. | |
369 | ||
370 | You can browse scan tables online here: `dvb-scan-tables | |
371 | <https://git.linuxtv.org/dtv-scan-tables.git>`_. | |
372 | ||
373 | Assuming this channel is named 'channel.conf', you can then run:: | |
374 | ||
375 | $ dvbv5-scan channel.conf | |
020120af MCC |
376 | dvbv5-scan ~/vidtv.conf |
377 | ERROR command BANDWIDTH_HZ (5) not found during retrieve | |
378 | Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet). | |
379 | Scanning frequency #1 330000000 | |
380 | (0x00) Signal= -68.00dBm | |
381 | Scanning frequency #2 474000000 | |
382 | Lock (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0 | |
383 | Service Beethoven, provider LinuxTV.org: digital television | |
1f9a7046 DA |
384 | |
385 | For more information on dvb-scan, check its documentation online here: | |
386 | `dvb-scan Documentation <https://www.linuxtv.org/wiki/index.php/Dvbscan>`_. | |
387 | ||
388 | Using dvb-zap | |
389 | ~~~~~~~~~~~~~ | |
390 | ||
391 | dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The | |
392 | typical use is to tune into a channel and put it into record mode. The example | |
020120af | 393 | below - which is taken from the documentation - illustrates that\ [1]_:: |
1f9a7046 | 394 | |
020120af MCC |
395 | $ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10 |
396 | using demux 'dvb0.demux0' | |
1f9a7046 | 397 | reading channels from file 'dvb_channel.conf' |
020120af MCC |
398 | tuning to 474000000 Hz |
399 | pass all PID's to TS | |
400 | dvb_set_pesfilter 8192 | |
401 | dvb_dev_set_bufsize: buffer set to 6160384 | |
402 | Lock (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0 | |
403 | Lock (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0 | |
404 | Record to file 'music.ts' started | |
405 | received 24587768 bytes (2401 Kbytes/sec) | |
406 | Lock (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0 | |
1f9a7046 | 407 | |
020120af MCC |
408 | .. [1] In this example, it records 10 seconds with all program ID's stored |
409 | at the music.ts file. | |
410 | ||
411 | ||
412 | The channel can be watched by playing the contents of the stream with some | |
413 | player that recognizes the MPEG-TS format, such as ``mplayer`` or ``vlc``. | |
1f9a7046 DA |
414 | |
415 | By playing the contents of the stream one can visually inspect the workings of | |
020120af MCC |
416 | vidtv, e.g., to play a recorded TS file with:: |
417 | ||
418 | $ mplayer music.ts | |
419 | ||
420 | or, alternatively, running this command on one terminal:: | |
421 | ||
422 | $ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r & | |
423 | ||
424 | And, on a second terminal, playing the contents from DVR interface with:: | |
1f9a7046 DA |
425 | |
426 | $ mplayer /dev/dvb/adapter0/dvr0 | |
427 | ||
428 | For more information on dvb-zap check its online documentation here: | |
429 | `dvb-zap Documentation | |
430 | <https://www.linuxtv.org/wiki/index.php/Dvbv5-zap>`_. | |
431 | See also: `zap <https://www.linuxtv.org/wiki/index.php/Zap>`_. | |
432 | ||
433 | ||
434 | What can still be improved in vidtv | |
435 | ----------------------------------- | |
436 | ||
437 | Add *debugfs* integration | |
438 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
439 | ||
440 | Although frontend drivers provide DVBv5 statistics via the .read_status | |
441 | call, a nice addition would be to make additional statistics available to | |
442 | userspace via debugfs, which is a simple-to-use, RAM-based filesystem | |
443 | specifically designed for debug purposes. | |
444 | ||
445 | The logic for this would be implemented on a separate file so as not to | |
446 | pollute the frontend driver. These statistics are driver-specific and can | |
447 | be useful during tests. | |
448 | ||
449 | The Siano driver is one example of a driver using | |
450 | debugfs to convey driver-specific statistics to userspace and it can be | |
451 | used as a reference. | |
452 | ||
453 | This should be further enabled and disabled via a Kconfig | |
454 | option for convenience. | |
455 | ||
456 | Add a way to test video | |
457 | ~~~~~~~~~~~~~~~~~~~~~~~ | |
458 | ||
459 | Currently, vidtv can only encode PCM audio. It would be great to implement | |
460 | a barebones version of MPEG-2 video encoding so we can also test video. The | |
461 | first place to look into is *ISO 13818-2: Information technology — Generic | |
462 | coding of moving pictures and associated audio information — Part 2: Video*, | |
463 | which covers the encoding of compressed video in MPEG Transport Streams. | |
464 | ||
465 | This might optionally use the Video4Linux2 Test Pattern Generator, v4l2-tpg, | |
466 | which resides at:: | |
467 | ||
468 | drivers/media/common/v4l2-tpg/ | |
469 | ||
470 | ||
471 | Add white noise simulation | |
472 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
473 | ||
474 | The vidtv tuner already has code to identify whether the chosen frequency | |
475 | is too far away from a table of valid frequencies. For now, this means that | |
476 | the demodulator can eventually lose the lock on the signal, since the tuner will | |
477 | report a bad signal quality. | |
478 | ||
479 | A nice addition is to simulate some noise when the signal quality is bad by: | |
480 | ||
481 | - Randomly dropping some TS packets. This will trigger a continuity error if the | |
482 | continuity counter is updated but the packet is not passed on to the demux. | |
483 | ||
484 | - Updating the error statistics accordingly (e.g. BER, etc). | |
485 | ||
486 | - Simulating some noise in the encoded data. |