USB Camera (UVC 驱动)

nosilence_2007 2012-12-14 12:48:25
UVC支持YUV和MJPEG的preview,但是奇怪的是上层通过了S_FMT来设置是yuv还是MJPEG,但是并没有找到哪里将MJPEG格式信息通过USB 设置到摄像头这个硬件去了啊。


附 过程:
case VIDIOC_S_FMT:
if ((ret = uvc_acquire_privileges(handle)) < 0)
return ret;

return uvc_v4l2_set_format(stream, arg);

and the uvc_v4l2_set_format call ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
uvc_v4l2_try_format is defined as :
static int 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)
{
struct uvc_format *format = NULL;
struct uvc_frame *frame = NULL;
__u16 rw, rh;
unsigned int d, maxd;
unsigned int i;
__u32 interval;
int ret = 0;
__u8 *fcc;

if (fmt->type != stream->type)
return -EINVAL;

fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
fmt->fmt.pix.pixelformat,
fcc[0], fcc[1], fcc[2], fcc[3],
fmt->fmt.pix.width, fmt->fmt.pix.height);

/* Check if the hardware supports the requested format. */
for (i = 0; i < stream->nformats; ++i) {
format = &stream->format[i];
if (format->fcc == fmt->fmt.pix.pixelformat)
break;
}

if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n",
fmt->fmt.pix.pixelformat);
return -EINVAL;
}

/* Find the closest image size. The distance between image sizes is
* the size in pixels of the non-overlapping regions between the
* requested size and the frame-specified size.
*/
rw = fmt->fmt.pix.width;
rh = fmt->fmt.pix.height;
maxd = (unsigned int)-1;

for (i = 0; i < format->nframes; ++i) {
__u16 w = format->frame[i].wWidth;
__u16 h = format->frame[i].wHeight;

d = min(w, rw) * min(h, rh);
d = w*h + rw*rh - 2*d;
if (d < maxd) {
maxd = d;
frame = &format->frame[i];
}

if (maxd == 0)
break;
}

if (frame == NULL) {
uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n",
fmt->fmt.pix.width, fmt->fmt.pix.height);
return -EINVAL;
}

/* Use the default frame interval. */
interval = frame->dwDefaultFrameInterval;
uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us "
"(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
(100000000/interval)%10);

/* Set the format index, frame index and frame interval. */
memset(probe, 0, sizeof *probe);
probe->bmHint = 1; /* dwFrameInterval */
probe->bFormatIndex = format->index;
probe->bFrameIndex = frame->bFrameIndex;
probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
/* Some webcams stall the probe control set request when the
* dwMaxVideoFrameSize field is set to zero. The UVC specification
* clearly states that the field is read-only from the host, so this
* is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
* the webcam to work around the problem.
*
* The workaround could probably be enabled for all webcams, so the
* quirk can be removed if needed. It's currently useful to detect
* webcam bugs and fix them before they hit the market (providing
* developers test their webcams with the Linux driver as well as with
* the Windows driver).
*/
mutex_lock(&stream->mutex);
if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
probe->dwMaxVideoFrameSize =
stream->ctrl.dwMaxVideoFrameSize;

/* Probe the device. */
ret = uvc_probe_video(stream, probe);
mutex_unlock(&stream->mutex);
if (ret < 0)
goto done;

fmt->fmt.pix.width = frame->wWidth;
fmt->fmt.pix.height = frame->wHeight;
fmt->fmt.pix.field = V4L2_FIELD_NONE;
fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
fmt->fmt.pix.colorspace = format->colorspace;
fmt->fmt.pix.priv = 0;

if (uvc_format != NULL)
*uvc_format = format;
if (uvc_frame != NULL)
*uvc_frame = frame;

done:
return ret;
}


...全文
1157 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
nosilence_2007 2012-12-26
  • 打赏
  • 举报
回复
引用 1 楼 Huntercao 的回复:
在ret = uvc_probe_video(stream, probe);中, 调用ret = uvc_set_video_ctrl(stream, probe, 1); 将uvc_streaming_control *probe传给硬件。
关键在这里: /* Check if the hardware supports the requested format. */ for (i = 0; i < stream->nformats; ++i) { format = &stream->format[i]; if (format->fcc == fmt->fmt.pix.pixelformat) break; }
曹大夯 2012-12-14
  • 打赏
  • 举报
回复
在ret = uvc_probe_video(stream, probe);中, 调用ret = uvc_set_video_ctrl(stream, probe, 1); 将uvc_streaming_control *probe传给硬件。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