Пример #1
0
/*
 * Setup RTSP(S) connection
 */
static int
iptv_rtsp_start
  ( iptv_mux_t *im, const char *raw, const url_t *u )
{
  rtsp_priv_t *rp;
  http_client_t *hc;
  udp_connection_t *rtp, *rtcp;
  int r;

  if (!(hc = http_client_connect(im, RTSP_VERSION_1_0, u->scheme,
                                 u->host, u->port, NULL)))
    return SM_CODE_TUNING_FAILED;

  if (u->user)
    hc->hc_rtsp_user = strdup(u->user);
  if (u->pass)
    hc->hc_rtsp_pass = strdup(u->pass);

  if (udp_bind_double(&rtp, &rtcp,
                      "IPTV", "rtp", "rtcp",
                      NULL, 0, NULL,
                      128*1024, 16384, 4*1024, 4*1024) < 0) {
    http_client_close(hc);
    return SM_CODE_TUNING_FAILED;
  }

  hc->hc_hdr_received        = iptv_rtsp_header;
  hc->hc_data_received       = iptv_rtsp_data;
  hc->hc_handle_location     = 1;                      /* allow redirects */
  hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_GET_PARAMETER; /* start keep alive loop with GET_PARAMETER */
  http_client_register(hc);                            /* register to the HTTP thread */
  r = rtsp_setup(hc, u->path, u->query, NULL,
                 ntohs(IP_PORT(rtp->ip)),
                 ntohs(IP_PORT(rtcp->ip)));
  if (r < 0) {
    udp_close(rtcp);
    udp_close(rtp);
    http_client_close(hc);
    return SM_CODE_TUNING_FAILED;
  }

  rp = calloc(1, sizeof(*rp));
  rp->rtcp_info = calloc(1, sizeof(iptv_rtcp_info_t));
  rtcp_init(rp->rtcp_info);
  rp->rtcp_info->connection = rtcp;
  rp->hc = hc;
  udp_multirecv_init(&rp->um, IPTV_PKTS, IPTV_PKT_PAYLOAD);
  rp->path = strdup(u->path ?: "");
  rp->query = strdup(u->query ?: "");

  im->im_data = rp;
  im->mm_iptv_fd = rtp->fd;
  im->mm_iptv_connection = rtp;
  im->mm_iptv_fd2 = rtcp->fd;
  im->mm_iptv_connection2 = rtcp;

  return 0;
}
Пример #2
0
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);
}
Пример #3
0
/*
 * Stop connection
 */
static void
iptv_rtsp_stop
  ( iptv_mux_t *im )
{
  rtsp_priv_t *rp = im->im_data;
  int play;

  lock_assert(&global_lock);

  if (rp == NULL)
    return;

  play = rp->play;
  im->im_data = NULL;
  rp->hc->hc_aux = NULL;
  if (play)
    rtsp_teardown(rp->hc, rp->path, "");
  pthread_mutex_unlock(&iptv_lock);
  gtimer_disarm(&rp->alive_timer);
  udp_multirecv_free(&rp->um);
  if (!play)
    http_client_close(rp->hc);
  free(rp->path);
  free(rp->query);
  rtcp_destroy(rp->rtcp_info);
  free(rp->rtcp_info);
  free(rp);
  pthread_mutex_lock(&iptv_lock);
}
Пример #4
0
/*
 * Setup HTTP(S) connection
 */
static int
iptv_http_start
  ( iptv_mux_t *im, const char *raw, const url_t *u )
{
  http_client_t *hc;
  int r;

  if (!(hc = http_client_connect(im, HTTP_VERSION_1_1, u->scheme,
                                 u->host, u->port, NULL)))
    return SM_CODE_TUNING_FAILED;
  hc->hc_hdr_create      = iptv_http_create_header;
  hc->hc_hdr_received    = iptv_http_header;
  hc->hc_data_received   = iptv_http_data;
  hc->hc_data_complete   = iptv_http_complete;
  hc->hc_handle_location = 1;        /* allow redirects */
  hc->hc_io_size         = 128*1024; /* increase buffering */
  http_client_register(hc);          /* register to the HTTP thread */
  r = http_client_simple(hc, u);
  if (r < 0) {
    http_client_close(hc);
    return SM_CODE_TUNING_FAILED;
  }
  im->im_data = hc;
  sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_BUF_SIZE);

  return 0;
}
Пример #5
0
/*
 * Cleanup for http_xml_send()
 */
static void
http_xml_send_cleanup(void *arg)
{
	struct http_client_connection *cc = arg;

	http_client_close(&cc);
}
Пример #6
0
static void
download_fetch_done(void *aux)
{
  http_client_t *hc = aux;
  download_t *dm = hc->hc_aux;
  if (dm->http_client) {
    dm->http_client = NULL;
    http_client_close((http_client_t *)aux);
  }
}
Пример #7
0
/*
 * Stop connection
 */
