Open Vavooon opened 1 year ago
H264 levels - https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Levels
The default is level 4.0 (the spec for the encoder), which can do 1080p30 or 720p68.
Exceed the rates defined for the configured level and the encoder will reject it when you attempt to start it.
Use v4l2src extra-controls extra-controls="foo,h264_level=13
.
More recent versions of GStreamer it will take the H264 level from the caps, so making it video/x-h264,width=1280,height=720,framerate=30/1,level=(string)4.2
should do the same thing (it certainly applies to v4l2h264enc, but don't know if it applies to v4l2src).
Thanks for the explanation.
It does help to use v4l2src extra-controls="foo,h264_level=13"
in 720p mode.
Although, I rather wanted to report a problem with false capabilities advertisement provided by camera V4L2 interface. Again, the issue I see here is inability to pick highest available frame rate for the specified resolution when running a GStreamer pipeline without explicitly specified frame rate. E.g. when I run:
v4l2-ctl --device=/dev/video0 --list-frameintervals width=1920,height=1080,pixelformat=H264
It says:
ioctl: VIDIOC_ENUM_FRAMEINTERVALS
Interval: Continuous 0.011s - 1.000s (1.000-90.000 fps)
Which is high above supported capabilities, so running something like gst-launch-1.0 v4l2src device=/dev/video0 extra-controls="foo,h264_level=13" ! video/x-h264, width=1920, height=1080 ! rtph264pay
makes the same issue.
So the expected behavior to me is to advertise correct frame rates over V4L2 interface, e.g. 1080p30/720p60 for V2 camera or whatever is possible/officially advertised.
It's a really a mismatch between the V4L2 API and how to expose the capabilities of the SoC.
For VIDIOC_ENUM_FRAMESIZES you either list discrete resolutions, or you can return CONTINUOUS or STEPWISE as you have cropping or scaling that can produce any output resolution. For each resolution and pixel format you can then list the supported frame rates via VIDIOC_ENUM_FRAMEINTERVALS. However if you're dealing with H264 just having the resolution and pixel format is insufficient as you need the codec level as well. There's no nice way to integrate that use of a control in with the VIDIOC_ENUM_FRAMEINTERVALS, so depending on how the last user left the control you could get any number of answers from the call.
Seeing as the legacy camera stack is deprecated in favour of libcamera, it's not a priority for us to fix it.
The lockup when you do exceed the H264 limit is a bug. I thought I'd sorted that a while ago (I remember it just being some state not cleaned up in the error path), but I guess either my memory is going, or the fix has been dropped due to a merge conflict.
Ok, thanks for the explanation. Unfortunately the legacy camera stack is the only way for me to work with H.264 video streaming on old Raspberry Pi models since it gives acceptable performance.
I hope this issue will help other people who could be affected by the problem.
Describe the bug
I use GStreamer with
v4l2src
and legacy camera stack for H.264/RTP streaming from Raspberry Pi camera v2.1. While 720p60 and below modes work fine, ones with higher frame rates (720p75, 720p90) can only be executed once.While I'm completely happy with 720p60, the problem I see here is that it won't work with default params, since GStreamer automatically selects highest available frame rate for given resolution which is 90 in my case.
Working pipelines:
gst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! fakesink
gst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=60/1 ! h264parse ! fakesink
Problematic pipelines:gst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=75/1 ! h264parse ! fakesink
gst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=90/1 ! h264parse ! fakesink
When I try the same command for second time, GStreamer fails with error
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory.
I have to reload the module in order to make it working again:
sudo rmmod bcm2835_v4l2; sudo modprobe bcm2835_v4l2
Steps to reproduce the behaviour
gst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=90/1 ! h264parse ! fakesink
Ctrl+Cgst-launch-1.0 v4l2src ! video/x-h264,width=1280,height=720,framerate=90/1 ! h264parse ! fakesink
Device (s)
Raspberry Pi Zero, Raspberry Pi 1 Mod. B
System
raspinfo.txt
Logs
720p30 start/stop log
720p90 first start/stop log
720p90 second start/stop log (with issue)
Additional context
No response