Beispiel #1
0
/**
 * Allocate a new packet and give it a refcount of one (which caller is
 * suppoed to take care of)
 */
th_pkt_t *
pkt_alloc(streaming_component_type_t type, const uint8_t *data, size_t datalen,
          int64_t pts, int64_t dts, int64_t pcr)
{
  th_pkt_t *pkt;
  pktbuf_t *payload;

  if (datalen > 0) {
    payload = pktbuf_alloc(data, datalen);
    if (payload == NULL)
      return NULL;
  } else {
    payload = NULL;
  }

  pkt = calloc(1, sizeof(th_pkt_t));
  if (pkt) {
    pkt->pkt_type = type;
    pkt->pkt_payload = payload;
    pkt->pkt_dts = dts;
    pkt->pkt_pts = pts;
    pkt->pkt_pcr = pcr;
    pkt->pkt_refcount = 1;
    memoryinfo_alloc(&pkt_memoryinfo, sizeof(*pkt));
  } else {
    if (payload)
      pktbuf_ref_dec(payload);
  }
  return pkt;
}
Beispiel #2
0
pktbuf_t *
pktbuf_alloc(const uint8_t *data, size_t size)
{
  pktbuf_t *pb;
  uint8_t *buffer;

  buffer = size > 0 ? malloc(size) : NULL;
  if (buffer) {\
    if (data != NULL)
      memcpy(buffer, data, size);
  } else if (size > 0) {
    return NULL;
  }
  pb = malloc(sizeof(pktbuf_t));
  if (pb == NULL) {
    free(buffer);
    return NULL;
  }
  pb->pb_refcount = 1;
  pb->pb_data = buffer;
  pb->pb_size = size;
  pb->pb_err = 0;
  memoryinfo_alloc(&pktbuf_memoryinfo, sizeof(*pb) + size);
  return pb;
}
Beispiel #3
0
/*
 * Stream start handling
 */
static void _handle_sstart ( timeshift_t *ts, timeshift_file_t *tsf, streaming_message_t *sm )
{
  timeshift_index_data_t *ti = calloc(1, sizeof(timeshift_index_data_t));

  memoryinfo_alloc(&timeshift_memoryinfo, sizeof(*ti));
  ti->pos  = tsf->size;
  ti->data = sm;
  TAILQ_INSERT_TAIL(&tsf->sstart, ti, link);
}
Beispiel #4
0
th_pktref_t *
pktref_create(th_pkt_t *pkt)
{
  th_pktref_t *pr = malloc(sizeof(th_pktref_t));
  if (pr) {
    pr->pr_pkt = pkt;
    memoryinfo_alloc(&pktref_memoryinfo, sizeof(*pr));
  }
  return pr;
}
Beispiel #5
0
/**
 * Reference count is transfered to queue
 */
void
pktref_enqueue(struct th_pktref_queue *q, th_pkt_t *pkt)
{
  th_pktref_t *pr = malloc(sizeof(th_pktref_t));
  if (pr) {
    pr->pr_pkt = pkt;
    TAILQ_INSERT_TAIL(q, pr, pr_link);
    memoryinfo_alloc(&pktref_memoryinfo, sizeof(*pr));
  }
}
Beispiel #6
0
tasklet_t *
tasklet_arm_alloc(tsk_callback_t *callback, void *opaque)
{
  tasklet_t *tsk = calloc(1, sizeof(*tsk));
  if (tsk) {
    memoryinfo_alloc(&tasklet_memoryinfo, sizeof(*tsk));
    tsk->tsk_free = free;
    tasklet_arm(tsk, callback, opaque);
  }
  return tsk;
}
Beispiel #7
0
/**
 * Reference count is transfered to queue
 */
