drivers/media/test-drivers/vivid/vivid-kthread-out.c

Source file repositories/reference/linux-study-clean/drivers/media/test-drivers/vivid/vivid-kthread-out.c

File Facts

System
Linux kernel
Corpus path
drivers/media/test-drivers/vivid/vivid-kthread-out.c
Extension
.c
Size
10970 bytes
Lines
363
Domain
Driver Families
Bucket
drivers/media
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 (dev->field_out == V4L2_FIELD_ALTERNATE) {
			/*
			 * The sequence counter counts frames, not fields.
			 * So divide by two.
			 */
			vid_out_buf->vb.sequence /= 2;
		}
		vid_out_buf->vb.vb2_buf.timestamp =
			ktime_get_ns() + dev->time_wrap_offset;
		vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
		dprintk(dev, 2, "vid_out buffer %d done\n",
			vid_out_buf->vb.vb2_buf.index);
	}

	if (vbi_out_buf) {
		v4l2_ctrl_request_setup(vbi_out_buf->vb.vb2_buf.req_obj.req,
					&dev->ctrl_hdl_vbi_out);
		v4l2_ctrl_request_complete(vbi_out_buf->vb.vb2_buf.req_obj.req,
					   &dev->ctrl_hdl_vbi_out);
		if (dev->stream_sliced_vbi_out)
			vivid_sliced_vbi_out_process(dev, vbi_out_buf);

		vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
		vbi_out_buf->vb.vb2_buf.timestamp =
			ktime_get_ns() + dev->time_wrap_offset;
		vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
		dprintk(dev, 2, "vbi_out buffer %d done\n",
			vbi_out_buf->vb.vb2_buf.index);
	}
	if (meta_out_buf) {
		v4l2_ctrl_request_setup(meta_out_buf->vb.vb2_buf.req_obj.req,
					&dev->ctrl_hdl_meta_out);
		v4l2_ctrl_request_complete(meta_out_buf->vb.vb2_buf.req_obj.req,
					   &dev->ctrl_hdl_meta_out);
		vivid_meta_out_process(dev, meta_out_buf);
		meta_out_buf->vb.sequence = dev->meta_out_seq_count;
		meta_out_buf->vb.vb2_buf.timestamp =
			ktime_get_ns() + dev->time_wrap_offset;
		vb2_buffer_done(&meta_out_buf->vb.vb2_buf, dev->dqbuf_error ?
				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
		dprintk(dev, 2, "meta_out buffer %d done\n",
			meta_out_buf->vb.vb2_buf.index);
	}

	dev->dqbuf_error = false;
}

static int vivid_thread_vid_out(void *data)
{
	struct vivid_dev *dev = data;
	u64 numerators_since_start;
	u64 buffers_since_start;
	u64 next_jiffies_since_start;
	unsigned long jiffies_since_start;
	unsigned long cur_jiffies;
	unsigned wait_jiffies;
	unsigned numerator;
	unsigned denominator;

	dprintk(dev, 1, "Video Output Thread Start\n");

	set_freezable();

	/* Resets frame counters */
	dev->out_seq_offset = 0;
	dev->out_seq_count = 0;
	dev->jiffies_vid_out = jiffies;
	dev->out_seq_resync = false;
	if (dev->time_wrap)
		dev->time_wrap_offset = dev->time_wrap - ktime_get_ns();
	else
		dev->time_wrap_offset = 0;

	for (;;) {
		try_to_freeze();
		if (kthread_should_stop())
			break;

		if (!mutex_trylock(&dev->mutex)) {
			schedule();
			continue;
		}

		cur_jiffies = jiffies;
		if (dev->out_seq_resync) {
			dev->jiffies_vid_out = cur_jiffies;
			dev->out_seq_offset = dev->out_seq_count + 1;
			dev->out_seq_count = 0;

Annotation

Implementation Notes