diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2020-07-15 02:00:47 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2020-07-15 02:00:47 -0700 |
commit | dd4c2fc328a1332642660de376baf0b8b6024874 (patch) | |
tree | 282cd88956cce69f297844b7e51fe9d5642202ca /src | |
parent | 19a7c45b7b4adcd13b5481697f5cb82ba378918b (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/rmd_get_frame.c | 15 |
1 files changed, 15 insertions, 0 deletions
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) |