void
pktref_enqueue_sorted(struct th_pktref_queue *q, th_pkt_t *pkt,
                      int (*cmp)(const void *, const void *))
{
  th_pktref_t *pr = malloc(sizeof(th_pktref_t));
  if (pr) {
    pr->pr_pkt = pkt;
    TAILQ_INSERT_SORTED(q, pr, pr_link, cmp);
    memoryinfo_alloc(&pktref_memoryinfo, sizeof(*pr));
  }
}
Beispiel #8
0
streaming_message_t *
streaming_msg_create(streaming_message_type_t type)
{
  streaming_message_t *sm = malloc(sizeof(streaming_message_t));
  memoryinfo_alloc(&streaming_msg_memoryinfo, sizeof(*sm));
  sm->sm_type = type;
#if ENABLE_TIMESHIFT
  sm->sm_time      = 0;
#endif
  return sm;
}
Beispiel #9
0
pktbuf_t *
pktbuf_make(void *data, size_t size)
{
  pktbuf_t *pb = malloc(sizeof(pktbuf_t));
  if (pb) {
    pb->pb_refcount = 1;
    pb->pb_size = size;
    pb->pb_data = data;
    memoryinfo_alloc(&pktbuf_memoryinfo, sizeof(*pb) + pb->pb_size);
  }
  return pb;
}
Beispiel #10
0
/**
 * Create timeshift buffer
 *
 * max_period of buffer in seconds (0 = unlimited)
 * max_size   of buffer in bytes   (0 = unlimited)
 */
