From: Adam Sutton Date: Sun, 23 Dec 2012 21:33:17 +0000 (+0000) Subject: timeshift: Added on-demand buffer mode. X-Git-Tag: v3.5~139 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=acebb13f153fb0b53b6ccb94f440aee82fecc61e;p=thirdparty%2Ftvheadend.git timeshift: Added on-demand buffer mode. 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. --- diff --git a/src/timeshift.c b/src/timeshift.c index 14cee0d1d..afd4237a3 100644 --- a/src/timeshift.c +++ b/src/timeshift.c @@ -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); diff --git a/src/timeshift/private.h b/src/timeshift/private.h index 133eb6954..ed64a12ff 100644 --- a/src/timeshift/private.h +++ b/src/timeshift/private.h @@ -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__ */ diff --git a/src/timeshift/timeshift_filemgr.c b/src/timeshift/timeshift_filemgr.c index 3562393f4..445710487 100644 --- a/src/timeshift/timeshift_filemgr.c +++ b/src/timeshift/timeshift_filemgr.c @@ -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); diff --git a/src/timeshift/timeshift_reader.c b/src/timeshift/timeshift_reader.c index 25968f241..ab57cdff2 100644 --- a/src/timeshift/timeshift_reader.c +++ b/src/timeshift/timeshift_reader.c @@ -29,6 +29,8 @@ #include #include +//#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);