From 0c2316b638020f4087a664525f9ce7004d506488 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 17 Jan 2015 15:03:01 +0100 Subject: [PATCH] Added the new command line option --updindex --- CONTRIBUTORS | 1 + HISTORY | 2 ++ recording.c | 44 +++++++++++++++++++++++++++++++++----------- recording.h | 10 +++++++--- vdr.1 | 14 +++++++++++++- vdr.c | 6 +++++- 6 files changed, 61 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index d43f92ec..988a80f4 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -623,6 +623,7 @@ Helmut Auer via the main menu and by pressing the Recordings key for helping to debug a problem with frame detection in MPEG-2 streams that have "bottom fields" or varying GOP structures + for a patch that was used to implement the command line option --updindex Jeremy Hall for fixing an incomplete initialization of the filter parameters in eit.c diff --git a/HISTORY b/HISTORY index c62d9a98..5ea71eb2 100644 --- a/HISTORY +++ b/HISTORY @@ -8392,3 +8392,5 @@ Video Disk Recorder Revision History frames at their very end, which probably doesn't matter. At any rate, if you have generated an index file with VDR version 2.0.6, 2.1.5 or 2.1.6, you may want to do so again with this version to make sure the index is OK. +- Added the new command line option --updindex, which can be used to update an + incomplete index of a recording (based on a patch from Helmut Auer). diff --git a/recording.c b/recording.c index 669e8ffa..e9a6b169 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.20 2015/01/17 13:47:33 kls Exp $ + * $Id: recording.c 3.21 2015/01/17 14:52:28 kls Exp $ */ #include "recording.h" @@ -2241,17 +2241,19 @@ void cRecordingUserCommand::InvokeCommand(const char *State, const char *Recordi class cIndexFileGenerator : public cThread { private: cString recordingName; + bool update; protected: virtual void Action(void); public: - cIndexFileGenerator(const char *RecordingName); + cIndexFileGenerator(const char *RecordingName, bool Update = false); ~cIndexFileGenerator(); }; -cIndexFileGenerator::cIndexFileGenerator(const char *RecordingName) +cIndexFileGenerator::cIndexFileGenerator(const char *RecordingName, bool Update) :cThread("index file generator") ,recordingName(RecordingName) { + update = Update; Start(); } @@ -2270,16 +2272,34 @@ void cIndexFileGenerator::Action(void) cRingBufferLinear Buffer(IFG_BUFFER_SIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE); cPatPmtParser PatPmtParser; cFrameDetector FrameDetector; - cIndexFile IndexFile(recordingName, true); + cIndexFile IndexFile(recordingName, true, false, false, true); int BufferChunks = KILOBYTE(1); // no need to read a lot at the beginning when parsing PAT/PMT off_t FileSize = 0; off_t FrameOffset = -1; + uint16_t FileNumber = 1; + off_t FileOffset = 0; + int Last = -1; + if (update) { + // Look for current index and position to end of it if present: + bool Independent; + int Length; + Last = IndexFile.Last(); + if (Last >= 0 && !IndexFile.Get(Last, &FileNumber, &FileOffset, &Independent, &Length)) + Last = -1; // reset Last if an error occurred + if (Last >= 0) { + Rewind = true; + isyslog("updating index file"); + } + else + isyslog("generating index file"); + } Skins.QueueMessage(mtInfo, tr("Regenerating index file")); bool Stuffed = false; while (Running()) { // Rewind input file: if (Rewind) { - ReplayFile = FileName.SetOffset(1); + ReplayFile = FileName.SetOffset(FileNumber, FileOffset); + FileSize = FileOffset; Buffer.Clear(); Rewind = false; } @@ -2294,7 +2314,8 @@ void cIndexFileGenerator::Action(void) int Processed = FrameDetector.Analyze(Data, Length); if (Processed > 0) { if (FrameDetector.NewFrame()) { - IndexFile.Write(FrameDetector.IndependentFrame(), FileName.Number(), FrameOffset >= 0 ? FrameOffset : FileSize); + if (IndexFileWritten || Last < 0) // check for first frame and do not write if in update mode + IndexFile.Write(FrameDetector.IndependentFrame(), FileName.Number(), FrameOffset >= 0 ? FrameOffset : FileSize); FrameOffset = -1; IndexFileWritten = true; } @@ -2419,7 +2440,7 @@ struct tIndexTs { #define INDEXFILECHECKINTERVAL 500 // ms between checks for existence of the regenerated index file #define INDEXFILETESTINTERVAL 10 // ms between tests for the size of the index file in case of pausing live video -cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording, bool PauseLive) +cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording, bool PauseLive, bool Update) :resumeFile(FileName, IsPesRecording) { f = -1; @@ -2458,7 +2479,7 @@ cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording, b esyslog("ERROR: invalid file size (%"PRId64") in '%s'", buf.st_size, *fileName); } last = int((buf.st_size + delta) / sizeof(tIndexTs) - 1); - if (!Record && last >= 0) { + if ((!Record || Update) && last >= 0) { size = last + 1; index = MALLOC(tIndexTs, size); if (index) { @@ -2746,15 +2767,16 @@ int cIndexFile::GetLength(const char *FileName, bool IsPesRecording) return -1; } -bool GenerateIndex(const char *FileName) +bool GenerateIndex(const char *FileName, bool Update) { if (DirectoryOk(FileName)) { cRecording Recording(FileName); if (Recording.Name()) { if (!Recording.IsPesRecording()) { cString IndexFileName = AddDirectory(FileName, INDEXFILESUFFIX); - unlink(IndexFileName); - cIndexFileGenerator *IndexFileGenerator = new cIndexFileGenerator(FileName); + if (!Update) + unlink(IndexFileName); + cIndexFileGenerator *IndexFileGenerator = new cIndexFileGenerator(FileName, Update); while (IndexFileGenerator->Active()) cCondWait::SleepMs(INDEXFILECHECKINTERVAL); if (access(IndexFileName, R_OK) == 0) diff --git a/recording.h b/recording.h index 7d5228eb..c9e950b3 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.4 2014/01/01 12:45:18 kls Exp $ + * $Id: recording.h 3.5 2015/01/17 14:33:05 kls Exp $ */ #ifndef __RECORDING_H @@ -429,7 +429,7 @@ private: void ConvertToPes(tIndexTs *IndexTs, int Count); bool CatchUp(int Index = -1); public: - cIndexFile(const char *FileName, bool Record, bool IsPesRecording = false, bool PauseLive = false); + cIndexFile(const char *FileName, bool Record, bool IsPesRecording = false, bool PauseLive = false, bool Update = false); ~cIndexFile(); bool Ok(void) { return index != NULL; } bool Write(bool Independent, uint16_t FileNumber, off_t FileOffset); @@ -488,7 +488,11 @@ char *ExchangeChars(char *s, bool ToFileSystem); // be modified and may be reallocated if more space is needed. The return // value points to the resulting string, which may be different from s. -bool GenerateIndex(const char *FileName); +bool GenerateIndex(const char *FileName, bool Update = false); + ///< Generates the index of the existing recording with the given FileName. + ///< If Update is true, an existing index file will be checked whether it is + ///< complete, and will be updated if it isn't. Otherwise an existing index + ///< file will be removed before a new one is generated. enum eRecordingsSortMode { rsmName, rsmTime }; extern eRecordingsSortMode RecordingsSortMode; diff --git a/vdr.1 b/vdr.1 index c5bd281c..5727ee5a 100644 --- a/vdr.1 +++ b/vdr.1 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.1 3.2 2014/04/14 12:52:45 kls Exp $ +.\" $Id: vdr.1 3.3 2015/01/17 14:46:22 kls Exp $ .\" .TH vdr 1 "31 Mar 2013" "2.0" "Video Disk Recorder" .SH NAME @@ -201,6 +201,18 @@ be set from the transponder data, but for security reasons vdr can switch to a lesser privileged user id during normal operation. .TP +.BI \-\-updindex= rec +Update the index file for the given recording. +\fIrec\fR must be the full path name of an existing recording. +The recording must be in TS format. +If the recording already has an index file, it will be checked +whether it is complete, and will be updated if it isn't. If +there is no index file yet, a new one will be generated. +The program will return immediately after updating the index. +Note that using this option while another instance of VDR is +currently replaying the given recording, or if the recording +has not been finished yet, may lead to unexpected results. +.TP .BI \-\-userdump Allow coredumps if -u is given (only for debugging). .TP diff --git a/vdr.c b/vdr.c index 53d8bacc..336130f8 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 3.14 2015/01/14 12:11:41 kls Exp $ + * $Id: vdr.c 3.15 2015/01/17 14:48:09 kls Exp $ */ #include @@ -269,6 +269,7 @@ int main(int argc, char *argv[]) { "shutdown", required_argument, NULL, 's' }, { "split", no_argument, NULL, 's' | 0x100 }, { "terminal", required_argument, NULL, 't' }, + { "updindex", required_argument, NULL, 'u' | 0x200 }, { "user", required_argument, NULL, 'u' }, { "userdump", no_argument, NULL, 'u' | 0x100 }, { "version", no_argument, NULL, 'V' }, @@ -463,6 +464,8 @@ int main(int argc, char *argv[]) case 'u' | 0x100: UserDump = true; break; + case 'u' | 0x200: + return GenerateIndex(optarg, true) ? 0 : 2; case 'V': DisplayVersion = true; break; case 'v' | 0x100: @@ -569,6 +572,7 @@ int main(int argc, char *argv[]) " -t TTY, --terminal=TTY controlling tty\n" " -u USER, --user=USER run as user USER; only applicable if started as\n" " root\n" + " --updindex=REC update index for recording REC and exit\n" " --userdump allow coredumps if -u is given (debugging)\n" " -v DIR, --video=DIR use DIR as video directory (default: %s)\n" " -V, --version print version information and exit\n"