timeshift: add abs seek and proper 90kHz/1MHz conversions.
This commit is contained in:
parent
54e7e2ce5e
commit
eb6b33922e
5 changed files with 41 additions and 15 deletions
|
@ -1402,18 +1402,6 @@ htsp_method_skip(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
if(htsmsg_get_u32(in, "subscriptionId", &sid))
|
||||
return htsp_error("Missing argument 'subscriptionId'");
|
||||
|
||||
abs = htsmsg_get_u32_or_default(in, "absolute", 0);
|
||||
|
||||
if(!htsmsg_get_s64(in, "time", &s64)) {
|
||||
skip.type = abs ? SMT_SKIP_ABS_TIME : SMT_SKIP_REL_TIME;
|
||||
skip.time = s64;
|
||||
} else if (!htsmsg_get_s64(in, "size", &s64)) {
|
||||
skip.type = abs ? SMT_SKIP_ABS_SIZE : SMT_SKIP_REL_SIZE;
|
||||
skip.size = s64;
|
||||
} else {
|
||||
return htsp_error("Missing argument 'time' or 'size'");
|
||||
}
|
||||
|
||||
LIST_FOREACH(hs, &htsp->htsp_subscriptions, hs_link)
|
||||
if(hs->hs_sid == sid)
|
||||
break;
|
||||
|
@ -1421,6 +1409,18 @@ htsp_method_skip(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
if(hs == NULL)
|
||||
return htsp_error("Requested subscription does not exist");
|
||||
|
||||
abs = htsmsg_get_u32_or_default(in, "absolute", 0);
|
||||
|
||||
if(!htsmsg_get_s64(in, "time", &s64)) {
|
||||
skip.type = abs ? SMT_SKIP_ABS_TIME : SMT_SKIP_REL_TIME;
|
||||
skip.time = hs->hs_90khz ? s64 : ts_rescale_i(s64, 1000000);
|
||||
} else if (!htsmsg_get_s64(in, "size", &s64)) {
|
||||
skip.type = abs ? SMT_SKIP_ABS_SIZE : SMT_SKIP_REL_SIZE;
|
||||
skip.size = s64;
|
||||
} else {
|
||||
return htsp_error("Missing argument 'time' or 'size'");
|
||||
}
|
||||
|
||||
subscription_set_skip(hs->hs_s, &skip);
|
||||
|
||||
htsp_reply(htsp, in, htsmsg_create_map());
|
||||
|
@ -2445,7 +2445,7 @@ htsp_subscription_skip(htsp_subscription_t *hs, streaming_skip_t *skip)
|
|||
if (skip->type == SMT_SKIP_ERROR)
|
||||
htsmsg_add_u32(m, "error", 1);
|
||||
else if (skip->type == SMT_SKIP_ABS_TIME || skip->type == SMT_SKIP_REL_TIME)
|
||||
htsmsg_add_s64(m, "time", skip->time);
|
||||
htsmsg_add_s64(m, "time", hs->hs_90khz ? skip->time : ts_rescale(skip->time, 1000000));
|
||||
else if (skip->type == SMT_SKIP_ABS_SIZE || skip->type == SMT_SKIP_REL_SIZE)
|
||||
htsmsg_add_s64(m, "size", skip->size);
|
||||
htsp_send(hs->hs_htsp, m, NULL, &hs->hs_q, 0);
|
||||
|
|
|
@ -146,6 +146,13 @@ static void timeshift_input
|
|||
(sm->sm_type == SMT_STOP && sm->sm_code == 0))
|
||||
exit = 1;
|
||||
|
||||
/* Record (one-off) PTS delta */
|
||||
if (sm->sm_type == SMT_PACKET && ts->pts_delta == PTS_UNSET) {
|
||||
th_pkt_t *pkt = sm->sm_data;
|
||||
if (pkt->pkt_pts != PTS_UNSET)
|
||||
ts->pts_delta = getmonoclock() - ts_rescale(pkt->pkt_pts, 1000000);
|
||||
}
|
||||
|
||||
/* Buffer to disk */
|
||||
if ((ts->state > TS_LIVE) || (!ts->ondemand && (ts->state == TS_LIVE))) {
|
||||
sm->sm_time = getmonoclock();
|
||||
|
@ -230,6 +237,7 @@ streaming_target_t *timeshift_create
|
|||
ts->vididx = -1;
|
||||
ts->id = timeshift_index;
|
||||
ts->ondemand = timeshift_ondemand;
|
||||
ts->pts_delta = PTS_UNSET;
|
||||
pthread_mutex_init(&ts->rdwr_mutex, NULL);
|
||||
pthread_mutex_init(&ts->state_mutex, NULL);
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct timeshift {
|
|||
char *path; ///< Directory containing buffer
|
||||
time_t max_time; ///< Maximum period to shift
|
||||
int ondemand; ///< Whether this is an on-demand timeshift
|
||||
int64_t pts_delta; ///< Delta between system clock and PTS
|
||||
|
||||
enum {
|
||||
TS_INIT,
|
||||
|
|
|
@ -382,12 +382,23 @@ void *timeshift_reader ( void *p )
|
|||
} else if (ctrl->sm_type == SMT_SKIP) {
|
||||
skip = ctrl->sm_data;
|
||||
switch (skip->type) {
|
||||
case SMT_SKIP_ABS_TIME:
|
||||
if (ts->pts_delta == PTS_UNSET) {
|
||||
tvhlog(LOG_ERR, "timeshift", "ts %d abs skip not possible no PTS delta", ts->id);
|
||||
skip = NULL;
|
||||
break;
|
||||
}
|
||||
/* -fallthrough */
|
||||
case SMT_SKIP_REL_TIME:
|
||||
tvhlog(LOG_DEBUG, "timeshift", "ts %d skip %"PRId64" requested", ts->id, skip->time);
|
||||
|
||||
/* Convert */
|
||||
skip_time = ts_rescale(skip->time, 1000000);
|
||||
skip_time += (skip->type == SMT_SKIP_ABS_TIME) ? ts->pts_delta : last_time;
|
||||
|
||||
/* Must handle live playback case */
|
||||
if (ts->state == TS_LIVE) {
|
||||
if (skip->time < 0) {
|
||||
if (skip_time < now) {
|
||||
pthread_mutex_lock(&ts->rdwr_mutex);
|
||||
if ((cur_file = timeshift_filemgr_get(ts, ts->ondemand))) {
|
||||
ts->state = TS_PLAY;
|
||||
|
@ -408,9 +419,10 @@ void *timeshift_reader ( void *p )
|
|||
|
||||
/* OK */
|
||||
if (skip) {
|
||||
|
||||
/* Adjust time */
|
||||
play_time = now;
|
||||
pause_time = skip_time = last_time + skip->time;
|
||||
pause_time = skip_time;
|
||||
tsi = NULL;
|
||||
|
||||
/* Clear existing packet */
|
||||
|
|
|
@ -526,6 +526,11 @@ static inline int64_t ts_rescale(int64_t ts, int tb)
|
|||
return (ts * tb ) / 90000LL;
|
||||
}
|
||||
|
||||
static inline int64_t ts_rescale_i(int64_t ts, int tb)
|
||||
{
|
||||
return (ts * 90000LL) / tb;
|
||||
}
|
||||
|
||||
void sbuf_init(sbuf_t *sb);
|
||||
|
||||
void sbuf_free(sbuf_t *sb);
|
||||
|
|
Loading…
Add table
Reference in a new issue