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_USB_DEVICE_DISCONNECTED (SDL_USEREVENT + 4)
#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");
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,

View file

@ -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);

View file

@ -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;