Search code examples
ffmpegandroid-ffmpeg

FFmpeg on Android with Rubberband


When I try to link librubberband.a I get: libavfilter/af_rubberband.c:236: error: undefined reference to 'rubberband_set_pitch_scale'

  1. I compiled rubberband for armv7a, and created a static library (rubberband.a). I checked the library, and It contained the needed symbols (using nm).

  2. I verified that librubberband.a is in the libpath (-L)

  3. I verified that extern C exists in the rubberband.c.h file.

Any ideas?


Solution

  • The error happened in the link stage. Make sure the link directory has been added to -L parameters of your compiler.

    -L/directory/of/your/lib

    And specify the library with -l option.

    So make sure the option -L/directory/of/your/lib -lrubberband set for your compiler when you build ffmpeg with rubberband support.

    If you didn't use pkg-config to add the library. You can use the option --extra-ldflags to add when configure ffmpeg before build.

    ./configure \
    # some configure options
    --extra-ldflags="-L/directory/of/your/lib -lrubberband" \
    # more configure options
    

    If you use pkg-config to find out the libraries. Just add the library.pc directory to PKG_CONFIG_PATH, and let the build system do the remaining.

    export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/directory/to/your/rubberband.pc
    

    Updated

    Finally make sure you link against to the same architecture of your library.

    $ arm-linux-androideabi-readelf -h librubberband.a |grep 'Class\|Machine
    

    For armeabi-v7a, it should be ELF32 and ARM.

    Updated

    I have cloned the source of rubberband from https://bitbucket.org/breakfastquay/rubberband

    And found the function call rubberband_set_pitch_scale is defined at src/rubberband-c.cpp, this file is not include in Android.mk when build for Android (WHY?).

    So you have to add this file to build.

    RUBBERBAND_SRC_FILES = ... \
        $(RUBBERBAND_SRC_PATH)/rubberband-c.cpp
    

    After build done, you need to create directory structure like below

        .
    ├── include
    │   └── rubberband
    │       ├── RubberBandStretcher.h
    │       └── rubberband-c.h
    └── lib
        ├── librubberband.a
        └── pkgconfig
            └── rubberband.pc
    

    The file rubberband.pc was copied from rubberband.in.pc with some minor changes.

    prefix=/path/to/rubberband/install/root
    exec_prefix=${prefix}
    libdir=${exec_prefix}/lib
    includedir=${prefix}/include
    
    Name: rubberband
    Version: 1.8.1
    Description: 
    Libs: -L${libdir} -lrubberband -L/path/to/android/ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -lgnustl_static
    Cflags: -I${includedir} 
    

    Then add

    export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/rubberband/install/root
    

    before ./configure to tell ffmpeg find rubberband by pkg-config.

    I have tried with the latest ffmpeg, it works.