aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp17
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp93
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h45
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp31
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h3
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp44
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h3
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp32
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp42
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h2
-rw-r--r--xbmc/cores/AudioEngine/Interfaces/AE.h14
-rw-r--r--xbmc/cores/AudioEngine/Interfaces/AEResample.h9
-rw-r--r--xbmc/cores/AudioEngine/Interfaces/AEStream.h10
-rw-r--r--xbmc/cores/RetroPlayer/buffers/BaseRenderBufferPool.cpp2
-rw-r--r--xbmc/cores/RetroPlayer/streams/RetroPlayerAudio.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/AudioSinkAE.cpp13
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodec.h2
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp23
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h3
-rw-r--r--xbmc/cores/paplayer/PAPlayer.cpp4
-rw-r--r--xbmc/cores/paplayer/VideoPlayerCodec.cpp30
21 files changed, 228 insertions, 196 deletions
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
index cdf81b4614..c9270445d7 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
@@ -3147,21 +3147,12 @@ bool CActiveAE::ResampleSound(CActiveAESound *sound)
}
IAEResample *resampler = CAEResampleFactory::Create(AERESAMPLEFACTORY_QUICK_RESAMPLE);
- resampler->Init(dst_config.channel_layout,
- dst_config.channels,
- dst_config.sample_rate,
- dst_config.fmt,
- dst_config.bits_per_sample,
- dst_config.dither_bits,
- orig_config.channel_layout,
- orig_config.channels,
- orig_config.sample_rate,
- orig_config.fmt,
- orig_config.bits_per_sample,
- orig_config.dither_bits,
+
+ resampler->Init(dst_config, orig_config,
false,
true,
- outChannels.Count() > 0 ? &outChannels : NULL,
+ M_SQRT1_2,
+ outChannels.Count() > 0 ? &outChannels : nullptr,
m_settings.resampleQuality,
false);
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp
index 36698878e5..c7c66009cf 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp
@@ -29,11 +29,8 @@ CSoundPacket::~CSoundPacket()
CActiveAE::FreeSoundSample(data);
}
-CSampleBuffer::CSampleBuffer() : pkt(NULL), pool(NULL)
+CSampleBuffer::CSampleBuffer()
{
- refCount = 0;
- timestamp = 0;
- pkt_start_offset = 0;
}
CSampleBuffer::~CSampleBuffer()
@@ -86,6 +83,7 @@ CSampleBuffer* CActiveAEBufferPool::GetFreeBuffer()
buf = m_freeSamples.front();
m_freeSamples.pop_front();
buf->refCount = 1;
+ buf->centerMixLevel = M_SQRT1_2;
}
return buf;
}
@@ -145,18 +143,7 @@ CActiveAEBufferPoolResample::CActiveAEBufferPoolResample(const AEAudioFormat& in
m_inputFormat.m_channelLayout.Reset();
m_inputFormat.m_channelLayout += AE_CH_FC;
}
- m_resampler = nullptr;
- m_fillPackets = false;
- m_drain = false;
- m_empty = true;
- m_procSample = nullptr;
- m_resampleRatio = 1.0;
m_resampleQuality = quality;
- m_forceResampler = false;
- m_stereoUpmix = false;
- m_normalize = true;
- m_changeResampler = false;
- m_lastSamplePts = 0;
}
CActiveAEBufferPoolResample::~CActiveAEBufferPoolResample()
@@ -182,30 +169,7 @@ bool CActiveAEBufferPoolResample::Create(unsigned int totaltime, bool remap, boo
m_inputFormat.m_dataFormat != m_format.m_dataFormat ||
m_changeResampler)
{
- if (!m_resampler)
- {
- m_resampler = CAEResampleFactory::Create();
- }
-
- m_resampler->Init(CAEUtil::GetAVChannelLayout(m_format.m_channelLayout),
- m_format.m_channelLayout.Count(),
- m_format.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_format.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat),
- CAEUtil::GetAVChannelLayout(m_inputFormat.m_channelLayout),
- m_inputFormat.m_channelLayout.Count(),
- m_inputFormat.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_inputFormat.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_inputFormat.m_dataFormat),
- upmix,
- m_normalize,
- remap ? &m_format.m_channelLayout : NULL,
- m_resampleQuality,
- m_forceResampler);
-
- m_changeResampler = false;
+ ChangeResampler();
}
return true;
}
@@ -219,23 +183,29 @@ void CActiveAEBufferPoolResample::ChangeResampler()
}
m_resampler = CAEResampleFactory::Create();
- m_resampler->Init(CAEUtil::GetAVChannelLayout(m_format.m_channelLayout),
- m_format.m_channelLayout.Count(),
- m_format.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_format.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat),
- CAEUtil::GetAVChannelLayout(m_inputFormat.m_channelLayout),
- m_inputFormat.m_channelLayout.Count(),
- m_inputFormat.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_inputFormat.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_inputFormat.m_dataFormat),
- m_stereoUpmix,
- m_normalize,
- m_remap ? &m_format.m_channelLayout : NULL,
- m_resampleQuality,
- m_forceResampler);
+
+ SampleConfig dstConfig, srcConfig;
+ dstConfig.channel_layout = CAEUtil::GetAVChannelLayout(m_format.m_channelLayout);
+ dstConfig.channels = m_format.m_channelLayout.Count();
+ dstConfig.sample_rate = m_format.m_sampleRate;
+ dstConfig.fmt = CAEUtil::GetAVSampleFormat(m_format.m_dataFormat);
+ dstConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat);
+ dstConfig.dither_bits = CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat);
+
+ srcConfig.channel_layout = CAEUtil::GetAVChannelLayout(m_inputFormat.m_channelLayout);
+ srcConfig.channels = m_inputFormat.m_channelLayout.Count();
+ srcConfig.sample_rate = m_inputFormat.m_sampleRate;
+ srcConfig.fmt = CAEUtil::GetAVSampleFormat(m_inputFormat.m_dataFormat);
+ srcConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_inputFormat.m_dataFormat);
+ srcConfig.dither_bits = CAEUtil::DataFormatToDitherBits(m_inputFormat.m_dataFormat);
+
+ m_resampler->Init(dstConfig, srcConfig,
+ m_stereoUpmix,
+ m_normalize,
+ m_centerMixLevel,
+ m_remap ? &m_format.m_channelLayout : nullptr,
+ m_resampleQuality,
+ m_forceResampler);
m_changeResampler = false;
}
@@ -290,10 +260,17 @@ bool CActiveAEBufferPoolResample::ResampleBuffers(int64_t timestamp)
if (hasInput && !skipInput && !m_changeResampler)
{
in = m_inputSamples.front();
- m_inputSamples.pop_front();
+ if (in->centerMixLevel != m_centerMixLevel &&
+ in->pkt->nb_samples > 0)
+ {
+ m_centerMixLevel = in->centerMixLevel;
+ m_changeResampler = true;
+ }
+ else
+ m_inputSamples.pop_front();
}
else
- in = NULL;
+ in = nullptr;
int start = m_procSample->pkt->nb_samples *
m_procSample->pkt->bytes_per_sample *
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h
index d3acf2209f..20fbac5e45 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h
@@ -10,6 +10,7 @@
#include "cores/AudioEngine/Utils/AEAudioFormat.h"
#include "cores/AudioEngine/Interfaces/AE.h"
+#include <cmath>
#include <deque>
#include <memory>
@@ -21,16 +22,6 @@ extern "C" {
namespace ActiveAE
{
-struct SampleConfig
-{
- AVSampleFormat fmt;
- uint64_t channel_layout;
- int channels;
- int sample_rate;
- int bits_per_sample;
- int dither_bits;
-};
-
/**
* the variables here follow ffmpeg naming
*/
@@ -58,11 +49,12 @@ public:
~CSampleBuffer();
CSampleBuffer *Acquire();
void Return();
- CSoundPacket *pkt;
- CActiveAEBufferPool *pool;
+ CSoundPacket *pkt = nullptr;
+ CActiveAEBufferPool *pool = nullptr;
int64_t timestamp;
- int pkt_start_offset;
- int refCount;
+ int pkt_start_offset = 0;
+ int refCount = 0;
+ double centerMixLevel;
};
class CActiveAEBufferPool
@@ -105,19 +97,20 @@ protected:
void ChangeResampler();
uint8_t *m_planes[16];
- bool m_empty;
- bool m_drain;
- int64_t m_lastSamplePts;
- bool m_remap;
- CSampleBuffer *m_procSample;
- IAEResample *m_resampler;
- double m_resampleRatio;
- bool m_fillPackets;
- bool m_normalize;
- bool m_changeResampler;
- bool m_forceResampler;
+ bool m_empty = true;
+ bool m_drain = false;
+ int64_t m_lastSamplePts = 0;
+ bool m_remap = false;
+ CSampleBuffer *m_procSample = nullptr;
+ IAEResample *m_resampler = nullptr;
+ double m_resampleRatio = 1.0f;
+ double m_centerMixLevel = M_SQRT1_2;
+ bool m_fillPackets = false;
+ bool m_normalize = true;
+ bool m_changeResampler = false;
+ bool m_forceResampler = false;
AEQuality m_resampleQuality;
- bool m_stereoUpmix;
+ bool m_stereoUpmix = false;
};
class CActiveAEFilter;
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
index 3ff977f568..fda623e016 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
@@ -29,20 +29,21 @@ CActiveAEResampleFFMPEG::~CActiveAEResampleFFMPEG()
swr_free(&m_pContext);
}
-bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample)
+bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
+ CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample)
{
- m_dst_chan_layout = dst_chan_layout;
- m_dst_channels = dst_channels;
- m_dst_rate = dst_rate;
- m_dst_fmt = dst_fmt;
- m_dst_bits = dst_bits;
- m_dst_dither_bits = dst_dither;
- m_src_chan_layout = src_chan_layout;
- m_src_channels = src_channels;
- m_src_rate = src_rate;
- m_src_fmt = src_fmt;
- m_src_bits = src_bits;
- m_src_dither_bits = src_dither;
+ m_dst_chan_layout = dstConfig.channel_layout;
+ m_dst_channels = dstConfig.channels;
+ m_dst_rate = dstConfig.sample_rate;
+ m_dst_fmt = dstConfig.fmt;
+ m_dst_bits = dstConfig.bits_per_sample;
+ m_dst_dither_bits = dstConfig.dither_bits;
+ m_src_chan_layout = srcConfig.channel_layout;
+ m_src_channels = srcConfig.channels;
+ m_src_rate = srcConfig.sample_rate;
+ m_src_fmt = srcConfig.fmt;
+ m_src_bits = srcConfig.bits_per_sample;
+ m_src_dither_bits = srcConfig.dither_bits;
if (m_src_rate != m_dst_rate)
m_doesResample = true;
@@ -56,7 +57,7 @@ bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, i
m_src_chan_layout, m_src_fmt, m_src_rate,
0, NULL);
- if(!m_pContext)
+ if (!m_pContext)
{
CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed");
return false;
@@ -93,6 +94,8 @@ bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, i
av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0);
}
+ av_opt_set_double(m_pContext, "center_mix_level", centerMix, 0);
+
if (remapLayout)
{
// one-to-one mapping of channels
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h
index 828fca1d72..aebd2f1917 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.h
@@ -28,7 +28,8 @@ public:
const char *GetName() override { return "ActiveAEResampleFFMPEG"; }
CActiveAEResampleFFMPEG();
~CActiveAEResampleFFMPEG() override;
- bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample) override;
+ bool Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
+ CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample) override;
int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio) override;
int64_t GetDelay(int64_t base) override;
int GetBufferedSamples() override;
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
index 72a4c8bcf6..331fac2129 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
@@ -95,29 +95,31 @@ static int format_to_bits(AVSampleFormat fmt)
return 0;
}
-bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample)
+bool CActiveAEResamplePi::Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
+ CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample)
{
LOGTIMEINIT("x");
CLog::Log(LOGINFO,
"%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d dither:%d->%d "
"norm:%d upmix:%d",
- CLASSNAME, __func__, static_cast<void*>(remapLayout), src_channels, dst_channels,
- src_rate, dst_rate, src_fmt, dst_fmt, src_bits, dst_bits, src_dither, dst_dither,
+ CLASSNAME, __func__, static_cast<void*>(remapLayout), srcConfig.channels, dstConfig.channels,
+ srcConfig.sample_rate, dstConfig.sample_rate, srcConfig.fmt, dstConfig.fmt,
+ srcConfig.bits_per_sample, dstConfig.bits_per_sample, srcConfig.dither_bits, dstConfig.dither_bits,
normalize, upmix);
- m_dst_chan_layout = dst_chan_layout;
- m_dst_channels = dst_channels;
- m_dst_rate = dst_rate;
- m_dst_fmt = dst_fmt;
- m_dst_bits = dst_bits;
- m_dst_dither_bits = dst_dither;
- m_src_chan_layout = src_chan_layout;
- m_src_channels = src_channels;
- m_src_rate = src_rate;
- m_src_fmt = src_fmt;
- m_src_bits = src_bits;
- m_src_dither_bits = src_dither;
+ m_dst_chan_layout = dstConfig.channel_layout;
+ m_dst_channels = dstConfig.channels;
+ m_dst_rate = dstConfig.sample_rate;
+ m_dst_fmt = dstConfig.fmt;
+ m_dst_bits = dstConfig.bits_per_sample;
+ m_dst_dither_bits = dstConfig.dither_bits;
+ m_src_chan_layout = srcConfig.channel_layout;
+ m_src_channels = srcConfig.channels;
+ m_src_rate = srcConfig.sample_rate;
+ m_src_fmt = srcConfig.fmt;
+ m_src_bits = srcConfig.bits_per_sample;
+ m_src_dither_bits = srcConfig.dither_bits;
m_offset = 0;
m_src_pitch = format_to_bits(m_src_fmt) >> 3;
m_dst_pitch = format_to_bits(m_dst_fmt) >> 3;
@@ -284,8 +286,8 @@ bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int d
m_ratio = 1.0;
}
// audio_mixer only supports up to 192kHz, however as long as ratio of samplerates remains the same we can lie
- while (src_rate > 192000 || dst_rate > 192000)
- src_rate >>= 1, dst_rate >>= 1;
+ while (srcConfig.sample_rate > 192000 || dstConfig.sample_rate > 192000)
+ srcConfig.sample_rate >>= 1, dstConfig.sample_rate >>= 1;
OMX_INIT_STRUCTURE(m_pcm_input);
m_pcm_input.nPortIndex = m_omx_mixer.GetInputPort();
@@ -300,8 +302,8 @@ bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int d
if (m_src_fmt >= AV_SAMPLE_FMT_U8P)
flags |= 0x10000;
m_pcm_input.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags;
- m_pcm_input.nChannels = src_channels;
- m_pcm_input.nSamplingRate = src_rate;
+ m_pcm_input.nChannels = srcConfig.channels;
+ m_pcm_input.nSamplingRate = srcConfig.sample_rate;
omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_input);
if (omx_err != OMX_ErrorNone)
@@ -323,8 +325,8 @@ bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int d
flags |= (32 - m_dst_bits - m_dst_dither_bits) << 8;
m_pcm_output.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags;
- m_pcm_output.nChannels = dst_channels;
- m_pcm_output.nSamplingRate = dst_rate;
+ m_pcm_output.nChannels = dstConfig.channels;
+ m_pcm_output.nSamplingRate = dstConfig.sample_rate;
omx_err = m_omx_mixer.SetParameter(OMX_IndexParamAudioPcm, &m_pcm_output);
if (omx_err != OMX_ErrorNone)
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h
index 60d9d7fc98..bd9936c94c 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h
@@ -20,7 +20,8 @@ public:
const char *GetName() { return "ActiveAEResamplePi"; }
CActiveAEResamplePi();
virtual ~CActiveAEResamplePi();
- bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample);
+ bool Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
+ CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample);
int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio);
int64_t GetDelay(int64_t base);
int GetBufferedSamples();
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
index c08a601089..940cc5e74d 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
@@ -1084,19 +1084,25 @@ void CActiveAESink::GenerateNoise()
SampleConfig config = m_sampleOfSilence.pkt->config;
IAEResample *resampler = CAEResampleFactory::Create(AERESAMPLEFACTORY_QUICK_RESAMPLE);
- resampler->Init(config.channel_layout,
- config.channels,
- config.sample_rate,
- config.fmt,
- config.bits_per_sample,
- config.dither_bits,
- config.channel_layout,
- config.channels,
- config.sample_rate,
- AV_SAMPLE_FMT_FLT,
- CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_sinkFormat.m_dataFormat),
- false, false, nullptr, AE_QUALITY_UNKNOWN, false);
+
+ SampleConfig dstConfig, srcConfig;
+ dstConfig.channel_layout = config.channel_layout;
+ dstConfig.channels = config.channels;
+ dstConfig.sample_rate = config.sample_rate;
+ dstConfig.fmt = config.fmt;
+ dstConfig.bits_per_sample = config.bits_per_sample;
+ dstConfig.dither_bits = config.dither_bits;
+
+ srcConfig.channel_layout = config.channel_layout;
+ srcConfig.channels = config.channels;
+ srcConfig.sample_rate = config.sample_rate;
+ srcConfig.fmt = AV_SAMPLE_FMT_FLT;
+ srcConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_sinkFormat.m_dataFormat);
+ srcConfig.dither_bits = CAEUtil::DataFormatToDitherBits(m_sinkFormat.m_dataFormat);
+
+ resampler->Init(dstConfig, srcConfig,
+ false, false, M_SQRT1_2, nullptr, AE_QUALITY_UNKNOWN, false);
+
resampler->Resample(m_sampleOfSilence.pkt->data, m_sampleOfSilence.pkt->max_nb_samples,
(uint8_t**)&noise, m_sampleOfSilence.pkt->max_nb_samples, 1.0);
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
index 4d76e55c50..652f04ca0e 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
@@ -137,20 +137,25 @@ void CActiveAEStream::InitRemapper()
}
// initialize resampler for only doing remapping
- m_remapper->Init(avLayout,
- m_format.m_channelLayout.Count(),
- m_format.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_format.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat),
- avLayout,
- m_format.m_channelLayout.Count(),
- m_format.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_format.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat),
+ SampleConfig dstConfig, srcConfig;
+ dstConfig.channel_layout = avLayout;
+ dstConfig.channels = m_format.m_channelLayout.Count();
+ dstConfig.sample_rate = m_format.m_sampleRate;
+ dstConfig.fmt = CAEUtil::GetAVSampleFormat(m_format.m_dataFormat);
+ dstConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat);
+ dstConfig.dither_bits = CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat);
+
+ srcConfig.channel_layout = avLayout;
+ srcConfig.channels = m_format.m_channelLayout.Count();
+ srcConfig.sample_rate = m_format.m_sampleRate;
+ srcConfig.fmt = CAEUtil::GetAVSampleFormat(m_format.m_dataFormat);
+ srcConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat);
+ srcConfig.dither_bits = CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat);
+
+ m_remapper->Init(dstConfig, srcConfig,
false,
false,
+ M_SQRT1_2,
&remapLayout,
AE_QUALITY_LOW, // not used for remapping
false);
@@ -226,12 +231,18 @@ unsigned int CActiveAEStream::GetSpace()
return m_streamFreeBuffers * m_streamSpace;
}
-unsigned int CActiveAEStream::AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, double pts)
+unsigned int CActiveAEStream::AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, ExtData *extData)
{
Message *msg;
unsigned int copied = 0;
int sourceFrames = frames;
const uint8_t* const *buf = data;
+ double pts = 0;
+
+ if (extData)
+ {
+ pts = extData->pts;
+ }
m_streamIsFlushed = false;
@@ -279,6 +290,9 @@ unsigned int CActiveAEStream::AddData(const uint8_t* const *data, unsigned int o
}
copied += minFrames;
+ if (extData && extData->hasDownmix)
+ m_currentBuffer->centerMixLevel = extData->centerMixLevel;
+
bool rawPktComplete = false;
{
CSingleLock lock(m_statsLock);
@@ -302,7 +316,7 @@ unsigned int CActiveAEStream::AddData(const uint8_t* const *data, unsigned int o
msgData.stream = this;
RemapBuffer();
m_streamPort->SendOutMessage(CActiveAEDataProtocol::STREAMSAMPLE, &msgData, sizeof(MsgStreamSample));
- m_currentBuffer = NULL;
+ m_currentBuffer = nullptr;
}
continue;
}
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h
index f5ae61525b..1c9db008c8 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h
@@ -140,7 +140,7 @@ protected:
public:
unsigned int GetSpace() override;
- unsigned int AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, double pts = 0.0) override;
+ unsigned int AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, ExtData *extData) override;
double GetDelay() override;
CAESyncInfo GetSyncInfo() override;
bool IsBuffering() override;
diff --git a/xbmc/cores/AudioEngine/Interfaces/AE.h b/xbmc/cores/AudioEngine/Interfaces/AE.h
index e4620aa439..0c4a015a5f 100644
--- a/xbmc/cores/AudioEngine/Interfaces/AE.h
+++ b/xbmc/cores/AudioEngine/Interfaces/AE.h
@@ -15,6 +15,10 @@
#include "cores/AudioEngine/Utils/AEAudioFormat.h"
+extern "C" {
+#include "libavutil/samplefmt.h"
+}
+
typedef std::pair<std::string, std::string> AEDevice;
typedef std::vector<AEDevice> AEDeviceList;
@@ -52,6 +56,16 @@ enum AEQuality
AE_QUALITY_GPU = 101, /* GPU acceleration */
};
+struct SampleConfig
+{
+ AVSampleFormat fmt;
+ uint64_t channel_layout;
+ int channels;
+ int sample_rate;
+ int bits_per_sample;
+ int dither_bits;
+};
+
/**
* IAE Interface
*/
diff --git a/xbmc/cores/AudioEngine/Interfaces/AEResample.h b/xbmc/cores/AudioEngine/Interfaces/AEResample.h
index 087230ceba..8b27b32b86 100644
--- a/xbmc/cores/AudioEngine/Interfaces/AEResample.h
+++ b/xbmc/cores/AudioEngine/Interfaces/AEResample.h
@@ -10,21 +10,18 @@
#include "cores/AudioEngine/Interfaces/AE.h"
-extern "C" {
-#include "libavutil/samplefmt.h"
-}
-
namespace ActiveAE
{
class IAEResample
{
public:
- /* return the name of this sync for logging */
+ // return the name of this sync for logging
virtual const char *GetName() = 0;
IAEResample() = default;
virtual ~IAEResample() = default;
- virtual bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample) = 0;
+ virtual bool Init(SampleConfig dstConfig, SampleConfig srcConfig, bool upmix, bool normalize, double centerMix,
+ CAEChannelInfo *remapLayout, AEQuality quality, bool force_resample) = 0;
virtual int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio) = 0;
virtual int64_t GetDelay(int64_t base) = 0;
virtual int GetBufferedSamples() = 0;
diff --git a/xbmc/cores/AudioEngine/Interfaces/AEStream.h b/xbmc/cores/AudioEngine/Interfaces/AEStream.h
index 4055aca13b..e6e2e261e7 100644
--- a/xbmc/cores/AudioEngine/Interfaces/AEStream.h
+++ b/xbmc/cores/AudioEngine/Interfaces/AEStream.h
@@ -57,6 +57,14 @@ protected:
virtual ~IAEStream() = default;
public:
+ struct ExtData
+ {
+ double pts = 0;
+ bool hasDownmix = false;
+ double centerMixLevel = 1;
+ };
+
+public:
/**
* Returns the amount of space available in the stream
* @return The number of bytes AddData will consume
@@ -71,7 +79,7 @@ public:
* @param pts timestamp
* @return The number of frames consumed
*/
- virtual unsigned int AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, double pts = 0.0) = 0;
+ virtual unsigned int AddData(const uint8_t* const *data, unsigned int offset, unsigned int frames, ExtData *extData) = 0;
/**
* Returns the time in seconds that it will take
diff --git a/xbmc/cores/RetroPlayer/buffers/BaseRenderBufferPool.cpp b/xbmc/cores/RetroPlayer/buffers/BaseRenderBufferPool.cpp
index 0300986a09..a2fcc2d7dc 100644
--- a/xbmc/cores/RetroPlayer/buffers/BaseRenderBufferPool.cpp
+++ b/xbmc/cores/RetroPlayer/buffers/BaseRenderBufferPool.cpp
@@ -72,7 +72,7 @@ IRenderBuffer *CBaseRenderBufferPool::GetBuffer(unsigned int width, unsigned int
for (auto it = m_free.begin(); it != m_free.end(); ++it)
{
- std::unique_ptr<IRenderBuffer> &buffer = m_free.front();
+ std::unique_ptr<IRenderBuffer> &buffer = *it;
// Only return buffers of the same dimensions
const unsigned int bufferWidth = buffer->GetWidth();
diff --git a/xbmc/cores/RetroPlayer/streams/RetroPlayerAudio.cpp b/xbmc/cores/RetroPlayer/streams/RetroPlayerAudio.cpp
index ce65f713e9..6e280f1597 100644
--- a/xbmc/cores/RetroPlayer/streams/RetroPlayerAudio.cpp
+++ b/xbmc/cores/RetroPlayer/streams/RetroPlayerAudio.cpp
@@ -124,7 +124,7 @@ void CRetroPlayerAudio::AddStreamData(const StreamPacket &packet)
CLog::Log(LOGDEBUG, "RetroPlayer[AUDIO]: Audio delay (%0.2f ms) is too high - flushing", delaySecs * 1000);
}
- m_pAudioStream->AddData(&audioPacket.data, 0, frameCount);
+ m_pAudioStream->AddData(&audioPacket.data, 0, frameCount, nullptr);
}
}
}
diff --git a/xbmc/cores/VideoPlayer/AudioSinkAE.cpp b/xbmc/cores/VideoPlayer/AudioSinkAE.cpp
index 8646ee7473..acd7f6566e 100644
--- a/xbmc/cores/VideoPlayer/AudioSinkAE.cpp
+++ b/xbmc/cores/VideoPlayer/AudioSinkAE.cpp
@@ -124,8 +124,17 @@ unsigned int CAudioSinkAE::AddPackets(const DVDAudioFrame &audioframe)
unsigned int offset = audioframe.framesOut;
do
{
- double pts = (offset == 0) ? audioframe.pts / DVD_TIME_BASE * 1000 : 0.0;
- unsigned int copied = m_pAudioStream->AddData(audioframe.data, offset, frames, pts);
+ IAEStream::ExtData ext;
+ if (offset == 0)
+ {
+ ext.pts = audioframe.pts / DVD_TIME_BASE * 1000;
+ }
+ if (audioframe.hasDownmix)
+ {
+ ext.hasDownmix = true;
+ ext.centerMixLevel = audioframe.centerMixLevel;
+ }
+ unsigned int copied = m_pAudioStream->AddData(audioframe.data, offset, frames, &ext);
offset += copied;
frames -= copied;
if (frames <= 0)
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodec.h
index 8462902769..3bf5e57e61 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodec.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodec.h
@@ -44,6 +44,8 @@ typedef struct stDVDAudioFrame
enum AVAudioServiceType audio_service_type;
enum AVMatrixEncoding matrix_encoding;
int profile;
+ bool hasDownmix;
+ double centerMixLevel;
} DVDAudioFrame;
class CDVDAudioCodec
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
index 12e19a83ef..d47cd43da0 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp
@@ -7,23 +7,16 @@
*/
#include "DVDAudioCodecFFmpeg.h"
-#ifdef TARGET_POSIX
-#include "XMemUtils.h"
-#include "platform/linux/XTimeUtils.h"
-#endif
#include "../../DVDStreamInfo.h"
#include "utils/log.h"
#include "settings/AdvancedSettings.h"
+#include "settings/Settings.h"
#include "DVDCodecs/DVDCodecs.h"
+
extern "C" {
#include "libavutil/opt.h"
}
-#include "settings/Settings.h"
-#if defined(TARGET_DARWIN)
-#include "cores/AudioEngine/Utils/AEUtil.h"
-#endif
-
CDVDAudioCodecFFmpeg::CDVDAudioCodecFFmpeg(CProcessInfo &processInfo) : CDVDAudioCodec(processInfo)
{
m_pCodecContext = NULL;
@@ -120,6 +113,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
m_iSampleFormat = AV_SAMPLE_FMT_NONE;
m_matrixEncoding = AV_MATRIX_ENCODING_NONE;
+ m_hasDownmix = false;
m_codecName = "ff-" + std::string(m_pCodecContext->codec->name);
@@ -205,6 +199,12 @@ void CDVDAudioCodecFFmpeg::GetData(DVDAudioFrame &frame)
frame.pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE;
else
frame.pts = DVD_NOPTS_VALUE;
+
+ frame.hasDownmix = m_hasDownmix;
+ if (frame.hasDownmix)
+ {
+ frame.centerMixLevel = m_downmixInfo.center_mix_level;
+ }
}
int CDVDAudioCodecFFmpeg::GetData(uint8_t** dst)
@@ -223,6 +223,11 @@ int CDVDAudioCodecFFmpeg::GetData(uint8_t** dst)
{
m_matrixEncoding = *(enum AVMatrixEncoding*)sd->data;
}
+ else if (sd->type == AV_FRAME_DATA_DOWNMIX_INFO)
+ {
+ m_downmixInfo = *(AVDownmixInfo*)sd->data;
+ m_hasDownmix = true;
+ }
}
}
}
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h
index b2b71a0774..c49257fcbe 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.h
@@ -16,6 +16,7 @@ extern "C" {
#include "libavutil/avutil.h"
#include "libavutil/channel_layout.h"
#include "libswresample/swresample.h"
+#include "libavutil/downmix_info.h"
}
class CProcessInfo;
@@ -52,6 +53,8 @@ protected:
CAEChannelInfo m_channelLayout;
enum AVMatrixEncoding m_matrixEncoding = AV_MATRIX_ENCODING_NONE;
AVFrame* m_pFrame;
+ AVDownmixInfo m_downmixInfo;
+ bool m_hasDownmix = false;
bool m_eof;
int m_channels;
uint64_t m_layout;
diff --git a/xbmc/cores/paplayer/PAPlayer.cpp b/xbmc/cores/paplayer/PAPlayer.cpp
index 47ed9c0e3f..ce854df183 100644
--- a/xbmc/cores/paplayer/PAPlayer.cpp
+++ b/xbmc/cores/paplayer/PAPlayer.cpp
@@ -849,7 +849,7 @@ bool PAPlayer::QueueData(StreamInfo *si)
}
unsigned int frames = samples/si->m_audioFormat.m_channelLayout.Count();
- unsigned int added = si->m_stream->AddData(&data, 0, frames, 0);
+ unsigned int added = si->m_stream->AddData(&data, 0, frames, nullptr);
si->m_framesSent += added;
}
else
@@ -861,7 +861,7 @@ bool PAPlayer::QueueData(StreamInfo *si)
uint8_t *data = si->m_decoder.GetRawData(size);
if (data && size)
{
- int added = si->m_stream->AddData(&data, 0, size, 0);
+ int added = si->m_stream->AddData(&data, 0, size, nullptr);
if (added != size)
{
CLog::Log(LOGERROR, "PAPlayer::QueueData - unknown error");
diff --git a/xbmc/cores/paplayer/VideoPlayerCodec.cpp b/xbmc/cores/paplayer/VideoPlayerCodec.cpp
index e48011fc6e..4edadf0454 100644
--- a/xbmc/cores/paplayer/VideoPlayerCodec.cpp
+++ b/xbmc/cores/paplayer/VideoPlayerCodec.cpp
@@ -249,20 +249,26 @@ bool VideoPlayerCodec::Init(const CFileItem &file, unsigned int filecache)
{
m_needConvert = true;
m_pResampler = ActiveAE::CAEResampleFactory::Create();
- m_pResampler->Init(CAEUtil::GetAVChannelLayout(m_srcFormat.m_channelLayout),
- m_channels,
- m_srcFormat.m_sampleRate,
- CAEUtil::GetAVSampleFormat(AE_FMT_FLOAT),
- CAEUtil::DataFormatToUsedBits(AE_FMT_FLOAT),
- CAEUtil::DataFormatToDitherBits(AE_FMT_FLOAT),
- CAEUtil::GetAVChannelLayout(m_srcFormat.m_channelLayout),
- m_channels,
- m_srcFormat.m_sampleRate,
- CAEUtil::GetAVSampleFormat(m_srcFormat.m_dataFormat),
- CAEUtil::DataFormatToUsedBits(m_srcFormat.m_dataFormat),
- CAEUtil::DataFormatToDitherBits(m_srcFormat.m_dataFormat),
+
+ SampleConfig dstConfig, srcConfig;
+ dstConfig.channel_layout = CAEUtil::GetAVChannelLayout(m_srcFormat.m_channelLayout);
+ dstConfig.channels = m_channels;
+ dstConfig.sample_rate = m_srcFormat.m_sampleRate;
+ dstConfig.fmt = CAEUtil::GetAVSampleFormat(AE_FMT_FLOAT);
+ dstConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(AE_FMT_FLOAT);
+ dstConfig.dither_bits = CAEUtil::DataFormatToDitherBits(AE_FMT_FLOAT);
+
+ srcConfig.channel_layout = CAEUtil::GetAVChannelLayout(m_srcFormat.m_channelLayout);
+ srcConfig.channels = m_channels;
+ srcConfig.sample_rate = m_srcFormat.m_sampleRate;
+ srcConfig.fmt = CAEUtil::GetAVSampleFormat(m_srcFormat.m_dataFormat);
+ srcConfig.bits_per_sample = CAEUtil::DataFormatToUsedBits(m_srcFormat.m_dataFormat);
+ srcConfig.dither_bits = CAEUtil::DataFormatToDitherBits(m_srcFormat.m_dataFormat);
+
+ m_pResampler->Init(dstConfig, srcConfig,
false,
false,
+ M_SQRT1_2,
NULL,
AE_QUALITY_UNKNOWN,
false);