Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Including a prebuilt library
QtWS25 Last Chance

Including a prebuilt library

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 5 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    vlada
    wrote on last edited by
    #1

    Hi,

    I would like to use FFT function from ffmpeg library. I downloaded a prebuilt binary and copied all files to the correct folders (lib, bin, include) in c:\qt\version\mingw53_32.

    In the .pro file I added this line:

        LIBS += -Llibavcodec
    

    Then I included the header file I need:

    #include "libavcodec/avfft.h"
    

    Later in my code I call a function defined in the header:

    ctx = av_rdft_init((int) log2(N), DFT_R2C);
    

    Everything seems to be fine until I try to compile my code. I always get this error:

    ./release\spectrummeter.o:spectrummeter.cpp:(.text+0x385): undefined reference to `av_rdft_init(int, RDFTransformType)'
    ./release\spectrummeter.o:spectrummeter.cpp:(.text+0xcec): undefined reference to `av_rdft_calc(RDFTContext*, float*)'
    collect2.exe: error: ld returned 1 exit status
    

    I don't know what is the problem. The two mentioned functions are defined in the header file and I included the library. What could be the problem? What is still missing?

    As a reference here is the complete header file avfft.h:

    /*
     * This file is part of FFmpeg.
     *
     * FFmpeg is free software; you can redistribute it and/or
     * modify it under the terms of the GNU Lesser General Public
     * License as published by the Free Software Foundation; either
     * version 2.1 of the License, or (at your option) any later version.
     *
     * FFmpeg is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     * Lesser General Public License for more details.
     *
     * You should have received a copy of the GNU Lesser General Public
     * License along with FFmpeg; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     */
    
    #ifndef AVCODEC_AVFFT_H
    #define AVCODEC_AVFFT_H
    
    /**
     * @file
     * @ingroup lavc_fft
     * FFT functions
     */
    
    /**
     * @defgroup lavc_fft FFT functions
     * @ingroup lavc_misc
     *
     * @{
     */
    
    typedef float FFTSample;
    
    typedef struct FFTComplex {
        FFTSample re, im;
    } FFTComplex;
    
    typedef struct FFTContext FFTContext;
    
    /**
     * Set up a complex FFT.
     * @param nbits           log2 of the length of the input array
     * @param inverse         if 0 perform the forward transform, if 1 perform the inverse
     */
    FFTContext *av_fft_init(int nbits, int inverse);
    
    /**
     * Do the permutation needed BEFORE calling ff_fft_calc().
     */
    void av_fft_permute(FFTContext *s, FFTComplex *z);
    
    /**
     * Do a complex FFT with the parameters defined in av_fft_init(). The
     * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
     */
    void av_fft_calc(FFTContext *s, FFTComplex *z);
    
    void av_fft_end(FFTContext *s);
    
    FFTContext *av_mdct_init(int nbits, int inverse, double scale);
    void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
    void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
    void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
    void av_mdct_end(FFTContext *s);
    
    /* Real Discrete Fourier Transform */
    
    enum RDFTransformType {
        DFT_R2C,
        IDFT_C2R,
        IDFT_R2C,
        DFT_C2R,
    };
    
    typedef struct RDFTContext RDFTContext;
    
    /**
     * Set up a real FFT.
     * @param nbits           log2 of the length of the input array
     * @param trans           the type of transform
     */
    RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
    void av_rdft_calc(RDFTContext *s, FFTSample *data);
    void av_rdft_end(RDFTContext *s);
    
    /* Discrete Cosine Transform */
    
    typedef struct DCTContext DCTContext;
    
    enum DCTTransformType {
        DCT_II = 0,
        DCT_III,
        DCT_I,
        DST_I,
    };
    
    /**
     * Set up DCT.
     *
     * @param nbits           size of the input array:
     *                        (1 << nbits)     for DCT-II, DCT-III and DST-I
     *                        (1 << nbits) + 1 for DCT-I
     * @param type            the type of transform
     *
     * @note the first element of the input of DST-I is ignored
     */
    DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
    void av_dct_calc(DCTContext *s, FFTSample *data);
    void av_dct_end (DCTContext *s);
    
    /**
     * @}
     */
    
    #endif /* AVCODEC_AVFFT_H */ 
    
    K 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Since its prebuild. Are you sure its
      for mingw 32 bit? and not say for visual studio etc ?

      1 Reply Last reply
      2
      • V vlada

        Hi,

        I would like to use FFT function from ffmpeg library. I downloaded a prebuilt binary and copied all files to the correct folders (lib, bin, include) in c:\qt\version\mingw53_32.

        In the .pro file I added this line:

            LIBS += -Llibavcodec
        

        Then I included the header file I need:

        #include "libavcodec/avfft.h"
        

        Later in my code I call a function defined in the header:

        ctx = av_rdft_init((int) log2(N), DFT_R2C);
        

        Everything seems to be fine until I try to compile my code. I always get this error:

        ./release\spectrummeter.o:spectrummeter.cpp:(.text+0x385): undefined reference to `av_rdft_init(int, RDFTransformType)'
        ./release\spectrummeter.o:spectrummeter.cpp:(.text+0xcec): undefined reference to `av_rdft_calc(RDFTContext*, float*)'
        collect2.exe: error: ld returned 1 exit status
        

        I don't know what is the problem. The two mentioned functions are defined in the header file and I included the library. What could be the problem? What is still missing?

        As a reference here is the complete header file avfft.h:

        /*
         * This file is part of FFmpeg.
         *
         * FFmpeg is free software; you can redistribute it and/or
         * modify it under the terms of the GNU Lesser General Public
         * License as published by the Free Software Foundation; either
         * version 2.1 of the License, or (at your option) any later version.
         *
         * FFmpeg is distributed in the hope that it will be useful,
         * but WITHOUT ANY WARRANTY; without even the implied warranty of
         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         * Lesser General Public License for more details.
         *
         * You should have received a copy of the GNU Lesser General Public
         * License along with FFmpeg; if not, write to the Free Software
         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
         */
        
        #ifndef AVCODEC_AVFFT_H
        #define AVCODEC_AVFFT_H
        
        /**
         * @file
         * @ingroup lavc_fft
         * FFT functions
         */
        
        /**
         * @defgroup lavc_fft FFT functions
         * @ingroup lavc_misc
         *
         * @{
         */
        
        typedef float FFTSample;
        
        typedef struct FFTComplex {
            FFTSample re, im;
        } FFTComplex;
        
        typedef struct FFTContext FFTContext;
        
        /**
         * Set up a complex FFT.
         * @param nbits           log2 of the length of the input array
         * @param inverse         if 0 perform the forward transform, if 1 perform the inverse
         */
        FFTContext *av_fft_init(int nbits, int inverse);
        
        /**
         * Do the permutation needed BEFORE calling ff_fft_calc().
         */
        void av_fft_permute(FFTContext *s, FFTComplex *z);
        
        /**
         * Do a complex FFT with the parameters defined in av_fft_init(). The
         * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
         */
        void av_fft_calc(FFTContext *s, FFTComplex *z);
        
        void av_fft_end(FFTContext *s);
        
        FFTContext *av_mdct_init(int nbits, int inverse, double scale);
        void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
        void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
        void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
        void av_mdct_end(FFTContext *s);
        
        /* Real Discrete Fourier Transform */
        
        enum RDFTransformType {
            DFT_R2C,
            IDFT_C2R,
            IDFT_R2C,
            DFT_C2R,
        };
        
        typedef struct RDFTContext RDFTContext;
        
        /**
         * Set up a real FFT.
         * @param nbits           log2 of the length of the input array
         * @param trans           the type of transform
         */
        RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
        void av_rdft_calc(RDFTContext *s, FFTSample *data);
        void av_rdft_end(RDFTContext *s);
        
        /* Discrete Cosine Transform */
        
        typedef struct DCTContext DCTContext;
        
        enum DCTTransformType {
            DCT_II = 0,
            DCT_III,
            DCT_I,
            DST_I,
        };
        
        /**
         * Set up DCT.
         *
         * @param nbits           size of the input array:
         *                        (1 << nbits)     for DCT-II, DCT-III and DST-I
         *                        (1 << nbits) + 1 for DCT-I
         * @param type            the type of transform
         *
         * @note the first element of the input of DST-I is ignored
         */
        DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
        void av_dct_calc(DCTContext *s, FFTSample *data);
        void av_dct_end (DCTContext *s);
        
        /**
         * @}
         */
        
        #endif /* AVCODEC_AVFFT_H */ 
        
        K Offline
        K Offline
        koahnig
        wrote on last edited by aha_1980
        #3

        @vlada

        LIBS parameter has in your example only the path with -L declared, but the library name starting with -l is missing.
        See here

        Vote the answer(s) that helped you to solve your issue(s)

        1 Reply Last reply
        3
        • V Offline
          V Offline
          vlada
          wrote on last edited by vlada
          #4

          @mrjj I'm pretty sure I have the correct version. I need the ffmpeg libraries for QtAV and here it works correctly. I use the MinGW version from here.

          @koahnig Yes, this was definitely wrong. I fixed it like this:

          LIBS += C:/Qt/5.11.1/mingw53_32/lib/avcodec.lib
          

          but unfortunately it didn't help. I still get the same error. Unfortunately I don't fully understand how ther linker works and were are the different library files (lib/avcodec.lib, lib/libavcodec.dll.a, bin/avcodec-58.dll) used.

          1 Reply Last reply
          0
          • G Offline
            G Offline
            Gerd
            wrote on last edited by
            #5

            assuming you are compiling your code as c++-code it looks like a name mangling problem.

            try to change this

            #include "libavcodec/avfft.h"

            to

            extern "C" {
            #include "libavcodec/avfft.h"
            }

            aha_1980A 1 Reply Last reply
            1
            • G Gerd

              assuming you are compiling your code as c++-code it looks like a name mangling problem.

              try to change this

              #include "libavcodec/avfft.h"

              to

              extern "C" {
              #include "libavcodec/avfft.h"
              }

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi @Gerd,
              looking at the linker error:

              undefined reference to 'av_rdft_init(int, RDFTransformType)'

              I don't thing name mangling is the problem here.

              Hi @vlada,
              you should always verify your changes by looking at the linker command in Creators Compile Output.

              If your library is in C:/Qt/5.11.1/mingw53_32/lib/avcodec.lib, the .pro file should look like this: LIBS += -LC:/Qt/5.11.1/mingw53_32/lib -lavcodec

              Regards

              Qt has to stay free or it will die.

              1 Reply Last reply
              0
              • V Offline
                V Offline
                vlada
                wrote on last edited by
                #7

                @Gerd I'm not sure what is a "mangling problem" but using your code fixed the compilation.

                @aha_1980 I tried this syntax too but the result was the same. The linker command looks like this:

                g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\Muzika.exe object_script.Muzika.Release  -lmingw32 -LC:\Qt\5.11.1\mingw53_32\lib C:\Qt\5.11.1\mingw53_32\lib\libqtmain.a -LC:\openssl\lib -LC:\Utils\my_sql\mysql-5.6.11-win32\lib -LC:\Utils\postgresql\pgsql\lib -lshell32 -LC:\Moje\QtProjects\Muzika\3rdparty\taglib\lib -ltag -LC:\Moje\QtProjects\build-MuzikaPlayer-Desktop_Qt_5_11_1_MinGW_32bit-Vydu00e1nu00ed\release -lfftreal -LC:\Moje\QtProjects\Muzika\3rdparty\mediainfo\lib -lmediainfo -lavcodec C:\Qt\5.11.1\mingw53_32\lib\libQt5Quick.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Svg.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Widgets.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Multimedia.a -lQt5AV C:\Qt\5.11.1\mingw53_32\lib\libQt5Gui.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Qml.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Network.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Sql.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Xml.a C:\Qt\5.11.1\mingw53_32\lib\libQt5Core.a release\muzika_res.o 
                ./release\spectrummeter.o:spectrummeter.cpp:(.text+0x45d): undefined reference to `av_rdft_init(int, RDFTransformType)'
                ./release\spectrummeter.o:spectrummeter.cpp:(.text+0xf9b): undefined reference to `av_rdft_calc(RDFTContext*, float*)'
                collect2.exe: error: ld returned 1 exit status
                

                Now the program runs and even the inicialisation of FFT is working:

                ctx = av_rdft_init(11, DFT_R2C);
                

                But calling the real calculation causes a hard crash:

                av_rdft_calc(ctx, fft_data);
                

                I have no idea what is the problem here. Maybe wrong data size. I followed this guide to implement the FFT calculation. But I probably have a mistake somewhere.

                I do believe that if the library would be incorrectly linked, it would already crash at time my app calls the initialisation. Right?

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  Gerd
                  wrote on last edited by
                  #8

                  Hi @aha_1980 ,
                  the linker error gave me the hint about the problem:

                  undefined reference to 'av_rdft_init(int, RDFTransformType)'
                  

                  If the linker complains about a missing C-Funktion i would expect

                  undefined reference to 'av_rdft_init'
                  

                  without the parameter-types

                  Hi @vlada ,
                  here is a short description of name mangling name mangling.

                  --I do believe that if the library would be incorrectly linked, it would already crash at time my app calls the initialisation. Right?
                  Yeah, hat should be.

                  Check the parameters of the call to av_rdft_init and be sure the return value is valid.
                  Also, for the call to av_rdft_calc, check that fft_data has the rght format and size.

                  aha_1980A 1 Reply Last reply
                  2
                  • G Gerd

                    Hi @aha_1980 ,
                    the linker error gave me the hint about the problem:

                    undefined reference to 'av_rdft_init(int, RDFTransformType)'
                    

                    If the linker complains about a missing C-Funktion i would expect

                    undefined reference to 'av_rdft_init'
                    

                    without the parameter-types

                    Hi @vlada ,
                    here is a short description of name mangling name mangling.

                    --I do believe that if the library would be incorrectly linked, it would already crash at time my app calls the initialisation. Right?
                    Yeah, hat should be.

                    Check the parameters of the call to av_rdft_init and be sure the return value is valid.
                    Also, for the call to av_rdft_calc, check that fft_data has the rght format and size.

                    aha_1980A Offline
                    aha_1980A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @Gerd very good observation :)

                    Sad that still some libraries don't provide this guard by itself.

                    @vlada if you like, you can try my version of the linker command line nevertheless, as it is the more portable version.

                    Regards

                    Qt has to stay free or it will die.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved