예제 #1
0
파일: download.c 프로젝트: Ferni7/tvheadend
static int
download_pipe(download_t *dn, const char *args)
{
  char **argv = NULL;
  int r;

  download_pipe_close(dn);
  gtimer_disarm(&dn->pipe_read_timer);

  /* Arguments */
  if (spawn_parse_args(&argv, 64, args, NULL)) {
    tvherror(dn->log, "pipe: unable to parse arguments (%s)", args);
    return -1;
  }

  /* Grab */
  r = spawn_and_give_stdout(argv[0], argv, NULL, &dn->pipe_fd, &dn->pipe_pid, 1);

  spawn_free_args(argv);

  if (r < 0) {
    dn->pipe_fd = -1;
    dn->pipe_pid = 0;
    tvherror(dn->log, "pipe: cannot start (%s)", args);
    return -1;
  }

  fcntl(dn->pipe_fd, F_SETFL, fcntl(dn->pipe_fd, F_GETFL) | O_NONBLOCK);

  gtimer_arm_ms(&dn->pipe_read_timer, download_pipe_read, dn, 250);
  return 0;
}
예제 #2
0
/*
 * Complete data
 */
static int
iptv_http_complete
  ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  char *url;
  url_t u;
  int r;

  if (im->im_m3u_header) {
    im->im_m3u_header = 0;
    sbuf_append(&im->mm_iptv_buffer, "", 1);
    url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data);
    sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
    if (url == NULL) {
      tvherror("iptv", "m3u contents parsing failed");
      return 0;
    }
    urlinit(&u);
    if (!urlparse(url, &u)) {
      hc->hc_keepalive = 0;
      r = http_client_simple_reconnect(hc, &u);
      if (r < 0)
        tvherror("iptv", "cannot reopen http client: %d'", r);
    } else {
      tvherror("iptv", "m3u url invalid '%s'", url);
    }
    urlreset(&u);
    free(url);
    return 0;
  }
  return 0;
}
예제 #3
0
static int
lav_muxer_open_file(muxer_t *m, const char *filename)
{
  AVFormatContext *oc;
  lav_muxer_t *lm = (lav_muxer_t*)m;
  char buf[256];
  int r;

  oc = lm->lm_oc;
  snprintf(oc->filename, sizeof(oc->filename), "%s", filename);

  if((r = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
    av_strerror(r, buf, sizeof(buf));
    tvherror(LS_LIBAV,  "%s: Could not open -- %s", filename, buf);
    lm->m_errors++;
    return -1;
  }

  /* bypass umask settings */
  if (chmod(filename, lm->m_config.m_file_permissions))
    tvherror(LS_LIBAV, "%s: Unable to change permissions -- %s",
             filename, strerror(errno));

  return 0;
}
예제 #4
0
파일: download.c 프로젝트: Ferni7/tvheadend
static void
download_fetch(void *aux)
{
  download_t *dn = aux;
  http_client_t *hc;
  url_t u;

  urlinit(&u);

  if (dn->url == NULL)
    goto done;

  if (strncmp(dn->url, "file://", 7) == 0) {
    download_file(dn, dn->url + 7);
    goto done;
  }

  if (strncmp(dn->url, "pipe://", 7) == 0) {
    download_pipe(dn, dn->url + 7);
    goto done;
  }

  if (dn->http_client) {
    http_client_close(dn->http_client);
    dn->http_client = NULL;
  }

  if (urlparse(dn->url, &u) < 0) {
    tvherror(dn->log, "wrong url");
    goto stop;
  }
  hc = http_client_connect(dn, HTTP_VERSION_1_1, u.scheme, u.host, u.port, NULL);
  if (hc == NULL) {
    tvherror(dn->log, "unable to open http client");
    goto stop;
  }
  hc->hc_handle_location = 1;
  hc->hc_data_limit = 1024*1024;
  hc->hc_data_complete = download_fetch_complete;
  http_client_register(hc);
  http_client_ssl_peer_verify(hc, dn->ssl_peer_verify);
  if (http_client_simple(hc, &u) < 0) {
    http_client_close(hc);
    tvherror(dn->log, "unable to send http command");
    goto stop;
  }

  dn->http_client = hc;
  goto done;

stop:
  if (dn->stop)
    dn->stop(dn->aux);
done:
  urlreset(&u);
}
예제 #5
0
/*
 * Complete data
 */
static int
iptv_http_complete
  ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  char *url, *url2, *s, *p;
  url_t u;
  int r;

  if (im->im_m3u_header) {
    im->im_m3u_header = 0;
    sbuf_append(&im->mm_iptv_buffer, "", 1);
    url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data);
    sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
    if (url == NULL) {
      tvherror("iptv", "m3u contents parsing failed");
      return 0;
    }
    urlinit(&u);
    if (url[0] == '/') {
      s = strdupa(im->mm_iptv_url_raw);
      if ((p = strchr(s, '/')) != NULL)
        *p = '\0';
      if (!urlparse(s, &u))
        goto invalid;
      url2 = malloc(512);
      url2[0] = '\0';
      if ((p = http_arg_get(&hc->hc_args, "Host")) != NULL) {
        snprintf(url2, 512, "%s://%s%s",
                 hc->hc_ssl ? "https" : "http", p, url);
      } else if (im->mm_iptv_url_raw) {
        snprintf(url2, 512, "%s%s", s, url);
      }
      free(url);
      url = url2;
      urlinit(&u);
    }
    if (!urlparse(url, &u)) {
      hc->hc_keepalive = 0;
      r = http_client_simple_reconnect(hc, &u, HTTP_VERSION_1_1);
      if (r < 0)
        tvherror("iptv", "cannot reopen http client: %d'", r);
    } else {
invalid:
      tvherror("iptv", "m3u url invalid '%s'", url);
    }
    urlreset(&u);
    free(url);
    return 0;
  }
  return 0;
}
예제 #6
0
/*
 * Output packet
 */
