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
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
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
Nissl).
- 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;
}
.code {
background-color: #f0f0f0;
background-color: #F0F0F0;
}
.modified {
background-color: #FFDDDD;
}
</style>
</head>
@ -25,12 +28,15 @@ html, body {
<div class="center">
<h1>The VDR Plugin System</h1>
<b>Version 1.6</b>
<b>Version 1.7</b>
<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="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
</div>
<div class="modified">
Important modifications introduced since version 1.6 are marked like this.
</div modified>
<p>
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.
@ -1844,6 +1850,9 @@ virtual bool HasDecoder(void) const;
virtual bool CanReplay(void) const;
virtual bool SetPlayMode(ePlayMode PlayMode);
virtual int64_t GetSTC(void);
<div class="modified">
virtual bool IsPlayingVideo(void) const;
</div modified>
virtual bool HasIBPTrickSpeed(void);
virtual void TrickSpeed(int Speed);
virtual void Clear(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@ -81,6 +81,7 @@ cDevice::cDevice(void)
startScrambleDetection = 0;
player = NULL;
isPlayingVideo = false;
ClrAvailableTracks();
currentAudioTrack = ttNone;
currentAudioTrackMissingCount = 0;
@ -1099,6 +1100,7 @@ void cDevice::Detach(cPlayer *Player)
SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
PlayTs(NULL, 0);
Audios.ClearAudio();
isPlayingVideo = false;
}
}
@ -1151,6 +1153,7 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly)
switch (c) {
case 0xBE: // padding stream, needed for MPEG1
case 0xE0 ... 0xEF: // video
isPlayingVideo = true;
w = PlayVideo(Start, d);
break;
case 0xC0 ... 0xDF: // audio
@ -1322,8 +1325,10 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
patPmtParser.ParsePat(Data, Length);
else if (Pid == patPmtParser.PmtPid())
patPmtParser.ParsePmt(Data, Length);
else if (Pid == patPmtParser.Vpid())
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);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@ -477,6 +477,7 @@ private:
cTsToPes tsToPesVideo;
cTsToPes tsToPesAudio;
cTsToPes tsToPesSubtitle;
bool isPlayingVideo;
protected:
virtual bool CanReplay(void) const;
///< 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
///< synchronize audio and video. If this device is unable to
///< 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; }
///< Returns true if this device can handle all frames in 'fast forward'
///< trick speeds.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@ -412,8 +412,12 @@ void cDvbPlayer::Action(void)
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, NULL, &Length))
Index = readIndex + 1;
}
else
Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, TimeShiftMode);
else {
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 (!NextFile(FileNumber, FileOffset)) {
readIndex = Index;
@ -516,9 +520,9 @@ void cDvbPlayer::Action(void)
if (p) {
int w;
if (isPesRecording)
w = PlayPes(p, pc, playMode != pmPlay);
w = PlayPes(p, pc, playMode != pmPlay && DeviceIsPlayingVideo());
else
w = PlayTs(p, TS_SIZE, playMode != pmPlay);
w = PlayTs(p, TS_SIZE, playMode != pmPlay && DeviceIsPlayingVideo());
if (w > 0) {
p += w;
pc -= w;
@ -593,7 +597,8 @@ void cDvbPlayer::Forward(void)
LOCK_THREAD;
if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
Empty();
DeviceMute();
if (DeviceIsPlayingVideo())
DeviceMute();
playMode = pmFast;
playDir = pdForward;
trickSpeed = NORMAL_SPEED;
@ -639,7 +644,8 @@ void cDvbPlayer::Backward(void)
case pmPlay: {
LOCK_THREAD;
Empty();
DeviceMute();
if (DeviceIsPlayingVideo())
DeviceMute();
playMode = pmFast;
playDir = pdBackward;
trickSpeed = NORMAL_SPEED;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@ -26,6 +26,7 @@ protected:
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 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 DeviceClear(void) { if (device) device->Clear(); }
void DevicePlay(void) { if (device) device->Play(); }