Initialize recorder fields from init()

The recorder has two initialization phases: one to initialize the
concrete recorder object, and one to open its packet_sink trait.

Initialize mutex and condvar as part of the object initialization.

If there were several packet_sink traits (spoiler: one for video, one
for audio), then the mutex and condvar would still be initialized only
once.
This commit is contained in:
Romain Vimont 2023-02-14 08:40:44 +01:00
parent b1b33e3eaf
commit fb29135591

View file

@ -248,33 +248,18 @@ run_recorder(void *data) {
static bool static bool
sc_recorder_open(struct sc_recorder *recorder, const AVCodec *input_codec) { sc_recorder_open(struct sc_recorder *recorder, const AVCodec *input_codec) {
bool ok = sc_mutex_init(&recorder->mutex);
if (!ok) {
return false;
}
ok = sc_cond_init(&recorder->queue_cond);
if (!ok) {
goto error_mutex_destroy;
}
sc_queue_init(&recorder->queue);
recorder->stopped = false;
recorder->failed = false;
recorder->header_written = false;
const char *format_name = sc_recorder_get_format_name(recorder->format); const char *format_name = sc_recorder_get_format_name(recorder->format);
assert(format_name); assert(format_name);
const AVOutputFormat *format = find_muxer(format_name); const AVOutputFormat *format = find_muxer(format_name);
if (!format) { if (!format) {
LOGE("Could not find muxer"); LOGE("Could not find muxer");
goto error_cond_destroy; return false;
} }
recorder->ctx = avformat_alloc_context(); recorder->ctx = avformat_alloc_context();
if (!recorder->ctx) { if (!recorder->ctx) {
LOG_OOM(); LOG_OOM();
goto error_cond_destroy; return false;
} }
// contrary to the deprecated API (av_oformat_next()), av_muxer_iterate() // contrary to the deprecated API (av_oformat_next()), av_muxer_iterate()
@ -306,8 +291,8 @@ sc_recorder_open(struct sc_recorder *recorder, const AVCodec *input_codec) {
} }
LOGD("Starting recorder thread"); LOGD("Starting recorder thread");
ok = sc_thread_create(&recorder->thread, run_recorder, "scrcpy-recorder", bool ok = sc_thread_create(&recorder->thread, run_recorder,
recorder); "scrcpy-recorder", recorder);
if (!ok) { if (!ok) {
LOGE("Could not start recorder thread"); LOGE("Could not start recorder thread");
goto error_avio_close; goto error_avio_close;
@ -321,10 +306,6 @@ error_avio_close:
avio_close(recorder->ctx->pb); avio_close(recorder->ctx->pb);
error_avformat_free_context: error_avformat_free_context:
avformat_free_context(recorder->ctx); avformat_free_context(recorder->ctx);
error_cond_destroy:
sc_cond_destroy(&recorder->queue_cond);
error_mutex_destroy:
sc_mutex_destroy(&recorder->mutex);
return false; return false;
} }
@ -340,8 +321,6 @@ sc_recorder_close(struct sc_recorder *recorder) {
avio_close(recorder->ctx->pb); avio_close(recorder->ctx->pb);
avformat_free_context(recorder->ctx); avformat_free_context(recorder->ctx);
sc_cond_destroy(&recorder->queue_cond);
sc_mutex_destroy(&recorder->mutex);
} }
static bool static bool
@ -400,6 +379,21 @@ sc_recorder_init(struct sc_recorder *recorder, const char *filename,
return false; return false;
} }
bool ok = sc_mutex_init(&recorder->mutex);
if (!ok) {
goto error_free_filename;
}
ok = sc_cond_init(&recorder->queue_cond);
if (!ok) {
goto error_mutex_destroy;
}
sc_queue_init(&recorder->queue);
recorder->stopped = false;
recorder->failed = false;
recorder->header_written = false;
recorder->format = format; recorder->format = format;
recorder->declared_frame_size = declared_frame_size; recorder->declared_frame_size = declared_frame_size;
@ -416,9 +410,18 @@ sc_recorder_init(struct sc_recorder *recorder, const char *filename,
recorder->packet_sink.ops = &ops; recorder->packet_sink.ops = &ops;
return true; return true;
error_mutex_destroy:
sc_mutex_destroy(&recorder->mutex);
error_free_filename:
free(recorder->filename);
return false;
} }
void void
sc_recorder_destroy(struct sc_recorder *recorder) { sc_recorder_destroy(struct sc_recorder *recorder) {
sc_cond_destroy(&recorder->queue_cond);
sc_mutex_destroy(&recorder->mutex);
free(recorder->filename); free(recorder->filename);
} }