[media] cx18: embed video_device
Embed the video_device struct to simplify the error handling and in order to (eventually) get rid of video_device_alloc/release. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Cc: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
38a1421ddd
commit
08569d6477
|
@ -216,7 +216,7 @@ static int cx18_alsa_load(struct cx18 *cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
|
s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
|
||||||
if (s->video_dev == NULL) {
|
if (s->video_dev.v4l2_dev == NULL) {
|
||||||
CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
|
CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
|
||||||
"skipping\n", __func__);
|
"skipping\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -373,7 +373,7 @@ struct cx18_in_work_order {
|
||||||
struct cx18_stream {
|
struct cx18_stream {
|
||||||
/* These first five fields are always set, even if the stream
|
/* These first five fields are always set, even if the stream
|
||||||
is not actually created. */
|
is not actually created. */
|
||||||
struct video_device *video_dev; /* NULL when stream not created */
|
struct video_device video_dev; /* v4l2_dev is NULL when stream not created */
|
||||||
struct cx18_dvb *dvb; /* DVB / Digital Transport */
|
struct cx18_dvb *dvb; /* DVB / Digital Transport */
|
||||||
struct cx18 *cx; /* for ease of use */
|
struct cx18 *cx; /* for ease of use */
|
||||||
const char *name; /* name of the stream */
|
const char *name; /* name of the stream */
|
||||||
|
|
|
@ -797,7 +797,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
|
||||||
CX18_DEBUG_WARN("nomem on v4l2 open\n");
|
CX18_DEBUG_WARN("nomem on v4l2 open\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
v4l2_fh_init(&item->fh, s->video_dev);
|
v4l2_fh_init(&item->fh, &s->video_dev);
|
||||||
|
|
||||||
item->cx = cx;
|
item->cx = cx;
|
||||||
item->type = s->type;
|
item->type = s->type;
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ static int cx18_log_status(struct file *file, void *fh)
|
||||||
for (i = 0; i < CX18_MAX_STREAMS; i++) {
|
for (i = 0; i < CX18_MAX_STREAMS; i++) {
|
||||||
struct cx18_stream *s = &cx->streams[i];
|
struct cx18_stream *s = &cx->streams[i];
|
||||||
|
|
||||||
if (s->video_dev == NULL || s->buffers == 0)
|
if (s->video_dev.v4l2_dev == NULL || s->buffers == 0)
|
||||||
continue;
|
continue;
|
||||||
CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
|
CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
|
||||||
s->name, s->s_flags,
|
s->name, s->s_flags,
|
||||||
|
|
|
@ -254,11 +254,8 @@ static struct videobuf_queue_ops cx18_videobuf_qops = {
|
||||||
static void cx18_stream_init(struct cx18 *cx, int type)
|
static void cx18_stream_init(struct cx18 *cx, int type)
|
||||||
{
|
{
|
||||||
struct cx18_stream *s = &cx->streams[type];
|
struct cx18_stream *s = &cx->streams[type];
|
||||||
struct video_device *video_dev = s->video_dev;
|
|
||||||
|
|
||||||
/* we need to keep video_dev, so restore it afterwards */
|
|
||||||
memset(s, 0, sizeof(*s));
|
memset(s, 0, sizeof(*s));
|
||||||
s->video_dev = video_dev;
|
|
||||||
|
|
||||||
/* initialize cx18_stream fields */
|
/* initialize cx18_stream fields */
|
||||||
s->dvb = NULL;
|
s->dvb = NULL;
|
||||||
|
@ -319,12 +316,12 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These five fields are always initialized.
|
* These five fields are always initialized.
|
||||||
* For analog capture related streams, if video_dev == NULL then the
|
* For analog capture related streams, if video_dev.v4l2_dev == NULL then the
|
||||||
* stream is not in use.
|
* stream is not in use.
|
||||||
* For the TS stream, if dvb == NULL then the stream is not in use.
|
* For the TS stream, if dvb == NULL then the stream is not in use.
|
||||||
* In those cases no other fields but these four can be used.
|
* In those cases no other fields but these four can be used.
|
||||||
*/
|
*/
|
||||||
s->video_dev = NULL;
|
s->video_dev.v4l2_dev = NULL;
|
||||||
s->dvb = NULL;
|
s->dvb = NULL;
|
||||||
s->cx = cx;
|
s->cx = cx;
|
||||||
s->type = type;
|
s->type = type;
|
||||||
|
@ -367,24 +364,17 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
|
||||||
if (num_offset == -1)
|
if (num_offset == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* allocate and initialize the v4l2 video device structure */
|
/* initialize the v4l2 video device structure */
|
||||||
s->video_dev = video_device_alloc();
|
snprintf(s->video_dev.name, sizeof(s->video_dev.name), "%s %s",
|
||||||
if (s->video_dev == NULL) {
|
|
||||||
CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
|
|
||||||
s->name);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
|
|
||||||
cx->v4l2_dev.name, s->name);
|
cx->v4l2_dev.name, s->name);
|
||||||
|
|
||||||
s->video_dev->num = num;
|
s->video_dev.num = num;
|
||||||
s->video_dev->v4l2_dev = &cx->v4l2_dev;
|
s->video_dev.v4l2_dev = &cx->v4l2_dev;
|
||||||
s->video_dev->fops = &cx18_v4l2_enc_fops;
|
s->video_dev.fops = &cx18_v4l2_enc_fops;
|
||||||
s->video_dev->release = video_device_release;
|
s->video_dev.release = video_device_release_empty;
|
||||||
s->video_dev->tvnorms = V4L2_STD_ALL;
|
s->video_dev.tvnorms = V4L2_STD_ALL;
|
||||||
s->video_dev->lock = &cx->serialize_lock;
|
s->video_dev.lock = &cx->serialize_lock;
|
||||||
cx18_set_funcs(s->video_dev);
|
cx18_set_funcs(&s->video_dev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,31 +418,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->video_dev == NULL)
|
if (s->video_dev.v4l2_dev == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
num = s->video_dev->num;
|
num = s->video_dev.num;
|
||||||
/* card number + user defined offset + device offset */
|
/* card number + user defined offset + device offset */
|
||||||
if (type != CX18_ENC_STREAM_TYPE_MPG) {
|
if (type != CX18_ENC_STREAM_TYPE_MPG) {
|
||||||
struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
|
struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
|
||||||
|
|
||||||
if (s_mpg->video_dev)
|
if (s_mpg->video_dev.v4l2_dev)
|
||||||
num = s_mpg->video_dev->num
|
num = s_mpg->video_dev.num
|
||||||
+ cx18_stream_info[type].num_offset;
|
+ cx18_stream_info[type].num_offset;
|
||||||
}
|
}
|
||||||
video_set_drvdata(s->video_dev, s);
|
video_set_drvdata(&s->video_dev, s);
|
||||||
|
|
||||||
/* Register device. First try the desired minor, then any free one. */
|
/* Register device. First try the desired minor, then any free one. */
|
||||||
ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
|
ret = video_register_device_no_warn(&s->video_dev, vfl_type, num);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
|
CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
|
||||||
s->name, num);
|
s->name, num);
|
||||||
video_device_release(s->video_dev);
|
s->video_dev.v4l2_dev = NULL;
|
||||||
s->video_dev = NULL;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = video_device_node_name(s->video_dev);
|
name = video_device_node_name(&s->video_dev);
|
||||||
|
|
||||||
switch (vfl_type) {
|
switch (vfl_type) {
|
||||||
case VFL_TYPE_GRABBER:
|
case VFL_TYPE_GRABBER:
|
||||||
|
@ -542,10 +531,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If struct video_device exists, can have buffers allocated */
|
/* If struct video_device exists, can have buffers allocated */
|
||||||
vdev = cx->streams[type].video_dev;
|
vdev = &cx->streams[type].video_dev;
|
||||||
|
|
||||||
cx->streams[type].video_dev = NULL;
|
if (vdev->v4l2_dev == NULL)
|
||||||
if (vdev == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (type == CX18_ENC_STREAM_TYPE_YUV)
|
if (type == CX18_ENC_STREAM_TYPE_YUV)
|
||||||
|
@ -553,11 +541,7 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
|
||||||
|
|
||||||
cx18_stream_free(&cx->streams[type]);
|
cx18_stream_free(&cx->streams[type]);
|
||||||
|
|
||||||
/* Unregister or release device */
|
video_unregister_device(vdev);
|
||||||
if (unregister)
|
|
||||||
video_unregister_device(vdev);
|
|
||||||
else
|
|
||||||
video_device_release(vdev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1042,7 +1026,7 @@ u32 cx18_find_handle(struct cx18 *cx)
|
||||||
for (i = 0; i < CX18_MAX_STREAMS; i++) {
|
for (i = 0; i < CX18_MAX_STREAMS; i++) {
|
||||||
struct cx18_stream *s = &cx->streams[i];
|
struct cx18_stream *s = &cx->streams[i];
|
||||||
|
|
||||||
if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
|
if (s->video_dev.v4l2_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
|
||||||
return s->handle;
|
return s->handle;
|
||||||
}
|
}
|
||||||
return CX18_INVALID_TASK_HANDLE;
|
return CX18_INVALID_TASK_HANDLE;
|
||||||
|
|
|
@ -33,7 +33,7 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
|
||||||
|
|
||||||
static inline bool cx18_stream_enabled(struct cx18_stream *s)
|
static inline bool cx18_stream_enabled(struct cx18_stream *s)
|
||||||
{
|
{
|
||||||
return s->video_dev ||
|
return s->video_dev.v4l2_dev ||
|
||||||
(s->dvb && s->dvb->enabled) ||
|
(s->dvb && s->dvb->enabled) ||
|
||||||
(s->type == CX18_ENC_STREAM_TYPE_IDX &&
|
(s->type == CX18_ENC_STREAM_TYPE_IDX &&
|
||||||
s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
|
s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
|
||||||
|
|
Loading…
Reference in New Issue