static timeshift_index_iframe_t *_timeshift_last_frame ( timeshift_t *ts ) { int end; timeshift_index_iframe_t *tsi = NULL; timeshift_file_t *tsf = timeshift_filemgr_get(ts, 0); while (tsf && !tsi) { if (!(tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) { tsf = timeshift_filemgr_prev(tsf, &end, 0); } } if (tsf) tsf->refcount--; return tsi; }
static int _timeshift_skip ( timeshift_t *ts, int64_t req_time, int64_t cur_time, timeshift_file_t *cur_file, timeshift_file_t **new_file, timeshift_index_iframe_t **iframe ) { timeshift_index_iframe_t *tsi = *iframe; timeshift_file_t *tsf = cur_file, *tsf_last; int64_t sec = req_time / (1000000 * TIMESHIFT_FILE_PERIOD); int back = (req_time < cur_time) ? 1 : 0; int end = 0; /* Hold local ref */ if (cur_file) cur_file->refcount++; /* Coarse search */ if (!tsi) { while (tsf && !end) { if (back) { if ((tsf->time <= sec) && (tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) break; tsf = timeshift_filemgr_prev(tsf, &end, 1); } else { if ((tsf->time >= sec) && (tsi = TAILQ_FIRST(&tsf->iframes))) break; tsf = timeshift_filemgr_next(tsf, &end, 0); } tsi = NULL; } } /* Fine search */ if (back) { while (!end && tsf && tsi && (tsi->time > req_time)) { tsi = TAILQ_PREV(tsi, timeshift_index_iframe_list, link); while (!end && tsf && !tsi) { if ((tsf = timeshift_filemgr_prev(tsf, &end, 1))) tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list); } } } else { while (!end && tsf && tsi && (tsi->time < req_time)) { tsi = TAILQ_NEXT(tsi, link); while (!end && tsf && !tsi) { if ((tsf = timeshift_filemgr_next(tsf, &end, 0))) tsi = TAILQ_FIRST(&tsf->iframes); } } } /* End */ if (!tsf || !tsi) end = 1; /* Find start/end of buffer */ if (end) { if (back) { tsf = tsf_last = timeshift_filemgr_oldest(ts); tsi = NULL; while (tsf && !tsi) { tsf_last = tsf; if (!(tsi = TAILQ_FIRST(&tsf->iframes))) tsf = timeshift_filemgr_next(tsf, &end, 0); } if (!tsf) tsf = tsf_last; end = -1; } else { tsf = tsf_last = timeshift_filemgr_get(ts, 0); tsi = NULL; while (tsf && !tsi) { tsf_last = tsf; if (!(tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) tsf = timeshift_filemgr_prev(tsf, &end, 0); } if (!tsf) tsf = tsf_last; end = 1; } } if (cur_file) cur_file->refcount--; /* Done */ *new_file = tsf; *iframe = tsi; return end; }
static int _timeshift_skip ( timeshift_t *ts, int64_t req_time, int64_t cur_time, timeshift_seek_t *seek, timeshift_seek_t *nseek ) { timeshift_index_iframe_t *tsi = seek->frame; timeshift_file_t *tsf = seek->file, *tsf_last; int64_t sec = mono2sec(req_time) / TIMESHIFT_FILE_PERIOD; int back = (req_time < cur_time) ? 1 : 0; int end = 0; /* Coarse search */ if (!tsi) { while (tsf && !end) { if (back) { if ((tsf->time <= sec) && (tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) break; tsf = timeshift_filemgr_prev(tsf, &end, 1); } else { if ((tsf->time >= sec) && (tsi = TAILQ_FIRST(&tsf->iframes))) break; tsf = timeshift_filemgr_next(tsf, &end, 0); } tsi = NULL; } } /* Fine search */ if (back) { while (!end && tsf && tsi && (tsi->time > req_time)) { tsi = TAILQ_PREV(tsi, timeshift_index_iframe_list, link); while (!end && tsf && !tsi) { if ((tsf = timeshift_filemgr_prev(tsf, &end, 1))) tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list); } } } else { while (!end && tsf && tsi && (tsi->time < req_time)) { tsi = TAILQ_NEXT(tsi, link); while (!end && tsf && !tsi) { if ((tsf = timeshift_filemgr_next(tsf, &end, 0))) tsi = TAILQ_FIRST(&tsf->iframes); } } } /* End */ if (!tsf || !tsi) end = 1; /* Find start/end of buffer */ if (end) { timeshift_file_put(tsf); if (back) { tsf = tsf_last = timeshift_filemgr_oldest(ts); tsi = NULL; while (tsf && !tsi) { tsf_last = tsf; if (!(tsi = TAILQ_FIRST(&tsf->iframes))) tsf = timeshift_filemgr_next(tsf, &end, 0); } if (!tsf) tsf = tsf_last; end = -1; } else { tsf = tsf_last = timeshift_filemgr_newest(ts); tsi = NULL; while (tsf && !tsi) { tsf_last = tsf; if (!(tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) tsf = timeshift_filemgr_prev(tsf, &end, 0); } if (!tsf) tsf = tsf_last; end = 1; } } /* Done */ nseek->file = tsf; nseek->frame = tsi; return end; }