2020-08-26 15:03:09 +08:00
|
|
|
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
|
2020-09-24 20:04:26 +08:00
|
|
|
.. c:namespace:: V4L
|
2018-08-30 22:15:26 +08:00
|
|
|
|
2016-06-30 21:18:56 +08:00
|
|
|
.. _rds:
|
|
|
|
|
|
|
|
*************
|
|
|
|
RDS Interface
|
|
|
|
*************
|
|
|
|
|
|
|
|
The Radio Data System transmits supplementary information in binary
|
|
|
|
format, for example the station name or travel information, on an
|
|
|
|
inaudible audio subcarrier of a radio program. This interface is aimed
|
|
|
|
at devices capable of receiving and/or transmitting RDS information.
|
|
|
|
|
|
|
|
For more information see the core RDS standard :ref:`iec62106` and the
|
|
|
|
RBDS standard :ref:`nrsc4`.
|
|
|
|
|
2016-08-16 04:49:50 +08:00
|
|
|
.. note::
|
|
|
|
|
|
|
|
Note that the RBDS standard as is used in the USA is almost
|
2016-07-10 22:57:43 +08:00
|
|
|
identical to the RDS standard. Any RDS decoder/encoder can also handle
|
|
|
|
RBDS. Only some of the fields have slightly different meanings. See the
|
|
|
|
RBDS standard for more information.
|
2016-06-30 21:18:56 +08:00
|
|
|
|
|
|
|
The RBDS standard also specifies support for MMBS (Modified Mobile
|
|
|
|
Search). This is a proprietary format which seems to be discontinued.
|
|
|
|
The RDS interface does not support this format. Should support for MMBS
|
|
|
|
(or the so-called 'E blocks' in general) be needed, then please contact
|
|
|
|
the linux-media mailing list:
|
|
|
|
`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
|
|
|
|
|
|
|
|
Querying Capabilities
|
|
|
|
=====================
|
|
|
|
|
|
|
|
Devices supporting the RDS capturing API set the
|
|
|
|
``V4L2_CAP_RDS_CAPTURE`` flag in the ``capabilities`` field of struct
|
2016-08-30 04:37:59 +08:00
|
|
|
:c:type:`v4l2_capability` returned by the
|
2016-07-02 00:58:44 +08:00
|
|
|
:ref:`VIDIOC_QUERYCAP` ioctl. Any tuner that
|
2016-06-30 21:18:56 +08:00
|
|
|
supports RDS will set the ``V4L2_TUNER_CAP_RDS`` flag in the
|
2016-08-30 04:37:59 +08:00
|
|
|
``capability`` field of struct :c:type:`v4l2_tuner`. If the
|
2016-06-30 21:18:56 +08:00
|
|
|
driver only passes RDS blocks without interpreting the data the
|
|
|
|
``V4L2_TUNER_CAP_RDS_BLOCK_IO`` flag has to be set, see
|
|
|
|
:ref:`Reading RDS data <reading-rds-data>`. For future use the flag
|
|
|
|
``V4L2_TUNER_CAP_RDS_CONTROLS`` has also been defined. However, a driver
|
|
|
|
for a radio tuner with this capability does not yet exist, so if you are
|
|
|
|
planning to write such a driver you should discuss this on the
|
|
|
|
linux-media mailing list:
|
|
|
|
`https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
|
|
|
|
|
|
|
|
Whether an RDS signal is present can be detected by looking at the
|
2016-08-30 04:37:59 +08:00
|
|
|
``rxsubchans`` field of struct :c:type:`v4l2_tuner`: the
|
2016-06-30 21:18:56 +08:00
|
|
|
``V4L2_TUNER_SUB_RDS`` will be set if RDS data was detected.
|
|
|
|
|
|
|
|
Devices supporting the RDS output API set the ``V4L2_CAP_RDS_OUTPUT``
|
|
|
|
flag in the ``capabilities`` field of struct
|
2016-08-30 04:37:59 +08:00
|
|
|
:c:type:`v4l2_capability` returned by the
|
2016-07-02 00:58:44 +08:00
|
|
|
:ref:`VIDIOC_QUERYCAP` ioctl. Any modulator that
|
2016-06-30 21:18:56 +08:00
|
|
|
supports RDS will set the ``V4L2_TUNER_CAP_RDS`` flag in the
|
|
|
|
``capability`` field of struct
|
2016-08-30 04:37:59 +08:00
|
|
|
:c:type:`v4l2_modulator`. In order to enable the RDS
|
2016-06-30 21:18:56 +08:00
|
|
|
transmission one must set the ``V4L2_TUNER_SUB_RDS`` bit in the
|
|
|
|
``txsubchans`` field of struct
|
2016-08-30 04:37:59 +08:00
|
|
|
:c:type:`v4l2_modulator`. If the driver only passes RDS
|
2016-06-30 21:18:56 +08:00
|
|
|
blocks without interpreting the data the ``V4L2_TUNER_CAP_RDS_BLOCK_IO``
|
|
|
|
flag has to be set. If the tuner is capable of handling RDS entities
|
|
|
|
like program identification codes and radio text, the flag
|
|
|
|
``V4L2_TUNER_CAP_RDS_CONTROLS`` should be set, see
|
|
|
|
:ref:`Writing RDS data <writing-rds-data>` and
|
|
|
|
:ref:`FM Transmitter Control Reference <fm-tx-controls>`.
|
|
|
|
|
|
|
|
.. _reading-rds-data:
|
|
|
|
|
|
|
|
Reading RDS data
|
|
|
|
================
|
|
|
|
|
|
|
|
RDS data can be read from the radio device with the
|
2020-09-24 20:04:26 +08:00
|
|
|
:c:func:`read()` function. The data is packed in groups of
|
2016-06-30 21:18:56 +08:00
|
|
|
three bytes.
|
|
|
|
|
|
|
|
.. _writing-rds-data:
|
|
|
|
|
|
|
|
Writing RDS data
|
|
|
|
================
|
|
|
|
|
|
|
|
RDS data can be written to the radio device with the
|
2020-09-24 20:04:26 +08:00
|
|
|
:c:func:`write()` function. The data is packed in groups of
|
2016-06-30 21:18:56 +08:00
|
|
|
three bytes, as follows:
|
|
|
|
|
|
|
|
RDS datastructures
|
|
|
|
==================
|
|
|
|
|
2016-08-30 04:37:59 +08:00
|
|
|
.. c:type:: v4l2_rds_data
|
2016-06-30 21:18:56 +08:00
|
|
|
|
|
|
|
.. flat-table:: struct v4l2_rds_data
|
|
|
|
:header-rows: 0
|
|
|
|
:stub-columns: 0
|
|
|
|
:widths: 1 1 5
|
|
|
|
|
[media] v4l: doc: Remove row numbers from tables
Shorten the tables by removing row numbers in comments, allowing for
later insertion of rows with minimal diffs.
All changes have been generated by the following script.
import io
import re
import sys
def process_table(fname, data):
if fname.endswith('hist-v4l2.rst'):
data = re.sub(u'\n{1,2}\t( ?) -( ?) ?', u'\n\t\\1 -\\2', data, flags = re.MULTILINE)
data = re.sub(u'\n(\t| )- \.\. row [0-9]+\n\t ?-( ?) ?', u'\\1* -\\2', data, flags = re.MULTILINE)
else:
data = re.sub(u'\n{1,2} -( ?) ?', u'\n -\\1', data, flags = re.MULTILINE)
data = re.sub(u'(\n?)(\n\n - \.\. row 1\n)', u'\n\\2', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. row [0-9]+\n -( ?) ?', u' * -\\1', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. row [0-9]+\n \.\. (_[A-Z0-9_`-]*:)', u'\n - .. \\1', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. (_[A-Z0-9_`-]*:)\n -', u' * .. \\1\n\n -', data, flags = re.MULTILINE)
data = re.sub(u'^ - ', u' -', data, flags = re.MULTILINE)
data = re.sub(u'^(\t{1,2}) ', u'\\1', data, flags = re.MULTILINE)
return data
def process_file(fname, data):
buf = io.StringIO(data)
output = ''
in_table = False
table_separator = 0
for line in buf.readlines():
if line.find('.. flat-table::') != -1:
in_table = True
table = ''
elif in_table and not re.match('^[\t\n]|( )', line):
in_table = False
output += process_table(fname, table)
if in_table:
table += line
else:
output += line
if in_table:
in_table = False
output += process_table(fname, table)
return output
fname = sys.argv[1]
data = file(fname, 'rb').read().decode('utf-8')
data = process_file(fname, data)
file(fname, 'wb').write(data.encode('utf-8'))
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2016-09-05 19:44:34 +08:00
|
|
|
* - __u8
|
|
|
|
- ``lsb``
|
|
|
|
- Least Significant Byte of RDS Block
|
|
|
|
* - __u8
|
|
|
|
- ``msb``
|
|
|
|
- Most Significant Byte of RDS Block
|
|
|
|
* - __u8
|
|
|
|
- ``block``
|
|
|
|
- Block description
|
2016-06-30 21:18:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
.. _v4l2-rds-block:
|
|
|
|
|
[media] docs-rst: add tabularcolumns to all tables
LaTeX doesn't handle too well auto-width on tables, and ReST
markup requires an special tag to give it the needed hints.
As we're using A4 paper, we have 17cm of useful spaces. As
most media tables have widths, let's use it to generate the
needed via the following perl script:
my ($line_size, $table_header, $has_cols) = (17.5, 0, 0);
my $out;
my $header = "";
my @widths = ();
sub round { $_[0] > 0 ? int($_[0] + .5) : -int(-$_[0] + .5) }
while (<>) {
if (!$table_header) {
$has_cols = 1 if (m/..\s+tabularcolumns::/);
if (m/..\s+flat-table::/) {
$table_header = 1;
$header = $_;
next;
}
$out .= $_;
next;
}
$header .= $_;
@widths = split(/ /, $1) if (m/:widths:\s+(.*)/);
if (m/^\n$/) {
if (!$has_cols && @widths) {
my ($tot, $t, $i) = (0, 0, 0);
foreach my $v(@widths) { $tot += $v; };
$out .= ".. tabularcolumns:: |";
for ($i = 0; $i < scalar @widths - 1; $i++) {
my $v = $widths[$i];
my $w = round(10 * ($v * $line_size) / $tot) / 10;
$out .= sprintf "p{%.1fcm}|", $w;
$t += $w;
}
my $w = $line_size - $t;
$out .= sprintf "p{%.1fcm}|\n\n", $w;
}
$out .= $header;
$table_header = 0;
$has_cols = 0;
$header = "";
@widths = ();
}
}
print $out;
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-08-17 19:14:19 +08:00
|
|
|
.. tabularcolumns:: |p{2.9cm}|p{14.6cm}|
|
|
|
|
|
2016-06-30 21:18:56 +08:00
|
|
|
.. flat-table:: Block description
|
|
|
|
:header-rows: 0
|
|
|
|
:stub-columns: 0
|
|
|
|
:widths: 1 5
|
|
|
|
|
[media] v4l: doc: Remove row numbers from tables
Shorten the tables by removing row numbers in comments, allowing for
later insertion of rows with minimal diffs.
All changes have been generated by the following script.
import io
import re
import sys
def process_table(fname, data):
if fname.endswith('hist-v4l2.rst'):
data = re.sub(u'\n{1,2}\t( ?) -( ?) ?', u'\n\t\\1 -\\2', data, flags = re.MULTILINE)
data = re.sub(u'\n(\t| )- \.\. row [0-9]+\n\t ?-( ?) ?', u'\\1* -\\2', data, flags = re.MULTILINE)
else:
data = re.sub(u'\n{1,2} -( ?) ?', u'\n -\\1', data, flags = re.MULTILINE)
data = re.sub(u'(\n?)(\n\n - \.\. row 1\n)', u'\n\\2', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. row [0-9]+\n -( ?) ?', u' * -\\1', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. row [0-9]+\n \.\. (_[A-Z0-9_`-]*:)', u'\n - .. \\1', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. (_[A-Z0-9_`-]*:)\n -', u' * .. \\1\n\n -', data, flags = re.MULTILINE)
data = re.sub(u'^ - ', u' -', data, flags = re.MULTILINE)
data = re.sub(u'^(\t{1,2}) ', u'\\1', data, flags = re.MULTILINE)
return data
def process_file(fname, data):
buf = io.StringIO(data)
output = ''
in_table = False
table_separator = 0
for line in buf.readlines():
if line.find('.. flat-table::') != -1:
in_table = True
table = ''
elif in_table and not re.match('^[\t\n]|( )', line):
in_table = False
output += process_table(fname, table)
if in_table:
table += line
else:
output += line
if in_table:
in_table = False
output += process_table(fname, table)
return output
fname = sys.argv[1]
data = file(fname, 'rb').read().decode('utf-8')
data = process_file(fname, data)
file(fname, 'wb').write(data.encode('utf-8'))
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2016-09-05 19:44:34 +08:00
|
|
|
* - Bits 0-2
|
|
|
|
- Block (aka offset) of the received data.
|
|
|
|
* - Bits 3-5
|
|
|
|
- Deprecated. Currently identical to bits 0-2. Do not use these
|
|
|
|
bits.
|
|
|
|
* - Bit 6
|
|
|
|
- Corrected bit. Indicates that an error was corrected for this data
|
|
|
|
block.
|
|
|
|
* - Bit 7
|
|
|
|
- Error bit. Indicates that an uncorrectable error occurred during
|
|
|
|
reception of this block.
|
2016-06-30 21:18:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
.. _v4l2-rds-block-codes:
|
|
|
|
|
2020-12-10 18:39:46 +08:00
|
|
|
.. tabularcolumns:: |p{6.4cm}|p{2.0cm}|p{1.2cm}|p{7.0cm}|
|
[media] docs-rst: add tabularcolumns to all tables
LaTeX doesn't handle too well auto-width on tables, and ReST
markup requires an special tag to give it the needed hints.
As we're using A4 paper, we have 17cm of useful spaces. As
most media tables have widths, let's use it to generate the
needed via the following perl script:
my ($line_size, $table_header, $has_cols) = (17.5, 0, 0);
my $out;
my $header = "";
my @widths = ();
sub round { $_[0] > 0 ? int($_[0] + .5) : -int(-$_[0] + .5) }
while (<>) {
if (!$table_header) {
$has_cols = 1 if (m/..\s+tabularcolumns::/);
if (m/..\s+flat-table::/) {
$table_header = 1;
$header = $_;
next;
}
$out .= $_;
next;
}
$header .= $_;
@widths = split(/ /, $1) if (m/:widths:\s+(.*)/);
if (m/^\n$/) {
if (!$has_cols && @widths) {
my ($tot, $t, $i) = (0, 0, 0);
foreach my $v(@widths) { $tot += $v; };
$out .= ".. tabularcolumns:: |";
for ($i = 0; $i < scalar @widths - 1; $i++) {
my $v = $widths[$i];
my $w = round(10 * ($v * $line_size) / $tot) / 10;
$out .= sprintf "p{%.1fcm}|", $w;
$t += $w;
}
my $w = $line_size - $t;
$out .= sprintf "p{%.1fcm}|\n\n", $w;
}
$out .= $header;
$table_header = 0;
$has_cols = 0;
$header = "";
@widths = ();
}
}
print $out;
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-08-17 19:14:19 +08:00
|
|
|
|
2016-06-30 21:18:56 +08:00
|
|
|
.. flat-table:: Block defines
|
|
|
|
:header-rows: 0
|
|
|
|
:stub-columns: 0
|
|
|
|
:widths: 1 1 1 5
|
|
|
|
|
[media] v4l: doc: Remove row numbers from tables
Shorten the tables by removing row numbers in comments, allowing for
later insertion of rows with minimal diffs.
All changes have been generated by the following script.
import io
import re
import sys
def process_table(fname, data):
if fname.endswith('hist-v4l2.rst'):
data = re.sub(u'\n{1,2}\t( ?) -( ?) ?', u'\n\t\\1 -\\2', data, flags = re.MULTILINE)
data = re.sub(u'\n(\t| )- \.\. row [0-9]+\n\t ?-( ?) ?', u'\\1* -\\2', data, flags = re.MULTILINE)
else:
data = re.sub(u'\n{1,2} -( ?) ?', u'\n -\\1', data, flags = re.MULTILINE)
data = re.sub(u'(\n?)(\n\n - \.\. row 1\n)', u'\n\\2', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. row [0-9]+\n -( ?) ?', u' * -\\1', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. row [0-9]+\n \.\. (_[A-Z0-9_`-]*:)', u'\n - .. \\1', data, flags = re.MULTILINE)
data = re.sub(u'\n - \.\. (_[A-Z0-9_`-]*:)\n -', u' * .. \\1\n\n -', data, flags = re.MULTILINE)
data = re.sub(u'^ - ', u' -', data, flags = re.MULTILINE)
data = re.sub(u'^(\t{1,2}) ', u'\\1', data, flags = re.MULTILINE)
return data
def process_file(fname, data):
buf = io.StringIO(data)
output = ''
in_table = False
table_separator = 0
for line in buf.readlines():
if line.find('.. flat-table::') != -1:
in_table = True
table = ''
elif in_table and not re.match('^[\t\n]|( )', line):
in_table = False
output += process_table(fname, table)
if in_table:
table += line
else:
output += line
if in_table:
in_table = False
output += process_table(fname, table)
return output
fname = sys.argv[1]
data = file(fname, 'rb').read().decode('utf-8')
data = process_file(fname, data)
file(fname, 'wb').write(data.encode('utf-8'))
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2016-09-05 19:44:34 +08:00
|
|
|
* - V4L2_RDS_BLOCK_MSK
|
|
|
|
-
|
|
|
|
- 7
|
|
|
|
- Mask for bits 0-2 to get the block ID.
|
|
|
|
* - V4L2_RDS_BLOCK_A
|
|
|
|
-
|
|
|
|
- 0
|
|
|
|
- Block A.
|
|
|
|
* - V4L2_RDS_BLOCK_B
|
|
|
|
-
|
|
|
|
- 1
|
|
|
|
- Block B.
|
|
|
|
* - V4L2_RDS_BLOCK_C
|
|
|
|
-
|
|
|
|
- 2
|
|
|
|
- Block C.
|
|
|
|
* - V4L2_RDS_BLOCK_D
|
|
|
|
-
|
|
|
|
- 3
|
|
|
|
- Block D.
|
|
|
|
* - V4L2_RDS_BLOCK_C_ALT
|
|
|
|
-
|
|
|
|
- 4
|
|
|
|
- Block C'.
|
|
|
|
* - V4L2_RDS_BLOCK_INVALID
|
|
|
|
- read-only
|
|
|
|
- 7
|
|
|
|
- An invalid block.
|
|
|
|
* - V4L2_RDS_BLOCK_CORRECTED
|
|
|
|
- read-only
|
|
|
|
- 0x40
|
|
|
|
- A bit error was detected but corrected.
|
|
|
|
* - V4L2_RDS_BLOCK_ERROR
|
|
|
|
- read-only
|
|
|
|
- 0x80
|
|
|
|
- An uncorrectable error occurred.
|