sh_mobile_ceu_camera.rst 3.8 KB

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