"Auto" encoding present always defaults to veryfast for QSV hardware encoding #6687

Closed
opened 2026-02-07 03:59:16 +03:00 by OVERLORD · 2 comments
Owner

Originally created by @alechouse97 on GitHub (Jan 26, 2025).

Description of the bug

I've been playing with the QSV hardware encoding options and have discovered that, when setting Encoding preset to Auto, the veryfast preset is always chosen, even when a much slower preset would be able to exceed the required framerate. This has persisted across multiple

The logs below show an example where veryfast is selected and the transcoding framerate is > 200 fps. I then set the preset to slower, and the framerate was ~35 fps, still greater than the 24 fps playback. This has persisted across multiple titles with different encodings and bitrates.

How does jellyfin decide on the encoding preset when auto is selected? Is it based on hardware or the title being played?

I searched a little bit, and it looks like it might always be set to veryfast unless otherwise specified? This starts on line 1498 of jellyfin/MediaBrowser.Controller/MediaEncoding//EncodingHelper.cs

            else if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) // h264 (h264_qsv)
                     || string.Equals(videoEncoder, "hevc_qsv", StringComparison.OrdinalIgnoreCase) // hevc (hevc_qsv)
                     || string.Equals(videoEncoder, "av1_qsv", StringComparison.OrdinalIgnoreCase)) // av1 (av1_qsv)
            {
                EncoderPreset[] valid_presets = [EncoderPreset.veryslow, EncoderPreset.slower, EncoderPreset.slow, EncoderPreset.medium, EncoderPreset.fast, EncoderPreset.faster, EncoderPreset.veryfast];

                param += " -preset " + (valid_presets.Contains(encoderPreset) ? encoderPreset : EncoderPreset.veryfast).ToString().ToLowerInvariant();
            }

Reproduction steps

  1. Enable QSV hardware encoding
  2. Set encoding preset to auto
  3. Play a video that requires transcoding
  4. Note preset in ffmpeg log

What is the current bug behavior?

ffmpeg encoding preset always set to veryfast when using hevc_qsv

What is the expected correct behavior?

I would expect jellyfin to select the slowest preset that can still maintain the target framerate (perhaps with some safety factor).

Jellyfin Server version

10.10.0+

Specify commit id

No response

Specify unstable release number

No response

Specify version number

No response

Specify the build version

10.10.5

Environment

- OS: Ubuntu 24.04.1 LTS
- Linux Kernel: 6.8.0-51-generic
- Virtualization: Docker
- Clients: Android TV
- Browser: Firefox
- FFmpeg Version: 7.0.2-Jellyfin
- Playback Method: Transcode
- Hardware Acceleration: QSV
- GPU Model: UHD 630
- Storage: local

Jellyfin logs

[2025-01-26 00:01:03.616 +00:00] [INF] [47] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.0.8" request
[2025-01-26 00:01:05.910 +00:00] [INF] [43] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "alec". EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[2025-01-26 00:01:06.378 +00:00] [INF] [41] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2025-01-26 00:01:06.399 +00:00] [INF] [41] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -f matroska -init_hw_device vaapi=va:,vendor_id=0x8086,driver=iHD -init_hw_device qsv=qs@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:\"/media/drive2/movies/The Lord of the Rings - The Fellowship of the Ring (2001)/The Lord of the Rings - The Fellowship of the Ring (2001).mkv\" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_qsv -preset veryfast -b:v 29270902 -maxrate 29270902 -bufsize 58541804 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12:extra_hw_frames=24,hwmap=derive_device=qsv,format=qsv\" -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename \"7b61427505cbf924aed0007c91a07b21-1.mp4\" -start_number 0 -hls_segment_filename \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8\""
[2025-01-26 00:01:07.547 +00:00] [INF] [42] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8"
[2025-01-26 00:01:07.990 +00:00] [INF] [42] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0
[2025-01-26 00:01:07.992 +00:00] [INF] [42] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2025-01-26 00:01:07.993 +00:00] [INF] [42] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -ss 01:35:39.000 -noaccurate_seek -f matroska -init_hw_device vaapi=va:,vendor_id=0x8086,driver=iHD -init_hw_device qsv=qs@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:\"/media/drive2/movies/The Lord of the Rings - The Fellowship of the Ring (2001)/The Lord of the Rings - The Fellowship of the Ring (2001).mkv\" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_qsv -preset veryfast -b:v 29270902 -maxrate 29270902 -bufsize 58541804 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12:extra_hw_frames=24,hwmap=derive_device=qsv,format=qsv\" -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename \"7b61427505cbf924aed0007c91a07b21-1.mp4\" -start_number 1913 -hls_segment_filename \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8\""
[2025-01-26 00:01:34.469 +00:00] [INF] [42] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.0.8" closed
[2025-01-26 00:02:31.489 +00:00] [INF] [15] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: Transcoding kill timer stopped for JobId "0b65a6adfff94c3d837a8828ac791403" PlaySessionId "c57116b2ef8947e987e5f181c612e928". Killing transcoding
[2025-01-26 00:02:31.489 +00:00] [INF] [15] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8"
[2025-01-26 00:02:31.611 +00:00] [INF] [15] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0
[2025-01-26 00:02:31.612 +00:00] [INF] [15] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: Deleting partial stream file(s) "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8"

