Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 ================================
0004 vidtv: Virtual Digital TV driver
0005 ================================
0006 
0007 Author: Daniel W. S. Almeida <dwlsalmeida@gmail.com>, June 2020.
0008 
0009 Background
0010 ----------
0011 
0012 Vidtv is a virtual DVB driver that aims to serve as a reference for driver
0013 writers by serving as a template. It also validates the existing media DVB
0014 APIs, thus helping userspace application writers.
0015 
0016 Currently, it consists of:
0017 
0018 - A fake tuner driver, which will report a bad signal quality if the chosen
0019   frequency is too far away from a table of valid frequencies for a
0020   particular delivery system.
0021 
0022 - A fake demod driver, which will constantly poll the fake signal quality
0023   returned by the tuner, simulating a device that can lose/reacquire a lock
0024   on the signal depending on the CNR levels.
0025 
0026 - A fake bridge driver, which is the module responsible for modprobing the
0027   fake tuner and demod modules and implementing the demux logic. This module
0028   takes parameters at initialization that will dictate how the simulation
0029   behaves.
0030 
0031 - Code reponsible for encoding a valid MPEG Transport Stream, which is then
0032   passed to the bridge driver. This fake stream contains some hardcoded content.
0033   For now, we have a single, audio-only channel containing a single MPEG
0034   Elementary Stream, which in turn contains a SMPTE 302m encoded sine-wave.
0035   Note that this particular encoder was chosen because it is the easiest
0036   way to encode PCM audio data in a MPEG Transport Stream.
0037 
0038 Building vidtv
0039 --------------
0040 vidtv is a test driver and thus is **not** enabled by default when
0041 compiling the kernel.
0042 
0043 In order to enable compilation of vidtv:
0044 
0045 - Enable **DVB_TEST_DRIVERS**, then
0046 - Enable **DVB_VIDTV**
0047 
0048 When compiled as a module, expect the following .ko files:
0049 
0050 - dvb_vidtv_tuner.ko
0051 
0052 - dvb_vidtv_demod.ko
0053 
0054 - dvb_vidtv_bridge.ko
0055 
0056 Running vidtv
0057 -------------
0058 When compiled as a module, run::
0059 
0060         modprobe vidtv
0061 
0062 That's it! The bridge driver will initialize the tuner and demod drivers as
0063 part of its own initialization.
0064 
0065 By default, it will accept the following frequencies:
0066 
0067         - 474 MHz for DVB-T/T2/C;
0068         - 11,362 GHz for DVB-S/S2.
0069 
0070 For satellite systems, the driver simulates an universal extended
0071 LNBf, with frequencies at Ku-Band, ranging from 10.7 GHz to 12.75 GHz.
0072 
0073 You can optionally define some command-line arguments to vidtv.
0074 
0075 Command-line arguments to vidtv
0076 -------------------------------
0077 Below is a list of all arguments that can be supplied to vidtv:
0078 
0079 drop_tslock_prob_on_low_snr
0080         Probability of losing the TS lock if the signal quality is bad.
0081         This probability be used by the fake demodulator driver to
0082         eventually return a status of 0 when the signal quality is not
0083         good.
0084 
0085 recover_tslock_prob_on_good_snr:
0086         Probability recovering the TS lock when the signal improves. This
0087         probability be used by the fake demodulator driver to eventually
0088         return a status of 0x1f when/if the signal quality improves.
0089 
0090 mock_power_up_delay_msec
0091         Simulate a power up delay.  Default: 0.
0092 
0093 mock_tune_delay_msec
0094         Simulate a tune delay.  Default 0.
0095 
0096 vidtv_valid_dvb_t_freqs
0097         Valid DVB-T frequencies to simulate, in Hz.
0098 
0099 vidtv_valid_dvb_c_freqs
0100         Valid DVB-C frequencies to simulate, in Hz.
0101 
0102 vidtv_valid_dvb_s_freqs
0103         Valid DVB-S/S2 frequencies to simulate at Ku-Band, in kHz.
0104 
0105 max_frequency_shift_hz,
0106         Maximum shift in HZ allowed when tuning in a channel.
0107 
0108 si_period_msec
0109         How often to send SI packets.  Default: 40ms.
0110 
0111 pcr_period_msec
0112         How often to send PCR packets.  Default: 40ms.
0113 
0114 mux_rate_kbytes_sec
0115         Attempt to maintain this bit rate by inserting TS null packets, if
0116         necessary.  Default: 4096.
0117 
0118 pcr_pid,
0119         PCR PID for all channels.  Default: 0x200.
0120 
0121 mux_buf_sz_pkts,
0122         Size for the mux buffer in multiples of 188 bytes.
0123 
0124 vidtv internal structure
0125 ------------------------
0126 The kernel modules are split in the following way:
0127 
0128 vidtv_tuner.[ch]
0129         Implements a fake tuner DVB driver.
0130 
0131 vidtv_demod.[ch]
0132         Implements a fake demodulator DVB driver.
0133 
0134 vidtv_bridge.[ch]
0135         Implements a bridge driver.
0136 
0137 The MPEG related code is split in the following way:
0138 
0139 vidtv_ts.[ch]
0140         Code to work with MPEG TS packets, such as TS headers, adaptation
0141         fields, PCR packets and NULL packets.
0142 
0143 vidtv_psi.[ch]
0144         This is the PSI generator.  PSI packets contain general information
0145         about a MPEG Transport Stream.  A PSI generator is needed so
0146         userspace apps can retrieve information about the Transport Stream
0147         and eventually tune into a (dummy) channel.
0148 
0149         Because the generator is implemented in a separate file, it can be
0150         reused elsewhere in the media subsystem.
0151 
0152         Currently vidtv supports working with 5 PSI tables: PAT, PMT,
0153         SDT, NIT and EIT.
0154 
0155         The specification for PAT and PMT can be found in *ISO 13818-1:
0156         Systems*, while the specification for the SDT, NIT, EIT can be found in *ETSI
0157         EN 300 468: Specification for Service Information (SI) in DVB
0158         systems*.
0159 
0160         It isn't strictly necessary, but using a real TS file helps when
0161         debugging PSI tables. Vidtv currently tries to replicate the PSI
0162         structure found in this file: `TS1Globo.ts
0163         <https://tsduck.io/streams/brazil-isdb-tb/TS1globo.ts>`_.
0164 
0165         A good way to visualize the structure of streams is by using
0166         `DVBInspector <https://sourceforge.net/projects/dvbinspector/>`_.
0167 
0168 vidtv_pes.[ch]
0169         Implements the PES logic to convert encoder data into MPEG TS
0170         packets. These can then be fed into a TS multiplexer and eventually
0171         into userspace.
0172 
0173 vidtv_encoder.h
0174         An interface for vidtv encoders. New encoders can be added to this
0175         driver by implementing the calls in this file.
0176 
0177 vidtv_s302m.[ch]
0178         Implements a S302M encoder to make it possible to insert PCM audio
0179         data in the generated MPEG Transport Stream. The relevant
0180         specification is available online as *SMPTE 302M-2007: Television -
0181         Mapping of AES3 Data into MPEG-2 Transport Stream*.
0182 
0183 
0184         The resulting MPEG Elementary Stream is conveyed in a private
0185         stream with a S302M registration descriptor attached.
0186 
0187         This shall enable passing an audio signal into userspace so it can
0188         be decoded and played by media software. The corresponding decoder
0189         in ffmpeg is located in 'libavcodec/s302m.c' and is experimental.
0190 
0191 vidtv_channel.[ch]
0192         Implements a 'channel' abstraction.
0193 
0194         When vidtv boots, it will create some hardcoded channels:
0195 
0196         #. Their services will be concatenated to populate the SDT.
0197 
0198         #. Their programs will be concatenated to populate the PAT
0199 
0200         #. Their events will be concatenated to populate the EIT
0201 
0202         #. For each program in the PAT, a PMT section will be created
0203 
0204         #. The PMT section for a channel will be assigned its streams.
0205 
0206         #. Every stream will have its corresponding encoder polled in a
0207            loop to produce TS packets.
0208            These packets may be interleaved by the muxer and then delivered
0209            to the bridge.
0210 
0211 vidtv_mux.[ch]
0212         Implements a MPEG TS mux, loosely based on the ffmpeg
0213         implementation in "libavcodec/mpegtsenc.c"
0214 
0215         The muxer runs a loop which is responsible for:
0216 
0217         #. Keeping track of the amount of time elapsed since the last
0218            iteration.
0219 
0220         #. Polling encoders in order to fetch 'elapsed_time' worth of data.
0221 
0222         #. Inserting PSI and/or PCR packets, if needed.
0223 
0224         #. Padding the resulting stream with NULL packets if
0225            necessary in order to maintain the chosen bit rate.
0226 
0227         #. Delivering the resulting TS packets to the bridge
0228            driver so it can pass them to the demux.
0229 
0230 Testing vidtv with v4l-utils
0231 ----------------------------
0232 
0233 Using the tools in v4l-utils is a great way to test and inspect the output of
0234 vidtv. It is hosted here: `v4l-utils Documentation
0235 <https://linuxtv.org/wiki/index.php/V4l-utils>`_.
0236 
0237 From its webpage::
0238 
0239         The v4l-utils are a series of packages for handling media devices.
0240 
0241         It is hosted at http://git.linuxtv.org/v4l-utils.git, and packaged
0242         on most distributions.
0243 
0244         It provides a series of libraries and utilities to be used to
0245         control several aspect of the media boards.
0246 
0247 
0248 Start by installing v4l-utils and then modprobing vidtv::
0249 
0250         modprobe dvb_vidtv_bridge
0251 
0252 If the driver is OK, it should load and its probing code will run. This will
0253 pull in the tuner and demod drivers.
0254 
0255 Using dvb-fe-tool
0256 ~~~~~~~~~~~~~~~~~
0257 
0258 The first step to check whether the demod loaded successfully is to run::
0259 
0260         $ dvb-fe-tool
0261         Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities:
0262             CAN_FEC_1_2
0263             CAN_FEC_2_3
0264             CAN_FEC_3_4
0265             CAN_FEC_4_5
0266             CAN_FEC_5_6
0267             CAN_FEC_6_7
0268             CAN_FEC_7_8
0269             CAN_FEC_8_9
0270             CAN_FEC_AUTO
0271             CAN_GUARD_INTERVAL_AUTO
0272             CAN_HIERARCHY_AUTO
0273             CAN_INVERSION_AUTO
0274             CAN_QAM_16
0275             CAN_QAM_32
0276             CAN_QAM_64
0277             CAN_QAM_128
0278             CAN_QAM_256
0279             CAN_QAM_AUTO
0280             CAN_QPSK
0281             CAN_TRANSMISSION_MODE_AUTO
0282         DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A
0283         Supported delivery systems:
0284             DVBT
0285             DVBT2
0286             [DVBC/ANNEX_A]
0287             DVBS
0288             DVBS2
0289         Frequency range for the current standard:
0290         From:            51.0 MHz
0291         To:              2.15 GHz
0292         Step:            62.5 kHz
0293         Tolerance:       29.5 MHz
0294         Symbol rate ranges for the current standard:
0295         From:            1.00 MBauds
0296         To:              45.0 MBauds
0297 
0298 This should return what is currently set up at the demod struct, i.e.::
0299 
0300         static const struct dvb_frontend_ops vidtv_demod_ops = {
0301                 .delsys = {
0302                         SYS_DVBT,
0303                         SYS_DVBT2,
0304                         SYS_DVBC_ANNEX_A,
0305                         SYS_DVBS,
0306                         SYS_DVBS2,
0307                 },
0308 
0309                 .info = {
0310                         .name                   = "Dummy demod for DVB-T/T2/C/S/S2",
0311                         .frequency_min_hz       = 51 * MHz,
0312                         .frequency_max_hz       = 2150 * MHz,
0313                         .frequency_stepsize_hz  = 62500,
0314                         .frequency_tolerance_hz = 29500 * kHz,
0315                         .symbol_rate_min        = 1000000,
0316                         .symbol_rate_max        = 45000000,
0317 
0318                         .caps = FE_CAN_FEC_1_2 |
0319                                 FE_CAN_FEC_2_3 |
0320                                 FE_CAN_FEC_3_4 |
0321                                 FE_CAN_FEC_4_5 |
0322                                 FE_CAN_FEC_5_6 |
0323                                 FE_CAN_FEC_6_7 |
0324                                 FE_CAN_FEC_7_8 |
0325                                 FE_CAN_FEC_8_9 |
0326                                 FE_CAN_QAM_16 |
0327                                 FE_CAN_QAM_64 |
0328                                 FE_CAN_QAM_32 |
0329                                 FE_CAN_QAM_128 |
0330                                 FE_CAN_QAM_256 |
0331                                 FE_CAN_QAM_AUTO |
0332                                 FE_CAN_QPSK |
0333                                 FE_CAN_FEC_AUTO |
0334                                 FE_CAN_INVERSION_AUTO |
0335                                 FE_CAN_TRANSMISSION_MODE_AUTO |
0336                                 FE_CAN_GUARD_INTERVAL_AUTO |
0337                                 FE_CAN_HIERARCHY_AUTO,
0338                 }
0339 
0340                 ....
0341 
0342 For more information on dvb-fe-tools check its online documentation here:
0343 `dvb-fe-tool Documentation
0344 <https://www.linuxtv.org/wiki/index.php/Dvb-fe-tool>`_.
0345 
0346 Using dvb-scan
0347 ~~~~~~~~~~~~~~
0348 
0349 In order to tune into a channel and read the PSI tables, we can use dvb-scan.
0350 
0351 For this, one should provide a configuration file known as a 'scan file',
0352 here's an example::
0353 
0354         [Channel]
0355         FREQUENCY = 474000000
0356         MODULATION = QAM/AUTO
0357         SYMBOL_RATE = 6940000
0358         INNER_FEC = AUTO
0359         DELIVERY_SYSTEM = DVBC/ANNEX_A
0360 
0361 .. note::
0362         The parameters depend on the video standard you're testing.
0363 
0364 .. note::
0365         Vidtv is a fake driver and does not validate much of the information
0366         in the scan file. Just specifying 'FREQUENCY' and 'DELIVERY_SYSTEM'
0367         should be enough for DVB-T/DVB-T2. For DVB-S/DVB-C however, you
0368         should also provide 'SYMBOL_RATE'.
0369 
0370 You can browse scan tables online here: `dvb-scan-tables
0371 <https://git.linuxtv.org/dtv-scan-tables.git>`_.
0372 
0373 Assuming this channel is named 'channel.conf', you can then run::
0374 
0375         $ dvbv5-scan channel.conf
0376         dvbv5-scan ~/vidtv.conf
0377         ERROR    command BANDWIDTH_HZ (5) not found during retrieve
0378         Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet).
0379         Scanning frequency #1 330000000
0380             (0x00) Signal= -68.00dBm
0381         Scanning frequency #2 474000000
0382         Lock   (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0
0383         Service Beethoven, provider LinuxTV.org: digital television
0384 
0385 For more information on dvb-scan, check its documentation online here:
0386 `dvb-scan Documentation <https://www.linuxtv.org/wiki/index.php/Dvbscan>`_.
0387 
0388 Using dvb-zap
0389 ~~~~~~~~~~~~~
0390 
0391 dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The
0392 typical use is to tune into a channel and put it into record mode. The example
0393 below - which is taken from the documentation - illustrates that\ [1]_::
0394 
0395         $ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10
0396         using demux 'dvb0.demux0'
0397         reading channels from file 'dvb_channel.conf'
0398         tuning to 474000000 Hz
0399         pass all PID's to TS
0400         dvb_set_pesfilter 8192
0401         dvb_dev_set_bufsize: buffer set to 6160384
0402         Lock   (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
0403         Lock   (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
0404         Record to file 'music.ts' started
0405         received 24587768 bytes (2401 Kbytes/sec)
0406         Lock   (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0
0407 
0408 .. [1] In this example, it records 10 seconds with all program ID's stored
0409        at the music.ts file.
0410 
0411 
0412 The channel can be watched by playing the contents of the stream with some
0413 player that  recognizes the MPEG-TS format, such as ``mplayer`` or ``vlc``.
0414 
0415 By playing the contents of the stream one can visually inspect the workings of
0416 vidtv, e.g., to play a recorded TS file with::
0417 
0418         $ mplayer music.ts
0419 
0420 or, alternatively, running this command on one terminal::
0421 
0422         $ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r &
0423 
0424 And, on a second terminal, playing the contents from DVR interface with::
0425 
0426         $ mplayer /dev/dvb/adapter0/dvr0
0427 
0428 For more information on dvb-zap check its online documentation here:
0429 `dvb-zap Documentation
0430 <https://www.linuxtv.org/wiki/index.php/Dvbv5-zap>`_.
0431 See also: `zap <https://www.linuxtv.org/wiki/index.php/Zap>`_.
0432 
0433 
0434 What can still be improved in vidtv
0435 -----------------------------------
0436 
0437 Add *debugfs* integration
0438 ~~~~~~~~~~~~~~~~~~~~~~~~~
0439 
0440 Although frontend drivers provide DVBv5 statistics via the .read_status
0441 call, a nice addition would be to make additional statistics available to
0442 userspace via debugfs, which is a simple-to-use, RAM-based filesystem
0443 specifically designed for debug purposes.
0444 
0445 The logic for this would be implemented on a separate file so as not to
0446 pollute the frontend driver.  These statistics are driver-specific and can
0447 be useful during tests.
0448 
0449 The Siano driver is one example of a driver using
0450 debugfs to convey driver-specific statistics to userspace and it can be
0451 used as a reference.
0452 
0453 This should be further enabled and disabled via a Kconfig
0454 option for convenience.
0455 
0456 Add a way to test video
0457 ~~~~~~~~~~~~~~~~~~~~~~~
0458 
0459 Currently, vidtv can only encode PCM audio. It would be great to implement
0460 a barebones version of MPEG-2 video encoding so we can also test video. The
0461 first place to look into is *ISO 13818-2: Information technology — Generic
0462 coding of moving pictures and associated audio information — Part 2: Video*,
0463 which covers the encoding of compressed video in MPEG Transport Streams.
0464 
0465 This might optionally use the Video4Linux2 Test Pattern Generator, v4l2-tpg,
0466 which resides at::
0467 
0468         drivers/media/common/v4l2-tpg/
0469 
0470 
0471 Add white noise simulation
0472 ~~~~~~~~~~~~~~~~~~~~~~~~~~
0473 
0474 The vidtv tuner already has code to identify whether the chosen frequency
0475 is too far away from a table of valid frequencies. For now, this means that
0476 the demodulator can eventually lose the lock on the signal, since the tuner will
0477 report a bad signal quality.
0478 
0479 A nice addition is to simulate some noise when the signal quality is bad by:
0480 
0481 - Randomly dropping some TS packets. This will trigger a continuity error if the
0482   continuity counter is updated but the packet is not passed on to the demux.
0483 
0484 - Updating the error statistics accordingly (e.g. BER, etc).
0485 
0486 - Simulating some noise in the encoded data.
0487 
0488 Functions and structs used within vidtv
0489 ---------------------------------------
0490 
0491 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_bridge.h
0492 
0493 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_channel.h
0494 
0495 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_demod.h
0496 
0497 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_encoder.h
0498 
0499 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_mux.h
0500 
0501 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_pes.h
0502 
0503 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_psi.h
0504 
0505 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_s302m.h
0506 
0507 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_ts.h
0508 
0509 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.h
0510 
0511 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_common.c
0512 
0513 .. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.c