From 6028d064cc887792c73ed338cb86a16db5bef721 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 9 Dec 2024 09:20:07 -0400 Subject: [PATCH] MT#55283 add a second step of resampling In some cases, in particular when multiple input codecs are transcoding to the same output codec (e.g. audio + DTMF -> audio), it's possible that one of the input decoders produces frames in a format different from the one expected by the encoder. Add an encoder-side resampler to compensate for that. Change-Id: I74d55edf47ac2fa65f950e68f4a5975f1ab947bb (cherry picked from commit 461f663e5853ac372969488786d6694948517402) --- lib/codeclib.c | 9 ++- lib/codeclib.h | 2 + t/auto-daemon-tests.pl | 158 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 1 deletion(-) diff --git a/lib/codeclib.c b/lib/codeclib.c index b2fe50918..a0f50e97d 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -1773,6 +1773,7 @@ void encoder_close(encoder_t *enc) { void encoder_free(encoder_t *enc) { encoder_close(enc); av_packet_free(&enc->avpkt); + resample_shutdown(&enc->resampler); g_slice_free1(sizeof(*enc), enc); } @@ -1913,8 +1914,14 @@ static int encoder_fifo_flush(encoder_t *enc, int encoder_input_fifo(encoder_t *enc, AVFrame *frame, int (*callback)(encoder_t *, void *u1, void *u2), void *u1, void *u2) { - if (av_audio_fifo_write(enc->fifo, (void **) frame->extended_data, frame->nb_samples) < 0) + AVFrame *rsmp_frame = resample_frame(&enc->resampler, frame, &enc->actual_format); + if (!rsmp_frame) { + ilog(LOG_ERR | LOG_FLAG_LIMIT, "Resampling failed"); return -1; + } + if (av_audio_fifo_write(enc->fifo, (void **) rsmp_frame->extended_data, rsmp_frame->nb_samples) < 0) + return -1; + av_frame_free(&rsmp_frame); return encoder_fifo_flush(enc, callback, u1, u2); } diff --git a/lib/codeclib.h b/lib/codeclib.h index d9ccf8dd6..39d7cd571 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -314,6 +314,8 @@ struct encoder_s { encoder_callback_t callback; union codec_format_options format_options; + resample_t resampler; + union { struct { const AVCodec *codec; diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index 45737eaec..25a6e97ff 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -82,6 +82,164 @@ sub stun_succ { +($sock_a, $sock_b) = new_call([qw(198.51.100.65 3000)], [qw(198.51.100.65 3002)]); + +($port_a) = offer('opus<>opus+DTMF', { }, <opus+DTMF', { flags => [qw,allow-asymmetric-codecs,] }, <opus+DTMF', { codec => { accept => ['all'], transcode => [qw,G722 PCMA,] } }, <opus+DTMF', { }, <