• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 #             (C) 2008 Elmar Kleijn <elmar_kleijn@hotmail.com>
3 #             (C) 2008 Sjoerd Piepenbrink <need4weed@gmail.com>
4 #             (C) 2008 Hans de Goede <hdegoede@redhat.com>
5 
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License as published by
8 # the Free Software Foundation; either version 2.1 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335  USA
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include "../libv4lconvert/libv4lsyscall-priv.h"
26 #if defined(__OpenBSD__)
27 #include <sys/videoio.h>
28 #else
29 #include <linux/videodev2.h>
30 #endif
31 #include "libv4l2.h"
32 #include "libv4l2-priv.h"
33 
34 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
35 
36 FILE *v4l2_log_file = NULL;
37 
38 const char *v4l2_ioctls[] = {
39 	/* start v4l2 ioctls */
40 	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
41 	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
42 	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
43 	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
44 	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
45 	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
46 	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
47 	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
48 	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
49 	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
50 	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
51 	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
52 	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
53 	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
54 	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
55 	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
56 	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
57 	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
58 	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
59 	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
60 	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
61 	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
62 	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
63 	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
64 	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
65 	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
66 	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
67 	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
68 	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
69 	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
70 	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
71 	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
72 	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
73 	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
74 	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
75 	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
76 	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
77 	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
78 	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
79 	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
80 	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
81 	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
82 	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
83 	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
84 	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
85 	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
86 	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
87 	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
88 	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
89 	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
90 	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
91 	[_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
92 	[_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
93 	[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
94 	[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
95 	[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
96 	[_IOC_NR(VIDIOC_G_ENC_INDEX)]	   = "VIDIOC_G_ENC_INDEX",
97 	[_IOC_NR(VIDIOC_ENCODER_CMD)]	   = "VIDIOC_ENCODER_CMD",
98 	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
99 	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
100 	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
101 	[_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)]   = "VIDIOC_S_HW_FREQ_SEEK",
102 	[_IOC_NR(VIDIOC_S_DV_TIMINGS)]	   = "VIDIOC_S_DV_TIMINGS",
103 	[_IOC_NR(VIDIOC_G_DV_TIMINGS)]	   = "VIDIOC_G_DV_TIMINGS",
104 	[_IOC_NR(VIDIOC_DQEVENT)]	   = "VIDIOC_DQEVENT",
105 	[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
106 	[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
107 	[_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
108 	[_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
109 	[_IOC_NR(VIDIOC_G_SELECTION)]      = "VIDIOC_G_SELECTION",
110 	[_IOC_NR(VIDIOC_S_SELECTION)]      = "VIDIOC_S_SELECTION",
111 	[_IOC_NR(VIDIOC_DECODER_CMD)]      = "VIDIOC_DECODER_CMD",
112 	[_IOC_NR(VIDIOC_TRY_DECODER_CMD)]  = "VIDIOC_TRY_DECODER_CMD",
113 	[_IOC_NR(VIDIOC_ENUM_DV_TIMINGS)]  = "VIDIOC_ENUM_DV_TIMINGS",
114 	[_IOC_NR(VIDIOC_QUERY_DV_TIMINGS)] = "VIDIOC_QUERY_DV_TIMINGS",
115 	[_IOC_NR(VIDIOC_DV_TIMINGS_CAP)]   = "VIDIOC_DV_TIMINGS_CAP",
116 	[_IOC_NR(VIDIOC_ENUM_FREQ_BANDS)]  = "VIDIOC_ENUM_FREQ_BANDS",
117 	[_IOC_NR(VIDIOC_DBG_G_CHIP_INFO)]  = "VIDIOC_DBG_G_CHIP_INFO",
118 };
119 
v4l2_log_ioctl(unsigned long int request,void * arg,int result)120 void v4l2_log_ioctl(unsigned long int request, void *arg, int result)
121 {
122 	const char *ioctl_str;
123 	char buf[40];
124 	int saved_errno = errno;
125 
126 	if (!v4l2_log_file)
127 		return;
128 
129 	if (_IOC_TYPE(request) == 'V' && _IOC_NR(request) < ARRAY_SIZE(v4l2_ioctls))
130 		ioctl_str = v4l2_ioctls[_IOC_NR(request)];
131 	else {
132 		snprintf(buf, sizeof(buf), "unknown request: %c %d",
133 				(int)_IOC_TYPE(request), (int)_IOC_NR(request));
134 		ioctl_str = buf;
135 	}
136 
137 	fprintf(v4l2_log_file, "request == %s\n", ioctl_str);
138 
139 	switch (request) {
140 	case VIDIOC_ENUM_FMT: {
141 		struct v4l2_fmtdesc *fmt = arg;
142 
143 		fprintf(v4l2_log_file, "  index: %u, description: %s\n",
144 				fmt->index, (result < 0) ? "" : (const char *)fmt->description);
145 		break;
146 	}
147 	case VIDIOC_G_FMT:
148 	case VIDIOC_S_FMT:
149 	case VIDIOC_TRY_FMT: {
150 		struct v4l2_format *fmt = arg;
151 		int pixfmt = fmt->fmt.pix.pixelformat;
152 
153 		if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
154 			fprintf(v4l2_log_file, "  pixelformat: %c%c%c%c %ux%u\n",
155 					pixfmt & 0xff,
156 					(pixfmt >> 8) & 0xff,
157 					(pixfmt >> 16) & 0xff,
158 					pixfmt >> 24,
159 					fmt->fmt.pix.width,
160 					fmt->fmt.pix.height);
161 			fprintf(v4l2_log_file, "  field: %d bytesperline: %d imagesize: %d\n",
162 					(int)fmt->fmt.pix.field, (int)fmt->fmt.pix.bytesperline,
163 					(int)fmt->fmt.pix.sizeimage);
164 			fprintf(v4l2_log_file, "  colorspace: %d, priv: %x\n",
165 					(int)fmt->fmt.pix.colorspace, (int)fmt->fmt.pix.priv);
166 		} else {
167 			 fprintf(v4l2_log_file, "  type: %d\n", (int)fmt->type);
168 		}
169 		break;
170 	}
171 	case VIDIOC_REQBUFS: {
172 		struct v4l2_requestbuffers *req = arg;
173 
174 		fprintf(v4l2_log_file, "  count: %u type: %d memory: %d\n",
175 				req->count, (int)req->type, (int)req->memory);
176 		break;
177 	}
178 	case VIDIOC_DQBUF: {
179 		struct v4l2_buffer *buf = arg;
180 		fprintf(v4l2_log_file, "  timestamp %ld.%06ld\n",
181 			(long)buf->timestamp.tv_sec,
182 			(long)buf->timestamp.tv_usec);
183 		break;
184 	}
185 	case VIDIOC_ENUM_FRAMESIZES: {
186 		struct v4l2_frmsizeenum *frmsize = arg;
187 		int pixfmt = frmsize->pixel_format;
188 
189 		fprintf(v4l2_log_file, "  index: %u pixelformat: %c%c%c%c\n",
190 				frmsize->index,
191 				pixfmt & 0xff,
192 				(pixfmt >> 8) & 0xff,
193 				(pixfmt >> 16) & 0xff,
194 				pixfmt >> 24);
195 		switch (frmsize->type) {
196 		case V4L2_FRMSIZE_TYPE_DISCRETE:
197 			fprintf(v4l2_log_file, "  %ux%u\n", frmsize->discrete.width,
198 					frmsize->discrete.height);
199 			break;
200 		case V4L2_FRMSIZE_TYPE_CONTINUOUS:
201 		case V4L2_FRMSIZE_TYPE_STEPWISE:
202 			fprintf(v4l2_log_file, "  %ux%u -> %ux%u\n",
203 					frmsize->stepwise.min_width, frmsize->stepwise.min_height,
204 					frmsize->stepwise.max_width, frmsize->stepwise.max_height);
205 			break;
206 		}
207 		break;
208 	}
209 	case VIDIOC_ENUM_FRAMEINTERVALS: {
210 		struct v4l2_frmivalenum *frmival = arg;
211 		int pixfmt = frmival->pixel_format;
212 
213 		fprintf(v4l2_log_file, "  index: %u pixelformat: %c%c%c%c %ux%u:\n",
214 				frmival->index,
215 				pixfmt & 0xff,
216 				(pixfmt >> 8) & 0xff,
217 				(pixfmt >> 16) & 0xff,
218 				pixfmt >> 24,
219 				frmival->width,
220 				frmival->height);
221 		switch (frmival->type) {
222 		case V4L2_FRMIVAL_TYPE_DISCRETE:
223 			fprintf(v4l2_log_file, "  %u/%u\n", frmival->discrete.numerator,
224 					frmival->discrete.denominator);
225 			break;
226 		case V4L2_FRMIVAL_TYPE_CONTINUOUS:
227 		case V4L2_FRMIVAL_TYPE_STEPWISE:
228 			fprintf(v4l2_log_file, "  %u/%u -> %u/%u\n",
229 					frmival->stepwise.min.numerator,
230 					frmival->stepwise.min.denominator,
231 					frmival->stepwise.max.numerator,
232 					frmival->stepwise.max.denominator);
233 			break;
234 		}
235 		break;
236 	}
237 	case VIDIOC_G_PARM:
238 	case VIDIOC_S_PARM: {
239 		struct v4l2_streamparm *parm = arg;
240 
241 		if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
242 			break;
243 
244 		if (parm->parm.capture.capability & V4L2_CAP_TIMEPERFRAME)
245 			fprintf(v4l2_log_file, "timeperframe: %u/%u\n",
246 				parm->parm.capture.timeperframe.numerator,
247 				parm->parm.capture.timeperframe.denominator);
248 		break;
249 	}
250 	}
251 
252 	if (result < 0)
253 		fprintf(v4l2_log_file, "result == %d (%s)\n", result, strerror(saved_errno));
254 	else
255 		fprintf(v4l2_log_file, "result == %d\n", result);
256 
257 	fflush(v4l2_log_file);
258 }
259