-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
[WIP] AAC/HE-AAC encoder (powered by libfdk-aac) #1387
Conversation
Do you plan this to be ready before our beta deadline? This is a great often requested feature. Since it requires the patched libshout version, we could make it conditional. |
On Windows, it cannot be built, because of libshout. I see that under the lib subfolder, you included a tar for version 2.3.1 that includes a patch to add aac support. We will need to apply that patch into the windows libs so that it can be built previous to merging this (else windows builds will become broken). [CXX] src\engine\sidechain\shoutconnection.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for bringing this back to live.
I have left some comments and ideas for improvements.
It would be great if we can finish this by the end of this month to include it in the 2.3 beta.
If not, never mind, than we can shift it to 2.4
m_pAacDataBuffer(nullptr), | ||
m_aacInfo() { | ||
|
||
if (pFormat == ENCODING_AAC) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can become a switch case
const mixxx::Logger kLogger("EncoderFdkAac"); | ||
} | ||
|
||
EncoderFdkAac::EncoderFdkAac(EncoderCallback* pCallback, QString pFormat) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pFormat: we use the p prefix for pointers.
In this case you can use a constant reference:
const QString format
build/depends.py
Outdated
@@ -682,6 +682,11 @@ def configure(self, build, conf): | |||
if not conf.CheckLib(['libmp3lame', 'libmp3lame-static']): | |||
raise Exception("Could not find libmp3lame.") | |||
|
|||
class FdkAac(Dependence): | |||
def configure(self, build, conf): | |||
if not conf.CheckLib(['libfdk-aac']): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This must be removed. It would be required without our dynamic loading code.
#endif | ||
|
||
for (const auto& libname : libnames) { | ||
m_library = new QLibrary(libname, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can become a unique_ptr and new can be replaced my std::make_unique
kLogger.debug() << "Successfully loaded encoder library " << libname; | ||
break; | ||
} else { | ||
kLogger.warning() << "Failed to load " << libname << ", " << m_library->errorString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is IMHO not a warning because we may find a library later. Can we give the warning after the loop, listing the all probed locations?
} | ||
|
||
void EncoderFdkAac::flush() { | ||
// At this point there may still be samples in the FIFO buffer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also drop a word why.
QString buttWindowsFdkAac(); | ||
|
||
// libfdk-aac common AOTs | ||
static const int AOT_AAC_LC = 2; // AAC-LC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add a comment where these values come from.
We normally initialize all variables in the C++ file.
.travis.yml
Outdated
before_install: | ||
# Virtual X, needed for analyzer waveform tests | ||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=:99.0 ; fi | ||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh -e /etc/init.d/xvfb start ; fi | ||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install scons portaudio libsndfile libogg libvorbis portmidi taglib libshout protobuf flac ffmpeg qt chromaprint rubberband libmodplug libid3tag libmad mp4v2 faad2 wavpack opusfile lilv lame sound-touch; fi | ||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install scons portaudio libsndfile libogg libvorbis portmidi taglib libshout protobuf flac ffmpeg qt chromaprint rubberband libmodplug libid3tag libmad mp4v2 faad2 wavpack opusfile lilv lame sound-touch fdk-aac; fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need this, because we dynamic load the library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have tests that exercise AAC encoding? won't those fail w/o the library being installed?
appveyor.yml
Outdated
@@ -50,7 +50,7 @@ for: | |||
|
|||
install: | |||
- sudo apt-get update | |||
- sudo apt-get -y install gdb libavformat-dev libchromaprint-dev libfaad-dev libflac-dev libid3tag0-dev libmad0-dev libmodplug-dev libmp3lame-dev libmp4v2-dev libopus-dev libopusfile-dev libportmidi-dev libprotobuf-dev libqt5opengl5-dev libqt5sql5-sqlite libqt5svg5-dev librubberband-dev libshout3-dev libsndfile1-dev libsqlite3-dev libtag1-dev libupower-glib-dev libusb-1.0-0-dev libwavpack-dev portaudio19-dev protobuf-compiler qt5-default qtscript5-dev libqt5x11extras5-dev scons qtkeychain-dev liblilv-dev libsoundtouch-dev | |||
- sudo apt-get -y install gdb libavformat-dev libchromaprint-dev libfaad-dev libflac-dev libid3tag0-dev libmad0-dev libmodplug-dev libmp3lame-dev libmp4v2-dev libopus-dev libopusfile-dev libportmidi-dev libprotobuf-dev libqt5opengl5-dev libqt5sql5-sqlite libqt5svg5-dev librubberband-dev libshout3-dev libsndfile1-dev libsqlite3-dev libtag1-dev libupower-glib-dev libusb-1.0-0-dev libwavpack-dev portaudio19-dev protobuf-compiler qt5-default qtscript5-dev libqt5x11extras5-dev scons qtkeychain-dev liblilv-dev libsoundtouch-dev libfdk-aac-dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need this, because we dynamic load the library.
build/depends.py
Outdated
@@ -1507,7 +1514,7 @@ def depends(self, build): | |||
FidLib, SndFile, FLAC, OggVorbis, OpenGL, TagLib, ProtoBuf, | |||
Chromaprint, RubberBand, SecurityFramework, CoreServices, IOKit, | |||
QtScriptByteArray, Reverb, FpClassify, PortAudioRingBuffer, LAME, | |||
QueenMaryDsp] | |||
QueenMaryDsp, FdkAac] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be removed.
This will make a big difference for our radio DJs :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for working on this!
QString fileExtIn = QString::null) : | ||
label(labelIn), internalName(nameIn), lossless(losslessIn), | ||
fileExtension(fileExtIn){ | ||
if(fileExtension == QString::null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use .isEmpty()
instead of == QString::null
Format(QString labelIn, QString nameIn, bool losslessIn) : | ||
label(labelIn), internalName(nameIn), lossless(losslessIn) {} | ||
Format(QString labelIn, QString nameIn, bool losslessIn, | ||
QString fileExtIn = QString::null) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be simpler to use QString()
instead of QString::null
m_pInputFifo(nullptr), | ||
m_pFifoChunkBuffer(nullptr), | ||
m_readRequired(0), | ||
m_aacEnc(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it will be initialized unless it's explicitly in this list, will it?
https://godbolt.org/z/2VaJx5
vs.
https://godbolt.org/z/Dn8zTE
#elif __WINDOWS__ | ||
// Give top priority to libfdk-aac copied | ||
// into Mixxx's installation folder | ||
libnames << "libfdk-aac-1.dll"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that filename a commonly distributed Windows DLL? Why the -1
?
// Last resort choices: try versions with unusual names | ||
libnames << "libfdk-aac.dll"; | ||
libnames << "libfdkaac.dll"; | ||
#elif __APPLE__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add libfdk-aac
here too so that if it's present in the search paths it will work.
|
||
// Actual encoder init, validates settings provided above | ||
int result = aacEncEncode(m_aacEnc, nullptr, nullptr, nullptr, nullptr); | ||
if (result != AACENC_OK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any API we can call that gives a human readable error message ?
return -1; | ||
} | ||
|
||
// This initializes the encoder handle but not the encoder itself. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need error checking for any of the function calls below? Or is the aacEncEncode
the only way we can know if these methods failed?
Thanks! I can address the aforementioned issues on short notice, but the main blocking point is aac support in libshout. Or maybe libshout has a "transparent" mode where it just passes through whatever's given to it. |
Just a quick note. The aac support on libshout is intentionally not part of
the library.
They don't accept the patch into the source because they don't want to
support non-free codecs. Support for mp3 came originally from its
popularity.
Finally, no, there is no "pass through" mode so that Mixxx could itself add
the missing blocks.
So i believe that in this case we need to use our own libshout if aac
encoding is enabled. (As in another setting in scons like faad)
El dl., 21 gen. 2019 , 11:25, Stéphane Lepin <[email protected]> va
escriure:
… Thanks! I can address the aforementioned issues on short notice, but the
main blocking point is aac support in libshout. Or maybe libshout has a
"transparent" mode where it just passes through whatever's given to it.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1387 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AJdFf1mJOtfdLuzEp4y4C98DloKbnFp4ks5vFZWogaJpZM4QlZgc>
.
|
Here is the link to our discussion we had 6 Years ago. https://icecast-dev.xiph.narkive.com/yIVmJeBE/streaming-aac-with-libshout For me it would be fine to merge this without a supporting libshout. Instead we can link the AAC patch in the wiki. |
"Link the patch in the wiki"? I'm not sure I quite understand that. Do you mean: "we don't support it, but hey... this is open source and you can modify it with this patch" ? |
Yes that makes sense. We just need a PR. The patch is here xiph/Icecast-libshout#8 |
@daschuer I won't have enough time to finish this by the end of this month. Would be best to postpone it to 2.4. |
Ok, nevermind. |
I have just found libshout-idjc-2.3.1 it looks like they have renamed mp3.c to mpeg.c and added AAC capability. At least I can select AAC encoding in idjc. Can we use this libary in Mixxx? |
It seems so, for Linux at leasr. I need to check how it can be used on Windows and macOS |
On Windows and MacOs we ship our own libraries so we can use it there as well. |
Thank you for you recent changes. I wonder how building will work on the various Linux distros. Do w need to maintain the non idjc version? If yes, we need to make it conditional in scons. In a way that it fails by default if the idjc package is required but not available or so. I am currently working on a solution for Mixxx 2.2.3 of https://bugs.launchpad.net/bugs/1833225 Maybe we can ship for 2.3.0 the idjc version in the source tree? |
@daschuer Thanks!
What do you mean by that?
Will do!
By 2.4.2 and 2.4.3, you mean versions of libshout or libshout-idjc? Regarding shipping libshout-idjc in the source tree, is it something that's been done or is being done for another dependency? |
Here is a version without conflicts and libshout-idcj: https://github.com/Palakis/mixxx/pull/5 |
This PR is marked as stale because it has been open 90 days with no activity. |
Superseded by #3615 |
Thank you for starting this @Palakis. Sorry it has taken so long to get it merged and released. We have spent the past few months investing a ton of effort to make our build infrastructure more maintainable so adding new dependencies is no longer a big deal. Since you have started this there is now a fork of fdk-aac without HE-AAC support to avoid patent issues that Fedora and Arch Linux package. We are now using it in our Windows and macOS builds. |
Features:
Started as an internal PR on my fork. Original conversation here: https://github.com/Palakis/mixxx/pull/4
NOTE: Compiling and using this requires a version of libshout modified to support AAC. A ready-to-build source Debian package is provided in lib/ and a build is provided here: https://launchpad.net/~palakis/+archive/ubuntu/libshout-aac