27
27
28
28
#define RPIVID_MIN_WIDTH 16U
29
29
#define RPIVID_MIN_HEIGHT 16U
30
+ #define RPIVID_DEFAULT_WIDTH 1920U
31
+ #define RPIVID_DEFAULT_HEIGHT 1088U
30
32
#define RPIVID_MAX_WIDTH 4096U
31
33
#define RPIVID_MAX_HEIGHT 4096U
32
34
@@ -70,25 +72,22 @@ size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_min
70
72
return rpivid_round_up_size (bits_alloc );
71
73
}
72
74
73
- int rpivid_prepare_src_format (struct v4l2_pix_format_mplane * pix_fmt )
75
+ void rpivid_prepare_src_format (struct v4l2_pix_format_mplane * pix_fmt )
74
76
{
75
77
size_t size ;
76
78
u32 w ;
77
79
u32 h ;
78
80
79
- if (pix_fmt -> pixelformat != V4L2_PIX_FMT_HEVC_SLICE )
80
- return - EINVAL ;
81
-
82
81
w = pix_fmt -> width ;
83
82
h = pix_fmt -> height ;
84
83
if (!w || !h ) {
85
- w = 1920 ;
86
- h = 1080 ;
84
+ w = RPIVID_DEFAULT_WIDTH ;
85
+ h = RPIVID_DEFAULT_HEIGHT ;
87
86
}
88
- if (w > 4096 )
89
- w = 4096 ;
90
- if (h > 4096 )
91
- h = 4096 ;
87
+ if (w > RPIVID_MAX_WIDTH )
88
+ w = RPIVID_MAX_WIDTH ;
89
+ if (h > RPIVID_MAX_HEIGHT )
90
+ h = RPIVID_MAX_HEIGHT ;
92
91
93
92
if (!pix_fmt -> plane_fmt [0 ].sizeimage ||
94
93
pix_fmt -> plane_fmt [0 ].sizeimage > SZ_32M ) {
@@ -98,29 +97,41 @@ int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt)
98
97
/* Set a minimum */
99
98
size = max_t (u32 , SZ_4K , pix_fmt -> plane_fmt [0 ].sizeimage );
100
99
100
+ pix_fmt -> pixelformat = V4L2_PIX_FMT_HEVC_SLICE ;
101
101
pix_fmt -> width = w ;
102
102
pix_fmt -> height = h ;
103
103
pix_fmt -> num_planes = 1 ;
104
104
pix_fmt -> field = V4L2_FIELD_NONE ;
105
105
/* Zero bytes per line for encoded source. */
106
106
pix_fmt -> plane_fmt [0 ].bytesperline = 0 ;
107
107
pix_fmt -> plane_fmt [0 ].sizeimage = size ;
108
-
109
- return 0 ;
110
108
}
111
109
112
- int rpivid_prepare_dst_format (struct v4l2_pix_format_mplane * pix_fmt )
110
+ /* Take any pix_format and make it valid */
111
+ static void rpivid_prepare_dst_format (struct v4l2_pix_format_mplane * pix_fmt )
113
112
{
114
113
unsigned int width = pix_fmt -> width ;
115
114
unsigned int height = pix_fmt -> height ;
116
115
unsigned int sizeimage = pix_fmt -> plane_fmt [0 ].sizeimage ;
117
116
unsigned int bytesperline = pix_fmt -> plane_fmt [0 ].bytesperline ;
118
117
119
- switch (pix_fmt -> pixelformat ) {
118
+ if (!width )
119
+ width = RPIVID_DEFAULT_WIDTH ;
120
+ if (width > RPIVID_MAX_WIDTH )
121
+ width = RPIVID_MAX_WIDTH ;
122
+ if (!height )
123
+ height = RPIVID_DEFAULT_HEIGHT ;
124
+ if (height > RPIVID_MAX_HEIGHT )
125
+ height = RPIVID_MAX_HEIGHT ;
126
+
120
127
/* For column formats set bytesperline to column height (stride2) */
128
+ switch (pix_fmt -> pixelformat ) {
129
+ default :
130
+ pix_fmt -> pixelformat = V4L2_PIX_FMT_NV12_COL128 ;
131
+ fallthrough ;
121
132
case V4L2_PIX_FMT_NV12_COL128 :
122
133
/* Width rounds up to columns */
123
- width = ALIGN (min ( width , RPIVID_MAX_WIDTH ) , 128 );
134
+ width = ALIGN (width , 128 );
124
135
125
136
/* 16 aligned height - not sure we even need that */
126
137
height = ALIGN (height , 16 );
@@ -140,7 +151,7 @@ int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
140
151
/* width in pixels (3 pels = 4 bytes) rounded to 128 byte
141
152
* columns
142
153
*/
143
- width = ALIGN (((min ( width , RPIVID_MAX_WIDTH ) + 2 ) / 3 ), 32 ) * 3 ;
154
+ width = ALIGN (((width + 2 ) / 3 ), 32 ) * 3 ;
144
155
145
156
/* 16-aligned height. */
146
157
height = ALIGN (height , 16 );
@@ -157,9 +168,6 @@ int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
157
168
sizeimage = constrain2x (sizeimage ,
158
169
bytesperline * width * 4 / 3 );
159
170
break ;
160
-
161
- default :
162
- return - EINVAL ;
163
171
}
164
172
165
173
pix_fmt -> width = width ;
@@ -169,7 +177,6 @@ int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
169
177
pix_fmt -> plane_fmt [0 ].bytesperline = bytesperline ;
170
178
pix_fmt -> plane_fmt [0 ].sizeimage = sizeimage ;
171
179
pix_fmt -> num_planes = 1 ;
172
- return 0 ;
173
180
}
174
181
175
182
static int rpivid_querycap (struct file * file , void * priv ,
@@ -260,14 +267,13 @@ static u32 pixelformat_from_sps(const struct v4l2_ctrl_hevc_sps * const sps,
260
267
{
261
268
u32 pf = 0 ;
262
269
263
- // Use width 0 as a signifier of unsetness
264
- if (!is_sps_set (sps )) {
270
+ if (!is_sps_set (sps ) || !rpivid_hevc_validate_sps (sps )) {
265
271
/* Treat this as an error? For now return both */
266
272
if (index == 0 )
267
273
pf = V4L2_PIX_FMT_NV12_COL128 ;
268
274
else if (index == 1 )
269
275
pf = V4L2_PIX_FMT_NV12_10_COL128 ;
270
- } else if (index == 0 && rpivid_hevc_validate_sps ( sps ) ) {
276
+ } else if (index == 0 ) {
271
277
if (sps -> bit_depth_luma_minus8 == 0 )
272
278
pf = V4L2_PIX_FMT_NV12_COL128 ;
273
279
else if (sps -> bit_depth_luma_minus8 == 2 )
@@ -282,11 +288,14 @@ rpivid_hevc_default_dst_fmt(struct rpivid_ctx * const ctx)
282
288
{
283
289
const struct v4l2_ctrl_hevc_sps * const sps =
284
290
rpivid_find_control_data (ctx , V4L2_CID_MPEG_VIDEO_HEVC_SPS );
285
- struct v4l2_pix_format_mplane pix_fmt = {
286
- .width = sps -> pic_width_in_luma_samples ,
287
- .height = sps -> pic_height_in_luma_samples ,
288
- .pixelformat = pixelformat_from_sps (sps , 0 )
289
- };
291
+ struct v4l2_pix_format_mplane pix_fmt ;
292
+
293
+ memset (& pix_fmt , 0 , sizeof (pix_fmt ));
294
+ if (is_sps_set (sps )) {
295
+ pix_fmt .width = sps -> pic_width_in_luma_samples ;
296
+ pix_fmt .height = sps -> pic_height_in_luma_samples ;
297
+ pix_fmt .pixelformat = pixelformat_from_sps (sps , 0 );
298
+ }
290
299
291
300
rpivid_prepare_dst_format (& pix_fmt );
292
301
return pix_fmt ;
@@ -315,14 +324,23 @@ static int rpivid_enum_fmt_vid_cap(struct file *file, void *priv,
315
324
return 0 ;
316
325
}
317
326
327
+ /*
328
+ * get dst format - sets it to default if otherwise unset
329
+ * returns a pointer to the struct as a convienience
330
+ */
331
+ static struct v4l2_pix_format_mplane * get_dst_fmt (struct rpivid_ctx * const ctx )
332
+ {
333
+ if (!ctx -> dst_fmt_set )
334
+ ctx -> dst_fmt = rpivid_hevc_default_dst_fmt (ctx );
335
+ return & ctx -> dst_fmt ;
336
+ }
337
+
318
338
static int rpivid_g_fmt_vid_cap (struct file * file , void * priv ,
319
339
struct v4l2_format * f )
320
340
{
321
341
struct rpivid_ctx * ctx = rpivid_file2ctx (file );
322
342
323
- if (!ctx -> dst_fmt_set )
324
- ctx -> dst_fmt = rpivid_hevc_default_dst_fmt (ctx );
325
- f -> fmt .pix_mp = ctx -> dst_fmt ;
343
+ f -> fmt .pix_mp = * get_dst_fmt (ctx );
326
344
return 0 ;
327
345
}
328
346
@@ -358,31 +376,20 @@ static int rpivid_try_fmt_vid_cap(struct file *file, void *priv,
358
376
break ;
359
377
}
360
378
361
- // If we can't use requested fmt then set to default
362
- if (pixelformat == 0 ) {
363
- pixelformat = pixelformat_from_sps (sps , 0 );
364
- // If we don't have a default then give up
365
- if (pixelformat == 0 )
366
- return - EINVAL ;
367
- }
368
-
369
379
// We don't have any way of finding out colourspace so believe
370
380
// anything we are told - take anything set in src as a default
371
381
if (f -> fmt .pix_mp .colorspace == V4L2_COLORSPACE_DEFAULT )
372
382
copy_color (& f -> fmt .pix_mp , & ctx -> src_fmt );
373
383
374
384
f -> fmt .pix_mp .pixelformat = pixelformat ;
375
- return rpivid_prepare_dst_format (& f -> fmt .pix_mp );
385
+ rpivid_prepare_dst_format (& f -> fmt .pix_mp );
386
+ return 0 ;
376
387
}
377
388
378
389
static int rpivid_try_fmt_vid_out (struct file * file , void * priv ,
379
390
struct v4l2_format * f )
380
391
{
381
- if (rpivid_prepare_src_format (& f -> fmt .pix_mp )) {
382
- // Set default src format
383
- f -> fmt .pix_mp .pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT ;
384
- rpivid_prepare_src_format (& f -> fmt .pix_mp );
385
- }
392
+ rpivid_prepare_src_format (& f -> fmt .pix_mp );
386
393
return 0 ;
387
394
}
388
395
@@ -474,7 +481,7 @@ static int rpivid_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
474
481
if (V4L2_TYPE_IS_OUTPUT (vq -> type ))
475
482
pix_fmt = & ctx -> src_fmt ;
476
483
else
477
- pix_fmt = & ctx -> dst_fmt ;
484
+ pix_fmt = get_dst_fmt ( ctx ) ;
478
485
479
486
if (* nplanes ) {
480
487
if (sizes [0 ] < pix_fmt -> plane_fmt [0 ].sizeimage )
0 commit comments