Details
-
Suggestion
-
Resolution: Unresolved
-
Not Evaluated
-
None
-
None
-
None
Description
Provisioning scripts that install FFmpeg build it from sources each time provisioning is happening. This takes too much time and resources while provisioning and shouldn't be done in this way. Actually none of the compilation should occur during provisioning stage at all (QTQAINFRA-6249). Therefore current approach with supplying FFmpeg needs to be reworked. There're multiple solutions to this problem each with its own strengths and weaknesses.
Approach 1: Build once, upload, and reuse on subsequent builds during provisioning
This approach boils down to the change in the current provisioning scripts to something like this (pseudocode):
if (!tryDownloadPrecompiledFFmpeg()) {
compileFFmpeg()
uploadCompiledFFmpeg()
}
It's possible to implement this approach but not possible to fully automate the process. Currently there's no functionality in place to programmatically upload files. It means that it can be implemented only using manual uploads. When new version of FFmpeg is about to be used in Qt it should be compiled for each target and uploaded manually. Otherwise, some mechanism to upload files from script should be put in place (e.g. HTTP endpoint that receives files via POST request).
As a side note, other parts of provisioning can also benefit from this approach for instance gRPC which is currently compiled during provisioning too.
Testing and prechecks might be challenging with this approach because each time a built version is present it will be reused. Additional functionality is needed to take into account possible overwrites of the same version or deleting one.
Jøger: The tryDownloadPrecompiledFFmpeg() function needs ability to download the correct version. How will we know if the uploaded compiled libraries are out-of-date? The precompiled FFmpeg binaries will change depending of FFmpeg version, and the build configuration we use (configuration flags, msys version, compiler version etc), so we need to precisely identify it. I believe current provisioning use a hash over the provisioning sub-directory as an identifier. Is this how we will identify the precompiled FFmpeg? If so, we will likely rebuild FFmpeg even with unrelated changes to provisioning.
Pavel: I think we talked about using SHA1 of *.tar file that contains build artifacts.
Jøger: How will a change to any configure settings or dependencies trigger a new build?
Jimis: For that you'll have to name the file differently manually, for example ffmpeg-build_03-x86_64-mingw.tar.gz. Notice the "build_03" part, which will have to be manually increased when you change any configure settings or dependencies. Then "tryDownload()" will fail (not find the file) and a new build will be triggered.
Approach 2: Add QtFFmpeg module
Another solution would be to create a separate Qt module and make QtMultimedia depend on it. This module will contain the source code for FFmpeg (cloned FFmpeg repo that points to the specific version). Extra CMake wrapper around FFmpeg build should be created. This approach will benefit from the CI caching infrastructure i.e. it will be built once and then just copied similar to other modules. From time to time CI cache can be cleared for various reasons and this will trigger clean build for the module which is probably a good thing to have a clean fresh build from time to time even if the FFmpeg version stays the same.
When a new version of FFmpeg is needed for QtMultimedia the module will be synced with the upstream repo to the desired version.
Having FFmpeg as a part of a build step may also provide more pleasant experience in debugging and modifying it when needed.
Additional advantage is that if provided as part of Qt sources more recent version of FFmpeg can be used on embedded environments that usually come with much older versions.
Jøger: Will this be an internal implementation detail that is conceptually part of our CI infrastructure, like provisioning is today. Or is this something that users will see / be using as well?
What is the main difference to Approach 3? Is Approach 3 the same as approach 2 with the only difference that the QtFFmpeg module is linked as a submodule in QtMultimedia?
Pavel: In my understanding proposed QtFFmpeg module will be the same as any other except the codebase will be a reflection of FFmpeg repo hence it will be used by others as any other dependency module correct me if I'm wrong.
As I see it the main difference is that this approach can take advantage of already in place CI cache and do not rebuild the module most of the times. I think it's what happening currently with other modules (e.g. qtbase) if they're not changed.
Approach 3: Add FFmpeg as a submodule of QtMultimedia
This is probably the most straightforward approach. FFmpeg is a submodule of QtMultimedia (similar to Chromium and QtWebEngine).
Additional configuration option can be provided that will determine whether FFmpeg should be built as a part of QtMultimedia build step or FFmpeg that is installed in the system should be used. When building in CI it will be always built making use of build system caching (less performant than simply copying precompiled artifacts).
It has the same benefits of debugging/modifying and supplying latest versions to embedded environment as the previous approach.
Jøger: This will make the FFmpeg dependency more explicit and visible to users. This makes it more likely that users will want to build FFmpeg through this mechanism, even if there is a way to opt in/out. This can be an advantage because we give users full recipe for building FFmpeg themselves. It is also a drawback because it will complicate build environment setup, particularly on Windows. This can scare people off.
Approach 4: NuGet
Even though NuGet is quite robust and comfortable system to work with it's not adopted by Qt yet and probably it would be better to try to use something that's already in place first. Will require infrastructure to manage and build NuGet packages, as well as consuming NuGet packages in Qt.
Approach 5: vcpkg
The main problem with this package manager is that it lacks many configuration options for FFmpeg hence a lot of upstreaming would be required to make it work.
Attachments
Issue Links
- relates to
-
QTBUG-129339 Reduce time spent on FFmpeg upgrades
- Open
-
QTBUG-122745 Build ffmpeg on arm Windows on CI
- Closed