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;
}