]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
timeshift: Added on-demand buffer mode.
authorAdam Sutton <dev@adamsutton.me.uk>
Sun, 23 Dec 2012 21:33:17 +0000 (21:33 +0000)
committerAdam Sutton <dev@adamsutton.me.uk>
Wed, 9 Jan 2013 21:26:52 +0000 (21:26 +0000)
In this mode data will only be written to disk when paused and anything
in the buffer prior to the current play point will immediately be removed.

This implies that rewinding is never possible in this mode (though FF is)
and trying to do so will result in the buffer playback being paused.

src/timeshift.c
src/timeshift/private.h
src/timeshift/timeshift_filemgr.c
src/timeshift/timeshift_reader.c

index 14cee0d1d6c391e6f337e83307fcb67f6a4076a2..afd4237a361f271f2b1ab15445c7662d7fb4eb18 100644 (file)
@@ -147,7 +147,7 @@ static void timeshift_input
       exit = 1;
 
     /* Buffer to disk */
-    if (ts->state >= TS_LIVE) {
+    if ((ts->state > TS_LIVE) || (!ts->ondemand && (ts->state == TS_LIVE))) {
       sm->sm_time = getmonoclock();
       streaming_target_deliver2(&ts->wr_queue.sq_st, sm);
     } else
@@ -170,7 +170,6 @@ void
 timeshift_destroy(streaming_target_t *pad)
 {
   timeshift_t *ts = (timeshift_t*)pad;
-  timeshift_file_t *tsf;
   streaming_message_t *sm;
 
   /* Must hold global lock */
@@ -193,8 +192,7 @@ timeshift_destroy(streaming_target_t *pad)
   close(ts->rd_pipe.wr);
 
   /* Flush files */
-  while ((tsf = TAILQ_FIRST(&ts->files)))
-    timeshift_filemgr_remove(ts, tsf, 1);
+  timeshift_filemgr_flush(ts, NULL);
 
   free(ts->path);
   free(ts);
index 133eb6954c90b4ecbe3118ede8159c59acfbd89c..ed64a12ffa86358525674eb219e12c2f5746c14b 100644 (file)
@@ -141,6 +141,7 @@ timeshift_file_t *timeshift_filemgr_next
   ( timeshift_file_t *ts, int *end, int keep );
 void timeshift_filemgr_remove
   ( timeshift_t *ts, timeshift_file_t *tsf, int force );
+void timeshift_filemgr_flush ( timeshift_t *ts, timeshift_file_t *end );
 void timeshift_filemgr_close ( timeshift_file_t *tsf );
 
 #endif /* __TVH_TIMESHIFT_PRIVATE_H__ */
index 3562393f4c61ac3283f179e7f10e54a1770c840d..44571048768917ede9993c7e3b9d1fd750321a90 100644 (file)
@@ -117,9 +117,12 @@ static void timeshift_reaper_remove ( timeshift_file_t *tsf )
 static void timeshift_filemgr_get_root ( char *buf, size_t len )
 {
   const char *path = timeshift_path;
-  if (!path || !*path)
+  if (!path || !*path) {
     path = hts_settings_get_root();
-  snprintf(buf, len, "%s/timeshift/temp", path);
+    snprintf(buf, len, "%s/timeshift/buffer", path);
+  } else {
+    snprintf(buf, len, "%s/buffer", path);
+  }
 }
 
 /*
@@ -156,6 +159,18 @@ void timeshift_filemgr_remove
   timeshift_reaper_remove(tsf);
 }
 
+/*
+ * Flush all files
+ */
+void timeshift_filemgr_flush ( timeshift_t *ts, timeshift_file_t *end )
+{
+  timeshift_file_t *tsf;
+  while ((tsf = TAILQ_FIRST(&ts->files))) {
+    if (tsf == end) break;
+    timeshift_filemgr_remove(ts, tsf, 1);
+  }
+}
+
 /*
  * Get current / new file
  */
@@ -216,6 +231,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int create )
         tsf_tmp->fd       = fd;
         tsf_tmp->path     = strdup(path);
         tsf_tmp->refcount = 0;
+        tsf_tmp->last     = getmonoclock();
         TAILQ_INIT(&tsf_tmp->iframes);
         TAILQ_INIT(&tsf_tmp->sstart);
         TAILQ_INSERT_TAIL(&ts->files, tsf_tmp, link);
index 25968f241dd4bafa3851eedda335c18c33bacfc0..ab57cdff2c75fb1ff241910ca5fef6d2b92b162a 100644 (file)
@@ -29,6 +29,8 @@
 #include <string.h>
 #include <assert.h>
 
+//#define TSHFT_TRACE
+
 /* **************************************************************************
  * File Reading
  * *************************************************************************/
@@ -223,6 +225,10 @@ void *timeshift_reader ( void *p )
           if (speed > 3200)  speed = 3200;
           if (speed < -3200) speed = -3200;
 
+          /* Ignore negative */
+          if (ts->ondemand && (speed < 0))
+            speed = 0;
+
           /* Process */
           if (cur_speed != speed) {
 
@@ -241,7 +247,7 @@ void *timeshift_reader ( void *p )
                        ts->id);
                 timeshift_writer_flush(ts);
                 pthread_mutex_lock(&ts->rdwr_mutex);
-                if ((cur_file   = timeshift_filemgr_get(ts, 0))) {
+                if ((cur_file   = timeshift_filemgr_get(ts, ts->ondemand))) {
                   cur_off    = cur_file->size;
                   pause_time = cur_file->last;
                   last_time  = pause_time;
@@ -467,6 +473,10 @@ void *timeshift_reader ( void *p )
         ctrl      = streaming_msg_create_code(SMT_SPEED, cur_speed);
         streaming_target_deliver2(ts->output, ctrl);
 
+        /* Flush ALL files */
+        if (ts->ondemand)
+          timeshift_filemgr_flush(ts, NULL);
+
       /* Pause */
       } else if (cur_speed < 0) {
         tvhlog(LOG_DEBUG, "timeshift", "ts %d sob pause stream", ts->id);
@@ -475,6 +485,10 @@ void *timeshift_reader ( void *p )
         ctrl      = streaming_msg_create_code(SMT_SPEED, cur_speed);
         streaming_target_deliver2(ts->output, ctrl);
       }
+
+    /* Flush unwanted */
+    } else if (ts->ondemand && cur_file) {
+      timeshift_filemgr_flush(ts, cur_file);
     }
 
     pthread_mutex_unlock(&ts->rdwr_mutex);