drivers/usb/gadget/function/uvc_v4l2.c

Source file repositories/reference/linux-study-clean/drivers/usb/gadget/function/uvc_v4l2.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/gadget/function/uvc_v4l2.c
Extension
.c
Size
18936 bytes
Lines
746
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (index == i) {
			uformat = format->fmt;
			break;
		}
		i++;
	}

	return uformat;
}

static struct uvcg_frame *find_frame_by_index(struct uvc_device *uvc,
				       struct uvcg_format *uformat,
				       int index)
{
	struct uvcg_format_ptr *format;
	struct uvcg_frame_ptr *frame;
	struct uvcg_frame *uframe = NULL;

	list_for_each_entry(format, &uvc->header->formats, entry) {
		if (format->fmt->type != uformat->type)
			continue;
		list_for_each_entry(frame, &format->fmt->frames, entry) {
			if (index == frame->frm->frame.b_frame_index) {
				uframe = frame->frm;
				break;
			}
		}
	}

	return uframe;
}

static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc,
					      u32 pixelformat)
{
	struct uvcg_format_ptr *format;
	struct uvcg_format *uformat = NULL;

	list_for_each_entry(format, &uvc->header->formats, entry) {
		const struct uvc_format_desc *fmtdesc = to_uvc_format(format->fmt);

		if (IS_ERR(fmtdesc))
			continue;

		if (fmtdesc->fcc == pixelformat) {
			uformat = format->fmt;
			break;
		}
	}

	return uformat;
}

static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc,
					   struct uvcg_format *uformat,
					   u16 rw, u16 rh)
{
	struct uvc_video *video = &uvc->video;
	struct uvcg_format_ptr *format;
	struct uvcg_frame_ptr *frame;
	struct uvcg_frame *uframe = NULL;
	unsigned int d, maxd;

	/* 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.
	 */
	maxd = (unsigned int)-1;

	list_for_each_entry(format, &uvc->header->formats, entry) {
		if (format->fmt->type != uformat->type)
			continue;

		list_for_each_entry(frame, &format->fmt->frames, entry) {
			u16 w, h;

			w = frame->frm->frame.w_width;
			h = frame->frm->frame.w_height;

			d = min(w, rw) * min(h, rh);
			d = w*h + rw*rh - 2*d;
			if (d < maxd) {
				maxd = d;
				uframe = frame->frm;
			}

			if (maxd == 0)
				break;
		}
	}

Annotation

Implementation Notes