Report video buffer downstream errors

Make the video buffer stop if its consumer could not receive a frame.
This commit is contained in:
Romain Vimont 2023-03-01 18:45:22 +01:00
parent ad94ccca0b
commit 4540f1d69e
5 changed files with 10 additions and 22 deletions

View file

@ -362,27 +362,17 @@ sc_screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) {
return sc_video_buffer_push(&screen->vb, frame); return sc_video_buffer_push(&screen->vb, frame);
} }
static void static bool
sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped, sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
void *userdata) { void *userdata) {
(void) vb; (void) vb;
struct sc_screen *screen = userdata; struct sc_screen *screen = userdata;
// event_failed implies previous_skipped (the previous frame may not have
// been consumed if the event was not sent)
assert(!screen->event_failed || previous_skipped);
bool need_new_event;
if (previous_skipped) { if (previous_skipped) {
sc_fps_counter_add_skipped_frame(&screen->fps_counter); sc_fps_counter_add_skipped_frame(&screen->fps_counter);
// The SC_EVENT_NEW_FRAME triggered for the previous frame will consume // The SC_EVENT_NEW_FRAME triggered for the previous frame will consume
// this new frame instead, unless the previous event failed // this new frame instead
need_new_event = screen->event_failed;
} else { } else {
need_new_event = true;
}
if (need_new_event) {
static SDL_Event new_frame_event = { static SDL_Event new_frame_event = {
.type = SC_EVENT_NEW_FRAME, .type = SC_EVENT_NEW_FRAME,
}; };
@ -391,11 +381,11 @@ sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
int ret = SDL_PushEvent(&new_frame_event); int ret = SDL_PushEvent(&new_frame_event);
if (ret < 0) { if (ret < 0) {
LOGW("Could not post new frame event: %s", SDL_GetError()); LOGW("Could not post new frame event: %s", SDL_GetError());
screen->event_failed = true; return false;
} else {
screen->event_failed = false;
} }
} }
return true;
} }
bool bool
@ -405,7 +395,6 @@ sc_screen_init(struct sc_screen *screen,
screen->has_frame = false; screen->has_frame = false;
screen->fullscreen = false; screen->fullscreen = false;
screen->maximized = false; screen->maximized = false;
screen->event_failed = false;
screen->mouse_capture_key_pressed = 0; screen->mouse_capture_key_pressed = 0;
screen->req.x = params->window_x; screen->req.x = params->window_x;

View file

@ -59,8 +59,6 @@ struct sc_screen {
bool maximized; bool maximized;
bool mipmaps; bool mipmaps;
bool event_failed; // in case SDL_PushEvent() returned an error
// To enable/disable mouse capture, a mouse capture key (LALT, LGUI or // To enable/disable mouse capture, a mouse capture key (LALT, LGUI or
// RGUI) must be pressed. This variable tracks the pressed capture key. // RGUI) must be pressed. This variable tracks the pressed capture key.
SDL_Keycode mouse_capture_key_pressed; SDL_Keycode mouse_capture_key_pressed;

View file

@ -141,7 +141,7 @@ run_v4l2_sink(void *data) {
return 0; return 0;
} }
static void static bool
sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped, sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
void *userdata) { void *userdata) {
(void) vb; (void) vb;
@ -153,6 +153,8 @@ sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
sc_cond_signal(&vs->cond); sc_cond_signal(&vs->cond);
sc_mutex_unlock(&vs->mutex); sc_mutex_unlock(&vs->mutex);
} }
return true;
} }
static bool static bool

View file

@ -40,8 +40,7 @@ sc_video_buffer_offer(struct sc_video_buffer *vb, const AVFrame *frame) {
return false; return false;
} }
vb->cbs->on_new_frame(vb, previous_skipped, vb->cbs_userdata); return vb->cbs->on_new_frame(vb, previous_skipped, vb->cbs_userdata);
return true;
} }
static int static int

View file

@ -45,7 +45,7 @@ struct sc_video_buffer {
}; };
struct sc_video_buffer_callbacks { struct sc_video_buffer_callbacks {
void (*on_new_frame)(struct sc_video_buffer *vb, bool previous_skipped, bool (*on_new_frame)(struct sc_video_buffer *vb, bool previous_skipped,
void *userdata); void *userdata);
}; };