mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
cDvbPlayer and cReplayControl now use the same list of editing marks
This commit is contained in:
parent
4ffd2d6ccd
commit
f3e6d39382
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
|
||||
|
44
dvbplayer.c
44
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)))
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user