aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/av7110_av.c
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2009-04-10 09:20:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 17:21:02 -0400
commitfd46d16d602ab7fd53cef7ff55b9dcb0b47ad3bf (patch)
tree26bf9c0d2aa0130decae58943cdc6eea3feaf52a /drivers/media/dvb/ttpci/av7110_av.c
parentb7fd6067143181becb5b14765f4ad25857846491 (diff)
V4L/DVB (11759): dvb-ttpci: Add TS replay capability
Implemented TS replay capability. audio/video devices are able to process PES and TS data now. Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/ttpci/av7110_av.c')
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c95
1 files changed, 78 insertions, 17 deletions
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index e4d0900d5121..2fc90e9a8b77 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -89,6 +89,7 @@
89 89
90static void p_to_t(u8 const *buf, long int length, u16 pid, 90static void p_to_t(u8 const *buf, long int length, u16 pid,
91 u8 *counter, struct dvb_demux_feed *feed); 91 u8 *counter, struct dvb_demux_feed *feed);
92static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len);
92 93
93 94
94int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) 95int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
@@ -437,6 +438,45 @@ static void play_audio_cb(u8 *buf, int count, void *priv)
437 aux_ring_buffer_write(&av7110->aout, buf, count); 438 aux_ring_buffer_write(&av7110->aout, buf, count);
438} 439}
439 440
441
442#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096)
443
444static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
445 unsigned long count, int nonblock, int type)
446{
447 struct dvb_ringbuffer *rb;
448 u8 *kb;
449 unsigned long todo = count;
450
451 dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count);
452
453 rb = (type) ? &av7110->avout : &av7110->aout;
454 kb = av7110->kbuf[type];
455
456 if (!kb)
457 return -ENOBUFS;
458
459 if (nonblock && !FREE_COND_TS)
460 return -EWOULDBLOCK;
461
462 while (todo >= TS_SIZE) {
463 if (!FREE_COND_TS) {
464 if (nonblock)
465 return count - todo;
466 if (wait_event_interruptible(rb->queue, FREE_COND_TS))
467 return count - todo;
468 }
469 if (copy_from_user(kb, buf, TS_SIZE))
470 return -EFAULT;
471 write_ts_to_decoder(av7110, type, kb, TS_SIZE);
472 todo -= TS_SIZE;
473 buf += TS_SIZE;
474 }
475
476 return count - todo;
477}
478
479
440#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ 480#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
441 dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 481 dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
442 482
@@ -780,11 +820,32 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
780} 820}
781 821
782 822
823static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len)
824{
825 struct ipack *ipack = &av7110->ipack[type];
826
827 if (!(buf[3] & PAYLOAD))
828 return -1;
829
830 if (buf[1] & PAY_START)
831 av7110_ipack_flush(ipack);
832
833 if (buf[3] & ADAPT_FIELD) {
834 len -= buf[4] + 1;
835 buf += buf[4] + 1;
836 if (!len)
837 return 0;
838 }
839
840 av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
841 return 0;
842}
843
844
783int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) 845int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
784{ 846{
785 struct dvb_demux *demux = feed->demux; 847 struct dvb_demux *demux = feed->demux;
786 struct av7110 *av7110 = (struct av7110 *) demux->priv; 848 struct av7110 *av7110 = (struct av7110 *) demux->priv;
787 struct ipack *ipack = &av7110->ipack[feed->pes_type];
788 849
789 dprintk(2, "av7110:%p, \n", av7110); 850 dprintk(2, "av7110:%p, \n", av7110);
790 851
@@ -804,20 +865,7 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l
804 return -1; 865 return -1;
805 } 866 }
806 867
807 if (!(buf[3] & 0x10)) /* no payload? */ 868 return write_ts_to_decoder(av7110, feed->pes_type, buf, len);
808 return -1;
809 if (buf[1] & 0x40)
810 av7110_ipack_flush(ipack);
811
812 if (buf[3] & 0x20) { /* adaptation field? */
813 len -= buf[4] + 1;
814 buf += buf[4] + 1;
815 if (!len)
816 return 0;
817 }
818
819 av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]);
820 return 0;
821} 869}
822 870
823 871
@@ -916,6 +964,7 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf,
916{ 964{
917 struct dvb_device *dvbdev = file->private_data; 965 struct dvb_device *dvbdev = file->private_data;
918 struct av7110 *av7110 = dvbdev->priv; 966 struct av7110 *av7110 = dvbdev->priv;
967 unsigned char c;
919 968
920 dprintk(2, "av7110:%p, \n", av7110); 969 dprintk(2, "av7110:%p, \n", av7110);
921 970
@@ -925,7 +974,12 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf,
925 if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) 974 if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
926 return -EPERM; 975 return -EPERM;
927 976
928 return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 977 if (get_user(c, buf))
978 return -EFAULT;
979 if (c == 0x47 && count % TS_SIZE == 0)
980 return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
981 else
982 return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
929} 983}
930 984
931static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) 985static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
@@ -952,6 +1006,7 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
952{ 1006{
953 struct dvb_device *dvbdev = file->private_data; 1007 struct dvb_device *dvbdev = file->private_data;
954 struct av7110 *av7110 = dvbdev->priv; 1008 struct av7110 *av7110 = dvbdev->priv;
1009 unsigned char c;
955 1010
956 dprintk(2, "av7110:%p, \n", av7110); 1011 dprintk(2, "av7110:%p, \n", av7110);
957 1012
@@ -959,7 +1014,13 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
959 printk(KERN_ERR "not audio source memory\n"); 1014 printk(KERN_ERR "not audio source memory\n");
960 return -EPERM; 1015 return -EPERM;
961 } 1016 }
962 return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 1017
1018 if (get_user(c, buf))
1019 return -EFAULT;
1020 if (c == 0x47 && count % TS_SIZE == 0)
1021 return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
1022 else
1023 return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
963} 1024}
964 1025
965static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; 1026static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };