Improved fast-forward/-rewind for audio recordings

This commit is contained in:
Klaus Schmidinger 2009-01-25 11:39:43 +01:00
parent 73be47a4b1
commit f9c1974f2d
6 changed files with 52 additions and 15 deletions

14
HISTORY
View File

@ -5912,7 +5912,7 @@ Video Disk Recorder Revision History
can handle DVB-S2. The #define is still there to allow people with older drivers can handle DVB-S2. The #define is still there to allow people with older drivers
who don't need DVB-S2 to use this version without pathcing. who don't need DVB-S2 to use this version without pathcing.
2009-01-24: Version 1.7.4 2009-01-25: Version 1.7.4
- Removed the '#define FE_CAN_2ND_GEN_MODULATION', since it was wrong and the - Removed the '#define FE_CAN_2ND_GEN_MODULATION', since it was wrong and the
flag is now in the driver, anyway. flag is now in the driver, anyway.
@ -5966,3 +5966,15 @@ Video Disk Recorder Revision History
- The PAT/PMT is now only processed if its version changes (reported by Reinhard - The PAT/PMT is now only processed if its version changes (reported by Reinhard
Nissl). Nissl).
- Fixed handling the maximum video file size (reported by Udo Richter). - Fixed handling the maximum video file size (reported by Udo Richter).
- Improved fast-forward/-rewind for audio recordings. The actual data is now sent
to the output device, so that it can be replayed and thus cause the proper delay.
For pure audio recordings the audio is no longer muted in fast-forward/-rewind
mode, so that some orientation regarding the position within the recording is
possible. There may still be some offset in the replay position displayed by the
progress indicator when switching from fast-forward/-rewind to play mode, as well
as in the current position during normal play mode. This is due to the various
buffers between the player and the output device and will be addressed later.
Note the new function cDevice::IsPlayingVideo(), which is used to inform the
player whether there is video data in the currently replayed stream. If a derived
cDevice class reimplements PlayTs() or PlayPes(), it also needs to make sure this
new function works as expected.

View File

@ -16,7 +16,10 @@ html, body {
text-align: center; text-align: center;
} }
.code { .code {
background-color: #f0f0f0; background-color: #F0F0F0;
}
.modified {
background-color: #FFDDDD;
} }
</style> </style>
</head> </head>
@ -25,12 +28,15 @@ html, body {
<div class="center"> <div class="center">
<h1>The VDR Plugin System</h1> <h1>The VDR Plugin System</h1>
<b>Version 1.6</b> <b>Version 1.7</b>
<p> <p>
Copyright &copy; 2008 Klaus Schmidinger<br> Copyright &copy; 2009 Klaus Schmidinger<br>
<a href="mailto:kls@cadsoft.de">kls@cadsoft.de</a><br> <a href="mailto:kls@cadsoft.de">kls@cadsoft.de</a><br>
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a> <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
</div> </div>
<div class="modified">
Important modifications introduced since version 1.6 are marked like this.
</div modified>
<p> <p>
VDR provides an easy to use plugin interface that allows additional functionality VDR provides an easy to use plugin interface that allows additional functionality
to be added to the program by implementing a dynamically loadable library file. to be added to the program by implementing a dynamically loadable library file.
@ -1844,6 +1850,9 @@ virtual bool HasDecoder(void) const;
virtual bool CanReplay(void) const; virtual bool CanReplay(void) const;
virtual bool SetPlayMode(ePlayMode PlayMode); virtual bool SetPlayMode(ePlayMode PlayMode);
virtual int64_t GetSTC(void); virtual int64_t GetSTC(void);
<div class="modified">
virtual bool IsPlayingVideo(void) const;
</div modified>
virtual bool HasIBPTrickSpeed(void); virtual bool HasIBPTrickSpeed(void);
virtual void TrickSpeed(int Speed); virtual void TrickSpeed(int Speed);
virtual void Clear(void); virtual void Clear(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 2.10 2009/01/24 13:40:54 kls Exp $ * $Id: device.c 2.11 2009/01/25 11:10:56 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -81,6 +81,7 @@ cDevice::cDevice(void)
startScrambleDetection = 0; startScrambleDetection = 0;
player = NULL; player = NULL;
isPlayingVideo = false;
ClrAvailableTracks(); ClrAvailableTracks();
currentAudioTrack = ttNone; currentAudioTrack = ttNone;
currentAudioTrackMissingCount = 0; currentAudioTrackMissingCount = 0;
@ -1099,6 +1100,7 @@ void cDevice::Detach(cPlayer *Player)
SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat)); SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
PlayTs(NULL, 0); PlayTs(NULL, 0);
Audios.ClearAudio(); Audios.ClearAudio();
isPlayingVideo = false;
} }
} }
@ -1151,6 +1153,7 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly)
switch (c) { switch (c) {
case 0xBE: // padding stream, needed for MPEG1 case 0xBE: // padding stream, needed for MPEG1
case 0xE0 ... 0xEF: // video case 0xE0 ... 0xEF: // video
isPlayingVideo = true;
w = PlayVideo(Start, d); w = PlayVideo(Start, d);
break; break;
case 0xC0 ... 0xDF: // audio case 0xC0 ... 0xDF: // audio
@ -1322,8 +1325,10 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
patPmtParser.ParsePat(Data, Length); patPmtParser.ParsePat(Data, Length);
else if (Pid == patPmtParser.PmtPid()) else if (Pid == patPmtParser.PmtPid())
patPmtParser.ParsePmt(Data, Length); patPmtParser.ParsePmt(Data, Length);
else if (Pid == patPmtParser.Vpid()) else if (Pid == patPmtParser.Vpid()) {
isPlayingVideo = true;
return PlayTsVideo(Data, Length); return PlayTsVideo(Data, Length);
}
else if (Pid == availableTracks[currentAudioTrack].id) { else if (Pid == availableTracks[currentAudioTrack].id) {
if (!VideoOnly || HasIBPTrickSpeed()) { if (!VideoOnly || HasIBPTrickSpeed()) {
int w = PlayTsAudio(Data, Length); int w = PlayTsAudio(Data, Length);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.h 2.5 2009/01/10 10:04:30 kls Exp $ * $Id: device.h 2.6 2009/01/25 11:04:39 kls Exp $
*/ */
#ifndef __DEVICE_H #ifndef __DEVICE_H
@ -477,6 +477,7 @@ private:
cTsToPes tsToPesVideo; cTsToPes tsToPesVideo;
cTsToPes tsToPesAudio; cTsToPes tsToPesAudio;
cTsToPes tsToPesSubtitle; cTsToPes tsToPesSubtitle;
bool isPlayingVideo;
protected: protected:
virtual bool CanReplay(void) const; virtual bool CanReplay(void) const;
///< Returns true if this device can currently start a replay session. ///< Returns true if this device can currently start a replay session.
@ -542,6 +543,9 @@ public:
///< Gets the current System Time Counter, which can be used to ///< Gets the current System Time Counter, which can be used to
///< synchronize audio and video. If this device is unable to ///< synchronize audio and video. If this device is unable to
///< provide the STC, -1 will be returned. ///< provide the STC, -1 will be returned.
virtual bool IsPlayingVideo(void) const { return isPlayingVideo; }
///< \return Returns true if the currently attached player has delivered
///< any video packets.
virtual bool HasIBPTrickSpeed(void) { return false; } virtual bool HasIBPTrickSpeed(void) { return false; }
///< Returns true if this device can handle all frames in 'fast forward' ///< Returns true if this device can handle all frames in 'fast forward'
///< trick speeds. ///< trick speeds.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbplayer.c 2.2 2009/01/24 11:42:07 kls Exp $ * $Id: dvbplayer.c 2.3 2009/01/25 11:11:39 kls Exp $
*/ */
#include "dvbplayer.h" #include "dvbplayer.h"
@ -412,8 +412,12 @@ void cDvbPlayer::Action(void)
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, NULL, &Length)) if (index->Get(readIndex + 1, &FileNumber, &FileOffset, NULL, &Length))
Index = readIndex + 1; Index = readIndex + 1;
} }
else else {
Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, TimeShiftMode); int d = int(round(0.4 * framesPerSecond));
if (playDir != pdForward)
d = -d;
Index = index->GetNextIFrame(readIndex + d, playDir == pdForward, &FileNumber, &FileOffset, &Length, TimeShiftMode);
}
if (Index >= 0) { if (Index >= 0) {
if (!NextFile(FileNumber, FileOffset)) { if (!NextFile(FileNumber, FileOffset)) {
readIndex = Index; readIndex = Index;
@ -516,9 +520,9 @@ void cDvbPlayer::Action(void)
if (p) { if (p) {
int w; int w;
if (isPesRecording) if (isPesRecording)
w = PlayPes(p, pc, playMode != pmPlay); w = PlayPes(p, pc, playMode != pmPlay && DeviceIsPlayingVideo());
else else
w = PlayTs(p, TS_SIZE, playMode != pmPlay); w = PlayTs(p, TS_SIZE, playMode != pmPlay && DeviceIsPlayingVideo());
if (w > 0) { if (w > 0) {
p += w; p += w;
pc -= w; pc -= w;
@ -593,7 +597,8 @@ void cDvbPlayer::Forward(void)
LOCK_THREAD; LOCK_THREAD;
if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward)) if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
Empty(); Empty();
DeviceMute(); if (DeviceIsPlayingVideo())
DeviceMute();
playMode = pmFast; playMode = pmFast;
playDir = pdForward; playDir = pdForward;
trickSpeed = NORMAL_SPEED; trickSpeed = NORMAL_SPEED;
@ -639,7 +644,8 @@ void cDvbPlayer::Backward(void)
case pmPlay: { case pmPlay: {
LOCK_THREAD; LOCK_THREAD;
Empty(); Empty();
DeviceMute(); if (DeviceIsPlayingVideo())
DeviceMute();
playMode = pmFast; playMode = pmFast;
playDir = pdBackward; playDir = pdBackward;
trickSpeed = NORMAL_SPEED; trickSpeed = NORMAL_SPEED;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: player.h 2.2 2009/01/05 13:04:10 kls Exp $ * $Id: player.h 2.3 2009/01/25 11:03:44 kls Exp $
*/ */
#ifndef __PLAYER_H #ifndef __PLAYER_H
@ -26,6 +26,7 @@ protected:
bool DevicePoll(cPoller &Poller, int TimeoutMs = 0) { return device ? device->Poll(Poller, TimeoutMs) : false; } bool DevicePoll(cPoller &Poller, int TimeoutMs = 0) { return device ? device->Poll(Poller, TimeoutMs) : false; }
bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; } bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; }
bool DeviceHasIBPTrickSpeed(void) { return device ? device->HasIBPTrickSpeed() : false; } bool DeviceHasIBPTrickSpeed(void) { return device ? device->HasIBPTrickSpeed() : false; }
bool DeviceIsPlayingVideo(void) { return device ? device->IsPlayingVideo() : false; }
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); } void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); }
void DeviceClear(void) { if (device) device->Clear(); } void DeviceClear(void) { if (device) device->Clear(); }
void DevicePlay(void) { if (device) device->Play(); } void DevicePlay(void) { if (device) device->Play(); }