From 19a7c45b7b4adcd13b5481697f5cb82ba378918b Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Wed, 15 Jul 2020 01:52:27 -0700 Subject: timer: maintain video side of avd in frame timer Since the frame timer implements a frame counter, and that frame count is propagated through the get->encode pipeline for samples that get through, any missed frames are noticed and dealt with making it not lossy from the point of the timer down to the encoded stream in terms of number of frames. It's certainly lossy in terms of the contents of those frames, but synchronization is all about the temporal domain and as long as the frame counts all make it into the stream as frames, we can account for them at the timer in terms of avd. This in combination with the other commit moving the audio side of avd maintenance immediately upon capture into the raw buffer, shrinks the variable capacitance separating the audio timer and the frame timer to virtually nil. As a consequence, the frame timer can now be much more accurate in terms of how much longer/less to sleep or if a frame should be dropped to get the timer caught up. When avd was being maintained at points far removed from the actual things they represented there was too much elastic capacitance in there for sync_streams() to inform its adjustment accurately. --- src/rmd_cache_frame.c | 7 +------ src/rmd_encode_image_buffer.c | 4 ---- src/rmd_timer.c | 7 +++++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/rmd_cache_frame.c b/src/rmd_cache_frame.c index 5c0ea5b..cae1c14 100644 --- a/src/rmd_cache_frame.c +++ b/src/rmd_cache_frame.c @@ -105,7 +105,7 @@ void *rmdCacheImageBuffer(ProgData *pdata) { v_short_blocks[blocknum_x * blocknum_y]; unsigned long long int total_bytes = 0; unsigned long long int total_received_bytes = 0; - unsigned int capture_frameno = 0, last_capture_frameno = 0; + unsigned int capture_frameno = 0; rmdThreadsSetName("rmdCacheImages"); @@ -255,9 +255,6 @@ void *rmdCacheImageBuffer(ProgData *pdata) { nbytes += rmdFlushBlock(NULL, 0, 0, 0, 0, fp, ucfp, 1); /**@________________@**/ - pthread_mutex_lock(&pdata->avd_mutex); - pdata->avd += pdata->frametime * (capture_frameno - last_capture_frameno); - pthread_mutex_unlock(&pdata->avd_mutex); if (nbytes > CACHE_FILE_SIZE_LIMIT) { if (rmdSwapCacheFilesWrite(pdata->cache_data->imgdata, nth_cache, &fp, &ucfp)) { @@ -281,8 +278,6 @@ void *rmdCacheImageBuffer(ProgData *pdata) { nth_cache++; nbytes = 0; } - - last_capture_frameno = capture_frameno; } total_bytes += nbytes; diff --git a/src/rmd_encode_image_buffer.c b/src/rmd_encode_image_buffer.c index 5b08620..bfb3888 100644 --- a/src/rmd_encode_image_buffer.c +++ b/src/rmd_encode_image_buffer.c @@ -77,10 +77,6 @@ void *rmdEncodeImageBuffer(ProgData *pdata) { pthread_mutex_unlock(&pdata->libogg_mutex); } - pthread_mutex_lock(&pdata->avd_mutex); - pdata->avd += pdata->frametime * n_frames; - pthread_mutex_unlock(&pdata->avd_mutex); - last_encode_frameno = encode_frameno; } diff --git a/src/rmd_timer.c b/src/rmd_timer.c index a523166..dd7b26c 100644 --- a/src/rmd_timer.c +++ b/src/rmd_timer.c @@ -51,8 +51,7 @@ static void sync_streams(ProgData *pdata, unsigned int *frame_step, struct times int avd; pthread_mutex_lock(&pdata->avd_mutex); - avd = pdata->avd; - pthread_mutex_unlock(&pdata->avd_mutex); + avd = pdata->avd + pdata->frametime; /* There are two knobs available for keeping the video synchronized with the audio: * 1. frame_step; how many frames to encode from this frame (aka dropping frames if > 1) @@ -72,6 +71,7 @@ static void sync_streams(ProgData *pdata, unsigned int *frame_step, struct times if (frames_behind > 0) { /* more than a whole frame behind, drop frames to catch up */ *frame_step += frames_behind; + avd += frames_behind * pdata->frametime; } else { /* less than a whole frame behind, just sleep less */ *delay = us_to_timespec(pdata->frametime + avd); @@ -82,6 +82,9 @@ static void sync_streams(ProgData *pdata, unsigned int *frame_step, struct times *delay = us_to_timespec(pdata->frametime + avd); } + pdata->avd = avd; + pthread_mutex_unlock(&pdata->avd_mutex); + #if 0 printf("avd: %i frame_step: %u delay: %lu,%lu\n", avd, *frame_step, (*delay).tv_sec, (*delay).tv_nsec); -- cgit v1.2.1