diff --git a/app/src/resizer.c b/app/src/resizer.c index 25198658..4b213491 100644 --- a/app/src/resizer.c +++ b/app/src/resizer.c @@ -7,8 +7,7 @@ bool sc_resizer_init(struct sc_resizer *resizer, struct video_buffer *vb_in, - struct video_buffer *vb_out, enum sc_scale_filter scale_filter, - struct size size) { + enum sc_scale_filter scale_filter, struct size size) { bool ok = sc_mutex_init(&resizer->mutex); if (!ok) { return false; @@ -20,15 +19,22 @@ sc_resizer_init(struct sc_resizer *resizer, struct video_buffer *vb_in, return false; } + ok = video_buffer_init(&resizer->vb_out, false); // FIXME wait_consumer + if (!ok) { + sc_cond_destroy(&resizer->req_cond); + sc_mutex_destroy(&resizer->mutex); + return false; + } + resizer->resized_frame = av_frame_alloc(); if (!resizer->resized_frame) { + video_buffer_destroy(&resizer->vb_out); sc_cond_destroy(&resizer->req_cond); sc_mutex_destroy(&resizer->mutex); return false; } resizer->vb_in = vb_in; - resizer->vb_out = vb_out; resizer->scale_filter = scale_filter; resizer->size = size; @@ -123,10 +129,16 @@ run_resizer(void *data) { // Do the actual work without mutex sc_resizer_swscale(resizer); - video_buffer_producer_offer_frame(resizer->vb_out, - &resizer->resized_frame); - sc_mutex_lock(&resizer->mutex); + + // Update the original size of the resized frame + resizer->original_size.width = resizer->input_frame->width; + resizer->original_size.height = resizer->input_frame->height; + assert(resizer->original_size.width); + assert(resizer->original_size.height); + + video_buffer_producer_offer_frame(&resizer->vb_out, + &resizer->resized_frame); } sc_mutex_unlock(&resizer->mutex); @@ -154,7 +166,7 @@ sc_resizer_stop(struct sc_resizer *resizer) { sc_cond_signal(&resizer->req_cond); sc_mutex_unlock(&resizer->mutex); - video_buffer_interrupt(resizer->vb_out); + video_buffer_interrupt(&resizer->vb_out); } void @@ -162,6 +174,20 @@ sc_resizer_join(struct sc_resizer *resizer) { sc_thread_join(&resizer->thread, NULL); } +const AVFrame * +sc_resizer_consumer_take_frame(struct sc_resizer *resizer, + struct size *out_original_size) { + // Locking the mutex is necessary to ensure that the size corresponds to the correct frame + sc_mutex_lock(&resizer->mutex); + + const AVFrame *frame = video_buffer_consumer_take_frame(&resizer->vb_out); + *out_original_size = resizer->original_size; + + sc_mutex_unlock(&resizer->mutex); + + return frame; +} + void sc_resizer_process_new_frame(struct sc_resizer *resizer) { sc_mutex_lock(&resizer->mutex); diff --git a/app/src/resizer.h b/app/src/resizer.h index 5bd53de7..be741e71 100644 --- a/app/src/resizer.h +++ b/app/src/resizer.h @@ -13,7 +13,7 @@ struct sc_resizer { struct video_buffer *vb_in; - struct video_buffer *vb_out; + struct video_buffer vb_out; enum sc_scale_filter scale_filter; struct size size; @@ -21,6 +21,9 @@ struct sc_resizer { const AVFrame *input_frame; AVFrame *resized_frame; + // original size of the available (resized) frame in vb_out + struct size original_size; + sc_thread thread; sc_mutex mutex; sc_cond req_cond; @@ -32,8 +35,7 @@ struct sc_resizer { bool sc_resizer_init(struct sc_resizer *resizer, struct video_buffer *vb_in, - struct video_buffer *vb_out, enum sc_scale_filter scale_filter, - struct size size); + enum sc_scale_filter scale_filter, struct size size); void sc_resizer_destroy(struct sc_resizer *resizer); @@ -47,6 +49,10 @@ sc_resizer_stop(struct sc_resizer *resizer); void sc_resizer_join(struct sc_resizer *resizer); +const AVFrame * +sc_resizer_consumer_take_frame(struct sc_resizer *resizer, + struct size *out_original_size); + void sc_resizer_process_new_frame(struct sc_resizer *resizer); diff --git a/app/src/screen.c b/app/src/screen.c index bb7198e4..daa6f22a 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -216,6 +216,25 @@ on_frame_skipped(struct video_buffer *vb, void *userdata) { fps_counter_add_skipped_frame(screen->fps_counter); } +static void +resizer_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 +resizer_on_frame_skipped(struct video_buffer *vb, void *userdata) { + // Count skipped frames from decoder or resizer the same way + on_frame_skipped(vb, userdata); +} + void screen_init(struct screen *screen, struct video_buffer *vb, struct fps_counter *fps_counter) { @@ -271,19 +290,6 @@ is_swscale(enum sc_scale_filter scale_filter) { && scale_filter != SC_SCALE_FILTER_TRILINEAR; } -static void -on_resizer_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); -} - bool screen_init_rendering(struct screen *screen, const char *window_title, struct size frame_size, bool always_on_top, @@ -378,8 +384,8 @@ screen_init_rendering(struct screen *screen, const char *window_title, return false; } - ok = sc_resizer_init(&screen->resizer, screen->vb, &screen->resizer_vb, - scale_filter, window_size); + ok = sc_resizer_init(&screen->resizer, screen->vb, scale_filter, + window_size); if (!ok) { LOGE("Could not create resizer"); video_buffer_destroy(&screen->resizer_vb); @@ -388,6 +394,14 @@ screen_init_rendering(struct screen *screen, const char *window_title, return false; } + static const struct video_buffer_callbacks cbs = { + .on_frame_available = resizer_on_frame_available, + .on_frame_skipped = resizer_on_frame_skipped, + }; + + video_buffer_set_consumer_callbacks(&screen->resizer.vb_out, &cbs, + screen); + ok = sc_resizer_start(&screen->resizer); if (!ok) { LOGE("Could not start resizer");