[feature,request] recording length computation and storage

Message ID 4E510BEE.8090705@tvdr.de
State New
Headers

Commit Message

Klaus Schmidinger Aug. 21, 2011, 1:45 p.m. UTC
  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

Steffen Barszus Aug. 23, 2011, 4:54 p.m. UTC | #1
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 :)
  

Patch

--- recording.h	2011/08/21 11:34:03	2.24
+++ recording.h	2011/08/21 13:10:39
@@ -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; }
--- recording.c	2011/08/21 11:19:55	2.35
+++ recording.c	2011/08/21 13:43:03
@@ -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;