hendriks73 / ffsampledsp

FFmpeg based service provider for javax.sound.sampled.
GNU Lesser General Public License v2.1
24 stars 5 forks source link

SUPPORT: CentOs #1

Closed jonashartwig closed 7 years ago

jonashartwig commented 7 years ago

Hi, I used this ffsampledsp through java on my mac. I found this very nice built and worked without any major issues. However for centos I would need to build my own JNI implementation to go against ffempeg. I already build and installed ffmpeg on my centos with what I need. Can you provide some steps on how I can build the ffsampled platform specific JNI code?

Regards

hendriks73 commented 7 years ago

Hey Jonas,

I cannot provide the actual code, but really all you need to do is

  1. Create the header files for FFAudioFileReader, FFCodecInputStream, FFURLInputStream, FFStreamInputStream with the javah tool.
  2. Compile and link the C code in ffsampledsp-x86_64-darwin/src/main/c/ (together with the generated header files)
  3. Make sure the JNI library can be found by com.tagtraum.ffsampledsp.FFNativeLibraryLoader - that class is currently only suitable for Mac/Windows

If you want to automate the build process, take a look at the pom.xml files in the sub-modules. To build the native component, FFSamplesSP uses the Maven native-maven-plugin.

Good luck!

jonashartwig commented 7 years ago

HI, thanks for the advice. I got everything set up and currently I try to build the shared library (so). I have the jni things available, the headers generated with javah and the built code for ffmpeg. Everything is on the CPATH. However I get the error: In file included from FFAudioFileReader.c:25:0: FFUtils.h:53:47: fatal error: libswresample/swresample_internal.h: No such file or directory

include <libswresample/swresample_internal.h>From multiple files. That file does not exist in the build ffmpeg only in the sources. Is that correct? Do I have to put the sources on the CPATH as well?

regards

hendriks73 commented 7 years ago

I guess I should have mentioned that the header files for all FFmpeg libraries (libavutil, libswresample, ...) have to be in the path, as that's of course what you compile against.

It's very instructive to look at the Maven output when building the regular FFSampledSP. E.g. for Windows:

[INFO] ------------------------------------------------------------------------
[INFO] Building FFSampledSP Native Library Windows (32bit) 0.9.20-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ ffsampledsp-i386-mingw32 ---
[INFO] Deleting /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target
[INFO]
[INFO] --- native-maven-plugin:1.0-alpha-8:initialize (default-initialize) @ ffsampledsp-i386-mingw32 ---
[INFO]
[INFO] --- native-maven-plugin:1.0-alpha-8:unzipinc (default-unzipinc) @ ffsampledsp-i386-mingw32 ---
[INFO]
[INFO] --- native-maven-plugin:1.0-alpha-8:javah (default-javah) @ ffsampledsp-i386-mingw32 ---
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && javah -d /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/javah -classpath /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/classes:/Users/hendrik/Projects/ffsampledsp/ffsampledsp-java/target/ffsampledsp-java-0.9.20-SNAPSHOT.jar:/Users/hendrik/.m2/repository/com/tagtraum/ffmpeg/ffmpeg/3.3.1/ffmpeg-3.3.1-sources-i386-mingw32.jar:/Users/hendrik/.m2/repository/com/tagtraum/ffmpeg/ffmpeg/3.3.1/ffmpeg-3.3.1-sources.jar com.tagtraum.ffsampledsp.FFAudioFileReader com.tagtraum.ffsampledsp.FFCodecInputStream com.tagtraum.ffsampledsp.FFURLInputStream com.tagtraum.ffsampledsp.FFStreamInputStream
[INFO]
[INFO] --- maven-dependency-plugin:2.10:unpack (unpack) @ ffsampledsp-i386-mingw32 ---
[INFO] Configured Artifact: com.tagtraum.ffmpeg:ffmpeg:sources-i386-mingw32:3.3.1:jar
[INFO] Unpacking /Users/hendrik/.m2/repository/com/tagtraum/ffmpeg/ffmpeg/3.3.1/ffmpeg-3.3.1-sources-i386-mingw32.jar to /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include with includes "**/*.h" and excludes ""
[INFO]
[INFO] --- native-maven-plugin:1.0-alpha-8:resource-compile (default-resource-compile) @ ffsampledsp-i386-mingw32 ---
[INFO]
[INFO] --- native-maven-plugin:1.0-alpha-8:compile (default-compile) @ ffsampledsp-i386-mingw32 ---
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && /Users/hendrik/mingw/mingw-w32-i686/bin/i686-w64-mingw32-gcc -Wall -x c -Wno-multichar -D_JNI_IMPLEMENTATION_ -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/javah -I/Users/hendrik/windows-jdk/include -I/Users/hendrik/windows-jdk/include/win32 -o /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/objs/FFAudioFileReader.o -c /Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFAudioFileReader.c
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && /Users/hendrik/mingw/mingw-w32-i686/bin/i686-w64-mingw32-gcc -Wall -x c -Wno-multichar -D_JNI_IMPLEMENTATION_ -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/javah -I/Users/hendrik/windows-jdk/include -I/Users/hendrik/windows-jdk/include/win32 -o /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/objs/FFCodecInputStream.o -c /Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFCodecInputStream.c
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && /Users/hendrik/mingw/mingw-w32-i686/bin/i686-w64-mingw32-gcc -Wall -x c -Wno-multichar -D_JNI_IMPLEMENTATION_ -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/javah -I/Users/hendrik/windows-jdk/include -I/Users/hendrik/windows-jdk/include/win32 -o /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/objs/FFStreamInputStream.o -c /Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFStreamInputStream.c
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && /Users/hendrik/mingw/mingw-w32-i686/bin/i686-w64-mingw32-gcc -Wall -x c -Wno-multichar -D_JNI_IMPLEMENTATION_ -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/javah -I/Users/hendrik/windows-jdk/include -I/Users/hendrik/windows-jdk/include/win32 -o /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/objs/FFURLInputStream.o -c /Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFURLInputStream.c
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && /Users/hendrik/mingw/mingw-w32-i686/bin/i686-w64-mingw32-gcc -Wall -x c -Wno-multichar -D_JNI_IMPLEMENTATION_ -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include -I/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/javah -I/Users/hendrik/windows-jdk/include -I/Users/hendrik/windows-jdk/include/win32 -o /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/objs/FFUtils.o -c /Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFUtils.c
/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFUtils.c: In function 'encode_buffer':
/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFUtils.c:610:5: warning: 'avcodec_encode_audio2' is deprecated (declared at /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include/libavcodec/avcodec.h:5377) [-Wdeprecated-declarations]
     res = avcodec_encode_audio2(aio->encode_context, &aio->encode_packet, aio->encode_frame, &got_output);
     ^
