From 15bb8ca60db165833441e44da6d8861e9a7df0ad Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 15 Oct 2012 11:23:59 +0200 Subject: [PATCH] If a frame position in the 'marks' file of a recording doesn't point to an I-frame, it will now be shifted towards the next I-frame --- HISTORY | 5 ++++- UPDATE-2.0.0 | 3 +++ recording.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- recording.h | 10 +++++++++- vdr.5 | 10 +++++----- 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/HISTORY b/HISTORY index 5fdc7b47..2f6a560c 100644 --- a/HISTORY +++ b/HISTORY @@ -7272,7 +7272,7 @@ Video Disk Recorder Revision History ".keep" to prevent a directory from being deleted when it is empty. Currently the only file name that is ignored is ".sort". -2012-10-13: Version 1.7.32 +2012-10-15: Version 1.7.32 - Pressing the Play key during normal live viewing mode now opens the Recordings menu if there is no "last viewed" recording (thanks to Alexander Wenzel). @@ -7298,3 +7298,6 @@ Video Disk Recorder Revision History Make.config.template. - Fixed handling VPS timers in case the running status of an event goes to '1' (not running) and later goes to '4' (running). +- If a frame position in the 'marks' file of a recording doesn't point to an I-frame, + it will now be shifted towards the next I-frame (either up or down, whichever is + closer). diff --git a/UPDATE-2.0.0 b/UPDATE-2.0.0 index 30f3cbbd..e65ab45f 100644 --- a/UPDATE-2.0.0 +++ b/UPDATE-2.0.0 @@ -327,6 +327,9 @@ Recordings: This obsoletes the CUTTIME patch. - An ongoing editing process is now canceled if either the original or the edited version of the recording is deleted from the Recordings menu. +- If a frame position in the 'marks' file of a recording doesn't point to an I-frame, + it will now be shifted towards the next I-frame (either up or down, whichever is + closer). SVDRP: diff --git a/recording.c b/recording.c index 783a46e5..71272fca 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 2.66 2012/10/04 12:21:38 kls Exp $ + * $Id: recording.c 2.67 2012/10/15 10:23:37 kls Exp $ */ #include "recording.h" @@ -1358,8 +1358,10 @@ bool cMark::Save(FILE *f) bool cMarks::Load(const char *RecordingFileName, double FramesPerSecond, bool IsPesRecording) { + recordingFileName = RecordingFileName; fileName = AddDirectory(RecordingFileName, IsPesRecording ? MARKSFILESUFFIX ".vdr" : MARKSFILESUFFIX); framesPerSecond = FramesPerSecond; + isPesRecording = IsPesRecording; nextUpdate = 0; lastFileTime = -1; // the first call to Load() must take place! lastChange = 0; @@ -1388,6 +1390,7 @@ bool cMarks::Update(void) cMutexLock MutexLock(&MutexMarkFramesPerSecond); MarkFramesPerSecond = framesPerSecond; if (cConfig::Load(fileName)) { + Align(); Sort(); return true; } @@ -1396,6 +1399,18 @@ bool cMarks::Update(void) return false; } +void cMarks::Align(void) +{ + cIndexFile IndexFile(recordingFileName, isPesRecording); + for (cMark *m = First(); m; m = Next(m)) { + int p = IndexFile.GetClosestIFrame(m->Position()); + if (int d = m->Position() - p) { + isyslog("aligned editing mark %s to %s (off by %d frame%s)", *IndexToHMSF(m->Position(), true, framesPerSecond), *IndexToHMSF(p, true, framesPerSecond), d, abs(d) > 1 ? "s" : ""); + m->SetPosition(p); + } + } +} + void cMarks::Sort(void) { for (cMark *m1 = First(); m1; m1 = Next(m1)) { @@ -1882,6 +1897,34 @@ int cIndexFile::GetNextIFrame(int Index, bool Forward, uint16_t *FileNumber, off return -1; } +int cIndexFile::GetClosestIFrame(int Index) +{ + if (last > 0) { + Index = constrain(Index, 0, last - 1); + if (index[Index].independent) + return Index; + int il = Index - 1; + int ih = Index + 1; + for (;;) { + if (il >= 0) { + if (index[il].independent) + return il; + il--; + } + else if (ih >= last) + break; + if (ih < last) { + if (index[ih].independent) + return ih; + ih++; + } + else if (il < 0) + break; + } + } + return 0; +} + int cIndexFile::Get(uint16_t FileNumber, off_t FileOffset) { if (CatchUp()) { diff --git a/recording.h b/recording.h index ac44ad5b..22c5d3a7 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 2.37 2012/09/17 08:53:23 kls Exp $ + * $Id: recording.h 2.38 2012/10/15 10:22:27 kls Exp $ */ #ifndef __RECORDING_H @@ -222,14 +222,17 @@ public: class cMarks : public cConfig { private: + cString recordingFileName; cString fileName; double framesPerSecond; + bool isPesRecording; time_t nextUpdate; time_t lastFileTime; time_t lastChange; public: bool Load(const char *RecordingFileName, double FramesPerSecond = DEFAULTFRAMESPERSECOND, bool IsPesRecording = false); bool Update(void); + void Align(void); void Sort(void); cMark *Add(int Position); cMark *Get(int Position); @@ -291,6 +294,11 @@ public: bool Write(bool Independent, uint16_t FileNumber, off_t FileOffset); bool Get(int Index, uint16_t *FileNumber, off_t *FileOffset, bool *Independent = NULL, int *Length = NULL); int GetNextIFrame(int Index, bool Forward, uint16_t *FileNumber = NULL, off_t *FileOffset = NULL, int *Length = NULL); + int GetClosestIFrame(int Index); + ///< Returns the index of the I-frame that is closest to the given Index (or Index itself, + ///< if it already points to an I-frame). Index may be any value, even outside the current + ///< range of frame indexes. + ///< If there is no actual index data available, 0 is returned. int Get(uint16_t FileNumber, off_t FileOffset); int Last(void) { CatchUp(); return last; } int GetResume(void) { return resumeFile.Read(); } diff --git a/vdr.5 b/vdr.5 index a606dde8..4003a5e9 100644 --- a/vdr.5 +++ b/vdr.5 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 2.29 2012/03/10 14:56:01 kls Exp $ +.\" $Id: vdr.5 2.30 2012/10/15 10:50:23 kls Exp $ .\" .TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files" .SH NAME @@ -815,13 +815,13 @@ least one blank. The lines in this file need not necessarily appear in the correct temporal sequence, they will be automatically sorted by time index. +If a frame position doesn't point to an I-frame of the corresponding recording, +it will be shifted towards the next I-frame (either up or down, whichever is +closer). + \fBCURRENT RESTRICTIONS:\fR -\ the comment is currently not used by VDR -.br --\ marks must have a frame number, and that frame MUST be an I-frame (this -means that only marks generated by VDR itself can be used, since they -will always be guaranteed to mark I-frames). .SS EPG DATA The file \fIepg.data\fR contains the EPG data in an easily parsable format. The first character of each line defines what kind of data this line contains.