jellyfin / jellyfin-media-player

Jellyfin Desktop Client
GNU General Public License v2.0
3.18k stars 315 forks source link

JMP not transcoding in HEVC/H265 but plays HEVC in direct play just fine. #319

Closed japtain-cack closed 1 year ago

japtain-cack commented 2 years ago

The whole reason I left plex/emby and chose Jellyfin, is that it actually supports encode to HEVC for transcoding. HEVC is supported by 99% of devices now, so I don't understand plex/emby's argument to not implement it.

Anyway, I'm 100% satisfied with the FireTV app and Android client apps when it comes to transcoding. I have confirmed HEVC transcoding is working beautifully on those platforms/apps. This solves the issues for my family and streaming my content, especially 4k content.

My issue is, when I am roaming personally. I'm usually on my XPS 13 7390 2-in-1. It has an i7-1065G7 processor, and to my understanding has native HEVC support. That must be the case because direct play works in HEVC and my test below shows ffmpeg can decode it. I'm running Windows 11 on this device btw.

I've tried various JMP client settings and a combinations of them as well, with no effect on HEVC transcoding:

According to this document, the desktop client supports hevc main and main10 profiles. According to this issue, the desktop column refers to the JMP client.

I should also mention, everything above applies to the Web Client running in MS Edge as well. It supports HEVC per the Jellyfin Client docs and the website test, but cannot transcode in h265.

Here are my JMP logs. I started with a clean log file, started the app, and played the same video. One file has transcoding playback, the other is direct play playback. I reset JMP to defaults before generating the logs, by deleting the entire appdata folder, The only settings I changed were "Prefer fMP4-HLS Media Container", which is on, and hardware decoding is on it's default value of "copy". All other settings are default.

https://publicsj.mimir-tech.org/jmplogs.zip

Using these instructions, obtained form Jellyfin's docs on hardware acceleration. I confirmed the ability to hardware decode an HEVC file.

