[feature,request] recording length computation and storage
Commit Message
On 19.08.2011 23:56, Steffen Barszus wrote:
> On Fri, 19 Aug 2011 22:18:03 +0200
> Udo Richter<udo_richter@gmx.de> wrote:
>
>> Am 19.08.2011 15:30, schrieb Steffen Barszus:
>>>>>> On 08/19/11 11:46, Steffen Barszus wrote:
>>>>>>> i would like to request, that
>>>>>>> vdr is storing the length of a recording and make it accessible
>>>>>>> to the plug-ins.
>>>
>>> Where it gets stored is not my point, that it can be served from in
>>> meory data read by ScanVideoDir is my point.
>>>
>>> - read&compute by the core
>>> - dont access harddisk for known recordings
>>> - dont do it multiple times, if more then one part of vdr wants to
>>> know it.
>>>
>>> If its only in memory and read by the scanner its fine with me.
>>>
>>> for medium to large recording base we speak about minutes not
>>> milliseconds for reading that data.
>>
>>
>> Maybe some kind of caching mechanism, but please don't calculate the
>> length every time while doing the scan of the video directory. The
>> directory scanner is already slow enough, no need to add these minutes
>> to it.
>
> It's slow since it needs to iterate through all recordings
> and check file size of the index file (thats what i understand from
> Klaus comment), so divide that by number of frames of the recording and
> thats it. the directory scanner is anyway doing the same (iterating
> the video directory and pick up necessary information). So it wouldn't
> add anything substantially.
Would the attached patch work for you?
Line numbers may be off a little.
Klaus
Comments
On Sun, 21 Aug 2011 15:45:18 +0200
Klaus Schmidinger <Klaus.Schmidinger@tvdr.de> wrote:
> On 19.08.2011 23:56, Steffen Barszus wrote:
> > It's slow since it needs to iterate through all recordings
> > and check file size of the index file (thats what i understand from
> > Klaus comment), so divide that by number of frames of the recording
> > and thats it. the directory scanner is anyway doing the same
> > (iterating the video directory and pick up necessary information).
> > So it wouldn't add anything substantially.
>
> Would the attached patch work for you?
> Line numbers may be off a little.
Tested and looks good to me. Shows the correct result, where possible,
no delay in getting the result and doesnt crash on strange recordings.
Perfect :)
Would love to see this in next developer version :)
@@ -89,6 +89,7 @@
mutable char *fileName;
mutable char *name;
mutable int fileSizeMB;
+ mutable int numFrames;
int channel;
int instanceId;
bool isPesRecording;
@@ -123,6 +124,11 @@
int HierarchyLevels(void) const;
void ResetResume(void) const;
double FramesPerSecond(void) const { return framesPerSecond; }
+ int NumFrames(void) const;
+ ///< Returns the number of frames in this recording.
+ ///< If the number of frames is unknown, -1 will be returned.
+ int LengthInSeconds(void) const;
+ ///< Returns the length (in seconds) of this recording, or -1 in case of error.
bool IsNew(void) const { return GetResume() <= 0; }
bool IsEdited(void) const;
bool IsPesRecording(void) const { return isPesRecording; }
@@ -60,6 +60,7 @@
#define DISKCHECKDELTA 100 // seconds between checks for free disk space
#define REMOVELATENCY 10 // seconds to wait until next check after removing a file
#define MARKSUPDATEDELTA 10 // seconds between checks for updating editing marks
+#define MININDEXAGE 3600 // seconds before an index file is considered no longer to be written
#define MAX_SUBTITLE_LENGTH 40
@@ -617,6 +618,7 @@
instanceId = InstanceId;
isPesRecording = false;
framesPerSecond = DEFAULTFRAMESPERSECOND;
+ numFrames = -1;
deleted = 0;
// set up the actual name:
const char *Title = Event ? Event->Title() : NULL;
@@ -676,6 +678,7 @@
lifetime = MAXLIFETIME;
isPesRecording = false;
framesPerSecond = DEFAULTFRAMESPERSECOND;
+ numFrames = -1;
deleted = 0;
titleBuffer = NULL;
sortBuffer = NULL;
@@ -1031,6 +1034,25 @@
resume = RESUME_NOT_INITIALIZED;
}
+int cRecording::NumFrames(void) const
+{
+ if (numFrames < 0) {
+ int nf = cIndexFile::GetLength(FileName(), IsPesRecording());
+ if (time(NULL) - LastModifiedTime(FileName()) < MININDEXAGE)
+ return nf; // check again later for ongoing recordings
+ numFrames = nf;
+ }
+ return numFrames;
+}
+
+int cRecording::LengthInSeconds(void) const
+{
+ int nf = NumFrames();
+ if (nf >= 0)
+ return int((nf / FramesPerSecond() + 30) / 60) * 60;
+ return -1;
+}
+
// --- cRecordings -----------------------------------------------------------
cRecordings Recordings;
@@ -1102,6 +1124,7 @@
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
cRecording *r = new cRecording(buffer);
if (r->Name()) {
+ r->NumFrames(); // initializes the numFrames member
Lock();
Add(r);
ChangeState();
@@ -1514,9 +1537,6 @@
// The maximum time to wait before giving up while catching up on an index file:
#define MAXINDEXCATCHUP 8 // seconds
-// The minimum age of an index file for considering it no longer to be written:
-#define MININDEXAGE 3600 // seconds
-
struct tIndexPes {
uint32_t offset;
uchar type;