2 * vivid-vbi-out.c - vbi output support functions.
4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 * This program is free software; you may redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 #include <linux/errno.h>
21 #include <linux/kernel.h>
22 #include <linux/videodev2.h>
23 #include <media/v4l2-common.h>
25 #include "vivid-core.h"
26 #include "vivid-kthread-out.h"
27 #include "vivid-vbi-out.h"
28 #include "vivid-vbi-cap.h"
30 static int vbi_out_queue_setup(struct vb2_queue
*vq
, const struct v4l2_format
*fmt
,
31 unsigned *nbuffers
, unsigned *nplanes
,
32 unsigned sizes
[], void *alloc_ctxs
[])
34 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
35 bool is_60hz
= dev
->std_out
& V4L2_STD_525_60
;
36 unsigned size
= vq
->type
== V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
?
37 36 * sizeof(struct v4l2_sliced_vbi_data
) :
38 1440 * 2 * (is_60hz
? 12 : 18);
40 if (!vivid_is_svid_out(dev
))
45 if (vq
->num_buffers
+ *nbuffers
< 2)
46 *nbuffers
= 2 - vq
->num_buffers
;
52 static int vbi_out_buf_prepare(struct vb2_buffer
*vb
)
54 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
55 bool is_60hz
= dev
->std_out
& V4L2_STD_525_60
;
56 unsigned size
= vb
->vb2_queue
->type
== V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
?
57 36 * sizeof(struct v4l2_sliced_vbi_data
) :
58 1440 * 2 * (is_60hz
? 12 : 18);
60 dprintk(dev
, 1, "%s\n", __func__
);
62 if (dev
->buf_prepare_error
) {
64 * Error injection: test what happens if buf_prepare() returns
67 dev
->buf_prepare_error
= false;
70 if (vb2_plane_size(vb
, 0) < size
) {
71 dprintk(dev
, 1, "%s data will not fit into plane (%lu < %u)\n",
72 __func__
, vb2_plane_size(vb
, 0), size
);
75 vb2_set_plane_payload(vb
, 0, size
);
80 static void vbi_out_buf_queue(struct vb2_buffer
*vb
)
82 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
83 struct vivid_buffer
*buf
= container_of(vb
, struct vivid_buffer
, vb
);
85 dprintk(dev
, 1, "%s\n", __func__
);
87 spin_lock(&dev
->slock
);
88 list_add_tail(&buf
->list
, &dev
->vbi_out_active
);
89 spin_unlock(&dev
->slock
);
92 static int vbi_out_start_streaming(struct vb2_queue
*vq
, unsigned count
)
94 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
97 dprintk(dev
, 1, "%s\n", __func__
);
98 dev
->vbi_out_seq_count
= 0;
99 if (dev
->start_streaming_error
) {
100 dev
->start_streaming_error
= false;
103 err
= vivid_start_generating_vid_out(dev
, &dev
->vbi_out_streaming
);
106 struct vivid_buffer
*buf
, *tmp
;
108 list_for_each_entry_safe(buf
, tmp
, &dev
->vbi_out_active
, list
) {
109 list_del(&buf
->list
);
110 vb2_buffer_done(&buf
->vb
, VB2_BUF_STATE_QUEUED
);
116 /* abort streaming and wait for last buffer */
117 static void vbi_out_stop_streaming(struct vb2_queue
*vq
)
119 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
121 dprintk(dev
, 1, "%s\n", __func__
);
122 vivid_stop_generating_vid_out(dev
, &dev
->vbi_out_streaming
);
123 dev
->vbi_out_have_wss
= false;
124 dev
->vbi_out_have_cc
[0] = false;
125 dev
->vbi_out_have_cc
[1] = false;
128 const struct vb2_ops vivid_vbi_out_qops
= {
129 .queue_setup
= vbi_out_queue_setup
,
130 .buf_prepare
= vbi_out_buf_prepare
,
131 .buf_queue
= vbi_out_buf_queue
,
132 .start_streaming
= vbi_out_start_streaming
,
133 .stop_streaming
= vbi_out_stop_streaming
,
134 .wait_prepare
= vivid_unlock
,
135 .wait_finish
= vivid_lock
,
138 int vidioc_g_fmt_vbi_out(struct file
*file
, void *priv
,
139 struct v4l2_format
*f
)
141 struct vivid_dev
*dev
= video_drvdata(file
);
142 struct v4l2_vbi_format
*vbi
= &f
->fmt
.vbi
;
143 bool is_60hz
= dev
->std_out
& V4L2_STD_525_60
;
145 if (!vivid_is_svid_out(dev
) || !dev
->has_raw_vbi_out
)
148 vbi
->sampling_rate
= 25000000;
150 vbi
->samples_per_line
= 1440;
151 vbi
->sample_format
= V4L2_PIX_FMT_GREY
;
152 vbi
->start
[0] = is_60hz
? 10 : 6;
153 vbi
->start
[1] = is_60hz
? 273 : 318;
154 vbi
->count
[0] = vbi
->count
[1] = is_60hz
? 12 : 18;
155 vbi
->flags
= dev
->vbi_cap_interlaced
? V4L2_VBI_INTERLACED
: 0;
156 vbi
->reserved
[0] = 0;
157 vbi
->reserved
[1] = 0;
161 int vidioc_s_fmt_vbi_out(struct file
*file
, void *priv
,
162 struct v4l2_format
*f
)
164 struct vivid_dev
*dev
= video_drvdata(file
);
165 int ret
= vidioc_g_fmt_vbi_out(file
, priv
, f
);
169 if (vb2_is_busy(&dev
->vb_vbi_out_q
))
171 dev
->stream_sliced_vbi_out
= false;
172 dev
->vbi_out_dev
.queue
->type
= V4L2_BUF_TYPE_VBI_OUTPUT
;
176 int vidioc_g_fmt_sliced_vbi_out(struct file
*file
, void *fh
, struct v4l2_format
*fmt
)
178 struct vivid_dev
*dev
= video_drvdata(file
);
179 struct v4l2_sliced_vbi_format
*vbi
= &fmt
->fmt
.sliced
;
181 if (!vivid_is_svid_out(dev
) || !dev
->has_sliced_vbi_out
)
184 vivid_fill_service_lines(vbi
, dev
->service_set_out
);
188 int vidioc_try_fmt_sliced_vbi_out(struct file
*file
, void *fh
, struct v4l2_format
*fmt
)
190 struct vivid_dev
*dev
= video_drvdata(file
);
191 struct v4l2_sliced_vbi_format
*vbi
= &fmt
->fmt
.sliced
;
192 bool is_60hz
= dev
->std_out
& V4L2_STD_525_60
;
193 u32 service_set
= vbi
->service_set
;
195 if (!vivid_is_svid_out(dev
) || !dev
->has_sliced_vbi_out
)
198 service_set
&= is_60hz
? V4L2_SLICED_CAPTION_525
: V4L2_SLICED_WSS_625
;
199 vivid_fill_service_lines(vbi
, service_set
);
203 int vidioc_s_fmt_sliced_vbi_out(struct file
*file
, void *fh
, struct v4l2_format
*fmt
)
205 struct vivid_dev
*dev
= video_drvdata(file
);
206 struct v4l2_sliced_vbi_format
*vbi
= &fmt
->fmt
.sliced
;
207 int ret
= vidioc_try_fmt_sliced_vbi_out(file
, fh
, fmt
);
211 if (vb2_is_busy(&dev
->vb_vbi_out_q
))
213 dev
->service_set_out
= vbi
->service_set
;
214 dev
->stream_sliced_vbi_out
= true;
215 dev
->vbi_out_dev
.queue
->type
= V4L2_BUF_TYPE_SLICED_VBI_OUTPUT
;
219 void vivid_sliced_vbi_out_process(struct vivid_dev
*dev
, struct vivid_buffer
*buf
)
221 struct v4l2_sliced_vbi_data
*vbi
= vb2_plane_vaddr(&buf
->vb
, 0);
222 unsigned elems
= vb2_get_plane_payload(&buf
->vb
, 0) / sizeof(*vbi
);
224 dev
->vbi_out_have_cc
[0] = false;
225 dev
->vbi_out_have_cc
[1] = false;
226 dev
->vbi_out_have_wss
= false;
229 case V4L2_SLICED_CAPTION_525
:
230 if ((dev
->std_out
& V4L2_STD_525_60
) && vbi
->line
== 21) {
231 dev
->vbi_out_have_cc
[!!vbi
->field
] = true;
232 dev
->vbi_out_cc
[!!vbi
->field
][0] = vbi
->data
[0];
233 dev
->vbi_out_cc
[!!vbi
->field
][1] = vbi
->data
[1];
236 case V4L2_SLICED_WSS_625
:
237 if ((dev
->std_out
& V4L2_STD_625_50
) &&
238 vbi
->field
== 0 && vbi
->line
== 23) {
239 dev
->vbi_out_have_wss
= true;
240 dev
->vbi_out_wss
[0] = vbi
->data
[0];
241 dev
->vbi_out_wss
[1] = vbi
->data
[1];