OS_THREAD_ROUTINE video_send_thread()

in libftl/media.c [1197:1277]


OS_THREAD_ROUTINE video_send_thread(void *data)
{
  ftl_stream_configuration_private_t *ftl = (ftl_stream_configuration_private_t *)data;
  ftl_media_config_t *media = &ftl->media;
  ftl_media_component_common_t *video = &ftl->video.media_component;

  int first_packet = 1;
  int bytes_per_ms;
  int pkt_sent;
  int video_kbps = -1;
  int disable_flow_control = 1;
  int initial_peak_kbps;

  int transmit_level;
  struct timeval start_tv;

#ifdef _WIN32
  if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
    FTL_LOG(ftl, FTL_LOG_WARN, "Failed to set recv_thread priority to THREAD_PRIORITY_TIME_CRITICAL\n");
  }
#endif

  initial_peak_kbps = video->kbps = video->peak_kbps;
  video_kbps = 0;
  transmit_level = 5 * video->kbps * 1000 / 8 / 1000; /*small initial level to prevent bursting at the start of a stream*/

  while (1) {

    if (initial_peak_kbps != video->peak_kbps) {
      initial_peak_kbps = video->kbps = video->peak_kbps;
    }

    if (video->kbps != video_kbps) {
      bytes_per_ms = video->kbps * 1000 / 8 / 1000;
      video_kbps = video->kbps;

      disable_flow_control = 0;
      if (video_kbps <= 0) {
        disable_flow_control = 1;
      }
    }

    os_semaphore_pend(&video->pkt_ready, FOREVER);

    if (!ftl_get_state(ftl, FTL_TX_THRD)) {
      break;
    }

    if (disable_flow_control) {
      _media_send_packet(ftl, video);
    }
    else {
      pkt_sent = 0;
      if (first_packet) {
        gettimeofday(&start_tv, NULL);
        first_packet = 0;
      }

      _update_xmit_level(ftl, &transmit_level, &start_tv, bytes_per_ms);
      while (!pkt_sent && ftl_get_state(ftl, FTL_TX_THRD)) {

        if (transmit_level <= 0) {
          ftl->video.media_component.stats.bw_throttling_count++;
          sleep_ms(MAX_MTU / bytes_per_ms + 1);
          _update_xmit_level(ftl, &transmit_level, &start_tv, bytes_per_ms);
        }

        if (transmit_level > 0) {
          transmit_level -= _media_send_packet(ftl, video);
          pkt_sent = 1;
        }
      }

    }

    _update_stats(ftl);
  }

  FTL_LOG(ftl, FTL_LOG_INFO, "Exited Send Thread\n");
  return (OS_THREAD_TYPE)0;
}