/* * Output packet */ static int _timeshift_read ( timeshift_t *ts, timeshift_file_t **cur_file, off_t *cur_off, int *fd, streaming_message_t **sm, int *wait ) { if (*cur_file) { /* Open file */ if (*fd == -1) { tvhtrace("timeshift", "ts %d open file %s", ts->id, (*cur_file)->path); *fd = open((*cur_file)->path, O_RDONLY); } tvhtrace("timeshift", "ts %d seek to %"PRIoff_t, ts->id, *cur_off); lseek(*fd, *cur_off, SEEK_SET); /* Read msg */ ssize_t r = _read_msg(*fd, sm); if (r < 0) { streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); streaming_target_deliver2(ts->output, e); tvhlog(LOG_ERR, "timeshift", "ts %d could not read buffer", ts->id); return -1; } tvhtrace("timeshift", "ts %d read msg %p (%"PRIssize_t")", ts->id, *sm, r); /* Incomplete */ if (r == 0) { lseek(*fd, *cur_off, SEEK_SET); return 0; } /* Update */ *cur_off += r; /* Special case - EOF */ if (r == sizeof(size_t) || *cur_off > (*cur_file)->size) { close(*fd); *fd = -1; pthread_mutex_lock(&ts->rdwr_mutex); *cur_file = timeshift_filemgr_next(*cur_file, NULL, 0); pthread_mutex_unlock(&ts->rdwr_mutex); *cur_off = 0; // reset *wait = 0; /* Check SMT_START index */ } else { streaming_message_t *ssm = _timeshift_find_sstart(*cur_file, (*sm)->sm_time); if (ssm && ssm->sm_data != ts->smt_start) { streaming_target_deliver2(ts->output, streaming_msg_clone(ssm)); if (ts->smt_start) streaming_start_unref(ts->smt_start); ts->smt_start = ssm->sm_data; atomic_add(&ts->smt_start->ss_refcount, 1); } } } return 0; }
/* * Output packet */ static int _timeshift_read ( timeshift_t *ts, timeshift_file_t **cur_file, streaming_message_t **sm, int *wait ) { timeshift_file_t *tsf = *cur_file; ssize_t r; off_t off, ooff; if (tsf) { /* Open file */ if (tsf->rfd < 0 && !tsf->ram) { tsf->rfd = open(tsf->path, O_RDONLY); tvhtrace("timeshift", "ts %d open file %s (fd %i)", ts->id, tsf->path, tsf->rfd); if (tsf->rfd < 0) return -1; } if (tsf->rfd >= 0) if ((off = lseek(tsf->rfd, tsf->roff, SEEK_SET)) != tsf->roff) tvherror("timeshift", "ts %d seek to %s failed (off %"PRId64" != %"PRId64"): %s", ts->id, tsf->path, (int64_t)tsf->roff, (int64_t)off, strerror(errno)); /* Read msg */ ooff = tsf->roff; r = _read_msg(tsf, -1, sm); if (r < 0) { streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); streaming_target_deliver2(ts->output, e); tvhtrace("timeshift", "ts %d seek to %jd (fd %i)", ts->id, (intmax_t)tsf->roff, tsf->rfd); tvhlog(LOG_ERR, "timeshift", "ts %d could not read buffer", ts->id); return -1; } tvhtrace("timeshift", "ts %d seek to %jd (fd %i) read msg %p (%"PRId64")", ts->id, (intmax_t)tsf->roff, tsf->rfd, *sm, (int64_t)r); /* Incomplete */ if (r == 0) { if (tsf->rfd >= 0) { tvhtrace("timeshift", "ts %d seek to %jd (fd %i) (incomplete)", ts->id, (intmax_t)tsf->roff, tsf->rfd); if ((off = lseek(tsf->rfd, ooff, SEEK_SET)) != ooff) tvherror("timeshift", "seek to %s failed (off %"PRId64" != %"PRId64"): %s", tsf->path, (int64_t)ooff, (int64_t)off, strerror(errno)); } tsf->roff = ooff; return 0; } /* Special case - EOF */ if (r == sizeof(size_t) || tsf->roff > tsf->size) { if (tsf->rfd >= 0) close(tsf->rfd); tsf->rfd = -1; pthread_mutex_lock(&ts->rdwr_mutex); *cur_file = timeshift_filemgr_next(tsf, NULL, 0); pthread_mutex_unlock(&ts->rdwr_mutex); tsf->roff = 0; // reset *wait = 0; /* Check SMT_START index */ } else { streaming_message_t *ssm = _timeshift_find_sstart(*cur_file, (*sm)->sm_time); if (ssm && ssm->sm_data != ts->smt_start) { streaming_target_deliver2(ts->output, streaming_msg_clone(ssm)); if (ts->smt_start) streaming_start_unref(ts->smt_start); ts->smt_start = ssm->sm_data; atomic_add(&ts->smt_start->ss_refcount, 1); } } } return 0; }