Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoundSourceM4A: Reconfigure decoder after channel config errors #2850

Merged
merged 20 commits into from
Jun 13, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,14 @@ endif()
# FAAD AAC audio file decoder plugin
find_package(MP4)
find_package(MP4v2)
option(FAAD "FAAD AAC audio file decoder support" OFF)
# It is enabled by default on Linux only, because other targets have other solutions.
# Used FAAD_DEFAULT because the complex expression is not supported by cmake_dependent_option()
if(UNIX AND NOT APPLE AND (MP4_FOUND OR MP4v2_FOUND))
set(FAAD_DEFAULT TRUE)
else()
set(FAAD_DEFAULT FALSE)
endif()
cmake_dependent_option(FAAD "FAAD AAC audio file decoder support" ON "FAAD_DEFAULT" OFF)
if(FAAD)
if(NOT MP4_FOUND AND NOT MP4v2_FOUND)
message(FATAL_ERROR "FAAD AAC audio support requires libmp4 or libmp4v2 with development headers.")
Expand Down
13 changes: 6 additions & 7 deletions src/sources/audiosource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ bool AudioSource::initFrameIndexRangeOnce(
<< frameIndexRange;
return false; // abort
}
VERIFY_OR_DEBUG_ASSERT(m_frameIndexRange.empty() || (m_frameIndexRange == frameIndexRange)) {
if (!m_frameIndexRange.empty() &&
m_frameIndexRange != frameIndexRange) {
kLogger.warning()
<< "Frame index range has already been initialized to"
<< m_frameIndexRange
Expand All @@ -80,9 +81,8 @@ bool AudioSource::initChannelCountOnce(
<< channelCount;
return false; // abort
}
VERIFY_OR_DEBUG_ASSERT(
!m_signalInfo.getChannelCount().isValid() ||
m_signalInfo.getChannelCount() == channelCount) {
if (m_signalInfo.getChannelCount().isValid() &&
m_signalInfo.getChannelCount() != channelCount) {
kLogger.warning()
<< "Channel count has already been initialized to"
<< m_signalInfo.getChannelCount()
Expand All @@ -102,9 +102,8 @@ bool AudioSource::initSampleRateOnce(
<< sampleRate;
return false; // abort
}
VERIFY_OR_DEBUG_ASSERT(
!m_signalInfo.getSampleRate().isValid() ||
m_signalInfo.getSampleRate() == sampleRate) {
if (m_signalInfo.getSampleRate().isValid() &&
m_signalInfo.getSampleRate() != sampleRate) {
kLogger.warning()
<< "Sample rate has already been initialized to"
<< m_signalInfo.getSampleRate()
Expand Down
146 changes: 108 additions & 38 deletions src/sources/libfaadloader.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
#include "sources/libfaadloader.h"

#include "util/logger.h"

namespace {

mixxx::Logger kLogger("LibFaadLoader");
mixxx::Logger kLogger("faad2::LibLoader");

} // anonymous namespace

namespace faad2 {

// static
LibFaadLoader* LibFaadLoader::Instance() {
static LibFaadLoader libFaadLoader;
LibLoader* LibLoader::Instance() {
static LibLoader libFaadLoader;
return &libFaadLoader;
}

LibFaadLoader::LibFaadLoader()
LibLoader::LibLoader()
: m_neAACDecOpen(nullptr),
m_neAACDecGetCurrentConfiguration(nullptr),
m_neAACDecSetConfiguration(nullptr),
m_neAACDecInit(nullptr),
m_neAACDecInit2(nullptr),
m_neAACDecClose(nullptr),
m_neAACDecPostSeekReset(nullptr),
m_neAACDecDecode2(nullptr),
m_neAACDecGetErrorMessage(nullptr) {
m_neAACDecGetErrorMessage(nullptr),
m_neAACDecGetVersion(nullptr) {
// Load shared library
QStringList libnames;
#ifdef __WINDOWS__
Expand Down Expand Up @@ -58,6 +63,8 @@ LibFaadLoader::LibFaadLoader()
m_pLibrary->resolve("NeAACDecGetCurrentConfiguration"));
m_neAACDecSetConfiguration = reinterpret_cast<NeAACDecSetConfiguration_t>(
m_pLibrary->resolve("NeAACDecSetConfiguration"));
m_neAACDecInit = reinterpret_cast<NeAACDecInit_t>(
m_pLibrary->resolve("NeAACDecInit"));
m_neAACDecInit2 = reinterpret_cast<NeAACDecInit2_t>(
m_pLibrary->resolve("NeAACDecInit2"));
m_neAACDecClose = reinterpret_cast<NeAACDecClose_t>(
Expand All @@ -68,62 +75,75 @@ LibFaadLoader::LibFaadLoader()
m_pLibrary->resolve("NeAACDecDecode2"));
m_neAACDecGetErrorMessage = reinterpret_cast<NeAACDecGetErrorMessage_t>(
m_pLibrary->resolve("NeAACDecGetErrorMessage"));
m_neAACDecGetVersion = reinterpret_cast<NeAACDecGetVersion_t>(
m_pLibrary->resolve("NeAACDecGetVersion"));

if (!m_neAACDecOpen ||
!m_neAACDecGetCurrentConfiguration ||
!m_neAACDecSetConfiguration ||
!m_neAACDecInit ||
!m_neAACDecInit2 ||
!m_neAACDecClose ||
!m_neAACDecPostSeekReset ||
!m_neAACDecDecode2 ||
!m_neAACDecGetErrorMessage) {
kLogger.debug() << "NeAACDecOpen:" << m_neAACDecOpen;
kLogger.debug() << "NeAACDecGetCurrentConfiguration:" << m_neAACDecGetCurrentConfiguration;
kLogger.debug() << "NeAACDecSetConfiguration:" << m_neAACDecSetConfiguration;
kLogger.debug() << "NeAACDecInit2:" << m_neAACDecInit2;
kLogger.debug() << "NeAACDecClose:" << m_neAACDecClose;
kLogger.debug() << "NeAACDecPostSeekReset:" << m_neAACDecPostSeekReset;
kLogger.debug() << "NeAACDecDecode2:" << m_neAACDecDecode2;
kLogger.debug() << "NeAACDecGetErrorMessage:" << m_neAACDecGetErrorMessage;
kLogger.warning() << "NeAACDecOpen:" << m_neAACDecOpen;
kLogger.warning() << "NeAACDecGetCurrentConfiguration:" << m_neAACDecGetCurrentConfiguration;
kLogger.warning() << "NeAACDecSetConfiguration:" << m_neAACDecSetConfiguration;
kLogger.warning() << "NeAACDecInit:" << m_neAACDecInit;
kLogger.warning() << "NeAACDecInit2:" << m_neAACDecInit2;
kLogger.warning() << "NeAACDecClose:" << m_neAACDecClose;
kLogger.warning() << "NeAACDecPostSeekReset:" << m_neAACDecPostSeekReset;
kLogger.warning() << "NeAACDecDecode2:" << m_neAACDecDecode2;
kLogger.warning() << "NeAACDecGetErrorMessage:" << m_neAACDecGetErrorMessage;
kLogger.warning() << "NeAACDecGetVersion:" << m_neAACDecGetVersion; // From FAAD 2.8.2
m_neAACDecOpen = nullptr;
m_neAACDecGetCurrentConfiguration = nullptr;
m_neAACDecSetConfiguration = nullptr;
m_neAACDecInit = nullptr;
m_neAACDecInit2 = nullptr;
m_neAACDecClose = nullptr;
m_neAACDecPostSeekReset = nullptr;
m_neAACDecDecode2 = nullptr;
m_neAACDecGetErrorMessage = nullptr;
m_neAACDecGetVersion = nullptr;
m_pLibrary->unload();
m_pLibrary.reset();
return;
}
kLogger.info() << "Successfully loaded library" << m_pLibrary->fileName();
char* faad_id_string = nullptr;
char const* version =
GetVersion(&faad_id_string, nullptr) == 0 ? faad_id_string : "<unknown>";
kLogger.info()
<< "Successfully loaded FAAD2 library"
<< m_pLibrary->fileName()
<< "version"
<< version;
};

bool LibFaadLoader::isLoaded() {
if (m_pLibrary) {
return m_pLibrary->isLoaded();
}
return false;
bool LibLoader::isLoaded() const {
return m_pLibrary && m_pLibrary->isLoaded();
}

LibFaadLoader::Handle LibFaadLoader::Open() {
DecoderHandle LibLoader::Open() const {
if (m_neAACDecOpen) {
return m_neAACDecOpen();
}
return nullptr;
}

LibFaadLoader::Configuration*
LibFaadLoader::GetCurrentConfiguration(Handle hDecoder) {
Configuration*
LibLoader::GetCurrentConfiguration(
DecoderHandle hDecoder) const {
if (m_neAACDecGetCurrentConfiguration) {
return m_neAACDecGetCurrentConfiguration(hDecoder);
}
return nullptr;
}

unsigned char LibFaadLoader::SetConfiguration(
Handle hDecoder, Configuration* pConfig) {
unsigned char LibLoader::SetConfiguration(
DecoderHandle hDecoder,
Configuration* pConfig) const {
if (m_neAACDecSetConfiguration) {
return m_neAACDecSetConfiguration(hDecoder, pConfig);
}
Expand All @@ -133,18 +153,36 @@ unsigned char LibFaadLoader::SetConfiguration(
return 0;
}

// Init the library using a DecoderSpecificInfo
char LibFaadLoader::Init2(
Handle hDecoder,
long LibLoader::Init(
DecoderHandle hDecoder,
unsigned char* pBuffer,
unsigned long SizeOfDecoderSpecificInfo,
unsigned long* pSamplerate,
unsigned char* pChannels) {
unsigned long sizeofBuffer,
unsigned long* pSampleRate,
unsigned char* pChannels) const {
if (m_neAACDecInit) {
return m_neAACDecInit(hDecoder,
pBuffer,
sizeofBuffer,
pSampleRate,
pChannels);
}
// Return values:
// < 0 – Error
// 0 - OK
return -1;
}

char LibLoader::Init2(
DecoderHandle hDecoder,
unsigned char* pBuffer,
unsigned long sizeofBuffer,
unsigned long* pSampleRate,
unsigned char* pChannels) const {
if (m_neAACDecInit2) {
return m_neAACDecInit2(hDecoder,
pBuffer,
SizeOfDecoderSpecificInfo,
pSamplerate,
sizeofBuffer,
pSampleRate,
pChannels);
}
// Return values:
Expand All @@ -153,25 +191,28 @@ char LibFaadLoader::Init2(
return -1;
}

void LibFaadLoader::Close(Handle hDecoder) {
void LibLoader::Close(
DecoderHandle hDecoder) const {
if (m_neAACDecClose) {
m_neAACDecClose(hDecoder);
}
}

void LibFaadLoader::PostSeekReset(Handle hDecoder, long frame) {
void LibLoader::PostSeekReset(
DecoderHandle hDecoder,
long frame) const {
if (m_neAACDecPostSeekReset) {
m_neAACDecPostSeekReset(hDecoder, frame);
}
}

void* LibFaadLoader::Decode2(
Handle hDecoder,
void* LibLoader::Decode2(
DecoderHandle hDecoder,
FrameInfo* pInfo,
unsigned char* pBuffer,
unsigned long bufferSize,
void** ppSampleBuffer,
unsigned long sampleBufferSize) {
unsigned long sampleBufferSize) const {
if (m_neAACDecDecode2) {
return m_neAACDecDecode2(
hDecoder,
Expand All @@ -184,9 +225,38 @@ void* LibFaadLoader::Decode2(
return nullptr;
}

char* LibFaadLoader::GetErrorMessage(unsigned char errcode) {
char* LibLoader::GetErrorMessage(
unsigned char errcode) const {
if (m_neAACDecGetErrorMessage) {
return m_neAACDecGetErrorMessage(errcode);
}
return nullptr;
}

int LibLoader::GetVersion(
char** faad_id_string,
char** faad_copyright_string) const {
if (m_neAACDecGetVersion) {
return m_neAACDecGetVersion(faad_id_string, faad_copyright_string);
}
// Return values:
// < 0 – Error
// 0 - OK
return -1;
}

} // namespace faad2

QDebug operator<<(
QDebug dbg,
const faad2::Configuration& cfg) {
return dbg
<< "FAAD2 Configuration{"
<< "defObjectType:" << static_cast<int>(cfg.defObjectType)
<< "defSampleRate:" << cfg.defSampleRate
<< "outputFormat:" << static_cast<int>(cfg.outputFormat)
<< "downMatrix:" << static_cast<int>(cfg.downMatrix)
<< "useOldADTSFormat:" << static_cast<int>(cfg.useOldADTSFormat)
<< "dontUpSampleImplicitSBR:" << static_cast<int>(cfg.dontUpSampleImplicitSBR)
<< '}';
}
Loading