1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * vivid-kthread-out.h - video/vbi output thread support functions.
4 *
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 */
7
8#include <linux/module.h>
9#include <linux/errno.h>
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/sched.h>
13#include <linux/slab.h>
14#include <linux/font.h>
15#include <linux/mutex.h>
16#include <linux/videodev2.h>
17#include <linux/kthread.h>
18#include <linux/freezer.h>
19#include <linux/random.h>
20#include <linux/v4l2-dv-timings.h>
21#include <asm/div64.h>
22#include <media/videobuf2-vmalloc.h>
23#include <media/v4l2-dv-timings.h>
24#include <media/v4l2-ioctl.h>
25#include <media/v4l2-fh.h>
26#include <media/v4l2-event.h>
27
28#include "vivid-core.h"
29#include "vivid-vid-common.h"
30#include "vivid-vid-cap.h"
31#include "vivid-vid-out.h"
32#include "vivid-radio-common.h"
33#include "vivid-radio-rx.h"
34#include "vivid-radio-tx.h"
35#include "vivid-sdr-cap.h"
36#include "vivid-vbi-cap.h"
37#include "vivid-vbi-out.h"
38#include "vivid-osd.h"
39#include "vivid-ctrls.h"
40#include "vivid-kthread-out.h"
41#include "vivid-meta-out.h"
42
43static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
44{
45	struct vivid_buffer *vid_out_buf = NULL;
46	struct vivid_buffer *vbi_out_buf = NULL;
47	struct vivid_buffer *meta_out_buf = NULL;
48
49	dprintk(dev, 1, "Video Output Thread Tick\n");
50
51	/* Drop a certain percentage of buffers. */
52	if (dev->perc_dropped_buffers &&
53	    prandom_u32_max(100) < dev->perc_dropped_buffers)
54		return;
55
56	spin_lock(&dev->slock);
57	/*
58	 * Only dequeue buffer if there is at least one more pending.
59	 * This makes video loopback possible.
60	 */
61	if (!list_empty(&dev->vid_out_active) &&
62	    !list_is_singular(&dev->vid_out_active)) {
63		vid_out_buf = list_entry(dev->vid_out_active.next,
64					 struct vivid_buffer, list);
65		list_del(&vid_out_buf->list);
66	}
67	if (!list_empty(&dev->vbi_out_active) &&
68	    (dev->field_out != V4L2_FIELD_ALTERNATE ||
69	     (dev->vbi_out_seq_count & 1))) {
70		vbi_out_buf = list_entry(dev->vbi_out_active.next,
71					 struct vivid_buffer, list);
72		list_del(&vbi_out_buf->list);
73	}
74	if (!list_empty(&dev->meta_out_active)) {
75		meta_out_buf = list_entry(dev->meta_out_active.next,
76					  struct vivid_buffer, list);
77		list_del(&meta_out_buf->list);
78	}
79	spin_unlock(&dev->slock);
80
81	if (!vid_out_buf && !vbi_out_buf && !meta_out_buf)
82		return;
83
84	if (vid_out_buf) {
85		v4l2_ctrl_request_setup(vid_out_buf->vb.vb2_buf.req_obj.req,
86					&dev->ctrl_hdl_vid_out);
87		v4l2_ctrl_request_complete(vid_out_buf->vb.vb2_buf.req_obj.req,
88					   &dev->ctrl_hdl_vid_out);
89		vid_out_buf->vb.sequence = dev->vid_out_seq_count;
90		if (dev->field_out == V4L2_FIELD_ALTERNATE) {
91			/*
92			 * The sequence counter counts frames, not fields.
93			 * So divide by two.
94			 */
95			vid_out_buf->vb.sequence /= 2;
96		}
97		vid_out_buf->vb.vb2_buf.timestamp =
98			ktime_get_ns() + dev->time_wrap_offset;
99		vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
100				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
101		dprintk(dev, 2, "vid_out buffer %d done\n",
102			vid_out_buf->vb.vb2_buf.index);
103	}
104
105	if (vbi_out_buf) {
106		v4l2_ctrl_request_setup(vbi_out_buf->vb.vb2_buf.req_obj.req,
107					&dev->ctrl_hdl_vbi_out);
108		v4l2_ctrl_request_complete(vbi_out_buf->vb.vb2_buf.req_obj.req,
109					   &dev->ctrl_hdl_vbi_out);
110		if (dev->stream_sliced_vbi_out)
111			vivid_sliced_vbi_out_process(dev, vbi_out_buf);
112
113		vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
114		vbi_out_buf->vb.vb2_buf.timestamp =
115			ktime_get_ns() + dev->time_wrap_offset;
116		vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
117				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
118		dprintk(dev, 2, "vbi_out buffer %d done\n",
119			vbi_out_buf->vb.vb2_buf.index);
120	}
121	if (meta_out_buf) {
122		v4l2_ctrl_request_setup(meta_out_buf->vb.vb2_buf.req_obj.req,
123					&dev->ctrl_hdl_meta_out);
124		v4l2_ctrl_request_complete(meta_out_buf->vb.vb2_buf.req_obj.req,
125					   &dev->ctrl_hdl_meta_out);
126		vivid_meta_out_process(dev, meta_out_buf);
127		meta_out_buf->vb.sequence = dev->meta_out_seq_count;
128		meta_out_buf->vb.vb2_buf.timestamp =
129			ktime_get_ns() + dev->time_wrap_offset;
130		vb2_buffer_done(&meta_out_buf->vb.vb2_buf, dev->dqbuf_error ?
131				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
132		dprintk(dev, 2, "meta_out buffer %d done\n",
133			meta_out_buf->vb.vb2_buf.index);
134	}
135
136	dev->dqbuf_error = false;
137}
138
139static int vivid_thread_vid_out(void *data)
140{
141	struct vivid_dev *dev = data;
142	u64 numerators_since_start;
143	u64 buffers_since_start;
144	u64 next_jiffies_since_start;
145	unsigned long jiffies_since_start;
146	unsigned long cur_jiffies;
147	unsigned wait_jiffies;
148	unsigned numerator;
149	unsigned denominator;
150
151	dprintk(dev, 1, "Video Output Thread Start\n");
152
153	set_freezable();
154
155	/* Resets frame counters */
156	dev->out_seq_offset = 0;
157	if (dev->seq_wrap)
158		dev->out_seq_count = 0xffffff80U;
159	dev->jiffies_vid_out = jiffies;
160	dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
161	dev->meta_out_seq_start = 0;
162	dev->out_seq_resync = false;
163
164	for (;;) {
165		try_to_freeze();
166		if (kthread_should_stop())
167			break;
168
169		if (!mutex_trylock(&dev->mutex)) {
170			schedule_timeout_uninterruptible(1);
171			continue;
172		}
173
174		cur_jiffies = jiffies;
175		if (dev->out_seq_resync) {
176			dev->jiffies_vid_out = cur_jiffies;
177			dev->out_seq_offset = dev->out_seq_count + 1;
178			dev->out_seq_count = 0;
179			dev->out_seq_resync = false;
180		}
181		numerator = dev->timeperframe_vid_out.numerator;
182		denominator = dev->timeperframe_vid_out.denominator;
183
184		if (dev->field_out == V4L2_FIELD_ALTERNATE)
185			denominator *= 2;
186
187		/* Calculate the number of jiffies since we started streaming */
188		jiffies_since_start = cur_jiffies - dev->jiffies_vid_out;
189		/* Get the number of buffers streamed since the start */
190		buffers_since_start = (u64)jiffies_since_start * denominator +
191				      (HZ * numerator) / 2;
192		do_div(buffers_since_start, HZ * numerator);
193
194		/*
195		 * After more than 0xf0000000 (rounded down to a multiple of
196		 * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
197		 * jiffies have passed since we started streaming reset the
198		 * counters and keep track of the sequence offset.
199		 */
200		if (jiffies_since_start > JIFFIES_RESYNC) {
201			dev->jiffies_vid_out = cur_jiffies;
202			dev->out_seq_offset = buffers_since_start;
203			buffers_since_start = 0;
204		}
205		dev->out_seq_count = buffers_since_start + dev->out_seq_offset;
206		dev->vid_out_seq_count = dev->out_seq_count - dev->vid_out_seq_start;
207		dev->vbi_out_seq_count = dev->out_seq_count - dev->vbi_out_seq_start;
208		dev->meta_out_seq_count = dev->out_seq_count - dev->meta_out_seq_start;
209
210		vivid_thread_vid_out_tick(dev);
211		mutex_unlock(&dev->mutex);
212
213		/*
214		 * Calculate the number of 'numerators' streamed since we started,
215		 * not including the current buffer.
216		 */
217		numerators_since_start = buffers_since_start * numerator;
218
219		/* And the number of jiffies since we started */
220		jiffies_since_start = jiffies - dev->jiffies_vid_out;
221
222		/* Increase by the 'numerator' of one buffer */
223		numerators_since_start += numerator;
224		/*
225		 * Calculate when that next buffer is supposed to start
226		 * in jiffies since we started streaming.
227		 */
228		next_jiffies_since_start = numerators_since_start * HZ +
229					   denominator / 2;
230		do_div(next_jiffies_since_start, denominator);
231		/* If it is in the past, then just schedule asap */
232		if (next_jiffies_since_start < jiffies_since_start)
233			next_jiffies_since_start = jiffies_since_start;
234
235		wait_jiffies = next_jiffies_since_start - jiffies_since_start;
236		schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
237	}
238	dprintk(dev, 1, "Video Output Thread End\n");
239	return 0;
240}
241
242static void vivid_grab_controls(struct vivid_dev *dev, bool grab)
243{
244	v4l2_ctrl_grab(dev->ctrl_has_crop_out, grab);
245	v4l2_ctrl_grab(dev->ctrl_has_compose_out, grab);
246	v4l2_ctrl_grab(dev->ctrl_has_scaler_out, grab);
247	v4l2_ctrl_grab(dev->ctrl_tx_mode, grab);
248	v4l2_ctrl_grab(dev->ctrl_tx_rgb_range, grab);
249}
250
251int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
252{
253	dprintk(dev, 1, "%s\n", __func__);
254
255	if (dev->kthread_vid_out) {
256		u32 seq_count = dev->out_seq_count + dev->seq_wrap * 128;
257
258		if (pstreaming == &dev->vid_out_streaming)
259			dev->vid_out_seq_start = seq_count;
260		else if (pstreaming == &dev->vbi_out_streaming)
261			dev->vbi_out_seq_start = seq_count;
262		else
263			dev->meta_out_seq_start = seq_count;
264		*pstreaming = true;
265		return 0;
266	}
267
268	/* Resets frame counters */
269	dev->jiffies_vid_out = jiffies;
270	dev->vid_out_seq_start = dev->seq_wrap * 128;
271	dev->vbi_out_seq_start = dev->seq_wrap * 128;
272	dev->meta_out_seq_start = dev->seq_wrap * 128;
273
274	dev->kthread_vid_out = kthread_run(vivid_thread_vid_out, dev,
275			"%s-vid-out", dev->v4l2_dev.name);
276
277	if (IS_ERR(dev->kthread_vid_out)) {
278		int err = PTR_ERR(dev->kthread_vid_out);
279
280		dev->kthread_vid_out = NULL;
281		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
282		return err;
283	}
284	*pstreaming = true;
285	vivid_grab_controls(dev, true);
286
287	dprintk(dev, 1, "returning from %s\n", __func__);
288	return 0;
289}
290
291void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
292{
293	dprintk(dev, 1, "%s\n", __func__);
294
295	if (dev->kthread_vid_out == NULL)
296		return;
297
298	*pstreaming = false;
299	if (pstreaming == &dev->vid_out_streaming) {
300		/* Release all active buffers */
301		while (!list_empty(&dev->vid_out_active)) {
302			struct vivid_buffer *buf;
303
304			buf = list_entry(dev->vid_out_active.next,
305					 struct vivid_buffer, list);
306			list_del(&buf->list);
307			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
308						   &dev->ctrl_hdl_vid_out);
309			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
310			dprintk(dev, 2, "vid_out buffer %d done\n",
311				buf->vb.vb2_buf.index);
312		}
313	}
314
315	if (pstreaming == &dev->vbi_out_streaming) {
316		while (!list_empty(&dev->vbi_out_active)) {
317			struct vivid_buffer *buf;
318
319			buf = list_entry(dev->vbi_out_active.next,
320					 struct vivid_buffer, list);
321			list_del(&buf->list);
322			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
323						   &dev->ctrl_hdl_vbi_out);
324			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
325			dprintk(dev, 2, "vbi_out buffer %d done\n",
326				buf->vb.vb2_buf.index);
327		}
328	}
329
330	if (pstreaming == &dev->meta_out_streaming) {
331		while (!list_empty(&dev->meta_out_active)) {
332			struct vivid_buffer *buf;
333
334			buf = list_entry(dev->meta_out_active.next,
335					 struct vivid_buffer, list);
336			list_del(&buf->list);
337			v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
338						   &dev->ctrl_hdl_meta_out);
339			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
340			dprintk(dev, 2, "meta_out buffer %d done\n",
341				buf->vb.vb2_buf.index);
342		}
343	}
344
345	if (dev->vid_out_streaming || dev->vbi_out_streaming ||
346	    dev->meta_out_streaming)
347		return;
348
349	/* shutdown control thread */
350	vivid_grab_controls(dev, false);
351	kthread_stop(dev->kthread_vid_out);
352	dev->kthread_vid_out = NULL;
353}
354