Beispiel #1
0
krad_mixer_t *krad_mixer_create (char *name) {

  int p;

  krad_mixer_t *krad_mixer;

  if ((krad_mixer = calloc (1, sizeof (krad_mixer_t))) == NULL) {
    failfast ("Krad Mixer memory alloc failure");
  }
  
  krad_mixer->address.path.unit = KR_MIXER;
  krad_mixer->address.path.subunit.mixer_subunit = KR_UNIT;
  
  krad_mixer->name = strdup (name);
  krad_mixer->sample_rate = KRAD_MIXER_DEFAULT_SAMPLE_RATE;
  krad_mixer->rms_window_size = (krad_mixer->sample_rate / 1000) * KRAD_MIXER_RMS_WINDOW_SIZE_MS;
  krad_mixer->ticker_period = KRAD_MIXER_DEFAULT_TICKER_PERIOD;
  krad_mixer->frames_per_peak_broadcast = 1536;
  
  krad_mixer->crossfade_group = calloc (KRAD_MIXER_MAX_PORTGROUPS / 2, sizeof (krad_mixer_crossfade_group_t));

  for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
    krad_mixer->portgroup[p] = calloc (1, sizeof (krad_mixer_portgroup_t));
  }
  
  krad_mixer->krad_audio = krad_audio_create (krad_mixer);
  
  krad_mixer->master_mix = krad_mixer_portgroup_create (krad_mixer, "MasterBUS", MIX,
                           NOTOUTPUT, 2, DEFAULT_MASTERBUS_LEVEL, NULL, MIXBUS, NULL, 0);
  
  krad_mixer->tone_port = krad_mixer_portgroup_create (krad_mixer, "DTMF", INPUT, NOTOUTPUT, 1, 35.0f,
                              krad_mixer->master_mix, KRAD_TONE, NULL, 0);
  
  krad_mixer_portgroup_mixmap_channel (krad_mixer->tone_port, 0, 1);

  return krad_mixer;
}
Beispiel #2
0
void *krad_transmitter_listening_thread (void *arg) {

    krad_transmitter_t *krad_transmitter = (krad_transmitter_t *)arg;

    krad_system_set_thread_name ("kr_tx_listen");

    krad_transmission_receiver_t *krad_transmission_receiver;

    int e;
    int ret;
    int eret;
    int cret;
    int addr_size;
    int client_fd;
    struct sockaddr_in remote_address;

    char hbuf[NI_MAXHOST];
    char sbuf[NI_MAXSERV];

    printk ("Krad Transmitter: Listening thread starting");

    addr_size = 0;
    e = 0;
    ret = 0;
    eret = 0;
    cret = 0;
    krad_transmission_receiver = NULL;
    memset (&remote_address, 0, sizeof(remote_address));

    addr_size = sizeof (remote_address);

    while (krad_transmitter->stop_listening == 0) {

        ret = epoll_wait (krad_transmitter->incoming_connections_efd, krad_transmitter->incoming_connection_events, KRAD_TRANSMITTER_MAXEVENTS, 50);

        if (ret < 0) {
            if ((ret < 0) && (errno == EINTR)) {
                continue;
            }
            printke ("Krad Transmitter: Failed on epoll wait %s", strerror(errno));
            krad_transmitter->stop_listening = 1;
            break;
        }

        if (ret > 0) {

            for (e = 0; e < ret; e++) {

                if ((krad_transmitter->incoming_connection_events[e].events & EPOLLERR) ||
                        (krad_transmitter->incoming_connection_events[e].events & EPOLLHUP))
                {

                    if (krad_transmitter->incoming_connections_sd == krad_transmitter->incoming_connection_events[e].data.fd) {
                        failfast ("Krad Transmitter: error on listen socket");
                    } else {

                        if (krad_transmitter->incoming_connection_events[e].events & EPOLLHUP) {
                            printke ("Krad Transmitter: incoming transmitter connection hangup");
                        }
                        if (krad_transmitter->incoming_connection_events[e].events & EPOLLERR) {
                            printke ("Krad Transmitter: incoming transmitter connection error");
                        }
                        krad_transmitter_receiver_destroy (krad_transmitter->incoming_connection_events[e].data.ptr);
                        continue;
                    }

                }

                if (krad_transmitter->incoming_connections_sd == krad_transmitter->incoming_connection_events[e].data.fd) {

                    while (1) {

                        client_fd = accept (krad_transmitter->incoming_connections_sd, (struct sockaddr *)&remote_address, (socklen_t *)&addr_size);
                        if (client_fd == -1) {
                            if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                                // We have processed all incoming connections.
                                break;
                            } else {
                                failfast ("Krad Transmitter: error on listen socket accept");
                            }
                        }

                        if (getnameinfo ((struct sockaddr *)&remote_address, addr_size, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
                            printk ("Krad Transmitter: Accepted transmitter connection on descriptor %d (host=%s, port=%s)", client_fd, hbuf, sbuf);
                        } else {
                            printke ("Krad Transmitter: Accepted transmitter connection on descriptor %d ... but could not getnameinfo()?", client_fd, hbuf, sbuf);
                        }

                        krad_system_set_socket_nonblocking (client_fd);

                        krad_transmission_receiver = krad_transmitter_receiver_create (krad_transmitter, client_fd);

                        if (krad_transmission_receiver == NULL) {
                            failfast ("Krad Transmitter: ran out of connections!");
                        }

                        eret = epoll_ctl (krad_transmitter->incoming_connections_efd, EPOLL_CTL_ADD, client_fd, &krad_transmission_receiver->event);
                        if (eret != 0) {
                            failfast ("Krad Transmitter: incoming transmitter connection epoll error eret is %d errno is %i", eret, errno);
                        }
                    }

                    continue;
                }

                if (krad_transmitter->incoming_connection_events[e].events & EPOLLIN) {

                    while (1) {
                        krad_transmission_receiver = (krad_transmission_receiver_t *)krad_transmitter->incoming_connection_events[e].data.ptr;

                        cret = read (krad_transmission_receiver->fd,
                                     krad_transmission_receiver->buffer + krad_transmission_receiver->position,
                                     sizeof (krad_transmission_receiver->buffer) -  krad_transmission_receiver->position);
                        if (cret == -1) {
                            if (errno != EAGAIN) {
                                printke ("Krad Transmitter: error reading from a new incoming connection socket");
                                krad_transmitter_receiver_destroy (krad_transmitter->incoming_connection_events[e].data.ptr);
                            }
                            break;
                        }

                        if (cret == 0) {
                            printk ("Krad Transmitter: Client EOF Closed connection");
                            krad_transmitter_receiver_destroy (krad_transmitter->incoming_connection_events[e].data.ptr);
                            break;
                        }

                        if (cret > 0) {
                            krad_transmission_receiver->position += cret;
                            krad_transmitter_handle_incoming_connection (krad_transmitter, krad_transmission_receiver);
                            break;
                        }
                    }
                }
            }
        }

        if (ret == 0) {
            //printk ("Krad Transmitter: Listening thread... nothing happened");
        }
    }

    close (krad_transmitter->incoming_connections_efd);
    close (krad_transmitter->incoming_connections_sd);
    free (krad_transmitter->incoming_connection_events);

    krad_transmitter->port = 0;
    krad_transmitter->listening = 0;

    printk ("Krad Transmitter: Listening thread exiting");

    return NULL;

}
Beispiel #3
0
static int krad_transmitter_transmission_transmit (krad_transmission_t *krad_transmission,
        krad_transmission_receiver_t *krad_transmission_receiver) {

    int ret;
    uint64_t buf_avail;
    uint32_t vec_pos;
    uint32_t vec_avail;
    krad_ringbuffer_data_t *vec;

    vec_avail = 0;
    vec_pos = 0;
    ret = 0;
    buf_avail = 0;

    if ((krad_transmission == NULL) || (krad_transmission_receiver == NULL)) {
        failfast ("Krad Transmitter: this should not be");
    }

    while (1) {

        if ((krad_transmission_receiver->wrote_http_header != 1) || (krad_transmission_receiver->wrote_header != 1)) {
            ret = krad_transmitter_transmission_transmit_header (krad_transmission, krad_transmission_receiver);
            if (ret == 1) {
                continue;
            } else {
                return 0;
            }
        }

        if (krad_transmission_receiver->position == krad_transmission->position) {
            if (krad_transmission_receiver->ready == 0) {
                krad_transmission_add_ready (krad_transmission, krad_transmission_receiver);
            }
            break;
        }

        if (krad_transmission_receiver->position < krad_transmission->horizon) {
            printke ("Krad Transmitter: client fell so far behind oh no");
            krad_transmitter_receiver_destroy (krad_transmission_receiver);
            break;
        }

        buf_avail = krad_transmission->position - krad_transmission_receiver->position;

        if (buf_avail > krad_transmission->tx_vec[1].len) {
            vec = &krad_transmission->tx_vec[0];
            vec_pos = krad_transmission->tx_vec[0].len - (buf_avail - krad_transmission->tx_vec[1].len);
            vec_avail = vec->len - vec_pos;

            ret = write (krad_transmission_receiver->fd,
                         vec->buf + vec_pos,
                         vec_avail);
        } else {
            vec = &krad_transmission->tx_vec[1];
            vec_pos = krad_transmission->tx_vec[1].len - buf_avail;
            vec_avail = vec->len - vec_pos;

            ret = write (krad_transmission_receiver->fd,
                         vec->buf + vec_pos,
                         vec_avail);
        }

        if (ret == -1) {
            if (errno != EAGAIN) {
                printke ("Krad Transmitter: transmission error writing to socket");
                krad_transmitter_receiver_destroy (krad_transmission_receiver);
                break;
            }
            if (krad_transmission_receiver->ready == 1) {
                krad_transmission_remove_ready (krad_transmission, krad_transmission_receiver);
            }
            break;
        }

        if (ret == 0) {
            printk ("Krad Transmitter: transmission transmit wrote to client 0 bytes");
            krad_transmitter_receiver_destroy (krad_transmission_receiver);
            break;
        }

        if (ret > 0) {
            krad_transmission_receiver->position += ret;
        }

        if (ret < vec_avail) {
            if (krad_transmission_receiver->ready == 1) {
                krad_transmission_remove_ready (krad_transmission, krad_transmission_receiver);
            }
            break;
        }
    }

    return 0;
}
Beispiel #4
0
static int krad_app_client_init (krad_app_client_t *client, int timeout_ms) {

  int rc;
  char port_string[6];
  struct sockaddr_un unix_saddr;
  struct in6_addr serveraddr;
  struct addrinfo hints;
  struct addrinfo *res;

  res = NULL;

  //FIXME make connect nonblocking  
  

  if (client->tcp_port != 0) {

    //FIXME hrm we don't know the sysname of a remote connect! crazy ?
    //printf ("Krad APP Client: Connecting to remote %s:%d", client->host, client->tcp_port);

    memset(&hints, 0x00, sizeof(hints));
    hints.ai_flags = AI_NUMERICSERV;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    rc = inet_pton (AF_INET, client->host, &serveraddr);
    if (rc == 1) {
      hints.ai_family = AF_INET;
      hints.ai_flags |= AI_NUMERICHOST;
    } else {
      rc = inet_pton (AF_INET6, client->host, &serveraddr);
      if (rc == 1) {
        hints.ai_family = AF_INET6;
        hints.ai_flags |= AI_NUMERICHOST;
      }
    }

    snprintf (port_string, 6, "%d", client->tcp_port);

    rc = getaddrinfo (client->host, port_string, &hints, &res);
    if (rc != 0) {
       printf ("Krad APP Client: Host not found --> %s\n", gai_strerror(rc));
       return 0;
    }
    
    client->sd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
    if (client->sd < 0) {
      printf ("Krad APP Client: Socket Error");
      if (res != NULL) {
        freeaddrinfo (res);
        res = NULL;
      }
      return 0;
    }

    rc = connect (client->sd, res->ai_addr, res->ai_addrlen);
    if (rc < 0) {
      printf ("Krad APP Client: Remote Connect Error\n");
      if (res != NULL) {
        freeaddrinfo (res);
        res = NULL;
      }
      return 0;
    }

    if (res != NULL) {
      freeaddrinfo (res);
      res = NULL;
    }

  } else {

    client->sd = socket (AF_UNIX, SOCK_STREAM, 0);
    if (client->sd == -1) {
      failfast ("Krad APP Client: socket fail");
      return 0;
    }

    memset(&unix_saddr, 0x00, sizeof(unix_saddr));
    unix_saddr.sun_family = AF_UNIX;
    snprintf (unix_saddr.sun_path, sizeof(unix_saddr.sun_path), "%s", client->api_path);
    if (client->on_linux) {
      unix_saddr.sun_path[0] = '\0';
    }

    if (connect (client->sd, (struct sockaddr *) &unix_saddr, sizeof (unix_saddr)) == -1) {
      close (client->sd);
      client->sd = 0;
      printke ("Krad APP Client: Can't connect to socket %s", client->api_path);
      return 0;
    }
  }
  
  krad_system_set_socket_nonblocking (client->sd);

  return client->sd;
}
Beispiel #5
0
krad_vpx_encoder_t *krad_vpx_encoder_create (int width, int height,
                                             int fps_numerator,
                                             int fps_denominator,
                                             int bitrate) {

  krad_vpx_encoder_t *vpx;
  
  vpx = calloc (1, sizeof(krad_vpx_encoder_t));
  
  vpx->width = width;
  vpx->height = height;
  vpx->fps_numerator = fps_numerator;
  vpx->fps_denominator = fps_denominator;
  vpx->bitrate = bitrate;
  
  printk ("Krad Radio using libvpx version: %s",
          vpx_codec_version_str ());

  vpx->res = vpx_codec_enc_config_default (vpx_codec_vp8_cx(),
                                           &vpx->cfg, 0);

  if (vpx->res) {
    failfast ("Failed to get config: %s\n",
              vpx_codec_err_to_string(vpx->res));
  }

  // print default config
  krad_vpx_encoder_print_config (vpx);

  //TEMP
  //vpx->cfg.g_lag_in_frames = 1;

  vpx->cfg.g_w = vpx->width;
  vpx->cfg.g_h = vpx->height;
  /* Next two lines are really right */
  vpx->cfg.g_timebase.num = vpx->fps_denominator;
  vpx->cfg.g_timebase.den = vpx->fps_numerator;
  vpx->cfg.rc_target_bitrate = bitrate;  
  vpx->cfg.g_threads = 4;
  vpx->cfg.kf_mode = VPX_KF_AUTO;
  vpx->cfg.rc_end_usage = VPX_VBR;
  
  vpx->cfg.kf_max_dist = 120;
  
  vpx->deadline = 15 * 1000;

  vpx->min_quantizer = vpx->cfg.rc_min_quantizer;
  vpx->max_quantizer = vpx->cfg.rc_max_quantizer;

  //krad_vpx_encoder_print_config (vpx);

  if (vpx_codec_enc_init (&vpx->encoder,
                          vpx_codec_vp8_cx(),
                          &vpx->cfg, 0)) {
    krad_vpx_fail (&vpx->encoder, "Failed to initialize encoder");
  }

  krad_vpx_encoder_print_config (vpx);

  //vpx_codec_control (&vpx->encoder, VP8E_SET_ENABLEAUTOALTREF, 1);

  return vpx;
}
Beispiel #6
0
krad_mixer_portgroup_t *krad_mixer_portgroup_create (krad_mixer_t *krad_mixer, char *sysname, int direction,
                           krad_mixer_output_t output_type, int channels, float volume,
                           krad_mixer_mixbus_t *mixbus, krad_mixer_portgroup_io_t io_type, 
                           void *io_ptr, krad_audio_api_t api) {

  int p;
  int c;
  krad_mixer_portgroup_t *portgroup;
  
  portgroup = NULL;

  /* prevent dupe names */
  for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
    if (krad_mixer->portgroup[p]->active != 0) {
      if (strncmp(sysname, krad_mixer->portgroup[p]->sysname, strlen(sysname)) == 0) {
        return NULL;
      }
    }
  }
  
  //FIXME race here if portgroup being created via ipc and transponder at same moment
  for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
    if (krad_mixer->portgroup[p]->active == 0) {
      portgroup = krad_mixer->portgroup[p];
      break;
    }
  }
  
  if (portgroup == NULL) {
    return NULL;
  }
  
  /* Prevent multiple JACK direct outputs as this is redundant */
  if ((api == JACK) && (direction == OUTPUT) && (output_type == DIRECT)) {
    for (p = 0; p < KRAD_MIXER_MAX_PORTGROUPS; p++) {
      if ((krad_mixer->portgroup[p]->active == 1) || (krad_mixer->portgroup[p]->active == 2)) {
        if ((krad_mixer_portgroup_is_jack(krad_mixer->portgroup[p])) &&
            (krad_mixer->portgroup[p]->direction == OUTPUT) &&
            (krad_mixer->portgroup[p]->output_type == DIRECT)) {
          return NULL;
        }
      }
    }
  }

  portgroup->krad_mixer = krad_mixer;

  strcpy (portgroup->sysname, sysname);
  portgroup->channels = channels;
  portgroup->io_type = io_type;
  portgroup->output_type = output_type;
  portgroup->mixbus = mixbus;
  portgroup->direction = direction;

  portgroup->address.path.unit = KR_MIXER;
  portgroup->address.path.subunit.mixer_subunit = KR_PORTGROUP;
  strcpy (portgroup->address.id.name, portgroup->sysname);

  for (c = 0; c < KRAD_MIXER_MAX_CHANNELS; c++) {

    if (c < portgroup->channels) {
      portgroup->mixmap[c] = c;
    } else {
      portgroup->mixmap[c] = -1;
    }
    portgroup->map[c] = c;
    portgroup->mapped_samples[c] = &portgroup->samples[c];
    if ((portgroup->direction != OUTPUT) || (portgroup->output_type == AUX)) {
      portgroup->volume[c] = volume;
    } else {
      portgroup->volume[c] = 100.0f;
    }
    portgroup->volume_actual[c] = (float)(portgroup->volume[c]/100.0f);
    portgroup->volume_actual[c] *= portgroup->volume_actual[c];
    portgroup->new_volume_actual[c] = portgroup->volume_actual[c];

    switch ( portgroup->io_type ) {
      case KRAD_TONE:
        portgroup->samples[c] = calloc (1, 16384);
        break;    
      case MIXBUS:
        portgroup->samples[c] = calloc (1, 16384);
        break;
      case KRAD_AUDIO:
        break;
      case KRAD_LINK:
        portgroup->samples[c] = calloc (1, 16384);
        break;
      case KLOCALSHM:
        break;
    }
  }
  
  switch ( portgroup->io_type ) {
    case KRAD_TONE:
      portgroup->io_ptr = krad_tone_create (krad_mixer->sample_rate);
    case MIXBUS:
      break;
    case KRAD_AUDIO:
      portgroup->io_ptr = krad_audio_portgroup_create (krad_mixer->krad_audio, portgroup->sysname, 
                               portgroup->direction, portgroup->channels, api);
      break;
    case KRAD_LINK:
      portgroup->io_ptr = io_ptr;
      break;
    case KLOCALSHM:
      portgroup->io_ptr = io_ptr;    
      break;      
  }
  
  if (portgroup->io_type != KRAD_LINK) {
    portgroup->krad_tags = krad_tags_create (portgroup->sysname);
    //if ((portgroup->krad_tags != NULL) && (krad_mixer->krad_ipc != NULL)) {
    //  krad_tags_set_set_tag_callback (portgroup->krad_tags, krad_mixer->krad_ipc, 
    //                  (void (*)(void *, char *, char *, char *, int))krad_ipc_server_broadcast_tag);
    //}
  } else {
    portgroup->krad_tags = krad_link_get_tags (portgroup->io_ptr);
  }

  if (portgroup->krad_tags == NULL) {
    failfast ("Oh I couldn't find me tags");
  }

  portgroup->effects = kr_effects_create (portgroup->channels, portgroup->krad_mixer->sample_rate);
  
  if (portgroup->effects == NULL) {
    failfast ("Oh I couldn't make effects");
  }

  if (portgroup->direction == INPUT) {
    kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("eq"),
                            portgroup->krad_mixer, portgroup->sysname);
    kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("lowpass"),
                            portgroup->krad_mixer, portgroup->sysname);
    kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("highpass"),
                            portgroup->krad_mixer, portgroup->sysname);
    kr_effects_effect_add2 (portgroup->effects, kr_effects_string_to_effect ("analog"),
                            portgroup->krad_mixer, portgroup->sysname);
  }
    
  if (portgroup->io_type != KLOCALSHM) {
    portgroup->active = 1;
  }

  return portgroup;
}
Beispiel #7
0
void krad_x11_enable_capture (krad_x11_t *x11, uint32_t window_id) {

  xcb_get_geometry_reply_t *geo;
  xcb_query_tree_reply_t *tree;
  xcb_translate_coordinates_cookie_t translateCookie;
  xcb_translate_coordinates_reply_t *trans;

  geo = xcb_get_geometry_reply (x11->connection,
        xcb_get_geometry (x11->connection, window_id), NULL);
  if (geo == NULL) {
    window_id = 0;
  } else {
    tree = xcb_query_tree_reply (x11->connection,
                                 xcb_query_tree (x11->connection, window_id), NULL);
    if (tree == NULL) {
      window_id = 0;
      free (geo);
    } else {

      translateCookie = xcb_translate_coordinates (x11->connection,
                                                  window_id,
                                                  x11->screen->root,
                                                  geo->x, geo->y);

      trans = xcb_translate_coordinates_reply (x11->connection,
                                               translateCookie,
                                               NULL);    

      if (trans == NULL) {
        window_id = 0;
        free (tree);
        free (geo);
      } else {
        x11->width = geo->width;
        x11->height = geo->height;
        x11->x = trans->dst_x - geo->x;
        x11->y = trans->dst_y - geo->y;
        free (trans);
        free (tree);
        free (geo);
      }
    }
  }

  if (window_id == 0) {
    x11->width = x11->screen_width;
    x11->height = x11->screen_height;
    x11->window = x11->screen->root;
  }

  //printf ("capture width %d height %d x %d y %d\n",
  //       x11->width, x11->height, x11->x, x11->y);

  x11->img = xcb_image_create_native (x11->connection,
                                      x11->width, x11->height,
                                      XCB_IMAGE_FORMAT_Z_PIXMAP,
                                      x11->screen_bit_depth, 0, ~0, 0);
  if (!x11->img) {
    exit (15);
  }
  
  x11->stride = x11->img->stride;

  x11->shminfo.shmid = shmget (IPC_PRIVATE,
                               x11->img->stride * x11->img->height,
                               (IPC_CREAT | 0666));

  if (x11->shminfo.shmid == (uint32_t)-1) {
    xcb_image_destroy (x11->img);
    failfast ("shminfo fail");
  }

  x11->shminfo.shmaddr = shmat (x11->shminfo.shmid, 0, 0);
  x11->img->data = x11->shminfo.shmaddr;

  if (x11->img->data == (uint8_t *)-1) {
    xcb_image_destroy (x11->img);
    failfast ("xcb image fail");
  }

  x11->shminfo.shmseg = xcb_generate_id (x11->connection);
  xcb_shm_attach (x11->connection, x11->shminfo.shmseg, x11->shminfo.shmid, 0);
  x11->capture_enabled = 1;
}
Beispiel #8
0
void krad_slicer_sendto (krad_slicer_t *krad_slicer, unsigned char *data,
                         int size, int track, int keyframe, char *ip,
                         int port) {

  int ret;
  int remaining;
  int payload_size;
  int packet_size;
  int sent;
  int packet;
  struct sockaddr_in remote_client;
    
  ret = 0;
  sent = 0;
  payload_size = 0;
  packet_size = 0;
  packet = 0;
  remaining = size;

  memset((char *) &remote_client, 0, sizeof(remote_client));
  remote_client.sin_port = htons(port);
  remote_client.sin_family = AF_INET;
  
  if (inet_pton(remote_client.sin_family, ip, &(remote_client.sin_addr)) != 1) {
    failfast ("inet_pton() failed");
  }

  while (remaining) {
    
    packet++;
  
    if (remaining > KRAD_UDP_MAX_PAYOAD_SIZE) {
      payload_size = KRAD_UDP_MAX_PAYOAD_SIZE;
    } else {
      payload_size = remaining;
    }
    
    remaining -= payload_size;
    packet_size = payload_size + KRAD_UDP_HEADER_SIZE;
    
    // header|key|track number|sequence number|start_byte|total_bytes
    
    if (keyframe == 1) {
      krad_slicer->data[2] = 'K';
    } else {
      krad_slicer->data[2] = 'N';
    }
    memcpy (krad_slicer->data + 3, &track, 4);
    memcpy (krad_slicer->data + 7, &krad_slicer->track_seq[track], 4);
    memcpy (krad_slicer->data + 11, &sent, 4);
    memcpy (krad_slicer->data + 15, &size, 4);

    memcpy (krad_slicer->data + 19, data + sent, payload_size);

    //printk("track: %d slice: %d size: %d packet: %d range: %d - %d packet size: %d payload size: %d\n", 
    //    track, krad_slicer->track_seq[track], size, packet, sent, sent + payload_size - 1, packet_size, payload_size);
    
    ret = sendto(krad_slicer->sd, krad_slicer->data, packet_size, 0, 
           (struct sockaddr *) &remote_client, sizeof(remote_client));
    
    if (ret != packet_size) {
      failfast ("udp sending error");
    }
    
    sent += payload_size;
  }  

  krad_slicer->track_seq[track]++;
}
Beispiel #9
0
void kr_streamer_run (kr_streamer_t *streamer) {

  krad_frame_t *frame;
  int32_t frames;
  kr_medium_t *amedium;
  kr_codeme_t *acodeme;
  kr_medium_t *vmedium;
  kr_codeme_t *vcodeme;
  struct SwsContext *converter;
  int sws_algo;
  int32_t ret;
  int32_t muxdelay;
  uint32_t c;

  muxdelay = 1;

  signal (SIGINT, signal_recv);
  signal (SIGTERM, signal_recv);

  converter = NULL;
  sws_algo = SWS_BILINEAR;

  amedium = kr_medium_kludge_create ();
  acodeme = kr_codeme_kludge_create ();
  vmedium = kr_medium_kludge_create ();
  vcodeme = kr_codeme_kludge_create ();

  streamer->timer = krad_timer_create ();

  kr_audioport_connect(streamer->audioport);
  kr_videoport_activate (streamer->videoport);

  while (!destroy) {

    while (krad_ringbuffer_read_space (streamer->audio_ring[1]) >= 1024 * 4) {

      for (c = 0; c < streamer->params->channels; c++) {
        krad_ringbuffer_read (streamer->audio_ring[c],
                              (char *)amedium->a.samples[c],
                              1024 * 4);
      }

      amedium->a.count = 1024;
      amedium->a.channels = streamer->params->channels;

      ret = kr_vorbis_encode (streamer->vorbis_enc, acodeme, amedium);
      if (ret == 1) {
        kr_mkv_add_audio (streamer->mkv, 2,
                          acodeme->data,
                          acodeme->sz,
                          acodeme->count);
        muxdelay = 0;
        while (1) {
        ret = kr_vorbis_encode (streamer->vorbis_enc, acodeme, NULL);
        if (ret == 1) {
          kr_mkv_add_audio (streamer->mkv, 2,
                            acodeme->data,
                            acodeme->sz,
                            acodeme->count);
          } else {
            break;
          }
        }
      }
    }

    if (muxdelay > 0) {
      continue;
    }

    frame = NULL;
    frames = krad_ringbuffer_read_space (streamer->frame_ring) / sizeof(void *);

    if (frames > 1) {
      krad_vpx_encoder_deadline_set (streamer->vpx_enc, 1);
      sws_algo = SWS_POINT;
    }

    if (frames == 0) {
      krad_vpx_encoder_deadline_set (streamer->vpx_enc, 10000);
      sws_algo = SWS_BILINEAR;
      usleep (2000);
      continue;
    }

    if (frames > 0) {
      krad_ringbuffer_read (streamer->frame_ring,
                            (char *)&frame,
                            sizeof(krad_frame_t *));

      vmedium->v.tc = krad_timer_current_ms (streamer->timer);
      if (!krad_timer_started (streamer->timer)) {
        krad_timer_start (streamer->timer);
      }

      frame->yuv_pixels[0] = (uint8_t *)frame->pixels;
      frame->format = PIX_FMT_RGB32;
      frame->yuv_pixels[1] = NULL;
      frame->yuv_pixels[2] = NULL;
      frame->yuv_strides[0] = streamer->width * 4;
      frame->yuv_strides[1] = 0;
      frame->yuv_strides[2] = 0;
      frame->yuv_strides[3] = 0;

      converter = sws_getCachedContext ( converter,
                                         streamer->width,
                                         streamer->height,
                                         frame->format,
                                         streamer->params->width,
                                         streamer->params->height,
                                         PIX_FMT_YUV420P,
                                         sws_algo,
                                         NULL, NULL, NULL);

      if (converter == NULL) {
        failfast ("Krad streamer: could not sws_getCachedContext");
      }

      vmedium->v.pps[0] = streamer->params->width;
      vmedium->v.pps[1] = streamer->params->width/2;
      vmedium->v.pps[2] = streamer->params->width/2;
      vmedium->v.ppx[0] = vmedium->data;
      vmedium->v.ppx[1] = vmedium->data +
                          streamer->params->width * (streamer->params->height);
      vmedium->v.ppx[2] = vmedium->data + streamer->params->width *
                          (streamer->params->height) +
                          ((streamer->params->width * (streamer->params->height)) /4);

      sws_scale (converter,
                (const uint8_t * const*)frame->yuv_pixels,
                frame->yuv_strides,
                0,
                streamer->height,
                vmedium->v.ppx,
                vmedium->v.pps);

      krad_framepool_unref_frame (frame);

      ret = kr_vpx_encode (streamer->vpx_enc, vcodeme, vmedium);
      if (ret == 1) {
        kr_mkv_add_video_tc (streamer->mkv, 1,
                             vcodeme->data, vcodeme->sz,
                             vcodeme->key, vcodeme->tc);
      }

      printf ("\rKrad Streamer Frame# %12"PRIu64"",
              streamer->eframes++);
      fflush (stdout);

      //krad_ticker_wait (streamer->ticker);
    }
  }

  kr_medium_kludge_destroy (&vmedium);
  kr_codeme_kludge_destroy (&vcodeme);

  kr_medium_kludge_destroy (&amedium);
  kr_codeme_kludge_destroy (&acodeme);

  if (converter != NULL) {
    sws_freeContext (converter);
    converter = NULL;
  }

  krad_timer_destroy (streamer->timer);
}
Beispiel #10
0
static krad_stream_t *kr_stream_connect (char *host, int port) {

  krad_stream_t *stream;
  int ret;
  int flags;
  char port_string[6];
  struct in6_addr serveraddr;
  struct addrinfo hints;
  struct addrinfo *res;

  res = NULL;  

  if ((host == NULL) || ((port < 0) || (port > 65535))) {
    return NULL;
  }

  stream = calloc (1, sizeof(krad_stream_t));

  memset (&hints, 0, sizeof(hints));
  hints.ai_flags = AI_NUMERICSERV;
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  ret = inet_pton (AF_INET, host, &serveraddr);
  if (ret == 1) {
    hints.ai_family = AF_INET;
    hints.ai_flags |= AI_NUMERICHOST;
  } else {
    ret = inet_pton (AF_INET6, host, &serveraddr);
    if (ret == 1) {
      hints.ai_family = AF_INET6;
      hints.ai_flags |= AI_NUMERICHOST;
    }
  }
  snprintf (port_string, 6, "%d", port);
  ret = getaddrinfo (host, port_string, &hints, &res);
  if (ret != 0) {
    kr_stream_destroy (&stream);
    return NULL;
  }

  stream->sd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
  if (stream->sd < 0) {
    kr_stream_destroy (&stream);
  } else {
    flags = fcntl (stream->sd, F_GETFL, 0);
    if (flags == -1) {
      failfast ("Krad System: error on syscall fcntl F_GETFL");
    } else {
      flags |= O_NONBLOCK;
      ret = fcntl (stream->sd, F_SETFL, flags);
      if (ret == -1) {
        failfast ("Krad System: error on syscall fcntl F_SETFL");
      } else {
        ret = connect (stream->sd, res->ai_addr, res->ai_addrlen);
        if ((ret < 0) && (errno != EINPROGRESS)) {
          kr_stream_destroy (&stream);
        }
      }
    }
  }

  if (res != NULL) {
    freeaddrinfo (res);
  }

  return stream;
}
Beispiel #11
0
krad_opus_t *krad_opus_decoder_create (unsigned char *header_data, int header_length, float output_sample_rate) {

	int c;

	krad_opus_t *krad_opus = calloc (1, sizeof(krad_opus_t));

	krad_opus->output_sample_rate = output_sample_rate;

	krad_opus->opus_header = calloc (1, sizeof(OpusHeader));
	
	if (opus_header_parse (header_data, header_length, krad_opus->opus_header) != 1) {
		failfast ("krad_opus_decoder_create problem reading opus header");	
	}

	// oops
	//krad_opus->input_sample_rate = krad_opus->opus_header->input_sample_rate;

	krad_opus->channels = krad_opus->opus_header->channels;

	krad_opus->interleaved_samples = malloc(16 * 8192);
	
	for (c = 0; c < krad_opus->channels; c++) {
		krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->samples[c] = malloc (16 * 8192);
		krad_opus->read_samples[c] = malloc (16 * 8192);
		krad_opus->resampled_samples[c] = malloc (16 * 8192);

		krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]);
		if (krad_opus->src_resampler[c] == NULL) {
			failfast ("krad_opus_decoder_create src resampler error: %s", src_strerror (krad_opus->src_error[c]));
		}
	
		krad_opus->src_data[c].src_ratio = output_sample_rate / 48000;
	
		printk ("krad_opus_decoder_create src resampler ratio is: %f", krad_opus->src_data[c].src_ratio);	

	}

	krad_opus->streams = krad_opus->opus_header->nb_streams;
	krad_opus->coupled_streams = krad_opus->opus_header->nb_coupled;

	memcpy (krad_opus->mapping, krad_opus->opus_header->stream_map, 256);

	printk ("krad_opus_decoder_create channels %d streams %d coupled %d",
			krad_opus->channels,
			krad_opus->streams,
			krad_opus->coupled_streams
			);	

	krad_opus->decoder = opus_multistream_decoder_create (48000,
														  krad_opus->opus_header->channels,
														  krad_opus->streams,
														  krad_opus->coupled_streams,
														  krad_opus->mapping,
														  &krad_opus->opus_decoder_error);
	if (krad_opus->opus_decoder_error != OPUS_OK) {
		failfast ("Cannot create decoder: %s", opus_strerror (krad_opus->opus_decoder_error));
	}

	return krad_opus;

}
Beispiel #12
0
krad_opus_t *krad_opus_encoder_create (int channels, int input_sample_rate, int bitrate, int application) {

	int c;

	krad_opus_t *krad_opus = calloc(1, sizeof(krad_opus_t));

	krad_opus->opus_header = calloc(1, sizeof(OpusHeader));

	krad_opus->input_sample_rate = input_sample_rate;
	krad_opus->channels = channels;
	krad_opus->bitrate = bitrate;
	krad_opus->application = application;
	krad_opus->complexity = DEFAULT_OPUS_COMPLEXITY;
	krad_opus->signal = OPUS_AUTO;
	krad_opus->frame_size = DEFAULT_OPUS_FRAME_SIZE;
	krad_opus->bandwidth = OPUS_BANDWIDTH_FULLBAND;

	krad_opus->new_frame_size = krad_opus->frame_size;
	krad_opus->new_complexity = krad_opus->complexity;
	krad_opus->new_bitrate = krad_opus->bitrate;
	krad_opus->new_signal = krad_opus->signal;
	krad_opus->new_bandwidth = krad_opus->bandwidth;
	
	for (c = 0; c < krad_opus->channels; c++) {
		krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->samples[c] = malloc(16 * 8192);
		krad_opus->resampled_samples[c] = malloc(16 * 8192);
		krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]);
		if (krad_opus->src_resampler[c] == NULL) {
			failfast ("Krad Opus Encoder: src resampler error: %s", src_strerror (krad_opus->src_error[c]));
		}
		
		krad_opus->src_data[c].src_ratio = 48000.0 / krad_opus->input_sample_rate;
	}

	if (krad_opus->channels < 3) {

		krad_opus->streams = 1;
		
		if (krad_opus->channels == 2) {
			krad_opus->coupled_streams = 1;
			krad_opus->mapping[0] = 0;
			krad_opus->mapping[1] = 1;			
		} else {
			krad_opus->coupled_streams = 0;		
			krad_opus->mapping[0] = 0;
		}
		
		krad_opus->opus_header->channel_mapping = 0;

	} else {
		krad_opus->opus_header->channel_mapping = 1;

		switch (krad_opus->channels) {
			case 3:
				krad_opus->streams = 2;
				krad_opus->coupled_streams = 1;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 1;
				krad_opus->mapping[2] = 2;
			case 4:
				krad_opus->streams = 2;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 1;
				krad_opus->mapping[2] = 2;
				krad_opus->mapping[3] = 3;				
			case 5:
				krad_opus->streams = 3;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
			case 6:
				krad_opus->streams = 4;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 5;
			case 7:
				krad_opus->streams = 5;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 5;
				krad_opus->mapping[6] = 6;				
			case 8:
				krad_opus->streams = 5;
				krad_opus->coupled_streams = 3;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 6;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 4;
				krad_opus->mapping[6] = 5;
				krad_opus->mapping[7] = 7;				
		}
	}
	
	krad_opus->opus_header->channels = krad_opus->channels;
	krad_opus->opus_header->nb_streams = krad_opus->streams;
	krad_opus->opus_header->nb_coupled = krad_opus->coupled_streams;
	
	memcpy (krad_opus->opus_header->stream_map, krad_opus->mapping, 256);

	krad_opus->encoder = opus_multistream_encoder_create (48000,
														  krad_opus->channels,
														  krad_opus->streams,
														  krad_opus->coupled_streams,
														  krad_opus->mapping,
														  krad_opus->application,
														  &krad_opus->err);

	if (krad_opus->err != OPUS_OK) {
		failfast ("Krad Opus Encoder: Cannot create encoder: %s", opus_strerror (krad_opus->err));
	}
	

	opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_GET_LOOKAHEAD (&krad_opus->lookahead));
	krad_opus->opus_header->preskip = krad_opus->lookahead;

	krad_opus->opus_header->gain = 0;
	krad_opus->opus_header->input_sample_rate = 48000;
	
	if (opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE (krad_opus->bitrate)) != OPUS_OK) {
		failfast ("Krad Opus Encoder: bitrate request failed");
	}

	krad_opus->header_data_size = opus_header_to_packet (krad_opus->opus_header, krad_opus->header_data, 100);
	krad_opus->krad_codec_header.codec = OPUS;
	krad_opus->krad_codec_header.header[0] = krad_opus->header_data;
	krad_opus->krad_codec_header.header_size[0] = krad_opus->header_data_size;
	krad_opus->krad_codec_header.header_combined = krad_opus->header_data;
	krad_opus->krad_codec_header.header_combined_size = krad_opus->header_data_size;
	krad_opus->krad_codec_header.header_count = 2;

	krad_opus->krad_codec_header.header_size[1] = 
	8 + 4 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER=") + strlen (APPVERSION);
	
	krad_opus->opustags_header = calloc (1, krad_opus->krad_codec_header.header_size[1]);
	
	memcpy (krad_opus->opustags_header, "OpusTags", 8);
	
	krad_opus->opustags_header[8] = strlen (opus_get_version_string ());
	
	memcpy (krad_opus->opustags_header + 12, opus_get_version_string (), strlen (opus_get_version_string ()));

	krad_opus->opustags_header[12 + strlen (opus_get_version_string ())] = 1;

	krad_opus->opustags_header[12 + strlen (opus_get_version_string ()) + 4] = strlen ("ENCODER=") + strlen (APPVERSION);
	
	memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4, "ENCODER=", strlen ("ENCODER="));
	
	memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER="),
			APPVERSION,
			strlen (APPVERSION));	
	
	krad_opus->krad_codec_header.header[1] = krad_opus->opustags_header;
	
	return krad_opus;

}
Beispiel #13
0
int krad_opus_encoder_read (krad_opus_t *krad_opus, unsigned char *buffer, int *nframes) {

	int ready;
	int bytes;
	int resp;
	int s, c;

	while (krad_ringbuffer_read_space (krad_opus->ringbuf[krad_opus->channels - 1]) >= 512 * 4 ) {
		   
		for (c = 0; c < krad_opus->channels; c++) {

			krad_opus->ret = krad_ringbuffer_peek (krad_opus->ringbuf[c], (char *)krad_opus->samples[c], (512 * 4) );
			
			krad_opus->src_data[c].data_in = krad_opus->samples[c];
			krad_opus->src_data[c].input_frames = 512;
			krad_opus->src_data[c].data_out = krad_opus->resampled_samples[c];
			krad_opus->src_data[c].output_frames = 2048;
			krad_opus->src_error[c] = src_process (krad_opus->src_resampler[c], &krad_opus->src_data[c]);
			if (krad_opus->src_error[c] != 0) {
				failfast ("Krad Opus Encoder: src resampler error: %s\n", src_strerror(krad_opus->src_error[c]));
			}
			krad_ringbuffer_read_advance (krad_opus->ringbuf[c], (krad_opus->src_data[c].input_frames_used * 4) );
			krad_opus->ret = krad_ringbuffer_write (krad_opus->resampled_ringbuf[c],
										   (char *)krad_opus->resampled_samples[c],
										           (krad_opus->src_data[c].output_frames_gen * 4) );
		}
	}
	
	if (krad_opus->new_bitrate != krad_opus->bitrate) {
		krad_opus->bitrate = krad_opus->new_bitrate;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE(krad_opus->bitrate));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: bitrate request failed %s\n", opus_strerror (resp));
		} else {
			printk  ("Krad Opus Encoder: set opus bitrate %d\n", krad_opus->bitrate);
		}
	}
	
	if (krad_opus->new_frame_size != krad_opus->frame_size) {
		krad_opus->frame_size = krad_opus->new_frame_size;
		printk ("Krad Opus Encoder: frame size is now %d\n", krad_opus->frame_size);		
	}
	
	if (krad_opus->new_complexity != krad_opus->complexity) {
		krad_opus->complexity = krad_opus->new_complexity;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_COMPLEXITY(krad_opus->complexity));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: complexity request failed %s. \n", opus_strerror(resp));
		} else {
			printk ("Krad Opus Encoder: set opus complexity %d\n", krad_opus->complexity);
		}
	}	

	if (krad_opus->new_signal != krad_opus->signal) {
		krad_opus->signal = krad_opus->new_signal;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_SIGNAL(krad_opus->signal));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: signal request failed %s\n", opus_strerror(resp));
		} else {
			printk ("Krad Opus Encoder: set opus signal mode %d\n", krad_opus->signal);
		}
	}
	
	if (krad_opus->new_bandwidth != krad_opus->bandwidth) {
		krad_opus->bandwidth = krad_opus->new_bandwidth;
		resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BANDWIDTH(krad_opus->bandwidth));
		if (resp != OPUS_OK) {
			failfast ("Krad Opus Encoder: bandwidth request failed %s\n", opus_strerror(resp));
		} else {
			printk ("Krad Opus Encoder: Set Opus bandwidth mode %d\n", krad_opus->bandwidth);
		}
	}
		
	ready = 1;
	
	for (c = 0; c < krad_opus->channels; c++) {
		if (krad_ringbuffer_read_space (krad_opus->resampled_ringbuf[c]) < krad_opus->frame_size * 4) {
			ready = 0;
		}
	}

	if (ready == 1) {

		for (c = 0; c < krad_opus->channels; c++) {
			krad_opus->ret = krad_ringbuffer_read (krad_opus->resampled_ringbuf[c],
										  (char *)krad_opus->resampled_samples[c],
										          (krad_opus->frame_size * 4) );
		}

		for (s = 0; s < krad_opus->frame_size; s++) {
			for (c = 0; c < krad_opus->channels; c++) {
				krad_opus->interleaved_resampled_samples[s * krad_opus->channels + c] = krad_opus->resampled_samples[c][s];
			}
		}

		bytes = opus_multistream_encode_float (krad_opus->encoder,
											   krad_opus->interleaved_resampled_samples,
											   krad_opus->frame_size,
											   buffer,
											   krad_opus->frame_size * 2);

		if (bytes < 0) {
			failfast ("Krad Opus Encoding failed: %s.", opus_strerror (bytes));
		}

		*nframes = krad_opus->frame_size;

		return bytes;
	}
	
	return 0;

}