I'm using Boundary Devices Nitrogen6x with the Yocto Linux BSP (daisy).
I have written code to drive the VPU using the native API (vpu_lib.h) in order to encode h.264 at 1080p. I've based my code on this: imx-testing-apps-misc/libvpu_encode.c at master · ahmedammar/imx-testing-apps-misc · GitHub but also cross-checked it against how things are done in mfw_gst_vpu_encoder.c from the Gstreamer plugins.
I can correctly generate h.264 - the bitstream plays correctly using ffmpeg, and h264_analyze reports (as does EncOutputInfo::picType) that the first frame is an I-frame and subsequent frames are P-frames. I can vary this appropriately by setting EncOpenParam::gopSize or by using EncParam::forceIPicture.
So far so good. However, the size of my P-frames is exactly the same as the size of I-frames - for fixed quantization the output bitrate is the same whether I use all I-frames (gopSize=1) or I and P frames (gopSize>1).
If I set CBR by putting EncOpenParam::bitrate>0 then I do get the bitrate that I asked for, but if I encode a static image, then the qp for each frame gets worse over time rather than better (as you'd expect) - again, consistent with each P frame actually being coded like an I frame.
I know this is not a hardware problem because when I use gstreamer I don't see the same effect - much smaller P frames than I frames for fixed qp, and qp getting better in each frame for CBR encoding of a static image. So clearly I am doing something wrong - but I have now tried just about every combination of parameter and nothing seems to change.
Has anyone ever seen this effect before? For various reasons, I don't just want to give up and use gstreamer, so I need to find a way of fixing this!