Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-27T07:28:01.777Z
Answers.Text: 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?
Answers.UserDisplayName: Elektito
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-27T08:17:33.000Z
Answers.Text: 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!
Answers.UserDisplayName: Elektito
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-27T11:51:06.640Z
Answers.Text: 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.
Answers.UserDisplayName: Elektito
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-27T14:40:50.887Z
Answers.Text: 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
Answers.UserDisplayName: Gyan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-27T15:04:58.870Z
Answers.Text: 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.
Answers.UserDisplayName: Elektito
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-27T15:34:43.683Z
Answers.Text: If scenecut is 0 then x265 may insert non-IDR I-slices - those aren't keyframes.
Answers.UserDisplayName: Gyan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-26T16:37:07.820Z
Answers.LastActivityDate: 2019-08-26T16:37:07.820Z
Answers.UserDisplayName: Gyan
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-08-26T15:36:03.237Z
Comments.Text: Which output format?
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-08-26T15:39:17.987Z
Comments.Text: H.265 output format.
Comments.UserDisplayName: Elektito
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-08-26T15:42:10.937Z
Comments.Text: As in,  a raw bitstream?
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-08-26T15:43:41.007Z
Comments.Text: Frankly, doesn't really matter. I can fix the container if I need to, later. But the raw stream is what matters to me.
Comments.UserDisplayName: Elektito
Tags: <ffmpeg><h265><hevc>
Title: ffmpeg/x265: fixed-GOP, IDR only keyframes, repeating headers
UserDisplayName: Elektito
ThreadText: # 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.  
  
  ---
  
  