Handle errors using gotos in recorder_open()

There are many initializations in recorder_open(). Handle RAII-like
deinitialization using gotos.
This commit is contained in:
Romain Vimont 2021-04-18 11:32:21 +02:00
parent e3fccc5a5e
commit 2a5dfc1c17

View file

@ -227,8 +227,7 @@ recorder_open(struct recorder *recorder, const AVCodec *input_codec) {
ok = sc_cond_init(&recorder->queue_cond); ok = sc_cond_init(&recorder->queue_cond);
if (!ok) { if (!ok) {
LOGC("Could not create cond"); LOGC("Could not create cond");
sc_mutex_destroy(&recorder->mutex); goto error_mutex_destroy;
return false;
} }
queue_init(&recorder->queue); queue_init(&recorder->queue);
@ -242,17 +241,13 @@ recorder_open(struct recorder *recorder, const AVCodec *input_codec) {
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");
sc_cond_destroy(&recorder->queue_cond); goto error_cond_destroy;
sc_mutex_destroy(&recorder->mutex);
return false;
} }
recorder->ctx = avformat_alloc_context(); recorder->ctx = avformat_alloc_context();
if (!recorder->ctx) { if (!recorder->ctx) {
LOGE("Could not allocate output context"); LOGE("Could not allocate output context");
sc_cond_destroy(&recorder->queue_cond); goto error_cond_destroy;
sc_mutex_destroy(&recorder->mutex);
return false;
} }
// contrary to the deprecated API (av_oformat_next()), av_muxer_iterate() // contrary to the deprecated API (av_oformat_next()), av_muxer_iterate()
@ -266,10 +261,7 @@ recorder_open(struct recorder *recorder, const AVCodec *input_codec) {
AVStream *ostream = avformat_new_stream(recorder->ctx, input_codec); AVStream *ostream = avformat_new_stream(recorder->ctx, input_codec);
if (!ostream) { if (!ostream) {
avformat_free_context(recorder->ctx); goto error_avformat_free_context;
sc_cond_destroy(&recorder->queue_cond);
sc_mutex_destroy(&recorder->mutex);
return false;
} }
ostream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; ostream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
@ -283,10 +275,7 @@ recorder_open(struct recorder *recorder, const AVCodec *input_codec) {
if (ret < 0) { if (ret < 0) {
LOGE("Failed to open output file: %s", recorder->filename); LOGE("Failed to open output file: %s", recorder->filename);
// ostream will be cleaned up during context cleaning // ostream will be cleaned up during context cleaning
avformat_free_context(recorder->ctx); goto error_avformat_free_context;
sc_cond_destroy(&recorder->queue_cond);
sc_mutex_destroy(&recorder->mutex);
return false;
} }
LOGD("Starting recorder thread"); LOGD("Starting recorder thread");
@ -294,16 +283,23 @@ recorder_open(struct recorder *recorder, const AVCodec *input_codec) {
recorder); recorder);
if (!ok) { if (!ok) {
LOGC("Could not start recorder thread"); LOGC("Could not start recorder thread");
avio_close(recorder->ctx->pb); goto error_avio_close;
avformat_free_context(recorder->ctx);
sc_cond_destroy(&recorder->queue_cond);
sc_mutex_destroy(&recorder->mutex);
return false;
} }
LOGI("Recording started to %s file: %s", format_name, recorder->filename); LOGI("Recording started to %s file: %s", format_name, recorder->filename);
return true; return true;
error_avio_close:
avio_close(recorder->ctx->pb);
error_avformat_free_context:
avformat_free_context(recorder->ctx);
error_cond_destroy:
sc_cond_destroy(&recorder->queue_cond);
error_mutex_destroy:
sc_mutex_destroy(&recorder->mutex);
return false;
} }
static void static void