Video Preview Thumbnail Generation Fails for Some Items

Hi,

I have issues with the generation of video preview thumbnails for some movies. For most movies it works just fine, but some (about 5) the following behavior can be observed:

  • when triggering “Analyze” manually, there is no spinning activity wheel which normally indicates the progress of preview thumbnail generation.
  • after generation failed, I can always observe this log entry:
BaseIndexFrameFileManager: expected 4174 images, but found 0

Here are the verbose log entries some seconds before the crash:

I did already a full wipe of all preview thumbnails and tried to regenerate them manually for the movies I have issues with. But without success. The behavior was the same.

I also checked those mkv’s with mkvalidator and remuxed them with the latest mkvtoolnix, but also no success.

I run Plex with docker-compose using the image of linuxserver.io with the latest Plex server.

Server Version#: 1.19.4.2935
Player Version#: 4.30.2

Does anyone experience similar issues?

Thanks.

1 Like

I have yes, I primarily have REMUX quality files, and it often fails as you have described. I have also tried repackaging them with mkvtoolnix, didn’t change the outcome.

Okay interesting… I also have many Remux files, but the mkv’s that don’t work for me are all h264/x264 encodes.

Here is the video codec information metadata copied from Plex from such a file:

Codec H264
Bitrate 8541 kbps
Language Deutsch
Bit Depth 8
Chroma Location left
Chroma Subsampling 4:2:0
Coded Height 1088
Coded Width 1920
Color Primaries bt709
Color Range tv
Color Space bt709
Color Trc bt709
Frame Rate 23.976 fps
Height 1080
Level 4.1
Profile high
Ref Frames 3
Scan Type progressive
Width 1920
Display Title 1080p (H.264)

Another one that doesn’t work:

Codec H264
Bitrate 8826 kbps
Language English
Bit Depth 8
Chroma Location left
Chroma Subsampling 4:2:0
Coded Height 800
Coded Width 1920
Color Primaries bt709
Color Range tv
Color Space bt709
Color Trc bt709
Frame Rate 23.976 fps
Height 800
Level 4.1
Profile high
Ref Frames 3
Scan Type progressive
Width 1920
Display Title 1080p (H.264)

Here is a comparable one that works:

Codec H264
Bitrate 710 kbps
Bit Depth 8
Chroma Location left
Chroma Subsampling 4:2:0
Coded Height 304
Coded Width 720
Color Range tv
Color Space bt709
Frame Rate 23.976 fps
Height 304
Level 3.1
Profile high
Ref Frames 5
Scan Type progressive
Width 720
Display Title SD (H.264)

Doesn’t seem too suspicious…

Here’s the mediainfo for a REMUX file I have that doesn’t work:

failed_bif.txt (13.7 KB)

Been having the same issue for quite a while now. I usually put all my movies in an MP4 container, but same thing. Some generate thumbnails just fine, while others fail with the same type of error message. I’m encoding the movies with the same program and output settings. There’s no real pattern to which ones work and which ones don’t. Would really like to get to the bottom of this.

I have the same error message, server # 1.19.5.3035

I’m just moving to Plex from Emby and while everything else is fine, I’m finding this error too on certain files.

I’m running on a Linux Docker installation, but I’ve also tried the Windows server, with the same results.

I think I’ve narrowed it down. Most of my TV programmes are ripped from my DVD collection, and I’ve then reencoded to H264/MKV with a “visually lossless” CRF setting. It seems to be these files that cause problems, whether they’re films or TV. Rips that I’ve taken directly from my satellite box - so, exactly as transmitted - generate the thumbnails perfectly.

So I’m guessing that there’s something about the way the H264 encoder (I use TMPGEnc) creates video that Plex’s generator doesn’t like. But then on the other hand, some of my Blu-ray discs ripped directly work in terms of thumbnail generation, while others don’t. These have not been re-encoded at all, so should surely be “official” in the standards sense?

Just to reiterate, all the files play and index absolutely fine, it’s only the video preview thumbnail generation that seems to cause problems.

