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

Community sourced tested version and config list, Clarification on compile settings and generation instructions #244

Closed
wants to merge 1 commit into from

Conversation

FrostKiwi
Copy link

@FrostKiwi FrostKiwi commented Mar 15, 2023

I need to generate C# bindings for a custom ffmpeg build. I try to document the changes here in this PR and merge it into FFmpeg.AutoGen's official docs to make it less confusing for people trying to do the same.
I haven't yet managed to create bindings, but want to nail down and correct concrete facts in my journey whilst doing so. Even though it is still a draft, I still created this PR, as I would love some help to nail down the facts.
Added Documentation is:

Clarification regarding ffmpeg versions

  • As of time of writing, FFmpeg 5.1 is supported, whilst FFmpeg 6.0 is not. Versions older or in-between may or may not be supported. Check and contribute to the table below to keep track of the version used.

Clarification regarding VisualStudio versions

  • Visual Studio 2022 with C# and C++ desktop development workloads and Windows SDK for desktop. Older Visual Studio versions are not supported in the master branch and require minor modification of the project file to do so.

Clarification regarding VisualStudio settings

My current understanding and complete and utter guess as to how Generation vs Inclusion of bindings works in terms of platform settings. Hope to confirm this this week.

  • Just for clarification: Only FFmpeg.AutoGen.CppSharpUnsafeGenerator needs to run in a specific architecture. The bindings may be used in your project as as AnyCPU or another architecture. However, the bindings won't be valid, even if paired with a .dll of the correct platform. Bindings need to be regenerated per platform and included per-platform with program logic to switch between them with an AnyCPU build is desired.

