From 371a9a90250463bb1b5aeece709c444a836269aa Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 5 Apr 2009 12:29:27 +0200 Subject: cDevice::PlayTs() now plays as many TS packets as possible in one call --- HISTORY | 1 + device.c | 77 +++++++++++++++++++++++++++++++++++-------------------------- device.h | 8 +++---- dvbplayer.c | 33 +++++++++++--------------- 4 files changed, 62 insertions(+), 57 deletions(-) diff --git a/HISTORY b/HISTORY index 3dcc9cb2..0df948e1 100644 --- a/HISTORY +++ b/HISTORY @@ -6020,3 +6020,4 @@ Video Disk Recorder Revision History - Fixed a crash when jumping to an editing mark in an audio recording. - Fixed the 'VideoOnly' condition in the PlayPes() and PlayTs() calls in cDvbPlayer::Action() (thanks to Reinhard Nissl). +- cDevice::PlayTs() now plays as many TS packets as possible in one call. diff --git a/device.c b/device.c index 4a20fd74..ccf176c4 100644 --- a/device.c +++ b/device.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 2.12 2009/01/30 16:01:53 kls Exp $ + * $Id: device.c 2.13 2009/04/05 12:15:41 kls Exp $ */ #include "device.h" @@ -1315,43 +1315,54 @@ int cDevice::PlayTsSubtitle(const uchar *Data, int Length) //TODO detect and report continuity errors? int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) { - if (Length == TS_SIZE) { - if (!TsHasPayload(Data)) - return Length; // silently ignore TS packets w/o payload - int PayloadOffset = TsPayloadOffset(Data); - if (PayloadOffset < Length) { - cMutexLock MutexLock(&mutexCurrentAudioTrack); - int Pid = TsPid(Data); - if (Pid == 0) - patPmtParser.ParsePat(Data, Length); - else if (Pid == patPmtParser.PmtPid()) - patPmtParser.ParsePmt(Data, Length); - else if (Pid == patPmtParser.Vpid()) { - isPlayingVideo = true; - return PlayTsVideo(Data, Length); - } - else if (Pid == availableTracks[currentAudioTrack].id) { - if (!VideoOnly || HasIBPTrickSpeed()) { - int w = PlayTsAudio(Data, Length); - if (w > 0) - Audios.PlayTsAudio(Data, Length); - return w; - } - } - else if (Pid == availableTracks[currentSubtitleTrack].id) { - if (!VideoOnly || HasIBPTrickSpeed()) - return PlayTsSubtitle(Data, Length); - } - return Length; - } - } - else if (Data == NULL) { + int Played = 0; + if (Data == NULL) { patPmtParser.Reset(); tsToPesVideo.Reset(); tsToPesAudio.Reset(); tsToPesSubtitle.Reset(); } - return -1; + else { + cMutexLock MutexLock(&mutexCurrentAudioTrack); + while (Length >= TS_SIZE) { + if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload + int PayloadOffset = TsPayloadOffset(Data); + if (PayloadOffset < TS_SIZE) { + int Pid = TsPid(Data); + if (Pid == 0) + patPmtParser.ParsePat(Data, TS_SIZE); + else if (Pid == patPmtParser.PmtPid()) + patPmtParser.ParsePmt(Data, TS_SIZE); + else if (Pid == patPmtParser.Vpid()) { + isPlayingVideo = true; + int w = PlayTsVideo(Data, TS_SIZE); + if (w < 0) + return Played ? Played : w; + if (w == 0) + break; + } + else if (Pid == availableTracks[currentAudioTrack].id) { + if (!VideoOnly || HasIBPTrickSpeed()) { + int w = PlayTsAudio(Data, TS_SIZE); + if (w < 0) + return Played ? Played : w; + if (w == 0) + break; + Audios.PlayTsAudio(Data, TS_SIZE); + } + } + else if (Pid == availableTracks[currentSubtitleTrack].id) { + if (!VideoOnly || HasIBPTrickSpeed()) + PlayTsSubtitle(Data, TS_SIZE); + } + } + } + Played += TS_SIZE; + Length -= TS_SIZE; + Data += TS_SIZE; + } + } + return Played; } int cDevice::Priority(void) const diff --git a/device.h b/device.h index c63f2bcd..c3a170b2 100644 --- a/device.h +++ b/device.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 2.8 2009/03/28 21:53:26 kls Exp $ + * $Id: device.h 2.9 2009/04/05 12:12:44 kls Exp $ */ #ifndef __DEVICE_H @@ -619,9 +619,9 @@ public: ///< must be sent to the base class function. This applies especially ///< to the PAT/PMT packets. ///< Returns -1 in case of error, otherwise the number of actually - ///< processed bytes is returned, which must be Length. - ///< PlayTs() shall process the packet either as a whole (returning - ///< Length) or not at all returning 0 or -1 and setting 'errno' accordingly). + ///< processed bytes is returned. + ///< PlayTs() shall process the TS packets either as a whole (returning + ///< n*TS_SIZE) or not at all, returning 0 or -1 and setting 'errno' accordingly). bool Replaying(void) const; ///< Returns true if we are currently replaying. bool Transferring(void) const; diff --git a/dvbplayer.c b/dvbplayer.c index 8ffd406a..69a434e3 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbplayer.c 2.9 2009/04/05 10:55:11 kls Exp $ + * $Id: dvbplayer.c 2.10 2009/04/05 12:29:27 kls Exp $ */ #include "dvbplayer.h" @@ -527,24 +527,17 @@ void cDvbPlayer::Action(void) } } if (p) { - //XXX maybe make PlayTs() play as much as possible, until w == 0? would save this extra code here (and the goto)... - while (pc > 0) { - int w; - if (isPesRecording) - w = PlayPes(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo()); - else - w = PlayTs(p, TS_SIZE, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo()); - if (w > 0) { - p += w; - pc -= w; - } - else if (w == 0) - break; - else if (w < 0 && FATALERRNO) { - LOG_ERROR; - goto End; - } - } + int w; + if (isPesRecording) + w = PlayPes(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo()); + else + w = PlayTs(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo()); + if (w > 0) { + p += w; + pc -= w; + } + else if (w < 0 && FATALERRNO) + LOG_ERROR; } if (pc <= 0) { if (!eof || (playDir != pdForward && playFrame->Index() > 0) || (playDir == pdForward && playFrame->Index() < readIndex)) @@ -589,7 +582,7 @@ void cDvbPlayer::Action(void) } } } -End: + cNonBlockingFileReader *nbfr = nonBlockingFileReader; nonBlockingFileReader = NULL; delete nbfr; -- cgit v1.2.3