Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
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;
}