bcm27xx: add support for linux v5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.15 / 950-0399-media-rpivid-Improve-values-returned-when-setting-ou.patch
1 From 9f32962c0fe4129a01bd0422cd1cda76a13c5ef4 Mon Sep 17 00:00:00 2001
2 From: John Cox <jc@kynesim.co.uk>
3 Date: Thu, 1 Apr 2021 16:20:58 +0100
4 Subject: [PATCH] media: rpivid: Improve values returned when setting
5 output format
6
7 Guess a better value for the compressed bitstream buffer size
8
9 Signed-off-by: John Cox <jc@kynesim.co.uk>
10 ---
11 drivers/staging/media/rpivid/rpivid_h265.c | 66 ++++-----------------
12 drivers/staging/media/rpivid/rpivid_video.c | 61 +++++++++++++++++--
13 drivers/staging/media/rpivid/rpivid_video.h | 4 ++
14 3 files changed, 70 insertions(+), 61 deletions(-)
15
16 --- a/drivers/staging/media/rpivid/rpivid_h265.c
17 +++ b/drivers/staging/media/rpivid/rpivid_h265.c
18 @@ -18,6 +18,7 @@
19
20 #include "rpivid.h"
21 #include "rpivid_hw.h"
22 +#include "rpivid_video.h"
23
24 #define DEBUG_TRACE_P1_CMD 0
25 #define DEBUG_TRACE_EXECUTION 0
26 @@ -115,41 +116,9 @@ static int gptr_realloc_new(struct rpivi
27 return 0;
28 }
29
30 -/* floor(log2(x)) */
31 -static unsigned int log2_size(size_t x)
32 -{
33 - unsigned int n = 0;
34 -
35 - if (x & ~0xffff) {
36 - n += 16;
37 - x >>= 16;
38 - }
39 - if (x & ~0xff) {
40 - n += 8;
41 - x >>= 8;
42 - }
43 - if (x & ~0xf) {
44 - n += 4;
45 - x >>= 4;
46 - }
47 - if (x & ~3) {
48 - n += 2;
49 - x >>= 2;
50 - }
51 - return (x & ~1) ? n + 1 : n;
52 -}
53 -
54 -static size_t round_up_size(const size_t x)
55 -{
56 - /* Admit no size < 256 */
57 - const unsigned int n = x < 256 ? 8 : log2_size(x) - 1;
58 -
59 - return x >= (3 << n) ? 4 << n : (3 << n);
60 -}
61 -
62 static size_t next_size(const size_t x)
63 {
64 - return round_up_size(x + 1);
65 + return rpivid_round_up_size(x + 1);
66 }
67
68 #define NUM_SCALING_FACTORS 4064 /* Not a typo = 0xbe0 + 0x400 */
69 @@ -332,7 +301,7 @@ static int cmds_check_space(struct rpivi
70 if (de->cmd_len + n <= de->cmd_max)
71 return 0;
72
73 - newmax = 2 << log2_size(de->cmd_len + n);
74 + newmax = roundup_pow_of_two(de->cmd_len + n);
75
76 a = krealloc(de->cmd_fifo, newmax * sizeof(struct rpi_cmd),
77 GFP_KERNEL);
78 @@ -1855,23 +1824,10 @@ static void rpivid_h265_setup(struct rpi
79 * slice as we can use the src buf directly
80 */
81 if (!s->frame_end && !de->bit_copy_gptr->ptr) {
82 - const size_t wxh = s->sps.pic_width_in_luma_samples *
83 - s->sps.pic_height_in_luma_samples;
84 size_t bits_alloc;
85 -
86 - /* Annex A gives a min compression of 2 @ lvl 3.1
87 - * (wxh <= 983040) and min 4 thereafter but avoid
88 - * the odity of 983041 having a lower limit than
89 - * 983040.
90 - * Multiply by 3/2 for 4:2:0
91 - */
92 - bits_alloc = wxh < 983040 ? wxh * 3 / 4 :
93 - wxh < 983040 * 2 ? 983040 * 3 / 4 :
94 - wxh * 3 / 8;
95 - /* Allow for bit depth */
96 - bits_alloc += (bits_alloc *
97 - s->sps.bit_depth_luma_minus8) / 8;
98 - bits_alloc = round_up_size(bits_alloc);
99 + bits_alloc = rpivid_bit_buf_size(s->sps.pic_width_in_luma_samples,
100 + s->sps.pic_height_in_luma_samples,
101 + s->sps.bit_depth_luma_minus8);
102
103 if (gptr_alloc(dev, de->bit_copy_gptr,
104 bits_alloc,
105 @@ -2454,17 +2410,15 @@ static int rpivid_h265_start(struct rpiv
106
107 // Finger in the air PU & Coeff alloc
108 // Will be realloced if too small
109 - coeff_alloc = round_up_size(wxh);
110 - pu_alloc = round_up_size(wxh / 4);
111 + coeff_alloc = rpivid_round_up_size(wxh);
112 + pu_alloc = rpivid_round_up_size(wxh / 4);
113 for (i = 0; i != ARRAY_SIZE(ctx->pu_bufs); ++i) {
114 // Don't actually need a kernel mapping here
115 if (gptr_alloc(dev, ctx->pu_bufs + i, pu_alloc,
116 - DMA_ATTR_FORCE_CONTIGUOUS |
117 - DMA_ATTR_NO_KERNEL_MAPPING))
118 + DMA_ATTR_NO_KERNEL_MAPPING))
119 goto fail;
120 if (gptr_alloc(dev, ctx->coeff_bufs + i, coeff_alloc,
121 - DMA_ATTR_FORCE_CONTIGUOUS |
122 - DMA_ATTR_NO_KERNEL_MAPPING))
123 + DMA_ATTR_NO_KERNEL_MAPPING))
124 goto fail;
125 }
126 aux_q_init(ctx);
127 --- a/drivers/staging/media/rpivid/rpivid_video.c
128 +++ b/drivers/staging/media/rpivid/rpivid_video.c
129 @@ -42,18 +42,69 @@ static inline unsigned int constrain2x(u
130 (x > y * 2) ? y : x;
131 }
132
133 +size_t rpivid_round_up_size(const size_t x)
134 +{
135 + /* Admit no size < 256 */
136 + const unsigned int n = x < 256 ? 8 : ilog2(x);
137 +
138 + return x >= (3 << n) ? 4 << n : (3 << n);
139 +}
140 +
141 +size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8)
142 +{
143 + const size_t wxh = w * h;
144 + size_t bits_alloc;
145 +
146 + /* Annex A gives a min compression of 2 @ lvl 3.1
147 + * (wxh <= 983040) and min 4 thereafter but avoid
148 + * the odity of 983041 having a lower limit than
149 + * 983040.
150 + * Multiply by 3/2 for 4:2:0
151 + */
152 + bits_alloc = wxh < 983040 ? wxh * 3 / 4 :
153 + wxh < 983040 * 2 ? 983040 * 3 / 4 :
154 + wxh * 3 / 8;
155 + /* Allow for bit depth */
156 + bits_alloc += (bits_alloc * bits_minus8) / 8;
157 + return rpivid_round_up_size(bits_alloc);
158 +}
159 +
160 int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt)
161 {
162 + size_t size;
163 + u32 w;
164 + u32 h;
165 +
166 if (pix_fmt->pixelformat != V4L2_PIX_FMT_HEVC_SLICE)
167 return -EINVAL;
168
169 - /* Zero bytes per line for encoded source. */
170 - pix_fmt->plane_fmt[0].bytesperline = 0;
171 - /* Choose some minimum size since this can't be 0 */
172 - pix_fmt->plane_fmt[0].sizeimage = max_t(u32, SZ_1K,
173 - pix_fmt->plane_fmt[0].sizeimage);
174 + w = pix_fmt->width;
175 + h = pix_fmt->height;
176 + if (!w || !h) {
177 + w = 1920;
178 + h = 1080;
179 + }
180 + if (w > 4096)
181 + w = 4096;
182 + if (h > 4096)
183 + h = 4096;
184 +
185 + if (!pix_fmt->plane_fmt[0].sizeimage ||
186 + pix_fmt->plane_fmt[0].sizeimage > SZ_32M) {
187 + /* Unspecified or way too big - pick max for size */
188 + size = rpivid_bit_buf_size(w, h, 2);
189 + }
190 + /* Set a minimum */
191 + size = max_t(u32, SZ_4K, pix_fmt->plane_fmt[0].sizeimage);
192 +
193 + pix_fmt->width = w;
194 + pix_fmt->height = h;
195 pix_fmt->num_planes = 1;
196 pix_fmt->field = V4L2_FIELD_NONE;
197 + /* Zero bytes per line for encoded source. */
198 + pix_fmt->plane_fmt[0].bytesperline = 0;
199 + pix_fmt->plane_fmt[0].sizeimage = size;
200 +
201 return 0;
202 }
203
204 --- a/drivers/staging/media/rpivid/rpivid_video.h
205 +++ b/drivers/staging/media/rpivid/rpivid_video.h
206 @@ -24,6 +24,10 @@ extern const struct v4l2_ioctl_ops rpivi
207
208 int rpivid_queue_init(void *priv, struct vb2_queue *src_vq,
209 struct vb2_queue *dst_vq);
210 +
211 +size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8);
212 +size_t rpivid_round_up_size(const size_t x);
213 +
214 int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt);
215 int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt);
216