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.
This commit is contained in:
Romain Vimont 2023-02-10 18:10:24 +01:00
parent db5751a76a
commit b1b33e3eaf
4 changed files with 41 additions and 8 deletions

View file

@ -4,3 +4,4 @@
#define SC_EVENT_SERVER_CONNECTED (SDL_USEREVENT + 3) #define SC_EVENT_SERVER_CONNECTED (SDL_USEREVENT + 3)
#define SC_EVENT_USB_DEVICE_DISCONNECTED (SDL_USEREVENT + 4) #define SC_EVENT_USB_DEVICE_DISCONNECTED (SDL_USEREVENT + 4)
#define SC_EVENT_DEMUXER_ERROR (SDL_USEREVENT + 5) #define SC_EVENT_DEMUXER_ERROR (SDL_USEREVENT + 5)
#define SC_EVENT_RECORDER_ERROR (SDL_USEREVENT + 6)

View file

@ -240,6 +240,9 @@ run_recorder(void *data) {
LOGD("Recorder thread ended"); LOGD("Recorder thread ended");
recorder->cbs->on_ended(recorder, !recorder->failed,
recorder->cbs_userdata);
return 0; return 0;
} }
@ -387,10 +390,10 @@ sc_recorder_packet_sink_push(struct sc_packet_sink *sink,
} }
bool bool
sc_recorder_init(struct sc_recorder *recorder, sc_recorder_init(struct sc_recorder *recorder, const char *filename,
const char *filename,
enum sc_record_format format, 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); recorder->filename = strdup(filename);
if (!recorder->filename) { if (!recorder->filename) {
LOG_OOM(); LOG_OOM();
@ -400,6 +403,10 @@ sc_recorder_init(struct sc_recorder *recorder,
recorder->format = format; recorder->format = format;
recorder->declared_frame_size = declared_frame_size; 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 = { static const struct sc_packet_sink_ops ops = {
.open = sc_recorder_packet_sink_open, .open = sc_recorder_packet_sink_open,
.close = sc_recorder_packet_sink_close, .close = sc_recorder_packet_sink_close,

View file

@ -34,12 +34,21 @@ struct sc_recorder {
bool stopped; // set on recorder_close() bool stopped; // set on recorder_close()
bool failed; // set on packet write failure bool failed; // set on packet write failure
struct sc_recorder_queue queue; 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 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, 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 void
sc_recorder_destroy(struct sc_recorder *recorder); sc_recorder_destroy(struct sc_recorder *recorder);

View file

@ -161,6 +161,9 @@ event_loop(struct scrcpy *s) {
case SC_EVENT_DEMUXER_ERROR: case SC_EVENT_DEMUXER_ERROR:
LOGE("Demuxer error"); LOGE("Demuxer error");
return SCRCPY_EXIT_FAILURE; return SCRCPY_EXIT_FAILURE;
case SC_EVENT_RECORDER_ERROR:
LOGE("Recorder error");
return SCRCPY_EXIT_FAILURE;
case SDL_QUIT: case SDL_QUIT:
LOGD("User requested to quit"); LOGD("User requested to quit");
return SCRCPY_EXIT_SUCCESS; return SCRCPY_EXIT_SUCCESS;
@ -198,6 +201,17 @@ await_for_server(bool *connected) {
return false; 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 static void
sc_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos, void *userdata) { sc_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos, void *userdata) {
(void) demuxer; (void) demuxer;
@ -379,10 +393,12 @@ scrcpy(struct scrcpy_options *options) {
struct sc_recorder *rec = NULL; struct sc_recorder *rec = NULL;
if (options->record_filename) { if (options->record_filename) {
if (!sc_recorder_init(&s->recorder, static const struct sc_recorder_callbacks recorder_cbs = {
options->record_filename, .on_ended = sc_recorder_on_ended,
options->record_format, };
info->frame_size)) { if (!sc_recorder_init(&s->recorder, options->record_filename,
options->record_format, info->frame_size,
&recorder_cbs, NULL)) {
goto end; goto end;
} }
rec = &s->recorder; rec = &s->recorder;