2

I need to transcode a video to another one with the following properties:

  • GOP size is always fixed at a given value
  • Only IDR frames are used as key-frames (not I-slices)
  • SPS/PPS/VPS frames are repeated every time before the IDR frame.

Is there a way to do this with ffmpeg?

Also, it would be great if you can also tell me of a simple way of verifying all this (perhaps using ffprobe?).

4
  • Which output format?
    – Gyan
    Aug 26, 2019 at 15:36
  • H.265 output format.
    – Elektito
    Aug 26, 2019 at 15:39
  • As in, a raw bitstream?
    – Gyan
    Aug 26, 2019 at 15:42
  • Frankly, doesn't really matter. I can fix the container if I need to, later. But the raw stream is what matters to me.
    – Elektito
    Aug 26, 2019 at 15:43

1 Answer 1

5

Minimal command line, for a GOP size of 2 seconds:

ffmpeg -i input -force_key_frames expr:gte(t,n_forced*2) -c:v libx265 -x265-params open-gop=0:scenecut=0:repeat-headers=1 output.hevc

Verification:

ffmpeg -i output.hevc -c copy -bsf:v trace_headers -f null -

After each line containing key frame e.g.,

Packet: 18115 bytes, key frame, no pts, dts 2319977, duration 40000.

You should see the VPS/SPS/PPS. The first Slice Segment Header that follows should have a NAL unit type of 20 which is IDR_N_LP.

ffprobe can't invoke bitstream filters.

6
  • The seems to be working. Thanks. The verification command doesn't work for me though ("Unknown bitstream filter trace_headers"). Also, not that it's a problem, but there is a "supplemental enhancement information" NAL after VPS, SPS and PPS which wasn't there before. Could you tell me why this particular command causes that to appear?
    – Elektito
    Aug 27, 2019 at 7:28
  • Oh, and also, the expr:gte(t,n_forced*2) part of the first ffmpeg command needs to be quoted. I'd suggested you edit that in the interest of the future copy-pasters!
    – Elektito
    Aug 27, 2019 at 8:17
  • So maybe I was wrong. I tried this with another video and looks like it does not always work. Keyframes frequently happen before the 250 frames (10 seconds) that I set is up (I'm assuming the n_forced*2 determines GOP size and I changed it to n_forced*10). I tried adding min-keyint=250:keyint=250 to the x2675 params. No effect. I also tried the -g option of ffmpeg. Still the same thing happens.
    – Elektito
    Aug 27, 2019 at 11:51
  • if your source is a container with VFR stream and/or fps < 25, then there may not be 250 frames in a 10 second interval. You can change t to n and the value to a frame distance
    – Gyan
    Aug 27, 2019 at 14:40
  • The FPS I'm sure is 25 (or so ffprobe says). I'm not sure about VFR (that's variable frame rate, right?), but I think it's unlikely. I think the problem is that whatever we do libx265 seems to not honor min-keyint. Your force_key_frames option does work and it fixes my main issue, but x265 right at the beginning says that Keyframe min / max / scenecut : 126 / 250 / 0 even though I've set both min-keyint and keyint to 250.
    – Elektito
    Aug 27, 2019 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.