sh_mobile_ceu_camera.rst 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. .. SPDX-License-Identifier: GPL-2.0
  2. Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
  3. =======================================================================
  4. Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  5. Terminology
  6. -----------
  7. sensor scales: horizontal and vertical scales, configured by the sensor driver
  8. host scales: -"- host driver
  9. combined scales: sensor_scale * host_scale
  10. Generic scaling / cropping scheme
  11. ---------------------------------
  12. .. code-block:: none
  13. -1--
  14. |
  15. -2-- -\
  16. | --\
  17. | --\
  18. +-5-- . -- -3-- -\
  19. | `... -\
  20. | `... -4-- . - -7..
  21. | `.
  22. | `. .6--
  23. |
  24. | . .6'-
  25. | .´
  26. | ... -4'- .´
  27. | ...´ - -7'.
  28. +-5'- .´ -/
  29. | -- -3'- -/
  30. | --/
  31. | --/
  32. -2'- -/
  33. |
  34. |
  35. -1'-
  36. In the above chart minuses and slashes represent "real" data amounts, points and
  37. accents represent "useful" data, basically, CEU scaled and cropped output,
  38. mapped back onto the client's source plane.
  39. Such a configuration can be produced by user requests:
  40. S_CROP(left / top = (5) - (1), width / height = (5') - (5))
  41. S_FMT(width / height = (6') - (6))
  42. Here:
  43. (1) to (1') - whole max width or height
  44. (1) to (2) - sensor cropped left or top
  45. (2) to (2') - sensor cropped width or height
  46. (3) to (3') - sensor scale
  47. (3) to (4) - CEU cropped left or top
  48. (4) to (4') - CEU cropped width or height
  49. (5) to (5') - reverse sensor scale applied to CEU cropped width or height
  50. (2) to (5) - reverse sensor scale applied to CEU cropped left or top
  51. (6) to (6') - CEU scale - user window
  52. S_FMT
  53. -----
  54. Do not touch input rectangle - it is already optimal.
  55. 1. Calculate current sensor scales:
  56. scale_s = ((2') - (2)) / ((3') - (3))
  57. 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
  58. current sensor scales onto input window - this is user S_CROP:
  59. width_u = (5') - (5) = ((4') - (4)) * scale_s
  60. 3. Calculate new combined scales from "effective" input window to requested user
  61. window:
  62. scale_comb = width_u / ((6') - (6))
  63. 4. Calculate sensor output window by applying combined scales to real input
  64. window:
  65. width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
  66. 5. Apply iterative sensor S_FMT for sensor output window.
  67. subdev->video_ops->s_fmt(.width = width_s_out)
  68. 6. Retrieve sensor output window (g_fmt)
  69. 7. Calculate new sensor scales:
  70. scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
  71. 8. Calculate new CEU crop - apply sensor scales to previously calculated
  72. "effective" crop:
  73. width_ceu = (4')_new - (4)_new = width_u / scale_s_new
  74. left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
  75. 9. Use CEU cropping to crop to the new window:
  76. ceu_crop(.width = width_ceu, .left = left_ceu)
  77. 10. Use CEU scaling to scale to the requested user window:
  78. scale_ceu = width_ceu / width
  79. S_CROP
  80. ------
  81. The :ref:`V4L2 crop API <crop-scale>` says:
  82. "...specification does not define an origin or units. However by convention
  83. drivers should horizontally count unscaled samples relative to 0H."
  84. We choose to follow the advise and interpret cropping units as client input
  85. pixels.
  86. Cropping is performed in the following 6 steps:
  87. 1. Request exactly user rectangle from the sensor.
  88. 2. If smaller - iterate until a larger one is obtained. Result: sensor cropped
  89. to 2 : 2', target crop 5 : 5', current output format 6' - 6.
  90. 3. In the previous step the sensor has tried to preserve its output frame as
  91. good as possible, but it could have changed. Retrieve it again.
  92. 4. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
  93. intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
  94. 5. Calculate and apply host scale = (6' - 6) / (4' - 4)
  95. 6. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)