1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * A virtual stateless device for stateless uAPI development purposes.
4 *
5 * This tool's objective is to help the development and testing of userspace
6 * applications that use the V4L2 stateless API to decode media.
7 *
8 * A userspace implementation can use visl to run a decoding loop even when no
9 * hardware is available or when the kernel uAPI for the codec has not been
10 * upstreamed yet. This can reveal bugs at an early stage.
11 *
12 * This driver can also trace the contents of the V4L2 controls submitted to it.
13 * It can also dump the contents of the vb2 buffers through a debugfs
14 * interface. This is in many ways similar to the tracing infrastructure
15 * available for other popular encode/decode APIs out there and can help develop
16 * a userspace application by using another (working) one as a reference.
17 *
18 * Note that no actual decoding of video frames is performed by visl. The V4L2
19 * test pattern generator is used to write various debug information to the
20 * capture buffers instead.
21 *
22 * Copyright (C) 2022 Collabora, Ltd.
23 *
24 * Based on the vim2m driver, that is:
25 *
26 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
27 * Pawel Osciak, <pawel@osciak.com>
28 * Marek Szyprowski, <m.szyprowski@samsung.com>
29 *
30 * Based on the vicodec driver, that is:
31 *
32 * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
33 *
34 * Based on the Cedrus VPU driver, that is:
35 *
36 * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
37 * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
38 * Copyright (C) 2018 Bootlin
39 */
40
41 #ifndef _VISL_H_
42 #define _VISL_H_
43
44 #include <linux/debugfs.h>
45 #include <linux/list.h>
46
47 #include <media/v4l2-ctrls.h>
48 #include <media/v4l2-device.h>
49 #include <media/tpg/v4l2-tpg.h>
50
51 #define VISL_NAME "visl"
52 #define VISL_M2M_NQUEUES 2
53
54 #define TPG_STR_BUF_SZ 2048
55
56 extern unsigned int visl_transtime_ms;
57
58 struct visl_ctrls {
59 const struct visl_ctrl_desc *ctrls;
60 unsigned int num_ctrls;
61 };
62
63 struct visl_coded_format_desc {
64 u32 pixelformat;
65 struct v4l2_frmsize_stepwise frmsize;
66 const struct visl_ctrls *ctrls;
67 unsigned int num_decoded_fmts;
68 const u32 *decoded_fmts;
69 };
70
71 extern const struct visl_coded_format_desc visl_coded_fmts[];
72 extern const size_t num_coded_fmts;
73
74 enum {
75 V4L2_M2M_SRC = 0,
76 V4L2_M2M_DST = 1,
77 };
78
79 extern unsigned int visl_debug;
80 #define dprintk(dev, fmt, arg...) \
81 v4l2_dbg(1, visl_debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
82
83 extern int visl_dprintk_frame_start;
84 extern unsigned int visl_dprintk_nframes;
85 extern bool keep_bitstream_buffers;
86 extern int bitstream_trace_frame_start;
87 extern unsigned int bitstream_trace_nframes;
88
89 #define frame_dprintk(dev, current, fmt, arg...) \
90 do { \
91 if (visl_dprintk_frame_start > -1 && \
92 (current) >= visl_dprintk_frame_start && \
93 (current) < visl_dprintk_frame_start + visl_dprintk_nframes) \
94 dprintk(dev, fmt, ## arg); \
95 } while (0) \
96
97 struct visl_q_data {
98 unsigned int sequence;
99 };
100
101 struct visl_dev {
102 struct v4l2_device v4l2_dev;
103 struct video_device vfd;
104 #ifdef CONFIG_MEDIA_CONTROLLER
105 struct media_device mdev;
106 #endif
107
108 struct mutex dev_mutex;
109
110 struct v4l2_m2m_dev *m2m_dev;
111
112 #ifdef CONFIG_VISL_DEBUGFS
113 struct dentry *debugfs_root;
114 struct dentry *bitstream_debugfs;
115 struct list_head bitstream_blobs;
116
117 /* Protects the "blob" list */
118 struct mutex bitstream_lock;
119 #endif
120 };
121
122 enum visl_codec {
123 VISL_CODEC_NONE,
124 VISL_CODEC_FWHT,
125 VISL_CODEC_MPEG2,
126 VISL_CODEC_VP8,
127 VISL_CODEC_VP9,
128 VISL_CODEC_H264,
129 VISL_CODEC_HEVC,
130 };
131
132 struct visl_blob {
133 struct list_head list;
134 struct dentry *dentry;
135 struct debugfs_blob_wrapper blob;
136 };
137
138 struct visl_ctx {
139 struct v4l2_fh fh;
140 struct visl_dev *dev;
141 struct v4l2_ctrl_handler hdl;
142
143 struct mutex vb_mutex;
144
145 struct visl_q_data q_data[VISL_M2M_NQUEUES];
146 enum visl_codec current_codec;
147
148 const struct visl_coded_format_desc *coded_format_desc;
149
150 struct v4l2_format coded_fmt;
151 struct v4l2_format decoded_fmt;
152
153 struct tpg_data tpg;
154 u64 capture_streamon_jiffies;
155 char *tpg_str_buf;
156 };
157
158 struct visl_ctrl_desc {
159 struct v4l2_ctrl_config cfg;
160 };
161
visl_file_to_ctx(struct file * file)162 static inline struct visl_ctx *visl_file_to_ctx(struct file *file)
163 {
164 return container_of(file->private_data, struct visl_ctx, fh);
165 }
166
visl_v4l2fh_to_ctx(struct v4l2_fh * v4l2_fh)167 static inline struct visl_ctx *visl_v4l2fh_to_ctx(struct v4l2_fh *v4l2_fh)
168 {
169 return container_of(v4l2_fh, struct visl_ctx, fh);
170 }
171
172 void *visl_find_control_data(struct visl_ctx *ctx, u32 id);
173 struct v4l2_ctrl *visl_find_control(struct visl_ctx *ctx, u32 id);
174 u32 visl_control_num_elems(struct visl_ctx *ctx, u32 id);
175
176 #endif /* _VISL_H_ */
177