static void
iptv_http_stop
  ( iptv_mux_t *im )
{
  http_client_t *hc = im->im_data;

  hc->hc_aux = NULL;
  pthread_mutex_unlock(&iptv_lock);
  http_client_close(hc);
  pthread_mutex_lock(&iptv_lock);
}
Пример #8
0
void
download_done( download_t *dn )
{
  if (dn->http_client) {
    http_client_close(dn->http_client);
    dn->http_client = NULL;
  }
  gtimer_disarm(&dn->fetch_timer);
  free(dn->log); dn->log = NULL;
  free(dn->url); dn->url = NULL;
}
Пример #9
0
void
download_start( download_t *dn, const char *url, void *aux )
{
  if (dn->http_client) {
    http_client_close(dn->http_client);
    dn->http_client = NULL;
  }
  if (url)
    dn->url = strdup(url);
  dn->aux = aux;
  gtimer_arm(&dn->fetch_timer, download_fetch, dn, 0);
}
Пример #10
0
static void
satip_discovery_destroy(satip_discovery_t *d, int unlink)
{
  if (d == NULL)
    return;
  if (unlink) {
    satip_discoveries_count--;
    TAILQ_REMOVE(&satip_discoveries, d, disc_link);
  }
  if (d->http_client)
    http_client_close(d->http_client);
  urlreset(&d->url);
  free(d->myaddr);
  free(d->location);
  free(d->server);
  free(d->uuid);
  free(d->bootid);
  free(d->configid);
  free(d->deviceid);
  free(d);
}
Пример #11
0
static void
iptv_rtsp_close_cb ( void *aux )
{
  http_client_close((http_client_t *)aux);
}
Пример #12
0
/*M
  \emph{Simple HTTP streaming server main loop.}

  The mainloop opens the MPEG Audio file \verb|filename|, reads each
  frame into an rtp packet and sends it out using HTTP. After sending
  a packet, the mainloop sleeps for the duration of the packet,
  synchronizing itself when the sleep is not accurate enough. If the
  sleep desynchronizes itself from the stream more than \verb|MAX_WAIT_TIME|,
  the synchronization is reset.
**/
int poc_mainloop(http_server_t *server, char *filename, int quiet) {
  /*M
    Open file for reading.
  **/
  file_t     mp3_file;
  if (!file_open_read(&mp3_file, filename)) {
    fprintf(stderr, "Could not open mp3 file: %s\n", filename);
    return 0;
  }

  if (!quiet)
    fprintf(stderr, "\rStreaming %s...\n", filename);
  
  static long wait_time = 0;
  unsigned long frame_time = 0;
  
  mp3_frame_t    frame;

  /*M
    Cycle through the frames and send them using HTTP.
  **/
  while ((mp3_next_frame(&mp3_file, &frame) >= 0) && !finished) {
    /*M
      Get start time for this frame iteration.
    **/
    struct timeval tv;
    gettimeofday(&tv, NULL);
    unsigned long start_sec, start_usec;
    start_sec = tv.tv_sec;
    start_usec = tv.tv_usec;
    
    /*M
      Go through HTTP main routine and check for timeouts,
      received data, etc...
    **/
    if (!http_server_main(server, NULL)) {
      fprintf(stderr, "Http main error\n");
      return 0;
    }
    
    /*M
      Write frame to HTTP clients.
    **/
    int i;
    for (i = 0; i < server->num_clients; i++) {
      if ((server->clients[i].fd != -1) &&
          (server->clients[i].found >= 2)) {
        int ret;
        
        ret = unix_write(server->clients[i].fd, frame.raw, frame.frame_size);
        
        if (ret != frame.frame_size) {
          fprintf(stderr, "Error writing to client %d: %d\n", i, ret);
          http_client_close(server, server->clients + i);
        }
      }
    }
    frame_time += frame.usec;
    wait_time += frame.usec;
    
    /*M
      Sleep for duration of frame.
    **/
    if (wait_time > 1000)
      usleep(wait_time);
    
    /*M
      Print information.
    **/
    if (!quiet) {
      static int count = 0;
      if ((count++) % 10 == 0) {
        if (mp3_file.size > 0) {
          fprintf(stderr, "\r%02ld:%02ld/%02ld:%02ld %7ld/%7ld (%3ld%%) %3ldkbit/s %4ldb ",
                  (frame_time/1000000) / 60,
                  (frame_time/1000000) % 60,

                  (long)((float)(frame_time/1000) / 
                         ((float)mp3_file.offset+1) * (float)mp3_file.size) / 
                  60000,
                  (long)((float)(frame_time/1000) / 
                         ((float)mp3_file.offset+1) * (float)mp3_file.size) / 
                  1000 % 60,
                  mp3_file.offset,
                  mp3_file.size,
                  (long)(100*(float)mp3_file.offset/(float)mp3_file.size),
                  frame.bitrate,
                  frame.frame_size);
        } else {
          fprintf(stderr, "\r%02ld:%02ld %ld %3ldkbit/s %4ldb ",
                  (frame_time/1000000) / 60,
                  (frame_time/1000000) % 60,
                  mp3_file.offset,
                  frame.bitrate,
                  frame.frame_size);
        }
      }
      fflush(stderr);
    }

    /*M
      Get length of iteration.
    **/
    gettimeofday(&tv, NULL);
    unsigned long len =
      (tv.tv_sec - start_sec) * 1000000 + (tv.tv_usec - start_usec);

    wait_time -= len;
    if (abs(wait_time) > MAX_WAIT_TIME)
      wait_time = 0;
  }
  
  if (!file_close(&mp3_file)) {
    fprintf(stderr, "Could not close mp3 file %s\n", filename);
    return 0;
  }

  return 1;
}