JuliaIO / VideoIO.jl

Reading and writing of video files in Julia via ffmpeg
https://juliaio.github.io/VideoIO.jl/stable
Other
126 stars 53 forks source link

Cannot generate FFMPEG bindings #287

Closed galenlynch closed 2 years ago

galenlynch commented 3 years ago

It seems that the script to generate the ffmpeg bindings no longer runs, at least on Julia 1.5.2.

It seems to use the Clang.jl interface that was deprecated in their version v0.8. Unfortunately Clang.jl seems to have a bug in the v0.8 range that prevents it from loading on my machine. Trying to use earlier versions (v0.7) no longer works on my machine because it seems to use my system's clang library, which was compiled with a newer version of GLIBCXX than the libstdc++ that is shipped with Julia.

galenlynch commented 3 years ago

This also does not work with Julia 1.0.5

giordano commented 3 years ago

Trying to use earlier versions (v0.7) no longer works on my machine because it seems to use my system's clang library, which was compiled with a newer version of GLIBCXX than the libstdc++ that is shipped with Julia.

The trick is to replace julia's libstdc++ with a copy of your system's libstdc++

galenlynch commented 3 years ago

Oh ok I'll try that, thanks! I guess that doesn't break things because my system's libstdc++ is newer?

giordano commented 3 years ago

No, it shouldn't break anything. If you are unsure keep a copy of julia's libstdc++ just in case

galenlynch commented 3 years ago

Thanks!

galenlynch commented 3 years ago

That works, thanks so much! I still can't generate the bindings but it's probably due to some problem with how I'm using it.

galenlynch commented 3 years ago

I think there are other things about this gen script that are outdated for julia 1.x, which causes it to silently fail. For example the clang_includes variable seems to point to an includes directory that is no longer shipped with Julia, from what I can tell. It's probably easy enough to fix that to point to a system include directory, but it might be indicative of other lurking problems.

galenlynch commented 3 years ago

It seems like the core issue is that VideoIO's init no longer finds and initializes the system's ffmpeg .so's, because VideoIO relies on the library provided by FFMPEG.jl. This causes some functions that the build script relies on to not be available, and will also create a real potential for mismatch between the system library being wrapped and the e.g. verision data provided by FFMPEG.jl's shipped library.

giordano commented 3 years ago

. This causes some functions that the build script relies on to not be available, and will also create a real potential for mismatch between the system library being wrapped and the e.g. verision data provided by FFMPEG.jl's shipped library.

Why using system libraries and not FFMPEG_jll directly?

galenlynch commented 3 years ago

