|
|
|
@ -6,7 +6,7 @@ |
|
|
|
#include <libavutil/channel_layout.h> |
|
|
|
#include <libavutil/mathematics.h> |
|
|
|
#include <inttypes.h> |
|
|
|
#include <libavresample/avresample.h> |
|
|
|
#include <libswresample/swresample.h> |
|
|
|
#include <libavutil/opt.h> |
|
|
|
#include <libavutil/frame.h> |
|
|
|
#include "log.h" |
|
|
|
@ -34,42 +34,28 @@ AVFrame *resample_frame(resample_t *resample, AVFrame *frame, const format_t *to |
|
|
|
|
|
|
|
resample: |
|
|
|
|
|
|
|
if (G_UNLIKELY(!resample->avresample)) { |
|
|
|
resample->avresample = avresample_alloc_context(); |
|
|
|
if (G_UNLIKELY(!resample->swresample)) { |
|
|
|
resample->swresample = swr_alloc_set_opts(NULL, |
|
|
|
to_channel_layout, |
|
|
|
to_format->format, |
|
|
|
to_format->clockrate, |
|
|
|
frame->channel_layout, |
|
|
|
frame->format, |
|
|
|
frame->sample_rate, |
|
|
|
0, NULL); |
|
|
|
err = "failed to alloc resample context"; |
|
|
|
if (!resample->avresample) |
|
|
|
if (!resample->swresample) |
|
|
|
goto err; |
|
|
|
|
|
|
|
err = "failed to set resample option"; |
|
|
|
if ((errcode = av_opt_set_int(resample->avresample, "in_channel_layout", |
|
|
|
frame->channel_layout, 0))) |
|
|
|
goto err; |
|
|
|
if ((errcode = av_opt_set_int(resample->avresample, "in_sample_fmt", |
|
|
|
frame->format, 0))) |
|
|
|
goto err; |
|
|
|
if ((errcode = av_opt_set_int(resample->avresample, "in_sample_rate", |
|
|
|
frame->sample_rate, 0))) |
|
|
|
goto err; |
|
|
|
if ((errcode = av_opt_set_int(resample->avresample, "out_channel_layout", |
|
|
|
to_channel_layout, 0))) |
|
|
|
goto err; |
|
|
|
if ((errcode = av_opt_set_int(resample->avresample, "out_sample_fmt", |
|
|
|
to_format->format, 0))) |
|
|
|
goto err; |
|
|
|
if ((errcode = av_opt_set_int(resample->avresample, "out_sample_rate", |
|
|
|
to_format->clockrate, 0))) |
|
|
|
goto err; |
|
|
|
// av_opt_set_int(dec->avresample, "internal_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); // ? |
|
|
|
|
|
|
|
err = "failed to init resample context"; |
|
|
|
if ((errcode = avresample_open(resample->avresample)) < 0) |
|
|
|
if ((errcode = swr_init(resample->swresample)) < 0) |
|
|
|
goto err; |
|
|
|
} |
|
|
|
|
|
|
|
// get a large enough buffer for resampled audio - this should be enough so we don't |
|
|
|
// have to loop |
|
|
|
int dst_samples = avresample_available(resample->avresample) + |
|
|
|
av_rescale_rnd(avresample_get_delay(resample->avresample) + frame->nb_samples, |
|
|
|
int dst_samples = av_rescale_rnd(swr_get_delay(resample->swresample, to_format->clockrate) |
|
|
|
+ frame->nb_samples, |
|
|
|
to_format->clockrate, frame->sample_rate, AV_ROUND_UP); |
|
|
|
|
|
|
|
AVFrame *swr_frame = av_frame_alloc(); |
|
|
|
@ -86,11 +72,10 @@ resample: |
|
|
|
if ((errcode = av_frame_get_buffer(swr_frame, 0)) < 0) |
|
|
|
goto err; |
|
|
|
|
|
|
|
swr_frame->nb_samples = dst_samples; |
|
|
|
int ret_samples = avresample_convert(resample->avresample, swr_frame->extended_data, |
|
|
|
swr_frame->linesize[0], dst_samples, |
|
|
|
frame->extended_data, |
|
|
|
frame->linesize[0], frame->nb_samples); |
|
|
|
int ret_samples = swr_convert(resample->swresample, swr_frame->extended_data, |
|
|
|
dst_samples, |
|
|
|
(const uint8_t **) frame->extended_data, |
|
|
|
frame->nb_samples); |
|
|
|
err = "failed to resample audio"; |
|
|
|
if ((errcode = ret_samples) < 0) |
|
|
|
goto err; |
|
|
|
@ -107,5 +92,5 @@ err: |
|
|
|
|
|
|
|
|
|
|
|
void resample_shutdown(resample_t *resample) { |
|
|
|
avresample_free(&resample->avresample); |
|
|
|
swr_free(&resample->swresample); |
|
|
|
} |