From 2a94a2b119a9efd2cd06ded03280872c81abe6b4 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 11 Apr 2021 15:01:05 +0200 Subject: [PATCH] Remove video_buffer callbacks Now that screen is both the owner and the listener of the video buffer, execute the code directly without callbacks. --- app/src/screen.c | 49 ++++++++++++++++++------------------------ app/src/video_buffer.c | 31 +++++--------------------- app/src/video_buffer.h | 20 +---------------- 3 files changed, 27 insertions(+), 73 deletions(-) diff --git a/app/src/screen.c b/app/src/screen.c index c067ab7a..ddf81b08 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -193,27 +193,6 @@ screen_update_content_rect(struct screen *screen) { } } -static void -on_frame_available(struct video_buffer *vb, void *userdata) { - (void) vb; - (void) userdata; - - static SDL_Event new_frame_event = { - .type = EVENT_NEW_FRAME, - }; - - // Post the event on the UI thread - SDL_PushEvent(&new_frame_event); -} - -static void -on_frame_skipped(struct video_buffer *vb, void *userdata) { - (void) vb; - - struct screen *screen = userdata; - fps_counter_add_skipped_frame(screen->fps_counter); -} - static inline SDL_Texture * create_texture(struct screen *screen) { SDL_Renderer *renderer = screen->renderer; @@ -284,7 +263,27 @@ screen_frame_sink_close(struct sc_frame_sink *sink) { static bool screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) { struct screen *screen = DOWNCAST(sink); - return video_buffer_push(&screen->vb, frame); + + bool previous_frame_skipped; + bool ok = video_buffer_push(&screen->vb, frame, &previous_frame_skipped); + if (!ok) { + return false; + } + + if (previous_frame_skipped) { + fps_counter_add_skipped_frame(screen->fps_counter); + // The EVENT_NEW_FRAME triggered for the previous frame will consume + // this new frame instead + } else { + static SDL_Event new_frame_event = { + .type = EVENT_NEW_FRAME, + }; + + // Post the event on the UI thread + SDL_PushEvent(&new_frame_event); + } + + return true; } bool @@ -303,12 +302,6 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter, return false; } - static const struct video_buffer_callbacks cbs = { - .on_frame_available = on_frame_available, - .on_frame_skipped = on_frame_skipped, - }; - video_buffer_set_consumer_callbacks(&screen->vb, &cbs, screen); - screen->frame_size = params->frame_size; screen->rotation = params->rotation; if (screen->rotation) { diff --git a/app/src/video_buffer.c b/app/src/video_buffer.c index 18a180fa..7adf098b 100644 --- a/app/src/video_buffer.c +++ b/app/src/video_buffer.c @@ -29,10 +29,6 @@ video_buffer_init(struct video_buffer *vb) { // there is initially no frame, so consider it has already been consumed vb->pending_frame_consumed = true; - // The callbacks must be set by the consumer via - // video_buffer_set_consumer_callbacks() - vb->cbs = NULL; - return true; } @@ -50,21 +46,9 @@ swap_frames(AVFrame **lhs, AVFrame **rhs) { *rhs = tmp; } -void -video_buffer_set_consumer_callbacks(struct video_buffer *vb, - const struct video_buffer_callbacks *cbs, - void *cbs_userdata) { - assert(!vb->cbs); // must be set only once - assert(cbs); - assert(cbs->on_frame_available); - vb->cbs = cbs; - vb->cbs_userdata = cbs_userdata; -} - bool -video_buffer_push(struct video_buffer *vb, const AVFrame *frame) { - assert(vb->cbs); - +video_buffer_push(struct video_buffer *vb, const AVFrame *frame, + bool *previous_frame_skipped) { sc_mutex_lock(&vb->mutex); // Use a temporary frame to preserve pending_frame in case of error. @@ -80,18 +64,13 @@ video_buffer_push(struct video_buffer *vb, const AVFrame *frame) { swap_frames(&vb->pending_frame, &vb->tmp_frame); av_frame_unref(vb->tmp_frame); - bool skipped = !vb->pending_frame_consumed; + if (previous_frame_skipped) { + *previous_frame_skipped = !vb->pending_frame_consumed; + } vb->pending_frame_consumed = false; sc_mutex_unlock(&vb->mutex); - if (skipped) { - if (vb->cbs->on_frame_skipped) - vb->cbs->on_frame_skipped(vb, vb->cbs_userdata); - } else { - vb->cbs->on_frame_available(vb, vb->cbs_userdata); - } - return true; } diff --git a/app/src/video_buffer.h b/app/src/video_buffer.h index cdecb259..b9478f4c 100644 --- a/app/src/video_buffer.h +++ b/app/src/video_buffer.h @@ -33,19 +33,6 @@ struct video_buffer { sc_mutex mutex; bool pending_frame_consumed; - - const struct video_buffer_callbacks *cbs; - void *cbs_userdata; -}; - -struct video_buffer_callbacks { - // Called when a new frame can be consumed. - // This callback is mandatory (it must not be NULL). - void (*on_frame_available)(struct video_buffer *vb, void *userdata); - - // Called when a pending frame has been overwritten by the producer. - // This callback is optional (it may be NULL). - void (*on_frame_skipped)(struct video_buffer *vb, void *userdata); }; bool @@ -54,13 +41,8 @@ video_buffer_init(struct video_buffer *vb); void video_buffer_destroy(struct video_buffer *vb); -void -video_buffer_set_consumer_callbacks(struct video_buffer *vb, - const struct video_buffer_callbacks *cbs, - void *cbs_userdata); - bool -video_buffer_push(struct video_buffer *vb, const AVFrame *frame); +video_buffer_push(struct video_buffer *vb, const AVFrame *frame, bool *skipped); void video_buffer_consume(struct video_buffer *vb, AVFrame *dst);