<p>Minimal command line, for a GOP size of 2 seconds:</p>

<p><code>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</code></p>

<p>Verification:</p>

<pre><code>ffmpeg -i output.hevc -c copy -bsf:v trace_headers -f null -
</code></pre>

<p>After each line containing key frame e.g.,</p>

<pre><code>Packet: 18115 bytes, key frame, no pts, dts 2319977, duration 40000.
</code></pre>

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

<p>ffprobe can't invoke bitstream filters.</p>

CC BY-SA 4.0
2019-08-27T07:28:01.777Z
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
CC BY-SA 4.0
2019-08-27T08:17:33.000Z
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
CC BY-SA 4.0
2019-08-27T11:51:06.640Z
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
CC BY-SA 4.0
2019-08-27T14:40:50.887Z
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
CC BY-SA 4.0
2019-08-27T15:04:58.870Z
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
CC BY-SA 4.0
2019-08-27T15:34:43.683Z
If scenecut is 0 then x265 may insert non-IDR I-slices - those aren't keyframes.
Gyan
CC BY-SA 4.0
2019-08-26T16:37:07.820Z
2019-08-26T16:37:07.820Z
Gyan
<p>I need to transcode a video to another one with the following properties:</p>

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

<p>Is there a way to do this with ffmpeg?</p>

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

CC BY-SA 4.0
2019-08-26T15:36:03.237Z
Which output format?
Gyan
CC BY-SA 4.0
2019-08-26T15:39:17.987Z
H.265 output format.
Elektito
CC BY-SA 4.0
2019-08-26T15:42:10.937Z
As in,  a raw bitstream?
Gyan
CC BY-SA 4.0
2019-08-26T15:43:41.007Z
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
<ffmpeg><h265><hevc>
ffmpeg/x265: fixed-GOP, IDR only keyframes, repeating headers
Elektito
# ffmpeg/x265: fixed-GOP, IDR only keyframes, repeating headers

(Asked by: username_0 on 2019-08-26)

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?).

**Tags:** ffmpeg, h265, hevc

> **Comments:**
> **username_1**: Which output format?  
> **username_0**: H.265 output format.  
> **username_1**: As in,  a raw bitstream?  
> **username_0**: Frankly, doesn't really matter. I can fix the container if I need to, later. But the raw stream is what matters to me.  

---

## 1 answers

### Answer by username_1 on 2019-08-26. Score: 5 | Accepted answer

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.

> **Comments:**
> **username_0**: 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?  
> **username_0**: 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!  
> **username_0**: 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.  
> **username_1**: 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  
> **username_0**: 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.  
> **username_1**: If scenecut is 0 then x265 may insert non-IDR I-slices - those aren't keyframes.  

---

