summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-07-15 02:00:47 -0700
committerVito Caputo <vcaputo@pengaru.com>2020-07-15 02:00:47 -0700
commitdd4c2fc328a1332642660de376baf0b8b6024874 (patch)
tree282cd88956cce69f297844b7e51fe9d5642202ca
parent19a7c45b7b4adcd13b5481697f5cb82ba378918b (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.
-rw-r--r--src/rmd_get_frame.c15
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)
© All Rights Reserved