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

Build fails with "error: ‘av_register_all’ was not declared in this scope" #1411

Open
TylerTheHumanCompiler opened this issue Apr 30, 2024 · 5 comments

Comments

@TylerTheHumanCompiler
Copy link

Build fails with the following error:

[100/308] Compiling src/essentia/utils/audiocontext.cpp
../src/essentia/utils/audiocontext.cpp: In constructor ‘essentia::AudioContext::AudioContext()’:
../src/essentia/utils/audiocontext.cpp:33:3: error: ‘av_register_all’ was not declared in this scope
   33 |   av_register_all(); // this should be done once only..
      |   ^~~~~~~~~~~~~~~
../src/essentia/utils/audiocontext.cpp: In member function ‘int essentia::AudioContext::create(const std::string&, const std::string&, int, int, int)’:
../src/essentia/utils/audiocontext.cpp:48:53: error: invalid conversion from ‘const AVOutputFormat*’ to ‘AVOutputFormat*’ [-fpermissive]
   48 |   AVOutputFormat* av_output_format = av_guess_format(format.c_str(), 0, 0);
      |                                      ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
      |                                                     |
      |                                                     const AVOutputFormat*
../src/essentia/utils/audiocontext.cpp:67:42: error: ‘AVStream’ {aka ‘struct AVStream’} has no member named ‘codec’
   67 |   _codecCtx                 = _avStream->codec;
      |                                          ^~~~~
@DarshReddy
Copy link

I am getting same errors when trying to compile for android

../src/essentia/utils/audiocontext.cpp:33:3: error: use of undeclared identifier 'av_register_all'
   33 |   av_register_all(); // this should be done once only..
      |   ^
../src/essentia/utils/audiocontext.cpp:48:19: error: cannot initialize a variable of type 'AVOutputFormat *' with an rvalue of type 'const AVOutputFormat *'
   48 |   AVOutputFormat* av_output_format = av_guess_format(format.c_str(), 0, 0);
      |                   ^                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/essentia/utils/audiocontext.cpp:67:42: error: no member named 'codec' in 'AVStream'
   67 |   _codecCtx                 = _avStream->codec;
      |                               ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:72:14: error: no member named 'channels' in 'AVCodecContext'
   72 |   _codecCtx->channels       = nChannels;
      |   ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:73:14: error: no member named 'channel_layout' in 'AVCodecContext'
   73 |   _codecCtx->channel_layout = av_get_default_channel_layout(nChannels);
      |   ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:73:31: error: use of undeclared identifier 'av_get_default_channel_layout'
   73 |   _codecCtx->channel_layout = av_get_default_channel_layout(nChannels);
      |                               ^
