mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Added the new command line option --updindex
This commit is contained in:
parent
f42cbac237
commit
0c2316b638
@ -623,6 +623,7 @@ Helmut Auer <vdr@helmutauer.de>
|
|||||||
via the main menu and by pressing the Recordings key
|
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"
|
for helping to debug a problem with frame detection in MPEG-2 streams that have "bottom fields"
|
||||||
or varying GOP structures
|
or varying GOP structures
|
||||||
|
for a patch that was used to implement the command line option --updindex
|
||||||
|
|
||||||
Jeremy Hall <jhall@UU.NET>
|
Jeremy Hall <jhall@UU.NET>
|
||||||
for fixing an incomplete initialization of the filter parameters in eit.c
|
for fixing an incomplete initialization of the filter parameters in eit.c
|
||||||
|
2
HISTORY
2
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
|
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
|
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.
|
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).
|
||||||
|
44
recording.c
44
recording.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "recording.h"
|
||||||
@ -2241,17 +2241,19 @@ void cRecordingUserCommand::InvokeCommand(const char *State, const char *Recordi
|
|||||||
class cIndexFileGenerator : public cThread {
|
class cIndexFileGenerator : public cThread {
|
||||||
private:
|
private:
|
||||||
cString recordingName;
|
cString recordingName;
|
||||||
|
bool update;
|
||||||
protected:
|
protected:
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
public:
|
public:
|
||||||
cIndexFileGenerator(const char *RecordingName);
|
cIndexFileGenerator(const char *RecordingName, bool Update = false);
|
||||||
~cIndexFileGenerator();
|
~cIndexFileGenerator();
|
||||||
};
|
};
|
||||||
|
|
||||||
cIndexFileGenerator::cIndexFileGenerator(const char *RecordingName)
|
cIndexFileGenerator::cIndexFileGenerator(const char *RecordingName, bool Update)
|
||||||
:cThread("index file generator")
|
:cThread("index file generator")
|
||||||
,recordingName(RecordingName)
|
,recordingName(RecordingName)
|
||||||
{
|
{
|
||||||
|
update = Update;
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2270,16 +2272,34 @@ void cIndexFileGenerator::Action(void)
|
|||||||
cRingBufferLinear Buffer(IFG_BUFFER_SIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE);
|
cRingBufferLinear Buffer(IFG_BUFFER_SIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE);
|
||||||
cPatPmtParser PatPmtParser;
|
cPatPmtParser PatPmtParser;
|
||||||
cFrameDetector FrameDetector;
|
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
|
int BufferChunks = KILOBYTE(1); // no need to read a lot at the beginning when parsing PAT/PMT
|
||||||
off_t FileSize = 0;
|
off_t FileSize = 0;
|
||||||
off_t FrameOffset = -1;
|
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"));
|
Skins.QueueMessage(mtInfo, tr("Regenerating index file"));
|
||||||
bool Stuffed = false;
|
bool Stuffed = false;
|
||||||
while (Running()) {
|
while (Running()) {
|
||||||
// Rewind input file:
|
// Rewind input file:
|
||||||
if (Rewind) {
|
if (Rewind) {
|
||||||
ReplayFile = FileName.SetOffset(1);
|
ReplayFile = FileName.SetOffset(FileNumber, FileOffset);
|
||||||
|
FileSize = FileOffset;
|
||||||
Buffer.Clear();
|
Buffer.Clear();
|
||||||
Rewind = false;
|
Rewind = false;
|
||||||
}
|
}
|
||||||
@ -2294,7 +2314,8 @@ void cIndexFileGenerator::Action(void)
|
|||||||
int Processed = FrameDetector.Analyze(Data, Length);
|
int Processed = FrameDetector.Analyze(Data, Length);
|
||||||
if (Processed > 0) {
|
if (Processed > 0) {
|
||||||
if (FrameDetector.NewFrame()) {
|
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;
|
FrameOffset = -1;
|
||||||
IndexFileWritten = true;
|
IndexFileWritten = true;
|
||||||
}
|
}
|
||||||
@ -2419,7 +2440,7 @@ struct tIndexTs {
|
|||||||
#define INDEXFILECHECKINTERVAL 500 // ms between checks for existence of the regenerated index file
|
#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
|
#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)
|
:resumeFile(FileName, IsPesRecording)
|
||||||
{
|
{
|
||||||
f = -1;
|
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);
|
esyslog("ERROR: invalid file size (%"PRId64") in '%s'", buf.st_size, *fileName);
|
||||||
}
|
}
|
||||||
last = int((buf.st_size + delta) / sizeof(tIndexTs) - 1);
|
last = int((buf.st_size + delta) / sizeof(tIndexTs) - 1);
|
||||||
if (!Record && last >= 0) {
|
if ((!Record || Update) && last >= 0) {
|
||||||
size = last + 1;
|
size = last + 1;
|
||||||
index = MALLOC(tIndexTs, size);
|
index = MALLOC(tIndexTs, size);
|
||||||
if (index) {
|
if (index) {
|
||||||
@ -2746,15 +2767,16 @@ int cIndexFile::GetLength(const char *FileName, bool IsPesRecording)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateIndex(const char *FileName)
|
bool GenerateIndex(const char *FileName, bool Update)
|
||||||
{
|
{
|
||||||
if (DirectoryOk(FileName)) {
|
if (DirectoryOk(FileName)) {
|
||||||
cRecording Recording(FileName);
|
cRecording Recording(FileName);
|
||||||
if (Recording.Name()) {
|
if (Recording.Name()) {
|
||||||
if (!Recording.IsPesRecording()) {
|
if (!Recording.IsPesRecording()) {
|
||||||
cString IndexFileName = AddDirectory(FileName, INDEXFILESUFFIX);
|
cString IndexFileName = AddDirectory(FileName, INDEXFILESUFFIX);
|
||||||
unlink(IndexFileName);
|
if (!Update)
|
||||||
cIndexFileGenerator *IndexFileGenerator = new cIndexFileGenerator(FileName);
|
unlink(IndexFileName);
|
||||||
|
cIndexFileGenerator *IndexFileGenerator = new cIndexFileGenerator(FileName, Update);
|
||||||
while (IndexFileGenerator->Active())
|
while (IndexFileGenerator->Active())
|
||||||
cCondWait::SleepMs(INDEXFILECHECKINTERVAL);
|
cCondWait::SleepMs(INDEXFILECHECKINTERVAL);
|
||||||
if (access(IndexFileName, R_OK) == 0)
|
if (access(IndexFileName, R_OK) == 0)
|
||||||
|
10
recording.h
10
recording.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __RECORDING_H
|
||||||
@ -429,7 +429,7 @@ private:
|
|||||||
void ConvertToPes(tIndexTs *IndexTs, int Count);
|
void ConvertToPes(tIndexTs *IndexTs, int Count);
|
||||||
bool CatchUp(int Index = -1);
|
bool CatchUp(int Index = -1);
|
||||||
public:
|
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();
|
~cIndexFile();
|
||||||
bool Ok(void) { return index != NULL; }
|
bool Ok(void) { return index != NULL; }
|
||||||
bool Write(bool Independent, uint16_t FileNumber, off_t FileOffset);
|
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
|
// 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.
|
// 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 };
|
enum eRecordingsSortMode { rsmName, rsmTime };
|
||||||
extern eRecordingsSortMode RecordingsSortMode;
|
extern eRecordingsSortMode RecordingsSortMode;
|
||||||
|
14
vdr.1
14
vdr.1
@ -8,7 +8,7 @@
|
|||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" 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"
|
.TH vdr 1 "31 Mar 2013" "2.0" "Video Disk Recorder"
|
||||||
.SH NAME
|
.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
|
vdr can switch to a lesser privileged user id during normal
|
||||||
operation.
|
operation.
|
||||||
.TP
|
.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
|
.BI \-\-userdump
|
||||||
Allow coredumps if -u is given (only for debugging).
|
Allow coredumps if -u is given (only for debugging).
|
||||||
.TP
|
.TP
|
||||||
|
6
vdr.c
6
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.tvdr.de
|
* 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>
|
#include <getopt.h>
|
||||||
@ -269,6 +269,7 @@ int main(int argc, char *argv[])
|
|||||||
{ "shutdown", required_argument, NULL, 's' },
|
{ "shutdown", required_argument, NULL, 's' },
|
||||||
{ "split", no_argument, NULL, 's' | 0x100 },
|
{ "split", no_argument, NULL, 's' | 0x100 },
|
||||||
{ "terminal", required_argument, NULL, 't' },
|
{ "terminal", required_argument, NULL, 't' },
|
||||||
|
{ "updindex", required_argument, NULL, 'u' | 0x200 },
|
||||||
{ "user", required_argument, NULL, 'u' },
|
{ "user", required_argument, NULL, 'u' },
|
||||||
{ "userdump", no_argument, NULL, 'u' | 0x100 },
|
{ "userdump", no_argument, NULL, 'u' | 0x100 },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
@ -463,6 +464,8 @@ int main(int argc, char *argv[])
|
|||||||
case 'u' | 0x100:
|
case 'u' | 0x100:
|
||||||
UserDump = true;
|
UserDump = true;
|
||||||
break;
|
break;
|
||||||
|
case 'u' | 0x200:
|
||||||
|
return GenerateIndex(optarg, true) ? 0 : 2;
|
||||||
case 'V': DisplayVersion = true;
|
case 'V': DisplayVersion = true;
|
||||||
break;
|
break;
|
||||||
case 'v' | 0x100:
|
case 'v' | 0x100:
|
||||||
@ -569,6 +572,7 @@ int main(int argc, char *argv[])
|
|||||||
" -t TTY, --terminal=TTY controlling tty\n"
|
" -t TTY, --terminal=TTY controlling tty\n"
|
||||||
" -u USER, --user=USER run as user USER; only applicable if started as\n"
|
" -u USER, --user=USER run as user USER; only applicable if started as\n"
|
||||||
" root\n"
|
" root\n"
|
||||||
|
" --updindex=REC update index for recording REC and exit\n"
|
||||||
" --userdump allow coredumps if -u is given (debugging)\n"
|
" --userdump allow coredumps if -u is given (debugging)\n"
|
||||||
" -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
|
" -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
|
||||||
" -V, --version print version information and exit\n"
|
" -V, --version print version information and exit\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user