blob: cb47e723af7436defbc6db5007bdf2fd3f675414 [file] [log] [blame]
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -03001 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| --\
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -030020+-5-- . -- -3-- -\
21| `... -\
22| `... -4-- . - -7..
23| `.
24| `. .6--
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -030025|
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -030026| . .6'-
27| .´
28| ... -4'- .´
29| ...´ - -7'.
30+-5'- .´ -/
31| -- -3'- -/
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -030032| --/
33| --/
34-2'- -/
35|
36|
37-1'-
38
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -030039In the above chart minuses and slashes represent "real" data amounts, points and
40accents represent "useful" data, basically, CEU scaled amd cropped output,
41mapped back onto the client's source plane.
42
43Such a configuration can be produced by user requests:
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -030044
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 = ((3') - (3)) / ((2') - (2))
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 = ((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
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -0300113The API at http://v4l2spec.bytesex.org/spec/x1904.htm says:
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300114
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -0300115"...specification does not define an origin or units. However by convention
116drivers should horizontally count unscaled samples relative to 0H."
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300117
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -0300118We choose to follow the advise and interpret cropping units as client input
119pixels.
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300120
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -0300121Cropping is performed in the following 6 steps:
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300122
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -03001231. Request exactly user rectangle from the sensor.
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300124
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -03001252. 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.
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300127
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -03001283. 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.
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300130
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -03001314. 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)
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300133
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -03001345. Calculate and apply host scale = (6' - 6) / (4' - 4)
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300135
Guennadi Liakhovetskif7fc97a2010-03-23 11:42:32 -03001366. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
Guennadi Liakhovetski35b23b52009-12-11 11:34:20 -0300137
138--
139Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>