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
7 Guess a better value for the compressed bitstream buffer size
9 Signed-off-by: John Cox <jc@kynesim.co.uk>
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(-)
16 --- a/drivers/staging/media/rpivid/rpivid_h265.c
17 +++ b/drivers/staging/media/rpivid/rpivid_h265.c
21 #include "rpivid_hw.h"
22 +#include "rpivid_video.h"
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
31 -static unsigned int log2_size(size_t x)
51 - return (x & ~1) ? n + 1 : n;
54 -static size_t round_up_size(const size_t x)
56 - /* Admit no size < 256 */
57 - const unsigned int n = x < 256 ? 8 : log2_size(x) - 1;
59 - return x >= (3 << n) ? 4 << n : (3 << n);
62 static size_t next_size(const size_t x)
64 - return round_up_size(x + 1);
65 + return rpivid_round_up_size(x + 1);
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)
73 - newmax = 2 << log2_size(de->cmd_len + n);
74 + newmax = roundup_pow_of_two(de->cmd_len + n);
76 a = krealloc(de->cmd_fifo, newmax * sizeof(struct rpi_cmd),
78 @@ -1855,23 +1824,10 @@ static void rpivid_h265_setup(struct rpi
79 * slice as we can use the src buf directly
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;
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
90 - * Multiply by 3/2 for 4:2:0
92 - bits_alloc = wxh < 983040 ? wxh * 3 / 4 :
93 - wxh < 983040 * 2 ? 983040 * 3 / 4 :
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);
103 if (gptr_alloc(dev, de->bit_copy_gptr,
105 @@ -2454,17 +2410,15 @@ static int rpivid_h265_start(struct rpiv
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))
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))
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
133 +size_t rpivid_round_up_size(const size_t x)
135 + /* Admit no size < 256 */
136 + const unsigned int n = x < 256 ? 8 : ilog2(x);
138 + return x >= (3 << n) ? 4 << n : (3 << n);
141 +size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8)
143 + const size_t wxh = w * h;
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
150 + * Multiply by 3/2 for 4:2:0
152 + bits_alloc = wxh < 983040 ? wxh * 3 / 4 :
153 + wxh < 983040 * 2 ? 983040 * 3 / 4 :
155 + /* Allow for bit depth */
156 + bits_alloc += (bits_alloc * bits_minus8) / 8;
157 + return rpivid_round_up_size(bits_alloc);
160 int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt)
166 if (pix_fmt->pixelformat != V4L2_PIX_FMT_HEVC_SLICE)
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;
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);
190 + /* Set a minimum */
191 + size = max_t(u32, SZ_4K, pix_fmt->plane_fmt[0].sizeimage);
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;
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
208 int rpivid_queue_init(void *priv, struct vb2_queue *src_vq,
209 struct vb2_queue *dst_vq);
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);
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);