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

feat(ffmpeg): implement new features of ffmpeg 7 #1040

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

skrashevich
Copy link
Contributor

This pull request introduces support for the new filter_threads and filter_complex_threads parameters in FFmpeg 7, specifically tailored to improve performance in the go2rtc module's handling of video streams. By leveraging enhanced multithreading capabilities, the updated integration optimizes processing speed and efficiency.

Highlights

  • Version Detection and Adaptive Configuration: Implemented FFmpeg version detection to adaptively configure processing parameters. When FFmpeg 7.0 or newer is detected, additional parameters (-filter_threads, -filter_complex_threads) are employed to improve performance without manual intervention.

  • Codebase Updates:

    • Dependency Management: Introduced the github.com/Masterminds/semver/v3 package to manage semantic versioning more effectively, aiding in the robust comparison of version strings.
    • Enhanced Logging: Improved logging capabilities to provide clearer insights into the configurations and operations, especially focusing on the adjustments made for newer FFmpeg versions.
    • Unit Tests: Expanded the unit tests to cover the new functionalities, including version comparison and CPU thread optimizations, ensuring the changes are robust and effective.

This commit introduces several enhancements to how ffmpeg arguments are generated and processed, particularly with the introduction of support for ffmpeg version 7.0 and above. Key changes include:

- Added dependency on `github.com/Masterminds/semver/v3` for semantic version comparison.
- Implemented `GetFFmpegVersion` in `pkg/ffmpeg/ffmpeg.go` to fetch the current ffmpeg version.
- Utilized `CompareVersions` from `pkg/core/helpers.go` to conditionally modify ffmpeg arguments based on the version check, specifically adding `-filter_threads` for versions 7.0+.
- Introduced `MaxCPUThreads` in `pkg/core/helpers.go` to calculate optimal thread usage, which is now used to set `filter_threads` and `filter_complex_threads` parameters dynamically.
- Added logging to report the detected ffmpeg version and modifications to default presets based on version checks.
- Included unit tests for new helper functions in `pkg/core/helpers_test.go` and `pkg/ffmpeg/ffmpeg_test.go` to ensure correctness of version comparisons and argument adjustments.

These changes aim to optimize ffmpeg performance by leveraging version-specific features and improving resource utilization based on system capabilities.
Replaced the use of github.com/Masterminds/semver/v3 with github.com/unascribed/FlexVer/go/flexver for version comparison in `CompareVersions` function within the core package. This change allows handling a broader range of version formats, including those prefixed with letters, by stripping any leading letter before performing the comparison. The update facilitates more flexible version comparison logic that can accommodate various versioning schemes beyond strict semantic versioning.

The removal of semver and introduction of FlexVer necessitated updates to both go.mod and go.sum to reflect the dependency changes. Additionally, the `CompareVersions` function has been updated to strip a leading letter from version strings if present before comparing them using flexver.Compare, enabling it to handle versions prefixed with letters indicating special version types or pre-release status.

This adjustment enhances the system's ability to compare version strings that may not strictly adhere to semantic versioning, such as those commonly found in certain projects or versioning systems, without compromising on the accuracy of comparisons for standard semantic versions.
Update `CompareVersions` function in `pkg/core/helpers.go` to use `flexver.CompareError` instead of `flexver.Compare`. This change introduces error handling for version comparison, ensuring that any errors encountered during the comparison process are gracefully handled by returning -1. Previously, the function lacked error handling, potentially leading to uncaught exceptions or inaccurate comparisons if `flexver.Compare` encountered an issue. This enhancement improves the reliability and robustness of version comparison logic within the application.
This commit introduces the inclusion of the FFmpeg version in the API response. The changes involve storing the FFmpeg version in a global variable within the application context and ensuring this version is locked alongside other information before responding to API requests. This enhancement aims to provide clients with more detailed system information, facilitating debugging and system monitoring.

- A new global variable `FFmpegVersion` is declared in `app.go`, initialized as an empty string.
- The FFmpeg version is now fetched and stored in `app.FFmpegVersion` during the initialization process in `ffmpeg.go`.
- The `apiHandler` function in `api.go` has been updated to include `app.FFmpegVersion` in its response.

This update allows clients to retrieve the FFmpeg version directly from the API, offering greater transparency regarding the server's capabilities and configurations.
This commit updates the index.html to include the FFmpeg version in the information displayed to the user. By extracting the FFmpeg version from the API response and appending it to the innerText of the `.info` element, users can now see the current FFmpeg version alongside the application version and configuration path. This enhancement improves transparency regarding the software versions being used, which can be crucial for debugging purposes or ensuring compatibility with specific media formats.
@skrashevich skrashevich changed the title Support and Enhancements for ffmpeg 7 feat(ffmpeg): implement new features of ffmpeg 7 Apr 18, 2024
@AlexxIT
Copy link
Owner

AlexxIT commented Apr 20, 2024

I think it's better to leave choosing this value to user via #raw params

@felipecrs
Copy link
Contributor

felipecrs commented Apr 20, 2024

I think shipping some free optimization for users is very nice. :)

@felipecrs
Copy link
Contributor

(Only few people understands ffmpeg args, not to mention very few people would know ffmpeg 7+ can use this optimization)

@felipecrs
Copy link
Contributor

felipecrs commented Apr 20, 2024

@skrashevich perhaps you should bump ffmpeg in dockerfile too?

@skrashevich
Copy link
Contributor Author

@skrashevich perhaps you should bump ffmpeg in dockerfile too?

It requires more careful research, as ffmpeg7 partially breaks backward compatibility.
BTW, I did it in my repository

@AlexxIT AlexxIT added the doubt label Apr 22, 2024
This commit introduces the ability to manually specify the FFmpeg version within the application's configuration, rather than solely relying on automatic detection. This enhancement facilitates greater control over the application's behavior when working with specific FFmpeg versions, especially in environments where automatic version detection might be unreliable or undesirable. Additionally, a default version ("6.0") is now set in the configuration defaults, ensuring consistent behavior across different setups.
This commit introduces the ability to manually specify the FFmpeg version within the application's configuration, rather than solely relying on automatic detection. This enhancement facilitates greater control over the application's behavior when working with specific FFmpeg versions, especially in environments where automatic version detection might be unreliable or undesirable. Additionally, a default version ("6.0") is now set in the configuration defaults, ensuring consistent behavior across different setups.
Comment on lines +36 to +40
if cfg.Mod["version"] == "6.0-default" {
app.FFmpegVersion, _ = parseArgs("").GetFFmpegVersion()
} else {
app.FFmpegVersion = cfg.Mod["version"]
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩼

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

Successfully merging this pull request may close these issues.

None yet

3 participants