GOP structure via FFmpeg
Asked Answered
H

2

5

I have two questions regarding the Group-of-Pictures (GOP) in MPEG4 Video (both for MPEG4 Part2 and H.264):

  1. How can I extract the GOP structure and size of a video sequence using FFmpeg? I know that the av_get_picture_type_char function of the AVPicture struct yields picture types for each frame, but I wonder if there is a more direct method to obtain the GOP information?

  2. How can I detect whether the sequence has open GOPs or closed GOPs, i.e. whether B frames from one GOP are allowed to refer to the I and P frames in an adjacent GOP?

Harpoon answered 25/9, 2015 at 12:39 Comment(0)
P
6

None of this is directly exported in ffmpeg, so you'll have to figure these things out yourself. So the short answer for 1 is "no". If you parse the frames (you don't need to decode them) and get the frame type, you should be able to identify location in file (offset, in bytes) in AVPacket.pos. For each I-frame in the sequence, search packets after it and note AVPacket.pos and AVPacket.pts. If B(pos) > I(pos) but B(pts) < I(pts), you have open GOP, else closed GOP. If you want to be more precise, find some way to export the POC from the h264 parser, which is directly proportional to the timestamp.

The parsing loop would just be av_read_frame().

Pris answered 25/9, 2015 at 16:0 Comment(3)
Thanks. Can you elaborate on why there is an open GOP if B(pos) > I(pos) but B(pts) < I(pts)?Harpoon
PTS = POC. If you have a frame that is (in bitstream / coding order) after an I-frame, but has a POC/pts before it, it almost universally means it uses that I as a reference, and thus open GOP. The official way to confirm that is parse the reference list from the headers and make sure the I is in the reflist for the B, but I doubt you want to go that far (unless this is academic in nature).Pris
Not that simple. Closed GOP can begin with two B frames too, either B Unidirectional frames or real B frames. Then it is a closed GOP. See, so you need to see which frames these two B frames depend on: forum.videohelp.com/images/imgfiles/Df6d4pR.jpgWharf
S
2

The following ffprobe cmdline works for me:

ffprobe -hide_banner -show_frames -i video.mp4 | egrep pict_type

Sample output:

pict_type=I
pict_type=B
pict_type=B
pict_type=P
pict_type=B
pict_type=B
pict_type=P
...

I believe that grepping for pkt_size gives you the encoded size of each frame, but I could be wrong.

See also How to calculate GOP size of a file H264

Edit: see also llogan's comment below.

Schulein answered 15/7, 2021 at 15:13 Comment(1)
No need for egrep with ffprobe -v error -show_entries frame=pict_type -of default=nw=1 input.mp4Pastiche

© 2022 - 2024 — McMap. All rights reserved.