summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY3
-rw-r--r--MANUAL4
-rw-r--r--dvbplayer.c46
-rw-r--r--dvbplayer.h4
-rw-r--r--menu.c8
-rw-r--r--recording.c9
-rw-r--r--recording.h14
7 files changed, 65 insertions, 23 deletions
diff --git a/HISTORY b/HISTORY
index 75cf676a..cc737bf0 100644
--- a/HISTORY
+++ b/HISTORY
@@ -8508,3 +8508,6 @@ Video Disk Recorder Revision History
process.
- Changed the naming of "binary skip mode" to "adaptive skip mode" (suggested by
Rolf Ahrenberg and Derek Kelly).
+- cDvbPlayer and cReplayControl now use the same list of editing marks. This avoids
+ inconsistent behavior with the "Skip edited parts" or "Pause replay at last mark"
+ functions when the editing marks are manipulated during replay.
diff --git a/MANUAL b/MANUAL
index f329a771..b0b7fa59 100644
--- a/MANUAL
+++ b/MANUAL
@@ -991,8 +991,6 @@ Version 2.0
automatically skipped during replay. This includes jumping
to the first mark if replay starts at the beginning of the
recording, and stopping at the last mark.
- In order to work, this option must be enabled before starting
- replay.
Pause replay at last mark = no
If enabled, replay of a recording will go into Pause mode
@@ -1000,8 +998,6 @@ Version 2.0
the actual position at which the pause occurs may be a couple
of frames before the last "end" mark, depending on how much
data is buffered by your output device.
- In order to work, this option must be enabled before starting
- replay.
Initial duration for adaptive skipping (s) = 120
Defines the number of seconds to jump from the current replay
diff --git a/dvbplayer.c b/dvbplayer.c
index 9e561ca1..94882e29 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,13 +4,12 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.c 3.4 2015/02/02 09:51:32 kls Exp $
+ * $Id: dvbplayer.c 3.5 2015/02/06 15:08:51 kls Exp $
*/
#include "dvbplayer.h"
#include <math.h>
#include <stdlib.h>
-#include "recording.h"
#include "remux.h"
#include "ringbuffer.h"
#include "thread.h"
@@ -211,7 +210,7 @@ private:
cNonBlockingFileReader *nonBlockingFileReader;
cRingBufferFrame *ringBuffer;
cPtsIndex ptsIndex;
- cMarks marks;
+ cMarks *marks;
cFileName *fileName;
cIndexFile *index;
cUnbufferedFile *replayFile;
@@ -240,6 +239,7 @@ protected:
public:
cDvbPlayer(const char *FileName, bool PauseLive);
virtual ~cDvbPlayer();
+ void SetMarks(cMarks *Marks);
bool Active(void) { return cThread::Running(); }
void Pause(void);
void Play(void);
@@ -265,6 +265,7 @@ cDvbPlayer::cDvbPlayer(const char *FileName, bool PauseLive)
{
nonBlockingFileReader = NULL;
ringBuffer = NULL;
+ marks = NULL;
index = NULL;
cRecording Recording(FileName);
framesPerSecond = Recording.FramesPerSecond();
@@ -297,8 +298,6 @@ cDvbPlayer::cDvbPlayer(const char *FileName, bool PauseLive)
}
else if (PauseLive)
framesPerSecond = cRecording(FileName).FramesPerSecond(); // the fps rate might have changed from the default
- if (Setup.SkipEdited || Setup.PauseAtLastMark)
- marks.Load(FileName, framesPerSecond, isPesRecording);
}
cDvbPlayer::~cDvbPlayer()
@@ -309,6 +308,12 @@ cDvbPlayer::~cDvbPlayer()
delete index;
delete fileName;
delete ringBuffer;
+ // don't delete marks here, we don't own them!
+}
+
+void cDvbPlayer::SetMarks(cMarks *Marks)
+{
+ marks = Marks;
}
void cDvbPlayer::TrickSpeed(int Increment)
@@ -377,8 +382,12 @@ bool cDvbPlayer::Save(void)
if (index) {
int Index = ptsIndex.FindIndex(DeviceGetSTC());
if (Index >= 0) {
- if (Setup.SkipEdited && marks.First() && abs(Index - marks.First()->Position()) <= int(round(RESUMEBACKUP * framesPerSecond)))
- Index = 0; // when stopping within RESUMEBACKUP seconds of the first mark the recording shall still be considered unviewed
+ if (Setup.SkipEdited && marks) {
+ marks->Lock();
+ if (marks->First() && abs(Index - marks->First()->Position()) <= int(round(RESUMEBACKUP * framesPerSecond)))
+ Index = 0; // when stopping within RESUMEBACKUP seconds of the first mark the recording shall still be considered unviewed
+ marks->Unlock();
+ }
Index -= int(round(RESUMEBACKUP * framesPerSecond));
if (Index > 0)
Index = index->GetNextIFrame(Index, false);
@@ -409,9 +418,10 @@ void cDvbPlayer::Action(void)
readIndex = Resume();
if (readIndex > 0)
isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true, framesPerSecond));
- else if (Setup.SkipEdited) {
- if (marks.First() && index) {
- int Index = marks.First()->Position();
+ else if (Setup.SkipEdited && marks) {
+ marks->Lock();
+ if (marks->First() && index) {
+ int Index = marks->First()->Position();
uint16_t FileNumber;
off_t FileOffset;
if (index->Get(Index, &FileNumber, &FileOffset) && NextFile(FileNumber, FileOffset)) {
@@ -419,6 +429,7 @@ void cDvbPlayer::Action(void)
readIndex = Index;
}
}
+ marks->Unlock();
}
nonBlockingFileReader = new cNonBlockingFileReader;
@@ -488,11 +499,11 @@ void cDvbPlayer::Action(void)
off_t FileOffset;
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent, &Length) && NextFile(FileNumber, FileOffset)) {
readIndex++;
- if (Setup.SkipEdited || Setup.PauseAtLastMark) {
- marks.Update();
- cMark *m = marks.Get(readIndex);
+ if ((Setup.SkipEdited || Setup.PauseAtLastMark) && marks) {
+ marks->Lock();
+ cMark *m = marks->Get(readIndex);
if (m && (m->Index() & 0x01) != 0) { // we're at an end mark
- m = marks.GetNextBegin(m);
+ m = marks->GetNextBegin(m);
int Index = -1;
if (m)
Index = m->Position(); // skip to next begin mark
@@ -508,6 +519,7 @@ void cDvbPlayer::Action(void)
CutIn = true;
}
}
+ marks->Unlock();
}
}
else
@@ -931,6 +943,12 @@ cDvbPlayerControl::~cDvbPlayerControl()
Stop();
}
+void cDvbPlayerControl::SetMarks(cMarks *Marks)
+{
+ if (player)
+ player->SetMarks(Marks);
+}
+
bool cDvbPlayerControl::Active(void)
{
return player && player->Active();
diff --git a/dvbplayer.h b/dvbplayer.h
index 678c9693..7094454d 100644
--- a/dvbplayer.h
+++ b/dvbplayer.h
@@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.h 3.1 2015/02/01 11:20:54 kls Exp $
+ * $Id: dvbplayer.h 3.2 2015/02/06 12:27:39 kls Exp $
*/
#ifndef __DVBPLAYER_H
#define __DVBPLAYER_H
#include "player.h"
+#include "recording.h"
#include "thread.h"
class cDvbPlayer;
@@ -25,6 +26,7 @@ public:
// file of the recording is long enough to allow the player to display
// the first frame in still picture mode.
virtual ~cDvbPlayerControl();
+ void SetMarks(cMarks *Marks);
bool Active(void);
void Stop(void);
// Stops the current replay session (if any).
diff --git a/menu.c b/menu.c
index 6cda42d0..fd18c1bb 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 3.42 2015/02/06 09:53:25 kls Exp $
+ * $Id: menu.c 3.43 2015/02/06 15:20:11 kls Exp $
*/
#include "menu.h"
@@ -5120,6 +5120,7 @@ cReplayControl::cReplayControl(bool PauseLive)
cRecording Recording(fileName);
cStatus::MsgReplaying(this, Recording.Name(), Recording.FileName(), true);
marks.Load(fileName, Recording.FramesPerSecond(), Recording.IsPesRecording());
+ SetMarks(&marks);
adaptiveSkipper.Initialize(&Setup.AdaptiveSkipInitial, Recording.FramesPerSecond());
SetTrackDescriptions(false);
if (Setup.ProgressDisplayTime)
@@ -5389,6 +5390,7 @@ void cReplayControl::MarkToggle(void)
int Current, Total;
if (GetIndex(Current, Total, true)) {
lastCurrent = -1; // triggers redisplay
+ cMutexLock MutexLock(&marks);
if (cMark *m = marks.Get(Current))
marks.Del(m);
else {
@@ -5409,6 +5411,7 @@ void cReplayControl::MarkJump(bool Forward)
{
int Current, Total;
if (GetIndex(Current, Total)) {
+ cMutexLock MutexLock(&marks);
if (marks.Count()) {
if (cMark *m = Forward ? marks.GetNext(Current) : marks.GetPrev(Current)) {
if (!Setup.PauseOnMarkJump) {
@@ -5437,6 +5440,7 @@ void cReplayControl::MarkMove(int Frames, bool MarkRequired)
bool Play, Forward;
int Speed;
GetReplayMode(Play, Forward, Speed);
+ cMutexLock MutexLock(&marks);
cMark *m = marks.Get(Current);
if (!Play && m) {
displayFrames = true;
@@ -5472,6 +5476,7 @@ void cReplayControl::EditCut(void)
if (*fileName) {
Hide();
if (!RecordingsHandler.GetUsage(fileName)) {
+ cMutexLock MutexLock(&marks);
if (!marks.Count())
Skins.Message(mtError, tr("No editing marks defined!"));
else if (!marks.GetNumSequences())
@@ -5493,6 +5498,7 @@ void cReplayControl::EditTest(void)
{
int Current, Total;
if (GetIndex(Current, Total)) {
+ cMutexLock MutexLock(&marks);
cMark *m = marks.Get(Current);
if (!m)
m = marks.GetNext(Current);
diff --git a/recording.c b/recording.c
index 19b36db8..271f6475 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.c 3.25 2015/02/05 13:50:39 kls Exp $
+ * $Id: recording.c 3.26 2015/02/06 15:13:59 kls Exp $
*/
#include "recording.h"
@@ -2059,6 +2059,7 @@ cString cMarks::MarksFileName(const cRecording *Recording)
bool cMarks::Load(const char *RecordingFileName, double FramesPerSecond, bool IsPesRecording)
{
+ cMutexLock MutexLock(this);
recordingFileName = RecordingFileName;
fileName = AddDirectory(RecordingFileName, IsPesRecording ? MARKSFILESUFFIX ".vdr" : MARKSFILESUFFIX);
framesPerSecond = FramesPerSecond;
@@ -2071,6 +2072,7 @@ bool cMarks::Load(const char *RecordingFileName, double FramesPerSecond, bool Is
bool cMarks::Update(void)
{
+ cMutexLock MutexLock(this);
time_t t = time(NULL);
if (t > nextUpdate && *fileName) {
time_t LastModified = LastModifiedTime(fileName);
@@ -2102,6 +2104,7 @@ bool cMarks::Update(void)
bool cMarks::Save(void)
{
+ cMutexLock MutexLock(this);
if (cConfig<cMark>::Save()) {
lastFileTime = LastModifiedTime(fileName);
return true;
@@ -2111,6 +2114,7 @@ bool cMarks::Save(void)
void cMarks::Align(void)
{
+ cMutexLock MutexLock(this);
cIndexFile IndexFile(recordingFileName, false, isPesRecording);
for (cMark *m = First(); m; m = Next(m)) {
int p = IndexFile.GetClosestIFrame(m->Position());
@@ -2123,6 +2127,7 @@ void cMarks::Align(void)
void cMarks::Sort(void)
{
+ cMutexLock MutexLock(this);
for (cMark *m1 = First(); m1; m1 = Next(m1)) {
for (cMark *m2 = Next(m1); m2; m2 = Next(m2)) {
if (m2->Position() < m1->Position()) {
@@ -2135,6 +2140,7 @@ void cMarks::Sort(void)
void cMarks::Add(int Position)
{
+ cMutexLock MutexLock(this);
cConfig<cMark>::Add(new cMark(Position, NULL, framesPerSecond));
Sort();
}
@@ -2202,6 +2208,7 @@ cMark *cMarks::GetNextEnd(cMark *BeginMark)
int cMarks::GetNumSequences(void)
{
+ cMutexLock MutexLock(this);
int NumSequences = 0;
if (cMark *BeginMark = GetNextBegin()) {
while (cMark *EndMark = GetNextEnd(BeginMark)) {
diff --git a/recording.h b/recording.h
index 1079ae1f..f6eaa19b 100644
--- a/recording.h
+++ b/recording.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.h 3.6 2015/01/31 13:34:44 kls Exp $
+ * $Id: recording.h 3.7 2015/02/06 15:17:04 kls Exp $
*/
#ifndef __RECORDING_H
@@ -350,7 +350,7 @@ public:
bool Save(FILE *f);
};
-class cMarks : public cConfig<cMark> {
+class cMarks : public cConfig<cMark>, public cMutex {
private:
cString recordingFileName;
cString fileName;
@@ -370,15 +370,25 @@ public:
void Sort(void);
void Add(int Position);
cMark *Get(int Position);
+ ///< If this cMarks object is used by multiple threads, the caller must hold a lock
+ ///< on this object as long as it handles the returned pointer.
cMark *GetPrev(int Position);
+ ///< If this cMarks object is used by multiple threads, the caller must hold a lock
+ ///< on this object as long as it handles the returned pointer.
cMark *GetNext(int Position);
+ ///< If this cMarks object is used by multiple threads, the caller must hold a lock
+ ///< on this object as long as it handles the returned pointer.
cMark *GetNextBegin(cMark *EndMark = NULL);
///< Returns the next "begin" mark after EndMark, skipping any marks at the
///< same position as EndMark. If EndMark is NULL, the first actual "begin"
///< will be returned (if any).
+ ///< If this cMarks object is used by multiple threads, the caller must hold a lock
+ ///< on this object as long as it handles the returned pointer.
cMark *GetNextEnd(cMark *BeginMark);
///< Returns the next "end" mark after BeginMark, skipping any marks at the
///< same position as BeginMark.
+ ///< If this cMarks object is used by multiple threads, the caller must hold a lock
+ ///< on this object as long as it handles the returned pointer.
int GetNumSequences(void);
///< Returns the actual number of sequences to be cut from the recording.
///< If there is only one actual "begin" mark, and it is positioned at index