V4l2 ioctl to reset the encoder

Hi

i want to encode singular AV1 I frames in a very specific size, and in order to do that i need encoder settings that will give me the same image size every time i compress the same image with the same requested bitrate

now, i know that if i try to do that , i’ll get a different size value every time until it stablizes, is there any way(probably a v4l2 ioctl) that can “reset” the encoder and give me the same output regardless of history?

thanks, etay markman

*** Please note that this reply is generated by LLM automatically ***

To address your question, we need to delve into the specifics of the Jetson AGX Orin’s video encoding capabilities and the V4L2 API.

The Jetson AGX Orin series supports hardware-accelerated video encoding, including H.264, H.265, and VP9. However, it does not natively support AV1 encoding. To achieve AV1 encoding, you would need to use a software-based encoder or a third-party library that provides AV1 encoding capabilities.

Regarding your requirement for consistent output size when encoding I-frames with a specific bitrate, this is a challenging task due to the nature of video encoding. The output size of an encoded frame depends on various factors, including the input frame’s complexity, the bitrate, and the encoder’s settings.

In V4L2, there is no specific ioctl that can reset the encoder to produce the same output size every time. However, you can try using the VIDIOC_S_CTRL ioctl to set the V4L2_CID_MPEG_VIDEO_BITRATE control to a fixed value, which might help achieve more consistent output sizes.

Another approach is to use the VIDIOC_S_EXT_CTRLS ioctl to set the V4L2_CID_MPEG_VIDEO_BITRATE_MODE control to V4L2_MPEG_VIDEO_BITRATE_MODE_CBR (Constant Bitrate) or V4L2_MPEG_VIDEO_BITRATE_MODE_VBR (Variable Bitrate). This might help the encoder produce more consistent output sizes.

To further improve the consistency of the output size, you can also try setting the V4L2_CID_MPEG_VIDEO_GOP_SIZE control to a fixed value, which will help the encoder maintain a consistent Group of Pictures (GOP) size.

It’s essential to note that even with these settings, the output size might still vary slightly due to the inherent variability of video encoding.

Here’s an example of how you can use the VIDIOC_S_CTRL ioctl to set the bitrate control:

struct v4l2_control control;
control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
control.value = desired_bitrate;

if (ioctl(fd, VIDIOC_S_CTRL, &control) < 0) {
    perror("VIDIOC_S_CTRL");
    return -1;
}

Similarly, you can use the VIDIOC_S_EXT_CTRLS ioctl to set the bitrate mode control:

struct v4l2_ext_control control;
control.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
control.value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;

if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &control) < 0) {
    perror("VIDIOC_S_EXT_CTRLS");
    return -1;
}

Keep in mind that these are just suggestions, and the actual behavior of the encoder might vary depending on the specific implementation and the input data.

In summary, while there is no single ioctl that can guarantee consistent output sizes, you can try using a combination of V4L2 controls to achieve more consistent results. However, the variability of video encoding might still affect the output size to some extent.

*** Please give the thumbs up if you get answers you like. Or provide feedback to help us improve the answer. ***

Hi,
You may use external rate control hints to set QP value of each frame. Please refer to the example:
Cbr ratecontrol and QP ranges - #8 by DaneLLL

Hi, trying that right now actually, but for some reason, the output frame’s minimum Qp is always 1 and the maximum is the minimum i put in the hints struct, the frame size is far off from the target bits

is it a known problem or an i doing something wrong?

tried in the sample and it produced the same issue

Hi,
Do you mean encoded frame does not have QP value in the range nFrameMinQp and nFrameMaxQp?

exactly, it’s literally in the range 1-nFrameMinQp

and after further research i found out that it only happens with AV1, on H265 and H264(on the sample) it worked fine, note that i am using jetpack 6.1 and i need to work with AV1

Hi,
We run the commands on developer kit and can see size of the stream is different:

01_video_encode$ gst-launch-1.0 videotestsrc num-buffers=66 ! video/x-raw,width=1280,height=720,format=I420 ! filesink location=~/1280_720.yuv
01_video_encode $ echo "166666 25 24 26 0" > hints.txt
01_video_encode $ ./video_encode ~/1280_720.yuv 1280 720 AV1 ~/av1.ivf -idri 45 --insert-spspps-idr
01_video_encode $ ./video_encode ~/1280_720.yuv 1280 720 AV1 ~/av1_1.ivf -idri 45 --insert-spspps-idr --erh -hf hints.txt --input-metadata
01_video_encode$ ll ~/av1*
-rw-rw-r-- 1 nvidia nvidia 5475810 Jan 15 07:38 /home/nvidia/av1_1.ivf
-rw-rw-r-- 1 nvidia nvidia 1262047 Jan 15 07:36 /home/nvidia/av1.ivf

Do you know how to parse the stream to get QP value of each frame? We use the parser:
GitHub - yohhoy/av1parser: AV1 video codec bitstream parser (not decoder!)

But it seems like it does not print out QP value. Not sure if you have the tool for parsing QP value out.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.