streaming_target_t *timeshift_create
  (streaming_target_t *out, time_t max_time)
{
  timeshift_t *ts = calloc(1, sizeof(timeshift_t));

  memoryinfo_alloc(&timeshift_memoryinfo, sizeof(timeshift_t));

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Setup structure */
  TAILQ_INIT(&ts->files);
  ts->output     = out;
  ts->path       = NULL;
  ts->max_time   = max_time;
  ts->state      = TS_LIVE;
  ts->exit       = 0;
  ts->full       = 0;
  ts->vididx     = -1;
  ts->id         = timeshift_index;
  ts->ondemand   = timeshift_conf.ondemand;
  ts->dobuf      = ts->ondemand ? 0 : 1;
  ts->packet_mode= 1;
  ts->last_wr_time = 0;
  ts->buf_time   = 0;
  ts->start_pts  = 0;
  ts->ref_time   = 0;
  ts->seek.file  = NULL;
  ts->seek.frame = NULL;
  ts->ram_segments = 0;
  ts->file_segments = 0;
  pthread_mutex_init(&ts->state_mutex, NULL);

  /* Initialise output */
  tvh_pipe(O_NONBLOCK, &ts->rd_pipe);

  /* Initialise input */
  streaming_queue_init(&ts->wr_queue, 0, 0);
  streaming_target_init(&ts->input, &timeshift_input_ops, ts, 0);
  tvhthread_create(&ts->wr_thread, NULL, timeshift_writer, ts, "tshift-wr");
  tvhthread_create(&ts->rd_thread, NULL, timeshift_reader, ts, "tshift-rd");

  /* Update index */
  timeshift_index++;

  return &ts->input;
}
Beispiel #11
0
th_pkt_t *
pkt_copy_nodata(th_pkt_t *pkt)
{
  th_pkt_t *n = malloc(sizeof(th_pkt_t));

  if (n) {
    blacklisted_memcpy(n, pkt, sizeof(*pkt));

    n->pkt_refcount = 1;

    n->pkt_meta = n->pkt_payload = NULL;

    memoryinfo_alloc(&pkt_memoryinfo, sizeof(*pkt));
  }

  return n;
}
Beispiel #12
0
th_pkt_t *
pkt_copy_shallow(th_pkt_t *pkt)
{
  th_pkt_t *n = malloc(sizeof(th_pkt_t));

  if (n) {
    blacklisted_memcpy(n, pkt, sizeof(*pkt));

    n->pkt_refcount = 1;

    pktbuf_ref_inc(n->pkt_meta);
    pktbuf_ref_inc(n->pkt_payload);

    memoryinfo_alloc(&pkt_memoryinfo, sizeof(*pkt));
  }

  return n;
}
Beispiel #13
0
static inline ssize_t _process_msg0
  ( timeshift_t *ts, timeshift_file_t *tsf, streaming_message_t *sm )
{
  ssize_t err;

  if (sm->sm_type == SMT_START) {
    err = 0;
    _handle_sstart(ts, tsf, streaming_msg_clone(sm));
  } else if (sm->sm_type == SMT_SIGNAL_STATUS)
    err = timeshift_write_sigstat(tsf, sm->sm_time, sm->sm_data);
  else if (sm->sm_type == SMT_PACKET) {
    err = timeshift_write_packet(tsf, sm->sm_time, sm->sm_data);
    if (err > 0) {
      th_pkt_t *pkt = sm->sm_data;

      /* Index video iframes */
      if (pkt->pkt_componentindex == ts->vididx &&
          pkt->pkt_frametype      == PKT_I_FRAME) {
        timeshift_index_iframe_t *ti = calloc(1, sizeof(timeshift_index_iframe_t));
        memoryinfo_alloc(&timeshift_memoryinfo, sizeof(*ti));
        ti->pos  = tsf->size;
        ti->time = sm->sm_time;
        TAILQ_INSERT_TAIL(&tsf->iframes, ti, link);
      }
    }
  } else if (sm->sm_type == SMT_MPEGTS) {
    err = timeshift_write_mpegts(tsf, sm->sm_time, sm->sm_data);
  }
  else
    err = 0;

  /* OK */
  if (err > 0) {
    tsf->last  = sm->sm_time;
    tsf->size += err;
    atomic_add_u64(&timeshift_total_size, err);
    if (tsf->ram)
      atomic_add_u64(&timeshift_total_ram_size, err);
  }
  return err;
}
Beispiel #14
0
streaming_message_t *
streaming_msg_clone(streaming_message_t *src)
{
  streaming_message_t *dst = malloc(sizeof(streaming_message_t));
  streaming_start_t *ss;

  memoryinfo_alloc(&streaming_msg_memoryinfo, sizeof(*dst));

  dst->sm_type      = src->sm_type;
#if ENABLE_TIMESHIFT
  dst->sm_time      = src->sm_time;
#endif

  switch(src->sm_type) {

  case SMT_PACKET:
    pkt_ref_inc(src->sm_data);
    dst->sm_data = src->sm_data;
    break;

  case SMT_START:
    ss = dst->sm_data = src->sm_data;
    streaming_start_ref(ss);
    break;

  case SMT_SKIP:
    dst->sm_data = malloc(sizeof(streaming_skip_t));
    memcpy(dst->sm_data, src->sm_data, sizeof(streaming_skip_t));
    break;

  case SMT_SIGNAL_STATUS:
    dst->sm_data = malloc(sizeof(signal_status_t));
    memcpy(dst->sm_data, src->sm_data, sizeof(signal_status_t));
    break;

  case SMT_DESCRAMBLE_INFO:
    dst->sm_data = malloc(sizeof(descramble_info_t));
    memcpy(dst->sm_data, src->sm_data, sizeof(descramble_info_t));
    break;

  case SMT_TIMESHIFT_STATUS:
    dst->sm_data = malloc(sizeof(timeshift_status_t));
    memcpy(dst->sm_data, src->sm_data, sizeof(timeshift_status_t));
    break;

  case SMT_GRACE:
  case SMT_SPEED:
  case SMT_STOP:
  case SMT_SERVICE_STATUS:
  case SMT_NOSTART:
  case SMT_NOSTART_WARN:
    dst->sm_code = src->sm_code;
    break;

  case SMT_EXIT:
    break;

  case SMT_MPEGTS:
    pktbuf_ref_inc(src->sm_data);
    dst->sm_data = src->sm_data;
    break;

  default:
    abort();
  }
  return dst;
}