crop.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. .. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
  2. .. c:namespace:: V4L
  3. .. _crop:
  4. *****************************************************
  5. Image Cropping, Insertion and Scaling -- the CROP API
  6. *****************************************************
  7. .. note::
  8. The CROP API is mostly superseded by the newer :ref:`SELECTION API
  9. <selection-api>`. The new API should be preferred in most cases,
  10. with the exception of pixel aspect ratio detection, which is
  11. implemented by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` and has no
  12. equivalent in the SELECTION API. See :ref:`selection-vs-crop` for a
  13. comparison of the two APIs.
  14. Some video capture devices can sample a subsection of the picture and
  15. shrink or enlarge it to an image of arbitrary size. We call these
  16. abilities cropping and scaling. Some video output devices can scale an
  17. image up or down and insert it at an arbitrary scan line and horizontal
  18. offset into a video signal.
  19. Applications can use the following API to select an area in the video
  20. signal, query the default area and the hardware limits.
  21. .. note::
  22. Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`,
  23. :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP
  24. <VIDIOC_G_CROP>` ioctls apply to input as well as output devices.
  25. Scaling requires a source and a target. On a video capture or overlay
  26. device the source is the video signal, and the cropping ioctls determine
  27. the area actually sampled. The target are images read by the application
  28. or overlaid onto the graphics screen. Their size (and position for an
  29. overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
  30. and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls.
  31. On a video output device the source are the images passed in by the
  32. application, and their size is again negotiated with the
  33. :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
  34. ioctls, or may be encoded in a compressed video stream. The target is
  35. the video signal, and the cropping ioctls determine the area where the
  36. images are inserted.
  37. Source and target rectangles are defined even if the device does not
  38. support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
  39. :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position
  40. where applicable) will be fixed in this case.
  41. .. note::
  42. All capture and output devices that support the CROP or SELECTION
  43. API will also support the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`
  44. ioctl.
  45. Cropping Structures
  46. ===================
  47. .. _crop-scale:
  48. .. kernel-figure:: crop.svg
  49. :alt: crop.svg
  50. :align: center
  51. Image Cropping, Insertion and Scaling
  52. The cropping, insertion and scaling process
  53. For capture devices the coordinates of the top left corner, width and
  54. height of the area which can be sampled is given by the ``bounds``
  55. substructure of the struct :c:type:`v4l2_cropcap` returned
  56. by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide
  57. range of hardware this specification does not define an origin or units.
  58. However by convention drivers should horizontally count unscaled samples
  59. relative to 0H (the leading edge of the horizontal sync pulse, see
  60. :ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field
  61. (see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for
  62. :ref:`625 lines <vbi-625>`), multiplied by two if the driver
  63. can capture both fields.
  64. The top left corner, width and height of the source rectangle, that is
  65. the area actually sampled, is given by struct
  66. :c:type:`v4l2_crop` using the same coordinate system as
  67. struct :c:type:`v4l2_cropcap`. Applications can use the
  68. :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>`
  69. ioctls to get and set this rectangle. It must lie completely within the
  70. capture boundaries and the driver may further adjust the requested size
  71. and/or position according to hardware limitations.
  72. Each capture device has a default source rectangle, given by the
  73. ``defrect`` substructure of struct
  74. :c:type:`v4l2_cropcap`. The center of this rectangle
  75. shall align with the center of the active picture area of the video
  76. signal, and cover what the driver writer considers the complete picture.
  77. Drivers shall reset the source rectangle to the default when the driver
  78. is first loaded, but not later.
  79. For output devices these structures and ioctls are used accordingly,
  80. defining the *target* rectangle where the images will be inserted into
  81. the video signal.
  82. Scaling Adjustments
  83. ===================
  84. Video hardware can have various cropping, insertion and scaling
  85. limitations. It may only scale up or down, support only discrete scaling
  86. factors, or have different scaling abilities in horizontal and vertical
  87. direction. Also it may not support scaling at all. At the same time the
  88. struct :c:type:`v4l2_crop` rectangle may have to be aligned,
  89. and both the source and target rectangles may have arbitrary upper and
  90. lower size limits. In particular the maximum ``width`` and ``height`` in
  91. struct :c:type:`v4l2_crop` may be smaller than the struct
  92. :c:type:`v4l2_cropcap`. ``bounds`` area. Therefore, as
  93. usual, drivers are expected to adjust the requested parameters and
  94. return the actual values selected.
  95. Applications can change the source or the target rectangle first, as
  96. they may prefer a particular image size or a certain area in the video
  97. signal. If the driver has to adjust both to satisfy hardware
  98. limitations, the last requested rectangle shall take priority, and the
  99. driver should preferably adjust the opposite one. The
  100. :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change
  101. the driver state and therefore only adjust the requested rectangle.
  102. Suppose scaling on a video capture device is restricted to a factor 1:1
  103. or 2:1 in either direction and the target image size must be a multiple
  104. of 16 × 16 pixels. The source cropping rectangle is set to defaults,
  105. which are also the upper limit in this example, of 640 × 400 pixels at
  106. offset 0, 0. An application requests an image size of 300 × 225 pixels,
  107. assuming video will be scaled down from the "full picture" accordingly.
  108. The driver sets the image size to the closest possible values 304 × 224,
  109. then chooses the cropping rectangle closest to the requested size, that
  110. is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is
  111. still valid, thus unmodified. Given the default cropping rectangle
  112. reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can
  113. easily propose another offset to center the cropping rectangle.
  114. Now the application may insist on covering an area using a picture
  115. aspect ratio closer to the original request, so it asks for a cropping
  116. rectangle of 608 × 456 pixels. The present scaling factors limit
  117. cropping to 640 × 384, so the driver returns the cropping size 608 × 384
  118. and adjusts the image size to closest possible 304 × 192.
  119. Examples
  120. ========
  121. Source and target rectangles shall remain unchanged across closing and
  122. reopening a device, such that piping data into or out of a device will
  123. work without special preparations. More advanced applications should
  124. ensure the parameters are suitable before starting I/O.
  125. .. note::
  126. On the next two examples, a video capture device is assumed;
  127. change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device.
  128. Example: Resetting the cropping parameters
  129. ==========================================
  130. .. code-block:: c
  131. struct v4l2_cropcap cropcap;
  132. struct v4l2_crop crop;
  133. memset (&cropcap, 0, sizeof (cropcap));
  134. cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  135. if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
  136. perror ("VIDIOC_CROPCAP");
  137. exit (EXIT_FAILURE);
  138. }
  139. memset (&crop, 0, sizeof (crop));
  140. crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  141. crop.c = cropcap.defrect;
  142. /* Ignore if cropping is not supported (EINVAL). */
  143. if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
  144. && errno != EINVAL) {
  145. perror ("VIDIOC_S_CROP");
  146. exit (EXIT_FAILURE);
  147. }
  148. Example: Simple downscaling
  149. ===========================
  150. .. code-block:: c
  151. struct v4l2_cropcap cropcap;
  152. struct v4l2_format format;
  153. reset_cropping_parameters ();
  154. /* Scale down to 1/4 size of full picture. */
  155. memset (&format, 0, sizeof (format)); /* defaults */
  156. format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  157. format.fmt.pix.width = cropcap.defrect.width >> 1;
  158. format.fmt.pix.height = cropcap.defrect.height >> 1;
  159. format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  160. if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) {
  161. perror ("VIDIOC_S_FORMAT");
  162. exit (EXIT_FAILURE);
  163. }
  164. /* We could check the actual image size now, the actual scaling factor
  165. or if the driver can scale at all. */
  166. Example: Selecting an output area
  167. =================================
  168. .. note:: This example assumes an output device.
  169. .. code-block:: c
  170. struct v4l2_cropcap cropcap;
  171. struct v4l2_crop crop;
  172. memset (&cropcap, 0, sizeof (cropcap));
  173. cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  174. if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
  175. perror ("VIDIOC_CROPCAP");
  176. exit (EXIT_FAILURE);
  177. }
  178. memset (&crop, 0, sizeof (crop));
  179. crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  180. crop.c = cropcap.defrect;
  181. /* Scale the width and height to 50 % of their original size
  182. and center the output. */
  183. crop.c.width /= 2;
  184. crop.c.height /= 2;
  185. crop.c.left += crop.c.width / 2;
  186. crop.c.top += crop.c.height / 2;
  187. /* Ignore if cropping is not supported (EINVAL). */
  188. if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
  189. && errno != EINVAL) {
  190. perror ("VIDIOC_S_CROP");
  191. exit (EXIT_FAILURE);
  192. }
  193. Example: Current scaling factor and pixel aspect
  194. ================================================
  195. .. note:: This example assumes a video capture device.
  196. .. code-block:: c
  197. struct v4l2_cropcap cropcap;
  198. struct v4l2_crop crop;
  199. struct v4l2_format format;
  200. double hscale, vscale;
  201. double aspect;
  202. int dwidth, dheight;
  203. memset (&cropcap, 0, sizeof (cropcap));
  204. cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  205. if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
  206. perror ("VIDIOC_CROPCAP");
  207. exit (EXIT_FAILURE);
  208. }
  209. memset (&crop, 0, sizeof (crop));
  210. crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  211. if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) {
  212. if (errno != EINVAL) {
  213. perror ("VIDIOC_G_CROP");
  214. exit (EXIT_FAILURE);
  215. }
  216. /* Cropping not supported. */
  217. crop.c = cropcap.defrect;
  218. }
  219. memset (&format, 0, sizeof (format));
  220. format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  221. if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) {
  222. perror ("VIDIOC_G_FMT");
  223. exit (EXIT_FAILURE);
  224. }
  225. /* The scaling applied by the driver. */
  226. hscale = format.fmt.pix.width / (double) crop.c.width;
  227. vscale = format.fmt.pix.height / (double) crop.c.height;
  228. aspect = cropcap.pixelaspect.numerator /
  229. (double) cropcap.pixelaspect.denominator;
  230. aspect = aspect * hscale / vscale;
  231. /* Devices following ITU-R BT.601 do not capture
  232. square pixels. For playback on a computer monitor
  233. we should scale the images to this size. */
  234. dwidth = format.fmt.pix.width / aspect;
  235. dheight = format.fmt.pix.height;