FFmpeg logs

/usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -ss 01:35:39.000 -noaccurate_seek -f matroska -init_hw_device vaapi=va:,vendor_id=0x8086,driver=iHD -init_hw_device qsv=qs@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:"/media/drive2/movies/The Lord of the Rings - The Fellowship of the Ring (2001)/The Lord of the Rings - The Fellowship of the Ring (2001).mkv" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_qsv -preset veryfast -b:v 29270902 -maxrate 29270902 -bufsize 58541804 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12:extra_hw_frames=24,hwmap=derive_device=qsv,format=qsv" -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename "7b61427505cbf924aed0007c91a07b21-1.mp4" -start_number 1913 -hls_segment_filename "/cache/transcodes/7b61427505cbf924aed0007c91a07b21%d.mp4" -hls_playlist_type vod -hls_list_size 0 -y "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8"

Client / Browser logs

No response

Relevant screenshots or videos

No response

Additional information

No response

Originally created by @alechouse97 on GitHub (Jan 26, 2025). ### Description of the bug I've been playing with the QSV hardware encoding options and have discovered that, when setting `Encoding preset` to `Auto`, the `veryfast` preset is always chosen, even when a much slower preset would be able to exceed the required framerate. This has persisted across multiple The logs below show an example where `veryfast` is selected and the transcoding framerate is > 200 fps. I then set the preset to `slower`, and the framerate was ~35 fps, still greater than the 24 fps playback. This has persisted across multiple titles with different encodings and bitrates. How does jellyfin decide on the encoding preset when `auto` is selected? Is it based on hardware or the title being played? I searched a little bit, and it looks like it might always be set to `veryfast` unless otherwise specified? This starts on line 1498 of `jellyfin/MediaBrowser.Controller/MediaEncoding//EncodingHelper.cs` ```cs else if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) // h264 (h264_qsv) || string.Equals(videoEncoder, "hevc_qsv", StringComparison.OrdinalIgnoreCase) // hevc (hevc_qsv) || string.Equals(videoEncoder, "av1_qsv", StringComparison.OrdinalIgnoreCase)) // av1 (av1_qsv) { EncoderPreset[] valid_presets = [EncoderPreset.veryslow, EncoderPreset.slower, EncoderPreset.slow, EncoderPreset.medium, EncoderPreset.fast, EncoderPreset.faster, EncoderPreset.veryfast]; param += " -preset " + (valid_presets.Contains(encoderPreset) ? encoderPreset : EncoderPreset.veryfast).ToString().ToLowerInvariant(); } ``` ### Reproduction steps 1. Enable QSV hardware encoding 2. Set encoding preset to auto 3. Play a video that requires transcoding 4. Note preset in ffmpeg log ### What is the current _bug_ behavior? ffmpeg encoding preset always set to `veryfast` when using `hevc_qsv` ### What is the expected _correct_ behavior? I would expect jellyfin to select the slowest preset that can still maintain the target framerate (perhaps with some safety factor). ### Jellyfin Server version 10.10.0+ ### Specify commit id _No response_ ### Specify unstable release number _No response_ ### Specify version number _No response_ ### Specify the build version 10.10.5 ### Environment ```markdown - OS: Ubuntu 24.04.1 LTS - Linux Kernel: 6.8.0-51-generic - Virtualization: Docker - Clients: Android TV - Browser: Firefox - FFmpeg Version: 7.0.2-Jellyfin - Playback Method: Transcode - Hardware Acceleration: QSV - GPU Model: UHD 630 - Storage: local ``` ### Jellyfin logs ```shell [2025-01-26 00:01:03.616 +00:00] [INF] [47] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.0.8" request [2025-01-26 00:01:05.910 +00:00] [INF] [43] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "alec". EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True [2025-01-26 00:01:06.378 +00:00] [INF] [41] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request [2025-01-26 00:01:06.399 +00:00] [INF] [41] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -f matroska -init_hw_device vaapi=va:,vendor_id=0x8086,driver=iHD -init_hw_device qsv=qs@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:\"/media/drive2/movies/The Lord of the Rings - The Fellowship of the Ring (2001)/The Lord of the Rings - The Fellowship of the Ring (2001).mkv\" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_qsv -preset veryfast -b:v 29270902 -maxrate 29270902 -bufsize 58541804 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12:extra_hw_frames=24,hwmap=derive_device=qsv,format=qsv\" -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename \"7b61427505cbf924aed0007c91a07b21-1.mp4\" -start_number 0 -hls_segment_filename \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8\"" [2025-01-26 00:01:07.547 +00:00] [INF] [42] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8" [2025-01-26 00:01:07.990 +00:00] [INF] [42] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0 [2025-01-26 00:01:07.992 +00:00] [INF] [42] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request [2025-01-26 00:01:07.993 +00:00] [INF] [42] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -ss 01:35:39.000 -noaccurate_seek -f matroska -init_hw_device vaapi=va:,vendor_id=0x8086,driver=iHD -init_hw_device qsv=qs@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:\"/media/drive2/movies/The Lord of the Rings - The Fellowship of the Ring (2001)/The Lord of the Rings - The Fellowship of the Ring (2001).mkv\" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_qsv -preset veryfast -b:v 29270902 -maxrate 29270902 -bufsize 58541804 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12:extra_hw_frames=24,hwmap=derive_device=qsv,format=qsv\" -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename \"7b61427505cbf924aed0007c91a07b21-1.mp4\" -start_number 1913 -hls_segment_filename \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8\"" [2025-01-26 00:01:34.469 +00:00] [INF] [42] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.0.8" closed [2025-01-26 00:02:31.489 +00:00] [INF] [15] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: Transcoding kill timer stopped for JobId "0b65a6adfff94c3d837a8828ac791403" PlaySessionId "c57116b2ef8947e987e5f181c612e928". Killing transcoding [2025-01-26 00:02:31.489 +00:00] [INF] [15] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8" [2025-01-26 00:02:31.611 +00:00] [INF] [15] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0 [2025-01-26 00:02:31.612 +00:00] [INF] [15] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: Deleting partial stream file(s) "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8" ``` ### FFmpeg logs ```shell /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -ss 01:35:39.000 -noaccurate_seek -f matroska -init_hw_device vaapi=va:,vendor_id=0x8086,driver=iHD -init_hw_device qsv=qs@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:"/media/drive2/movies/The Lord of the Rings - The Fellowship of the Ring (2001)/The Lord of the Rings - The Fellowship of the Ring (2001).mkv" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_qsv -preset veryfast -b:v 29270902 -maxrate 29270902 -bufsize 58541804 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12:extra_hw_frames=24,hwmap=derive_device=qsv,format=qsv" -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename "7b61427505cbf924aed0007c91a07b21-1.mp4" -start_number 1913 -hls_segment_filename "/cache/transcodes/7b61427505cbf924aed0007c91a07b21%d.mp4" -hls_playlist_type vod -hls_list_size 0 -y "/cache/transcodes/7b61427505cbf924aed0007c91a07b21.m3u8" ``` ### Client / Browser logs _No response_ ### Relevant screenshots or videos _No response_ ### Additional information _No response_
OVERLORD added the bug label 2026-02-07 03:59:16 +03:00
Author
Owner

@felix920506 commented on GitHub (Jan 26, 2025):

working as intended.

@felix920506 commented on GitHub (Jan 26, 2025): working as intended.
Author
Owner

@alechouse97 commented on GitHub (Jan 26, 2025):

@felix920506 - could you provide some more information on what the Auto option does?

@alechouse97 commented on GitHub (Jan 26, 2025): @felix920506 - could you provide some more information on what the `Auto` option does?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#6687