ftl_status_t media_init()

in libftl/media.c [95:218]


ftl_status_t media_init(ftl_stream_configuration_private_t *ftl) {

  ftl_media_config_t *media = &ftl->media;
  ftl_status_t status = FTL_SUCCESS;
  int idx;

  if (ftl_get_state(ftl, FTL_MEDIA_READY)) {
    return FTL_SUCCESS;
  }

  do {
    os_init_mutex(&media->mutex);
    os_init_mutex(&ftl->video.mutex);
    os_init_mutex(&ftl->audio.mutex);

    //use the same socket family as the control connection
    media->media_socket = socket(ftl->socket_family, SOCK_DGRAM, IPPROTO_UDP);
    if (media->media_socket == -1) {
            return FTL_DNS_FAILURE;
    }

    if ((status = _get_addr_info(ftl->socket_family, ftl->ingest_ip, media->assigned_port, &media->ingest_addr, &media->ingest_addrlen)) != FTL_SUCCESS) {
            return status;
    }

    media->max_mtu = MAX_MTU;
    gettimeofday(&media->stats_tv, NULL);
    media->sender_report_base_ntp.tv_usec = 0;
    media->sender_report_base_ntp.tv_sec = 0;

    ftl_media_component_common_t *media_comp[] = { &ftl->video.media_component, &ftl->audio.media_component };
    ftl_media_component_common_t *comp;

    for (idx = 0; idx < sizeof(media_comp) / sizeof(media_comp[0]); idx++) {

      comp = media_comp[idx];

      comp->nack_slots_initalized = FALSE;

      if ((status = _nack_init(comp)) != FTL_SUCCESS) {
        goto cleanup;
      }

      // According to RTP the time stamps should start at random values,
      // but to help sync issues and to make sync easier to calculate we
      // start at 0.
      comp->timestamp = 0;
      comp->producer = 0;
      comp->consumer = 0;
      comp->base_dts_usec = -1;

      _clear_stats(&comp->stats);
    }

    ftl->video.media_component.timestamp_clock = VIDEO_RTP_TS_CLOCK_HZ;
    ftl->audio.media_component.timestamp_clock = AUDIO_SAMPLE_RATE;
    ftl->audio.is_ready_to_send = FALSE;
    ftl->video.has_sent_first_frame = FALSE;

    ftl->video.wait_for_idr_frame = TRUE;

    // We need set this flag now so it is ready when the thread starts, but also
    // so it is set if we destroy this before the thread starts it will be cleaned up.
    ftl_set_state(ftl, FTL_RX_THRD);
    if ((os_create_thread(&media->recv_thread, NULL, recv_thread, ftl)) != 0) {
      ftl_clear_state(ftl, FTL_RX_THRD);
      status = FTL_MALLOC_FAILURE;
      break;
    }

    if (os_semaphore_create(&ftl->video.media_component.pkt_ready, "/VideoPkt", O_CREAT, 0) < 0) {
      status = FTL_MALLOC_FAILURE;
      break;
    }

    if (os_semaphore_create(&ftl->audio.media_component.pkt_ready, "/AudioPkt", O_CREAT, 0) < 0) {
        status = FTL_MALLOC_FAILURE;
        break;
    }

    // We need set this flag now so it is ready when the thread starts, but also
    // so it is set if we destroy this before the thread starts it will be cleaned up.
    ftl_set_state(ftl, FTL_TX_THRD);
    if ((os_create_thread(&media->video_send_thread, NULL, video_send_thread, ftl)) != 0) {
      ftl_clear_state(ftl, FTL_TX_THRD);
      status = FTL_MALLOC_FAILURE;
      break;
    }

    // We need set this flag now so it is ready when the thread starts, but also
    // so it is set if we destroy this before the thread starts it will be cleaned up.
    ftl_set_state(ftl, FTL_TX_THRD);
    if ((os_create_thread(&media->audio_send_thread, NULL, audio_send_thread, ftl)) != 0) {
        ftl_clear_state(ftl, FTL_TX_THRD);
        status = FTL_MALLOC_FAILURE;
        break;
    }

    if (os_semaphore_create(&media->ping_thread_shutdown, "/PingThreadShutdown", O_CREAT, 0) < 0) {
      status = FTL_MALLOC_FAILURE;
      break;
    }

    // We need set this flag now so it is ready when the thread starts, but also
    // so it is set if we destroy this before the thread starts it will be cleaned up.
    ftl_set_state(ftl, FTL_PING_THRD);
    if ((os_create_thread(&media->ping_thread, NULL, ping_thread, ftl)) != 0) {
      ftl_clear_state(ftl, FTL_PING_THRD);
      status = FTL_MALLOC_FAILURE;
      break;
    }

    ftl_clear_state(ftl, FTL_SPEED_TEST);

    ftl_set_state(ftl, FTL_MEDIA_READY);

    return FTL_SUCCESS;
  } while (0);
cleanup:

  _internal_media_destroy(ftl);

  return status;
}