Added the new command line option --updindex

This commit is contained in:
Klaus Schmidinger 2015-01-17 15:03:01 +01:00
parent f42cbac237
commit 0c2316b638
6 changed files with 61 additions and 16 deletions

View File

@ -623,6 +623,7 @@ Helmut Auer <vdr@helmutauer.de>
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 <jhall@UU.NET>
for fixing an incomplete initialization of the filter parameters in eit.c

View File

@ -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).

View File

@ -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)

View File

@ -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;

14
vdr.1
View File

@ -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

6
vdr.c
View File

@ -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 <getopt.h>
@ -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"