diff --git a/recording-daemon/output.c b/recording-daemon/output.c index b1a70e598..70e4a632c 100644 --- a/recording-daemon/output.c +++ b/recording-daemon/output.c @@ -357,48 +357,29 @@ static int64_t output_avio_mem_seek(void *opaque, int64_t offset, int whence) { return o->mempos; } -static bool output_config(sink_t *sink, output_t *output, const format_t *requested_format, - format_t *actual_format) -{ - const char *err; - int av_ret = 0; - - format_t req_fmt = *requested_format; - - // if we've already done this and don't care about the sample format, - // restore the already determined sample format - if (req_fmt.format == -1 && output->requested_format.format != -1) - req_fmt.format = output->requested_format.format; - - // anything to do? - if (G_LIKELY(format_eq(&req_fmt, &output->requested_format))) - goto done; - +static const char *output_setup(output_t *output, const format_t *requested_format, format_t *req_fmt) { output_shutdown(output, NULL, NULL); - err = "failed to alloc format context"; output->fmtctx = avformat_alloc_context(); if (!output->fmtctx) - goto err; + return "failed to alloc format context"; output->fmtctx->oformat = av_guess_format(output->file_format, NULL, NULL); - err = "failed to determine output format"; if (!output->fmtctx->oformat) - goto err; + return "failed to determine output format"; // mask the channel multiplier from external view output->requested_format = *requested_format; - if (encoder_config(output->encoder, output_codec, mp3_bitrate, 0, &req_fmt, &output->actual_format)) - goto err; + if (encoder_config(output->encoder, output_codec, mp3_bitrate, 0, req_fmt, &output->actual_format)) + return "failed to configure encoder"; // save the sample format if (requested_format->format == -1) output->requested_format.format = output->actual_format.format; - err = "failed to alloc output stream"; output->avst = avformat_new_stream(output->fmtctx, output->encoder->avc.codec); if (!output->avst) - goto err; + return "failed to alloc output stream"; output->avst->time_base = output->encoder->avc.avcctx->time_base; #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 0, 0) @@ -434,38 +415,32 @@ static bool output_config(sink_t *sink, output_t *output, const format_t *reques g_free(full_fn); } - err = "failed to find unused output file number"; - goto err; + return "failed to find unused output file number"; got_fn: output->filename = full_fn; - err = "failed to open output file"; output->fp = fopen(full_fn, (output_storage & OUTPUT_STORAGE_DB) ? "wb+" : "wb"); if (!output->fp) - goto err; + return "failed to open output file"; if (output_buffer > 0) { - err = "failed to alloc I/O buffer"; output->iobuf = g_malloc(output_buffer); if (!output->iobuf) - goto err; + return "failed to alloc I/O buffer"; - err = "failed to set I/O buffer"; if (setvbuf(output->fp, output->iobuf, _IOFBF, output_buffer)) - goto err; + return "failed to set I/O buffer"; } else { - err = "failed to set unuffered I/O"; if (setvbuf(output->fp, NULL, _IONBF, 0)) - goto err; + return "failed to set unuffered I/O"; } no_output_file: - err = "failed to alloc avio buffer"; void *avio_buf = av_malloc(DEFAULT_AVIO_BUFSIZE); if (!avio_buf) - goto err; + return "failed to alloc avio buffer"; if (!(output_storage & OUTPUT_STORAGE_MEMORY)) output->avioctx = avio_alloc_context(avio_buf, DEFAULT_AVIO_BUFSIZE, 1, output, @@ -475,18 +450,18 @@ no_output_file: output->avioctx = avio_alloc_context(avio_buf, DEFAULT_AVIO_BUFSIZE, 1, output, NULL, output_avio_mem_write, output_avio_mem_seek); } - err = "failed to alloc AVIOContext"; if (!output->avioctx) { av_freep(&avio_buf); - goto err; + return "failed to alloc AVIOContext"; } output->fmtctx->pb = output->avioctx; - err = "failed to write header"; - av_ret = avformat_write_header(output->fmtctx, NULL); - if (av_ret) - goto err; + int av_ret = avformat_write_header(output->fmtctx, NULL); + if (av_ret) { + ilog(LOG_ERR, "Error returned from libav: %s", av_error(av_ret)); + return "failed to write header"; + } if (output_chmod && output->filename) if (chmod(output->filename, output_chmod)) @@ -504,17 +479,34 @@ no_output_file: db_config_stream(output); ilog(LOG_INFO, "Opened output media file '%s' for writing", full_fn ?: "(mem stream)"); -done: + + return NULL; +} + +static bool output_config(sink_t *sink, output_t *output, const format_t *requested_format, + format_t *actual_format) +{ + format_t req_fmt = *requested_format; + + // if we've already done this and don't care about the sample format, + // restore the already determined sample format + if (req_fmt.format == -1 && output->requested_format.format != -1) + req_fmt.format = output->requested_format.format; + + // anything to do? + if (G_UNLIKELY(!format_eq(&req_fmt, &output->requested_format))) { + const char *err = output_setup(output, requested_format, &req_fmt); + if (err) { + output_shutdown(output, NULL, NULL); + ilog(LOG_ERR, "Error configuring media output: %s", err); + return false; + } + } + if (actual_format) *actual_format = output->actual_format; - return true; -err: - output_shutdown(output, NULL, NULL); - ilog(LOG_ERR, "Error configuring media output: %s", err); - if (av_ret) - ilog(LOG_ERR, "Error returned from libav: %s", av_error(av_ret)); - return false; + return true; }