A community sourced list of ffmpeg configs confirmed to work (Haven't managed yet to confirm this ffmpeg config I have used so far in my C projects...)

As build via the https://git.ffmpeg.org/ffmpeg.git repo and the relevant FFmpeg build docs

Commit or Tag Platform Configure Settings Comments / Config intention
n5.1 x86_64
Configure Flags used./configure --disable-nvenc --enable-shared --disable-nvdec --enable-gpl --enable-stripping --disable-vulkan --disable-sdl2 --disable-securetransport --disable-swresample --disable-swscale --disable-avfilter --disable-network --disable-doc --disable-programs --disable-d3d11va --disable-cuda-llvm --disable-dxva2 --disable-schannel --disable-mediafoundation --disable-postproc --disable-avdevice --disable-encoders --disable-hwaccels --disable-muxers --disable-parsers --disable-bsfs --disable-indevs --disable-outdevs --disable-devices --disable-filters --disable-decoders --enable-decoder=h264 --disable-protocols --enable-protocol=file --disable-demuxers --enable-demuxer=mov --enable-demuxer=h264 --enable-demuxer=m4v
Minimal build and config flags to software decode a soundless H.264 steam of a .mov file and nothing else. Total size: 10Mb

@FrostKiwi
Copy link
Author

FrostKiwi commented Mar 18, 2023

Once I managed to solve #250 I will finish this PR, including a detailed step-by-step to generate a minimal build with settings written down under the Confirmed and tested FFmpeg versions and configure options table

@Ruslan-B
Copy link
Owner

personal experience, I do appreciate but out of scope

@Ruslan-B Ruslan-B closed this Mar 27, 2023
@FrostKiwi
Copy link
Author

personal experience, I do appreciate but out of scope

Ohh, I thought it might be useful to others, now that I finally figured out how to compile custom and small FFmpeg version and the .configure settings required. But I see this is out of scope and would become more of a blog post / Tutorial. Thx for clarifying.

@Ruslan-B
Copy link
Owner

I am not closing anything I didn't got a value lets talk

@Ruslan-B Ruslan-B reopened this Mar 27, 2023
@Ruslan-B
Copy link
Owner

However, my aim is simple to generate bindings to any available path of execution of FFmpeg, dynamic nature helps

@Ruslan-B
Copy link
Owner

besides we do support 6.0 now which appears to be minor - 5.x gave much more problems

@Ruslan-B
Copy link
Owner

so in general I don't like fluctuations you involving here - please try to explain why it should be part of this repo history,

@Ruslan-B Ruslan-B closed this Mar 27, 2023
@FrostKiwi
Copy link
Author

so in general I don't like fluctuations you involving here - please try to explain why it should be part of this repo history,

It doesn't need to be. Just thought a tutorial might be useful to explain how to compile your own minimal FFmpeg, Build new AutoGen bindings and ship everything. But I see my approach doesn't fit this repo. I'm just super happy to have a custom FFmpeg consisting of only 3 .dlls (avcodec, avformat, avutil), everything is sub 2.5MBs and works. But that also requires you to comment out the files you don't need in FunctionResolverBase.cs, so maybe you are right, all this just doesn't belong in this repo.

@Ruslan-B
Copy link
Owner

intresting, never thought it is possible - except GPL part of ffmpeg

@FrostKiwi
Copy link
Author

intresting, never thought it is possible - except GPL part of ffmpeg

You can totally include or exclude any function you want using the configure script. Networking Streaming On Off, MP3 encoding On oFF, JPEG Decoding on off, color filters on off, a huge list of options. It just took me forever to figure out how to make sure everything is compiled into those DLLs, so you don't need to supply additional dependencies and this explanation with a list of "tested versions" is what I wanted this PR to be.

My config is for exporting an H.264 video, someone else might only need importing mjpeg Webcam streams, everyone can contribute their configure script settings.

That was the initial idea I had.

@Ruslan-B
Copy link
Owner

My way of saying thing might look rude - but I am just trying to be protective - be not offended. By itself project is complex enough.
We have sort of wiki here - but again I have limited time to keep everything update.
As for some folks here having hardware --disable-hwaccels --disable-muxers not an option.
This is my concern.

@Ruslan-B
Copy link
Owner

So my thinking to keep at least FFmpeg building process outside - it is easy to include GPL code for example by skipping a flag.
We tried in the past to complement this repo with native binaries - it did not work out.
Speaking it, you compiled it one of the first times and it was depended on the environment. 🤣
Took me a bit of time to figure out what was wrong.

@FrostKiwi
Copy link
Author

My way of saying thing might look rude - but I am just trying to be protective

Didn't take it as rude at all^^

As for some folks here having hardware --disable-hwaccels --disable-muxers not an option. This is my concern.

That's why I added the Comments / Config intention column. E.g. The config I created and confirmed working with FFmpeg.AutoGEN for my current project:

Tested Commit or Tag Platform Configure Settings Comments / Config intention
n5.1 and n6.0 x86 32-bit
Configure Flags used../configure --arch=x86 --cpu=i686 --disable-encoders --disable-demuxers --disable-parsers --enable-encoder=libx264 --disable-muxers --enable-muxer=h264 --disable-protocols --enable-protocol=file --disable-avfilter --disable-bsfs --disable-avdevice --disable-network --disable-ffprobe --disable-ffplay --disable-swscale --disable-postproc --disable-swresample --pkg-config-flags="--static" --disable-doc --prefix=installed --enable-shared --disable-static --disable-vulkan --enable-libx264 --enable-gpl --disable-autodetect --disable-indevs --disable-decoders --extra-ldflags="-static -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread"
Minimal config to only output one *.h264 file without sound via libx264. Only avcodec.dll, avformat.dll, avutil.dll (Other files non output, so they need to be commented out in FunctionResolverBase.cs) Total Size: 3.2MB

Probably smarter to use just use --disable-everything and just enable the things I need, since that config is long, as I disabled everything unneeded step-by-step...

@Ruslan-B
Copy link
Owner

Let's make a wiki page https://github.com/Ruslan-B/FFmpeg.AutoGen/wiki I think it would be better.

@zgabi
Copy link
Contributor

zgabi commented Mar 30, 2023

I'm also interested in it, since 15% of our applicaion is the FFmpeg. It is not a priority for us, but it would be good to make it smaller. (But hw acceleration is needed)

Why is it needed to modify the FunctionResolverBase.cs? What happens if it is not modified, but the functions are not used?

@FrostKiwi
Copy link
Author

FrostKiwi commented Mar 30, 2023

@zgabi

I'm also interested in it, since 15% of our applicaion is the FFmpeg. It is not a priority for us, but it would be good to make it smaller. (But hw acceleration is needed)

Why is it needed to modify the FunctionResolverBase.cs? What happens if it is not modified, but the functions are not used?

Which dlls FFmpeg.AutoGen expects is hardcoded here.
It expects 8 .dlls: avdevice avfilter avformat avutil postproc swresample swscale.
However, if you only want to encode or decode videos, you only need 3: avcodec avformat avutil

Some other feature-sets may require more or less. If you let FFmpeg.AutoGen generate bindings with the hardcoded 8 .dlls however, you will get an exception for those files missing, even though they are not required and never called. That's why you need to delete the lines corresponding to the files you don't need. I guess for hardware decode / encode avdevice is needed. And if only hardware decode/encode is needed, I theorize you can drop avcodec all together, but that's just a guess. Just go wild disabling things in the configure script of FFmpeg until something breaks...

The biggest drop in size comes from disabling codecs (eg. AV1, HEVC), networking and streaming features, Dropping all Image Encoding and Decoding (eg. JPEG, PNG) etc, Sound encoding, decoding (eg. FLAC, mp3, opus) and all the different editing features, like resizing, color correction etc.

Apparently there is also a way to statically compile(?), which may side-step all of this, but I have never done this in C#. In C I am used to statically compiling FFmpeg and with LTO turned on. It automatically only pulls in what it needs, which can end up being less than 1 megabyte for uses cases like just decoding one type of video without sound. But for C# I don't know how this works, so I just supply minimal .dlls for my project for now...

@Ruslan-B
Copy link
Owner

Ruslan-B commented Apr 2, 2023

Apparently there is also a way to statically compile

I guess this option is available only for OS X and iOS. Apple has (or had) strict rules with respect to JIT compilation.

@Ruslan-B
Copy link
Owner

Ruslan-B commented Apr 2, 2023

If there is an appetite for something that in size less than 700 KB, lets convert this PR to an issue.
We can discuss it there. Right now it generation includes everything all community requested.
Personally I think 700 KB is ok but how many users that many opinions and use cases.

@Ruslan-B
Copy link
Owner

Ruslan-B commented Apr 2, 2023

FFmpeg.AutoGen.Abstractions + FFmpeg.AutoGen.Bindings.DynamicallyLinked - it is around 450KB in binaries if you drop the rest
in case of .net core 3 and above behaves same if you complement it with native resolver

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

Successfully merging this pull request may close these issues.

3 participants