./ffmpeg -hwaccel dxva2 -threads 1 -i 'C:\Users\nathan.snow\Videos\Covidland_S1E03_The Shot.mkv' -f null - -benchmark
ffmpeg version 5.1.2-Jellyfin Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 10-win32 (GCC) 20220324
  configuration: --prefix=/opt/ffmpeg --arch=x86_64 --target-os=mingw32 --cross-prefix=x86_64-w64-mingw32- --pkg-config=pkg-config --pkg-config-flags=--static --extra-libs='-lfftw3f -lstdc++' --extra-cflags=-DCHROMAPRINT_NODLL --extra-version=Jellyfin --disable-ffplay --disable-debug --disable-doc --disable-sdl2 --disable-ptx-compression --disable-w32threads --enable-pthreads --enable-shared --enable-lto --enable-gpl --enable-version3 --enable-schannel --enable-iconv --enable-libxml2 --enable-zlib --enable-lzma --enable-gmp --enable-chromaprint --enable-libfreetype --enable-libfribidi --enable-libfontconfig --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libwebp --enable-libvpx --enable-libzimg --enable-libx264 --enable-libx265 --enable-libsvtav1 --enable-libdav1d --enable-libfdk-aac --enable-opencl --enable-dxva2 --enable-d3d11va --enable-amf --enable-libmfx --enable-ffnvcodec --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvdec --enable-nvenc
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, matroska,webm, from 'C:\Users\nathan.snow\Videos\Covidland_S1E03_The Shot.mkv':
  Metadata:
    creation_time   : 2022-06-17T02:35:18.000000Z
    ENCODER         : Lavf58.76.100
  Duration: 02:11:51.65, start: 0.000000, bitrate: 810 kb/s
  Chapters:
    Chapter #0:0: start 0.000000, end 42.334000
      Metadata:
        title           : Chapter 1
    Chapter #0:1: start 42.334000, end 440.440000
      Metadata:
        title           : Chapter 2
    Chapter #0:2: start 440.440000, end 760.009000
      Metadata:
        title           : Chapter 3
    Chapter #0:3: start 760.009000, end 920.461000
      Metadata:
        title           : Chapter 4
    Chapter #0:4: start 920.461000, end 1466.507000
      Metadata:
        title           : Chapter 5
    Chapter #0:5: start 1466.507000, end 2038.078000
      Metadata:
        title           : Chapter 6
    Chapter #0:6: start 2038.078000, end 2703.534000
      Metadata:
        title           : Chapter 7
    Chapter #0:7: start 2703.534000, end 3922.544000
      Metadata:
        title           : Chapter 8
    Chapter #0:8: start 3922.544000, end 4173.670000
      Metadata:
        title           : Chapter 9
    Chapter #0:9: start 4173.670000, end 4696.358000
      Metadata:
        title           : Chapter 10
    Chapter #0:10: start 4696.358000, end 5097.801000
      Metadata:
        title           : Chapter 11
    Chapter #0:11: start 5097.801000, end 6395.639000
      Metadata:
        title           : Chapter 12
    Chapter #0:12: start 6395.639000, end 7350.969000
      Metadata:
        title           : Chapter 13
    Chapter #0:13: start 7350.969000, end 7531.649000
      Metadata:
        title           : Chapter 14
    Chapter #0:14: start 7531.649000, end 7910.611000
      Metadata:
        title           : Chapter 15
  Stream #0:0: Video: hevc (Main), yuv420p(tv, smpte170m/smpte170m/bt709), 720x426 [SAR 32:27 DAR 1280:639], 23.98 fps, 23.98 tbr, 1k tbn (default)
    Metadata:
      DURATION        : 02:11:51.645000000
  Stream #0:1(eng): Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s (default)
    Metadata:
      title           : Stereo
      DURATION        : 02:11:51.616000000
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> wrapped_avframe (native))
  Stream #0:1 -> #0:1 (ac3 (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf59.27.100
  Chapters:
    Chapter #0:0: start 0.000000, end 42.334000
      Metadata:
        title           : Chapter 1
    Chapter #0:1: start 42.334000, end 440.440000
      Metadata:
        title           : Chapter 2
    Chapter #0:2: start 440.440000, end 760.009000
      Metadata:
        title           : Chapter 3
    Chapter #0:3: start 760.009000, end 920.461000
      Metadata:
        title           : Chapter 4
    Chapter #0:4: start 920.461000, end 1466.507000
      Metadata:
        title           : Chapter 5
    Chapter #0:5: start 1466.507000, end 2038.078000
      Metadata:
        title           : Chapter 6
    Chapter #0:6: start 2038.078000, end 2703.534000
      Metadata:
        title           : Chapter 7
    Chapter #0:7: start 2703.534000, end 3922.544000
      Metadata:
        title           : Chapter 8
    Chapter #0:8: start 3922.544000, end 4173.670000
      Metadata:
        title           : Chapter 9
    Chapter #0:9: start 4173.670000, end 4696.358000
      Metadata:
        title           : Chapter 10
    Chapter #0:10: start 4696.358000, end 5097.801000
      Metadata:
        title           : Chapter 11
    Chapter #0:11: start 5097.801000, end 6395.639000
      Metadata:
        title           : Chapter 12
    Chapter #0:12: start 6395.639000, end 7350.969000
      Metadata:
        title           : Chapter 13
    Chapter #0:13: start 7350.969000, end 7531.649000
      Metadata:
        title           : Chapter 14
    Chapter #0:14: start 7531.649000, end 7910.611000
      Metadata:
        title           : Chapter 15
  Stream #0:0: Video: wrapped_avframe, nv12(tv, smpte170m/smpte170m/bt709, progressive), 720x426 [SAR 32:27 DAR 1280:639], q=2-31, 200 kb/s, 23.98 fps, 23.98 tbn (default)
    Metadata:
      DURATION        : 02:11:51.645000000
      encoder         : Lavc59.37.100 wrapped_avframe
  Stream #0:1(eng): Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s (default)
    Metadata:
      title           : Stereo
      DURATION        : 02:11:51.616000000
      encoder         : Lavc59.37.100 pcm_s16le
