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