Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Setting profile="high" for H264Encoder causes OSError: [Errno 22] Invalid argument #1097

Open
03vmate opened this issue Aug 25, 2024 · 3 comments

Comments

@03vmate
Copy link

03vmate commented Aug 25, 2024

Trying to set profile="high" for H264Encoder causes the following:

Traceback (most recent call last):
  File "/home/pi/test.py", line 24, in <module>
    picam2.start_encoder(encoder, output, quality=Quality.HIGH)
  File "/usr/lib/python3/dist-packages/picamera2/picamera2.py", line 1712, in start_encoder
    _encoder.start(quality=quality)
  File "/usr/lib/python3/dist-packages/picamera2/encoders/encoder.py", line 231, in start
    self._start()
  File "/usr/lib/python3/dist-packages/picamera2/encoders/h264_encoder.py", line 87, in _start
    super()._start()
  File "/usr/lib/python3/dist-packages/picamera2/encoders/v4l2_encoder.py", line 111, in _start
    fcntl.ioctl(self.vd, VIDIOC_S_EXT_CTRLS, ext)
OSError: [Errno 22] Invalid argument

baseline and main work properly, only high causes the exception.

Example code :

from picamera2 import Picamera2
from picamera2.encoders import H264Encoder, Quality
from picamera2.outputs import FileOutput
import time

picam2 = Picamera2()

config = picam2.create_video_configuration(
    raw = None,
    lores = None,
    main = {
        "size": (1440, 1080)
    }
)

picam2.align_configuration(config)
picam2.configure(config)
picam2.set_controls({"FrameDurationLimits": (50000, 50000)}) # 20 FPS


output_file = open("output.h264", "wb")
output = FileOutput(output_file)
encoder = H264Encoder(repeat=True, iperiod=10, enable_sps_framerate=True, framerate=20, profile="high")
picam2.start_encoder(encoder, output, quality=Quality.HIGH)
picam2.start()

time.sleep(10)

picam2.stop()
picam2.stop_encoder()

Using Pi4 with HQ camera, Python 3.11.2, picamera2 0.3.19, libcamera v0.3.0+65-6ddd79b5, Linux 6.6.31+rpt-rpi-v8

@davidplowman
Copy link
Collaborator

davidplowman commented Aug 27, 2024

Hi, thanks for reporting this. Yes, it does indeed seem to be broken.

The problem is that the value of V4L2_MPEG_VIDEO_H264_PROFILE_HIGH is incorrect in the python-v4l2 package. I'll make up a PR and ask the repository owner to merge the fix. Then we'll have to make up an updated package, so it may all take a few days.

If you want a fix in the meantime, I might check out git clone https://github.com/RaspberryPiFoundation/python-v4l2 and then add the folder where you put it to your PYTHONPATH environment variable. Then, look in the file v4l2.py in there, and find V4L2_MPEG_VIDEO_H264_PROFILE_HIGH. Just above that add the following new line:

V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED,

Also change the range(4) below it to range(5). Then things should work.

@03vmate
Copy link
Author

03vmate commented Aug 27, 2024

@davidplowman Thanks for the workaround, one semi-related question: I was not able to find anything about the "default" profile when not specifying the profile parameter. What does it default to?

@davidplowman
Copy link
Collaborator

Haha, good question. It seems to leave it entirely to the hardware driver which, I think, sets it to... (drum roll)

https://github.com/raspberrypi/linux/blob/rpi-6.6.y/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c#L3302

High! So it looks like leaving it out altogether would also be a workaround. Obviously would be worth checking in practice. Oh well.

The patch has also been merged now, so just waiting for a new apt package to be made up. (You could install it with pip too, but mixing pip and apt packages often seems to lead me to a dark place.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants