diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 5246315a..74487594 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1214,3 +1214,7 @@ Achim Tuffentsammer Michael Heyse for his help in keeping 'channels.conf.terr' up to date + +Marco Kremer + for reporting a problem with playing files with PES packets longer than 2048 byte + through the full featured DVB card diff --git a/HISTORY b/HISTORY index 3d6f79b0..d81b54db 100644 --- a/HISTORY +++ b/HISTORY @@ -3308,3 +3308,6 @@ Video Disk Recorder Revision History - Added 'channels.conf.terr' entries for Mainz (thanks to Michael Heyse). - Implemented cDolbyRepacker for better handling of Dolby Digital PES packets (thanks to Reinhard Nissl). +- Fixed playing files with PES packets longer than 2048 byte through the full + featured DVB card (thanks to Marco Kremer for reporting this one and providing + a test sample). diff --git a/dvbdevice.c b/dvbdevice.c index d497aaff..3a7d3264 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.114 2005/01/14 14:00:44 kls Exp $ + * $Id: dvbdevice.c 1.115 2005/01/16 11:59:21 kls Exp $ */ #include "dvbdevice.h" @@ -1130,12 +1130,12 @@ bool cDvbDevice::Flush(int TimeoutMs) int cDvbDevice::PlayVideo(const uchar *Data, int Length) { - return write(fd_video, Data, Length); + return WriteAllOrNothing(fd_video, Data, Length, 1000, 10); } int cDvbDevice::PlayAudio(const uchar *Data, int Length) { - return write(fd_audio, Data, Length); + return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10); } bool cDvbDevice::OpenDvr(void) diff --git a/tools.c b/tools.c index af2a73c3..2f130c78 100644 --- a/tools.c +++ b/tools.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.87 2005/01/04 11:06:45 kls Exp $ + * $Id: tools.c 1.88 2005/01/16 11:47:44 kls Exp $ */ #include "tools.h" @@ -65,6 +65,30 @@ void writechar(int filedes, char c) safe_write(filedes, &c, sizeof(c)); } +int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs, int RetryMs) +{ + int written = 0; + while (Length > 0) { + int w = write(fd, Data + written, Length); + if (w > 0) { + Length -= w; + written += w; + } + else if (written > 0 && !FATALERRNO) { + // we've started writing, so we must finish it! + cTimeMs t; + cPoller Poller(fd, true); + Poller.Poll(RetryMs); + if (TimeoutMs > 0 && (TimeoutMs -= t.Elapsed()) <= 0) + break; + } + else + // nothing written yet (or fatal error), so we can just return the error code: + return w; + } + return written; +} + char *strcpyrealloc(char *dest, const char *src) { if (src) { diff --git a/tools.h b/tools.h index 621e589b..9067eb8d 100644 --- a/tools.h +++ b/tools.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.64 2005/01/04 11:09:51 kls Exp $ + * $Id: tools.h 1.65 2005/01/16 11:39:58 kls Exp $ */ #ifndef __TOOLS_H @@ -71,6 +71,10 @@ public: ssize_t safe_read(int filedes, void *buffer, size_t size); ssize_t safe_write(int filedes, const void *buffer, size_t size); void writechar(int filedes, char c); +int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs = 0, int RetryMs = 0); + ///< Writes either all Data to the given file descriptor, or nothing at all. + ///< If TimeoutMs is greater than 0, it will only retry for that long, otherwise + ///< it will retry forever. RetryMs defines the time between two retries. char *strcpyrealloc(char *dest, const char *src); char *strn0cpy(char *dest, const char *src, size_t n); char *strreplace(char *s, char c1, char c2);