Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma
[linux-2.6.git] / Documentation / video4linux / sh_mobile_ceu_camera.txt
blob1e96ce6e2d2f9d39705c8a79e60b95bcc6cc9082
1         Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
2         =======================================================================
4 Terminology
5 -----------
7 sensor scales: horizontal and vertical scales, configured by the sensor driver
8 host scales: -"- host driver
9 combined scales: sensor_scale * host_scale
12 Generic scaling / cropping scheme
13 ---------------------------------
15 -1--
17 -2-- -\
18 |      --\
19 |         --\
20 +-5-- .      -- -3-- -\
21 |      `...            -\
22 |          `... -4-- .   - -7..
23 |                     `.
24 |                       `. .6--
26 |                        . .6'-
27 |                      .´
28 |           ... -4'- .´
29 |       ...´             - -7'.
30 +-5'- .´               -/
31 |            -- -3'- -/
32 |         --/
33 |      --/
34 -2'- -/
37 -1'-
39 In the above chart minuses and slashes represent "real" data amounts, points and
40 accents represent "useful" data, basically, CEU scaled and cropped output,
41 mapped back onto the client's source plane.
43 Such a configuration can be produced by user requests:
45 S_CROP(left / top = (5) - (1), width / height = (5') - (5))
46 S_FMT(width / height = (6') - (6))
48 Here:
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
61 S_FMT
62 -----
64 Do not touch input rectangle - it is already optimal.
66 1. Calculate current sensor scales:
68         scale_s = ((2') - (2)) / ((3') - (3))
70 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
71 current sensor scales onto input window - this is user S_CROP:
73         width_u = (5') - (5) = ((4') - (4)) * scale_s
75 3. Calculate new combined scales from "effective" input window to requested user
76 window:
78         scale_comb = width_u / ((6') - (6))
80 4. Calculate sensor output window by applying combined scales to real input
81 window:
83         width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
85 5. Apply iterative sensor S_FMT for sensor output window.
87         subdev->video_ops->s_fmt(.width = width_s_out)
89 6. Retrieve sensor output window (g_fmt)
91 7. Calculate new sensor scales:
93         scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
95 8. Calculate new CEU crop - apply sensor scales to previously calculated
96 "effective" crop:
98         width_ceu = (4')_new - (4)_new = width_u / scale_s_new
99         left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
101 9. Use CEU cropping to crop to the new window:
103         ceu_crop(.width = width_ceu, .left = left_ceu)
105 10. Use CEU scaling to scale to the requested user window:
107         scale_ceu = width_ceu / width
110 S_CROP
111 ------
113 The API at http://v4l2spec.bytesex.org/spec/x1904.htm says:
115 "...specification does not define an origin or units. However by convention
116 drivers should horizontally count unscaled samples relative to 0H."
118 We choose to follow the advise and interpret cropping units as client input
119 pixels.
121 Cropping is performed in the following 6 steps:
123 1. Request exactly user rectangle from the sensor.
125 2. 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.
128 3. 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.
131 4. 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)
134 5. Calculate and apply host scale = (6' - 6) / (4' - 4)
136 6. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
139 Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>