xref: /openbmc/linux/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
1*577a7ad3SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2*577a7ad3SMauro Carvalho Chehab
3*577a7ad3SMauro Carvalho ChehabCropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
4*577a7ad3SMauro Carvalho Chehab=======================================================================
5*577a7ad3SMauro Carvalho Chehab
6*577a7ad3SMauro Carvalho ChehabAuthor: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
7*577a7ad3SMauro Carvalho Chehab
8*577a7ad3SMauro Carvalho ChehabTerminology
9*577a7ad3SMauro Carvalho Chehab-----------
10*577a7ad3SMauro Carvalho Chehab
11*577a7ad3SMauro Carvalho Chehabsensor scales: horizontal and vertical scales, configured by the sensor driver
12*577a7ad3SMauro Carvalho Chehabhost scales: -"- host driver
13*577a7ad3SMauro Carvalho Chehabcombined scales: sensor_scale * host_scale
14*577a7ad3SMauro Carvalho Chehab
15*577a7ad3SMauro Carvalho Chehab
16*577a7ad3SMauro Carvalho ChehabGeneric scaling / cropping scheme
17*577a7ad3SMauro Carvalho Chehab---------------------------------
18*577a7ad3SMauro Carvalho Chehab
19*577a7ad3SMauro Carvalho Chehab.. code-block:: none
20*577a7ad3SMauro Carvalho Chehab
21*577a7ad3SMauro Carvalho Chehab	-1--
22*577a7ad3SMauro Carvalho Chehab	|
23*577a7ad3SMauro Carvalho Chehab	-2-- -\
24*577a7ad3SMauro Carvalho Chehab	|      --\
25*577a7ad3SMauro Carvalho Chehab	|         --\
26*577a7ad3SMauro Carvalho Chehab	+-5-- .      -- -3-- -\
27*577a7ad3SMauro Carvalho Chehab	|      `...            -\
28*577a7ad3SMauro Carvalho Chehab	|          `... -4-- .   - -7..
29*577a7ad3SMauro Carvalho Chehab	|                     `.
30*577a7ad3SMauro Carvalho Chehab	|                       `. .6--
31*577a7ad3SMauro Carvalho Chehab	|
32*577a7ad3SMauro Carvalho Chehab	|                        . .6'-
33*577a7ad3SMauro Carvalho Chehab	|                      .´
34*577a7ad3SMauro Carvalho Chehab	|           ... -4'- .´
35*577a7ad3SMauro Carvalho Chehab	|       ...´             - -7'.
36*577a7ad3SMauro Carvalho Chehab	+-5'- .´               -/
37*577a7ad3SMauro Carvalho Chehab	|            -- -3'- -/
38*577a7ad3SMauro Carvalho Chehab	|         --/
39*577a7ad3SMauro Carvalho Chehab	|      --/
40*577a7ad3SMauro Carvalho Chehab	-2'- -/
41*577a7ad3SMauro Carvalho Chehab	|
42*577a7ad3SMauro Carvalho Chehab	|
43*577a7ad3SMauro Carvalho Chehab	-1'-
44*577a7ad3SMauro Carvalho Chehab
45*577a7ad3SMauro Carvalho ChehabIn the above chart minuses and slashes represent "real" data amounts, points and
46*577a7ad3SMauro Carvalho Chehabaccents represent "useful" data, basically, CEU scaled and cropped output,
47*577a7ad3SMauro Carvalho Chehabmapped back onto the client's source plane.
48*577a7ad3SMauro Carvalho Chehab
49*577a7ad3SMauro Carvalho ChehabSuch a configuration can be produced by user requests:
50*577a7ad3SMauro Carvalho Chehab
51*577a7ad3SMauro Carvalho ChehabS_CROP(left / top = (5) - (1), width / height = (5') - (5))
52*577a7ad3SMauro Carvalho ChehabS_FMT(width / height = (6') - (6))
53*577a7ad3SMauro Carvalho Chehab
54*577a7ad3SMauro Carvalho ChehabHere:
55*577a7ad3SMauro Carvalho Chehab
56*577a7ad3SMauro Carvalho Chehab(1) to (1') - whole max width or height
57*577a7ad3SMauro Carvalho Chehab(1) to (2)  - sensor cropped left or top
58*577a7ad3SMauro Carvalho Chehab(2) to (2') - sensor cropped width or height
59*577a7ad3SMauro Carvalho Chehab(3) to (3') - sensor scale
60*577a7ad3SMauro Carvalho Chehab(3) to (4)  - CEU cropped left or top
61*577a7ad3SMauro Carvalho Chehab(4) to (4') - CEU cropped width or height
62*577a7ad3SMauro Carvalho Chehab(5) to (5') - reverse sensor scale applied to CEU cropped width or height
63*577a7ad3SMauro Carvalho Chehab(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
64*577a7ad3SMauro Carvalho Chehab(6) to (6') - CEU scale - user window
65*577a7ad3SMauro Carvalho Chehab
66*577a7ad3SMauro Carvalho Chehab
67*577a7ad3SMauro Carvalho ChehabS_FMT
68*577a7ad3SMauro Carvalho Chehab-----
69*577a7ad3SMauro Carvalho Chehab
70*577a7ad3SMauro Carvalho ChehabDo not touch input rectangle - it is already optimal.
71*577a7ad3SMauro Carvalho Chehab
72*577a7ad3SMauro Carvalho Chehab1. Calculate current sensor scales:
73*577a7ad3SMauro Carvalho Chehab
74*577a7ad3SMauro Carvalho Chehab	scale_s = ((2') - (2)) / ((3') - (3))
75*577a7ad3SMauro Carvalho Chehab
76*577a7ad3SMauro Carvalho Chehab2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
77*577a7ad3SMauro Carvalho Chehabcurrent sensor scales onto input window - this is user S_CROP:
78*577a7ad3SMauro Carvalho Chehab
79*577a7ad3SMauro Carvalho Chehab	width_u = (5') - (5) = ((4') - (4)) * scale_s
80*577a7ad3SMauro Carvalho Chehab
81*577a7ad3SMauro Carvalho Chehab3. Calculate new combined scales from "effective" input window to requested user
82*577a7ad3SMauro Carvalho Chehabwindow:
83*577a7ad3SMauro Carvalho Chehab
84*577a7ad3SMauro Carvalho Chehab	scale_comb = width_u / ((6') - (6))
85*577a7ad3SMauro Carvalho Chehab
86*577a7ad3SMauro Carvalho Chehab4. Calculate sensor output window by applying combined scales to real input
87*577a7ad3SMauro Carvalho Chehabwindow:
88*577a7ad3SMauro Carvalho Chehab
89*577a7ad3SMauro Carvalho Chehab	width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
90*577a7ad3SMauro Carvalho Chehab
91*577a7ad3SMauro Carvalho Chehab5. Apply iterative sensor S_FMT for sensor output window.
92*577a7ad3SMauro Carvalho Chehab
93*577a7ad3SMauro Carvalho Chehab	subdev->video_ops->s_fmt(.width = width_s_out)
94*577a7ad3SMauro Carvalho Chehab
95*577a7ad3SMauro Carvalho Chehab6. Retrieve sensor output window (g_fmt)
96*577a7ad3SMauro Carvalho Chehab
97*577a7ad3SMauro Carvalho Chehab7. Calculate new sensor scales:
98*577a7ad3SMauro Carvalho Chehab
99*577a7ad3SMauro Carvalho Chehab	scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
100*577a7ad3SMauro Carvalho Chehab
101*577a7ad3SMauro Carvalho Chehab8. Calculate new CEU crop - apply sensor scales to previously calculated
102*577a7ad3SMauro Carvalho Chehab"effective" crop:
103*577a7ad3SMauro Carvalho Chehab
104*577a7ad3SMauro Carvalho Chehab	width_ceu = (4')_new - (4)_new = width_u / scale_s_new
105*577a7ad3SMauro Carvalho Chehab	left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
106*577a7ad3SMauro Carvalho Chehab
107*577a7ad3SMauro Carvalho Chehab9. Use CEU cropping to crop to the new window:
108*577a7ad3SMauro Carvalho Chehab
109*577a7ad3SMauro Carvalho Chehab	ceu_crop(.width = width_ceu, .left = left_ceu)
110*577a7ad3SMauro Carvalho Chehab
111*577a7ad3SMauro Carvalho Chehab10. Use CEU scaling to scale to the requested user window:
112*577a7ad3SMauro Carvalho Chehab
113*577a7ad3SMauro Carvalho Chehab	scale_ceu = width_ceu / width
114*577a7ad3SMauro Carvalho Chehab
115*577a7ad3SMauro Carvalho Chehab
116*577a7ad3SMauro Carvalho ChehabS_CROP
117*577a7ad3SMauro Carvalho Chehab------
118*577a7ad3SMauro Carvalho Chehab
119*577a7ad3SMauro Carvalho ChehabThe :ref:`V4L2 crop API <crop-scale>` says:
120*577a7ad3SMauro Carvalho Chehab
121*577a7ad3SMauro Carvalho Chehab"...specification does not define an origin or units. However by convention
122*577a7ad3SMauro Carvalho Chehabdrivers should horizontally count unscaled samples relative to 0H."
123*577a7ad3SMauro Carvalho Chehab
124*577a7ad3SMauro Carvalho ChehabWe choose to follow the advise and interpret cropping units as client input
125*577a7ad3SMauro Carvalho Chehabpixels.
126*577a7ad3SMauro Carvalho Chehab
127*577a7ad3SMauro Carvalho ChehabCropping is performed in the following 6 steps:
128*577a7ad3SMauro Carvalho Chehab
129*577a7ad3SMauro Carvalho Chehab1. Request exactly user rectangle from the sensor.
130*577a7ad3SMauro Carvalho Chehab
131*577a7ad3SMauro Carvalho Chehab2. If smaller - iterate until a larger one is obtained. Result: sensor cropped
132*577a7ad3SMauro Carvalho Chehab   to 2 : 2', target crop 5 : 5', current output format 6' - 6.
133*577a7ad3SMauro Carvalho Chehab
134*577a7ad3SMauro Carvalho Chehab3. In the previous step the sensor has tried to preserve its output frame as
135*577a7ad3SMauro Carvalho Chehab   good as possible, but it could have changed. Retrieve it again.
136*577a7ad3SMauro Carvalho Chehab
137*577a7ad3SMauro Carvalho Chehab4. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
138*577a7ad3SMauro Carvalho Chehab   intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
139*577a7ad3SMauro Carvalho Chehab
140*577a7ad3SMauro Carvalho Chehab5. Calculate and apply host scale = (6' - 6) / (4' - 4)
141*577a7ad3SMauro Carvalho Chehab
142*577a7ad3SMauro Carvalho Chehab6. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
143