2016-06-30 21:18:56 +08:00
|
|
|
.. -*- coding: utf-8; mode: rst -*-
|
|
|
|
|
|
|
|
.. _field-order:
|
|
|
|
|
|
|
|
***********
|
|
|
|
Field Order
|
|
|
|
***********
|
|
|
|
|
|
|
|
We have to distinguish between progressive and interlaced video.
|
|
|
|
Progressive video transmits all lines of a video image sequentially.
|
|
|
|
Interlaced video divides an image into two fields, containing only the
|
|
|
|
odd and even lines of the image, respectively. Alternating the so called
|
|
|
|
odd and even field are transmitted, and due to a small delay between
|
|
|
|
fields a cathode ray TV displays the lines interleaved, yielding the
|
|
|
|
original frame. This curious technique was invented because at refresh
|
|
|
|
rates similar to film the image would fade out too quickly. Transmitting
|
|
|
|
fields reduces the flicker without the necessity of doubling the frame
|
|
|
|
rate and with it the bandwidth required for each channel.
|
|
|
|
|
|
|
|
It is important to understand a video camera does not expose one frame
|
|
|
|
at a time, merely transmitting the frames separated into fields. The
|
|
|
|
fields are in fact captured at two different instances in time. An
|
|
|
|
object on screen may well move between one field and the next. For
|
|
|
|
applications analysing motion it is of paramount importance to recognize
|
|
|
|
which field of a frame is older, the *temporal order*.
|
|
|
|
|
|
|
|
When the driver provides or accepts images field by field rather than
|
|
|
|
interleaved, it is also important applications understand how the fields
|
|
|
|
combine to frames. We distinguish between top (aka odd) and bottom (aka
|
|
|
|
even) fields, the *spatial order*: The first line of the top field is
|
|
|
|
the first line of an interlaced frame, the first line of the bottom
|
|
|
|
field is the second line of that frame.
|
|
|
|
|
|
|
|
However because fields were captured one after the other, arguing
|
|
|
|
whether a frame commences with the top or bottom field is pointless. Any
|
|
|
|
two successive top and bottom, or bottom and top fields yield a valid
|
|
|
|
frame. Only when the source was progressive to begin with, e. g. when
|
|
|
|
transferring film to video, two fields may come from the same frame,
|
|
|
|
creating a natural order.
|
|
|
|
|
|
|
|
Counter to intuition the top field is not necessarily the older field.
|
|
|
|
Whether the older field contains the top or bottom lines is a convention
|
|
|
|
determined by the video standard. Hence the distinction between temporal
|
|
|
|
and spatial order of fields. The diagrams below should make this
|
|
|
|
clearer.
|
|
|
|
|
|
|
|
All video capture and output devices must report the current field
|
|
|
|
order. Some drivers may permit the selection of a different order, to
|
|
|
|
this end applications initialize the ``field`` field of struct
|
2016-08-30 04:37:59 +08:00
|
|
|
:c:type:`v4l2_pix_format` before calling the
|
2016-07-02 00:42:29 +08:00
|
|
|
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl. If this is not desired it
|
2016-06-30 21:18:56 +08:00
|
|
|
should have the value ``V4L2_FIELD_ANY`` (0).
|
|
|
|
|
|
|
|
|
2016-07-05 04:14:00 +08:00
|
|
|
enum v4l2_field
|
|
|
|
===============
|
|
|
|
|
[media] docs-rst: fix cross-references for videodev2.h
There are several broken references there, due to the conversion to
C domain. Fix them using this shell script and manually adjust what's
broken:
# funcs is a file with the broken functions/references
for i in $(cat funcs|sort|uniq|perl -ne 'print "$1\n" if (m/(\S+)$/)'); do
i=${i//-/_}
echo $i
j=${i//_/-}
for k in $(git grep -l "_$j:" Documentation/); do
sed s,\_$j\:,"c\:type\:\: $i", <$k >a && mv a $k
done
for k in $(git grep -l "$j" Documentation/media/*.exceptions); do
sed s,$j,":c\:type\:\`$i\`", <$k >a && mv a $k
done
for k in $(git grep -l "$j" Documentation/); do
sed "s,:ref:\`$i <$j>\`,:c:type:\`$i\`," <$k >a && mv a $k
sed "s,:ref:\`$j\`,:c:type:\`$i\`," <$k >a && mv a $k
sed -E "s,:ref:\`(.*)<$j>\`,:c:type:\`\1<$i>\`," <$k >a && mv a $k
done
for k in $(git grep -l "<$j>" include/media); do
sed -E "s,:ref:\`(.*)<$j>\`,enum \&$i," <$k >a && mv a $k
done
done
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-09-08 17:41:26 +08:00
|
|
|
.. c:type:: v4l2_field
|
|
|
|
|
[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{6.6cm}|p{2.2cm}|p{8.7cm}|
|
|
|
|
|
2016-07-05 04:14:00 +08:00
|
|
|
.. flat-table::
|
2016-06-30 21:18:56 +08:00
|
|
|
:header-rows: 0
|
|
|
|
:stub-columns: 0
|
|
|
|
:widths: 3 1 4
|
|
|
|
|
[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_FIELD_ANY``
|
|
|
|
- 0
|
|
|
|
- Applications request this field order when any one of the
|
|
|
|
``V4L2_FIELD_NONE``, ``V4L2_FIELD_TOP``, ``V4L2_FIELD_BOTTOM``, or
|
|
|
|
``V4L2_FIELD_INTERLACED`` formats is acceptable. Drivers choose
|
|
|
|
depending on hardware capabilities or e. g. the requested image
|
|
|
|
size, and return the actual field order. Drivers must never return
|
|
|
|
``V4L2_FIELD_ANY``. If multiple field orders are possible the
|
|
|
|
driver must choose one of the possible field orders during
|
|
|
|
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` or
|
|
|
|
:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>`. struct
|
|
|
|
:c:type:`v4l2_buffer` ``field`` can never be
|
|
|
|
``V4L2_FIELD_ANY``.
|
|
|
|
* - ``V4L2_FIELD_NONE``
|
|
|
|
- 1
|
|
|
|
- Images are in progressive format, not interlaced. The driver may
|
|
|
|
also indicate this order when it cannot distinguish between
|
|
|
|
``V4L2_FIELD_TOP`` and ``V4L2_FIELD_BOTTOM``.
|
|
|
|
* - ``V4L2_FIELD_TOP``
|
|
|
|
- 2
|
|
|
|
- Images consist of the top (aka odd) field only.
|
|
|
|
* - ``V4L2_FIELD_BOTTOM``
|
|
|
|
- 3
|
|
|
|
- Images consist of the bottom (aka even) field only. Applications
|
|
|
|
may wish to prevent a device from capturing interlaced images
|
|
|
|
because they will have "comb" or "feathering" artefacts around
|
|
|
|
moving objects.
|
|
|
|
* - ``V4L2_FIELD_INTERLACED``
|
|
|
|
- 4
|
|
|
|
- Images contain both fields, interleaved line by line. The temporal
|
|
|
|
order of the fields (whether the top or bottom field is first
|
|
|
|
transmitted) depends on the current video standard. M/NTSC
|
|
|
|
transmits the bottom field first, all other standards the top
|
|
|
|
field first.
|
|
|
|
* - ``V4L2_FIELD_SEQ_TB``
|
|
|
|
- 5
|
|
|
|
- Images contain both fields, the top field lines are stored first
|
|
|
|
in memory, immediately followed by the bottom field lines. Fields
|
|
|
|
are always stored in temporal order, the older one first in
|
|
|
|
memory. Image sizes refer to the frame, not fields.
|
|
|
|
* - ``V4L2_FIELD_SEQ_BT``
|
|
|
|
- 6
|
|
|
|
- Images contain both fields, the bottom field lines are stored
|
|
|
|
first in memory, immediately followed by the top field lines.
|
|
|
|
Fields are always stored in temporal order, the older one first in
|
|
|
|
memory. Image sizes refer to the frame, not fields.
|
|
|
|
* - ``V4L2_FIELD_ALTERNATE``
|
|
|
|
- 7
|
|
|
|
- The two fields of a frame are passed in separate buffers, in
|
|
|
|
temporal order, i. e. the older one first. To indicate the field
|
|
|
|
parity (whether the current field is a top or bottom field) the
|
|
|
|
driver or application, depending on data direction, must set
|
|
|
|
struct :c:type:`v4l2_buffer` ``field`` to
|
|
|
|
``V4L2_FIELD_TOP`` or ``V4L2_FIELD_BOTTOM``. Any two successive
|
|
|
|
fields pair to build a frame. If fields are successive, without
|
|
|
|
any dropped fields between them (fields can drop individually),
|
|
|
|
can be determined from the struct
|
|
|
|
:c:type:`v4l2_buffer` ``sequence`` field. This
|
|
|
|
format cannot be selected when using the read/write I/O method
|
|
|
|
since there is no way to communicate if a field was a top or
|
|
|
|
bottom field.
|
|
|
|
* - ``V4L2_FIELD_INTERLACED_TB``
|
|
|
|
- 8
|
|
|
|
- Images contain both fields, interleaved line by line, top field
|
|
|
|
first. The top field is transmitted first.
|
|
|
|
* - ``V4L2_FIELD_INTERLACED_BT``
|
|
|
|
- 9
|
|
|
|
- Images contain both fields, interleaved line by line, top field
|
|
|
|
first. The bottom field is transmitted first.
|
2016-06-30 21:18:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _fieldseq-tb:
|
|
|
|
|
2016-07-05 04:14:00 +08:00
|
|
|
Field Order, Top Field First Transmitted
|
|
|
|
========================================
|
|
|
|
|
2017-03-10 02:14:52 +08:00
|
|
|
.. kernel-figure:: fieldseq_tb.svg
|
|
|
|
:alt: fieldseq_tb.svg
|
2016-06-30 21:18:56 +08:00
|
|
|
:align: center
|
|
|
|
|
2017-03-10 02:14:52 +08:00
|
|
|
Field Order, Top Field First Transmitted
|
|
|
|
|
2016-06-30 21:18:56 +08:00
|
|
|
|
|
|
|
.. _fieldseq-bt:
|
|
|
|
|
2016-07-05 04:14:00 +08:00
|
|
|
Field Order, Bottom Field First Transmitted
|
|
|
|
===========================================
|
|
|
|
|
2017-03-10 02:14:52 +08:00
|
|
|
.. kernel-figure:: fieldseq_bt.svg
|
|
|
|
:alt: fieldseq_bt.svg
|
2016-06-30 21:18:56 +08:00
|
|
|
:align: center
|
|
|
|
|
2017-03-10 02:14:52 +08:00
|
|
|
Field Order, Bottom Field First Transmitted
|