Cleanup and rewrite of the audio resampling code to use non-deprecated code when possible

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2023-02-07 00:40:51 +01:00
parent b79444cdd9
commit 456dd531cf
2 changed files with 70 additions and 107 deletions

View File

@ -106,13 +106,15 @@ int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence)
}
CAudioStream::CAudioStream (CAudioContext* context, const std::string& filename) :
m_audioContext (context)
m_audioContext (context),
m_swrctx (nullptr)
{
this->loadCustomContent (filename.c_str ());
}
CAudioStream::CAudioStream (CAudioContext* context, const void* buffer, int length) :
m_audioContext (context)
m_audioContext (context),
m_swrctx (nullptr)
{
// setup a custom context first
this->m_formatContext = avformat_alloc_context ();
@ -145,11 +147,22 @@ CAudioStream::CAudioStream (CAudioContext* context, const void* buffer, int leng
CAudioStream::CAudioStream(CAudioContext* audioContext, AVCodecContext* context) :
m_context (context),
m_queue (new PacketQueue),
m_audioContext (audioContext)
m_audioContext (audioContext),
m_swrctx (nullptr)
{
this->initialize ();
}
CAudioStream::~CAudioStream()
{
if (this->m_swrctx != nullptr && swr_is_initialized (this->m_swrctx) == true)
swr_close (this->m_swrctx);
if (this->m_swrctx != nullptr)
swr_free (&this->m_swrctx);
// TODO: FREE EVERYTHING ELSE THAT THIS CLASS HOLDS!
}
void CAudioStream::loadCustomContent (const char* filename)
{
const AVCodec* aCodec = nullptr;
@ -204,6 +217,51 @@ void CAudioStream::initialize ()
this->m_queue->packetList = av_fifo_alloc (sizeof (MyAVPacketList));
#endif
int64_t out_channel_layout;
// set output audio channels based on the input audio channels
switch (this->m_audioContext->getChannels ())
{
case 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
}
#if FF_API_OLD_CHANNEL_LAYOUT
av_channel_layout_from_mask (&this->m_out_channel_layout, out_channel_layout);
swr_alloc_set_opts2 (
&this->m_swrctx,
&this->m_out_channel_layout,
this->m_audioContext->getFormat (),
this->m_audioContext->getSampleRate (),
&this->m_context->ch_layout,
this->m_context->sample_fmt,
this->m_context->sample_rate,
0,
nullptr
);
#else
// initialize swrctx
this->m_swrctx = swr_alloc_set_opts (
nullptr,
out_channel_layout,
this->m_audioContext->getFormat (),
this->m_audioContext->getSampleRate (),
this->getContext ()->channel_layout,
this->getContext ()->sample_fmt,
this->getContext ()->sample_rate,
0,
nullptr
);
#endif
if (this->m_swrctx == nullptr)
sLog.exception ("Cannot initialize swrctx for audio resampling");
// initialize the context
if (swr_init (this->m_swrctx) < 0)
sLog.exception("Failed to initialize the resampling context.");
// setup the queue information
this->m_queue->mutex = SDL_CreateMutex ();
this->m_queue->cond = SDL_CreateCond ();
@ -397,10 +455,7 @@ int CAudioStream::resampleAudio (
uint8_t * out_buf
)
{
SwrContext * swr_ctx = NULL;
int ret = 0;
int64_t in_channel_layout = this->getContext ()->channel_layout;
int64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
int out_nb_channels = 0;
int out_linesize = 0;
int in_nb_samples = 0;
@ -409,41 +464,6 @@ int CAudioStream::resampleAudio (
uint8_t ** resampled_data = NULL;
int resampled_data_size = 0;
swr_ctx = swr_alloc();
if (!swr_ctx)
{
sLog.error("swr_alloc error.\n");
return -1;
}
// get input audio channels
in_channel_layout = (this->getContext ()->channels ==
av_get_channel_layout_nb_channels(this->getContext ()->channel_layout)) ? // 2
this->getContext ()->channel_layout :
av_get_default_channel_layout(this->getContext ()->channels);
// check input audio channels correctly retrieved
if (in_channel_layout <= 0)
{
sLog.error("in_channel_layout error.\n");
return -1;
}
// set output audio channels based on the input audio channels
if (out_channels == 1)
{
out_channel_layout = AV_CH_LAYOUT_MONO;
}
else if (out_channels == 2)
{
out_channel_layout = AV_CH_LAYOUT_STEREO;
}
else
{
out_channel_layout = AV_CH_LAYOUT_SURROUND;
}
// retrieve number of audio samples (per channel)
in_nb_samples = decoded_audio_frame->nb_samples;
if (in_nb_samples <= 0)
@ -452,63 +472,6 @@ int CAudioStream::resampleAudio (
return -1;
}
// Set SwrContext parameters for resampling
av_opt_set_int( // 3
swr_ctx,
"in_channel_layout",
in_channel_layout,
0
);
// Set SwrContext parameters for resampling
av_opt_set_int(
swr_ctx,
"in_sample_rate",
this->getContext ()->sample_rate,
0
);
// Set SwrContext parameters for resampling
av_opt_set_sample_fmt(
swr_ctx,
"in_sample_fmt",
this->getContext ()->sample_fmt,
0
);
// Set SwrContext parameters for resampling
av_opt_set_int(
swr_ctx,
"out_channel_layout",
out_channel_layout,
0
);
// Set SwrContext parameters for resampling
av_opt_set_int(
swr_ctx,
"out_sample_rate",
out_sample_rate,
0
);
// Set SwrContext parameters for resampling
av_opt_set_sample_fmt(
swr_ctx,
"out_sample_fmt",
out_sample_fmt,
0
);
// Once all values have been set for the SwrContext, it must be initialized
// with swr_init().
ret = swr_init(swr_ctx);;
if (ret < 0)
{
sLog.error("Failed to initialize the resampling context.");
return -1;
}
max_out_nb_samples = out_nb_samples = av_rescale_rnd(
in_nb_samples,
out_sample_rate,
@ -524,7 +487,7 @@ int CAudioStream::resampleAudio (
}
// get number of output audio channels
out_nb_channels = av_get_channel_layout_nb_channels(out_channel_layout);
out_nb_channels = this->getContext ()->ch_layout.nb_channels;
ret = av_samples_alloc_array_and_samples(
&resampled_data,
@ -543,7 +506,7 @@ int CAudioStream::resampleAudio (
// retrieve output samples number taking into account the progressive delay
out_nb_samples = av_rescale_rnd(
swr_get_delay(swr_ctx, this->getContext ()->sample_rate) + in_nb_samples,
swr_get_delay(this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
out_sample_rate,
this->getContext ()->sample_rate,
AV_ROUND_UP
@ -583,7 +546,7 @@ int CAudioStream::resampleAudio (
// do the actual audio data resampling
ret = swr_convert(
swr_ctx,
this->m_swrctx,
resampled_data,
out_nb_samples,
(const uint8_t **) decoded_audio_frame->data,
@ -628,12 +591,6 @@ int CAudioStream::resampleAudio (
av_freep(&resampled_data);
resampled_data = NULL;
if (swr_ctx)
{
// Free the given SwrContext and set the pointer to NULL
swr_free(&swr_ctx);
}
return resampled_data_size;
}

View File

@ -25,6 +25,7 @@ namespace WallpaperEngine::Audio
CAudioStream (CAudioContext* context, const std::string& filename);
CAudioStream (CAudioContext* context, const void* buffer, int length);
CAudioStream (CAudioContext* audioContext, AVCodecContext* context);
~CAudioStream ();
void queuePacket (AVPacket* pkt);
@ -64,6 +65,11 @@ namespace WallpaperEngine::Audio
bool doQueue (AVPacket* pkt);
void initialize ();
#if FF_API_OLD_CHANNEL_LAYOUT
AVChannelLayout m_out_channel_layout;
#endif
SwrContext* m_swrctx;
CAudioContext* m_audioContext;
bool m_initialized;
bool m_repeat;