static int _timeshift_read
  ( timeshift_t *ts, timeshift_seek_t *seek,
    streaming_message_t **sm, int *wait )
{
  timeshift_file_t *tsf = seek->file;
  ssize_t r;
  off_t off = 0;

  *sm = NULL;

  if (tsf) {

    /* Open file */
    if (tsf->rfd < 0 && !tsf->ram) {
      tsf->rfd = tvh_open(tsf->path, O_RDONLY, 0);
      tvhtrace(LS_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(LS_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 */
    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(LS_TIMESHIFT, "ts %d seek to %jd (woff %jd) (fd %i)", ts->id, (intmax_t)off, (intmax_t)tsf->woff, tsf->rfd);
      tvherror(LS_TIMESHIFT, "ts %d could not read buffer", ts->id);
      return -1;
    }
    tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (fd %i) read msg %p/%"PRId64" (%"PRId64")",
             ts->id, (intmax_t)off, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r);

    /* Special case - EOF */
    if (r <= sizeof(size_t) || tsf->roff > tsf->size || *sm == NULL) {
      timeshift_file_get(seek->file); /* _read_close decreases file reference */
      _read_close(seek);
      _seek_set_file(seek, timeshift_filemgr_next(tsf, NULL, 0), 0);
      *wait     = 0;
      tvhtrace(LS_TIMESHIFT, "ts %d eof, seek->file %p (prev %p)", ts->id, seek->file, tsf);
      timeshift_filemgr_dump(ts);
    }
  }
  return 0;
}
예제 #7
0
static ssize_t
iptv_udp_read ( iptv_input_t *mi, iptv_mux_t *im )
{
  int i, n;
  struct iovec *iovec;
  udp_multirecv_t *um = im->im_data;
  ssize_t res = 0;

  n = udp_multirecv_read(um, im->mm_iptv_fd, IPTV_PKTS, &iovec);
  if (n < 0)
    return -1;

  im->mm_iptv_rtp_seq &= ~0xfff;
  for (i = 0; i < n; i++, iovec++) {
    if (iovec->iov_len <= 0)
      continue;
    if (*(uint8_t *)iovec->iov_base != 0x47) {
      im->mm_iptv_rtp_seq++;
      continue;
    }
    sbuf_append(&im->mm_iptv_buffer, iovec->iov_base, iovec->iov_len);
    res += iovec->iov_len;
  }

  if (im->mm_iptv_rtp_seq < 0xffff && im->mm_iptv_rtp_seq > 0x3ff) {
    tvherror(LS_IPTV, "receving non-raw UDP data for %s!", im->mm_nicename);
    im->mm_iptv_rtp_seq = 0x10000; /* no further logs! */
  }

  return res;
}
예제 #8
0
/**
 * Parse comskip data.
 *   filename, in: full path to comskip file.
 *   cut_list, in: empty list. out: the list filled with data.
 *   return:   number of read valid lines.
 *
 * Example of comskip file content (format v2):
 *
 * FILE PROCESSING COMPLETE  53999 FRAMES AT  2500
 * -------------------
 * 50      2459
 * 14923   23398
 * 42417   54004
 *
 */
static int
dvr_parse_comskip
  ( const char *line, dvr_cutpoint_t *cutpoint, float *frame_rate )
{
  int start = 0, end = 0;

  /* Header */
  if (sscanf(line, "FILE PROCESSING COMPLETE %*d FRAMES AT %f",
             frame_rate) == 1) {
    *frame_rate /= (*frame_rate > 1000.0f ? 100.0f : 1.0f);
    return 1; // TODO: probably not nice this returns "error"
  }

  /* Invalid line */
  if(*frame_rate <= 0.0f || sscanf(line, "%d\t%d", &start, &end) != 2)
    return 1;

  /* Sanity Checks */
  if(start < 0 || end < 0 || end < start || start == end) {
    tvherror("dvr", "Insane EDL entry: start=%d, end=%d. Skipping.", start, end);
    return 1;
  }

  /* Set values */
  cutpoint->dc_start_ms = (int) ((start * 1000) / *frame_rate);
  cutpoint->dc_end_ms   = (int) ((end * 1000) / *frame_rate);
  // Comskip don't have different actions, so use DVR_CP_COMM (Commercial skip)
  cutpoint->dc_type     = DVR_CP_COMM;

  return 0;
}
예제 #9
0
파일: uuid.c 프로젝트: 1stsetup/tvheadend
/* Initialise binary */
int
uuid_init_bin ( tvh_uuid_t *u, const char *str )
{
  memset(u, 0, sizeof(tvh_uuid_t));
  if (str) {
    if (strlen(str) != UUID_HEX_SIZE - 1) {
      tvherror("uuid", "wrong uuid size");
      return -EINVAL;
    }
    return hex2bin(u->bin, sizeof(u->bin), str);
  } else if (read(fd, u->bin, sizeof(u->bin)) != sizeof(u->bin)) {
    tvherror("uuid", "failed to read from %s", RANDOM_PATH);
    return -EINVAL;
  }
  return 0;
}
예제 #10
0
int
udp_connect( udp_connection_t *uc, const char *name,
              const char *host, int port )
{
  char buf[50];
  int r;

  if (uc == NULL || uc == UDP_FATAL_ERROR)
    return -1;

  uc->peer_host = host ? strdup(host) : NULL;
  uc->peer_port = port;
  uc->peer_multicast = 0;

  if (udp_resolve(uc, &uc->peer, host, port, &uc->peer_multicast, 1))
    return -1;

  if (connect(uc->fd, (struct sockaddr *)&uc->peer, sizeof(struct sockaddr_in))) {
    inet_ntop(uc->peer.ss_family, IP_IN_ADDR(uc->peer), buf, sizeof(buf));
    tvherror(uc->subsystem, "%s - cannot bind %s:%hu [e=%s]",
             name, buf, ntohs(IP_PORT(uc->peer)), strerror(errno));
    r = -errno;
    return r;
  }
  return 0;
}
예제 #11
0
static void
linuxdvb_ca_class_enabled_notify ( void *p, const char *lang )
{
  linuxdvb_ca_t *lca = (linuxdvb_ca_t *) p;

  if (lca->lca_enabled) {
    if (lca->lca_ca_fd < 0) {
      lca->lca_ca_fd = tvh_open(lca->lca_ca_path, O_RDWR | O_NONBLOCK, 0);
      tvhtrace(LS_LINUXDVB, "opening ca%u %s (fd %d)",
               lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd);
    }
  } else {
    tvhtrace(LS_LINUXDVB, "closing ca%u %s (fd %d)",
             lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd);

    if (lca->lca_en50221_thread_running) {
      lca->lca_en50221_thread_running = 0;
      pthread_join(lca->lca_en50221_thread, NULL);
    }

    if (ioctl(lca->lca_ca_fd, CA_RESET, NULL))
      tvherror(LS_LINUXDVB, "unable to reset ca%u %s",
               lca->lca_number, lca->lca_ca_path);

    close(lca->lca_ca_fd);
    lca->lca_ca_fd = -1;

    idnode_notify_title_changed(&lca->lca_id, lang);
  }
}
예제 #12
0
파일: uuid.c 프로젝트: 1stsetup/tvheadend
void
uuid_random ( uint8_t *buf, size_t bufsize )
{
  if (read(fd, buf, bufsize) != bufsize) {
    tvherror("uuid", "random failed: %s", strerror(errno));
    exit(1);
  }
}
예제 #13
0
파일: download.c 프로젝트: Ferni7/tvheadend
static int
download_file(download_t *dn, const char *filename)
{
  int fd, res;
  struct stat st;
  char *data, *last_url;
  ssize_t r;
  off_t off;

  fd = tvh_open(filename, O_RDONLY, 0);
  if (fd < 0) {
    tvherror(dn->log, "unable to open file '%s': %s",
             filename, strerror(errno));
    return -1;
  }
  if (fstat(fd, &st) || st.st_size == 0) {
    tvherror(dn->log, "unable to stat file '%s': %s",
             filename, strerror(errno));
    close(fd);
    return -1;
  }
  data = malloc(st.st_size+1);
  off = 0;
  do {
    r = read(fd, data + off, st.st_size - off);
    if (r < 0) {
      if (ERRNO_AGAIN(errno))
        continue;
      break;
    }
    off += r;
  } while (off != st.st_size);
  close(fd);

  if (off == st.st_size) {
    data[off] = '\0';
    last_url = strrchr(filename, '/');
    if (last_url)
      last_url++;
    res = dn->process(dn->aux, last_url, NULL, data, off);
  } else {
    res = -1;
  }
  free(data);
  return res;
}
예제 #14
0
/*
 * Connected
 */
static int
iptv_rtsp_header ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  rtsp_priv_t *rp;
  int r;

  if (im == NULL) {
    /* teardown (or teardown timeout) */
    if (hc->hc_cmd == RTSP_CMD_TEARDOWN) {
      pthread_mutex_lock(&global_lock);
      mtimer_arm_rel(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0);
      pthread_mutex_unlock(&global_lock);
    }
    return 0;
  }

  if (hc->hc_cmd == RTSP_CMD_GET_PARAMETER && hc->hc_code != HTTP_STATUS_OK) {
    tvhtrace("iptv", "GET_PARAMETER command returned invalid error code %d for '%s', "
        "fall back to OPTIONS in keep alive loop.", hc->hc_code, im->mm_iptv_url_raw);
    hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_OPTIONS;
    return 0;
  }

  if (hc->hc_code != HTTP_STATUS_OK) {
    tvherror("iptv", "invalid error code %d for '%s'", hc->hc_code, im->mm_iptv_url_raw);
    return 0;
  }

  rp = im->im_data;

  switch (hc->hc_cmd) {
  case RTSP_CMD_SETUP:
    r = rtsp_setup_decode(hc, 0);
    if (r >= 0) {
      rtsp_play(hc, rp->path, rp->query);
      rp->play = 1;
    }
    break;
  case RTSP_CMD_PLAY:
    // Now let's set peer port for RTCP
    // Use the HTTP host for sending RTCP reports, NOT the hc_rtp_dest (which is where the stream is sent)
    if (udp_connect(rp->rtcp_info->connection, "rtcp", hc->hc_host, hc->hc_rtcp_server_port)) {
        tvhlog(LOG_WARNING, "rtsp", "Can't connect to remote, RTCP receiver reports won't be sent");
    }
    hc->hc_cmd = HTTP_CMD_NONE;
    pthread_mutex_lock(&global_lock);
    iptv_input_mux_started(hc->hc_aux);
    mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im,
                   sec2mono(MAX(1, (hc->hc_rtp_timeout / 2) - 1)));
    pthread_mutex_unlock(&global_lock);
    break;
  default:
    break;
  }

  return 0;
}
예제 #15
0
파일: lock.c 프로젝트: 0p1pp1/tvheadend
int file_unlock(const char *lfile, int _fd)
{
    int err;

    err = state_lock_(lfile, 0, 10, _fd);
    if (err < 0)
        tvherror("lock", "file %s unlock error: %s", lfile, strerror(-err));
    return err;
}
예제 #16
0
파일: uuid.c 프로젝트: 1stsetup/tvheadend
void
uuid_init ( void )
{
  fd = open(RANDOM_PATH, O_RDONLY);
  if (fd == -1) {
    tvherror("uuid", "failed to open %s", RANDOM_PATH);
    exit(1);
  }
}
예제 #17
0
파일: lock.c 프로젝트: 0p1pp1/tvheadend
int file_lock(const char *lfile, int timeout)
{
    int err;

    err = state_lock_(lfile, 1, timeout, -1);
    if (err < 0)
        tvherror("lock", "file %s lock error: %s", lfile, strerror(-err));
    return err;
}
예제 #18
0
파일: dvr_rec.c 프로젝트: JPP1/tvheadend
void
dvr_rec_subscribe(dvr_entry_t *de)
{
  char buf[100];
  int weight;
  profile_t *pro;
  profile_chain_t *prch;

  assert(de->de_s == NULL);
  assert(de->de_chain == NULL);

  if(de->de_pri < ARRAY_SIZE(prio2weight))
    weight = prio2weight[de->de_pri];
  else
    weight = 300;

  snprintf(buf, sizeof(buf), "DVR: %s", lang_str_get(de->de_title, NULL));

  pro = de->de_config->dvr_profile;
  prch = malloc(sizeof(*prch));
  profile_chain_init(prch, pro, de->de_channel);
  if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, 0, 0)) {
    tvherror("dvr", "unable to create new channel streaming chain for '%s'",
             channel_get_name(de->de_channel));
    return;
  }

  de->de_s = subscription_create_from_channel(prch, weight,
					      buf, prch->prch_flags,
					      NULL, NULL, NULL);
  if (de->de_s == NULL) {
    tvherror("dvr", "unable to create new channel subcription for '%s'",
             channel_get_name(de->de_channel));
    profile_chain_close(prch);
    free(prch);
    de->de_chain = NULL;
    return;
  }

  de->de_chain = prch;

  tvhthread_create(&de->de_thread, NULL, dvr_thread, de);
}
예제 #19
0
static int
udp_resolve( udp_connection_t *uc,
             struct sockaddr_storage *ss,
             const char *host,
             int port, int *multicast,
             int receiver )
{
  struct addrinfo hints, *res, *ressave, *use = NULL;
  char port_buf[6];
  int x;

  snprintf(port_buf, 6, "%d", port);

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_flags = (receiver ? AI_PASSIVE : 0) | AI_NUMERICSERV;
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  
  x = getaddrinfo(host, port_buf, &hints, &res);
  if (x < 0) {
    tvhlog(LOG_ERR, uc->subsystem, "getaddrinfo: %s: %s",
           host != NULL ? host : "*",
           x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x));
    return -1;
  }

  ressave = res;
  while (res) {
    if (res->ai_family == tcp_preferred_address_family) {
      use = res;
      break;
    } else if (use == NULL) {
      use = res;
    }
    res = res->ai_next;
  }
  if (use->ai_family == AF_INET6) {
    ss->ss_family        = AF_INET6;
    IP_AS_V6(*ss, port)  = htons(port);
    memcpy(&IP_AS_V6(*ss, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr,
                                                             sizeof(struct in6_addr));
    *multicast           = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(*ss, addr));
  } else if (use->ai_family == AF_INET) {
    ss->ss_family        = AF_INET;
    IP_AS_V4(*ss, port)  = htons(port);
    IP_AS_V4(*ss, addr)  = ((struct sockaddr_in *)use->ai_addr)->sin_addr;
    *multicast           = !!IN_MULTICAST(ntohl(IP_AS_V4(*ss, addr.s_addr)));
  }
  freeaddrinfo(ressave);
  if (ss->ss_family != AF_INET && ss->ss_family != AF_INET6) {
    tvherror(uc->subsystem, "%s - failed to process host '%s'", uc->name, uc->host);
    return -1;
  }
  return 0;
}
예제 #20
0
static int
linuxdvb_ca_rm_changed_cb(void *arg, uint8_t slot_id,
                          uint16_t session_num)
{
    linuxdvb_ca_t * lca = arg;
    tvhtrace("en50221", "rm changed cb received for slot %d", slot_id);

    if (en50221_app_rm_enq(lca->lca_rm_resource, session_num)) {
        tvherror("en50221", "failed to send ENQ to slot %d", slot_id);
    }

    return 0;
}
예제 #21
0
void
api_register ( const api_hook_t *hook )
{
  api_link_t *t;
  SKEL_ALLOC(api_skel);
  api_skel->hook = hook;
  t = RB_INSERT_SORTED(&api_hook_tree, api_skel, link, ah_cmp);
  if (t) {
    tvherror("api", "trying to re-register subsystem");
  } else {
    SKEL_USED(api_skel);
  }
}
예제 #22
0
파일: api.c 프로젝트: anirut/tvheadend
void
api_register ( const api_hook_t *hook )
{
  static api_link_t *t, *skel = NULL;
  if (!skel)
    skel = calloc(1, sizeof(api_link_t));
  skel->hook = hook;
  t = RB_INSERT_SORTED(&api_hook_tree, skel, link, ah_cmp);
  if (t)
    tvherror("api", "trying to re-register subsystem");
  else
    skel = NULL;
}
예제 #23
0
static int
linuxdvb_ca_dt_enquiry_cb(void *arg, uint8_t slot_id, uint16_t session_num,
                          uint8_t response_int)
{
    linuxdvb_ca_t * lca = arg;
    tvhtrace("en50221", "datetime enquiry cb received for slot %d", slot_id);

    if (en50221_app_datetime_send(lca->lca_dt_resource, session_num, time(NULL), -1)) {
        tvherror("en50221", "Failed to send datetime to slot %d", slot_id);
    }

    return 0;
}
예제 #24
0
/**
 * Create a new libavformat based muxer
 */