Thank you very much for pinpointing the issue. Maybe someone of the dev team could have a look into this? :slight_smile:

Okay, I think I’ve narrowed it down further and found the problem, in my case at least.

When you encode to H264 format, you can choose to output as “Closed GOP” or “Open GOP”. GOP stands for “Group of Pictures” and it’s something to do with the way that various compression frames are arranged. Something like that… it’s too technical for me!

As I understood it, “Closed GOP” files are meant to be used when you know you later want to edit the file, and then when you’re ready to output the final version, you use Open GOP. So all my re-encodes were done with “Open GOP”. These are the ones failing.

I can take a native MPEG-2 DVD rip of a title and encode it using the exact same H264 encoding settiings: one with “Open GOP” and the other “Closed GOP”. Every time, the reencoded file with “Open GOP” throws up the error; the other doesn’t.

What I think might be happening is that with Closed GOP, the video preview thumbnail generator assumes it can read a set number of frames and then encode them. In files encoded with Open GOP, I think the frames aren’t following the “correct” order, which is why the error says it expected x number of frames but didn’t get them.

That might explain why “REMUX” files have this problem: often they’re re-encoded from the original to be smaller, and they might use Open GOP.

EDIT: Looking at the text file posted by f18cc above about a remuxed file that didn’t work, it includes “open_gop=1” in the encoding settings…

Devs! Is there any way you could detect if a file uses Open GOP encoding, and alter the behaviour of the thumbnail generator if it is?

2 Likes

Whatever’s going wrong, I don’t think it’s as simple as open_gop=1.

Can you create and share a partial file that exhibits this problem?

I just encoded a file with open_gop=1. I put it in plex. Video preview thumbnails were generated successfully.

  • Encoding settings : cabac=1 / ref=1 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=2 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=0 / threads=12 / lookahead_threads=4 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=1 / weightp=1 / keyint=240 / keyint_min=24 / scenecut=40 / intra_refresh=0 / rc_lookahead=10 / rc=crf / mbtree=1 / crf=24.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / vbv_maxrate=20000 / vbv_bufsize=30000 / crf_max=0.0 / nal_hrd=none / filler=0 / ip_ratio=1.40 / aq=1:1.00

  • Indexes sd

You’re right, GOPs are a group of pictures. Most modern video compression algorithms use GOPs. Movies are made up of multiple GOPs.

Each GOP contains an I frame - a complete Independent picture, sorta like a standalone JPEG file. GOPs also hold P and B frames. These aren’t complete pictures, they have to refer to other I, P, and B frames. This is one of the ways video compression makes videos smaller.

In a closed GOP, the partial P and B frames are only allowed to refer to other frames from within the same GOP.

In an open GOP, the P and B frames are allowed to refer to other frames that are OUTSIDE the GOP, too, in another GOP.

Using open GOPs can slightly increase video compression. It’s also more complicated, so not all editing tools can deal with it. There are lots of features that are made possible or simplified with closed GOPs.

REMUX should mean that the video stream has NOT been changed. The compressed video stream, especially the GOPs, can be copied and repackaged into a different container file, but NOT re-encoded.

index-sd.bif generation happens in two main steps, I believe. First the Transcoder, Plex’s fancy version of FFmpeg, is used to extract a bunch of jpeg stills from the movie. Then those are splatted together into the index-sd.bif file.

The command Plex uses to extract thumbnails looks a lot like this. This will produce a few (thousand) .jpg files if it succeeds, so be aware when you run it.

ffmpeg -skip_frame:v nokey -i input.mkv -q 3 -filter_complex "[0:V:0] fps=fps=0.500000:round=up,scale=w=320:h=240:force_original_aspect_ratio=decrease [out]" -map "[out]" img-%06d.jpg

Usually a closed GOP starts with an I or key frame. An open GOP might not.

If the problem is related to the way it extracts only keyframes, you might get a hint by running that command.

So if the problem is with the files and the GOPs, I wonder if -skip_frame:v nokey could be contributing. There are lots of other ways a GOP book could be ordered, or files could have fewer/more keyframes, etc.

