Add pull_frame(timeout)

Instead of blocking until the library is destroyed, add ability
to block at most N milliseconds before returning.

The code returns early if a frame is received within the specified
timeframe but will block at most "timeout "milliseconds
This commit is contained in:
Aaro Altonen 2020-05-11 17:36:13 +03:00
parent 037ea2b146
commit 7b73aede33
4 changed files with 40 additions and 0 deletions

View File

@ -84,8 +84,13 @@ namespace uvg_rtp {
* NOTE: pull_frame() is a blocking operation and a separate thread should be
* spawned for it!
*
* You can specify for how long should pull_frame() block by giving "timeout"
* parameter that denotes how long pull_frame() will wait for an incoming frame
* in milliseconds
*
* Return pointer to RTP frame on success */
uvg_rtp::frame::rtp_frame *pull_frame();
uvg_rtp::frame::rtp_frame *pull_frame(size_t timeout);
/* Alternative to pull_frame(). The provided hook is called when a frame is received.
*

View File

@ -28,6 +28,9 @@ namespace uvg_rtp {
/* NOTE: this operation is blocking */
uvg_rtp::frame::rtp_frame *pull_frame();
/* Block at most "timeout" milliseconds and return nullptr if nothing was received */
uvg_rtp::frame::rtp_frame *pull_frame(size_t timeout);
/* Open socket, start frame receiver and RTCP
*
* Return RTP_OK on success

View File

@ -223,6 +223,17 @@ uvg_rtp::frame::rtp_frame *uvg_rtp::media_stream::pull_frame()
return receiver_->pull_frame();
}
uvg_rtp::frame::rtp_frame *uvg_rtp::media_stream::pull_frame(size_t timeout)
{
if (!initialized_) {
LOG_ERROR("RTP context has not been initialized fully, cannot continue!");
rtp_errno = RTP_NOT_INITIALIZED;
return nullptr;
}
return receiver_->pull_frame(timeout);
}
rtp_error_t uvg_rtp::media_stream::install_receive_hook(void *arg, void (*hook)(void *, uvg_rtp::frame::rtp_frame *))
{
if (!initialized_) {

View File

@ -84,6 +84,27 @@ uvg_rtp::frame::rtp_frame *uvg_rtp::receiver::pull_frame()
return frame;
}
uvg_rtp::frame::rtp_frame *uvg_rtp::receiver::pull_frame(size_t timeout)
{
while (frames_.empty() && this->active() && timeout) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
--timeout;
}
if (!this->active())
return nullptr;
if (frames_.empty())
return nullptr;
frames_mtx_.lock();
auto frame = frames_.front();
frames_.erase(frames_.begin());
frames_mtx_.unlock();
return frame;
}
uint8_t *uvg_rtp::receiver::get_recv_buffer() const
{
return recv_buf_;