muxer_t*
lav_muxer_create(const muxer_config_t *m_cfg)
{
  const char *mux_name;
  lav_muxer_t *lm;
  AVOutputFormat *fmt;

  switch(m_cfg->m_type) {
  case MC_MPEGPS:
    mux_name = "dvd";
    break;
  case MC_MATROSKA:
  case MC_AVMATROSKA:
    mux_name = "matroska";
    break;
  case MC_WEBM:
  case MC_AVWEBM:
    mux_name = "webm";
    break;
  case MC_AVMP4:
    mux_name = "mp4";
    break;
  default:
    mux_name = muxer_container_type2txt(m_cfg->m_type);
    break;
  }

  fmt = av_guess_format(mux_name, NULL, NULL);
  if(!fmt) {
    tvherror(LS_LIBAV,  "Can't find the '%s' muxer", mux_name);
    return NULL;
  }

  lm = calloc(1, sizeof(lav_muxer_t));
  lm->m_open_stream  = lav_muxer_open_stream;
  lm->m_open_file    = lav_muxer_open_file;
  lm->m_init         = lav_muxer_init;
  lm->m_reconfigure  = lav_muxer_reconfigure;
  lm->m_mime         = lav_muxer_mime;
  lm->m_add_marker   = lav_muxer_add_marker;
  lm->m_write_meta   = lav_muxer_write_meta;
  lm->m_write_pkt    = lav_muxer_write_pkt;
  lm->m_close        = lav_muxer_close;
  lm->m_destroy      = lav_muxer_destroy;
  lm->lm_oc          = avformat_alloc_context();
  lm->lm_oc->oformat = fmt;
  lm->lm_fd          = -1;
  lm->lm_init        = 0;

  return (muxer_t*)lm;
}
예제 #25
0
int
urlparse ( const char *str, url_t *url )
{
    regmatch_t m[16];
    char buf[16];

    if (str == NULL || url == NULL)
        return -1;

    urlreset(url);

    /* Create regexp */
    if (!urlparse_exp) {
        urlparse_exp = calloc(1, sizeof(regex_t));
        if (regcomp(urlparse_exp, URL_RE, REG_ICASE | REG_EXTENDED)) {
            tvherror("url", "failed to compile regexp");
            exit(1);
        }
    }

    /* Execute */
    if (regexec(urlparse_exp, str, ARRAY_SIZE(m), m, 0))
        return -1;

    /* Extract data */
#define copy(x, i)\
  {\
    x = strndup(str+m[i].rm_so, m[i].rm_eo - m[i].rm_so);\
  }(void)0
#define copy_static(x, i)\
  {\
    int len = m[i].rm_eo - m[i].rm_so;\
    if (len >= sizeof(x) - 1)\
      len = sizeof(x) - 1;\
    memcpy(x, str+m[i].rm_so, len);\
    x[len] = 0;\
  }(void)0
    copy(url->scheme, 1);
    copy(url->user,   3);
    copy(url->pass,   5);
    copy(url->host,   6);
    copy(url->path,   9);
    copy_static(buf,  8);
    url->port = atoi(buf);
    copy(url->query, 11);
    copy(url->frag,  13);

    url->raw = strdup(str);

    return 0;
}
예제 #26
0
/*
 * Receive data
 */
