From b1b33e3eaf00b94d6a7d7a3c625b8bbc8c7c8014 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 10 Feb 2023 18:10:24 +0100 Subject: [PATCH] Report recorder errors Stop scrcpy on recorder errors. It was previously indirectly stopped by the demuxer, which failed to push packets to a recorder in error. Report it directly instead: - it avoids to wait for the next demuxer call; - it will allow to open the target file from a separate thread and stop immediately on any I/O error. --- app/src/events.h | 1 + app/src/recorder.c | 13 ++++++++++--- app/src/recorder.h | 11 ++++++++++- app/src/scrcpy.c | 24 ++++++++++++++++++++---- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/src/events.h b/app/src/events.h index 7fa10761..0a45b652 100644 --- a/app/src/events.h +++ b/app/src/events.h @@ -4,3 +4,4 @@ #define SC_EVENT_SERVER_CONNECTED (SDL_USEREVENT + 3) #define SC_EVENT_USB_DEVICE_DISCONNECTED (SDL_USEREVENT + 4) #define SC_EVENT_DEMUXER_ERROR (SDL_USEREVENT + 5) +#define SC_EVENT_RECORDER_ERROR (SDL_USEREVENT + 6) diff --git a/app/src/recorder.c b/app/src/recorder.c index c52bbb4d..beca48aa 100644 --- a/app/src/recorder.c +++ b/app/src/recorder.c @@ -240,6 +240,9 @@ run_recorder(void *data) { LOGD("Recorder thread ended"); + recorder->cbs->on_ended(recorder, !recorder->failed, + recorder->cbs_userdata); + return 0; } @@ -387,10 +390,10 @@ sc_recorder_packet_sink_push(struct sc_packet_sink *sink, } bool -sc_recorder_init(struct sc_recorder *recorder, - const char *filename, +sc_recorder_init(struct sc_recorder *recorder, const char *filename, enum sc_record_format format, - struct sc_size declared_frame_size) { + struct sc_size declared_frame_size, + const struct sc_recorder_callbacks *cbs, void *cbs_userdata) { recorder->filename = strdup(filename); if (!recorder->filename) { LOG_OOM(); @@ -400,6 +403,10 @@ sc_recorder_init(struct sc_recorder *recorder, recorder->format = format; recorder->declared_frame_size = declared_frame_size; + assert(cbs && cbs->on_ended); + recorder->cbs = cbs; + recorder->cbs_userdata = cbs_userdata; + static const struct sc_packet_sink_ops ops = { .open = sc_recorder_packet_sink_open, .close = sc_recorder_packet_sink_close, diff --git a/app/src/recorder.h b/app/src/recorder.h index 05d3857e..de5827e3 100644 --- a/app/src/recorder.h +++ b/app/src/recorder.h @@ -34,12 +34,21 @@ struct sc_recorder { bool stopped; // set on recorder_close() bool failed; // set on packet write failure struct sc_recorder_queue queue; + + const struct sc_recorder_callbacks *cbs; + void *cbs_userdata; +}; + +struct sc_recorder_callbacks { + void (*on_ended)(struct sc_recorder *recorder, bool success, + void *userdata); }; bool sc_recorder_init(struct sc_recorder *recorder, const char *filename, enum sc_record_format format, - struct sc_size declared_frame_size); + struct sc_size declared_frame_size, + const struct sc_recorder_callbacks *cbs, void *cbs_userdata); void sc_recorder_destroy(struct sc_recorder *recorder); diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index e96fa187..5a43a313 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -161,6 +161,9 @@ event_loop(struct scrcpy *s) { case SC_EVENT_DEMUXER_ERROR: LOGE("Demuxer error"); return SCRCPY_EXIT_FAILURE; + case SC_EVENT_RECORDER_ERROR: + LOGE("Recorder error"); + return SCRCPY_EXIT_FAILURE; case SDL_QUIT: LOGD("User requested to quit"); return SCRCPY_EXIT_SUCCESS; @@ -198,6 +201,17 @@ await_for_server(bool *connected) { return false; } +static void +sc_recorder_on_ended(struct sc_recorder *recorder, bool success, + void *userdata) { + (void) recorder; + (void) userdata; + + if (!success) { + PUSH_EVENT(SC_EVENT_RECORDER_ERROR); + } +} + static void sc_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos, void *userdata) { (void) demuxer; @@ -379,10 +393,12 @@ scrcpy(struct scrcpy_options *options) { struct sc_recorder *rec = NULL; if (options->record_filename) { - if (!sc_recorder_init(&s->recorder, - options->record_filename, - options->record_format, - info->frame_size)) { + static const struct sc_recorder_callbacks recorder_cbs = { + .on_ended = sc_recorder_on_ended, + }; + if (!sc_recorder_init(&s->recorder, options->record_filename, + options->record_format, info->frame_size, + &recorder_cbs, NULL)) { goto end; } rec = &s->recorder;