aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-08-23 16:51:07 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:06:49 -0400
commit559e196a56a5d518181efc1d2fefe0892f4689b4 (patch)
tree99de577c399d281b6d599ec9a7ba6ddb0a148780 /drivers
parenta158f3559334c6314c7876390caffe88c9fdb64d (diff)
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 <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c37
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c8
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 170bef61aa62..5b5d6666fa16 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,
258 } 258 }
259 return buf; 259 return buf;
260 } 260 }
261 /* return if file was opened with O_NONBLOCK */
262 if (non_block) {
263 *err = -EAGAIN;
264 return NULL;
265 }
266 261
267 /* return if end of stream */ 262 /* return if end of stream */
268 if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 263 if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
269 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
270 IVTV_DEBUG_INFO("EOS %s\n", s->name); 264 IVTV_DEBUG_INFO("EOS %s\n", s->name);
271 return NULL; 265 return NULL;
272 } 266 }
273 267
268 /* return if file was opened with O_NONBLOCK */
269 if (non_block) {
270 *err = -EAGAIN;
271 return NULL;
272 }
273
274 /* wait for more data to arrive */ 274 /* wait for more data to arrive */
275 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 275 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
276 /* New buffers might have become available before we were added to the waitqueue */ 276 /* 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
378 int rc; 378 int rc;
379 379
380 buf = ivtv_get_buffer(s, non_block, &rc); 380 buf = ivtv_get_buffer(s, non_block, &rc);
381 if (buf == NULL && rc == -EAGAIN && tot_written) 381 /* if there is no data available... */
382 break; 382 if (buf == NULL) {
383 if (buf == NULL) 383 /* if we got data, then return that regardless */
384 if (tot_written)
385 break;
386 /* EOS condition */
387 if (rc == 0) {
388 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
389 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
390 ivtv_release_stream(s);
391 }
392 /* set errno */
384 return rc; 393 return rc;
394 }
385 rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written); 395 rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);
386 if (buf != &itv->vbi.sliced_mpeg_buf) { 396 if (buf != &itv->vbi.sliced_mpeg_buf) {
387 ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io); 397 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)
738 ivtv_stop_v4l2_encode_stream(s, gop_end); 748 ivtv_stop_v4l2_encode_stream(s, gop_end);
739 } 749 }
740 } 750 }
741 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); 751 if (!gop_end) {
742 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 752 clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
743 753 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
744 ivtv_release_stream(s); 754 ivtv_release_stream(s);
755 }
745} 756}
746 757
747static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) 758static 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 e05af62a8cd5..a3296224f821 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)
719 struct ivtv *itv = s->itv; 719 struct ivtv *itv = s->itv;
720 DECLARE_WAITQUEUE(wait, current); 720 DECLARE_WAITQUEUE(wait, current);
721 int cap_type; 721 int cap_type;
722 unsigned long then;
723 int stopmode; 722 int stopmode;
724 723
725 if (s->v4l2dev == NULL) 724 if (s->v4l2dev == NULL)
@@ -762,14 +761,12 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
762 /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ 761 /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
763 ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); 762 ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
764 763
765 then = jiffies;
766
767 if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { 764 if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
768 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) { 765 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
769 /* only run these if we're shutting down the last cap */ 766 /* only run these if we're shutting down the last cap */
770 unsigned long duration; 767 unsigned long duration;
768 unsigned long then = jiffies;
771 769
772 then = jiffies;
773 add_wait_queue(&itv->eos_waitq, &wait); 770 add_wait_queue(&itv->eos_waitq, &wait);
774 771
775 set_current_state(TASK_INTERRUPTIBLE); 772 set_current_state(TASK_INTERRUPTIBLE);
@@ -797,10 +794,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
797 } 794 }
798 set_current_state(TASK_RUNNING); 795 set_current_state(TASK_RUNNING);
799 remove_wait_queue(&itv->eos_waitq, &wait); 796 remove_wait_queue(&itv->eos_waitq, &wait);
797 set_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
800 } 798 }
801 799
802 then = jiffies;
803
804 /* Handle any pending interrupts */ 800 /* Handle any pending interrupts */
805 ivtv_msleep_timeout(100, 1); 801 ivtv_msleep_timeout(100, 1);
806 } 802 }