static int
iptv_rtsp_data
  ( http_client_t *hc, void *buf, size_t len )
{
  iptv_mux_t *im = hc->hc_aux;

  if (im == NULL)
    return 0;

  if (len > 0)
    tvherror("iptv", "unknown data %zd received for '%s'", len, im->mm_iptv_url);

  return 0;
}
예제 #27
0
파일: dvr_rec.c 프로젝트: cloph/tvheadend
/**
 * Replace various chars with a dash
 */
static char *
cleanup_filename(char *s, dvr_config_t *cfg)
{
  int i, len = strlen(s), len2;
  char *s1;

  s1 = intlconv_utf8safestr(cfg->dvr_charset_id, s, len * 2);
  if (s1 == NULL) {
    tvherror("dvr", "Unsupported charset %s using ASCII", cfg->dvr_charset);
    s1 = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1),
                             s, len * 2);
    if (s1 == NULL)
      return NULL;
  }
  s = s1;

  /* Do not create hidden files */
  if (s[0] == '.')
    s[0] = '_';

  len2 = strlen(s);
  for (i = 0; i < len2; i++) {

    if(s[i] == '/')
      s[i] = '-';

    else if(cfg->dvr_whitespace_in_title &&
            (s[i] == ' ' || s[i] == '\t'))
      s[i] = '-';	

    else if(cfg->dvr_clean_title &&
            ((s[i] < 32) || (s[i] > 122) ||
             (strchr("/:\\<>|*?'\"", s[i]) != NULL)))
      s[i] = '_';
    else if(cfg->dvr_windows_compatible_filenames &&
             (strchr("/:\\<>|*?'\"", s[i]) != NULL))
      s[i] = '_';
  }

  if(cfg->dvr_windows_compatible_filenames) {
    // trim trailing spaces and dots
    for (i = len2 - 1; i >= 0; i--) {
      if((s[i] != ' ') && (s[i] != '.'))
        break;
      s[i] = '\0';
    }
  }

  return s;
}
예제 #28
0
static int
linuxdvb_ca_rm_enq_cb(void *arg, uint8_t slot_id, uint16_t session_num)
{
    linuxdvb_ca_t * lca = arg;

    tvhtrace("en50221", "rm enq callback received for slot %d", slot_id);

    if (en50221_app_rm_reply(lca->lca_rm_resource, session_num,
        sizeof(resource_ids)/4, resource_ids))
    {
      tvherror("en50221", "failed to send rm reply to slot %u session %u",
               slot_id, session_num);
    }

    return 0;
}
예제 #29
0
int
dvr_rec_subscribe(dvr_entry_t *de)
{
  char buf[100];
  int weight;
  profile_t *pro;
  profile_chain_t *prch;
  struct sockaddr sa;
  access_t *aa;
  uint32_t rec_count, net_count;
  int c1, c2;

  assert(de->de_s == NULL);
  assert(de->de_chain == NULL);

  if(de->de_pri >= 0 && de->de_pri < ARRAY_SIZE(prio2weight))
    weight = prio2weight[de->de_pri];
  else
    weight = 300;

  snprintf(buf, sizeof(buf), "DVR: %s", lang_str_get(de->de_title, NULL));

  if (de->de_owner && de->de_owner[0] != '\0')
    aa = access_get_by_username(de->de_owner);
  else if (de->de_creator && de->de_creator[0] != '\0' &&
           tcp_get_ip_from_str(de->de_creator, &sa) != NULL)
    aa = access_get_by_addr(&sa);
  else {
    tvherror(LS_DVR, "unable to find access (owner '%s', creator '%s')",
             de->de_owner, de->de_creator);
    return -EPERM;
 }

  if (aa->aa_conn_limit || aa->aa_conn_limit_dvr) {
    rec_count = dvr_usage_count(aa);
    net_count = aa->aa_conn_limit ? tcp_connection_count(aa) : 0;
    /* the rule is: allow if one condition is OK */
    c1 = aa->aa_conn_limit ? rec_count + net_count >= aa->aa_conn_limit : -1;
    c2 = aa->aa_conn_limit_dvr ? rec_count >= aa->aa_conn_limit_dvr : -1;
    if (c1 && c2) {
      tvherror(LS_DVR, "multiple connections are not allowed for user '%s' from '%s' "
                      "(limit %u, dvr limit %u, active DVR %u, streaming %u)",
               aa->aa_username ?: "", aa->aa_representative ?: "",
               aa->aa_conn_limit, aa->aa_conn_limit_dvr, rec_count, net_count);
      access_destroy(aa);
      return -EOVERFLOW;
    }
예제 #30
0
static void
linuxdvb_ca_monitor ( void *aux )
{
  linuxdvb_ca_t *lca = aux;
  ca_slot_info_t csi;
  int state;

  csi.num = 0;

  if (lca->lca_ca_fd >= 0) {
    if ((ioctl(lca->lca_ca_fd, CA_GET_SLOT_INFO, &csi)) != 0) {
      tvherror("linuxdvb", "failed to get CAM slot %u info [e=%s]",
               csi.num, strerror(errno));
    }
    if (csi.flags & CA_CI_MODULE_READY)
      state = CA_SLOT_STATE_MODULE_READY;
    else if (csi.flags & CA_CI_MODULE_PRESENT)
      state = CA_SLOT_STATE_MODULE_PRESENT;
    else
      state = CA_SLOT_STATE_EMPTY;

    lca->lca_state_str = ca_slot_state2str(state);

    if (lca->lca_state != state) {
      tvhlog(LOG_INFO, "linuxdvb", "CAM slot %u status changed to %s",
             csi.num, lca->lca_state_str);
      idnode_notify_title_changed(&lca->lca_id, NULL);
      lca->lca_state = state;
    }

    if ((!lca->lca_en50221_thread_running) &&
        (state == CA_SLOT_STATE_MODULE_READY)) 
    {
      lca->lca_en50221_thread_running = 1;
      tvhthread_create(&lca->lca_en50221_thread, NULL,
                       linuxdvb_ca_en50221_thread, lca);
    } else if (lca->lca_en50221_thread_running &&
               (state != CA_SLOT_STATE_MODULE_READY))
    {
      lca->lca_en50221_thread_running = 0;
      pthread_join(lca->lca_en50221_thread, NULL);
    }

  }

  gtimer_arm_ms(&lca->lca_monitor_timer, linuxdvb_ca_monitor, lca, 250);
}