2023-10-14, 12:57 AM
(This post was last modified: 2023-10-14, 01:00 AM by spatula. Edited 1 time in total.)
I think I found the trouble (maybe?). [TLDR: on KPIX 5.1 1080i content, Jellyfin omits the bwdif filter, but it includes it on KQED 9.1 1080i content; it also includes it for various subchannels' 480i content.]
It seems like sometimes Jellyfin does not include the bwdif filter at all when transcoding to HLS for Live TV. Here's a recent ffmpeg command from the log, on this occasion when I was using the web player for a KPIX news broadcast on my local network:
I saved off a copy of a few seconds of that stream, and issued the same command, but removed -copyts and the HLS splitting, just so I could save it off to an mp4 I could view with VLC, and in fact, it produces an interlaced video at 1080i just as I saw watching it live in Jellyfin.
If I simply add
If I watch a different sub-channel of KPIX that's broadcasting 480i, then Jellyfin *does* include bwdif in the ffmpeg command!
So it looks like for some reason, with SOME 1080i OTA content, Jellyfin is omitting the deinterlacing filter. It's also omitting the filter on various HD channels that broadcast in 720 lines, but I could see that being intentional given that many of these channels are broadcasting in 720p (ie, it's already progressive video so deinterlacing would add no value).
To make matters weirder, with KQED, channel 9, which broadcasts in 1080i also, Jellyfin *is* adding the deinterlacing filter:
So the problem seems down to what it is that makes Jellyfin decide that KPIX should not have bwdif added to the filter chain, but that KQED should; it does not appear to be anything wrong with what ffmpeg is doing (which probably makes this a lot easier to resolve).
It seems like sometimes Jellyfin does not include the bwdif filter at all when transcoding to HLS for Live TV. Here's a recent ffmpeg command from the log, on this occasion when I was using the web player for a KPIX news broadcast on my local network:
ffmpeg -analyzeduration 3000000 -fflags +igndts -f mpegts -autorotate 0 -i "http://192.168.1.160:8096/LiveTv/LiveStreamFiles/bb79e844fd5b4c109f50360764f882f7/stream.ts" -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 libx264 -preset fast -crf 21 -maxrate 20000000 -bufsize 40000000 -x264opts:0 subme=0:me_range=4:rc_lookahead=10:me=dia:no_chroma_me:8x8dct=0:partitions=none -force_key_frames:0 "expr:gte(t,n_forced*3)" -sc_threshold:v:0 0 -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,min(1920\,1080*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(1920/a\,1080))/2)*2,format=yuv420p" -flags -global_header -codec:a:0 libfdk_aac -ac 6 -ab 640000 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url "hls/ca5a2038ed46d6cd3d11cbb80451f3c6/" -hls_segment_filename "W:\Transcodes\ca5a2038ed46d6cd3d11cbb80451f3c6%d.ts" -hls_playlist_type event -hls_list_size 0 -y "W:\Transcodes\ca5a2038ed46d6cd3d11cbb80451f3c6.m3u8"
I saved off a copy of a few seconds of that stream, and issued the same command, but removed -copyts and the HLS splitting, just so I could save it off to an mp4 I could view with VLC, and in fact, it produces an interlaced video at 1080i just as I saw watching it live in Jellyfin.
If I simply add
bwdif=1:-1:0
before scale=
, I get a beautifully deinterlaced output file.If I watch a different sub-channel of KPIX that's broadcasting 480i, then Jellyfin *does* include bwdif in the ffmpeg command!
ffmpeg -analyzeduration 3000000 -fflags +igndts -f mpegts -autorotate 0 -i "http://192.168.1.160:8096/LiveTv/LiveStreamFiles/912c9df44ed64fa2b84fe85a3140feb1/stream.ts" -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 libx264 -preset fast -crf 21 -maxrate 5000000 -bufsize 10000000 -x264opts:0 subme=0:me_range=4:rc_lookahead=10:me=dia:no_chroma_me:8x8dct=0:partitions=none -force_key_frames:0 "expr:gte(t,n_forced*3)" -sc_threshold:v:0 0 -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,bwdif=1:-1:0,scale=trunc(min(max(iw\,ih*a)\,min(720\,480*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(720/a\,480))/2)*2,format=yuv420p" -flags -global_header -codec:a:0 copy -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url "hls/9b3479ea353cb7ccf109fb9b445ec3ac/" -hls_segment_filename "W:\Transcodes\9b3479ea353cb7ccf109fb9b445ec3ac%d.ts" -hls_playlist_type event -hls_list_size 0 -y "W:\Transcodes\9b3479ea353cb7ccf109fb9b445ec3ac.m3u8"
So it looks like for some reason, with SOME 1080i OTA content, Jellyfin is omitting the deinterlacing filter. It's also omitting the filter on various HD channels that broadcast in 720 lines, but I could see that being intentional given that many of these channels are broadcasting in 720p (ie, it's already progressive video so deinterlacing would add no value).
To make matters weirder, with KQED, channel 9, which broadcasts in 1080i also, Jellyfin *is* adding the deinterlacing filter:
ffmpeg -analyzeduration 3000000 -fflags +igndts -f mpegts -autorotate 0 -i "http://192.168.1.160:8096/LiveTv/LiveStreamFiles/ab8a8be03b504c96a16bc76bd9f88ef2/stream.ts" -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 libx264 -preset fast -crf 21 -maxrate 20000000 -bufsize 40000000 -x264opts:0 subme=0:me_range=4:rc_lookahead=10:me=dia:no_chroma_me:8x8dct=0:partitions=none -force_key_frames:0 "expr:gte(t,n_forced*3)" -sc_threshold:v:0 0 -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,bwdif=1:-1:0,scale=trunc(min(max(iw\,ih*a)\,min(1920\,1080*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(1920/a\,1080))/2)*2,format=yuv420p" -flags -global_header -codec:a:0 copy -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url "hls/6da3e68be217a05cf4e256bc242dbcf0/" -hls_segment_filename "W:\Transcodes\6da3e68be217a05cf4e256bc242dbcf0%d.ts" -hls_playlist_type event -hls_list_size 0 -y "W:\Transcodes\6da3e68be217a05cf4e256bc242dbcf0.m3u8"
So the problem seems down to what it is that makes Jellyfin decide that KPIX should not have bwdif added to the filter chain, but that KQED should; it does not appear to be anything wrong with what ffmpeg is doing (which probably makes this a lot easier to resolve).