mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
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:
parent
b79444cdd9
commit
456dd531cf
@ -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) :
|
CAudioStream::CAudioStream (CAudioContext* context, const std::string& filename) :
|
||||||
m_audioContext (context)
|
m_audioContext (context),
|
||||||
|
m_swrctx (nullptr)
|
||||||
{
|
{
|
||||||
this->loadCustomContent (filename.c_str ());
|
this->loadCustomContent (filename.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
CAudioStream::CAudioStream (CAudioContext* context, const void* buffer, int length) :
|
CAudioStream::CAudioStream (CAudioContext* context, const void* buffer, int length) :
|
||||||
m_audioContext (context)
|
m_audioContext (context),
|
||||||
|
m_swrctx (nullptr)
|
||||||
{
|
{
|
||||||
// setup a custom context first
|
// setup a custom context first
|
||||||
this->m_formatContext = avformat_alloc_context ();
|
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) :
|
CAudioStream::CAudioStream(CAudioContext* audioContext, AVCodecContext* context) :
|
||||||
m_context (context),
|
m_context (context),
|
||||||
m_queue (new PacketQueue),
|
m_queue (new PacketQueue),
|
||||||
m_audioContext (audioContext)
|
m_audioContext (audioContext),
|
||||||
|
m_swrctx (nullptr)
|
||||||
{
|
{
|
||||||
this->initialize ();
|
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)
|
void CAudioStream::loadCustomContent (const char* filename)
|
||||||
{
|
{
|
||||||
const AVCodec* aCodec = nullptr;
|
const AVCodec* aCodec = nullptr;
|
||||||
@ -204,6 +217,51 @@ void CAudioStream::initialize ()
|
|||||||
this->m_queue->packetList = av_fifo_alloc (sizeof (MyAVPacketList));
|
this->m_queue->packetList = av_fifo_alloc (sizeof (MyAVPacketList));
|
||||||
#endif
|
#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
|
// setup the queue information
|
||||||
this->m_queue->mutex = SDL_CreateMutex ();
|
this->m_queue->mutex = SDL_CreateMutex ();
|
||||||
this->m_queue->cond = SDL_CreateCond ();
|
this->m_queue->cond = SDL_CreateCond ();
|
||||||
@ -397,10 +455,7 @@ int CAudioStream::resampleAudio (
|
|||||||
uint8_t * out_buf
|
uint8_t * out_buf
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SwrContext * swr_ctx = NULL;
|
|
||||||
int ret = 0;
|
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_nb_channels = 0;
|
||||||
int out_linesize = 0;
|
int out_linesize = 0;
|
||||||
int in_nb_samples = 0;
|
int in_nb_samples = 0;
|
||||||
@ -409,41 +464,6 @@ int CAudioStream::resampleAudio (
|
|||||||
uint8_t ** resampled_data = NULL;
|
uint8_t ** resampled_data = NULL;
|
||||||
int resampled_data_size = 0;
|
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)
|
// retrieve number of audio samples (per channel)
|
||||||
in_nb_samples = decoded_audio_frame->nb_samples;
|
in_nb_samples = decoded_audio_frame->nb_samples;
|
||||||
if (in_nb_samples <= 0)
|
if (in_nb_samples <= 0)
|
||||||
@ -452,63 +472,6 @@ int CAudioStream::resampleAudio (
|
|||||||
return -1;
|
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(
|
max_out_nb_samples = out_nb_samples = av_rescale_rnd(
|
||||||
in_nb_samples,
|
in_nb_samples,
|
||||||
out_sample_rate,
|
out_sample_rate,
|
||||||
@ -524,7 +487,7 @@ int CAudioStream::resampleAudio (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get number of output audio channels
|
// 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(
|
ret = av_samples_alloc_array_and_samples(
|
||||||
&resampled_data,
|
&resampled_data,
|
||||||
@ -543,7 +506,7 @@ int CAudioStream::resampleAudio (
|
|||||||
|
|
||||||
// retrieve output samples number taking into account the progressive delay
|
// retrieve output samples number taking into account the progressive delay
|
||||||
out_nb_samples = av_rescale_rnd(
|
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,
|
out_sample_rate,
|
||||||
this->getContext ()->sample_rate,
|
this->getContext ()->sample_rate,
|
||||||
AV_ROUND_UP
|
AV_ROUND_UP
|
||||||
@ -583,7 +546,7 @@ int CAudioStream::resampleAudio (
|
|||||||
|
|
||||||
// do the actual audio data resampling
|
// do the actual audio data resampling
|
||||||
ret = swr_convert(
|
ret = swr_convert(
|
||||||
swr_ctx,
|
this->m_swrctx,
|
||||||
resampled_data,
|
resampled_data,
|
||||||
out_nb_samples,
|
out_nb_samples,
|
||||||
(const uint8_t **) decoded_audio_frame->data,
|
(const uint8_t **) decoded_audio_frame->data,
|
||||||
@ -628,12 +591,6 @@ int CAudioStream::resampleAudio (
|
|||||||
av_freep(&resampled_data);
|
av_freep(&resampled_data);
|
||||||
resampled_data = NULL;
|
resampled_data = NULL;
|
||||||
|
|
||||||
if (swr_ctx)
|
|
||||||
{
|
|
||||||
// Free the given SwrContext and set the pointer to NULL
|
|
||||||
swr_free(&swr_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resampled_data_size;
|
return resampled_data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ namespace WallpaperEngine::Audio
|
|||||||
CAudioStream (CAudioContext* context, const std::string& filename);
|
CAudioStream (CAudioContext* context, const std::string& filename);
|
||||||
CAudioStream (CAudioContext* context, const void* buffer, int length);
|
CAudioStream (CAudioContext* context, const void* buffer, int length);
|
||||||
CAudioStream (CAudioContext* audioContext, AVCodecContext* context);
|
CAudioStream (CAudioContext* audioContext, AVCodecContext* context);
|
||||||
|
~CAudioStream ();
|
||||||
|
|
||||||
void queuePacket (AVPacket* pkt);
|
void queuePacket (AVPacket* pkt);
|
||||||
|
|
||||||
@ -64,6 +65,11 @@ namespace WallpaperEngine::Audio
|
|||||||
bool doQueue (AVPacket* pkt);
|
bool doQueue (AVPacket* pkt);
|
||||||
void initialize ();
|
void initialize ();
|
||||||
|
|
||||||
|
#if FF_API_OLD_CHANNEL_LAYOUT
|
||||||
|
AVChannelLayout m_out_channel_layout;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SwrContext* m_swrctx;
|
||||||
CAudioContext* m_audioContext;
|
CAudioContext* m_audioContext;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
bool m_repeat;
|
bool m_repeat;
|
||||||
|
Loading…
Reference in New Issue
Block a user