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

Add more separate hardware decoding toggles, support videotoolbox #2809

Merged
merged 24 commits into from
Jun 16, 2020

Conversation

nyanmisaka
Copy link
Member

Changes

  • Allow users to customize whether to use the hardware decoder in a specific format when using VAAPI or AMF.

  • Allow hardware decoding to be turned off when transcoding HEVC or VP9 10-Bit videos. (Especially for older GPUs that do not support 10-Bit decoding)

  • Provide support for VP9/VP8 QSV decoder and VP9/VP8 NVDEC decoder coming in FFmpeg 4.3 in the future.

  • Continue to fix errors encountered in UTF-16 format SRT subtitles. (see 2503)

  • Completing some unlisted codecs that should be supported.

toggles

@Artiume
Copy link
Contributor

Artiume commented Apr 15, 2020

I can't remember, but I believe that there were some situations where 10bit h264 isn't hw supported either. Should we expand the 10bit toggle to include it?

I've been working with #2873 I think it might benefit from this PR. The i3 cpu seems to be missing some hw profiles.

@nyanmisaka
Copy link
Member Author

I can't remember, but I believe that there were some situations where 10bit h264 isn't hw supported either. Should we expand the 10bit toggle to include it?

I've been working with #2873 I think it might benefit from this PR. The i3 cpu seems to be missing some hw profiles.

Currently, only HEVC/VP9 may have a 10-bit hardware decoder. Therefore, in addition to these two formats, a software decoder should be used when encountering 10-bit video.

https://github.com/jellyfin/jellyfin/blob/a388d5dd72893fa0a4e30472bd1d5fc8854ad51d/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs#L2550#L2556

@nyanmisaka nyanmisaka requested a review from a team April 20, 2020 06:22
@JustAMan
Copy link
Contributor

I'll review shortly, but otherwise I find this approach a bit wrong. I mean, we should be able to do a few tests on the real HW to determine which ticks work and which don't automatically. So the ticks should be for overriding when stuff works but with some glitches.

That's just me thinking out loud, though, not a blocker for this PR (and not to be addressed here).

Copy link
Contributor

@JustAMan JustAMan left a comment

Choose a reason for hiding this comment

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

I'm not so sure about blanket "enable/disable 10-bit HW support", what if chip can decode 10-bit HEVC but cannot do 10-bit VP9?..

@JustAMan
Copy link
Contributor

@nyanmisaka is there a companion PR for jf-web to add the checkbox and localisation?

@nyanmisaka
Copy link
Member Author

@nyanmisaka is there a companion PR for jf-web to add the checkbox and localisation?

jellyfin/jellyfin-web#1046

@nyanmisaka
Copy link
Member Author

I'm not so sure about blanket "enable/disable 10-bit HW support", what if chip can decode 10-bit HEVC but cannot do 10-bit VP9?..

This may indeed happen. So I need to add another toggle to distinguish them. Or is there any other good way?

@nyanmisaka
Copy link
Member Author

I'll review shortly, but otherwise I find this approach a bit wrong. I mean, we should be able to do a few tests on the real HW to determine which ticks work and which don't automatically. So the ticks should be for overriding when stuff works but with some glitches.

That's just me thinking out loud, though, not a blocker for this PR (and not to be addressed here).

I also have the idea of being able to detect system and HWA capabilities through a utility program. And that's what Emby next door did. They wrote a ffdetect that can export HWA capabilities in json and other formats. Therefore, the ffmpeg command can be generated more accurately, and users do not need to manually tick when using HWA.

@JustAMan
Copy link
Contributor

This may indeed happen. So I need to add another toggle to distinguish them. Or is there any other good way?

Maybe just list those as separate toggle-able codecs, like HEVC and HEVC 10-bit?

They wrote a ffdetect that can export HWA capabilities in json and other formats.

Cannot we just call ffmpeg and tell it to transcode some still image to a video using HWA?
Also we can use same still image, encode it in software and try decoding with HWA.

Maybe we can even do without image and just make a pad filter with black 10x10 box or smth.

@EraYaN
Copy link
Member

EraYaN commented May 13, 2020

You will need the image because you need to check output colors. I've toyed with the idea, but the problem is reported support is not reliable. It was much more complicated you essentially need to try every single one and then do a bitmap compare and have some threshold as to when it's "unusable"

But really the toggles would need to be a matrix almost, one side the APIs and the top side the codecs (including YUV4:2:2 vs YUV4:2:0 etc but also resolution) with an auto detection thing too. I tried to make it but not in C#. It worked but was slow and took a good 15 minutes to complete. But then we can fill the matrix with tick marks of what we think works and then let the user adjust if required. And put warnings and crosses in there too if it doesn't work or if it's broken in some way. The added difficulty of HDR is a whole other ball game. It's basically not supported right now, but for nvenc someone made a stream post processor.

@anthonylavado anthonylavado added the merge conflict Merge conflicts should be resolved before a merge label May 16, 2020
@Artiume
Copy link
Contributor

