JPVenson / Jellyfin.HardwareVisualizer

Repository to host the Hardware Survey visualizer Server
https://hwa.jellyfin.org
3 stars 3 forks source link

Wrong decoder [args] - h264 and hevc mixed up #9

Open BotBlake opened 22 hours ago

BotBlake commented 22 hours ago

The Server provides the following response to a Client:

{
        "name": "jellyfish-120-mbps-4k-uhd-hevc-10bit",
        "source_url": "https://repo.jellyfin.org/jellyfish/media/jellyfish-120-mbps-4k-uhd-hevc-10bit.mkv",
        "source_hashs": null,
        "test_type": "transcode",
        "data": [
          {
            "id": "c1d474a5-ba17-69e3-c756-e60d4fa4da45",
            "from_resolution": "2160p",
            "to_resolution": "720p",
            "bitrate": 3616000,
            "arguments": [
              {
                "type": "nvidia",
                "args": "-init_hw_device cuda=cu:{gpu} -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid -i {video_file} -noautoscale -an -sn -vf \"scale_cuda=-1:429:yuv420p\" -c:v h264_nvenc -preset p1 -b:v 3616000 -maxrate 3616000 -f null - -benchmark",
                "codec": "h264"
              }
            ]
           }

         ]
}

(example of a current test on a hevc file on Windows 11)

You will see that the FILE is an hevc file - as stated in the filename. However the Server makes the client open it using the h264 decoder. That will not work and results in Problems.

This error happens:

Therefore this issue makes it impossible to run tests for any hevc file without modifying the args on Client side.

I also found logging that indicates that a hevc decoder is sometimes also selected on h264 files.

    -> /home/botblake/pytab/ffmpeg/ffmpeg_files/ffmpeg -c:v hevc -i /home/botblake/pytab/videos/jellyfish-40-mbps-hd-h264.mkv -noautoscale -an -sn -vf "scale=trunc(min(max(iw\,ih*a)\,142)/2)*2:trunc(ow/a/2)*2,format=yuv420p" -c:v libx265 -preset veryfast -b:v 9616000 -maxrate 9616000 -f null - -benchmark
        -| ffmpeg version 6.0.1-Jellyfin Copyright (c) 2000-2023 the FFmpeg developers
        -|   built with gcc 13.2.0 (crosstool-NG 1.26.0.65_ecc5e41)
        -|   configuration: --prefix=/ffbuild/prefix --pkg-config=pkg-config --pkg-config-flags=--static --cross-prefix=x86_64-ffbuild-linux-gnu- --arch=x86_64 --target-os=linux --extra-version=Jellyfin --extra-cflags= --extra-cxxflags= --extra-ldflags= --extra-ldexeflags=-pie --extra-libs=-ldl --enable-gpl --enable-version3 --enable-lto --disable-ffplay --disable-debug --disable-doc --disable-ptx-compression --disable-sdl2 --disable-libxcb --disable-xlib --enable-iconv --enable-libxml2 --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-openssl --enable-lzma --enable-fontconfig --enable-libvorbis --enable-opencl --enable-amf --enable-chromaprint --enable-libdav1d --enable-libfdk-aac --enable-ffnvcodec --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvdec --enable-nvenc --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvpl --enable-libvpx --enable-libwebp --enable-libopenmpt --enable-libsrt --enable-libsvtav1 --enable-libdrm --enable-vaapi --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libx264 --enable-libx265 --enable-libzimg --enable-libzvbi
        -|   libavutil      58.  2.100 / 58.  2.100
        -|   libavcodec     60.  3.100 / 60.  3.100
        -|   libavformat    60.  3.100 / 60.  3.100
        -|   libavdevice    60.  1.100 / 60.  1.100
        -|   libavfilter     9.  3.100 /  9.  3.100
        -|   libswscale      7.  1.100 /  7.  1.100
        -|   libswresample   4. 10.100 /  4. 10.100
        -|   libpostproc    57.  1.100 / 57.  1.100
        -| [hevc @ 0x55848b9ae0c0] Invalid NAL unit size in extradata.
        -| [matroska,webm @ 0x55848b9aba00] Failed to open codec in avformat_find_stream_info
        -| [NULL @ 0x55848b9ae0c0] Invalid NAL unit size in extradata.
        -| [NULL @ 0x55848b9ae0c0] Invalid NAL unit 0, skipping.
        -|     Last message repeated 2 times
        -| [NULL @ 0x55848b9ae0c0] Invalid NAL unit 8, skipping.
        -| [NULL @ 0x55848b9ae0c0] Invalid NAL unit 0, skipping.
        -|     Last message repeated 2 times
        -| [NULL @ 0x55848b9ae0c0] Invalid NAL unit size (44259 > 18658).
        -| [hevc @ 0x55848b9ae0c0] Invalid NAL unit size in extradata.
        -| Input #0, matroska,webm, from '/home/botblake/pytab/videos/jellyfish-40-mbps-hd-h264.mkv':
        -|   Metadata:
        -|     encoder         : libebml v1.2.0 + libmatroska v1.1.0
        -|     creation_time   : 2016-02-06T04:00:54.000000Z
        -|   Duration: 00:00:30.03, start: 0.000000, bitrate: 39833 kb/s
        -|   Stream #0:0(eng): Video: hevc, none, 1920x1080, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 1k tbn (default)
        -| [hevc @ 0x55848bb3e480] Invalid NAL unit size in extradata.
        -| Stream mapping:
        -|   Stream #0:0 -> #0:0 (hevc (native) -> hevc (libx265))
        -| Error while opening decoder for input stream #0:0 : Invalid data found when processing input
        -| bench: maxrss=39052kB
        ----

So generaly there needs to be a fix to make sure the correct decoder will be used!

We CAN implement this on Client side by running ffprobe on the file and determining its codec. However then the Server would have to provide a decoder field for us to use. I also suggest not to do this, as this would limit control over what exact decoder is used.

brys0 commented 21 hours ago

FFMpeg will auto determine the source files encoding. We do not even need to specify the encoder, the only benefit to doing so would be to ensure a user has not tampered with the file in any way. But that is better off being performed with a file checksum. The performance impact of letting FFMpeg auto-determine source file encoding should be negligible.

JkBoyo commented 16 hours ago

I think this issue is more complex than just submitting the wrong codecs. @JPVenson can you elaborate on what the tests are trying to do? I'm trying to go through your test command constructors and it seems that you are trying to submit transcodes to each different codec. This should still be valid, the machine should be able to do that.

The problem is that the args in practice are assuming that the file we are transcoding is the other type breaking everything.

I am not familiar enough with the code base to know how to fix this break. I've analyzed most of the Database config file but if you have anything that maps how the logic is supposed to flow for the test arg generation that would be great.

link with informative Disc discussion