1 /*
2 ********************************************************************************
3 * USB UVC Driver
4 *
5 * (c) Copyright 2006-2010, All winners Co,Ld.
6 * All Right Reserved
7 *
8 * FileName : uvc_v4l2.c
9 *
10 * Author : Kingvan
11 *
12 * Date : 2013/03/26
13 *
14 * Description : USB VIDEO CONTROL Driver中对USB接口设备的处理
15 *
16 * Others : NULL
17 *
18 * History:
19 * <time> <author> <version > <desc>
20 * 2013.03.26 Kingvan 1.0 build this file
21 *
22 ********************************************************************************
23 */
24 //#include "usb_host_config.h"
25 //#include "usb_host_base_types.h"
26 #include "usb_os_platform.h"
27 #include "error.h"
28
29 #include "usb_utils_find_zero_bit.h"
30 #include "usb_list.h"
31 #include "list_head_ext.h"
32
33 #include "usb_host_common.h"
34 #include "usb_gen_dev_mod.h"
35 #include "urb.h"
36 #include "usb_core_interface.h"
37 #include "usb_msg.h"
38
39 //#include "usbh_disk_info.h"
40 //#include "usbh_buff_manager.h"
41 //#include "usbh_disk_remove_time.h"
42
43 #include "video.h"
44 #include "uvcvideo.h"
45
46
47
48 /* ------------------------------------------------------------------------
49 * V4L2 interface
50 */
51
52 /*
53 * Find the frame interval closest to the requested frame interval for the
54 * given frame format and size. This should be done by the device as part of
55 * the Video Probe and Commit negotiation, but some hardware don't implement
56 * that feature.
57 */
uvc_try_frame_interval(struct uvc_frame * frame,__u32 interval)58 static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
59 {
60 __u32 i;
61
62 if (frame->bFrameIntervalType) {
63 __u32 best = -1, dist;
64
65 for (i = 0; i < frame->bFrameIntervalType; ++i) {
66 dist = interval > frame->dwFrameInterval[i]
67 ? interval - frame->dwFrameInterval[i]
68 : frame->dwFrameInterval[i] - interval;
69
70 if (dist > best)
71 break;
72
73 best = dist;
74 }
75
76 interval = frame->dwFrameInterval[i-1];
77 } else {
78 const __u32 min = frame->dwFrameInterval[0];
79 const __u32 max = frame->dwFrameInterval[1];
80 const __u32 step = frame->dwFrameInterval[2];
81
82 interval = min + (interval - min + step/2) / step * step;
83 if (interval > max)
84 interval = max;
85 }
86
87 return interval;
88 }
89
uvc_v4l2_try_format(struct uvc_streaming * stream,struct v4l2_format * fmt,struct uvc_streaming_control * probe,struct uvc_format ** uvc_format,struct uvc_frame ** uvc_frame)90 static int uvc_v4l2_try_format(struct uvc_streaming *stream,
91 struct v4l2_format *fmt, struct uvc_streaming_control *probe,
92 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
93 {
94 struct uvc_format *format = NULL;
95 struct uvc_frame *frame = NULL;
96 __u16 rw, rh;
97 unsigned int d, maxd;
98 unsigned int i;
99 __u32 interval;
100 int ret = 0;
101 __u8 *fcc;
102
103 if (fmt->type != stream->type)
104 return -EINVAL;
105
106 fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
107 hal_log_info("Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
108 fmt->fmt.pix.pixelformat,
109 fcc[0], fcc[1], fcc[2], fcc[3],
110 fmt->fmt.pix.width, fmt->fmt.pix.height);
111
112 /* Check if the hardware supports the requested format. */
113 for (i = 0; i < stream->nformats; ++i) {
114 format = &stream->format[i];
115 if (format->fcc == fmt->fmt.pix.pixelformat)
116 break;
117 }
118
119 if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
120 hal_log_err("Unsupported format 0x%08x.\n",
121 fmt->fmt.pix.pixelformat);
122 return -EINVAL;
123 }
124
125 /* Find the closest image size. The distance between image sizes is
126 * the size in pixels of the non-overlapping regions between the
127 * requested size and the frame-specified size.
128 */
129 rw = fmt->fmt.pix.width;
130 rh = fmt->fmt.pix.height;
131 maxd = (unsigned int)-1;
132
133 for (i = 0; i < format->nframes; ++i) {
134 __u16 w = format->frame[i].wWidth;
135 __u16 h = format->frame[i].wHeight;
136
137 d = min(w, rw) * min(h, rh);
138 d = w*h + rw*rh - 2*d;
139 if (d < maxd) {
140 maxd = d;
141 frame = &format->frame[i];
142 }
143
144 if (maxd == 0)
145 break;
146 }
147
148 if (frame == NULL) {
149 hal_log_err("Unsupported size %ux%u.\n",
150 fmt->fmt.pix.width, fmt->fmt.pix.height);
151 return -EINVAL;
152 }
153
154 /* Use the default frame interval. */
155 interval = frame->dwDefaultFrameInterval;
156 hal_log_info("Using default frame interval %u.%u us "
157 "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
158 (100000000/interval)%10);
159
160 /* Set the format index, frame index and frame interval. */
161 memset(probe, 0, sizeof *probe);
162 probe->bmHint = 1; /* dwFrameInterval */
163 probe->bFormatIndex = format->index;
164 probe->bFrameIndex = frame->bFrameIndex;
165 probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
166 /* Some webcams stall the probe control set request when the
167 * dwMaxVideoFrameSize field is set to zero. The UVC specification
168 * clearly states that the field is read-only from the host, so this
169 * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
170 * the webcam to work around the problem.
171 *
172 * The workaround could probably be enabled for all webcams, so the
173 * quirk can be removed if needed. It's currently useful to detect
174 * webcam bugs and fix them before they hit the market (providing
175 * developers test their webcams with the Linux driver as well as with
176 * the Windows driver).
177 */
178 // mutex_lock(&stream->mutex);
179 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
180 probe->dwMaxVideoFrameSize =
181 stream->ctrl.dwMaxVideoFrameSize;
182
183 /* Probe the device. */
184 ret = uvc_probe_video(stream, probe);
185 // mutex_unlock(&stream->mutex);
186 if (ret < 0)
187 goto done_try_format;
188
189 fmt->fmt.pix.width = frame->wWidth;
190 fmt->fmt.pix.height = frame->wHeight;
191 fmt->fmt.pix.field = V4L2_FIELD_NONE;
192 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
193 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
194 fmt->fmt.pix.colorspace = format->colorspace;
195 fmt->fmt.pix.priv = 0;
196
197 if (uvc_format != NULL)
198 *uvc_format = format;
199 if (uvc_frame != NULL)
200 *uvc_frame = frame;
201
202 done_try_format:
203 return ret;
204 }
205
uvc_v4l2_get_format(struct uvc_streaming * stream,struct v4l2_format * fmt)206 static int uvc_v4l2_get_format(struct uvc_streaming *stream,
207 struct v4l2_format *fmt)
208 {
209 struct uvc_format *format;
210 struct uvc_frame *frame;
211 int ret = 0;
212
213 if (fmt->type != stream->type)
214 return -EINVAL;
215
216 // mutex_lock(&stream->mutex);
217 format = stream->cur_format;
218 frame = stream->cur_frame;
219
220 if (format == NULL || frame == NULL) {
221 ret = -EINVAL;
222 goto done_get_format;
223 }
224
225 fmt->fmt.pix.pixelformat = format->fcc;
226 fmt->fmt.pix.width = frame->wWidth;
227 fmt->fmt.pix.height = frame->wHeight;
228 fmt->fmt.pix.field = V4L2_FIELD_NONE;
229 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
230 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
231 fmt->fmt.pix.colorspace = format->colorspace;
232 fmt->fmt.pix.priv = 0;
233
234 done_get_format:
235 // mutex_unlock(&stream->mutex);
236 return ret;
237 }
238
uvc_v4l2_set_format(struct uvc_streaming * stream,struct v4l2_format * fmt)239 static int uvc_v4l2_set_format(struct uvc_streaming *stream,
240 struct v4l2_format *fmt)
241 {
242 struct uvc_streaming_control probe;
243 struct uvc_format *format;
244 struct uvc_frame *frame;
245 __s32 ret;
246
247 if (fmt->type != stream->type)
248 return -EINVAL;
249
250 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
251 if (ret < 0)
252 return ret;
253
254 // mutex_lock(&stream->mutex);
255
256 // if (uvc_queue_allocated(&stream->queue)) {
257 // ret = -EBUSY;
258 // goto done;
259 // }
260
261 memcpy(&stream->ctrl, &probe, sizeof probe);
262 stream->cur_format = format;
263 stream->cur_frame = frame;
264
265 //done:
266 // mutex_unlock(&stream->mutex);
267 return ret;
268 }
269
uvc_v4l2_get_streamparm(struct uvc_streaming * stream,struct v4l2_streamparm * parm)270 static __s32 uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
271 struct v4l2_streamparm *parm)
272 {
273 __u32 numerator, denominator;
274
275 if (parm->type != stream->type)
276 return -EINVAL;
277
278 // mutex_lock(&stream->mutex);
279 numerator = stream->ctrl.dwFrameInterval;
280 // mutex_unlock(&stream->mutex);
281
282 denominator = 10000000;
283 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
284
285 memset(parm, 0, sizeof *parm);
286 parm->type = stream->type;
287
288 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
289 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
290 parm->parm.capture.capturemode = 0;
291 parm->parm.capture.timeperframe.numerator = numerator;
292 parm->parm.capture.timeperframe.denominator = denominator;
293 parm->parm.capture.extendedmode = 0;
294 parm->parm.capture.readbuffers = 0;
295 } else {
296 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
297 parm->parm.output.outputmode = 0;
298 parm->parm.output.timeperframe.numerator = numerator;
299 parm->parm.output.timeperframe.denominator = denominator;
300 }
301
302 return 0;
303 }
304
uvc_v4l2_set_streamparm(struct uvc_streaming * stream,struct v4l2_streamparm * parm)305 static __s32 uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
306 struct v4l2_streamparm *parm)
307 {
308 struct uvc_streaming_control probe;
309 struct v4l2_fract timeperframe;
310 __u32 interval;
311 __s32 ret;
312
313 if (parm->type != stream->type)
314 return -EINVAL;
315
316 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
317 timeperframe = parm->parm.capture.timeperframe;
318 else
319 timeperframe = parm->parm.output.timeperframe;
320
321 interval = uvc_fraction_to_interval(timeperframe.numerator,
322 timeperframe.denominator);
323 hal_log_err("Setting frame interval to %u/%u (%u).\n",
324 timeperframe.numerator, timeperframe.denominator, interval);
325
326 // mutex_lock(&stream->mutex);
327
328 // if (uvc_queue_streaming(&stream->queue)) {
329 // mutex_unlock(&stream->mutex);
330 // return -EBUSY;
331 // }
332
333 memcpy(&probe, &stream->ctrl, sizeof probe);
334 probe.dwFrameInterval =
335 uvc_try_frame_interval(stream->cur_frame, interval);
336
337 /* Probe the device with the new settings. */
338 ret = uvc_probe_video(stream, &probe);
339 if (ret < 0) {
340 // mutex_unlock(&stream->mutex);
341 return ret;
342 }
343
344 memcpy(&stream->ctrl, &probe, sizeof probe);
345 // mutex_unlock(&stream->mutex);
346
347 /* Return the actual frame period. */
348 timeperframe.numerator = probe.dwFrameInterval;
349 timeperframe.denominator = 10000000;
350 uvc_simplify_fraction(&timeperframe.numerator,
351 &timeperframe.denominator, 8, 333);
352
353 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
354 parm->parm.capture.timeperframe = timeperframe;
355 else
356 parm->parm.output.timeperframe = timeperframe;
357
358 return 0;
359 }
360
361 /* ------------------------------------------------------------------------
362 * Privilege management
363 */
364
365 /*
366 * Privilege management is the multiple-open implementation basis. The current
367 * implementation is completely transparent for the end-user and doesn't
368 * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
369 * Those ioctls enable finer control on the device (by making possible for a
370 * user to request exclusive access to a device), but are not mature yet.
371 * Switching to the V4L2 priority mechanism might be considered in the future
372 * if this situation changes.
373 *
374 * Each open instance of a UVC device can either be in a privileged or
375 * unprivileged state. Only a single instance can be in a privileged state at
376 * a given time. Trying to perform an operation that requires privileges will
377 * automatically acquire the required privileges if possible, or return -EBUSY
378 * otherwise. Privileges are dismissed when closing the instance or when
379 * freeing the video buffers using VIDIOC_REQBUFS.
380 *
381 * Operations that require privileges are:
382 *
383 * - VIDIOC_S_INPUT
384 * - VIDIOC_S_PARM
385 * - VIDIOC_S_FMT
386 * - VIDIOC_REQBUFS
387 */
uvc_acquire_privileges(struct uvc_fh * handle)388 static int uvc_acquire_privileges(struct uvc_fh *handle)
389 {
390 /* Always succeed if the handle is already privileged. */
391 if (handle->state == UVC_HANDLE_ACTIVE)
392 return 0;
393
394 // /* Check if the device already has a privileged handle. */
395 // if (atomic_inc_return(&handle->stream->active) != 1) {
396 // atomic_dec(&handle->stream->active);
397 // return -EBUSY;
398 // }
399
400 handle->state = UVC_HANDLE_ACTIVE;
401 return 0;
402 }
403
uvc_dismiss_privileges(struct uvc_fh * handle)404 static void uvc_dismiss_privileges(struct uvc_fh *handle)
405 {
406 // if (handle->state == UVC_HANDLE_ACTIVE)
407 // atomic_dec(&handle->stream->active);
408
409 handle->state = UVC_HANDLE_PASSIVE;
410 }
411
uvc_has_privileges(struct uvc_fh * handle)412 static int uvc_has_privileges(struct uvc_fh *handle)
413 {
414 return handle->state == UVC_HANDLE_ACTIVE;
415 }
416 /* ------------------------------------------------------------------------
417 * V4L2 file operations
418 */
419 //1.打开设备文件
uvc_v4l2_open(struct uvc_streaming * stream)420 struct uvc_fh * uvc_v4l2_open(struct uvc_streaming *stream)
421 {
422 struct uvc_fh *handle;
423
424 /* Create the device handle. */
425 handle = hal_malloc(sizeof(*handle));
426 if (handle == NULL) {
427 hal_log_err("esMEMS_Malloc() fail\n");
428 return NULL;
429 }
430 hal_log_err("uvc_v4l2_open\n");
431
432 handle->stream = stream;
433 handle->state = UVC_HANDLE_PASSIVE;
434
435 return handle;
436 }
437
438 //11.关闭视频设备
uvc_v4l2_release(struct uvc_fh * handle)439 __s32 uvc_v4l2_release(struct uvc_fh *handle)
440 {
441 struct uvc_streaming *stream = handle->stream;
442
443 hal_log_err("uvc_v4l2_release\n");
444
445 /* Only free resources if this is a privileged handle. */
446 // if (uvc_has_privileges(handle))
447 // uvc_video_enable(stream, 0);
448
449 /* Release the file handle. */
450 uvc_dismiss_privileges(handle);
451 hal_free(handle);
452
453 return 0;
454 }
455
uvc_v4l2_do_ioctl(struct uvc_fh * handle,unsigned int cmd,void * arg)456 __s32 uvc_v4l2_do_ioctl(struct uvc_fh *handle, unsigned int cmd, void *arg)
457 {
458 struct uvc_streaming *stream = handle->stream;
459 long ret = 0;
460
461 hal_log_info("uvc_v4l2_do_ioctl: 0x%x\n", cmd);
462
463 switch (cmd) {
464 /* Query capabilities */
465 case VIDIOC_QUERYCAP://2.取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。
466 {
467 // struct v4l2_capability *cap = arg;
468 //
469 // memset(cap, 0, sizeof *cap);
470 // uvc_strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
471 // uvc_strlcpy(cap->card, vdev->name, sizeof cap->card);
472 // usb_make_path(stream->dev->udev,
473 // cap->bus_info, sizeof(cap->bus_info));
474 // cap->version = DRIVER_VERSION_NUMBER;
475 // if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
476 // cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
477 // | V4L2_CAP_STREAMING;
478 // else
479 // cap->capabilities = V4L2_CAP_VIDEO_OUTPUT
480 // | V4L2_CAP_STREAMING;
481 break;
482 }
483
484 //获取当前驱动支持的视频格式
485 /* Try, Get, Set & Enum format */
486 case VIDIOC_ENUM_FMT:
487 {
488 struct v4l2_fmtdesc *fmt = arg;
489 struct uvc_format *format;
490 enum v4l2_buf_type type = fmt->type;
491 __u32 index = fmt->index;
492
493 if (fmt->type != stream->type ||
494 fmt->index >= stream->nformats)
495 return -EINVAL;
496
497 memset(fmt, 0, sizeof(*fmt));
498 fmt->index = index;
499 fmt->type = type;
500
501 format = &stream->format[fmt->index];
502 fmt->flags = 0;
503 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
504 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
505 uvc_strlcpy(fmt->description, format->name,
506 sizeof fmt->description);
507 fmt->description[sizeof fmt->description - 1] = 0;
508 fmt->pixelformat = format->fcc;
509 break;
510 }
511 //验证当前驱动的显示格式
512 case VIDIOC_TRY_FMT:
513 {
514 struct uvc_streaming_control probe;
515
516 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
517 }
518
519 case VIDIOC_S_FMT://3.设置视频帧的格式个包括宽度和高度等
520 if ((ret = uvc_acquire_privileges(handle)) < 0)
521 return ret;
522
523 return uvc_v4l2_set_format(stream, arg);
524 //读取视频帧的格式个包括宽度和高度等
525 case VIDIOC_G_FMT:
526 return uvc_v4l2_get_format(stream, arg);
527
528
529 /* Get & Set streaming parameters */
530 case VIDIOC_G_PARM:
531 return uvc_v4l2_get_streamparm(stream, arg);
532
533 case VIDIOC_S_PARM:
534 if ((ret = uvc_acquire_privileges(handle)) < 0)
535 return ret;
536
537 return uvc_v4l2_set_streamparm(stream, arg);
538 //查询驱动的修剪能力
539 /* Cropping and scaling */
540 case VIDIOC_CROPCAP:
541 {
542 struct v4l2_cropcap *ccap = arg;
543
544 if (ccap->type != stream->type)
545 return -EINVAL;
546
547 ccap->bounds.left = 0;
548 ccap->bounds.top = 0;
549
550 // mutex_lock(&stream->mutex);
551 ccap->bounds.width = stream->cur_frame->wWidth;
552 ccap->bounds.height = stream->cur_frame->wHeight;
553 // mutex_unlock(&stream->mutex);
554
555 ccap->defrect = ccap->bounds;
556
557 ccap->pixelaspect.numerator = 1;
558 ccap->pixelaspect.denominator = 1;
559 break;
560 }
561 //设置视频信号的边框
562 case VIDIOC_G_CROP:
563 case VIDIOC_S_CROP:
564 return -EINVAL;
565
566 /* Buffers & streaming */
567 case VIDIOC_REQBUFS://4.向驱动申请帧缓冲,一般不超过5个
568 {
569 struct v4l2_requestbuffers *rb = arg;
570
571 if (rb->type != stream->type ||
572 rb->memory != V4L2_MEMORY_MMAP)
573 return -EINVAL;
574
575 if ((ret = uvc_acquire_privileges(handle)) < 0)
576 return ret;
577
578 // mutex_lock(&stream->mutex);
579 // ret = uvc_alloc_buffers(&stream->queue, rb->count,
580 // stream->ctrl.dwMaxVideoFrameSize);
581 // mutex_unlock(&stream->mutex);
582 if (ret < 0)
583 return ret;
584
585 if (ret == 0)
586 uvc_dismiss_privileges(handle);
587
588 rb->count = ret;
589 ret = 0;
590 break;
591 }
592
593 case VIDIOC_QBUF://6.将申请到的帧缓冲全部入队列,以便存放采集到的数据; 9.将缓冲重新入队列尾,这样可以循环采集
594 // if (!uvc_has_privileges(handle))
595 // return -EBUSY;
596 //
597 // return uvc_queue_buffer(&stream->queue, arg);
598 break;
599
600 case VIDIOC_DQBUF://8.出队列以取得已采集数据的帧缓冲,取得原始采集数据
601 // if (!uvc_has_privileges(handle))
602 // return -EBUSY;
603 //
604 // return uvc_dequeue_buffer(&stream->queue, arg,
605 // file->f_flags & O_NONBLOCK);
606 break;
607
608 case VIDIOC_STREAMON://7.开始视频的采集
609 {
610 int type = (int)arg;
611
612 if (type != stream->type)
613 {
614 hal_log_err("%d != %d\n", type, stream->type);
615 return -EINVAL;
616 }
617
618 if (!uvc_has_privileges(handle))
619 {
620 hal_log_err("%d\n", handle->state);
621 return -EBUSY;
622 }
623
624 // mutex_lock(&stream->mutex);
625 ret = uvc_video_enable(stream, 1);
626 // mutex_unlock(&stream->mutex);
627 if (ret < 0)
628 return ret;
629 break;
630 }
631
632 case VIDIOC_STREAMOFF://10.停止视频的采集
633 {
634 int type = (int)arg;
635
636 if (type != stream->type)
637 {
638 hal_log_err("%d != %d\n", type, stream->type);
639 return -EINVAL;
640 }
641
642 if (!uvc_has_privileges(handle))
643 {
644 hal_log_err("%d\n", handle->state);
645 return -EBUSY;
646 }
647
648 return uvc_video_enable(stream, 0);
649 }
650
651 default:
652 hal_log_err("Unknown ioctl 0x%08x\n", cmd);
653 return -EINVAL;
654 }
655
656 return ret;
657 }
658