frame=31115 fps=446 q=-0.0 Lsize=N/A time=00:21:37.75 bitrate=N/A speed=18.6x
video:14342kB audio:243312kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
bench: utime=21.703s stime=4.562s rtime=69.793s
bench: maxrss=78092kB
AnonymousWebHacker commented 2 years ago

don't understand plex/emby's argument to not implement it.

hevc is not open source, it is private and payment, (which is why Plex and 70k projects don't use HEVC)

The transcoding of H265 HEVC is extremely slow, it comes with double compression, for that (not transcoding) and to be able to see them directly.

If it works for you directly, why do you want me to transcode? :/

japtain-cack commented 2 years ago

don't understand plex/emby's argument to not implement it.

hevc is not open source, it is private and payment, (which is why Plex and 70k projects don't use HEVC)

The transcoding of H265 HEVC is extremely slow, it comes with double compression, for that (not transcoding) and to be able to see them directly.

If it works for you directly, why do you want me to transcode? :/

Well, residential internet typically gives people around here like 5 - 10 Mbps for upload. Not really suited for direct play over wan. Especially for more than a single stream. So, transcoding to a lower bitrate is my top priority. I cap all clients, in the network settings of the server, to 5Mbps and many videos exceed this and can't be direct played.

h265 grants much higher quality at a lower file size than h264. Smaller files mean less, sometimes considerably less, bandwidth. Is this not important to anyone else???

This is already working on my server, transcoding to h265 for android and firetv apps. So, you can't tell me it's not possible, or the server is lacking the ability to do this. It's already happening... I can encode video in h265 on my server hardware just fine, CPU/GPU power/resources are no issue for me. I can encode an entire h265 video in a couple of minutes. When transcoding in h265 to my android over the wan, I can stream 4k 10bit HDR video in around 5Mbps with good quality. If I stream something in 1080p, then I only need 1.5 - 2 Mbps. So this is a no brainer to me.

As as I mentioned above, I bought my own license for the HEVC codec. I have the codecs on this device and proved my ability to decode with ffmpeg. So, I would like to know if using the codec I have on this system is a possibility. As I mentioned above, in the jellyfinmediaplayer.conf, there is a setting called useSystemVideoCodecs. Just looking at the setting, it sounds like this is what I need, but seemed to have no effect.

Also, please help me understand how the same client that can't seem to decode a transcoded video in h265, can decode that same exact file, which is natively encoded in h265, using direct play. Just because it's not a transcoded h265 stream vs direct play, doesn't mean it's not decoding h265 just the same. So this doesn't make sense to me.

Summary:

japtain-cack commented 2 years ago

I just tested Kodi on my XPS, and its transcoding in HEVC just fine. However, I prefer the Jellyfin player and layout, but I have found a temporary solution until this can be resolved in the native player.

japtain-cack commented 2 years ago

Also, according to this, x265 is free to use and uses the GPL. Can someone explain the cost issues to me? If I compile/install it myself, there should be no issue. Which is exactly what I've done by installing the HEVC codecs provided by Microsoft on this device. Plus the codec is indeed open source, it's under the GPL. Unless you're distributing binaries in your software or providing a service that uses it, it's free.

Below is a way to compile/install it for free, according to VLC, and below that is the official code repo for x265 which you can see the license is GPLv2.

https://www.videolan.org/developers/x265.html https://bitbucket.org/multicoreware/x265_git/src

Here is the contents of the readme.rst.

=================
x265 HEVC Encoder
=================

| **Read:** | Online `documentation <http://x265.readthedocs.org/en/master/>`_ | Developer `wiki <http://bitbucket.org/multicoreware/x265_git/wiki/>`_
| **Download:** | `releases <http://ftp.videolan.org/pub/videolan/x265/>`_ 
| **Interact:** | #x265 on freenode.irc.net | `x265-devel@videolan.org <http://mailman.videolan.org/listinfo/x265-devel>`_ | `Report an issue <https://bitbucket.org/multicoreware/x265/issues?status=new&status=open>`_

`x265 <https://www.videolan.org/developers/x265.html>`_ is an open
source HEVC encoder. See the developer wiki for instructions for
downloading and building the source.

x265 is free to use under the `GNU GPL <http://www.gnu.org/licenses/gpl-2.0.html>`_ 
and is also available under a commercial `license <http://x265.org>`_ 
AnonymousWebHacker commented 2 years ago

I have my server with HEVC videos, solution to your network problem at 2mb/s? Simple. I convert all the videos that I am uploading to my server from h264 to H265, but changing the bitrate to 800 kb/s video and 200kb/s audio, plus 100 kb/s of network noise (overhead), I need only 1.2 Mb/s to be able to see a 1920 video () it is no longer necessary to transcode :)

japtain-cack commented 2 years ago

I have my server with HEVC videos, solution to your network problem at 2mb/s? Simple. I convert all the videos that I am uploading to my server from h264 to H265, but changing the bitrate to 800 kb/s video and 200kb/s audio, plus 100 kb/s of network noise (overhead), I need only 1.2 Mb/s to be able to see a 1920 video () it is no longer necessary to transcode :)

