From dc80c27af761838a474eee3fada4b2fee5b65067 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 25 Jan 2018 12:56:36 -0500 Subject: [PATCH] TT#28163 split encoder from recording daemon into shared lib Change-Id: I76a744b1b1acd32f326d26db7a44273394a4dee1 --- daemon/codec.c | 30 +++- lib/codeclib.c | 197 ++++++++++++++++++++++++++ lib/codeclib.h | 20 +++ recording-daemon/.ycm_extra_conf.py | 1 + recording-daemon/db.c | 4 +- recording-daemon/main.c | 33 ----- recording-daemon/output.c | 208 +++++++++++----------------- recording-daemon/types.h | 11 +- 8 files changed, 329 insertions(+), 175 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 21673aac0..df3abdafe 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -15,6 +15,7 @@ struct codec_ssrc_handler { mutex_t lock; packet_sequencer_t sequencer; decoder_t *decoder; + encoder_t *encoder; }; struct transcode_packet { seq_packet_t p; // must be first @@ -306,6 +307,12 @@ static struct ssrc_entry *__ssrc_handler_new(void *p) { ch->decoder = decoder_new_fmt(h->source_pt.codec_def, h->source_pt.clock_rate, 1, 0); if (!ch->decoder) goto err; + ch->encoder = encoder_new(); + if (!ch->encoder) + goto err; + format_t format = { .clockrate = h->dest_pt.clock_rate, .channels = 1, .format = 0 }; + if (encoder_config(ch->encoder, h->dest_pt.codec_def->avcodec_id, 0, &format, &format)) + goto err; return &ch->h; err: @@ -316,13 +323,26 @@ static void __ssrc_handler_free(struct codec_ssrc_handler *ch) { packet_sequencer_destroy(&ch->sequencer); if (ch->decoder) decoder_close(ch->decoder); + if (ch->encoder) + encoder_free(ch->encoder); g_slice_free1(sizeof(*ch), ch); } -int __packet_decoded(decoder_t *decoder, AVFrame *frame, void *u1, void *u2) { - //struct codec_ssrc_handler *ch = u1; +static int __packet_encoded(encoder_t *enc, void *u1, void *u2) { + ilog(LOG_DEBUG, "RTP media successfully encoded: TS %llu, len %i", + (unsigned long long) enc->avpkt.pts, enc->avpkt.size); + return 0; +} + +static int __packet_decoded(decoder_t *decoder, AVFrame *frame, void *u1, void *u2) { + struct codec_ssrc_handler *ch = u1; + + ilog(LOG_DEBUG, "RTP media successfully decoded: TS %llu, samples %u", + (unsigned long long) frame->pts, frame->nb_samples); + + // XXX resample... - ilog(LOG_DEBUG, "RTP media successfully decoded"); + encoder_input_data(ch->encoder, frame, __packet_encoded, ch, NULL); av_frame_free(&frame); return 0; @@ -338,9 +358,9 @@ static int handler_func_transcode(struct codec_handler *h, struct call_media *me // create new packet and insert it into sequencer queue - ilog(LOG_DEBUG, "Received RTP packet: SSRC %u, PT %u, seq %u, TS %u", + ilog(LOG_DEBUG, "Received RTP packet: SSRC %u, PT %u, seq %u, TS %u, len %i", ntohl(mp->rtp->ssrc), mp->rtp->m_pt, ntohs(mp->rtp->seq_num), - ntohl(mp->rtp->timestamp)); + ntohl(mp->rtp->timestamp), mp->payload.len); struct codec_ssrc_handler *ch = get_ssrc(mp->rtp->ssrc, h->ssrc_hash); if (G_UNLIKELY(!ch)) diff --git a/lib/codeclib.c b/lib/codeclib.c index 0d390d133..1d7fcac19 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -261,11 +261,42 @@ err: } +static void avlog_ilog(void *ptr, int loglevel, const char *fmt, va_list ap) { + char *msg; + if (vasprintf(&msg, fmt, ap) <= 0) + ilog(LOG_ERR, "av_log message dropped"); + else { +#ifdef AV_LOG_PANIC + // translate AV_LOG_ constants to LOG_ levels + if (loglevel >= AV_LOG_VERBOSE) + loglevel = LOG_DEBUG; + else if (loglevel >= AV_LOG_INFO) + loglevel = LOG_NOTICE; + else if (loglevel >= AV_LOG_WARNING) + loglevel = LOG_WARNING; + else if (loglevel >= AV_LOG_ERROR) + loglevel = LOG_ERROR; + else if (loglevel >= AV_LOG_FATAL) + loglevel = LOG_CRIT; + else + loglevel = LOG_ALERT; +#else + // defuse avlog log levels to be either DEBUG or ERR + if (loglevel <= LOG_ERR) + loglevel = LOG_ERR; + else + loglevel = LOG_DEBUG; +#endif + ilog(loglevel, "av_log: %s", msg); + free(msg); + } +} void codeclib_init() { av_register_all(); avcodec_register_all(); avfilter_register_all(); avformat_network_init(); + av_log_set_callback(avlog_ilog); } @@ -386,3 +417,169 @@ seq_ok: return 0; } + + + + +encoder_t *encoder_new() { + encoder_t *ret = g_slice_alloc0(sizeof(*ret)); + format_init(&ret->requested_format); + format_init(&ret->actual_format); + return ret; +} + +int encoder_config(encoder_t *enc, int codec_id, int bitrate, const format_t *requested_format, + format_t *actual_format) +{ + const char *err; + + // anything to do? + if (G_LIKELY(format_eq(requested_format, &enc->requested_format))) + goto done; + + encoder_close(enc); + + enc->requested_format = *requested_format; + + err = "output codec not found"; + enc->codec = avcodec_find_encoder(codec_id); + if (!enc->codec) + goto err; + + err = "failed to alloc codec context"; + enc->avcctx = avcodec_alloc_context3(enc->codec); + if (!enc->avcctx) + goto err; + + enc->actual_format = enc->requested_format; + + enc->actual_format.format = -1; + for (const enum AVSampleFormat *sfmt = enc->codec->sample_fmts; sfmt && *sfmt != -1; sfmt++) { + dbg("supported sample format for output codec %s: %s", enc->codec->name, av_get_sample_fmt_name(*sfmt)); + if (*sfmt == requested_format->format) + enc->actual_format.format = *sfmt; + } + if (enc->actual_format.format == -1 && enc->codec->sample_fmts) + enc->actual_format.format = enc->codec->sample_fmts[0]; + dbg("using output sample format %s for codec %s", av_get_sample_fmt_name(enc->actual_format.format), enc->codec->name); + + enc->avcctx->channels = enc->actual_format.channels; + enc->avcctx->channel_layout = av_get_default_channel_layout(enc->actual_format.channels); + enc->avcctx->sample_rate = enc->actual_format.clockrate; + enc->avcctx->sample_fmt = enc->actual_format.format; + enc->avcctx->time_base = (AVRational){1,enc->actual_format.clockrate}; + enc->avcctx->bit_rate = bitrate; + + err = "failed to open output context"; + int i = avcodec_open2(enc->avcctx, enc->codec, NULL); + if (i) + goto err; + + av_init_packet(&enc->avpkt); + +done: + *actual_format = enc->actual_format; + return 0; + +err: + encoder_close(enc); + ilog(LOG_ERR, "Error configuring media output: %s", err); + return -1; +} + +void encoder_close(encoder_t *enc) { + if (!enc) + return; + if (enc->avcctx) { + avcodec_close(enc->avcctx); + avcodec_free_context(&enc->avcctx); + } + enc->avcctx = NULL; + format_init(&enc->requested_format); + format_init(&enc->actual_format); + enc->mux_dts = 0; +} +void encoder_free(encoder_t *enc) { + encoder_close(enc); + g_slice_free1(sizeof(*enc), enc); +} + +int encoder_input_data(encoder_t *enc, AVFrame *frame, + int (*callback)(encoder_t *, void *u1, void *u2), void *u1, void *u2) +{ + int keep_going; + int have_frame = 1; + do { + keep_going = 0; + int got_packet = 0; + +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 36, 0) + if (have_frame) { + int ret = avcodec_send_frame(enc->avcctx, frame); + dbg("send frame ret %i", ret); + if (ret == 0) { + // consumed + have_frame = 0; + keep_going = 1; + } + else { + if (ret == AVERROR(EAGAIN)) + ; // check output and maybe try again + else + return -1; + } + } + + int ret = avcodec_receive_packet(enc->avcctx, &enc->avpkt); + dbg("receive packet ret %i", ret); + if (ret == 0) { + // got some data + keep_going = 1; + got_packet = 1; + } + else { + if (ret == AVERROR(EAGAIN)) + ; // try again if there's still more input + else + return -1; + } +#else + if (!have_frame) + break; + + int ret = avcodec_encode_audio2(enc->avcctx, &enc->avpkt, frame, &got_packet); + dbg("encode frame ret %i, got packet %i", ret, got_packet); + if (ret == 0) + have_frame = 0; // consumed + else + return -1; // error + if (got_packet) + keep_going = 1; +#endif + + if (!got_packet) + continue; + +// dbg("{%s} output avpkt size is %i", output->file_name, (int) enc->avpkt.size); +// dbg("{%s} output pkt pts/dts is %li/%li", output->file_name, (long) enc->avpkt.pts, +// (long) enc->avpkt.dts); +// dbg("{%s} output dts %li", output->file_name, (long) output->mux_dts); + + // the encoder may return frames with the same dts multiple consecutive times. + // the muxer may not like this, so ensure monotonically increasing dts. + if (enc->mux_dts > enc->avpkt.dts) + enc->avpkt.dts = enc->mux_dts; + if (enc->avpkt.pts < enc->avpkt.dts) + enc->avpkt.pts = enc->avpkt.dts; + + //av_write_frame(output->fmtctx, &output->avpkt); + callback(enc, u1, u2); + + //output->fifo_pts += output->frame->nb_samples; + enc->mux_dts = enc->avpkt.dts + 1; // min next expected dts + + av_packet_unref(&enc->avpkt); + } while (keep_going); + + return 0; +} diff --git a/lib/codeclib.h b/lib/codeclib.h index 472502bcb..f6ba15cb5 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -10,6 +10,7 @@ struct codec_def_s; struct decoder_s; +struct encoder_s; struct format_s; struct resample_s; struct seq_packet_s; @@ -17,6 +18,7 @@ struct packet_sequencer_s; typedef struct codec_def_s codec_def_t; typedef struct decoder_s decoder_t; +typedef struct encoder_s encoder_t; typedef struct format_s format_t; typedef struct resample_s resample_t; typedef struct seq_packet_s seq_packet_t; @@ -56,6 +58,16 @@ struct decoder_s { unsigned int mixer_idx; }; +struct encoder_s { + format_t requested_format, + actual_format; + + AVCodec *codec; + AVCodecContext *avcctx; + AVPacket avpkt; + int64_t mux_dts; // last dts passed to muxer +}; + struct seq_packet_s { int seq; }; @@ -78,6 +90,14 @@ int decoder_input_data(decoder_t *dec, const str *data, unsigned long ts, int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2); +encoder_t *encoder_new(); +int encoder_config(encoder_t *enc, int codec_id, int bitrate, + const format_t *requested_format, format_t *actual_format); +void encoder_close(encoder_t *); +void encoder_free(encoder_t *); +int encoder_input_data(encoder_t *enc, AVFrame *frame, + int (*callback)(encoder_t *, void *u1, void *u2), void *u1, void *u2); + void packet_sequencer_init(packet_sequencer_t *ps, GDestroyNotify); void packet_sequencer_destroy(packet_sequencer_t *ps); diff --git a/recording-daemon/.ycm_extra_conf.py b/recording-daemon/.ycm_extra_conf.py index 64842e9e0..bc65e7192 100644 --- a/recording-daemon/.ycm_extra_conf.py +++ b/recording-daemon/.ycm_extra_conf.py @@ -18,6 +18,7 @@ flags = [ '-fno-strict-aliasing', '-I/usr/include/glib-2.0', '-I/usr/lib/x86_64-linux-gnu/glib-2.0/include', + '-I/usr/include/mysql', '-I../lib/', '-pthread', '-D_GNU_SOURCE', diff --git a/recording-daemon/db.c b/recording-daemon/db.c index 99a2598f9..24e55c9cd 100644 --- a/recording-daemon/db.c +++ b/recording-daemon/db.c @@ -317,8 +317,8 @@ void db_config_stream(output_t *op) { return; MYSQL_BIND b[3]; - my_i(&b[0], &op->actual_format.channels); - my_i(&b[1], &op->actual_format.clockrate); + my_i(&b[0], &op->encoder->actual_format.channels); + my_i(&b[1], &op->encoder->actual_format.clockrate); my_ull(&b[2], &op->db_id); execute_wrap(&stm_config_stream, b, NULL); diff --git a/recording-daemon/main.c b/recording-daemon/main.c index 290e7f333..75437a9ce 100644 --- a/recording-daemon/main.c +++ b/recording-daemon/main.c @@ -62,43 +62,10 @@ static void signals(void) { } -static void avlog_ilog(void *ptr, int loglevel, const char *fmt, va_list ap) { - char *msg; - if (vasprintf(&msg, fmt, ap) <= 0) - ilog(LOG_ERR, "av_log message dropped"); - else { -#ifdef AV_LOG_PANIC - // translate AV_LOG_ constants to LOG_ levels - if (loglevel >= AV_LOG_VERBOSE) - loglevel = LOG_DEBUG; - else if (loglevel >= AV_LOG_INFO) - loglevel = LOG_NOTICE; - else if (loglevel >= AV_LOG_WARNING) - loglevel = LOG_WARNING; - else if (loglevel >= AV_LOG_ERROR) - loglevel = LOG_ERROR; - else if (loglevel >= AV_LOG_FATAL) - loglevel = LOG_CRIT; - else - loglevel = LOG_ALERT; -#else - // defuse avlog log levels to be either DEBUG or ERR - if (loglevel <= LOG_ERR) - loglevel = LOG_ERR; - else - loglevel = LOG_DEBUG; -#endif - ilog(loglevel, "av_log: %s", msg); - free(msg); - } -} - - static void setup(void) { log_init("rtpengine-recording"); if (output_enabled) { codeclib_init(); - av_log_set_callback(avlog_ilog); output_init(output_format); if (!g_file_test(output_dir, G_FILE_TEST_IS_DIR)) { ilog(LOG_INFO, "Creating output dir '%s'", output_dir); diff --git a/recording-daemon/output.c b/recording-daemon/output.c index 20ec6f477..6cb245506 100644 --- a/recording-daemon/output.c +++ b/recording-daemon/output.c @@ -19,6 +19,22 @@ static void output_shutdown(output_t *output); +static int output_got_packet(encoder_t *enc, void *u1, void *u2) { + output_t *output = u1; + + dbg("{%s} output avpkt size is %i", output->file_name, (int) enc->avpkt.size); + dbg("{%s} output pkt pts/dts is %li/%li", output->file_name, (long) enc->avpkt.pts, + (long) enc->avpkt.dts); + dbg("{%s} output dts %li", output->file_name, (long) output->encoder->mux_dts); + + av_write_frame(output->fmtctx, &enc->avpkt); + + output->fifo_pts += output->frame->nb_samples; + + return 0; +} + + static int output_flush(output_t *output) { while (av_audio_fifo_size(output->fifo) >= output->frame->nb_samples) { @@ -29,78 +45,7 @@ static int output_flush(output_t *output) { dbg("{%s} output fifo pts %lu", output->file_name, (unsigned long) output->fifo_pts); output->frame->pts = output->fifo_pts; - int keep_going; - int have_frame = 1; - do { - keep_going = 0; - int got_packet = 0; - -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 36, 0) - if (have_frame) { - int ret = avcodec_send_frame(output->avcctx, output->frame); - dbg("{%s} send frame ret %i", output->file_name, ret); - if (ret == 0) { - // consumed - have_frame = 0; - keep_going = 1; - } - else { - if (ret == AVERROR(EAGAIN)) - ; // check output and maybe try again - else - return -1; - } - } - - int ret = avcodec_receive_packet(output->avcctx, &output->avpkt); - dbg("{%s} receive packet ret %i", output->file_name, ret); - if (ret == 0) { - // got some data - keep_going = 1; - got_packet = 1; - } - else { - if (ret == AVERROR(EAGAIN)) - ; // try again if there's still more input - else - return -1; - } -#else - if (!have_frame) - break; - - int ret = avcodec_encode_audio2(output->avcctx, &output->avpkt, output->frame, &got_packet); - dbg("{%s} encode frame ret %i, got packet %i", output->file_name, ret, got_packet); - if (ret == 0) - have_frame = 0; // consumed - else - return -1; // error - if (got_packet) - keep_going = 1; -#endif - - if (!got_packet) - continue; - - dbg("{%s} output avpkt size is %i", output->file_name, (int) output->avpkt.size); - dbg("{%s} output pkt pts/dts is %li/%li", output->file_name, (long) output->avpkt.pts, - (long) output->avpkt.dts); - dbg("{%s} output dts %li", output->file_name, (long) output->mux_dts); - - // the encoder may return frames with the same dts multiple consecutive times. - // the muxer may not like this, so ensure monotonically increasing dts. - if (output->mux_dts > output->avpkt.dts) - output->avpkt.dts = output->mux_dts; - if (output->avpkt.pts < output->avpkt.dts) - output->avpkt.pts = output->avpkt.dts; - - av_write_frame(output->fmtctx, &output->avpkt); - - output->fifo_pts += output->frame->nb_samples; - output->mux_dts = output->avpkt.dts + 1; // min next expected dts - - av_packet_unref(&output->avpkt); - } while (keep_going); + encoder_input_data(output->encoder, output->frame, output_got_packet, output, NULL); } return 0; @@ -131,9 +76,8 @@ output_t *output_new(const char *path, const char *filename) { g_strlcpy(ret->file_path, path, sizeof(ret->file_path)); g_strlcpy(ret->file_name, filename, sizeof(ret->file_name)); snprintf(ret->full_filename, sizeof(ret->full_filename), "%s/%s", path, filename); - format_init(&ret->requested_format); - format_init(&ret->actual_format); ret->file_format = output_file_format; + ret->encoder = encoder_new(); return ret; } @@ -141,13 +85,13 @@ output_t *output_new(const char *path, const char *filename) { int output_config(output_t *output, const format_t *requested_format, format_t *actual_format) { const char *err; - // anything to do? - if (G_LIKELY(format_eq(requested_format, &output->requested_format))) - goto done; +// // anything to do? +// if (G_LIKELY(format_eq(requested_format, &output->requested_format))) +// goto done; output_shutdown(output); - output->requested_format = *requested_format; +// output->requested_format = *requested_format; err = "failed to alloc format context"; output->fmtctx = avformat_alloc_context(); @@ -158,47 +102,50 @@ int output_config(output_t *output, const format_t *requested_format, format_t * if (!output->fmtctx->oformat) goto err; - err = "output codec not found"; - AVCodec *codec = avcodec_find_encoder(output_codec_id); - if (!codec) + if (encoder_config(output->encoder, output_codec_id, mp3_bitrate, requested_format, actual_format)) goto err; + +// err = "output codec not found"; +// AVCodec *codec = avcodec_find_encoder(output_codec_id); +// if (!codec) +// goto err; err = "failed to alloc output stream"; - output->avst = avformat_new_stream(output->fmtctx, codec); + output->avst = avformat_new_stream(output->fmtctx, output->encoder->codec); if (!output->avst) goto err; -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0) - err = "failed to alloc codec context"; - output->avcctx = avcodec_alloc_context3(codec); - if (!output->avcctx) - goto err; -#else - output->avcctx = output->avst->codec; -#endif +//#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0) +// err = "failed to alloc codec context"; +// output->avcctx = avcodec_alloc_context3(codec); +// if (!output->avcctx) +// goto err; +//#else +// output->avcctx = output->avst->codec; +//#endif // copy all format params - output->actual_format = output->requested_format; +// output->actual_format = output->requested_format; // determine sample format to use - output->actual_format.format = -1; - for (const enum AVSampleFormat *sfmt = codec->sample_fmts; sfmt && *sfmt != -1; sfmt++) { - dbg("supported sample format for output codec %s: %s", codec->name, av_get_sample_fmt_name(*sfmt)); - if (*sfmt == requested_format->format) - output->actual_format.format = *sfmt; - } - if (output->actual_format.format == -1 && codec->sample_fmts) - output->actual_format.format = codec->sample_fmts[0]; - dbg("using output sample format %s for codec %s", av_get_sample_fmt_name(output->actual_format.format), codec->name); - - output->avcctx->channels = output->actual_format.channels; - output->avcctx->channel_layout = av_get_default_channel_layout(output->actual_format.channels); - output->avcctx->sample_rate = output->actual_format.clockrate; - output->avcctx->sample_fmt = output->actual_format.format; - output->avcctx->time_base = (AVRational){1,output->actual_format.clockrate}; - output->avcctx->bit_rate = mp3_bitrate; - output->avst->time_base = output->avcctx->time_base; +// output->actual_format.format = -1; +// for (const enum AVSampleFormat *sfmt = codec->sample_fmts; sfmt && *sfmt != -1; sfmt++) { +// dbg("supported sample format for output codec %s: %s", codec->name, av_get_sample_fmt_name(*sfmt)); +// if (*sfmt == requested_format->format) +// output->actual_format.format = *sfmt; +// } +// if (output->actual_format.format == -1 && codec->sample_fmts) +// output->actual_format.format = codec->sample_fmts[0]; +// dbg("using output sample format %s for codec %s", av_get_sample_fmt_name(output->actual_format.format), codec->name); +// +// output->avcctx->channels = output->actual_format.channels; +// output->avcctx->channel_layout = av_get_default_channel_layout(output->actual_format.channels); +// output->avcctx->sample_rate = output->actual_format.clockrate; +// output->avcctx->sample_fmt = output->actual_format.format; +// output->avcctx->time_base = (AVRational){1,output->actual_format.clockrate}; +// output->avcctx->bit_rate = mp3_bitrate; + output->avst->time_base = output->encoder->avcctx->time_base; #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 26, 0) // exact version? present in 57.56 - avcodec_parameters_from_context(output->avst->codecpar, output->avcctx); + avcodec_parameters_from_context(output->avst->codecpar, output->encoder->avcctx); #endif char full_fn[PATH_MAX*2]; @@ -214,11 +161,12 @@ int output_config(output_t *output, const format_t *requested_format, format_t * goto err; got_fn: - err = "failed to open output context"; - int i = avcodec_open2(output->avcctx, codec, NULL); - if (i) - goto err; +// err = "failed to open output context"; +// int i = avcodec_open2(output->avcctx, codec, NULL); +// if (i) +// goto err; err = "failed to open avio"; + int i; i = avio_open(&output->fmtctx->pb, full_fn, AVIO_FLAG_WRITE); if (i < 0) goto err; @@ -227,24 +175,22 @@ got_fn: if (i) goto err; - av_init_packet(&output->avpkt); +// av_init_packet(&output->avpkt); // output frame and fifo output->frame = av_frame_alloc(); - output->frame->nb_samples = output->avcctx->frame_size ? : 256; - output->frame->format = output->avcctx->sample_fmt; - output->frame->sample_rate = output->avcctx->sample_rate; - output->frame->channel_layout = output->avcctx->channel_layout; + output->frame->nb_samples = output->encoder->avcctx->frame_size ? : 256; + output->frame->format = output->encoder->avcctx->sample_fmt; + output->frame->sample_rate = output->encoder->avcctx->sample_rate; + output->frame->channel_layout = output->encoder->avcctx->channel_layout; if (!output->frame->channel_layout) - output->frame->channel_layout = av_get_default_channel_layout(output->avcctx->channels); + output->frame->channel_layout = av_get_default_channel_layout(output->encoder->avcctx->channels); if (av_frame_get_buffer(output->frame, 0) < 0) abort(); - output->fifo = av_audio_fifo_alloc(output->avcctx->sample_fmt, output->avcctx->channels, + output->fifo = av_audio_fifo_alloc(output->encoder->avcctx->sample_fmt, output->encoder->avcctx->channels, output->frame->nb_samples); -done: - *actual_format = output->actual_format; db_config_stream(output); return 0; @@ -265,24 +211,25 @@ static void output_shutdown(output_t *output) { av_write_trailer(output->fmtctx); avio_closep(&output->fmtctx->pb); } - avcodec_close(output->avcctx); -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0) - avcodec_free_context(&output->avcctx); -#endif +// avcodec_close(output->avcctx); +//#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0) +// avcodec_free_context(&output->avcctx); +//#endif avformat_free_context(output->fmtctx); av_audio_fifo_free(output->fifo); av_frame_free(&output->frame); - output->avcctx = NULL; + encoder_close(output->encoder); + +// output->avcctx = NULL; output->fmtctx = NULL; output->avst = NULL; output->fifo = NULL; output->fifo_pts = 0; - output->mux_dts = 0; - format_init(&output->requested_format); - format_init(&output->actual_format); +// format_init(&output->requested_format); +// format_init(&output->actual_format); } @@ -291,6 +238,7 @@ void output_close(output_t *output) { return; output_shutdown(output); db_close_stream(output); + encoder_free(output->encoder); g_slice_free1(sizeof(*output), output); } diff --git a/recording-daemon/types.h b/recording-daemon/types.h index 9ebc2c937..5524fb7a9 100644 --- a/recording-daemon/types.h +++ b/recording-daemon/types.h @@ -110,17 +110,18 @@ struct output_s { const char *file_format; unsigned long long db_id; - format_t requested_format, - actual_format; +// format_t requested_format, +// actual_format; - AVCodecContext *avcctx; +// AVCodecContext *avcctx; AVFormatContext *fmtctx; AVStream *avst; - AVPacket avpkt; +// AVPacket avpkt; AVAudioFifo *fifo; int64_t fifo_pts; // pts of first data in fifo - int64_t mux_dts; // last dts passed to muxer +// int64_t mux_dts; // last dts passed to muxer AVFrame *frame; + encoder_t *encoder; };