From dd4c2fc328a1332642660de376baf0b8b6024874 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Wed, 15 Jul 2020 02:00:47 -0700 Subject: get_frame: refresh capture_frameno post acquire Acquiring the new frame can take a potentially significant amount of time, rather than letting any frames dropped during the acquire get all taken by the next frame, update this one to include them. It's both more accurate (the dropped frames occurred literally while this was going on) and makes it more likely get_frame() will have to wait on the upcoming cond_wait(time_cond) for the next tick. If the upcoming cond_wait(time_cond) doesn't wait because a new frame is already pending, it makes it more likely get_frame() will snatch yuv_mutex before the encode/cache thread can wake up and grab it. When that occurs it's effectively dropping frames because the encode/cache thread gets blocked on yuv_mutex while the contents get replaced, so the frames the previous contents were going to be applied to will instead get the updated contents that belong to the future sample's frames. --- src/rmd_get_frame.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/rmd_get_frame.c b/src/rmd_get_frame.c index 5c6e800..50a58ce 100644 --- a/src/rmd_get_frame.c +++ b/src/rmd_get_frame.c @@ -580,11 +580,26 @@ void *rmdGetFrame(ProgData *pdata) { if (!pdata->args.full_shots) rmdClearList(&pdata->rect_root); + /* Since frame acquisition may take a long and variable time, update + * frameno again just in case we've missed some so they can be included + * as this frame by the encoder. + */ + pthread_mutex_lock(&pdata->time_mutex); + time_frameno = pdata->time_frameno; + pthread_mutex_unlock(&pdata->time_mutex); + /* notify the encoder of the new frame */ pthread_mutex_lock(&pdata->img_buff_ready_mutex); pdata->capture_frameno = time_frameno; pthread_cond_signal(&pdata->image_buffer_ready); pthread_mutex_unlock(&pdata->img_buff_ready_mutex); + + /* XXX: note if the encoder thread doesn't manage to wake up and grab the yuv_mutex + * before this thread does in response to another tick, then the frame just + * submitted is lost and the encoder thread will wait again for another frame. + * In practice if this never happens it's irrelevant, but if it proves to be an + * issue there are options. + */ } if (!pdata->args.noframe) -- cgit v1.2.3