I understand what you're saying. However, most of my content is already h265, soon to be av1 as I have native av1 decoding hardware. Once I get a RTX 4080, I'll have hardware encoding av1 as well. However, I don't just watch content over the WAN. So converting all content, 4k or otherwise, to a much lesser quality seems counterproductive. If I want to keep the high quality file, and have a lower quality file for streaming over the wan, then I'm not really saving any space either.

Plus, it's also counterproductive to implement a content streaming server with transcoding, if it can't actually do that properly. I could just attach to a file share over my vpn, use Kodi, and get the same result as you described. No need for plex/emby/jellyfin if I have to do all the "transcoding" by hand.

You could argue that the only benefit, over Kodi, of plex/emby/jellyfin is that they can transcode. That is the main difference between those platforms. They all can do metadata lookups, they all organize your library, but Kodi doesn't transcode since it's not really a server.

I believe I've done enough research to show that this is an advertised feature, that is claimed to be possible with this specific client. This constitutes as a bug and my only intention is to report that bug. I'm not really interested in a workaround unless that workaround fixes the HEVC/transcoding issues.

Thank you for your suggestion nonetheless :)

ringus1 commented 2 years ago

Also, just a note that when I forced server to transcode to HEVC regardless of requested codec, JMP played it just fine. So it seems to be only a matter of adding supported codecs to some profile and set it as a first choice for server to choose from if it's enabled to transcode to HEVC.

As @japtain-cack mentioned it's just much better quality for streaming content without putting too much strain on your bandwidth when using cellular network for example. It doesn't make sense to have pre-transcoded movie/TV series to lower quality from the get go if you'd like to use Jellyfin also in home network when you can easily direct-play.

Schaka commented 1 year ago

@ringus1 how do you force the server to transcode to HEVC? Maybe I missed that option. I'm currently trying to get all my players (JMP, web, Android) properly working with transcode without wasting more bandwidth than my poor WiFi can handle.

Thank you for the rigorous report, @japtain-cack, it really helped me narrow things down with the issues I was seeing.

iwalton3 commented 1 year ago

The next JMP version is going to disable transcoding to HEVC by default due to issues with Dolby vision, but it should allow it for now. (In the next release it is an option you can enable in client settings.) It supports it but doesn't ask for it by default.

If you want to force it, you could edit the profile in the nativeshell.js file. Make sure HEVC is before h264 in the transcoding profile.

iwalton3 commented 1 year ago

I am adding an option to prefer HEVC in the next release which should close out this issue.

japtain-cack commented 1 year ago

This is why Jellyfin is the best. Everybody else says it's not possible or needed, but I get measurable improvements according to grafana and network/HAProxy metrics/graphs. When you only get 40mbps or less for egress, it matters. Thanks Jellyfin team, you guys are awesome. I am, and will continue, donating to your cause.