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