My impression (from #282 and looking at the script) is that the script that generates the Julia bindings to the libav libraries was made when VideoIO still used system libraries, instead of FFMPEG_jll. It seems to expect access to the headers (which are not present in FFMPEG_jll, AFAIK). I think any Clang.jl based approach to generating the bindings will need access to the headers.

I was just trying to run the gen script using the system libraries, but realized that because VideoIO has changed how it finds the libav libraries since the gen script was last run, that it probably won't work.

giordano commented 3 years ago

It seems to expect access to the headers (which are not present in FFMPEG_jll, AFAIK)

Uh?

shell> tree $(joinpath(FFMPEG_jll.artifact_dir, "include"))
/home/mose/.julia/artifacts/7f40eeb66d90d3026ae5fb68761c263b57adb840/include
├── libavcodec
│   ├── ac3_parser.h
│   ├── adts_parser.h
│   ├── avcodec.h
│   ├── avdct.h
│   ├── avfft.h
│   ├── bsf.h
│   ├── codec_desc.h
│   ├── codec.h
│   ├── codec_id.h
│   ├── codec_par.h
│   ├── d3d11va.h
│   ├── dirac.h
│   ├── dv_profile.h
│   ├── dxva2.h
│   ├── jni.h
│   ├── mediacodec.h
│   ├── packet.h
│   ├── qsv.h
│   ├── vaapi.h
│   ├── vdpau.h
│   ├── version.h
│   ├── videotoolbox.h
│   ├── vorbis_parser.h
│   └── xvmc.h
├── libavdevice
│   ├── avdevice.h
│   └── version.h
├── libavfilter
│   ├── avfilter.h
│   ├── buffersink.h
│   ├── buffersrc.h
│   └── version.h
├── libavformat
│   ├── avformat.h
│   ├── avio.h
│   └── version.h
├── libavresample
│   ├── avresample.h
│   └── version.h
├── libavutil
│   ├── adler32.h
│   ├── aes_ctr.h
│   ├── aes.h
│   ├── attributes.h
│   ├── audio_fifo.h
│   ├── avassert.h
│   ├── avconfig.h
│   ├── avstring.h
│   ├── avutil.h
│   ├── base64.h
│   ├── blowfish.h
│   ├── bprint.h
│   ├── bswap.h
│   ├── buffer.h
│   ├── camellia.h
│   ├── cast5.h
│   ├── channel_layout.h
│   ├── common.h
│   ├── cpu.h
│   ├── crc.h
│   ├── des.h
│   ├── dict.h
│   ├── display.h
│   ├── dovi_meta.h
│   ├── downmix_info.h
│   ├── encryption_info.h
│   ├── error.h
│   ├── eval.h
│   ├── ffversion.h
│   ├── fifo.h
│   ├── file.h
│   ├── frame.h
│   ├── hash.h
│   ├── hdr_dynamic_metadata.h
│   ├── hmac.h
│   ├── hwcontext_cuda.h
│   ├── hwcontext_d3d11va.h
│   ├── hwcontext_drm.h
│   ├── hwcontext_dxva2.h
│   ├── hwcontext.h
│   ├── hwcontext_mediacodec.h
│   ├── hwcontext_opencl.h
│   ├── hwcontext_qsv.h
│   ├── hwcontext_vaapi.h
│   ├── hwcontext_vdpau.h
│   ├── hwcontext_videotoolbox.h
│   ├── hwcontext_vulkan.h
│   ├── imgutils.h
│   ├── intfloat.h
│   ├── intreadwrite.h
│   ├── lfg.h
│   ├── log.h
│   ├── lzo.h
│   ├── macros.h
│   ├── mastering_display_metadata.h
│   ├── mathematics.h
│   ├── md5.h
│   ├── mem.h
│   ├── motion_vector.h
│   ├── murmur3.h
│   ├── opt.h
│   ├── parseutils.h
│   ├── pixdesc.h
│   ├── pixelutils.h
│   ├── pixfmt.h
│   ├── random_seed.h
│   ├── rational.h
│   ├── rc4.h
│   ├── replaygain.h
│   ├── ripemd.h
│   ├── samplefmt.h
│   ├── sha512.h
│   ├── sha.h
│   ├── spherical.h
│   ├── stereo3d.h
│   ├── tea.h
│   ├── threadmessage.h
│   ├── timecode.h
│   ├── time.h
│   ├── timestamp.h
│   ├── tree.h
│   ├── twofish.h
│   ├── tx.h
│   ├── version.h
│   ├── video_enc_params.h
│   └── xtea.h
├── libpostproc
│   ├── postprocess.h
│   └── version.h
├── libswresample
│   ├── swresample.h
│   └── version.h
└── libswscale
    ├── swscale.h
    └── version.h

9 directories, 127 files
galenlynch commented 3 years ago

Ah, my bad! So then the gen script should just be changed to use FFMPEG_jll

IanButterworth commented 3 years ago

If it's any help, that's how PNGFiles wraps libpng https://github.com/JuliaIO/PNGFiles.jl/blob/master/gen/libpng/wrap_libpng.jl

galenlynch commented 3 years ago

I got it working by copying the example on Clang.jl's readme, though it turns out the struct I was looking for is intentionally private in FFMPEG's API.