I think you might be onto the answer here. Two shots from my encoding app, one with Closed GOP settings and the other Open:


image

As you can see, changing to the Open GOP settings also changes the pattern of the frames, and they now begin with a B-frame instead of an I.

Time to fiddle around with the indexing settings…

I wouldn’t expect other valid GOP structures to bother FFmpeg (or the Plex Transcoder). But I do wonder if there’s something not-quite-right about the file(s).

(Edit: Coming back to this, I think the files are valid-per-the-spec, but their structure is confusing FFMpeg during thumbnail extraction.)

I suggested that FFmpeg command because it might help figure out where the problem is. If it doesn’t generate the expected jpgs from throughout the movie, it might give a useful error message.

Also, can you use your normal process, but create a shorter file that you can share? Perhaps 5 minutes.

Sure, thanks. Here’s about five minutes of an old Starsky & Hutch DVD! This is encoded as x264 in TMPGEnc Video Mastering Works 6 with the Open GOP settings, which is what I had been using. “BaseIndexFrameFileManager: expected 150 images, but found 0” in this case.

Obviously from now on I’ll encode as Closed GOP to avoid problems…

Heya Plex devs, this example file is perfect. It fails to generate video preview thumbnails, as advertised.

I think this might actually be an FFmpeg bug in -skip_frame nokey. It seems to skip the entire file.

No output jpg created:

% ffmpeg -skip_frame:v nokey -i input.mkv -q 3 -filter_complex "[0:V:0] fps=fps=0.500000:round=up,scale=w=320:h=240:force_original_aspect_ratio=decrease [out]" -map "[out]" img-%06d.jpg
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with Apple clang version 11.0.3 (clang-1103.0.32.62)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, matroska,webm, from 'input.mkv':
  Metadata:
    encoder         : TMPGEnc Video Mastering Works 6 Version. 6.2.11.38
    creation_time   : 2020-07-21T14:46:06.558000Z
  Duration: 00:05:01.64, start: 0.000000, bitrate: 2218 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt470bg, top first), 720x576 [SAR 12:11 DAR 15:11], SAR 157:144 DAR 785:576, 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
Stream mapping:
  Stream #0:0 (h264) -> fps
  scale -> Stream #0:0 (mjpeg)
Press [q] to stop, [?] for help
[h264 @ 0x7fd418034600] illegal short term buffer state detected
[swscaler @ 0x7fd41a073000] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'img-%06d.jpg':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 300x240 [SAR 157:144 DAR 785:576], q=2-31, 200 kb/s, 0.50 fps, 0.50 tbn, 0.50 tbc (default)
    Metadata:
      encoder         : Lavc58.91.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
frame=    0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=   0x    
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)

When used without -skip_frame:v nokey it’s slower, but it produces the files as expected.

% ffmpeg -i input.mkv -q 3 -filter_complex "[0:V:0] fps=fps=0.500000:round=up,scale=w=320:h=240:force_original_aspect_ratio=decrease [out]" -map "[out]" img-%06d.jpg         
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with Apple clang version 11.0.3 (clang-1103.0.32.62)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, matroska,webm, from 'input.mkv':
  Metadata:
    encoder         : TMPGEnc Video Mastering Works 6 Version. 6.2.11.38
    creation_time   : 2020-07-21T14:46:06.558000Z
  Duration: 00:05:01.64, start: 0.000000, bitrate: 2218 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt470bg, top first), 720x576 [SAR 12:11 DAR 15:11], SAR 157:144 DAR 785:576, 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
Stream mapping:
  Stream #0:0 (h264) -> fps
  scale -> Stream #0:0 (mjpeg)
Press [q] to stop, [?] for help
[swscaler @ 0x7fe5a1734000] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'img-%06d.jpg':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 300x240 [SAR 157:144 DAR 785:576], q=2-31, 200 kb/s, 0.50 fps, 0.50 tbn, 0.50 tbc (default)
    Metadata:
      encoder         : Lavc58.91.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
frame=  151 fps= 27 q=3.0 Lsize=N/A time=00:05:02.00 bitrate=N/A speed=54.4x    
video:1711kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
% ls *jpg  
img-000001.jpg	img-000017.jpg	img-000033.jpg	img-000049.jpg	img-000065.jpg	img-000081.jpg	img-000097.jpg	img-000113.jpg	img-000129.jpg	img-000145.jpg
img-000002.jpg	img-000018.jpg	img-000034.jpg	img-000050.jpg	img-000066.jpg	img-000082.jpg	img-000098.jpg	img-000114.jpg	img-000130.jpg	img-000146.jpg
img-000003.jpg	img-000019.jpg	img-000035.jpg	img-000051.jpg	img-000067.jpg	img-000083.jpg	img-000099.jpg	img-000115.jpg	img-000131.jpg	img-000147.jpg
img-000004.jpg	img-000020.jpg	img-000036.jpg	img-000052.jpg	img-000068.jpg	img-000084.jpg	img-000100.jpg	img-000116.jpg	img-000132.jpg	img-000148.jpg
img-000005.jpg	img-000021.jpg	img-000037.jpg	img-000053.jpg	img-000069.jpg	img-000085.jpg	img-000101.jpg	img-000117.jpg	img-000133.jpg	img-000149.jpg
img-000006.jpg	img-000022.jpg	img-000038.jpg	img-000054.jpg	img-000070.jpg	img-000086.jpg	img-000102.jpg	img-000118.jpg	img-000134.jpg	img-000150.jpg
img-000007.jpg	img-000023.jpg	img-000039.jpg	img-000055.jpg	img-000071.jpg	img-000087.jpg	img-000103.jpg	img-000119.jpg	img-000135.jpg	img-000151.jpg
img-000008.jpg	img-000024.jpg	img-000040.jpg	img-000056.jpg	img-000072.jpg	img-000088.jpg	img-000104.jpg	img-000120.jpg	img-000136.jpg
img-000009.jpg	img-000025.jpg	img-000041.jpg	img-000057.jpg	img-000073.jpg	img-000089.jpg	img-000105.jpg	img-000121.jpg	img-000137.jpg
img-000010.jpg	img-000026.jpg	img-000042.jpg	img-000058.jpg	img-000074.jpg	img-000090.jpg	img-000106.jpg	img-000122.jpg	img-000138.jpg
img-000011.jpg	img-000027.jpg	img-000043.jpg	img-000059.jpg	img-000075.jpg	img-000091.jpg	img-000107.jpg	img-000123.jpg	img-000139.jpg
img-000012.jpg	img-000028.jpg	img-000044.jpg	img-000060.jpg	img-000076.jpg	img-000092.jpg	img-000108.jpg	img-000124.jpg	img-000140.jpg
img-000013.jpg	img-000029.jpg	img-000045.jpg	img-000061.jpg	img-000077.jpg	img-000093.jpg	img-000109.jpg	img-000125.jpg	img-000141.jpg
img-000014.jpg	img-000030.jpg	img-000046.jpg	img-000062.jpg	img-000078.jpg	img-000094.jpg	img-000110.jpg	img-000126.jpg	img-000142.jpg
img-000015.jpg	img-000031.jpg	img-000047.jpg	img-000063.jpg	img-000079.jpg	img-000095.jpg	img-000111.jpg	img-000127.jpg	img-000143.jpg
img-000016.jpg	img-000032.jpg	img-000048.jpg	img-000064.jpg	img-000080.jpg	img-000096.jpg	img-000112.jpg	img-000128.jpg	img-000144.jpg

It definitely does have keyframes, and ffmpeg can identify and extract them. It seems like it’s just -skip_frame nokey that isn’t working.

% ffmpeg -i input.mkv -q 3 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 0 frame%03d.jpg
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with Apple clang version 11.0.3 (clang-1103.0.32.62)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, matroska,webm, from 'input.mkv':
  Metadata:
    encoder         : TMPGEnc Video Mastering Works 6 Version. 6.2.11.38
    creation_time   : 2020-07-21T14:46:06.558000Z
  Duration: 00:05:01.64, start: 0.000000, bitrate: 2218 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt470bg, top first), 720x576 [SAR 12:11 DAR 15:11], SAR 157:144 DAR 785:576, 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7f8257632000] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'frame%03d.jpg':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 720x576 [SAR 157:144 DAR 785:576], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc (default)
    Metadata:
      encoder         : Lavc58.91.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
frame=   31 fps=5.9 q=3.0 Lsize=N/A time=00:04:58.88 bitrate=N/A speed=  57x    
video:1481kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
% ls *jpg
frame001.jpg	frame005.jpg	frame009.jpg	frame013.jpg	frame017.jpg	frame021.jpg	frame025.jpg	frame029.jpg
frame002.jpg	frame006.jpg	frame010.jpg	frame014.jpg	frame018.jpg	frame022.jpg	frame026.jpg	frame030.jpg
frame003.jpg	frame007.jpg	frame011.jpg	frame015.jpg	frame019.jpg	frame023.jpg	frame027.jpg	frame031.jpg
frame004.jpg	frame008.jpg	frame012.jpg	frame016.jpg	frame020.jpg	frame024.jpg	frame028.jpg

ffprobe -show_frames finds 31 frames with key_frame=1 and pict_type=I, as expected, but it’s also weird with -skip_frame nokey.

1 Like

Can you share a sample of the same file, created with closed GOP?

I’m learning there is a difference between I and IDR frames and other CRA types.

It seems like ffprobe -show_frames identifies the I frames in the file as key frames.

it also seems like -skip_frame nokey seems to only look at IDR frames, not other recovery (I, CRA?) frames. I’m not sure if that’s expected behavior or not. It seems a bit inconsistent for FFmpeg to show the I frames as key frames in one place and skip them in another. I’d be interested in getting clarification from them.

The sample file truly doesn’t have many IDR frames. That’s not illegal, but a bit weird, I think.

I wonder if the way your encoder creates I, CRA, IDR frames ALSO changes, as a side effect, when you enable open GOP.

The chances of getting Plex Developers interested in Generating VPTs for broken files are:
Slim and None.

Try Handbrake - It works - at least well enough to fix that one.
480p is as close as I could get.
But I did de-interlace it - I couldn’t hep mysef!

I see a change was made to the FFmpeg source for HEVC to consider not-just-IDR frames, but also other recovery frames, as keyframes when skipping.

The AVC/H264 source doesn’t appear to do the same thing. It looks like it only treats IDR frames as keyframes and skips the others.

libavcodec/h264_slice.c:
        if (
            (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||
            (h->avctx->skip_frame >= AVDISCARD_BIDIR  && sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
            (h->avctx->skip_frame >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
            (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != H264_NAL_IDR_SLICE && h->sei.recovery_point.recovery_frame_cnt < 0) ||
            h->avctx->skip_frame >= AVDISCARD_ALL) {
            return 0;
        }

So at least this does seem inconsistent within FFmpeg. Within AVC/H264, it’s being more picky than I would expect, and more picky than in other parts of FFmpeg, about what counts as a key frame.

(Edit: note that I’m not completely sure I’m looking at or comparing the right code.)

I’m at least 95% sure they’re valid files, although I’m not sure that it’s clever to have so few IDR frames. It might also make streaming, especially seeking within the stream, really difficult.

@Raelworld, do you notice any challenges seeking within the Open GOP files? Especially when streaming, is it slower to seek in those files than the Closed GOP files?

For @Raelworld, I definitely think the immediate solution is to use Closed GOP from your encoder. It’s definitely not possible to fix these files in place or by remuxing.

Plex could work around the FFmpeg issue by calling it without -skip_frame noindex, but that would make index generation much slower for files WITH the expected IDR frames. There are some other ways FFmpeg could be filtered to only extract from I frames. I know that Plex has made other changes to this in the past.