linux/Documentation/video4linux/sh_mobile_ceu_camera.txt
<<
>>
Prefs
   1        Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
   2        =======================================================================
   3
   4Terminology
   5-----------
   6
   7sensor scales: horizontal and vertical scales, configured by the sensor driver
   8host scales: -"- host driver
   9combined scales: sensor_scale * host_scale
  10
  11
  12Generic scaling / cropping scheme
  13---------------------------------
  14
  15-1--
  16|
  17-2-- -\
  18|      --\
  19|         --\
  20+-5-- .      -- -3-- -\
  21|      `...            -\
  22|          `... -4-- .   - -7..
  23|                     `.
  24|                       `. .6--
  25|
  26|                        . .6'-
  27|                      .´
  28|           ... -4'- .´
  29|       ...´             - -7'.
  30+-5'- .´               -/
  31|            -- -3'- -/
  32|         --/
  33|      --/
  34-2'- -/
  35|
  36|
  37-1'-
  38
  39In the above chart minuses and slashes represent "real" data amounts, points and
  40accents represent "useful" data, basically, CEU scaled and cropped output,
  41mapped back onto the client's source plane.
  42
  43Such a configuration can be produced by user requests:
  44
  45S_CROP(left / top = (5) - (1), width / height = (5') - (5))
  46S_FMT(width / height = (6') - (6))
  47
  48Here:
  49
  50(1) to (1') - whole max width or height
  51(1) to (2)  - sensor cropped left or top
  52(2) to (2') - sensor cropped width or height
  53(3) to (3') - sensor scale
  54(3) to (4)  - CEU cropped left or top
  55(4) to (4') - CEU cropped width or height
  56(5) to (5') - reverse sensor scale applied to CEU cropped width or height
  57(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
  58(6) to (6') - CEU scale - user window
  59
  60
  61S_FMT
  62-----
  63
  64Do not touch input rectangle - it is already optimal.
  65
  661. Calculate current sensor scales:
  67
  68        scale_s = ((2') - (2)) / ((3') - (3))
  69
  702. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
  71current sensor scales onto input window - this is user S_CROP:
  72
  73        width_u = (5') - (5) = ((4') - (4)) * scale_s
  74
  753. Calculate new combined scales from "effective" input window to requested user
  76window:
  77
  78        scale_comb = width_u / ((6') - (6))
  79
  804. Calculate sensor output window by applying combined scales to real input
  81window:
  82
  83        width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
  84
  855. Apply iterative sensor S_FMT for sensor output window.
  86
  87        subdev->video_ops->s_fmt(.width = width_s_out)
  88
  896. Retrieve sensor output window (g_fmt)
  90
  917. Calculate new sensor scales:
  92
  93        scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
  94
  958. Calculate new CEU crop - apply sensor scales to previously calculated
  96"effective" crop:
  97
  98        width_ceu = (4')_new - (4)_new = width_u / scale_s_new
  99        left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
 100
 1019. Use CEU cropping to crop to the new window:
 102
 103        ceu_crop(.width = width_ceu, .left = left_ceu)
 104
 10510. Use CEU scaling to scale to the requested user window:
 106
 107        scale_ceu = width_ceu / width
 108
 109
 110S_CROP
 111------
 112
 113The API at http://v4l2spec.bytesex.org/spec/x1904.htm says:
 114
 115"...specification does not define an origin or units. However by convention
 116drivers should horizontally count unscaled samples relative to 0H."
 117
 118We choose to follow the advise and interpret cropping units as client input
 119pixels.
 120
 121Cropping is performed in the following 6 steps:
 122
 1231. Request exactly user rectangle from the sensor.
 124
 1252. If smaller - iterate until a larger one is obtained. Result: sensor cropped
 126   to 2 : 2', target crop 5 : 5', current output format 6' - 6.
 127
 1283. In the previous step the sensor has tried to preserve its output frame as
 129   good as possible, but it could have changed. Retrieve it again.
 130
 1314. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
 132   intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
 133
 1345. Calculate and apply host scale = (6' - 6) / (4' - 4)
 135
 1366. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
 137
 138--
 139Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 140
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.