summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-07-14 18:49:21 -0700
committerVito Caputo <vcaputo@pengaru.com>2020-07-14 18:49:21 -0700
commit79cc627a9acae89d05b4e0c213b97ad4c0aec619 (patch)
tree46a7cfeedcab2b79e0b81d8e5f7a651d6ead690a
parent5ce6553ccf5502fc71d11d654c76bd1714cd36dd (diff)
timer: don't advance time_frameno when paused
This requires a bit of adjustment in the get_frame time_cond wait loop so it still services the event loop when woken without advance At least now get_frame has no explicit pause code, but it does require the timer keep firing while paused so it signals time_cond.
-rw-r--r--src/rmd_get_frame.c26
-rw-r--r--src/rmd_timer.c21
2 files changed, 30 insertions, 17 deletions
diff --git a/src/rmd_get_frame.c b/src/rmd_get_frame.c
index 4f8343a..5c6e800 100644
--- a/src/rmd_get_frame.c
+++ b/src/rmd_get_frame.c
@@ -332,9 +332,22 @@ void *rmdGetFrame(ProgData *pdata) {
unsigned time_frameno;
pthread_mutex_lock(&pdata->time_mutex);
- while (pdata->capture_frameno >= pdata->time_frameno)
+ while (pdata->capture_frameno >= pdata->time_frameno) {
pthread_cond_wait(&pdata->time_cond, &pdata->time_mutex);
+ if (pdata->capture_frameno >= pdata->time_frameno) {
+ /* *Likely* paused, but could be a spurious wakeup.
+ * either way, it's harmless to service the event loop
+ * before waiting again. This is how the timer keeps
+ * the event loop serviced by signaling us without
+ * advancing time_frameno.
+ */
+ pthread_mutex_unlock(&pdata->time_mutex);
+ rmdEventLoop(pdata);
+ pthread_mutex_lock(&pdata->time_mutex);
+ }
+ }
+
time_frameno = pdata->time_frameno;
pthread_mutex_unlock(&pdata->time_mutex);
@@ -342,17 +355,6 @@ void *rmdGetFrame(ProgData *pdata) {
//events (if not full_shots)
rmdEventLoop(pdata);
- if (pdata->paused) {
- /* This is a bit janky, but there's need to service the event loop
- * when paused, so instead of blocking on pause_cond, a short sleep
- * is performed.
- * Since the timer keeps running currently when paused, the above
- * cond_wait() will never prevent us from reaching here.
- */
- nanosleep(&(struct timespec){ .tv_nsec = 50000000 }, NULL);
- continue;
- }
-
//switch back and front buffers (full_shots only)
if (d_buff)
img_sel = img_sel ? 0 : 1;
diff --git a/src/rmd_timer.c b/src/rmd_timer.c
index f584bf2..a523166 100644
--- a/src/rmd_timer.c
+++ b/src/rmd_timer.c
@@ -113,14 +113,25 @@ void *rmdTimer(ProgData *pdata) {
}
}
+ /* When paused, stop advancing time_frameno, get_frame only progresses
+ * when time_frameno > capture_frameno. But get_frame needs to service
+ * the event loop even when paused, so still signal time_cond just with
+ * pdata->time_frameno frozen. get_frame will then handle time_cond
+ * wakeups where capture_frameno >= time_frameno as "poll events".
+ */
+ if (pdata->paused)
+ frame_step = 0;
pthread_mutex_unlock(&pdata->pause_mutex);
- if (!pdata->args.nosound)
- sync_streams(pdata, &frame_step, &delay);
+ if (frame_step) {
+ if (!pdata->args.nosound)
+ sync_streams(pdata, &frame_step, &delay);
+
+ pthread_mutex_lock(&pdata->time_mutex);
+ pdata->time_frameno += frame_step;
+ pthread_mutex_unlock(&pdata->time_mutex);
+ }
- pthread_mutex_lock(&pdata->time_mutex);
- pdata->time_frameno += frame_step;
- pthread_mutex_unlock(&pdata->time_mutex);
pthread_cond_signal(&pdata->time_cond);
nanosleep(&delay, NULL);
© All Rights Reserved