media: cx231xx: convert to the vb2 framework
This patch converts the cx231xx driver to the vb2 framework. Since you can't do a partial conversion this is a big-bang patch, i.e. large and hard to review. I never found a way around this. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Co-developed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Родитель
7e86efa2ff
Коммит
7c617138b8
|
@ -4,7 +4,7 @@ config VIDEO_CX231XX
|
|||
depends on VIDEO_DEV && I2C && I2C_MUX
|
||||
select VIDEO_TUNER
|
||||
select VIDEO_TVEEPROM
|
||||
select VIDEOBUF_VMALLOC
|
||||
select VIDEOBUF2_VMALLOC
|
||||
select VIDEO_CX25840
|
||||
select VIDEO_CX2341X
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
@ -60,10 +61,6 @@
|
|||
#define MCI_MODE_MEMORY_READ 0x000
|
||||
#define MCI_MODE_MEMORY_WRITE 0x4000
|
||||
|
||||
static unsigned int mpegbufs = 8;
|
||||
module_param(mpegbufs, int, 0644);
|
||||
MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32");
|
||||
|
||||
static unsigned int mpeglines = 128;
|
||||
module_param(mpeglines, int, 0644);
|
||||
MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32");
|
||||
|
@ -1080,16 +1077,6 @@ static int cx231xx_load_firmware(struct cx231xx *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cx231xx_417_check_encoder(struct cx231xx *dev)
|
||||
{
|
||||
u32 status, seq;
|
||||
|
||||
status = 0;
|
||||
seq = 0;
|
||||
cx231xx_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq);
|
||||
dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq);
|
||||
}
|
||||
|
||||
static void cx231xx_codec_settings(struct cx231xx *dev)
|
||||
{
|
||||
dprintk(1, "%s()\n", __func__);
|
||||
|
@ -1227,42 +1214,27 @@ static int cx231xx_initialize_codec(struct cx231xx *dev)
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int bb_buf_setup(struct videobuf_queue *q,
|
||||
unsigned int *count, unsigned int *size)
|
||||
static int queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct cx231xx_fh *fh = q->priv_data;
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vq);
|
||||
unsigned int size = mpeglinesize * mpeglines;
|
||||
|
||||
fh->dev->ts1.ts_packet_size = mpeglinesize;
|
||||
fh->dev->ts1.ts_packet_count = mpeglines;
|
||||
dev->ts1.ts_packet_size = mpeglinesize;
|
||||
dev->ts1.ts_packet_count = mpeglines;
|
||||
|
||||
*size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
|
||||
*count = mpegbufs;
|
||||
if (vq->num_buffers + *nbuffers < CX231XX_MIN_BUF)
|
||||
*nbuffers = CX231XX_MIN_BUF - vq->num_buffers;
|
||||
|
||||
if (*nplanes)
|
||||
return sizes[0] < size ? -EINVAL : 0;
|
||||
*nplanes = 1;
|
||||
sizes[0] = mpeglinesize * mpeglines;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
|
||||
{
|
||||
struct cx231xx_fh *fh = vq->priv_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
unsigned long flags = 0;
|
||||
|
||||
BUG_ON(in_interrupt());
|
||||
|
||||
spin_lock_irqsave(&dev->video_mode.slock, flags);
|
||||
if (dev->USE_ISO) {
|
||||
if (dev->video_mode.isoc_ctl.buf == buf)
|
||||
dev->video_mode.isoc_ctl.buf = NULL;
|
||||
} else {
|
||||
if (dev->video_mode.bulk_ctl.buf == buf)
|
||||
dev->video_mode.bulk_ctl.buf = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->video_mode.slock, flags);
|
||||
videobuf_waiton(vq, &buf->vb, 0, 0);
|
||||
videobuf_vmalloc_free(&buf->vb);
|
||||
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
||||
}
|
||||
|
||||
static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb,
|
||||
struct cx231xx_dmaqueue *dma_q)
|
||||
{
|
||||
|
@ -1276,13 +1248,13 @@ static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *ur
|
|||
return;
|
||||
|
||||
buf = list_entry(dma_q->active.next,
|
||||
struct cx231xx_buffer, vb.queue);
|
||||
struct cx231xx_buffer, list);
|
||||
dev->video_mode.isoc_ctl.buf = buf;
|
||||
dma_q->mpeg_buffer_done = 1;
|
||||
}
|
||||
/* Fill buffer */
|
||||
buf = dev->video_mode.isoc_ctl.buf;
|
||||
vbuf = videobuf_to_vmalloc(&buf->vb);
|
||||
vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
||||
|
||||
if ((dma_q->mpeg_buffer_completed+len) <
|
||||
mpeglines*mpeglinesize) {
|
||||
|
@ -1306,11 +1278,10 @@ static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *ur
|
|||
memcpy(vbuf+dma_q->mpeg_buffer_completed,
|
||||
data, tail_data);
|
||||
|
||||
buf->vb.state = VIDEOBUF_DONE;
|
||||
buf->vb.field_count++;
|
||||
buf->vb.ts = ktime_get_ns();
|
||||
list_del(&buf->vb.queue);
|
||||
wake_up(&buf->vb.done);
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
buf->vb.sequence = dma_q->sequence++;
|
||||
list_del(&buf->list);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
dma_q->mpeg_buffer_completed = 0;
|
||||
|
||||
if (len - tail_data > 0) {
|
||||
|
@ -1331,17 +1302,15 @@ static void buffer_filled(char *data, int len, struct urb *urb,
|
|||
if (list_empty(&dma_q->active))
|
||||
return;
|
||||
|
||||
buf = list_entry(dma_q->active.next,
|
||||
struct cx231xx_buffer, vb.queue);
|
||||
buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list);
|
||||
|
||||
/* Fill buffer */
|
||||
vbuf = videobuf_to_vmalloc(&buf->vb);
|
||||
vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
||||
memcpy(vbuf, data, len);
|
||||
buf->vb.state = VIDEOBUF_DONE;
|
||||
buf->vb.field_count++;
|
||||
buf->vb.ts = ktime_get_ns();
|
||||
list_del(&buf->vb.queue);
|
||||
wake_up(&buf->vb.done);
|
||||
buf->vb.sequence = dma_q->sequence++;
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
list_del(&buf->list);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
}
|
||||
|
||||
static int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
|
||||
|
@ -1394,100 +1363,104 @@ static int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bb_buf_prepare(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb, enum v4l2_field field)
|
||||
static void buffer_queue(struct vb2_buffer *vb)
|
||||
{
|
||||
struct cx231xx_fh *fh = q->priv_data;
|
||||
struct cx231xx_buffer *buf =
|
||||
container_of(vb, struct cx231xx_buffer, vb);
|
||||
struct cx231xx *dev = fh->dev;
|
||||
int rc = 0, urb_init = 0;
|
||||
int size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
|
||||
container_of(vb, struct cx231xx_buffer, vb.vb2_buf);
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
|
||||
unsigned long flags;
|
||||
|
||||
if (0 != buf->vb.baddr && buf->vb.bsize < size)
|
||||
return -EINVAL;
|
||||
buf->vb.width = fh->dev->ts1.ts_packet_size;
|
||||
buf->vb.height = fh->dev->ts1.ts_packet_count;
|
||||
buf->vb.size = size;
|
||||
buf->vb.field = field;
|
||||
spin_lock_irqsave(&dev->video_mode.slock, flags);
|
||||
list_add_tail(&buf->list, &vidq->active);
|
||||
spin_unlock_irqrestore(&dev->video_mode.slock, flags);
|
||||
}
|
||||
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
rc = videobuf_iolock(q, &buf->vb, NULL);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
static void return_all_buffers(struct cx231xx *dev,
|
||||
enum vb2_buffer_state state)
|
||||
{
|
||||
struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
|
||||
struct cx231xx_buffer *buf, *node;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->video_mode.slock, flags);
|
||||
list_for_each_entry_safe(buf, node, &vidq->active, list) {
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, state);
|
||||
list_del(&buf->list);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->video_mode.slock, flags);
|
||||
}
|
||||
|
||||
if (dev->USE_ISO) {
|
||||
if (!dev->video_mode.isoc_ctl.num_bufs)
|
||||
urb_init = 1;
|
||||
} else {
|
||||
if (!dev->video_mode.bulk_ctl.num_bufs)
|
||||
urb_init = 1;
|
||||
}
|
||||
dev_dbg(dev->dev,
|
||||
"urb_init=%d dev->video_mode.max_pkt_size=%d\n",
|
||||
urb_init, dev->video_mode.max_pkt_size);
|
||||
static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
{
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vq);
|
||||
struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
|
||||
int ret = 0;
|
||||
|
||||
vidq->sequence = 0;
|
||||
dev->mode_tv = 1;
|
||||
|
||||
if (urb_init) {
|
||||
rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
|
||||
rc = cx231xx_unmute_audio(dev);
|
||||
if (dev->USE_ISO) {
|
||||
cx231xx_set_alt_setting(dev, INDEX_TS1, 4);
|
||||
rc = cx231xx_init_isoc(dev, mpeglines,
|
||||
mpegbufs,
|
||||
dev->ts1_mode.max_pkt_size,
|
||||
cx231xx_isoc_copy);
|
||||
} else {
|
||||
cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
|
||||
rc = cx231xx_init_bulk(dev, mpeglines,
|
||||
mpegbufs,
|
||||
dev->ts1_mode.max_pkt_size,
|
||||
cx231xx_bulk_copy);
|
||||
}
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
}
|
||||
cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
|
||||
cx231xx_set_gpio_value(dev, 2, 0);
|
||||
|
||||
buf->vb.state = VIDEOBUF_PREPARED;
|
||||
return 0;
|
||||
cx231xx_initialize_codec(dev);
|
||||
|
||||
fail:
|
||||
free_buffer(q, buf);
|
||||
return rc;
|
||||
cx231xx_start_TS1(dev);
|
||||
|
||||
cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
|
||||
cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
|
||||
if (dev->USE_ISO)
|
||||
ret = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
|
||||
CX231XX_NUM_BUFS,
|
||||
dev->ts1_mode.max_pkt_size,
|
||||
cx231xx_isoc_copy);
|
||||
else
|
||||
ret = cx231xx_init_bulk(dev, 320, 5,
|
||||
dev->ts1_mode.max_pkt_size,
|
||||
cx231xx_bulk_copy);
|
||||
if (ret)
|
||||
return_all_buffers(dev, VB2_BUF_STATE_QUEUED);
|
||||
|
||||
call_all(dev, video, s_stream, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bb_buf_queue(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb)
|
||||
static void stop_streaming(struct vb2_queue *vq)
|
||||
{
|
||||
struct cx231xx_fh *fh = q->priv_data;
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vq);
|
||||
unsigned long flags;
|
||||
|
||||
struct cx231xx_buffer *buf =
|
||||
container_of(vb, struct cx231xx_buffer, vb);
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
|
||||
call_all(dev, video, s_stream, 0);
|
||||
|
||||
buf->vb.state = VIDEOBUF_QUEUED;
|
||||
list_add_tail(&buf->vb.queue, &vidq->active);
|
||||
cx231xx_stop_TS1(dev);
|
||||
|
||||
/* do this before setting alternate! */
|
||||
if (dev->USE_ISO)
|
||||
cx231xx_uninit_isoc(dev);
|
||||
else
|
||||
cx231xx_uninit_bulk(dev);
|
||||
cx231xx_set_mode(dev, CX231XX_SUSPEND);
|
||||
|
||||
cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
|
||||
CX231xx_END_NOW, CX231xx_MPEG_CAPTURE,
|
||||
CX231xx_RAW_BITS_NONE);
|
||||
|
||||
spin_lock_irqsave(&dev->video_mode.slock, flags);
|
||||
if (dev->USE_ISO)
|
||||
dev->video_mode.isoc_ctl.buf = NULL;
|
||||
else
|
||||
dev->video_mode.bulk_ctl.buf = NULL;
|
||||
spin_unlock_irqrestore(&dev->video_mode.slock, flags);
|
||||
return_all_buffers(dev, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
|
||||
static void bb_buf_release(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb)
|
||||
{
|
||||
struct cx231xx_buffer *buf =
|
||||
container_of(vb, struct cx231xx_buffer, vb);
|
||||
/*struct cx231xx_fh *fh = q->priv_data;*/
|
||||
/*struct cx231xx *dev = (struct cx231xx *)fh->dev;*/
|
||||
|
||||
free_buffer(q, buf);
|
||||
}
|
||||
|
||||
static const struct videobuf_queue_ops cx231xx_qops = {
|
||||
.buf_setup = bb_buf_setup,
|
||||
.buf_prepare = bb_buf_prepare,
|
||||
.buf_queue = bb_buf_queue,
|
||||
.buf_release = bb_buf_release,
|
||||
static struct vb2_ops cx231xx_video_qops = {
|
||||
.queue_setup = queue_setup,
|
||||
.buf_queue = buffer_queue,
|
||||
.start_streaming = start_streaming,
|
||||
.stop_streaming = stop_streaming,
|
||||
.wait_prepare = vb2_ops_wait_prepare,
|
||||
.wait_finish = vb2_ops_wait_finish,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
@ -1495,8 +1468,7 @@ static const struct videobuf_queue_ops cx231xx_qops = {
|
|||
static int vidioc_g_pixelaspect(struct file *file, void *priv,
|
||||
int type, struct v4l2_fract *f)
|
||||
{
|
||||
struct cx231xx_fh *fh = priv;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
bool is_50hz = dev->encodernorm.id & V4L2_STD_625_50;
|
||||
|
||||
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
|
@ -1511,8 +1483,7 @@ static int vidioc_g_pixelaspect(struct file *file, void *priv,
|
|||
static int vidioc_g_selection(struct file *file, void *priv,
|
||||
struct v4l2_selection *s)
|
||||
{
|
||||
struct cx231xx_fh *fh = priv;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
|
||||
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
|
@ -1533,8 +1504,7 @@ static int vidioc_g_selection(struct file *file, void *priv,
|
|||
|
||||
static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
|
||||
*norm = dev->encodernorm.id;
|
||||
return 0;
|
||||
|
@ -1542,8 +1512,7 @@ static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
|
|||
|
||||
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cx231xx_tvnorms); i++)
|
||||
|
@ -1575,8 +1544,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
|
|||
static int vidioc_s_ctrl(struct file *file, void *priv,
|
||||
struct v4l2_control *ctl)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
struct v4l2_subdev *sd;
|
||||
|
||||
dprintk(3, "enter vidioc_s_ctrl()\n");
|
||||
|
@ -1601,8 +1569,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
|
|||
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
|
||||
dprintk(3, "enter vidioc_g_fmt_vid_cap()\n");
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
|
@ -1621,8 +1588,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
|
|||
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
|
||||
dprintk(3, "enter vidioc_try_fmt_vid_cap()\n");
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
|
@ -1636,230 +1602,21 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_reqbufs(struct file *file, void *priv,
|
||||
struct v4l2_requestbuffers *p)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
|
||||
return videobuf_reqbufs(&fh->vidq, p);
|
||||
}
|
||||
|
||||
static int vidioc_querybuf(struct file *file, void *priv,
|
||||
struct v4l2_buffer *p)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
|
||||
return videobuf_querybuf(&fh->vidq, p);
|
||||
}
|
||||
|
||||
static int vidioc_qbuf(struct file *file, void *priv,
|
||||
struct v4l2_buffer *p)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
|
||||
return videobuf_qbuf(&fh->vidq, p);
|
||||
}
|
||||
|
||||
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
||||
{
|
||||
struct cx231xx_fh *fh = priv;
|
||||
|
||||
return videobuf_dqbuf(&fh->vidq, b, file->f_flags & O_NONBLOCK);
|
||||
}
|
||||
|
||||
|
||||
static int vidioc_streamon(struct file *file, void *priv,
|
||||
enum v4l2_buf_type i)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
|
||||
dprintk(3, "enter vidioc_streamon()\n");
|
||||
cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
|
||||
cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
|
||||
if (dev->USE_ISO)
|
||||
cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
|
||||
CX231XX_NUM_BUFS,
|
||||
dev->video_mode.max_pkt_size,
|
||||
cx231xx_isoc_copy);
|
||||
else {
|
||||
cx231xx_init_bulk(dev, 320,
|
||||
5,
|
||||
dev->ts1_mode.max_pkt_size,
|
||||
cx231xx_bulk_copy);
|
||||
}
|
||||
dprintk(3, "exit vidioc_streamon()\n");
|
||||
return videobuf_streamon(&fh->vidq);
|
||||
}
|
||||
|
||||
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
|
||||
return videobuf_streamoff(&fh->vidq);
|
||||
}
|
||||
|
||||
static int vidioc_log_status(struct file *file, void *priv)
|
||||
{
|
||||
struct cx231xx_fh *fh = priv;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
|
||||
call_all(dev, core, log_status);
|
||||
return v4l2_ctrl_log_status(file, priv);
|
||||
}
|
||||
|
||||
static int mpeg_open(struct file *file)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct cx231xx *dev = video_drvdata(file);
|
||||
struct cx231xx_fh *fh;
|
||||
|
||||
dprintk(2, "%s()\n", __func__);
|
||||
|
||||
if (mutex_lock_interruptible(&dev->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* allocate + initialize per filehandle data */
|
||||
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
|
||||
if (NULL == fh) {
|
||||
mutex_unlock(&dev->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
file->private_data = fh;
|
||||
v4l2_fh_init(&fh->fh, vdev);
|
||||
fh->dev = dev;
|
||||
|
||||
|
||||
videobuf_queue_vmalloc_init(&fh->vidq, &cx231xx_qops,
|
||||
NULL, &dev->video_mode.slock,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED,
|
||||
sizeof(struct cx231xx_buffer), fh, &dev->lock);
|
||||
/*
|
||||
videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops,
|
||||
dev->dev, &dev->ts1.slock,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
V4L2_FIELD_INTERLACED,
|
||||
sizeof(struct cx231xx_buffer),
|
||||
fh, &dev->lock);
|
||||
*/
|
||||
|
||||
cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
|
||||
cx231xx_set_gpio_value(dev, 2, 0);
|
||||
|
||||
cx231xx_initialize_codec(dev);
|
||||
|
||||
mutex_unlock(&dev->lock);
|
||||
v4l2_fh_add(&fh->fh);
|
||||
cx231xx_start_TS1(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpeg_release(struct file *file)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
|
||||
dprintk(3, "mpeg_release()! dev=0x%p\n", dev);
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
cx231xx_stop_TS1(dev);
|
||||
|
||||
/* do this before setting alternate! */
|
||||
if (dev->USE_ISO)
|
||||
cx231xx_uninit_isoc(dev);
|
||||
else
|
||||
cx231xx_uninit_bulk(dev);
|
||||
cx231xx_set_mode(dev, CX231XX_SUSPEND);
|
||||
|
||||
cx231xx_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
|
||||
CX231xx_END_NOW, CX231xx_MPEG_CAPTURE,
|
||||
CX231xx_RAW_BITS_NONE);
|
||||
|
||||
/* FIXME: Review this crap */
|
||||
/* Shut device down on last close */
|
||||
if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
|
||||
if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
|
||||
/* stop mpeg capture */
|
||||
|
||||
msleep(500);
|
||||
cx231xx_417_check_encoder(dev);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (fh->vidq.streaming)
|
||||
videobuf_streamoff(&fh->vidq);
|
||||
if (fh->vidq.reading)
|
||||
videobuf_read_stop(&fh->vidq);
|
||||
|
||||
videobuf_mmap_free(&fh->vidq);
|
||||
v4l2_fh_del(&fh->fh);
|
||||
v4l2_fh_exit(&fh->fh);
|
||||
kfree(fh);
|
||||
mutex_unlock(&dev->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mpeg_read(struct file *file, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
|
||||
/* Deal w/ A/V decoder * and mpeg encoder sync issues. */
|
||||
/* Start mpeg encoder on first read. */
|
||||
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
|
||||
if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
|
||||
if (cx231xx_initialize_codec(dev) < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return videobuf_read_stream(&fh->vidq, data, count, ppos, 0,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
}
|
||||
|
||||
static __poll_t mpeg_poll(struct file *file,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
__poll_t req_events = poll_requested_events(wait);
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
__poll_t res = 0;
|
||||
|
||||
if (v4l2_event_pending(&fh->fh))
|
||||
res |= EPOLLPRI;
|
||||
else
|
||||
poll_wait(file, &fh->fh.wait, wait);
|
||||
|
||||
if (!(req_events & (EPOLLIN | EPOLLRDNORM)))
|
||||
return res;
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
res |= videobuf_poll_stream(file, &fh->vidq, wait);
|
||||
mutex_unlock(&dev->lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
|
||||
dprintk(2, "%s()\n", __func__);
|
||||
|
||||
return videobuf_mmap_mapper(&fh->vidq, vma);
|
||||
}
|
||||
|
||||
static const struct v4l2_file_operations mpeg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mpeg_open,
|
||||
.release = mpeg_release,
|
||||
.read = mpeg_read,
|
||||
.poll = mpeg_poll,
|
||||
.mmap = mpeg_mmap,
|
||||
.open = v4l2_fh_open,
|
||||
.release = vb2_fop_release,
|
||||
.read = vb2_fop_read,
|
||||
.poll = vb2_fop_poll,
|
||||
.mmap = vb2_fop_mmap,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
};
|
||||
|
||||
|
@ -1881,12 +1638,12 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
|
|||
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
|
||||
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
|
||||
.vidioc_s_fmt_vid_cap = vidioc_try_fmt_vid_cap,
|
||||
.vidioc_reqbufs = vidioc_reqbufs,
|
||||
.vidioc_querybuf = vidioc_querybuf,
|
||||
.vidioc_qbuf = vidioc_qbuf,
|
||||
.vidioc_dqbuf = vidioc_dqbuf,
|
||||
.vidioc_streamon = vidioc_streamon,
|
||||
.vidioc_streamoff = vidioc_streamoff,
|
||||
.vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||
.vidioc_querybuf = vb2_ioctl_querybuf,
|
||||
.vidioc_qbuf = vb2_ioctl_qbuf,
|
||||
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||
.vidioc_streamon = vb2_ioctl_streamon,
|
||||
.vidioc_streamoff = vb2_ioctl_streamoff,
|
||||
.vidioc_log_status = vidioc_log_status,
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
.vidioc_g_register = cx231xx_g_register,
|
||||
|
@ -1980,6 +1737,7 @@ int cx231xx_417_register(struct cx231xx *dev)
|
|||
/* FIXME: Port1 hardcoded here */
|
||||
int err = -ENODEV;
|
||||
struct cx231xx_tsport *tsport = &dev->ts1;
|
||||
struct vb2_queue *q;
|
||||
|
||||
dprintk(1, "%s()\n", __func__);
|
||||
|
||||
|
@ -2017,6 +1775,21 @@ int cx231xx_417_register(struct cx231xx *dev)
|
|||
/* Allocate and initialize V4L video device */
|
||||
cx231xx_video_dev_init(dev, dev->udev,
|
||||
&dev->v4l_device, &cx231xx_mpeg_template, "mpeg");
|
||||
q = &dev->mpegq;
|
||||
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
q->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF | VB2_READ;
|
||||
q->drv_priv = dev;
|
||||
q->buf_struct_size = sizeof(struct cx231xx_buffer);
|
||||
q->ops = &cx231xx_video_qops;
|
||||
q->mem_ops = &vb2_vmalloc_memops;
|
||||
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||
q->min_buffers_needed = 1;
|
||||
q->lock = &dev->lock;
|
||||
err = vb2_queue_init(q);
|
||||
if (err)
|
||||
return err;
|
||||
dev->v4l_device.queue = q;
|
||||
|
||||
err = video_register_device(&dev->v4l_device,
|
||||
VFL_TYPE_GRABBER, -1);
|
||||
if (err < 0) {
|
||||
|
|
|
@ -1479,13 +1479,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
|
|||
goto err_dev_init;
|
||||
}
|
||||
|
||||
/* init video dma queues */
|
||||
/* init video dma queue */
|
||||
INIT_LIST_HEAD(&dev->video_mode.vidq.active);
|
||||
INIT_LIST_HEAD(&dev->video_mode.vidq.queued);
|
||||
|
||||
/* init vbi dma queues */
|
||||
/* init vbi dma queue */
|
||||
INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
|
||||
INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued);
|
||||
|
||||
/* Reset other chips required if they are tied up with GPIO pins */
|
||||
cx231xx_add_into_devlist(dev);
|
||||
|
|
|
@ -153,131 +153,98 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
|
|||
Vbi buf operations
|
||||
------------------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
|
||||
unsigned int *size)
|
||||
static int vbi_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct cx231xx_fh *fh = vq->priv_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vq);
|
||||
u32 height = 0;
|
||||
|
||||
height = ((dev->norm & V4L2_STD_625_50) ?
|
||||
PAL_VBI_LINES : NTSC_VBI_LINES);
|
||||
|
||||
*size = (dev->width * height * 2 * 2);
|
||||
if (0 == *count)
|
||||
*count = CX231XX_DEF_VBI_BUF;
|
||||
|
||||
if (*count < CX231XX_MIN_BUF)
|
||||
*count = CX231XX_MIN_BUF;
|
||||
|
||||
*nplanes = 1;
|
||||
sizes[0] = (dev->width * height * 2 * 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is called *without* dev->slock held; please keep it that way */
|
||||
static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
|
||||
static int vbi_buf_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
struct cx231xx_fh *fh = vq->priv_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
unsigned long flags = 0;
|
||||
BUG_ON(in_interrupt());
|
||||
|
||||
/* We used to wait for the buffer to finish here, but this didn't work
|
||||
because, as we were keeping the state as VIDEOBUF_QUEUED,
|
||||
videobuf_queue_cancel marked it as finished for us.
|
||||
(Also, it could wedge forever if the hardware was misconfigured.)
|
||||
|
||||
This should be safe; by the time we get here, the buffer isn't
|
||||
queued anymore. If we ever start marking the buffers as
|
||||
VIDEOBUF_ACTIVE, it won't be, though.
|
||||
*/
|
||||
spin_lock_irqsave(&dev->vbi_mode.slock, flags);
|
||||
if (dev->vbi_mode.bulk_ctl.buf == buf)
|
||||
dev->vbi_mode.bulk_ctl.buf = NULL;
|
||||
spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
|
||||
|
||||
videobuf_vmalloc_free(&buf->vb);
|
||||
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
||||
}
|
||||
|
||||
static int
|
||||
vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
|
||||
enum v4l2_field field)
|
||||
{
|
||||
struct cx231xx_fh *fh = vq->priv_data;
|
||||
struct cx231xx_buffer *buf =
|
||||
container_of(vb, struct cx231xx_buffer, vb);
|
||||
struct cx231xx *dev = fh->dev;
|
||||
int rc = 0, urb_init = 0;
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||||
u32 height = 0;
|
||||
u32 size;
|
||||
|
||||
height = ((dev->norm & V4L2_STD_625_50) ?
|
||||
PAL_VBI_LINES : NTSC_VBI_LINES);
|
||||
buf->vb.size = ((dev->width << 1) * height * 2);
|
||||
size = ((dev->width << 1) * height * 2);
|
||||
|
||||
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
|
||||
if (vb2_plane_size(vb, 0) < size)
|
||||
return -EINVAL;
|
||||
|
||||
buf->vb.width = dev->width;
|
||||
buf->vb.height = height;
|
||||
buf->vb.field = field;
|
||||
buf->vb.field = V4L2_FIELD_SEQ_TB;
|
||||
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
rc = videobuf_iolock(vq, &buf->vb, NULL);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!dev->vbi_mode.bulk_ctl.num_bufs)
|
||||
urb_init = 1;
|
||||
|
||||
if (urb_init) {
|
||||
rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
|
||||
CX231XX_NUM_VBI_BUFS,
|
||||
dev->vbi_mode.alt_max_pkt_size[0],
|
||||
cx231xx_isoc_vbi_copy);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buf->vb.state = VIDEOBUF_PREPARED;
|
||||
vb2_set_plane_payload(vb, 0, size);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free_buffer(vq, buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
||||
static void vbi_buf_queue(struct vb2_buffer *vb)
|
||||
{
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct cx231xx_buffer *buf =
|
||||
container_of(vb, struct cx231xx_buffer, vb);
|
||||
struct cx231xx_fh *fh = vq->priv_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
container_of(vb, struct cx231xx_buffer, vb.vb2_buf);
|
||||
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
|
||||
unsigned long flags;
|
||||
|
||||
buf->vb.state = VIDEOBUF_QUEUED;
|
||||
list_add_tail(&buf->vb.queue, &vidq->active);
|
||||
|
||||
spin_lock_irqsave(&dev->vbi_mode.slock, flags);
|
||||
list_add_tail(&buf->list, &vidq->active);
|
||||
spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
|
||||
}
|
||||
|
||||
static void vbi_buffer_release(struct videobuf_queue *vq,
|
||||
struct videobuf_buffer *vb)
|
||||
static void return_all_buffers(struct cx231xx *dev,
|
||||
enum vb2_buffer_state state)
|
||||
{
|
||||
struct cx231xx_buffer *buf =
|
||||
container_of(vb, struct cx231xx_buffer, vb);
|
||||
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
|
||||
struct cx231xx_buffer *buf, *node;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
free_buffer(vq, buf);
|
||||
spin_lock_irqsave(&dev->vbi_mode.slock, flags);
|
||||
dev->vbi_mode.bulk_ctl.buf = NULL;
|
||||
list_for_each_entry_safe(buf, node, &vidq->active, list) {
|
||||
list_del(&buf->list);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, state);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
|
||||
}
|
||||
|
||||
const struct videobuf_queue_ops cx231xx_vbi_qops = {
|
||||
.buf_setup = vbi_buffer_setup,
|
||||
.buf_prepare = vbi_buffer_prepare,
|
||||
.buf_queue = vbi_buffer_queue,
|
||||
.buf_release = vbi_buffer_release,
|
||||
static int vbi_start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
{
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vq);
|
||||
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
|
||||
int ret;
|
||||
|
||||
vidq->sequence = 0;
|
||||
ret = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
|
||||
CX231XX_NUM_VBI_BUFS,
|
||||
dev->vbi_mode.alt_max_pkt_size[0],
|
||||
cx231xx_isoc_vbi_copy);
|
||||
if (ret)
|
||||
return_all_buffers(dev, VB2_BUF_STATE_QUEUED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void vbi_stop_streaming(struct vb2_queue *vq)
|
||||
{
|
||||
struct cx231xx *dev = vb2_get_drv_priv(vq);
|
||||
|
||||
return_all_buffers(dev, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
|
||||
struct vb2_ops cx231xx_vbi_qops = {
|
||||
.queue_setup = vbi_queue_setup,
|
||||
.buf_prepare = vbi_buf_prepare,
|
||||
.buf_queue = vbi_buf_queue,
|
||||
.start_streaming = vbi_start_streaming,
|
||||
.stop_streaming = vbi_stop_streaming,
|
||||
.wait_prepare = vb2_ops_wait_prepare,
|
||||
.wait_finish = vb2_ops_wait_finish,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
|
@ -512,16 +479,15 @@ static inline void vbi_buffer_filled(struct cx231xx *dev,
|
|||
struct cx231xx_buffer *buf)
|
||||
{
|
||||
/* Advice that buffer was filled */
|
||||
/* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */
|
||||
/* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.index); */
|
||||
|
||||
buf->vb.state = VIDEOBUF_DONE;
|
||||
buf->vb.field_count++;
|
||||
buf->vb.ts = ktime_get_ns();
|
||||
buf->vb.sequence = dma_q->sequence++;
|
||||
buf->vb.vb2_buf.timestamp = ktime_get_ns();
|
||||
|
||||
dev->vbi_mode.bulk_ctl.buf = NULL;
|
||||
|
||||
list_del(&buf->vb.queue);
|
||||
wake_up(&buf->vb.done);
|
||||
list_del(&buf->list);
|
||||
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
}
|
||||
|
||||
u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
|
||||
|
@ -611,11 +577,11 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
|
|||
}
|
||||
|
||||
/* Get the next buffer */
|
||||
*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
|
||||
*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list);
|
||||
|
||||
/* Cleans up buffer - Useful for testing for frame/URB loss */
|
||||
outp = videobuf_to_vmalloc(&(*buf)->vb);
|
||||
memset(outp, 0, (*buf)->vb.size);
|
||||
outp = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0);
|
||||
memset(outp, 0, vb2_plane_size(&(*buf)->vb.vb2_buf, 0));
|
||||
|
||||
dev->vbi_mode.bulk_ctl.buf = *buf;
|
||||
|
||||
|
@ -656,7 +622,7 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
|
|||
if (buf == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
p_out_buffer = videobuf_to_vmalloc(&buf->vb);
|
||||
p_out_buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
||||
|
||||
if (dma_q->bytes_left_in_line != _line_size) {
|
||||
current_line_bytes_copied =
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef _CX231XX_VBI_H
|
||||
#define _CX231XX_VBI_H
|
||||
|
||||
extern const struct videobuf_queue_ops cx231xx_vbi_qops;
|
||||
extern struct vb2_ops cx231xx_vbi_qops;
|
||||
|
||||
#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
|
||||
#define NTSC_VBI_END_LINE 21
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <media/drv-intf/cx2341x.h>
|
||||
|
||||
#include <media/videobuf-vmalloc.h>
|
||||
#include <media/videobuf2-vmalloc.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-fh.h>
|
||||
|
@ -223,8 +223,8 @@ struct cx231xx_fmt {
|
|||
/* buffer for one video frame */
|
||||
struct cx231xx_buffer {
|
||||
/* common v4l buffer stuff -- must be first */
|
||||
struct videobuf_buffer vb;
|
||||
|
||||
struct vb2_v4l2_buffer vb;
|
||||
struct list_head list;
|
||||
struct list_head frame;
|
||||
int top_field;
|
||||
int receiving;
|
||||
|
@ -237,7 +237,6 @@ enum ps_package_head {
|
|||
|
||||
struct cx231xx_dmaqueue {
|
||||
struct list_head active;
|
||||
struct list_head queued;
|
||||
|
||||
wait_queue_head_t wq;
|
||||
|
||||
|
@ -251,6 +250,7 @@ struct cx231xx_dmaqueue {
|
|||
u32 lines_completed;
|
||||
u8 field1_done;
|
||||
u32 lines_per_field;
|
||||
u32 sequence;
|
||||
|
||||
/*Mpeg2 control buffer*/
|
||||
u8 *p_left_data;
|
||||
|
@ -427,23 +427,6 @@ struct cx231xx_audio {
|
|||
|
||||
struct cx231xx;
|
||||
|
||||
struct cx231xx_fh {
|
||||
struct v4l2_fh fh;
|
||||
struct cx231xx *dev;
|
||||
unsigned int stream_on:1; /* Locks streams */
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
struct videobuf_queue vb_vidq;
|
||||
|
||||
/* vbi capture */
|
||||
struct videobuf_queue vidq;
|
||||
struct videobuf_queue vbiq;
|
||||
|
||||
/* MPEG Encoder specifics ONLY */
|
||||
|
||||
atomic_t v4l_reading;
|
||||
};
|
||||
|
||||
/*****************************************************************/
|
||||
/* set/get i2c */
|
||||
/* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
|
||||
|
@ -634,6 +617,7 @@ struct cx231xx {
|
|||
int width; /* current frame width */
|
||||
int height; /* current frame height */
|
||||
int interlaced; /* 1=interlace fields, 0=just top fields */
|
||||
unsigned int size;
|
||||
|
||||
struct cx231xx_audio adev;
|
||||
|
||||
|
@ -657,6 +641,9 @@ struct cx231xx {
|
|||
struct media_pad input_pad[MAX_CX231XX_INPUT];
|
||||
#endif
|
||||
|
||||
struct vb2_queue vidq;
|
||||
struct vb2_queue vbiq;
|
||||
|
||||
unsigned char eedata[256];
|
||||
|
||||
struct cx231xx_video_mode video_mode;
|
||||
|
@ -717,6 +704,7 @@ struct cx231xx {
|
|||
u8 USE_ISO;
|
||||
struct cx231xx_tvnorm encodernorm;
|
||||
struct cx231xx_tsport ts1, ts2;
|
||||
struct vb2_queue mpegq;
|
||||
struct video_device v4l_device;
|
||||
atomic_t v4l_reader_count;
|
||||
u32 freq;
|
||||
|
|
Загрузка…
Ссылка в новой задаче