mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	cDvbPlayer and cReplayControl now use the same list of editing marks
This commit is contained in:
		
							
								
								
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								MANUAL
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								dvbplayer.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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)) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								recording.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user