|
@@ -32,6 +32,7 @@
|
|
|
#include "ivtv-yuv.h"
|
|
|
#include "ivtv-ioctl.h"
|
|
|
#include "ivtv-cards.h"
|
|
|
+#include <media/v4l2-event.h>
|
|
|
#include <media/saa7115.h>
|
|
|
|
|
|
/* This function tries to claim the stream for a specific file descriptor.
|
|
@@ -506,7 +507,7 @@ int ivtv_start_capture(struct ivtv_open_id *id)
|
|
|
|
|
|
ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
|
|
|
{
|
|
|
- struct ivtv_open_id *id = filp->private_data;
|
|
|
+ struct ivtv_open_id *id = fh2id(filp->private_data);
|
|
|
struct ivtv *itv = id->itv;
|
|
|
struct ivtv_stream *s = &itv->streams[id->type];
|
|
|
int rc;
|
|
@@ -541,7 +542,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
|
|
|
|
|
|
ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
|
|
|
{
|
|
|
- struct ivtv_open_id *id = filp->private_data;
|
|
|
+ struct ivtv_open_id *id = fh2id(filp->private_data);
|
|
|
struct ivtv *itv = id->itv;
|
|
|
struct ivtv_stream *s = &itv->streams[id->type];
|
|
|
struct yuv_playback_info *yi = &itv->yuv_info;
|
|
@@ -711,19 +712,31 @@ retry:
|
|
|
|
|
|
unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
|
|
|
{
|
|
|
- struct ivtv_open_id *id = filp->private_data;
|
|
|
+ struct ivtv_open_id *id = fh2id(filp->private_data);
|
|
|
struct ivtv *itv = id->itv;
|
|
|
struct ivtv_stream *s = &itv->streams[id->type];
|
|
|
int res = 0;
|
|
|
|
|
|
/* add stream's waitq to the poll list */
|
|
|
IVTV_DEBUG_HI_FILE("Decoder poll\n");
|
|
|
- poll_wait(filp, &s->waitq, wait);
|
|
|
|
|
|
- set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
|
|
|
- if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
|
|
|
- test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
|
|
|
- res = POLLPRI;
|
|
|
+ /* If there are subscribed events, then only use the new event
|
|
|
+ API instead of the old video.h based API. */
|
|
|
+ if (!list_empty(&id->fh.events->subscribed)) {
|
|
|
+ poll_wait(filp, &id->fh.events->wait, wait);
|
|
|
+ /* Turn off the old-style vsync events */
|
|
|
+ clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
|
|
|
+ if (v4l2_event_pending(&id->fh))
|
|
|
+ res = POLLPRI;
|
|
|
+ } else {
|
|
|
+ /* This is the old-style API which is here only for backwards
|
|
|
+ compatibility. */
|
|
|
+ poll_wait(filp, &s->waitq, wait);
|
|
|
+ set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
|
|
|
+ if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
|
|
|
+ test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
|
|
|
+ res = POLLPRI;
|
|
|
+ }
|
|
|
|
|
|
/* Allow write if buffers are available for writing */
|
|
|
if (s->q_free.buffers)
|
|
@@ -733,7 +746,7 @@ unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
|
|
|
|
|
|
unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
|
|
|
{
|
|
|
- struct ivtv_open_id *id = filp->private_data;
|
|
|
+ struct ivtv_open_id *id = fh2id(filp->private_data);
|
|
|
struct ivtv *itv = id->itv;
|
|
|
struct ivtv_stream *s = &itv->streams[id->type];
|
|
|
int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
|
|
@@ -833,13 +846,16 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
|
|
|
|
|
|
int ivtv_v4l2_close(struct file *filp)
|
|
|
{
|
|
|
- struct ivtv_open_id *id = filp->private_data;
|
|
|
+ struct v4l2_fh *fh = filp->private_data;
|
|
|
+ struct ivtv_open_id *id = fh2id(fh);
|
|
|
struct ivtv *itv = id->itv;
|
|
|
struct ivtv_stream *s = &itv->streams[id->type];
|
|
|
|
|
|
IVTV_DEBUG_FILE("close %s\n", s->name);
|
|
|
|
|
|
v4l2_prio_close(&itv->prio, &id->prio);
|
|
|
+ v4l2_fh_del(fh);
|
|
|
+ v4l2_fh_exit(fh);
|
|
|
|
|
|
/* Easy case first: this stream was never claimed by us */
|
|
|
if (s->id != id->open_id) {
|
|
@@ -895,6 +911,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|
|
{
|
|
|
struct ivtv *itv = s->itv;
|
|
|
struct ivtv_open_id *item;
|
|
|
+ int res = 0;
|
|
|
|
|
|
IVTV_DEBUG_FILE("open %s\n", s->name);
|
|
|
|
|
@@ -915,17 +932,27 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|
|
}
|
|
|
|
|
|
/* Allocate memory */
|
|
|
- item = kmalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
|
|
|
+ item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
|
|
|
if (NULL == item) {
|
|
|
IVTV_DEBUG_WARN("nomem on v4l2 open\n");
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
+ v4l2_fh_init(&item->fh, s->vdev);
|
|
|
+ if (s->type == IVTV_DEC_STREAM_TYPE_YUV ||
|
|
|
+ s->type == IVTV_DEC_STREAM_TYPE_MPG) {
|
|
|
+ res = v4l2_event_alloc(&item->fh, 60);
|
|
|
+ }
|
|
|
+ if (res < 0) {
|
|
|
+ v4l2_fh_exit(&item->fh);
|
|
|
+ kfree(item);
|
|
|
+ return res;
|
|
|
+ }
|
|
|
item->itv = itv;
|
|
|
item->type = s->type;
|
|
|
v4l2_prio_open(&itv->prio, &item->prio);
|
|
|
|
|
|
item->open_id = itv->open_id++;
|
|
|
- filp->private_data = item;
|
|
|
+ filp->private_data = &item->fh;
|
|
|
|
|
|
if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {
|
|
|
/* Try to claim this stream */
|
|
@@ -940,6 +967,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|
|
/* switching to radio while capture is
|
|
|
in progress is not polite */
|
|
|
ivtv_release_stream(s);
|
|
|
+ v4l2_fh_exit(&item->fh);
|
|
|
kfree(item);
|
|
|
return -EBUSY;
|
|
|
}
|
|
@@ -970,6 +998,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|
|
1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
|
|
|
itv->yuv_info.stream_size = 0;
|
|
|
}
|
|
|
+ v4l2_fh_add(&item->fh);
|
|
|
return 0;
|
|
|
}
|
|
|
|