diff --git a/app/src/screen.c b/app/src/screen.c index a11235c9..a9ee1fb0 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -274,14 +274,16 @@ 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 sc_video_buffer_push(&screen->vb, frame); +} - bool previous_frame_skipped; - bool ok = sc_video_buffer_push(&screen->vb, frame, &previous_frame_skipped); - if (!ok) { - return false; - } +static void +sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped, + void *userdata) { + (void) vb; + struct screen *screen = userdata; - if (previous_frame_skipped) { + if (previous_skipped) { fps_counter_add_skipped_frame(&screen->fps_counter); // The EVENT_NEW_FRAME triggered for the previous frame will consume // this new frame instead @@ -293,8 +295,6 @@ screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) { // Post the event on the UI thread SDL_PushEvent(&new_frame_event); } - - return true; } bool @@ -304,7 +304,11 @@ screen_init(struct screen *screen, const struct screen_params *params) { screen->fullscreen = false; screen->maximized = false; - bool ok = sc_video_buffer_init(&screen->vb); + static const struct sc_video_buffer_callbacks cbs = { + .on_new_frame = sc_video_buffer_on_new_frame, + }; + + bool ok = sc_video_buffer_init(&screen->vb, &cbs, screen); if (!ok) { LOGE("Could not initialize video buffer"); return false; diff --git a/app/src/v4l2_sink.c b/app/src/v4l2_sink.c index 4b8ea043..21bbe404 100644 --- a/app/src/v4l2_sink.c +++ b/app/src/v4l2_sink.c @@ -139,9 +139,27 @@ run_v4l2_sink(void *data) { return 0; } +static void +sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped, + void *userdata) { + (void) vb; + struct sc_v4l2_sink *vs = userdata; + + if (!previous_skipped) { + sc_mutex_lock(&vs->mutex); + vs->has_frame = true; + sc_cond_signal(&vs->cond); + sc_mutex_unlock(&vs->mutex); + } +} + static bool sc_v4l2_sink_open(struct sc_v4l2_sink *vs) { - bool ok = sc_video_buffer_init(&vs->vb); + static const struct sc_video_buffer_callbacks cbs = { + .on_new_frame = sc_video_buffer_on_new_frame, + }; + + bool ok = sc_video_buffer_init(&vs->vb, &cbs, vs); if (!ok) { LOGE("Could not initialize video buffer"); return false; @@ -303,20 +321,7 @@ sc_v4l2_sink_close(struct sc_v4l2_sink *vs) { static bool sc_v4l2_sink_push(struct sc_v4l2_sink *vs, const AVFrame *frame) { - bool previous_skipped; - bool ok = sc_video_buffer_push(&vs->vb, frame, &previous_skipped); - if (!ok) { - return false; - } - - if (!previous_skipped) { - sc_mutex_lock(&vs->mutex); - vs->has_frame = true; - sc_cond_signal(&vs->cond); - sc_mutex_unlock(&vs->mutex); - } - - return true; + return sc_video_buffer_push(&vs->vb, frame); } static bool diff --git a/app/src/video_buffer.c b/app/src/video_buffer.c index 9a5fed43..664eb6c1 100644 --- a/app/src/video_buffer.c +++ b/app/src/video_buffer.c @@ -7,8 +7,20 @@ #include "util/log.h" bool -sc_video_buffer_init(struct sc_video_buffer *vb) { - return sc_frame_buffer_init(&vb->fb); +sc_video_buffer_init(struct sc_video_buffer *vb, + const struct sc_video_buffer_callbacks *cbs, + void *cbs_userdata) { + bool ok = sc_frame_buffer_init(&vb->fb); + if (!ok) { + return false; + } + + assert(cbs); + assert(cbs->on_new_frame); + + vb->cbs = cbs; + vb->cbs_userdata = cbs_userdata; + return true; } void @@ -17,9 +29,15 @@ sc_video_buffer_destroy(struct sc_video_buffer *vb) { } bool -sc_video_buffer_push(struct sc_video_buffer *vb, const AVFrame *frame, - bool *previous_frame_skipped) { - return sc_frame_buffer_push(&vb->fb, frame, previous_frame_skipped); +sc_video_buffer_push(struct sc_video_buffer *vb, const AVFrame *frame) { + bool previous_skipped; + bool ok = sc_frame_buffer_push(&vb->fb, frame, &previous_skipped); + if (!ok) { + return false; + } + + vb->cbs->on_new_frame(vb, previous_skipped, vb->cbs_userdata); + return true; } void diff --git a/app/src/video_buffer.h b/app/src/video_buffer.h index 9befd26d..6f258980 100644 --- a/app/src/video_buffer.h +++ b/app/src/video_buffer.h @@ -12,17 +12,26 @@ typedef struct AVFrame AVFrame; struct sc_video_buffer { struct sc_frame_buffer fb; + + const struct sc_video_buffer_callbacks *cbs; + void *cbs_userdata; +}; + +struct sc_video_buffer_callbacks { + void (*on_new_frame)(struct sc_video_buffer *vb, bool previous_skipped, + void *userdata); }; bool -sc_video_buffer_init(struct sc_video_buffer *vb); +sc_video_buffer_init(struct sc_video_buffer *vb, + const struct sc_video_buffer_callbacks *cbs, + void *cbs_userdata); void sc_video_buffer_destroy(struct sc_video_buffer *vb); bool -sc_video_buffer_push(struct sc_video_buffer *vb, const AVFrame *frame, - bool *skipped); +sc_video_buffer_push(struct sc_video_buffer *vb, const AVFrame *frame); void sc_video_buffer_consume(struct sc_video_buffer *vb, AVFrame *dst);