[media] cx88: move width, height and field to core struct
The width, height and field values are core fields since both vbi, video and blackbird use the same video input. Move those fields to the correct struct. Also fix the field checks in the try_fmt functions: add V4L2_FIELD_SEQ_BT/TB support and map incorrect field values to a correct field value instead of returning an error. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
d386259f8e
commit
ccd6f1d488
|
@ -515,12 +515,14 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
|
|||
|
||||
static void blackbird_codec_settings(struct cx8802_dev *dev)
|
||||
{
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
/* assign frame size */
|
||||
blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
|
||||
dev->height, dev->width);
|
||||
core->height, core->width);
|
||||
|
||||
dev->cxhdl.width = dev->width;
|
||||
dev->cxhdl.height = dev->height;
|
||||
dev->cxhdl.width = core->width;
|
||||
dev->cxhdl.height = core->height;
|
||||
cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50);
|
||||
cx2341x_handler_setup(&dev->cxhdl);
|
||||
}
|
||||
|
@ -658,7 +660,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
|||
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
|
||||
struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
|
||||
|
||||
return cx8802_buf_prepare(vb->vb2_queue, dev, buf, dev->field);
|
||||
return cx8802_buf_prepare(vb->vb2_queue, dev, buf);
|
||||
}
|
||||
|
||||
static void buffer_finish(struct vb2_buffer *vb)
|
||||
|
@ -796,55 +798,75 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_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 cx8802_dev *dev = video_drvdata(file);
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->fmt.pix.bytesperline = 0;
|
||||
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
f->fmt.pix.width = dev->width;
|
||||
f->fmt.pix.height = dev->height;
|
||||
f->fmt.pix.field = dev->field;
|
||||
dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
|
||||
dev->width, dev->height, dev->field);
|
||||
f->fmt.pix.width = core->width;
|
||||
f->fmt.pix.height = core->height;
|
||||
f->fmt.pix.field = core->field;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_try_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 cx8802_dev *dev = video_drvdata(file);
|
||||
struct cx88_core *core = dev->core;
|
||||
unsigned maxw, maxh;
|
||||
enum v4l2_field field;
|
||||
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->fmt.pix.bytesperline = 0;
|
||||
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
|
||||
dev->width, dev->height, dev->field);
|
||||
|
||||
maxw = norm_maxw(core->tvnorm);
|
||||
maxh = norm_maxh(core->tvnorm);
|
||||
|
||||
field = f->fmt.pix.field;
|
||||
|
||||
switch (field) {
|
||||
case V4L2_FIELD_TOP:
|
||||
case V4L2_FIELD_BOTTOM:
|
||||
case V4L2_FIELD_INTERLACED:
|
||||
case V4L2_FIELD_SEQ_BT:
|
||||
case V4L2_FIELD_SEQ_TB:
|
||||
break;
|
||||
default:
|
||||
field = (f->fmt.pix.height > maxh / 2)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_BOTTOM;
|
||||
break;
|
||||
}
|
||||
if (V4L2_FIELD_HAS_T_OR_B(field))
|
||||
maxh /= 2;
|
||||
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
|
||||
&f->fmt.pix.height, 32, maxh, 0, 0);
|
||||
f->fmt.pix.field = field;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
|
||||
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct cx8802_dev *dev = video_drvdata(file);
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->fmt.pix.bytesperline = 0;
|
||||
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
dev->width = f->fmt.pix.width;
|
||||
dev->height = f->fmt.pix.height;
|
||||
dev->field = f->fmt.pix.field;
|
||||
vidioc_try_fmt_vid_cap(file, priv, f);
|
||||
core->width = f->fmt.pix.width;
|
||||
core->height = f->fmt.pix.height;
|
||||
core->field = f->fmt.pix.field;
|
||||
cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
|
||||
blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
|
||||
f->fmt.pix.height, f->fmt.pix.width);
|
||||
dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
|
||||
f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -863,8 +885,8 @@ static int vidioc_s_frequency (struct file *file, void *priv,
|
|||
|
||||
cx88_set_freq (core,f);
|
||||
blackbird_initialize_codec(dev);
|
||||
cx88_set_scale(dev->core, dev->width, dev->height,
|
||||
dev->field);
|
||||
cx88_set_scale(core, core->width, core->height,
|
||||
core->field);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1128,16 +1150,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
|
|||
if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))
|
||||
goto fail_core;
|
||||
|
||||
dev->width = 720;
|
||||
if (core->tvnorm & V4L2_STD_525_60) {
|
||||
dev->height = 480;
|
||||
} else {
|
||||
dev->height = 576;
|
||||
}
|
||||
dev->field = V4L2_FIELD_INTERLACED;
|
||||
dev->cxhdl.port = CX2341X_PORT_STREAMING;
|
||||
dev->cxhdl.width = dev->width;
|
||||
dev->cxhdl.height = dev->height;
|
||||
dev->cxhdl.width = core->width;
|
||||
dev->cxhdl.height = core->height;
|
||||
dev->cxhdl.func = blackbird_mbox_func;
|
||||
dev->cxhdl.priv = dev;
|
||||
err = cx2341x_handler_init(&dev->cxhdl, 36);
|
||||
|
@ -1156,7 +1171,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
|
|||
// init_controls(core);
|
||||
cx88_set_tvnorm(core,core->tvnorm);
|
||||
cx88_video_mux(core,0);
|
||||
cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576);
|
||||
cx2341x_handler_set_50hz(&dev->cxhdl, core->height == 576);
|
||||
cx2341x_handler_setup(&dev->cxhdl);
|
||||
|
||||
q = &dev->vb2_mpegq;
|
||||
|
|
|
@ -3691,6 +3691,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
|
|||
core->nr = nr;
|
||||
sprintf(core->name, "cx88[%d]", core->nr);
|
||||
|
||||
core->tvnorm = V4L2_STD_NTSC_M;
|
||||
core->width = 320;
|
||||
core->height = 240;
|
||||
core->field = V4L2_FIELD_INTERLACED;
|
||||
|
||||
strcpy(core->v4l2_dev.name, core->name);
|
||||
if (v4l2_device_register(NULL, &core->v4l2_dev)) {
|
||||
kfree(core);
|
||||
|
|
|
@ -101,7 +101,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
|||
struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
|
||||
struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
|
||||
|
||||
return cx8802_buf_prepare(vb->vb2_queue, dev, buf, dev->field);
|
||||
return cx8802_buf_prepare(vb->vb2_queue, dev, buf);
|
||||
}
|
||||
|
||||
static void buffer_finish(struct vb2_buffer *vb)
|
||||
|
|
|
@ -93,7 +93,7 @@ int cx8802_start_dma(struct cx8802_dev *dev,
|
|||
struct cx88_core *core = dev->core;
|
||||
|
||||
dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
|
||||
dev->width, dev->height, dev->field);
|
||||
core->width, core->height, core->field);
|
||||
|
||||
/* setup fifo + format */
|
||||
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
|
||||
|
@ -224,7 +224,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
|
|||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev,
|
||||
struct cx88_buffer *buf, enum v4l2_field field)
|
||||
struct cx88_buffer *buf)
|
||||
{
|
||||
int size = dev->ts_packet_size * dev->ts_packet_count;
|
||||
struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
|
||||
|
|
|
@ -365,7 +365,7 @@ static int start_video_dma(struct cx8800_dev *dev,
|
|||
/* setup fifo + format */
|
||||
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
|
||||
buf->bpl, buf->risc.dma);
|
||||
cx88_set_scale(core, dev->width, dev->height, dev->field);
|
||||
cx88_set_scale(core, core->width, core->height, core->field);
|
||||
cx_write(MO_COLOR_CTRL, dev->fmt->cxformat | ColorFormatGamma);
|
||||
|
||||
/* reset counter */
|
||||
|
@ -436,9 +436,10 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
|
|||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
{
|
||||
struct cx8800_dev *dev = q->drv_priv;
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
*num_planes = 1;
|
||||
sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3;
|
||||
sizes[0] = (dev->fmt->depth * core->width * core->height) >> 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -450,52 +451,52 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
|||
struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
|
||||
int rc;
|
||||
|
||||
buf->bpl = dev->width * dev->fmt->depth >> 3;
|
||||
buf->bpl = core->width * dev->fmt->depth >> 3;
|
||||
|
||||
if (vb2_plane_size(vb, 0) < dev->height * buf->bpl)
|
||||
if (vb2_plane_size(vb, 0) < core->height * buf->bpl)
|
||||
return -EINVAL;
|
||||
vb2_set_plane_payload(vb, 0, dev->height * buf->bpl);
|
||||
vb2_set_plane_payload(vb, 0, core->height * buf->bpl);
|
||||
|
||||
rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
|
||||
if (!rc)
|
||||
return -EIO;
|
||||
|
||||
switch (dev->field) {
|
||||
switch (core->field) {
|
||||
case V4L2_FIELD_TOP:
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl, 0, UNSET,
|
||||
buf->bpl, 0, dev->height);
|
||||
buf->bpl, 0, core->height);
|
||||
break;
|
||||
case V4L2_FIELD_BOTTOM:
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl, UNSET, 0,
|
||||
buf->bpl, 0, dev->height);
|
||||
buf->bpl, 0, core->height);
|
||||
break;
|
||||
case V4L2_FIELD_SEQ_TB:
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl,
|
||||
0, buf->bpl * (dev->height >> 1),
|
||||
0, buf->bpl * (core->height >> 1),
|
||||
buf->bpl, 0,
|
||||
dev->height >> 1);
|
||||
core->height >> 1);
|
||||
break;
|
||||
case V4L2_FIELD_SEQ_BT:
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl,
|
||||
buf->bpl * (dev->height >> 1), 0,
|
||||
buf->bpl * (core->height >> 1), 0,
|
||||
buf->bpl, 0,
|
||||
dev->height >> 1);
|
||||
core->height >> 1);
|
||||
break;
|
||||
case V4L2_FIELD_INTERLACED:
|
||||
default:
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl, 0, buf->bpl,
|
||||
buf->bpl, buf->bpl,
|
||||
dev->height >> 1);
|
||||
core->height >> 1);
|
||||
break;
|
||||
}
|
||||
dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
|
||||
buf, buf->vb.v4l2_buf.index,
|
||||
dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
|
||||
core->width, core->height, dev->fmt->depth, dev->fmt->name,
|
||||
(unsigned long)buf->risc.dma);
|
||||
return 0;
|
||||
}
|
||||
|
@ -723,10 +724,11 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
|
|||
struct v4l2_format *f)
|
||||
{
|
||||
struct cx8800_dev *dev = video_drvdata(file);
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
f->fmt.pix.width = dev->width;
|
||||
f->fmt.pix.height = dev->height;
|
||||
f->fmt.pix.field = dev->field;
|
||||
f->fmt.pix.width = core->width;
|
||||
f->fmt.pix.height = core->height;
|
||||
f->fmt.pix.field = core->field;
|
||||
f->fmt.pix.pixelformat = dev->fmt->fourcc;
|
||||
f->fmt.pix.bytesperline =
|
||||
(f->fmt.pix.width * dev->fmt->depth) >> 3;
|
||||
|
@ -749,30 +751,30 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
|||
if (NULL == fmt)
|
||||
return -EINVAL;
|
||||
|
||||
field = f->fmt.pix.field;
|
||||
maxw = norm_maxw(core->tvnorm);
|
||||
maxh = norm_maxh(core->tvnorm);
|
||||
maxw = norm_maxw(core->tvnorm);
|
||||
maxh = norm_maxh(core->tvnorm);
|
||||
|
||||
if (V4L2_FIELD_ANY == field) {
|
||||
field = (f->fmt.pix.height > maxh/2)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_BOTTOM;
|
||||
}
|
||||
field = f->fmt.pix.field;
|
||||
|
||||
switch (field) {
|
||||
case V4L2_FIELD_TOP:
|
||||
case V4L2_FIELD_BOTTOM:
|
||||
maxh = maxh / 2;
|
||||
break;
|
||||
case V4L2_FIELD_INTERLACED:
|
||||
case V4L2_FIELD_SEQ_BT:
|
||||
case V4L2_FIELD_SEQ_TB:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
field = (f->fmt.pix.height > maxh / 2)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_BOTTOM;
|
||||
break;
|
||||
}
|
||||
if (V4L2_FIELD_HAS_T_OR_B(field))
|
||||
maxh /= 2;
|
||||
|
||||
f->fmt.pix.field = field;
|
||||
v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
|
||||
&f->fmt.pix.height, 32, maxh, 0, 0);
|
||||
f->fmt.pix.field = field;
|
||||
f->fmt.pix.bytesperline =
|
||||
(f->fmt.pix.width * fmt->depth) >> 3;
|
||||
f->fmt.pix.sizeimage =
|
||||
|
@ -785,14 +787,15 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
|||
struct v4l2_format *f)
|
||||
{
|
||||
struct cx8800_dev *dev = video_drvdata(file);
|
||||
struct cx88_core *core = dev->core;
|
||||
int err = vidioc_try_fmt_vid_cap (file,priv,f);
|
||||
|
||||
if (0 != err)
|
||||
return err;
|
||||
dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
||||
dev->width = f->fmt.pix.width;
|
||||
dev->height = f->fmt.pix.height;
|
||||
dev->field = f->fmt.pix.field;
|
||||
dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
||||
core->width = f->fmt.pix.width;
|
||||
core->height = f->fmt.pix.height;
|
||||
core->field = f->fmt.pix.field;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1343,7 +1346,6 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
|
|||
|
||||
/* initialize driver struct */
|
||||
spin_lock_init(&dev->slock);
|
||||
core->tvnorm = V4L2_STD_NTSC_M;
|
||||
|
||||
/* init video dma queues */
|
||||
INIT_LIST_HEAD(&dev->vidq.active);
|
||||
|
@ -1438,10 +1440,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
|
|||
/* Sets device info at pci_dev */
|
||||
pci_set_drvdata(pci_dev, dev);
|
||||
|
||||
dev->width = 320;
|
||||
dev->height = 240;
|
||||
dev->field = V4L2_FIELD_INTERLACED;
|
||||
dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
|
||||
dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
|
||||
|
||||
/* initial device configuration */
|
||||
mutex_lock(&core->lock);
|
||||
|
|
|
@ -379,6 +379,8 @@ struct cx88_core {
|
|||
/* state info */
|
||||
struct task_struct *kthread;
|
||||
v4l2_std_id tvnorm;
|
||||
unsigned width, height;
|
||||
unsigned field;
|
||||
enum cx88_tvaudio tvaudio;
|
||||
u32 audiomode_manual;
|
||||
u32 audiomode_current;
|
||||
|
@ -479,8 +481,6 @@ struct cx8800_dev {
|
|||
unsigned char pci_rev,pci_lat;
|
||||
|
||||
const struct cx8800_fmt *fmt;
|
||||
unsigned int width, height;
|
||||
unsigned field;
|
||||
|
||||
/* capture queues */
|
||||
struct cx88_dmaqueue vidq;
|
||||
|
@ -557,9 +557,6 @@ struct cx8802_dev {
|
|||
#if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD)
|
||||
struct video_device *mpeg_dev;
|
||||
u32 mailbox;
|
||||
int width;
|
||||
int height;
|
||||
unsigned field;
|
||||
unsigned char mpeg_active; /* nonzero if mpeg encoder is active */
|
||||
|
||||
/* mpeg params */
|
||||
|
@ -721,7 +718,7 @@ extern void cx88_i2c_init_ir(struct cx88_core *core);
|
|||
/* cx88-mpeg.c */
|
||||
|
||||
int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev,
|
||||
struct cx88_buffer *buf, enum v4l2_field field);
|
||||
struct cx88_buffer *buf);
|
||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
|
||||
void cx8802_cancel_buffers(struct cx8802_dev *dev);
|
||||
int cx8802_start_dma(struct cx8802_dev *dev,
|
||||
|
|
Loading…
Reference in New Issue