Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=559e196a56a5d518181efc1d2fefe0892f4689b4
Commit:     559e196a56a5d518181efc1d2fefe0892f4689b4
Parent:     a158f3559334c6314c7876390caffe88c9fdb64d
Author:     Hans Verkuil <[EMAIL PROTECTED]>
AuthorDate: Thu Aug 23 17:51:07 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 22:06:49 2007 -0300

    V4L/DVB (6096): ivtv: fix V4L2_ENC_CMD_STOP_AT_GOP_END support
    
    Support for V4L2_ENC_CMD_STOP_AT_GOP_END was broken. While the driver
    correctly waited for the card to capture until the GOP was complete,
    afterwards the driver buffers were just flushed instead of waiting
    for the application to read all the pending data.
    
    Signed-off-by: Hans Verkuil <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/ivtv/ivtv-fileops.c |   37 ++++++++++++++++++++-----------
 drivers/media/video/ivtv/ivtv-streams.c |    8 +-----
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/media/video/ivtv/ivtv-fileops.c 
b/drivers/media/video/ivtv/ivtv-fileops.c
index 170bef6..5b5d666 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -258,19 +258,19 @@ static struct ivtv_buffer *ivtv_get_buffer(struct 
ivtv_stream *s, int non_block,
                        }
                        return buf;
                }
-               /* return if file was opened with O_NONBLOCK */
-               if (non_block) {
-                       *err = -EAGAIN;
-                       return NULL;
-               }
 
                /* return if end of stream */
                if (s->type != IVTV_DEC_STREAM_TYPE_VBI && 
!test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
-                       clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
                        IVTV_DEBUG_INFO("EOS %s\n", s->name);
                        return NULL;
                }
 
+               /* return if file was opened with O_NONBLOCK */
+               if (non_block) {
+                       *err = -EAGAIN;
+                       return NULL;
+               }
+
                /* wait for more data to arrive */
                prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
                /* New buffers might have become available before we were added 
to the waitqueue */
@@ -378,10 +378,20 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char 
__user *ubuf, size_t tot_co
                int rc;
 
                buf = ivtv_get_buffer(s, non_block, &rc);
-               if (buf == NULL && rc == -EAGAIN && tot_written)
-                       break;
-               if (buf == NULL)
+               /* if there is no data available... */
+               if (buf == NULL) {
+                       /* if we got data, then return that regardless */
+                       if (tot_written)
+                               break;
+                       /* EOS condition */
+                       if (rc == 0) {
+                               clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
+                               clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+                               ivtv_release_stream(s);
+                       }
+                       /* set errno */
                        return rc;
+               }
                rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, 
tot_count - tot_written);
                if (buf != &itv->vbi.sliced_mpeg_buf) {
                        ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? 
&s->q_free : &s->q_io);
@@ -738,10 +748,11 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int 
gop_end)
                        ivtv_stop_v4l2_encode_stream(s, gop_end);
                }
        }
-       clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
-       clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
-       ivtv_release_stream(s);
+       if (!gop_end) {
+               clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+               clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
+               ivtv_release_stream(s);
+       }
 }
 
 static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
diff --git a/drivers/media/video/ivtv/ivtv-streams.c 
b/drivers/media/video/ivtv/ivtv-streams.c
index e05af62..a329622 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -719,7 +719,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int 
gop_end)
        struct ivtv *itv = s->itv;
        DECLARE_WAITQUEUE(wait, current);
        int cap_type;
-       unsigned long then;
        int stopmode;
 
        if (s->v4l2dev == NULL)
@@ -762,14 +761,12 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, 
int gop_end)
        /* when: 0 =  end of GOP  1 = NOW!, type: 0 = mpeg, subtype: 3 = 
video+audio */
        ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, 
s->subtype);
 
-       then = jiffies;
-
        if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
                if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
                        /* only run these if we're shutting down the last cap */
                        unsigned long duration;
+                       unsigned long then = jiffies;
 
-                       then = jiffies;
                        add_wait_queue(&itv->eos_waitq, &wait);
 
                        set_current_state(TASK_INTERRUPTIBLE);
@@ -797,10 +794,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, 
int gop_end)
                        }
                        set_current_state(TASK_RUNNING);
                        remove_wait_queue(&itv->eos_waitq, &wait);
+                       set_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
                }
 
-               then = jiffies;
-
                /* Handle any pending interrupts */
                ivtv_msleep_timeout(100, 1);
        }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to