../src/essentia/utils/audiocontext.cpp:77:12: error: cannot initialize a variable of type 'AVCodec *' with an rvalue of type 'const AVCodec *'
   77 |   AVCodec* audioCodec = avcodec_find_encoder(_codecCtx->codec_id);
      |            ^            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/essentia/utils/audiocontext.cpp:125:49: error: no member named 'channels' in 'AVCodecContext'
  125 |       _codecCtx->frame_size = 4096 / _codecCtx->channels / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
      |                                      ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:140:57: error: no member named 'channels' in 'AVCodecContext'
  140 |                                              _codecCtx->channels, 
      |                                              ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:145:20: error: no member named 'filename' in 'AVFormatContext'
  145 |   strncpy(_muxCtx->filename, _filename.c_str(), sizeof(_muxCtx->filename));
      |           ~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:145:65: error: no member named 'filename' in 'AVFormatContext'
  145 |   strncpy(_muxCtx->filename, _filename.c_str(), sizeof(_muxCtx->filename));
      |                                                        ~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:151:65: error: no member named 'channel_layout' in 'AVCodecContext'
  151 |   av_opt_set_int(_convertCtxAv, "in_channel_layout", _codecCtx->channel_layout, 0);
      |                                                      ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:152:66: error: no member named 'channel_layout' in 'AVCodecContext'
  152 |   av_opt_set_int(_convertCtxAv, "out_channel_layout", _codecCtx->channel_layout, 0);
      |                                                       ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:194:28: error: no member named 'codec' in 'AVStream'
  194 |   avcodec_close(_avStream->codec);
      |                 ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:198:24: error: no member named 'codec' in 'AVStream'
  198 |   av_freep(&_avStream->codec);
      |             ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:218:18: error: no member named 'channels' in 'AVCodecContext'
  218 |   if (_codecCtx->channels != 2) {
      |       ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:219:100: error: no member named 'channels' in 'AVCodecContext'
  219 |     throw EssentiaException("Trying to write stereo audio data to an audio file with ", _codecCtx->channels, " channels");
      |                                                                                         ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:243:18: error: no member named 'channels' in 'AVCodecContext'
  243 |   if (_codecCtx->channels != 1) {
      |       ~~~~~~~~~  ^
../src/essentia/utils/audiocontext.cpp:244:98: error: no member named 'channels' in 'AVCodecContext'
  244 |     throw EssentiaException("Trying to write mono audio data to an audio file with ", _codecCtx->channels, " channels");
      |                                                                                       ~~~~~~~~~  ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.

Waf: Leaving directory `/Users/darshreddy/Artium/essentia/build'
Build failed
 -> task in 'essentia' failed with exit status 1: 
	{task 4391454768: cxx audiocontext.cpp -> audiocontext.cpp.1.o}
['/usr/bin/clang++', '-std=c++11', '-pipe', '-Wall', '-O2', '-fPIC', '-std=c++11', '-I/usr/local/include', '-w', '-fPIC', '-Isrc', '-I../src', '-Isrc/essentia', '-I../src/essentia', '-Isrc/essentia/scheduler', '-I../src/essentia/scheduler', '-Isrc/essentia/streaming', '-I../src/essentia/streaming', '-Isrc/essentia/streaming/algorithms', '-I../src/essentia/streaming/algorithms', '-Isrc/essentia/utils', '-I../src/essentia/utils', '-Isrc/3rdparty', '-I../src/3rdparty', '-Isrc/3rdparty/spline', '-I../src/3rdparty/spline', '-Isrc/3rdparty/nnls', '-I../src/3rdparty/nnls', '-Isrc/3rdparty/cephes/bessel', '-I../src/3rdparty/cephes/bessel', '-I/opt/homebrew/Cellar/eigen/3.4.0_1/include/eigen3', '-I/opt/homebrew/Cellar/ffmpeg/7.0.2/include', '-I/opt/homebrew/Cellar/libsamplerate/0.2.2/include', '-DGTEST_HAS_TR1_TUPLE=0', '-DHAVE_EIGEN3=1', '-DEIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS', '-DHAVE_AVCODEC=1', '-DHAVE_AVFORMAT=1', '-DHAVE_AVUTIL=1', '-DHAVE_SWRESAMPLE=1', '-DHAVE_SAMPLERATE=1', '-D__STDC_CONSTANT_MACROS', '-DEIGEN_MPL2_ONLY', '../src/essentia/utils/audiocontext.cpp', '-c', '-o/Users/darshreddy/Artium/essentia/build/src/essentia/utils/audiocontext.cpp.1.o', '-fPIC', '-I/opt/homebrew/opt/[email protected]/include']

@luckysmg
Copy link

Get same error when build ios

@DarshReddy
Copy link

Hi @dbogdanov can you please help here? this is happening even on normal build from master branch

@caner-cetin
Copy link

caner-cetin commented Dec 30, 2024

Okay, so, this persists, and, Essentia desperately needs pre-built libraries because compiling C++ is borderline impossible if you care about your sanity. @dbogdanov

Same logs, same error messages, av_register_all does not exist, because, yes, it truly does not exist. leandromoreira/ffmpeg-libav-tutorial#29 it has been dropped with 4.0 version which was 6 years ago. So there is two locations where av_register_all is used.

One in here:

https://github.com/MTG/essentia/blob/master/src/algorithms/io/audioloader.h#L98

And others here:

https://github.com/MTG/essentia/blob/master/src/essentia/utils/audiocontext.cpp#L33

Then we need to downgrade ourselves to version 4 of ffmpeg because there is a

#1248

Support ffmpeg version 5 issue that has been open for two, nearly three years.

there is only two occurrences of this function call. If I delete both (it is recommended to replace them with nothing), then the algorithms_info.py that is used within both compiling and configuring will break, and, besides that two function calls, there are so many moving parts of ffmpeg and version 4 to 6 is definitely not compatible

How the fuck are we going to find the latest version of ffmpeg 4. X? This is where things get beyond fucked up.

https://patchwork.ffmpeg.org/project/ffmpeg/patch/AM7PR03MB6660E1F8A57B76DF6578148B8FDB9@AM7PR03MB6660.eurprd03.prod.outlook.com/

In this patch, at, Sept. 15, 2021 av_mallocz_array is deprecated, and there are, i am not exaggerating FUCKTON of references to this function call. At first, I have downloaded and setup 4.4.2 (yes i followed these steps twice, you can do it mate) which released after this patch and my CMake output is full of

[build] /home/cansu/ffmpeg-4.4.2/libavcodec/snowenc.c:88:(.text.unlikely+0x18f): undefined reference to `av_mallocz_array'

from all libraries. So I am picking version 4.4 which released on 2021-04-09

Get the source code:

$ wget https://ffmpeg.org/releases/ffmpeg-4.4.tar.xz
$ tar -xf ffmpeg-4.4.tar.xz
$ cd ffmpeg-4.4

Then build the ffmpeg yourself:

./configure --disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--pkg-config-flags="--static" \
--ld="g++"
sudo make
sudo make install
# compile breaks if i don't remove decklink headers, try yourself before removing
sudo rm libavdevice/decklink*

Configure won't throw any errors. If you run make with no errors, congrats, advance to the next step, if you see an error like this:

(essentia) ➜  ffmpeg-4.4.2 make
CC      libavformat/adtsenc.o
./libavcodec/x86/mathops.h: Assembler messages:
./libavcodec/x86/mathops.h:125: Error: operand type mismatch for `shr'
./libavcodec/x86/mathops.h:125: Error: operand type mismatch for `shr'
./libavcodec/x86/mathops.h:125: Error: operand type mismatch for `shr'

You are coming with me.

Apply the following patch: https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/effadce6c756247ea8bae32dc13bb3e6f464f0eb

with either using patch

patch -i ffmpeg.patch

where ffmpeg.patch is the patch from link above, for convenience https://pastebin.com/raw/c0Uq4TJU

If you want to manually edit, open libavcodec/x86/mathops.h file.

Change the NEG_USR32 with this:

#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s) {
  if (__builtin_constant_p(s))
    __asm__("shrl %1, %0\n\t" : "+r"(a) : "i"(-s & 0x1F));
  else
    __asm__("shrl %1, %0\n\t" : "+r"(a) : "c"((uint8_t)(-s)));
  return a;
}

Change the NEG_SSR32 with this:

#define NEG_SSR32 NEG_SSR32
static inline int32_t NEG_SSR32(int32_t a, int8_t s) {
  if (__builtin_constant_p(s))
    __asm__("sarl %1, %0\n\t" : "+r"(a) : "i"(-s & 0x1F));
  else
    __asm__("sarl %1, %0\n\t" : "+r"(a) : "c"((uint8_t)(-s)));
  return a;
}

Change the MULL with this:

#define MULL MULL
static av_always_inline av_const int MULL(int a, int b, unsigned shift) {
  int rt, dummy;
  __asm__(
      "imull %3               \n\t"
      "shrdl %4, %%edx, %%eax \n\t"
      : "=a"(rt), "=d"(dummy)
      : "a"(a), "rm"(b), "i"(shift & 0x1F));
  return rt;
}

then run the

make

command again. If you have no errors, yay, we are in the same state! If make errors out, god save your soul, you are not with me anymore.
Delete the latest versions of required libraries

sudo apt-get remove libavcodec-dev libavformat-dev libavutil-dev

run

sudo make install

if you got any errors, good luck, you are out again, if you see something like this when you run the built ffmpeg

(essentia) ➜  ffmpeg-4.4.2 ./ffmpeg -version
ffmpeg version 4.4.2 Copyright (c) 2000-2021 the FFmpeg developers

Then we are together again, and we are almost there! I say almost, because holy fucking shit, it does not end.

Now that we have compiled FFMPEG, we can compile Essentia

git clone https://github.com/MTG/essentia.git
cd essentia
python3 waf configure --build-static --with-tensorflow

if it is all green
image

python3 waf

there wont be any errors. if, somehow, you got error here, my condolences, you are out of my reach. if you have seen this output

[316/316] Linking build/src/libessentia.a
Waf: Leaving directory `/home/cansu/Git/essentia/essentia/build'
'build' finished successfully (3m55.438s)

run

python3 waf install

previously, I thought building inside a virtual environment and then moving the include headers + library to the source code folder is the solution, but, if you run the waf install outside of a virtual environment, waf will place all the files to /usr/local/..., and library wont work outside of /usr/local/...

Now it is time for GLSLang for libavcodec and various libraries of ffmpeg.

git clone https://github.com/KhronosGroup/glslang.git
cd glslang
python3 update_glslang_sources.py
BUILD_DIR="build"
cmake -B $BUILD_DIR -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
make -j4 install
sudo ln -s /usr/local/bin/glslang /usr/bin/glslang
sudo ln -s /usr/local/bin/spirv-remap /usr/bin/spirv-remap

hope there wont be any errors for you.

optionally, gtest.

sudo apt-get install -y libgtest-dev cmake
mkdir -p $HOME/build
cd $HOME/build
sudo cmake /usr/src/googletest/googletest
sudo make
sudo cp lib/libgtest* /usr/lib/
cd ..
sudo rm -rf build
sudo mkdir /usr/local/lib/googletest
sudo ln -s /usr/lib/libgtest.a /usr/local/lib/googletest/libgtest.a
sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/googletest/libgtest_main.a

cmake time.,

get the following from your package manager (x11 and video accel is optional), Ubuntu:

sudo apt-get install \
    libva-dev \
    libyaml-dev \
    libvdpau-dev \
    libx11-dev \
    libsamplerate0-dev \
    libprotobuf-dev \
    protobuf-compiler \
    libglslang-dev \
    libeigen3-dev \
    libfftw3-dev \
    libchromaprint-dev \
    libtagc0-dev \
    libva-drm2 \
    libbz2-dev \
    liblzma-dev \
    zlib1g-dev 

slam this to CMakeLists.txt. handwritten by myself, commented by Claude sorry if its overcommented

# Specify the minimum required version of CMake. The version range 3.14...3.31 means
# the project requires at least CMake 3.14 but will work with any version up to 3.31
cmake_minimum_required(VERSION 3.14...3.31)

project(Conan)

# Add preprocessor definitions that will be available during compilation
# These are important POSIX and GNU specific macros that enable various features
add_definitions(
    # Enable POSIX.1b real-time extensions
    -D_POSIX_C_SOURCE=199309L
    # Enable GNU extensions
    -D_GNU_SOURCE
    # Enable macros for constant values in stdint.h
    -D__STDC_CONSTANT_MACROS
    # Enable printf format macros in inttypes.h
    -D__STDC_FORMAT_MACROS
    # Enable limit macros in stdint.h
    -D__STDC_LIMIT_MACROS
)

# Configure C++ standard settings
set(CMAKE_CXX_STANDARD 17)              # Use C++17 standard
set(CMAKE_CXX_STANDARD_REQUIRED ON)     # Require C++17 support (don't fall back to previous versions)
set(CMAKE_CXX_EXTENSIONS ON)            # Allow compiler-specific extensions
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)   # Generate compile_commands.json for tooling

find_package(glslang REQUIRED)   # GLSL compiler
find_package(Protobuf REQUIRED)  # Protocol Buffers
find_package(PkgConfig REQUIRED) # Package configuration tool
find_package(X11 QUIET)         # X11 window system (optional)

# Use pkg-config to find additional libraries
find_package(PkgConfig REQUIRED)
pkg_check_modules(CHROMAPRINT REQUIRED libchromaprint)  # Audio fingerprinting library
pkg_check_modules(VDPAU QUIET vdpau)                    # Video acceleration (optional)

# Create the executable target from the main source file
add_executable(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/src/main.cpp)

# Define vendor directory paths for better organization
set(FFMPEG_VENDOR_DIR   ${CMAKE_SOURCE_DIR}/src/vendor/ffmpeg)
set(GLSLANG_VENDOR_DIR  ${CMAKE_SOURCE_DIR}/src/vendor/glslang)

# Configure include directories for the target
# PRIVATE means these includes are only used internally by this target
target_include_directories(${PROJECT_NAME} PRIVATE
    ${X11_INCLUDE_DIR}                    # X11 headers
    ${VDPAU_INCLUDE_DIRS}                 # VDPAU headers
    /usr/local/include/essentia  
    samplerate                           # Audio sample rate conversion
    ${CMAKE_SOURCE_DIR}/src/include      # Project headers
    ${Protobuf_INCLUDE_DIRS}            # Protocol Buffers headers
    # GLSL and SPIR-V related headers
    ${GLSLANG_VENDOR_DIR}/SPIRV
    ${GLSLANG_VENDOR_DIR}/external/spirv-headers/include
    ${GLSLANG_VENDOR_DIR}/External/spirv-tools
    /usr/local/include/spirv-tools/
    # Eigen matrix library headers
    /usr/include/eigen3
    /usr/include/eigen3/unsupported
    # TensorFlow headers
    /usr/local/tensorflow/include
    ${CMAKE_SOURCE_DIR}/src
    ${CHROMAPRINT_INCLUDE_DIRS}          # Chromaprint headers
    ${YAML_INCLUDE_DIR}                  # YAML parser headers
    # FFmpeg related headers
    ${FFMPEG_VENDOR_DIR}
    ${FFMPEG_VENDOR_DIR}/libavformat
    ${FFMPEG_VENDOR_DIR}/libavformat/*.h
    ${FFMPEG_VENDOR_DIR}/libavcodec
    ${FFMPEG_VENDOR_DIR}/libavcodec/*.h
    ${FFMPEG_VENDOR_DIR}/libavdevice
    ${FFMPEG_VENDOR_DIR}/libavfilter
    ${FFMPEG_VENDOR_DIR}/libavresample
    ${FFMPEG_VENDOR_DIR}/libavutil
    ${FFMPEG_VENDOR_DIR}/libpostproc
    ${FFMPEG_VENDOR_DIR}/libswresample
    ${FFMPEG_VENDOR_DIR}/libswscale
)

# Add additional library search directories
target_link_directories(${PROJECT_NAME} PRIVATE
    /usr/local/tensorflow/lib
)

# Define paths to FFmpeg static libraries
set(LIBAVUTIL_LIBRARY       ${FFMPEG_VENDOR_DIR}/libavutil/libavutil.a)
set(LIBAVCODEC_LIBRARY      ${FFMPEG_VENDOR_DIR}/libavcodec/libavcodec.a)
set(LIBAVFORMAT_LIBRARY     ${FFMPEG_VENDOR_DIR}/libavformat/libavformat.a)
set(LIBAVFILTER_LIBRARY     ${FFMPEG_VENDOR_DIR}/libavfilter/libavfilter.a)
set(LIBSWRESAMPLE_LIBRARY   ${FFMPEG_VENDOR_DIR}/libswresample/libswresample.a)
set(LIBSWSCALE_LIBRARY      ${FFMPEG_VENDOR_DIR}/libswscale/libswscale.a)
set(LIBAVDEVICE_LIBRARY     ${FFMPEG_VENDOR_DIR}/libavdevice/libavdevice.a)

# Link all required libraries to the target
# WARNING: FFmpeg libraries must be linked in this specific order due to dependencies
target_link_libraries(${PROJECT_NAME} PRIVATE
    /usr/local/lib/libessentia.a
    samplerate                          # Sample rate conversion
    # FFmpeg libraries (order matters!)
    ${LIBAVDEVICE_LIBRARY}
    ${LIBAVFILTER_LIBRARY}
    ${LIBAVFORMAT_LIBRARY}
    ${LIBAVCODEC_LIBRARY}
    ${LIBSWRESAMPLE_LIBRARY}
    ${LIBSWSCALE_LIBRARY}
    ${LIBAVUTIL_LIBRARY} 
    # Video acceleration libraries
    va
    va-drm
    ${X11_LIBRARIES}
    ${VDPAU_LIBRARIES}
    # Machine learning libraries
    tensorflow
    tensorflow_framework
    # Various other dependencies
    glslang
    ${Protobuf_LIBRARIES}
    tag                                 # Audio metadata library
    fftw3                              # Fast Fourier Transform
    fftw3f
    yaml                               # YAML parser
    va                                 # Video acceleration
    z                                  # Compression
    bz2                                # Compression
    lzma                               # Compression
    ${CHROMAPRINT_LIBRARIES}           # Audio fingerprinting
)

save this to main.cpp

#include <essentia/algorithmfactory.h>
#include <essentia/essentia.h>
#include <essentia/pool.h>

#include <vector>

using namespace essentia;
using namespace essentia::standard;
int main(int argc, char** argv) {
  essentia::init();
  Pool pool;

  AlgorithmFactory& factory = standard::AlgorithmFactory::instance();
  Algorithm* loader = factory.create("MonoLoader", "filename",
                                     "01. A Cleaved Head No Longer Plots.mp3",
                                     "sampleRate", 44100);
  Algorithm* duration = factory.create("Duration", "sampleRate", 44100);

  std::vector<Real> audioBuffer;
  Real durationSecond;
  loader->output("audio").set(audioBuffer);
  duration->input("signal").set(audioBuffer);
  duration->output("duration").set(durationSecond);

  loader->compute();
  duration->compute();

  factory.free(loader);
  factory.free(duration);

  essentia::shutdown();

  std::cout << durationSecond << std::endl;

  return 0;
}

change the audio path, configure, compile, run, have fun.

tldr: if you don't have any solid reasons, just use python bindings instead.

peace.

edit: bunch of typos, bad english, poor grammar, pinch me if you dont understand anything

@caner-cetin
Copy link

Updates, I have managed to compile CPP library by myself, attached a CMakeLists.txt, if any future readers stumble upon this and follow the comment, let me know if anything goes wrong, I can use Essentia + QT without any problems and fairly fast compilation time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants