From acebb13f153fb0b53b6ccb94f440aee82fecc61e Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sun, 23 Dec 2012 21:33:17 +0000 Subject: [PATCH] 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. --- src/timeshift.c | 6 ++---- src/timeshift/private.h | 1 + src/timeshift/timeshift_filemgr.c | 20 ++++++++++++++++++-- src/timeshift/timeshift_reader.c | 16 +++++++++++++++- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/timeshift.c b/src/timeshift.c index 14cee0d1..afd4237a 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 133eb695..ed64a12f 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 3562393f..44571048 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 25968f24..ab57cdff 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);