[Feature]can I add Iframe or request it after the encoder is started
I am using H264 encoder like this,
=== Encoder and recording ===
encoder = H264Encoder(bitrate=1500000,repeat=True)
FPS is set using, # === FPS and grayscale helpers === def set_fps(us_per_frame): picam2.set_controls({"FrameDurationLimits": (us_per_frame, int(1e6/3))})
Is it possible to change the -g value dynamically ? I want to send key frame every 2 seconds
Hi, thanks for suggesting this. I didn't fully understand what you wanted, but am I right in thinking you will be running the camera at a variable framerate, so you want an I-frame every 2 seconds, rather than (for example) every 60 frames?
I guess one solution would be to update the GOP size (I-frame period) dynamically, or another would be to have no I-frames at all except when the application says "give me one now". I think the "give me one now" approach is possibly more useful - I can imagine other kinds of application wanting that, maybe when a sudden change of scene is detected.
Both might be possible. Presumably we could just update the GOP size and (hopefully) the change will just be respected by the underlying software/hardware.
You don't say if you're using a Pi 5 or an earlier model. For a Pi 5, I think we can tell PyAV to give us an I-frame, and for earlier Pis with hardware encoders we have the V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME ioctl.
I wonder whether it's enough just to say to the encoder "give me that I-frame" and you'll get one "very soon", or whether it's worth being able to flag particular images as needing to be I-frames? It would be possible to flag images like that before they get to the encoder, though it would have to go in the main camera processing loop - so I'm not entirely sure how you could know for that frame in a timely manner. So maybe the vaguer "just give me that I-frame" is the way to go?
Actually, on reflection, I think V4L2 has a queue of buffers and you don't know for sure exactly where the codec is in this queue. The V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME ioctl isn't associated with any of the buffers so it behaves asynchronously, meaning I don't think think you can reliably target it at specific frames. So "just give me that I-frame" does look like the way to go.
This allows you to force an I-frame spontaneously at any moment. If you don't want any other I-frames besides these (except for the very first, of course), set the iperiod=0 when you create the encoder.
https://github.com/raspberrypi/picamera2/pull/1317
This will help. I wanted to sync the person detected event with the video. Since the g value is constant and framerate is changed I was struggling to align the event with recording.