]>
Commit | Line | Data |
---|---|---|
35b23b52 GL |
1 | Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver |
2 | ======================================================================= | |
3 | ||
4 | Terminology | |
5 | ----------- | |
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 | ||
11 | ||
12 | Generic scaling / cropping scheme | |
13 | --------------------------------- | |
14 | ||
15 | -1-- | |
16 | | | |
17 | -2-- -\ | |
18 | | --\ | |
19 | | --\ | |
20 | +-5-- -\ -- -3-- | |
21 | | ---\ | |
22 | | --- -4-- -\ | |
23 | | -\ | |
24 | | - -6-- | |
25 | | | |
26 | | - -6'- | |
27 | | -/ | |
28 | | --- -4'- -/ | |
29 | | ---/ | |
30 | +-5'- -/ | |
31 | | -- -3'- | |
32 | | --/ | |
33 | | --/ | |
34 | -2'- -/ | |
35 | | | |
36 | | | |
37 | -1'- | |
38 | ||
39 | Produced by user requests: | |
40 | ||
41 | S_CROP(left / top = (5) - (1), width / height = (5') - (5)) | |
42 | S_FMT(width / height = (6') - (6)) | |
43 | ||
44 | Here: | |
45 | ||
46 | (1) to (1') - whole max width or height | |
47 | (1) to (2) - sensor cropped left or top | |
48 | (2) to (2') - sensor cropped width or height | |
49 | (3) to (3') - sensor scale | |
50 | (3) to (4) - CEU cropped left or top | |
51 | (4) to (4') - CEU cropped width or height | |
52 | (5) to (5') - reverse sensor scale applied to CEU cropped width or height | |
53 | (2) to (5) - reverse sensor scale applied to CEU cropped left or top | |
54 | (6) to (6') - CEU scale - user window | |
55 | ||
56 | ||
57 | S_FMT | |
58 | ----- | |
59 | ||
60 | Do not touch input rectangle - it is already optimal. | |
61 | ||
62 | 1. Calculate current sensor scales: | |
63 | ||
64 | scale_s = ((3') - (3)) / ((2') - (2)) | |
65 | ||
66 | 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at | |
67 | current sensor scales onto input window - this is user S_CROP: | |
68 | ||
69 | width_u = (5') - (5) = ((4') - (4)) * scale_s | |
70 | ||
71 | 3. Calculate new combined scales from "effective" input window to requested user | |
72 | window: | |
73 | ||
74 | scale_comb = width_u / ((6') - (6)) | |
75 | ||
76 | 4. Calculate sensor output window by applying combined scales to real input | |
77 | window: | |
78 | ||
79 | width_s_out = ((2') - (2)) / scale_comb | |
80 | ||
81 | 5. Apply iterative sensor S_FMT for sensor output window. | |
82 | ||
83 | subdev->video_ops->s_fmt(.width = width_s_out) | |
84 | ||
85 | 6. Retrieve sensor output window (g_fmt) | |
86 | ||
87 | 7. Calculate new sensor scales: | |
88 | ||
89 | scale_s_new = ((3')_new - (3)_new) / ((2') - (2)) | |
90 | ||
91 | 8. Calculate new CEU crop - apply sensor scales to previously calculated | |
92 | "effective" crop: | |
93 | ||
94 | width_ceu = (4')_new - (4)_new = width_u / scale_s_new | |
95 | left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new | |
96 | ||
97 | 9. Use CEU cropping to crop to the new window: | |
98 | ||
99 | ceu_crop(.width = width_ceu, .left = left_ceu) | |
100 | ||
101 | 10. Use CEU scaling to scale to the requested user window: | |
102 | ||
103 | scale_ceu = width_ceu / width | |
104 | ||
105 | ||
106 | S_CROP | |
107 | ------ | |
108 | ||
109 | If old scale applied to new crop is invalid produce nearest new scale possible | |
110 | ||
111 | 1. Calculate current combined scales. | |
112 | ||
113 | scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3))) | |
114 | ||
115 | 2. Apply iterative sensor S_CROP for new input window. | |
116 | ||
117 | 3. If old combined scales applied to new crop produce an impossible user window, | |
118 | adjust scales to produce nearest possible window. | |
119 | ||
120 | width_u_out = ((5') - (5)) / scale_comb | |
121 | ||
122 | if (width_u_out > max) | |
123 | scale_comb = ((5') - (5)) / max; | |
124 | else if (width_u_out < min) | |
125 | scale_comb = ((5') - (5)) / min; | |
126 | ||
127 | 4. Issue G_CROP to retrieve actual input window. | |
128 | ||
129 | 5. Using actual input window and calculated combined scales calculate sensor | |
130 | target output window. | |
131 | ||
132 | width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb | |
133 | ||
134 | 6. Apply iterative S_FMT for new sensor target output window. | |
135 | ||
136 | 7. Issue G_FMT to retrieve the actual sensor output window. | |
137 | ||
138 | 8. Calculate sensor scales. | |
139 | ||
140 | scale_s = ((3') - (3)) / ((2') - (2)) | |
141 | ||
142 | 9. Calculate sensor output subwindow to be cropped on CEU by applying sensor | |
143 | scales to the requested window. | |
144 | ||
145 | width_ceu = ((5') - (5)) / scale_s | |
146 | ||
147 | 10. Use CEU cropping for above calculated window. | |
148 | ||
149 | 11. Calculate CEU scales from sensor scales from results of (10) and user window | |
150 | from (3) | |
151 | ||
152 | scale_ceu = calc_scale(((5') - (5)), &width_u_out) | |
153 | ||
154 | 12. Apply CEU scales. | |
155 | ||
156 | -- | |
157 | Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |