-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Gstreamer errors on specific h264 bytestream on Bullseye and Buster, works if Buster has firmware downgraded. #1673
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
Comments
@6by9 Not sure if you will have seen this so flagging up just in case. |
Found another pi 4 that is unafflicted, revision code If I had to wager a guess here - if I'm reading how to decode revision codes correctly, the only link I see is that this isn't affecting revision 1 pi 4s |
It seems extremely unlikely (not impossible) this is revision based - the differences are on the whole unrelated to the issue being described. I'd suspect a timing problem, but @6by9 is more likely to figure it out than I am. |
I agree the board revision is unlikely to be significant. |
This has been a different sdcard per Pi (one of them was USB boot, as well), but all set up using the same installation script on top of vanilla raspbian bullseye. |
Are you able to swap sdcard between a working and non-working board and confirm the problem remains with the board (and not the sdcard)? |
A long shot - add |
Swapping the physical sdcard won't be possible here due to the distances between pis, but what I can do is take an image of the working pi's sdcard, and flash it into the sdcard of a non working pi. Will report back with results (and over_voltage test as well) when I have them. |
Tested b03111, a03111, c03112 on the same image (https://github.com/icecube45/G37_Builder/suites/4934864438/artifacts/142769129) without any other modifications. |
Managed to source another pi (b03112) locally and tested an sd card swap from a pi that was working (with the same, unmodified image as linked above), and the issue did not appear. |
Continuing to gather whatever information I can that may be relevant. |
Ok! I did a lot more digging into this and think I found not only the actual core of this issue, but also a proper means of replicating it. I will edit the issue title to properly reflect this. It's not a matter of revision (as @JamesH65 properly guessed), nor is it an SD card issue (as @popcornmix suggested testing - I was able to swap cards on "bad" and "good" pis finally). The attached .h264 file replicates this issue on all pi revisions I've tested on so far, by running On bullseye: This command and testfile always fails with "Internal data stream error", regardless of firmware version On buster: This command fails with "No valid frames decoded before end of stream" when on latest firmware, after a |
The colour description fields translates to the V4L2 colourspaces - https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-defs.html Trying on Bullseye, (GStreamer 1.18.4), the kernel logging from V4L2 shows a load of attempts at TRY_FMT on the encoded stream which doesn't inherently have a colourspace), but no format being set or buffers passed in.
The GStreamer logging shows:
so I suspect it to be a colourspace mapping thing, and h264parse0 ends up saying that it can't produce something that meets the caps advertised by h264v4l2dec Enabling more logging with
so I read that as h264parse viewing the stream as ffprobe decodes your clip as " bt470bg/bt470bg/smpte170m". |
@6by9, thank you for looking into this.
Bear with me here as I try and explain why I think this is the case - I might be misinterpreting things. I've repeated your logging on Buster, with fully updated firmware, and downgraded firmware below the commit that this issue first started appearing. I've replaced the gstreamer logging for a dot file export. The dmesg and resultant pipeline can both be found in the files at the end of this issue. In both cases, it looks as if v4l2 is setting the same format (I see two VIDIOC_S_FMT statements in each log, one for H264, one for YU12). Similarly, the gstreamer pipelines look identical, with no colorspace cap on h264parse, and v4l2h264dec spitting out bt601. These tests are what made me feel like something more underlying firmware based is occurring. For the case of bullseye, it does look as if gstreamer is failing to link, for the reasons you mentioned (colorspace caps). That is to say, I can replicate your results. Similarly, I can get the gstreamer pipeline to link if I lie to it using capssetter: And because I was curious, I downgraded the firmware and combined it with the capssetter linking - no difference. Buster, firmware up to dateBuster, old firmwareBullseye, updated firmware, video signal removed from testfile.Bullseye, updated firmware, capssetter |
So decoding that
range = 1 -> GST_VIDEO_COLOR_RANGE_0_255 So it is correct that that your stream doesn't match any of the "standard" colorimetries . However there is the question as to whether h264parse should really be caring about the colorimetry of the encoded stream, or v4l2h264dec should care on the sink pad for the encoded data. Unfortunately I don't think v4l2h264dec gets a choice about it, as it just advertises the list of things it'll support in the caps, and the src pad then matches it. Otherwise the comment at https://github.com/GStreamer/gst-plugins-good/blob/master/sys/v4l2/gstv4l2object.c#L2394
is an invalid choice in v4l2h264dec. |
Having enabled the V4L2 and videobuf2 logging, it looks like GStreamer doesn't implement the dynamic resolution change handling required by the V4L2 Stateful Decoder Interface. After parsing the H264 headers the decoder has noted a change in the colourspace, and so triggered a resolution/format change event.
GStreamer hasn't subscribed to these events (
On the next DQBUF the decoder does generate a -EPIPE
The client doesn't (it misinterprets the -EPIPE as only applying to EOS documented under DRAIN), and therefore decode stops. gstv4l2src calls Ah https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/240 |
Double checking this (though I don't think it matters in the wider picture of what's going on) Sounds like an update to gstreamer (or well, the plugins) is needed to correct this, then? |
Yes, typo by me. It's 16_235.
AFAICT this is GStreamer not following the spec, so it would be an update required to the plugin. |
I went ahead and recompiled gst-plugins-good with the PR you linked above - the capssetter pipeline works in that case, so seems as though you're correct in the issue at play here. |
Seeing as that MR was started 2 years ago, the v4l2src rework was 11 months ago, I suspect it's stalled at present. I'm amazed it'll still apply and compile after all that time. You may find that changing https://github.com/raspberrypi/linux/blob/rpi-5.15.y/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c#L2533 so MMAL_PARAMETER_VIDEO_STOP_ON_PAR_COLOUR_CHANGE is set to 0 instead of 1 will workaround the issue - that could be done as a module parameter. We can't just ignore the parameter at the kernel level as the firmware will already have stopped when it saw the change. |
You also need to stop it setting the
All of these command lines have then worked
|
Thank you - confirming I can replicate your results by applying the same patch |
Does NXP MR for resolution changes works with your driver? I've been waiting all this time for folks to actually test this, but I see that workaround in drivers / firmware is more tempting. Note that the submitter has be very slow fixing review comments, but I can take over if some tested-by comment showed up. |
For an update, I realized you are looking at an old MR, the current implementation is here: |
@ndufresne once I get some free time (rare for these next 3 weeks), I'll give a go at compiling the MR linked, and testing the above pipeline with it |
I've not even looked at how the trees have changed. |
It might be easier to backport that change to GStreamer 1.20 and ship a patched GStreamer 1.20 in Raspberry Pi OS as backport. During GStreamer 1.19 development, quite a few bug fixes in GStreamer affecting streaming on a Raspberry Pi were merged. I went forward from 1.18 and it has been a tremendous improvement. |
I've been exploring the capssetter fix, to try to perfect it. @IceCubes's
This replaces the "true" colorimetry value 1:3:5:1 (that v4l2 can't find a match to) which I always seem to see on Apple's AirPlay h264 streams, with bt709, which seems to be the appropriate one, but ideally, I would like to just delete the colorimetry entry from the caps as @icecube45 's fix does (in that case, by omitting it but replicating all the other caps entries, and using replace=true). can someone confirm that there is no way to use capssetter to just remove one caps entry, leaving the others in place, (replace = false, join = true) without specifying them? (If not, it would be a good enhancement to capsetter to give it a "delete" capability something like ... ! capsetter caps="video/x-h264, colorimetry=(none)" ! ... ) With the capsetter fix, I encouragingly see a brief opening and closing of the window created by autovideosink ( I am on X11, not using kmssink, on R Pi 4B 8GB R Pi OS Bullseye 64bit Desktop), before the failure. The failure I see is now:
I assume (hope) the the "Duration invalid, not setting latency" is just a harmless warning, because the stream just started. What is the next step (patching v4l2 in gstreamer1.0-plugins-good, or kernel driver bcm2835-v4l2-codec.c ?) to try to demonstrate a fix. (I want to try to make sure that a fix to my issue exists and works, rather than just wait for the release cycle, and find out it's still broken). |
Raspberry Pi OS follows Debian unless there is a very good reason not to. Bullseye ships with GStreamer 1.18. |
The dynamic resolution change support is now queue or 1.22 release. Feel free to backport, obviously, 1.20 would be an easier target. The colorimetry issue remains, patch welcome of course. A new issue was reported today in the encoder, the driver does not allow "constrained-baseline", which is a bit of a non-sense as it expose its superset |
I have applied the "1381" patch to 1.20.0 (1.18.4 needs more work because other things would need to be backported too) Running on Manjaro GStreamer video pipeline is
very poor latency with an AirPlay stream of a youtube clip of a speech. GST_DEBUG=2 warnings are
fuller output is GST_DEBUG4.txt will try to build development branch. |
Now tested on main (1.21.0.1) as above. Same bad latency
|
Actually MUCH better news. the terrible latency was due to autovideosink choosing xvimagesink. so I would now say that the fix in 1.21.0.1 (plus the capssetter trick) works!
This means that the backport to 1.20 will be easy! (maybe it could get into 1.20.x?) 1.18 backport needs more investigation as changes in gstv4l2bufferpool will also need to be backported. need to test in kmssink, but I'm guessing it will be good. |
Yes, glupload will turn the decoder dmabuf into EGL image, which let the GPU sample the buffer directly, while XV requires 2 copied (1 to SHM, and the second into GL). The timestamp issue is on you though, since you use appsrc, its coming from you app. If you control the encoder, 1381 might be sufficient, but we samples that won't work as they have slightly different colorimetry from the "allowed list", which is partial really. This needs fixing in GStreamer still. |
I have posted a clean backport to 1.20.0 at FDH2/UxPlay#70. 1.18.4 backport seems like a nightmare, though. I don't control the encoding, but probably Apple does (I don't know it Apple reencodes media that it streams) , and it always seems to report as colorimetry 1:3:5:1; the substitution bt709 seems to give good results. Of course, if I patch, maybe I could find where the "allowed list" is defined, and add 1:3:5;1. |
Colorimetry is a combination of 4 parameters, hence the 4 numbers you get. Certain combinations have an alternate name based on the standards that apply.
and the list of defined standards is at https://github.com/GStreamer/gst-plugins-base/blob/master/gst-libs/gst/video/video-color.c#L66 Your 1:3:5:1 decodes as The standard BT709 colorimetry is the same except being GST_VIDEO_COLOR_RANGE_16_235. Don't ask me why Apple has chosen to encode full range - that's pretty uncommon within the video standards. I'm trying to backport to 1.18 at the moment. |
Backport pushed to https://github.com/6by9/gst-plugins-good/tree/1_18_res_change. It seems to work for me, so unless anyone else complains in the next few days, I'll send the 5 patches to be merged into Raspberry Pi OS. |
I'd like to test - how to get an updated package? |
@6by9 Since I will always get Apples choice, this seems to be a good fix. |
@ndufresne |
I've pushed a source branch - I don't build Debian packages. @fduncanh Thanks for testing. I'll send those patches to the relevant person to get Raspberry Pi OS updated. |
@bellum07 |
Thank you very much. |
I also tested on the 32-bit "lite" version using kmssink. Worked great as well. |
Raspberry Pi OS updated to include the backport today. |
@fduncanh Please start a new thread if you have a different issue. |
A regression was found and fixed in the new resolution change code: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1960 |
Thanks for the heads-up. I'll get that one backported too. |
there are two other of @ndufresne 's commits to master that need to be backported. I've checked that they work in 1.18.4 and can be added to your backport The first one is essential, without it there is a crash if the size of the video is changed, which requires a caps renegotiation https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/e2b2ff26c99723cbbe7129412cc707d0de6d78dd the second one didn't cause me any issues, but should also be added. https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/d394b8b4bdc229ab3a47dd6b666157b57b3eb8a3 |
Patches sent to the relevant person to be merged into Raspberry Pi OS. |
Uh oh!
There was an error while loading. Please reload this page.
Hi there, I work with a project that utilizes a C++ embedded gstreamer pipeline to process and display a h264 stream of video.
This pipeline, on a raspberry pi 4, resolves to:
appsrc name=mysrc is-live=true block=false max-latency=100 do-timestamp=true stream-type=stream ! queue ! h264parse ! v4l2h264dec ! videocrop top=0 bottom=0 name=videocropper ! capsfilter caps=video/x-raw name=mycapsfilter ! qtquick2videosink
(a dotfile was captured for this pipeline, here)
We're experiencing an issue where some Pi 4s updated to, or past, commit b4e395b3e87dba4964f314e12871630cabb35f70 error out on this pipeline, throwing
when these affected pis are downgraded below the stateful decode update commit, the embedded gstreamer pipeline works as expected.
Furthermore, these afflicted Pis can properly execute
gst-launch-1.0 filesrc location=testfile ! h264parse ! v4l2h264dec ! video/x-raw,format=I420 ! autovideosink
where
testfile
was recorded withappsrc name=mysrc is-live=true block=false max-latency=100 do-timestamp=true stream-type=stream ! filesink location=testfile
These afflicted Pis can also properly execute an embedded pipeline of
appsrc name=mysrc is-live=true block=false max-latency=100 do-timestamp=true stream-type=stream ! queue ! h264parse ! avdec_h264 ! videocrop top=0 bottom=0 name=videocropper ! capsfilter caps=video/x-raw name=mycapsfilter ! qtquick2videosink
Out of four Pi 4s this has been tested one, two were afflicted, and two worked even post the stateful decode update commit. All tested pis were on bullseye.
Afflicted revision numbers:
c03112
b03114
Unafflicted revision number:
b03111
a03111
I'd appreciate any help in resolving this manner, as I'm fully out of my depth debugging this issue further. Please let me know if you need any additional information.
The text was updated successfully, but these errors were encountered: