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(server): transcode bitrate and thread settings #2488
feat(server): transcode bitrate and thread settings #2488
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Ignored Deployment
|
Tagging @zackpollard since this is his baby |
Can we move this option to the setting page as well? and have it defaulted to |
web/src/lib/components/admin-page/settings/setting-input-field.svelte
Outdated
Show resolved
Hide resolved
web/src/lib/components/admin-page/settings/setting-input-field.svelte
Outdated
Show resolved
Hide resolved
server/libs/domain/src/system-config/dto/system-config-ffmpeg.dto.ts
Outdated
Show resolved
Hide resolved
….svelte Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
….svelte Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
Yup, I added it as a slider in the admin page. |
@mertalev is attempting to deploy a commit to the immich Team on Vercel. A member of the Team first needs to authorize it. |
Hi, I am a complete noob when it comes to transcoding. But as a user, I need to tweak ffmpeg settings as the defaults just did not work for me. I need smaller files so that there is no buffering in low bandwidth scenarios while finding a balance with acceptable quality. Hence, I started reading about vp9 recommendations and I realised that in Immich I cannot apply some settings that are recommended by many articles, including ffmpeg website and Google. I found this article particularly useful: https://streaminglearningcenter.com/codecs/encoding-vp9-in-ffmpeg-an-update.html#The_Recommended_Command_String I am very pleased to see this PR and thank you for solving some of these challenges. However, I feel that a couple of other options (or hardcoded defaults? for vp9) would make sense. E.g. "-row-mt 1" is highly recommended. I can also imagine that hundreds of other users may come up with hundreds of other needs. I have seen in some applications that they solve such problems by letting the users edit any ffmpeg options as they will. Maybe as an 'advanced option' on the UI? Thanks for considering my use case and ideas. Note, as per the linked article and Google's m vp9 guide (https://developers.google.com/media/vp9/settings/vod) I think that your below statement may not be fully correct because they use CRF with 2-pass encoding. But again, I am a noob, so it is very likely that I am wrong:
Thanks again! 🙏 |
Yup, this PR adds that flag for all VP9 transcodes.
You're right, VP9 allows for two-pass transcoding with constant quality based on CRF. The original PR didn't support this since the other two codecs (h264 and hevc) want bitrate ranges for two-pass encoding. That said, I later added support for VP9's CRF-based two-pass mode. The way two-pass mode works now is that if the max bitrate is 0, VP9 will use the provided CRF, else it will use the max bitrate specified. (For h264 and h265, setting the max bitrate to 0 will still disable two-pass mode even if it's enabled.) |
Thanks for the clarifications. Music to my ears. :) I am very excited to see this PR getting accepted and released.
Hmmm, I might have read that VP9 can do max bitrate AND CRF combined AND two-pass. Or have I misinterpreted something? |
According to the FFmpeg wiki, two-pass mode can be done with either bitrates or CRF, but it doesn't mention using both. Some of the commands from the Google page actually do have both bitrate ranges and CRF, but the article you shared suggests that the CRF in them was ignored (in this section). It's possible that just setting a max rate would use both, but the resources I've seen only mention that combination in the context of one-pass encoding. |
Thanks for the clarification. You are right, I think the Google page confused me. Sorry for the trouble. |
I have tested all possible combinations of
After some googling it looks like h264 doesn't support 2-pass encoding with |
Ah, my mistake. I handled that case in |
All encoding options are fine now. It is definitely a notable step for video transcoding. Thank you for the PR! |
Thanks for the detailed reviews! @brighteyed @jrasm91 @michelheusschen |
* support for two-pass transcoding * added max bitrate and thread to transcode api * admin page setting desc+bitrate and thread options * Update web/src/lib/components/admin-page/settings/setting-input-field.svelte Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Update web/src/lib/components/admin-page/settings/setting-input-field.svelte Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * two-pass slider, `crf` and `threads` as numbers * updated and added transcode tests * refactored `getFfmpegOptions` * default `threads`, `maxBitrate` now 0, more tests * vp9 constant quality mode * fixed nullable `crf` and `threads` * fixed two-pass slider, added apiproperty * optional `desc` for `SettingSelect` * disable two-pass if settings are incompatible * fixed test * transcode interface --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
Hi @mertalev, Once again, thank you for this change. The improvements are fantastic. I am doing vp9/opus transcoding and I have also noticed that only about 30-40% of my CPU capacity is utilised and meanwhile transcoding feels to take significantly slower than before. So I am trying to investigate the situation and better understand what is going on behind the scenes. My ffmpeg Immich UI settings:
Actual ffmeg paramteres while running: So, I have noticed that there is a "-cpu-used 5" parameter. Is this hardcoded? Or is this a representation of the preset that I set in the Immich UI?
Also, can you please point me in the right direction so that I can better understand the logic behind presets vs quality/deadline vs cpu-used/speed? I did some googling but could not find a source that explains it well and is trustworthy. Thanks. |
@Sherlock1979 Great questions!
If you set
The latter. The preset options map from 0-5 with Another change was to mirror H.264 and HEVC in making constant quality the default when only using CRF. Omitting Speaking of two-pass mode, I think the slower speed you noticed comes primarily from that. It just fundamentally adds a good chunk of work for each video. |
I tried with 0, 5, and 10 (I have 12 cores). Overall utilisation was below 50% in all cases.
Actually, first pass seems to be very fast so it should not have a significant impact on my overall experience. Typically first pass is done in between 1-2 minutes. |
I did some testing with FFmpeg and it seems it's a limitation of libvpx-vp9. 720p only uses up to 40% of my CPU, 1080p can reach 60%, and 4K can fully saturate it. Upon doing some research, it seems libvpx doesn't have frame-level parallelism for encoding (only decoding), so the level of parallelism you can get is limited by resolution (i.e. how many tiles the frame can be divided into). |
Hmm, given that, it might be good to make the job queue concurrency user-configurable. Encoding more than one video in parallel seems to be the only way to scale vp9 further at lower resolutions. |
Thanks for looking into it. Yes, I would love to be able to change concurrency. |
This PR allows users to set the max bitrate and thread count of transcoded videos through the admin transcoding page. This addresses two pain points with transcoding: high CPU usage and large file sizes.
Max Bitrate
This option is used for constrained quality (CQ) mode in FFmpeg. This mode respects the chosen CRF so long as it doesn't go beyond this bitrate, in which case it lowers quality dynamically. Setting an upper bound allows for predictable file sizes and prevents the issue of transcoded videos being much larger than the original.
Threads
Transcoding is naturally very CPU-intensive, and this can have an effect on other tasks and apps running on a device. Setting a thread count ensures that transcoding can only occupy a certain level of CPU resources.
However, the exact effect of this depends on the exact library used. While libvpx-vp9 respects FFmpeg's
-threads
flag, x264 and x265 create their own thread pools internally with heuristics set to max utilization. Disabling thread pooling led to a much closer relationship between-threads
and actual utilization, though there seems to be something else that isn't being affected by this option.Setting Descriptions
With the growth of the transcoding page over time, I think it's helpful to give some pointers on what these settings mean and what they can be useful for.
Extra
I also added support for two-pass transcoding, which does a fast transcode to generate statistics and uses those statistics to produce a better encoded video. CRF is ignored in this setting, and the actual quality is derived from the max bitrate set (following these recommendations). This setting is particularly good for VP9, as libvpx is optimized to take advantage of it for both quality and efficiency. The downside, of course, is that it takes more time to transcode in two passes than one.
It can be enabled by setting the environmental variable
ENABLE_TWO_PASS
totrue
.