-
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
fix: prevent choppy qsv transcodes with vfr content #25905
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
base: main
Are you sure you want to change the base?
Conversation
|
Label error. Requires exactly 1 of: changelog:.*. Found: 🗄️server. A maintainer will add the required label. |
|
Hmm, forcing the transcode to a constant frame rate doesn't seem ideal. Does vfr work? |
|
I tried that first, it didn't unfortunately |
|
Disabling bframes also helped before, but in my mind the cfr change was better as I didn't really understand why disabling bframes helped and if the fix was specific to qsv. Maybe that's not the case |
|
I looked into this a bit more and disabling bframes isn't a fix. It definitely makes things a lot better but there's still issues playing some transcodes. I'll keep looking into this, from what I've read online people have pretty strong opinions that cfr isn't a great thing to use I just haven't found a better solution (This is immich v2.5.5 with bframes disabled) Here are the PTS timestamps from the original |
|
Does adding |
|
Aha, I think Unfortunately +igndts did not change anything. I tested with |
This comment has been minimized.
This comment has been minimized.
|
Setting fps_mode=vfr is probably fine. B-frames can be disabled by default for QSV (with a comment explaining why), but you should be able to set them as normal. |
Description
Fixes #8657
Possibly #21484
Disclaimer: I am far from an expert in ffmpeg, hw stacks, etc. This is just an issue that's been bothering me and I took a stab at fixing it. let me know if it's completely off base!
HW Transcoding (QSV specifically for me) on some videos (newer iPhone vids that use variable fps are particularly bad) produces an extremely choppy video across all clients I tried (firefox/chrome, iOS app, immich-gallery on tvOS). For some reason the hw encode/decode paths on these videos produce outputs with out-of-order or nearly identical timestamps. Swapping the
-fps_modearg frompassthroughtocfr(constant frame rate) works around this by forcing ffmpeg to interpolate or duplicate frames as needed to output a vid at the specified fps. The trade-off is potential for frame duplication/dropping to enforce CFR.NOTE: it's possible to just set CFR and ffmpeg will match the original's framerate, but for videos with variable frame rates this can cause the transcode to be much larger than it needs to be. For example, in the video below the frame rate is spec'd at 120 but the average frame rate is about 29 (3597000/123509). It makes more sense to me to use the average framerate for a lossy transcode.
Alternate solutions: In my testing disabling B-frames also helped the choppiness. I feel setting
cfris a more complete fix, however.This example vid was filmed on an iphone 13. I cut it to 10 seconds and removed the location metadata. It's too big to upload straight to github unfortunately.
original.mov
Here are the timestamps:
Before, immich would invoke this ffmpeg command to transcode:
Which produced this choppy output
https://github.com/user-attachments/assets/8c0494ff-7bf6-4fd9-99a1-48019d958f5e
And has some frames out of order along with 5 crammed into just 0.0003s
After the change to use
cfrthe ffmpeg command becomesThe encoded vid is no longer choppy
https://github.com/user-attachments/assets/82d5c6f4-658c-49d5-bbcf-c39586483be2
And the timestamps are normal-looking
How Has This Been Tested?
docker.io/ant385525/immich-server:cfr-fixand retranscoded my library, verified all videos play wellScreenshots (if appropriate)
Checklist:
src/services/uses repositories implementations for database calls, filesystem operations, etc.src/repositories/is pretty basic/simple and does not have any immich specific logic (that belongs insrc/services/)Please describe to which degree, if any, an LLM was used in creating this pull request.
Used claude code to debug the video files and parse ffprobe/ffmpeg output. Impl logic is my own