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

[PAID BOUNTY] [LOCKED] Package up ffmpeg and ffprobe #8241

Closed
harry-cpp opened this issue Mar 15, 2024 · 10 comments
Closed

[PAID BOUNTY] [LOCKED] Package up ffmpeg and ffprobe #8241

harry-cpp opened this issue Mar 15, 2024 · 10 comments
Labels
Milestone

Comments

@harry-cpp
Copy link
Member

harry-cpp commented Mar 15, 2024

MonoGame needs to package up ffmpeg and ffprobe for content compilation.

📃Full details

In order to improve the maintainability of the 3rd party dependencies and tooling, we are trying to prepare the compilation and packaging for ffmpeg and ffprobe as per #8124.

Whats expected from this task is to build 3 repositories, one for shared tooling build scripts and two repositories for the ffmpeg and ffprobe executables, see "Expected delivery content*" bellow for clearer details.

The MonoGame Foundation wishes to accelerate this transition by offering a paid opportunity to undertake this task.

🔒 Bounty status

Locked for @AristurtleDev to complete. 🔒

💰 Bounty

$360,00 USD (Three hundred and sixty US dollars).

Requirements to apply

Standard requirements from our generic bounty requirements.

📦 Expected delivery content

  • MonoGame.Tool.BuildScripts repository that can be used as a shared scripts repository for all future tooling (Similary structured as MonoGame.Library.BuildScripts).
  • MonoGame.Tool.FFMpeg repository containing the packaging scripts for the ffmpeg executable. (Similary structured as MonoGame.Library.FreeType).
    • Should build the latest stable version of ffmpeg.
    • Should be packaged into a dotnet tool mgcb-ffmpeg.
    • Should upload the nuget to GitHub packages on build.
  • MonoGame.Tool.FFProbe repository containting the packaging scripts for the ffprobe executable. (Similary structured as MonoGame.Library.FreeType).
    • Should build the latest stable version of ffprobe.
    • Should be packaged into a dotnet tool mgcb-ffprobe.
    • Should upload the nuget to GitHub packages on build.
  • The C# coding style should match the standard Microsofts C# coding style guideliness.
  • The build scripts in all repository should use CAKE Frosting.
  • The CI system in all repositories should use GitHub Actions.

📅 Delivery timeline

As soon as possible.

@harry-cpp harry-cpp added this to the 3.8.2 milestone Mar 15, 2024
@harry-cpp harry-cpp changed the title [PAID BOUNTY] Package up ffmpeg and ffprobe [PAID BOUNTY] [LOCKED] Package up ffmpeg and ffprobe Mar 21, 2024
@AristurtleDev
Copy link
Contributor

Progress update on bounty

Customized compiling

I have the configuration setup to compile ffmpeg and ffprobe using only the encoders and muxers used in the MonoGame repository instead of the usual kitchen sink approach. This cuts the size of the ffmpeg binary per platform from ~30MB to ~16MB, almost a 50% reduction in distribution size for each binary.

Linux Compilation

I have a script working to build for linux-x64. This one wasn't so bad to do, it just kind of worked because Linux is Linux

Windows Compilation

Windows is a little tricker. Since this was to be setup the same way as the MonoGame.LIbrary.* repos, I assumed everything needed to be statically linked and pass the same dependency checks as the library tests. Compiling ffmpeg on windows is dumb and there is a lot of setup that needs to happen. Alternatively, there is a cross-compilation option where the WIndows executable can be built from Linux, which is far easier to setup and do, and I have compile successfully with that method.

Mac Compilation

Mac, weirdly enough, is where all of the issues are coming from. I can compile for x86_x64 on Mac, no problem. However, compiling for arm64(aarch64 ) is a bit more of an involved process and it's constantly failing. In order to ensure everything is statically linked that means all dependent libraries need to be compiled for arm64 as well. The GitHub macos-latest runner is an x86_x64 architecture, which means I have to setup llvm toolchain for compilation for every dependency that that builds up to the ffmpeg build. I've hit several roadblocks with this and it's the single cause of why this hasn't been completed yet.

TL;DR

  1. Reduced size of each platform binary by roughly 50%
  2. linux-x64, win-x64, macos-x64 build scripts pretty much done
  3. macos-arm64 is a pita and is pushing me past the initial ETA

I'm considering looking into the option of having the all binaries compiled on linux using cross platform compilation options, but need to get the setup for the mac tool chain on Linux figured out first. Doing this would significantly make things easier for all builds and then the final mac universal binary can be combined with lipo or the dotnet tool can be packaged with separate x64 and arm64 mac binaries

@Mindfulplays
Copy link
Contributor

MonoGame needs to package up ffmpeg and ffprobe for content compilation.

📃Full details

In order to improve the maintainability of the 3rd party dependencies and tooling, we are trying to prepare the compilation and packaging for ffmpeg and ffprobe as per #8124.

Whats expected from this task is to build 3 repositories, one for shared tooling build scripts and two repositories for the ffmpeg and ffprobe executables, see "Expected delivery content*" bellow for clearer details.

