mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved fast-forward/-rewind for audio recordings
This commit is contained in:
parent
73be47a4b1
commit
f9c1974f2d
14
HISTORY
14
HISTORY
@ -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.
|
||||||
|
15
PLUGINS.html
15
PLUGINS.html
@ -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 © 2008 Klaus Schmidinger<br>
|
Copyright © 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);
|
||||||
|
9
device.c
9
device.c
@ -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);
|
||||||
|
6
device.h
6
device.h
@ -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.
|
||||||
|
16
dvbplayer.c
16
dvbplayer.c
@ -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,6 +597,7 @@ void cDvbPlayer::Forward(void)
|
|||||||
LOCK_THREAD;
|
LOCK_THREAD;
|
||||||
if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
|
if (!(DeviceHasIBPTrickSpeed() && playDir == pdForward))
|
||||||
Empty();
|
Empty();
|
||||||
|
if (DeviceIsPlayingVideo())
|
||||||
DeviceMute();
|
DeviceMute();
|
||||||
playMode = pmFast;
|
playMode = pmFast;
|
||||||
playDir = pdForward;
|
playDir = pdForward;
|
||||||
@ -639,6 +644,7 @@ void cDvbPlayer::Backward(void)
|
|||||||
case pmPlay: {
|
case pmPlay: {
|
||||||
LOCK_THREAD;
|
LOCK_THREAD;
|
||||||
Empty();
|
Empty();
|
||||||
|
if (DeviceIsPlayingVideo())
|
||||||
DeviceMute();
|
DeviceMute();
|
||||||
playMode = pmFast;
|
playMode = pmFast;
|
||||||
playDir = pdBackward;
|
playDir = pdBackward;
|
||||||
|
3
player.h
3
player.h
@ -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(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user