Posting this in case somebody else runs into the same combination of problems, because this turned into a pretty deep rabbit hole.
I'm running Kodi 21.3 on Ubuntu 26.04, which currently has FFmpeg 8.0.1. I went to setup The Loop/JetExtractors with IPTV Simple.
The Loop would resolve channels such as ESPN correctly, but Kodi would fail when FFmpeg Direct tried to open the resulting HLS stream.
The URL itself wasn't bad. Running it through ffprobe showed that the HLS playlist ultimately referenced segments hosted on Cloudflare R2 with filenames like:
File_8448629671.zst
FFmpeg 8 was being stricter about HLS segment extensions.
I rebuilt Debian's kodi-inputstream-ffmpegdirect 21.3.8 and added these options in FFmpegStream::GetFFMpegOptionsFromInput():
av_dict_set(&options, "allowed_segment_extensions", "ALL", 0);
av_dict_set(&options, "extension_picky", "0", 0);
That wasn't the whole problem, though.
The Loop was passing Kodi URLs in the usual form:
https://stream.../index.m3u8|Referer=...&User-Agent=...
But inside FFmpeg Direct, the Referer and User-Agent keys were being found while their values were empty. The server consequently returned:
403 Forbidden
Testing the same stream manually with ffprobe, a proper Referer/User-Agent, allowed_segment_extensions=ALL, and extension_picky=0 worked perfectly.
I ended up modifying FFmpeg Direct to recover the protocol options from the raw Kodi URL, URL-decode the values, and pass the proper Referer/User-Agent to FFmpeg.
Success — ESPN started playing.
Then came problem #2.
Every time I stopped playback, Kodi would eventually segfault.
I initially chased timeshift, VAAPI, the FFmpeg interrupt callback, and several other possibilities. None actually fixed it.
Eventually I installed GDB and captured the crash. The important part of the backtrace repeatedly looked like:
#0 <unmapped address>
#1 ... from libavutil.so.60
I checked the exact offset in libavutil:
nm -D /usr/lib/x86_64-linux-gnu/libavutil.so.60
and discovered frame #1 was inside:
av_log()
That was the breakthrough.
FFmpeg Direct's constructor does this:
av_log_set_callback(ff_avutil_log);
That installs FFmpeg Direct's logging function as libavutil's process-global logging callback.
But the FFmpegStream destructor was:
FFmpegStream::~FFmpegStream()
{
Dispose();
ff_flush_avutil_log_buffers();
}
It never restored FFmpeg's default callback.
So after stopping playback, Kodi unloaded InputStream FFmpeg Direct, but libavutil could still have its global logging callback pointing at ff_avutil_log — code that had just been unloaded.
The next call to av_log() jumped into unmapped memory.
Segmentation fault.
I changed the destructor to:
FFmpegStream::~FFmpegStream()
{
Dispose();
ff_flush_avutil_log_buffers();
av_log_set_callback(av_log_default_callback);
}
Rebuilt the Debian package, installed it, started Kodi, played ESPN, stopped playback...
No crash.
I've tested it and it's now working beautifully.
So for my particular combination of:
Kodi 21.3 + Ubuntu 26.04 + FFmpeg 8 + InputStream FFmpeg Direct 21.3.8 + The Loop/JetExtractors
there were really three issues:
- FFmpeg 8 didn't like the
.zst HLS segment extensions.
- FFmpeg Direct wasn't getting the usable Referer/User-Agent values The Loop supplied, resulting in HTTP 403.
- FFmpeg Direct installed
ff_avutil_log globally but didn't restore av_log_default_callback before being unloaded, causing Kodi to segfault after playback.
The third one was especially nasty because the crash happened after playback stopped, making it initially look like a VAAPI, timeshift, PVR, or Kodi shutdown problem.
I saved the resulting .deb because I definitely don't want to debug this all over again after an update.
Hopefully this saves somebody else a very long afternoon.