Artiume commented May 25, 2020

Updated comments are here nyanmisaka#4

I also added a few sections for videotoolbox, I'll add a few more in a bit

This also includes the same fix for #2127 and allows it to be closed.

@anthonylavado anthonylavado removed the request for review from joshuaboniface May 26, 2020 19:32
@rigtorp
Copy link
Contributor

rigtorp commented May 29, 2020

When using vaapi the command vainfo outputs what codecs are supported. Have we tried --hwaccel auto?

@rigtorp
Copy link
Contributor

rigtorp commented May 29, 2020

Kodi has a list of sample files: https://kodi.wiki/view/Samples

I wonder if we could find a set of files in public domain for each codec and profile and just try each to see what is supported on JF startup.

@Artiume
Copy link
Contributor

Artiume commented May 29, 2020

vainfo would be good to parse and store. As for samples, I think @EraYaN and @JustAMan's idea to use a small image/clip and process it to verify operations. Pulling samples online seems nasty, especially in a bandwidth restricted situation.

@Artiume
Copy link
Contributor

Artiume commented May 29, 2020

nyanmisaka#5

Updated to split HEVC/VP9 10bit. Changed video toolbox's decoder to opencl. We need to use the libs from here https://github.com/upsuper/ffmpeg-vdadec and add --enable-opencl to ffmpeg.

.Append(encodingOptions.VaapiDevice)
.Append(" ");
}
else if (!isVaapiDecoder && isVaapiEncoder)
Copy link
Member

Choose a reason for hiding this comment

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

isVaapiDecoder is always false here.

@Artiume Artiume added the blocked Blocked by another pull request label Jun 2, 2020
@Artiume
Copy link
Contributor

Artiume commented Jun 2, 2020

Blocked pending web reviews and my PR's being commited

Comment on lines +39 to +40
public bool EnableDecodingColorDepth10Hevc { get; set; }
public bool EnableDecodingColorDepth10Vp9 { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

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

To be more future-proof we might want to nest a structure of bools, so it would become EnableDecodingColorDepth10.CodecName. Could be done later if needed, though.

@Artiume Artiume removed the blocked Blocked by another pull request label Jun 8, 2020
@Artiume
Copy link
Contributor

Artiume commented Jun 10, 2020

/azp run

@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 2809 in repo jellyfin/jellyfin

@Bond-009
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@anthonylavado anthonylavado merged commit 25f8e59 into jellyfin:master Jun 16, 2020
@nyanmisaka nyanmisaka deleted the hwaccel branch August 3, 2020 05:44
@davispuh
Copy link

This is really good and worked for me (I disabled 10-Bit hardware decoding for HEVC), but still there should be auto detection and fallback to software.

For me I got playback error in client which doesn't really say much.
Then looking at logs I saw

[2020-08-29 23:43:22.541 +03:00] [INF] [77] MediaBrowser.Api.Playback.Hls.DynamicHlsService: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2020-08-29 23:43:22.541 +03:00] [INF] [77] MediaBrowser.Api.Playback.Hls.DynamicHlsService: /usr/bin/ffmpeg -c:v hevc_cuvid -resize 1280x536 -i file:"/mnt/movie.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_nvenc -pix_fmtyuv420p -preset slow -b:v 2552000 -maxrate 2552000 -bufsize 5104000 -profile:v high  -g 72 -keyint_min 72 -sc_threshold 0 -start_at_zero -vsync -1 -codec:a:0 libmp3lame -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -f hls -max_delay 5000000 -hls_time 3 -individual_header_trailer 0 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/var/lib/jellyfin/transcoding-temp/transcodes/transcodes/bacfb5d5249b1e91877800fc3202d00d%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/var/lib/jellyfin/transcoding-temp/transcodes/transcodes/bacfb5d5249b1e91877800fc3202d00d.m3u8"
[2020-08-29 23:43:22.688 +03:00] [ERR] [19] MediaBrowser.Api.Playback.Hls.DynamicHlsService: FFMpeg exited with code 1
[2020-08-29 23:43:22.762 +03:00] [WRN] [47] MediaBrowser.Api.Playback.Hls.DynamicHlsService: cannot serve "/var/lib/jellyfin/transcoding-temp/transcodes/transcodes/bacfb5d5249b1e91877800fc3202d00d0.ts" as transcoding quit before we got there

Which also is pretty useless, I see that ffmpeg failed. Okay so then I run this command manually to find out that ffmpeg says

[hevc_cuvid @ 0x564beb15d300] Codec hevc_cuvid is not supported.

And only now I know what's the issue. Terrible user experience. I shouldn't have to know about any of this.
Jellyfin should automatically try hardware decoding and if it fails then do in software.
You could cache results so it has to try only once in a while.

@cvium
Copy link
Member

cvium commented Aug 30, 2020

@davispuh You're not wrong, but don't be an ass about it. Feel free to submit a PR to fix it 🙂

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

Successfully merging this pull request may close these issues.