diff --git a/include/uvgrtp/util.hh b/include/uvgrtp/util.hh index 2e1ad70..efa72be 100644 --- a/include/uvgrtp/util.hh +++ b/include/uvgrtp/util.hh @@ -391,6 +391,14 @@ enum RTP_CTX_CONFIGURATION_FLAGS { */ RCC_SESSION_BANDWIDTH = 12, + /** Set the timeout value for socket polling + * + * Default value is 100 ms. If you are experiencing packet loss when receiving, you can try + * lowering this value down to 0. This will, however cause a busy loop in the receiver, so + * use with caution. + */ + RCC_POLL_TIMEOUT = 13, + /// \cond DO_NOT_DOCUMENT RCC_LAST /// \endcond diff --git a/src/media_stream.cc b/src/media_stream.cc index 2a5e8aa..4fbfdf2 100644 --- a/src/media_stream.cc +++ b/src/media_stream.cc @@ -777,6 +777,12 @@ rtp_error_t uvgrtp::media_stream::configure_ctx(int rcc_flag, ssize_t value) return ret; } + else if (rcc_flag == RCC_POLL_TIMEOUT) { + if (reception_flow_) { + reception_flow_->set_poll_timeout_ms((int)value); + } + return ret; + } if (!initialized_) { UVG_LOG_ERROR("RTP context has not been initialized fully, cannot continue!"); @@ -952,6 +958,9 @@ int uvgrtp::media_stream::get_configuration_value(int rcc_flag) case RCC_SESSION_BANDWIDTH: { return (int)bandwidth_; } + case RCC_POLL_TIMEOUT: { + return reception_flow_->get_poll_timeout_ms(); + } default: ret = -1; } diff --git a/src/reception_flow.cc b/src/reception_flow.cc index 70226d9..db1b59d 100644 --- a/src/reception_flow.cc +++ b/src/reception_flow.cc @@ -38,6 +38,7 @@ uvgrtp::reception_flow::reception_flow(bool ipv6) : user_hook_arg_(nullptr), user_hook_(nullptr), packet_handlers_({}), + poll_timeout_ms_(100), ring_buffer_(), ring_read_index_(-1), // invalid first index that will increase to a valid one last_ring_write_index_(-1), @@ -118,6 +119,16 @@ void uvgrtp::reception_flow::set_payload_size(const size_t& value) create_ring_buffer(); } +void uvgrtp::reception_flow::set_poll_timeout_ms(int timeout_ms) +{ + poll_timeout_ms_ = timeout_ms; +} + +int uvgrtp::reception_flow::get_poll_timeout_ms() +{ + return poll_timeout_ms_; +} + rtp_error_t uvgrtp::reception_flow::start(std::shared_ptr socket, int rce_flags) { std::lock_guard lg(active_mutex_); @@ -423,13 +434,11 @@ void uvgrtp::reception_flow::receiver(std::shared_ptr socket) pfds->fd = read_fds; pfds->events = POLLIN; - // exits after this time if no data has been received to check whether we should exit - int timeout_ms = 100; - + // exits after poll_timeout_ms_ time if no data has been received to check whether we should exit #ifdef _WIN32 - if (WSAPoll(pfds, 1, timeout_ms) < 0) { + if (WSAPoll(pfds, 1, poll_timeout_ms_) < 0) { #else - if (poll(pfds, 1, timeout_ms) < 0) { + if (poll(pfds, 1, poll_timeout_ms_) < 0) { #endif UVG_LOG_ERROR("poll(2) failed"); if (pfds) diff --git a/src/reception_flow.hh b/src/reception_flow.hh index e6117ac..f1133fa 100644 --- a/src/reception_flow.hh +++ b/src/reception_flow.hh @@ -153,6 +153,8 @@ namespace uvgrtp { void set_buffer_size(const ssize_t& value); ssize_t get_buffer_size() const; void set_payload_size(const size_t& value); + void set_poll_timeout_ms(int timeout_ms); + int get_poll_timeout_ms(); rtp_error_t install_user_hook(void* arg, void (*hook)(void*, uint8_t* data, uint32_t len)); /// \endcond @@ -209,6 +211,8 @@ namespace uvgrtp { // Map different types of handlers by remote SSRC std::unordered_map packet_handlers_; + int poll_timeout_ms_; + std::vector ring_buffer_; std::mutex handlers_mutex_; std::mutex ring_mutex_;