/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFUtils.c: In function 'decode_packet':
/Users/hendrik/Projects/ffsampledsp/ffsampledsp-x86_64-darwin/src/main/c/FFUtils.c:706:9: warning: 'avcodec_decode_audio4' is deprecated (declared at /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include/libavcodec/avcodec.h:4852) [-Wdeprecated-declarations]
         bytesConsumed = avcodec_decode_audio4(aio->decode_context, aio->decode_frame, &aio->got_frame, &aio->decode_packet);
         ^
[INFO]
[INFO] --- native-maven-plugin:1.0-alpha-8:link (default-link) @ ffsampledsp-i386-mingw32 ---
[INFO] /bin/sh -c cd /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32 && /Users/hendrik/mingw/mingw-w32-i686/bin/i686-w64-mingw32-gcc -Wl,--kill-at -static-libgcc -shared -Os -s -o /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/ffsampledsp-i386-mingw32.dll target/objs/FFAudioFileReader.o target/objs/FFCodecInputStream.o target/objs/FFStreamInputStream.o target/objs/FFURLInputStream.o target/objs/FFUtils.o -L/Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/lib -lavformat -lavcodec -lavutil -lswresample -lz -lbz2 -lws2_32 -lsecur32

The directory /Users/hendrik/Projects/ffsampledsp/ffsampledsp-i386-mingw32/target/native/include contains the header files for the individual FFmpeg libs. They are automatically placed there by the native-maven-plugin plugin, because we have placed those <dependency> declarations in the pom.xml.

jonashartwig commented 7 years ago

Hi, thank you. Yes I understood that the FFMPEG headers need to be present. I am just curious about the fact that a header from the sources is needed and not from the build package ( I did not expect to build agains source, thats all ). I think I am getting close now. I am now adapting FFNativeLibraryLoader :)

hendriks73 commented 7 years ago

I am just curious about the fact that a header from the sources is needed and not from the build package ( I did not expect to build agains source, thats all ).

Hm. Yeah. Don't remember why it is needed. Have you tried simply removing #include <libswresample/swresample_internal.h> from FFUtils.h? It's entirely possible that it's just a leftover.

jonashartwig commented 7 years ago

So I followed your instructions and got everything to work :) Thanks again. A few remarks:

Thanks for the help!

jonashartwig commented 7 years ago

@hendriks73 how is your release schedule? Will you release the fix with the headers any time soon? :)

hendriks73 commented 7 years ago

There's isn't really a set schedule. Whenever there is something major, like a bug or a new FFmpeg release, I usually update.

Which header are you referring to? #include <libswresample/swresample_internal.h>?

jonashartwig commented 7 years ago

yes

hendriks73 commented 7 years ago

-> https://twitter.com/h_schreiber/status/901081005527896065

hendriks73 commented 7 years ago

Out of curiosity: Are you going to use the library in a publicly accessible application? Which one?

jonashartwig commented 7 years ago

no, currently I am working on a POC :)

hendriks73 commented 7 years ago

Good luck with that!

jonashartwig commented 7 years ago

Thanks. I will get back to you as soon I have something :)

guss77 commented 5 years ago

Hi, any chance of having the Linux support integrated into the public release?

hendriks73 commented 5 years ago

I currently build and compile the package on macOS using a cross compiler for Windows. If there was an easy to install cross compiler package for Linux (that runs on macOS), I'd love to support Linux as well, but (please correct me if I'm wrong!) as far as I know, there is no such thing.

guss77 commented 5 years ago

While not my preferred approach, you can use crosstool-ng to build for Linux, here's a tutorial: https://medium.com/coinmonks/setup-gcc-8-1-cross-compiler-toolchain-for-raspberry-pi-3-on-macos-high-sierra-cb3fc8b6443e (it demonstrates builds for ARM, but the change to build x86_64 is minimal - just choose a different platform as listed in the platform dir, and you probably want to also build for ARM as a lot of Linuxes are running on ARM these days).

That being said, why not just use a free CI such as Circle CI to build your binaries?

hendriks73 commented 2 years ago

That being said, why not just use a free CI such as Circle CI to build your binaries?

I have finally moved the build process to GitHub actions. As a result, the latest version contains an native lib compiled on Ubuntu 18. Not sure this also works on CentOS, but since it does not depend on dynamic libs, I guess it could.