The MonoGame Foundation wishes to accelerate this transition by offering a paid opportunity to undertake this task.

🔒 Bounty status

Locked for @AristurtleDev to complete. 🔒

💰 Bounty

$360,00 USD (Three hundred and sixty US dollars).

Requirements to apply

Standard requirements from our generic bounty requirements.

📦 Expected delivery content

  • MonoGame.Tool.BuildScripts repository that can be used as a shared scripts repository for all future tooling (Similary structured as MonoGame.Library.BuildScripts).

  • MonoGame.Tool.FFMpeg repository containing the packaging scripts for the ffmpeg executable. (Similary structured as MonoGame.Library.FreeType).

    • Should build the latest stable version of ffmpeg.
    • Should be packaged into a dotnet tool mgcb-ffmpeg.
    • Should upload the nuget to GitHub packages on build.
  • MonoGame.Tool.FFProbe repository containting the packaging scripts for the ffprobe executable. (Similary structured as MonoGame.Library.FreeType).

    • Should build the latest stable version of ffprobe.
    • Should be packaged into a dotnet tool mgcb-ffprobe.
    • Should upload the nuget to GitHub packages on build.
  • The C# coding style should match the standard Microsofts C# coding style guideliness.

  • The build scripts in all repository should use CAKE Frosting.

  • The CI system in all repositories should use GitHub Actions.

📅 Delivery timeline

As soon as possible.

@harry-cpp What's the goal/intention behind having statically linked dependencies?

@harry-cpp
Copy link
Member Author

@harry-cpp What's the goal/intention behind having statically linked dependencies?

For the MonoGame.Library.X repos this ensures that each dependency is independent, ie. multiple dependency can use different versions of the same library that they need.

For the MonoGame.Tool.X repos, it does not need to statically link against all of its dependencies, but in that case, all the dependencies would need to be included next to the executable.

@Mindfulplays
Copy link
Contributor

Given that ffmpeg/ffprobe are in MonoGame.Tool repos, with the information you provided, I assume there is no static linking constraint for ffmpeg/ffprobe?

I understand the MonoGame.Library constraint and it makes sense.

@AristurtleDev
Copy link
Contributor

Given that ffmpeg/ffprobe are in MonoGame.Tool repos, with the information you provided, I assume there is no static linking constraint for ffmpeg/ffprobe?

I understand the MonoGame.Library constraint and it makes sense.

Even if including the dynamic linked libs used by ffmpeg along side the binaries, those libs would need to be built statically for the operating system and/or architecture of the ffmpeg binary they support correct?

So statically linking them with the binary just seemed like the appropriate thing. If this is not the case, I can switch up how the builds are working

@Mindfulplays
Copy link
Contributor

Mindfulplays commented Apr 17, 2024

Even if including the dynamic linked libs used by ffmpeg along side the binaries, those libs would need to be built statically for the operating system and/or architecture of the ffmpeg binary they support correct?

Adding all the dylibs/dlls etc in a single downloadable nuget package (i.e. provide them statically not the compile-time static link) seems like the goal? which is what I would imagine a default brew/configure scripts would do? @harry-cpp

/*
For the bounty amount/effort, it feels like a whole lot more to strive for (literal) static linking with very little (or negative) benefit IMO. Just being able to see ffmpeg/ffprobe sources in a secure / verifiable / reproducible build alone will go a long way; having them be nuget packageable/updateable is even better.
*/

@harry-cpp
Copy link
Member Author

Even if including the dynamic linked libs used by ffmpeg along side the binaries, those libs would need to be built statically for the operating system and/or architecture of the ffmpeg binary they support correct?

Yes, all the dependencies would need to be included.

@AristurtleDev
Copy link
Contributor

AristurtleDev commented Apr 17, 2024

Yes, all the dependencies would need to be included

Yea so if all dependencies would need to be included, and those dependency libs would need to be compiled as statically linked, then might as well throw in the --enable-static configure flag for ffmpeg build. Then the tool is distributing just the binaries and not thr binaries and all its dependencies

@AristurtleDev
Copy link
Contributor

AristurtleDev commented Apr 30, 2024

Bounty completed.

References

Repositories

Build Statuses with artifacts

Note

Both FFMpeg and FFProbe are built with customized flags when the ./configure script is called. Each repository has a shared config file and a platform specific config file that's used in each build. The shared config file contains all the flags used for which encoders, decoders, and muxers to include when building the binaries.

After looking through the monogame repository and speaking with harry, the build was customized to only use the encoders needed that the content pipeline used, as well as muxers, but all standard decoders are included. If additional encoders, decoders, or muxers are needed in future versions, just edit the appropriate config file for each and add the one you need. This was done in effort to reduce the total size of each binary being distributed by only including what was needed instead of the entire kitchen sink.

You can determine the flags for which ones are available by executing the ./configure script for ffmpeg with the following flags

# View available encoders
./configure --list-encoders

# View available decoders
./configure --list-decoders

# View available muxers
./configure --list-muxers

@mrhelmut
Copy link
Contributor

mrhelmut commented May 1, 2024

Good job on completing the first bounty!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants