[FFmpeg-user] Is there a way to set 'closed_gop' in FFmpeg?

Mark Filipak markfilipak.imdb at gmail.com
Mon Jun 3 20:18:50 EEST 2024


With something a complicated as this stuff, I knew I would screw up something. Correction: I fixed 
the 'Commands used'.


Hey,

My cuts are perfect, true IDR. The join is perfect, yet MPV stalls for about 1/2 second and shows 
one, maybe two black frames. The only thing I can think of that would screw up the playing across my 
joins is MPEG's 'closed_gop' flag. It needs to set it to '1' for the GOP on the early side of the join.

I know that FFmpeg doesn't fix 'closed_gop' when it does '-ss' and '-to' on VOBs, so I assume it 
doesn't fix 'closed_gop' for M2TSes either. Just for clarity, I'm not using '-ss' and '-to'. I'm 
doing stream editing instead -- see the end matter, below.

Is there a way to set 'closed_gop' in FFmpeg?
Is there a way to set 'closed_gop' for an individual GOP?

Aside: I'm pretty sure this has something to do with '-ss' and '-to' sometimes failing to make 
segments that join properly. '-ss' and '-to' need to fiddle with the 'closed_gop' & 'broken_link' 
MPEG tags.

Thanks!
--Mark.


Commands used:

ffmpeg -copyts -i SOURCE_1 -map 0 -bsf 
noise=drop='lt(pts\,<I1_PTS>)+gte(dts\,<B_DTS>)',setts=dts='if(eq(DTS\,<I1_DTS>)\,<I1_PTS>-<1_frame>\,DTS)':pts='if(eq(PTS\,<I2_PTS>)\,<B_DTS>\,PTS)' 
-c copy -muxdelay 0 SEGMENT_1

ffmpeg -copyts -i SOURCE_2 -map 0 -bsf 
noise=drop='lt(pts\,<I1_PTS>)+gte(dts\,<B_DTS>)',setts=dts='if(eq(DTS\,<I1_DTS>)\,<I1_PTS>-<1_frame>+<OFFSET>\,DTS+<OFFSET>)':pts='if(eq(PTS\,<I2_PTS>+<OFFSET>)\,<B_DTS>+<OFFSET>\,PTS+<OFFSET>)' 
-c copy -muxdelay 0 SEGMENT_2

ffmpeg -copyts -i "concat:SEGMENT_1|SEGMENT_2" -map 0 -c copy -muxdelay 0 TARGET

(Paul, I don't think concat is a problem. I think this stuff, here, is the problem.)

Step 1: Make IDR cuts
SEGMENT_1 -- imagine i want just just one gop having only 6 frames
(source is all open GOPs)
                         I1_PTS                     I2_PTS
                               \<———6 frames———>   /
PTS order    .. B  B  P  B  B  I  B  B  P  B  B  I  B  B  P ..
                _¦__¦_/  _¦__¦_/  _¦__¦_/  _¦__¦_/  _¦__¦_/
               / ¦  ¦   / ¦  ¦   / ¦  ¦   / ¦  ¦   / ¦  ¦
DTS order .. P  B  B  I  B  B  P  B  B  I  B  B  P  B  B ..
                        \                       \
                         I1_DTS                  B_DTS

CUT pts < I1_PTS               <———6 frames———>
CUT dts >= B_DTS               I  B  B  P  B     I
                         ______/  _¦__¦_/  _¦____/
                        /        / ¦  ¦   / ¦
                       I        P  B  B  I  B

Note: If there was just one open B-frame, now there are no open B-frames. In that case (my case), 
the 6 frames are now a closed GOP and must be marked 'closed_gop = 1', but how do I do that?

.-------------------------WHAT IS CUT--------------------------.
¦                              <———6 frames———>                ¦
¦            .. B  B  P  B  B                 B     B  B  P .. ¦
¦              _¦__¦_/   ¦  ¦                 ¦    _¦__¦_/     ¦
¦             / ¦  ¦     ¦  ¦                 ¦   / ¦  ¦       ¦
¦         .. P  B  B     B  B                 B  P  B  B ..    ¦
'--------------------------------------------------------------'

ADJUST DTS & PTS               <———6 frames———>
                                I  B  B  P  B  I<——
                               /  _¦__¦_/  _¦_/
                              /  / ¦  ¦   / ¦
                       —————>I  P  B  B  I  B

(The ending I-frame has replaced the final open B-frame -- preserves N & sync.)


Step 2: Do the same and add OFFSET               <———6 frames———>
SEGMENT_2                                        I  B  B  P  B  I
                                                 /  _¦__¦_/  _¦_/
                                                /  / ¦  ¦   / ¦
                                               I  P  B  B  I  B


Step 3: Concatenate            <———6 frames———>  <———6 frames———>
                                I  B  B  P  B  I  I  B  B  P  B  I
                               /  _¦__¦_/  _¦_/  /  _¦__¦_/  _¦_/
                              /  / ¦  ¦   / ¦   /  / ¦  ¦   / ¦
                             I  P  B  B  I  B  I  P  B  B  I  B


ffmpeg -copyts -i "concat:SEGMENT_1|SEGMENT_2" -map 0 -c copy -muxdelay 0 TARGET

ffmpeg version 2024-05-20-git-127ded5078-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg 
developers
   built with gcc 13.2.0 (Rev5, Built by MSYS2 project)
   configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads 
--disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 
--enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist 
--enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray 
--enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d 
--enable-libdavs2 --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-librav1e 
--enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 
--enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg 
--enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype 
--enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf 
--enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va 
--enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi 
--enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio 
--enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb 
--enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc 
--enable-libcodec2 --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus 
--enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite 
--enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
   libavutil      59. 19.100 / 59. 19.100
   libavcodec     61.  5.104 / 61.  5.104
   libavformat    61.  3.103 / 61.  3.103
   libavdevice    61.  2.100 / 61.  2.100
   libavfilter    10.  2.102 / 10.  2.102
   libswscale      8.  2.100 /  8.  2.100
   libswresample   5.  2.100 /  5.  2.100
   libpostproc    58.  2.100 / 58.  2.100
Input #0, mpegts, from 'concat:SEGMENT_1|SEGMENT_2':
   Duration: 02:47:54.15, start: 31.712367, bitrate: 20859 kb/s
   Program 1
     Metadata:
       service_name    : Service01
       service_provider: FFmpeg
   Stream #0:0[0x1011]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080 
[SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 90k tbn
   Stream #0:1[0x1100]: Audio: dts (dca) (DTS-HD MA) ([130][0][0][0] / 0x0082), 48000 Hz, mono, s32p 
(24 bit)
Stream mapping:
   Stream #0:0 -> #0:0 (copy)
   Stream #0:1 -> #0:1 (copy)
Output #0, mpegts, to 'TARGET':
   Metadata:
     encoder         : Lavf61.3.103
   Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080 [SAR 
1:1 DAR 16:9], q=2-31, 23.98 fps, 23.98 tbr, 90k tbn
   Stream #0:1: Audio: dts (DTS-HD MA) ([130][0][0][0] / 0x0082), 48000 Hz, mono, s32p (24 bit)
[mpegts @ 00000000003c2c80] Packet corrupt (stream = 0, dts = NOPTS).
[out#0/mpegts @ 00000000004a7400] video:23082127KiB audio:1345500KiB subtitle:0KiB other 
streams:0KiB global headers:0KiB muxing overhead: 5.013221% size=25652238KiB time=02:47:48.97 
bitrate=20870.4kbits/s speed=5.47x


Note the line: "[mpegts @ 00000000003c2c80] Packet corrupt (stream = 0, dts = NOPTS)."
Which packet? What PTS?

Last Thought: Video is Legos.


More information about the ffmpeg-user mailing list