diff --git a/libpdraw-vsink/include/pdraw-vsink/pdraw_vsink.h b/libpdraw-vsink/include/pdraw-vsink/pdraw_vsink.h index e567c7b..49c1ce4 100644 --- a/libpdraw-vsink/include/pdraw-vsink/pdraw_vsink.h +++ b/libpdraw-vsink/include/pdraw-vsink/pdraw_vsink.h @@ -63,11 +63,14 @@ struct pdraw_vsink; * @param media_info: media info pointer to fill if not NULL. * Note: mdeia_info will be freed in pdraw_vsink_stop(). * @param ret_obj: pdraw_vsink instance handle (output) + * @param : timeout in second to connect (input) + * Note: 0 doesn't use a timeout * @return 0 on success, negative errno value in case of error */ PDRAW_VSINK_API int pdraw_vsink_start(const char *url, struct pdraw_media_info **media_info, - struct pdraw_vsink **ret_obj); + struct pdraw_vsink **ret_obj, + time_t timeout_seconds); /** @@ -86,14 +89,16 @@ PDRAW_VSINK_API int pdraw_vsink_stop(struct pdraw_vsink *self); * @param frame_memory: memory used by the frame (optional) * @param frame_info: frame information (output) * @param ret_frame: frame (output) + * @param timeout_seconds: timeout in second to get frame (input) + * Note: 0 doesn't use a timeout * @return 0 on success, negative errno value in case of error */ PDRAW_VSINK_API int pdraw_vsink_get_frame(struct pdraw_vsink *self, struct mbuf_mem *frame_memory, struct pdraw_video_frame *frame_info, - struct mbuf_raw_video_frame **ret_frame); -/* TODO: Add timeout !!! */ + struct mbuf_raw_video_frame **ret_frame, + time_t timeout_seconds); #ifdef __cplusplus diff --git a/libpdraw-vsink/src/pdraw_vsink.c b/libpdraw-vsink/src/pdraw_vsink.c index 52cde12..d1e07cc 100644 --- a/libpdraw-vsink/src/pdraw_vsink.c +++ b/libpdraw-vsink/src/pdraw_vsink.c @@ -403,7 +403,8 @@ static void stop_pdraw_idle(void *userdata) int pdraw_vsink_start(const char *url, struct pdraw_media_info **media_info, - struct pdraw_vsink **ret_obj) + struct pdraw_vsink **ret_obj, + time_t timeout_seconds) { int res, err; @@ -457,10 +458,27 @@ int pdraw_vsink_start(const char *url, } pthread_mutex_lock(&self->mutex); - pthread_cond_wait(&self->cond, &self->mutex); + + if(timeout_seconds > 0) + { + // Create timeout value + struct timespec max_wait = {0, 0}; + const int gettime_rv = clock_gettime(CLOCK_REALTIME, &max_wait); + max_wait.tv_sec += timeout_seconds; + const time_wait = pthread_cond_timedwait(&self->cond, &self->mutex, &max_wait); + } + else{ + pthread_cond_wait(&self->cond, &self->mutex); + } + res = self->result; pthread_mutex_unlock(&self->mutex); + if(time_wait) { + ULOG_ERRNO("mbuf_raw_video_frame_queue_pop timeout", -res); + goto error; + } + if (res < 0) { ULOG_ERRNO("failed to start pdraw vsink", -res); goto error; @@ -528,7 +546,8 @@ int pdraw_vsink_stop(struct pdraw_vsink *self) int pdraw_vsink_get_frame(struct pdraw_vsink *self, struct mbuf_mem *frame_memory, struct pdraw_video_frame *frame_info, - struct mbuf_raw_video_frame **ret_frame) + struct mbuf_raw_video_frame **ret_frame, + time_t timeout_seconds) { int res; struct mbuf_raw_video_frame *in_frame = NULL; @@ -548,8 +567,25 @@ int pdraw_vsink_get_frame(struct pdraw_vsink *self, res = mbuf_raw_video_frame_queue_pop(self->queue, &in_frame); if (res == -EAGAIN) { pthread_mutex_lock(&self->mutex); - pthread_cond_wait(&self->cond, &self->mutex); + + if(timeout_seconds > 0) + { + // Create timeout value + struct timespec max_wait = {0, 0}; + const int gettime_rv = clock_gettime(CLOCK_REALTIME, &max_wait); + max_wait.tv_sec += timeout_seconds; + res = pthread_cond_timedwait(&self->cond, &self->mutex, &max_wait); + } + else{ + pthread_cond_wait(&self->cond, &self->mutex); + } + pthread_mutex_unlock(&self->mutex); + + if(res) { + ULOG_ERRNO("mbuf_raw_video_frame_queue_pop timeout", -res); + return res; + } } else if (res < 0) { ULOG_ERRNO("mbuf_raw_video_frame_queue_pop", -res); return res;