# --- T2-COPYRIGHT-NOTE-BEGIN --- # This copyright note is auto-generated by ./scripts/Create-CopyPatch. # # T2 SDE: package/.../vdr/dvb-ttpci-ts_1.diff # Copyright (C) 2009 The T2 SDE Project # # More information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # --- T2-COPYRIGHT-NOTE-END --- # HG changeset patch # User Oliver Endriss # Date 1239371513 -7200 # Node ID b5567f27fba706c8af44bad9570351769d1b9a9a # Parent 55fa4f709cf2419cfb814591fe999e83005346b5 dvb-ttpci: Do not start replay before some data has arrived From: Oliver Endriss Do not start replay before some data has arrived. Priority: normal Signed-off-by: Oliver Endriss --- linux.orig/drivers/media/dvb/ttpci/av7110.h Fri Apr 10 15:20:00 2009 +0200 +++ linux/drivers/media/dvb/ttpci/av7110.h Fri Apr 10 15:51:53 2009 +0200 @@ -165,6 +165,8 @@ struct av7110 { #define RP_VIDEO 1 #define RP_AUDIO 2 #define RP_AV 3 + bool audio_start_delayed; + bool video_start_delayed; /* OSD */ --- linux.orig/drivers/media/dvb/ttpci/av7110_av.c Fri Apr 10 15:20:00 2009 +0200 +++ linux/drivers/media/dvb/ttpci/av7110_av.c Fri Apr 10 15:51:53 2009 +0200 @@ -90,6 +90,10 @@ static void p_to_t(u8 const *buf, long i static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed); static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len); +static int dvb_video_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *parg); +static int dvb_audio_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *parg); int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) @@ -965,6 +969,7 @@ static ssize_t dvb_video_write(struct fi struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; unsigned char c; + ssize_t rc; dprintk(2, "av7110:%p, \n", av7110); @@ -977,9 +982,16 @@ static ssize_t dvb_video_write(struct fi if (get_user(c, buf)) return -EFAULT; if (c == 0x47 && count % TS_SIZE == 0) - return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); + rc = ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); else - return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); + rc = dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); + + if (av7110->video_start_delayed) { + av7110->video_start_delayed = false; + dvb_video_ioctl(NULL, file, VIDEO_PLAY, NULL); + } + + return rc; } static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) @@ -1007,6 +1019,7 @@ static ssize_t dvb_audio_write(struct fi struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; unsigned char c; + ssize_t rc; dprintk(2, "av7110:%p, \n", av7110); @@ -1018,9 +1031,16 @@ static ssize_t dvb_audio_write(struct fi if (get_user(c, buf)) return -EFAULT; if (c == 0x47 && count % TS_SIZE == 0) - return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); + rc = ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); else - return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); + rc = dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); + + if (av7110->audio_start_delayed) { + av7110->audio_start_delayed = false; + dvb_audio_ioctl(NULL, file, AUDIO_PLAY, NULL); + } + + return rc; } static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; @@ -1105,6 +1125,7 @@ static int dvb_video_ioctl(struct inode switch (cmd) { case VIDEO_STOP: + av7110->video_start_delayed = false; av7110->videostate.play_state = VIDEO_STOPPED; if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) ret = av7110_av_stop(av7110, RP_VIDEO); @@ -1116,6 +1137,12 @@ static int dvb_video_ioctl(struct inode break; case VIDEO_PLAY: + if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { + if (dvb_ringbuffer_empty(&av7110->avout)) { + av7110->video_start_delayed = true; + break; + } + } av7110->trickmode = TRICK_NONE; if (av7110->videostate.play_state == VIDEO_FREEZED) { av7110->videostate.play_state = VIDEO_PLAYING; @@ -1123,7 +1150,6 @@ static int dvb_video_ioctl(struct inode if (ret) break; } - if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { if (av7110->playing == RP_AV) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); @@ -1140,6 +1166,8 @@ static int dvb_video_ioctl(struct inode break; case VIDEO_FREEZE: + if (av7110->video_start_delayed) + break; av7110->videostate.play_state = VIDEO_FREEZED; if (av7110->playing & RP_VIDEO) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); @@ -1150,6 +1178,8 @@ static int dvb_video_ioctl(struct inode break; case VIDEO_CONTINUE: + if (av7110->video_start_delayed) + break; if (av7110->playing & RP_VIDEO) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); if (!ret) @@ -1230,6 +1260,8 @@ static int dvb_video_ioctl(struct inode } case VIDEO_FAST_FORWARD: + if (av7110->video_start_delayed) + break; //note: arg is ignored by firmware if (av7110->playing & RP_VIDEO) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, @@ -1243,6 +1275,8 @@ static int dvb_video_ioctl(struct inode break; case VIDEO_SLOWMOTION: + if (av7110->video_start_delayed) + break; if (av7110->playing&RP_VIDEO) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); if (!ret) @@ -1289,13 +1323,13 @@ static int dvb_video_ioctl(struct inode break; case VIDEO_SET_STREAMTYPE: - break; default: ret = -ENOIOCTLCMD; break; } + return ret; } @@ -1315,6 +1349,7 @@ static int dvb_audio_ioctl(struct inode switch (cmd) { case AUDIO_STOP: + av7110->audio_start_delayed = false; if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) ret = av7110_av_stop(av7110, RP_AUDIO); else @@ -1324,8 +1359,13 @@ static int dvb_audio_ioctl(struct inode break; case AUDIO_PLAY: - if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) + if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) { + if (dvb_ringbuffer_avail(&av7110->aout) < 4096) { + av7110->audio_start_delayed = true; + break; + } ret = av7110_av_start_play(av7110, RP_AUDIO); + } if (!ret) ret = audcom(av7110, AUDIO_CMD_UNMUTE); if (!ret) @@ -1333,12 +1373,16 @@ static int dvb_audio_ioctl(struct inode break; case AUDIO_PAUSE: + if (av7110->audio_start_delayed) + break; ret = audcom(av7110, AUDIO_CMD_MUTE); if (!ret) av7110->audiostate.play_state = AUDIO_PAUSED; break; case AUDIO_CONTINUE: + if (av7110->audio_start_delayed) + break; if (av7110->audiostate.play_state == AUDIO_PAUSED) { av7110->audiostate.play_state = AUDIO_PLAYING; ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); @@ -1427,9 +1471,10 @@ static int dvb_audio_ioctl(struct inode ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); break; + case AUDIO_SET_ID: - - break; + break; + case AUDIO_SET_MIXER: { struct audio_mixer *amix = (struct audio_mixer *)parg; @@ -1437,11 +1482,14 @@ static int dvb_audio_ioctl(struct inode ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); break; } + case AUDIO_SET_STREAMTYPE: break; + default: ret = -ENOIOCTLCMD; } + return ret; }