diff --git a/recording-daemon/decoder.c b/recording-daemon/decoder.c index d7e5f7804..7be0debda 100644 --- a/recording-daemon/decoder.c +++ b/recording-daemon/decoder.c @@ -140,7 +140,7 @@ no_mix_out: dbg("SSRC %lx of stream #%lu has single output", ssrc->ssrc, stream->id); if (output_config(output, &dec->dest_format, NULL)) goto err; - if (output_add(output, frame)) + if (!sink_add(&output->sink, frame)) ilog(LOG_ERR, "Failed to add decoded packet to individual output"); } diff --git a/recording-daemon/mix.c b/recording-daemon/mix.c index f45dc3081..c623d8587 100644 --- a/recording-daemon/mix.c +++ b/recording-daemon/mix.c @@ -390,13 +390,13 @@ int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *ptr, output_t *o } frame = resample_frame(&mix->resample, mix->sink_frame, &mix->out_format); - ret = output_add(output, frame); + bool ok = sink_add(&output->sink, frame); av_frame_unref(mix->sink_frame); if (frame != mix->sink_frame) av_frame_free(&frame); - if (ret) + if (!ok) return -1; } diff --git a/recording-daemon/output.c b/recording-daemon/output.c index 53a3f9f28..84a9eadad 100644 --- a/recording-daemon/output.c +++ b/recording-daemon/output.c @@ -42,14 +42,26 @@ static int output_got_packet(encoder_t *enc, void *u1, void *u2) { } -int output_add(output_t *output, AVFrame *frame) { - if (!output) - return -1; +bool sink_add(sink_t *sink, AVFrame *frame) { + if (!sink) + return false; + return sink->add(sink, frame); +} + + +static bool output_add(sink_t *sink, AVFrame *frame) { + bool ret = false; + + output_t *output = sink->output; if (!output->encoder) // not ready - not configured - return -1; + goto out; if (!output->fmtctx) // output not open - return -1; - return encoder_input_fifo(output->encoder, frame, output_got_packet, output, NULL); + goto out; + ret = encoder_input_fifo(output->encoder, frame, output_got_packet, output, NULL) == 0; + +out: + av_frame_free(&frame); + return ret; } @@ -87,6 +99,11 @@ static void create_parent_dirs(char *dir) { } } +void sink_init(sink_t *sink) { + *sink = (__typeof(*sink)) { + }; +} + static output_t *output_alloc(const char *path, const char *name) { output_t *ret = g_new0(output_t, 1); ret->file_path = g_strdup(path); @@ -99,6 +116,10 @@ static output_t *output_alloc(const char *path, const char *name) { ret->actual_format.format = -1; ret->start_time_us = now_us(); + sink_init(&ret->sink); + ret->sink.output = ret; + ret->sink.add = output_add; + return ret; } diff --git a/recording-daemon/output.h b/recording-daemon/output.h index 28d39f2ed..a04982cb8 100644 --- a/recording-daemon/output.h +++ b/recording-daemon/output.h @@ -14,7 +14,11 @@ output_t *output_new_ext(metafile_t *, const char *type, const char *kind, const void output_close(metafile_t *, output_t *, tag_t *, bool discard); int output_config(output_t *output, const format_t *requested_format, format_t *actual_format); -int output_add(output_t *output, AVFrame *frame); + + +void sink_init(sink_t *); + +bool sink_add(sink_t *, AVFrame *frame); #endif diff --git a/recording-daemon/types.h b/recording-daemon/types.h index 159ecce19..6c290ee61 100644 --- a/recording-daemon/types.h +++ b/recording-daemon/types.h @@ -33,6 +33,7 @@ typedef struct decode_s decode_t; typedef struct packet_s packet_t; typedef struct stream_s stream_t; typedef struct ssrc_s ssrc_t; +typedef struct sink_s sink_t; typedef void handler_func(handler_t *); @@ -44,6 +45,15 @@ struct handler_s { }; +struct sink_s { + bool (*add)(sink_t *, AVFrame *); + + union { + output_t *output; + }; +}; + + struct stream_s { pthread_mutex_t lock; char *name; @@ -156,6 +166,8 @@ struct metafile_s { struct output_s { + sink_t sink; + char *full_filename, // path + filename *file_path, *file_name,