From acc30ec0fa4a9b1d91e318923200241321b02f58 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 12 Dec 2024 12:25:56 -0400 Subject: [PATCH] MT#55283 amend resample_frame() semantics In many transcoding scenarios resampling is not actually required. We can shortcut the operation by just returning the original frame, instead of a cloned and newly allocated one. We just need to distinguish between the cases to determine whether the frame returned by resample_frame() needs to be freed. Change-Id: I3f36a46bd3b967f140c8353119fdb24ad8363c15 --- daemon/codec.c | 3 ++- lib/codeclib.c | 6 ++++-- lib/resample.c | 2 +- recording-daemon/decoder.c | 8 ++++++-- recording-daemon/mix.c | 3 ++- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 6ea60b464..d0034d83c 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -4180,7 +4180,8 @@ static void __dtmf_detect(struct codec_ssrc_handler *ch, AVFrame *frame) { num_samples = ret; } ch->dtmf_ts = dsp_frame->pts + dsp_frame->nb_samples; - av_frame_free(&dsp_frame); + if (dsp_frame != frame) + av_frame_free(&dsp_frame); } static int packet_decoded_common(decoder_t *decoder, AVFrame *frame, void *u1, void *u2, diff --git a/lib/codeclib.c b/lib/codeclib.c index 06ecdae1c..7b932105a 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -1238,7 +1238,8 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t if (callback(dec, rsmp_frame, u1, u2)) ret = -1; } - av_frame_free(&frame); + if (rsmp_frame != frame) + av_frame_free(&frame); } if (ptime) @@ -2158,7 +2159,8 @@ int encoder_input_fifo(encoder_t *enc, AVFrame *frame, } if (av_audio_fifo_write(enc->fifo, (void **) rsmp_frame->extended_data, rsmp_frame->nb_samples) < 0) return -1; - av_frame_free(&rsmp_frame); + if (rsmp_frame != frame) + av_frame_free(&rsmp_frame); return encoder_fifo_flush(enc, callback, u1, u2); } diff --git a/lib/resample.c b/lib/resample.c index 8fbc58022..16f07378c 100644 --- a/lib/resample.c +++ b/lib/resample.c @@ -31,7 +31,7 @@ AVFrame *resample_frame(resample_t *resample, AVFrame *frame, const format_t *to if (!CH_LAYOUT_EQ(frame->CH_LAYOUT, to_channel_layout)) goto resample; - return av_frame_clone(frame); + return frame; resample: diff --git a/recording-daemon/decoder.c b/recording-daemon/decoder.c index a4ba07d91..ab1cc228e 100644 --- a/recording-daemon/decoder.c +++ b/recording-daemon/decoder.c @@ -121,13 +121,16 @@ static int decoder_got_frame(decoder_t *dec, AVFrame *frame, void *sp, void *dp) goto no_mix_out; mix_config(metafile->mix, &actual_format); // XXX might be a second resampling to same format - AVFrame *dec_frame = resample_frame(&deco->mix_resampler, frame, &actual_format); + AVFrame *copy_frame = av_frame_clone(frame); + AVFrame *dec_frame = resample_frame(&deco->mix_resampler, copy_frame, &actual_format); if (!dec_frame) { pthread_mutex_unlock(&metafile->mix_lock); goto err; } if (mix_add(metafile->mix, dec_frame, deco->mixer_idx, ssrc, metafile->mix_out)) ilog(LOG_ERR, "Failed to add decoded packet to mixed output"); + if (dec_frame != copy_frame) + av_frame_free(©_frame); } no_mix_out: pthread_mutex_unlock(&metafile->mix_lock); @@ -183,7 +186,8 @@ no_recording: int linesize = av_get_bytes_per_sample(dec_frame->format) * dec_frame->nb_samples; dbg("Writing %u bytes PCM to TLS", linesize); streambuf_write(ssrc->tls_fwd_stream, (char *) dec_frame->extended_data[0], linesize); - av_frame_free(&dec_frame); + if (dec_frame != frame) + av_frame_free(&dec_frame); } diff --git a/recording-daemon/mix.c b/recording-daemon/mix.c index c50f9364d..6f79d5231 100644 --- a/recording-daemon/mix.c +++ b/recording-daemon/mix.c @@ -393,7 +393,8 @@ int mix_add(mix_t *mix, AVFrame *frame, unsigned int idx, void *ptr, output_t *o ret = output_add(output, frame); av_frame_unref(mix->sink_frame); - av_frame_free(&frame); + if (frame != mix->sink_frame) + av_frame_free(&frame); if (ret) return -1;