userland: Dispmanx fails with zero-copied MMAL buffer?
It seems that Dispmanx fails with zero-copied MMAL buffer.
Please try with this code:
https://github.com/Terminus-IMRC/dispmanx-fails-with-zero-copied-mmal-buffer
This code gets 128x128 random image from vc.ril.source
component and feeds it to dispmanx to display it on screen.
If you keep #define ZERO_COPY 0
, it will work.
If you change this to #define ZERO_COPY 1
, it will fail with this error:
main.c:85: Dispmanx call failed: 0xffffffff
I also confirmed this issue with vc.ril.camera
component.
Am I wrong in usage of the APIs?
Thanks.
About this issue
- Original URL
- State: open
- Created 7 years ago
- Comments: 25 (23 by maintainers)
Standards. V4L2 is the Linux standard interface for cameras and codecs, and supports things like dmabufs for zero copy of data into DRM/KMS. Whilst that can be done with MMAL it requires a load of extra setup to be done by the app. GStreamer already supports an optimised decode path, and patches for FFmpeg are in the pipeline by others.
I have a long patchset of cleaning up the V4L2 camera driver and adding a V4L2 codec driver. Not ready for a PR yet, but I’ve pushed it to https://github.com/6by9/linux/tree/rpi-4.14.y-codecs-push2. https://github.com/6by9/linux/commit/07e61b8efa2490097ff7e5304307d26c107d68e8 is the commit that may fix it.
I think you’re correct there. They are both writing data into an existing DispmanX resource, so they have to copy the pixel data. I’m not sure if there is an API call that allows a client to pass in an existing MEM_HANDLE_T to be used as the source data. I couldn’t see it with a quick look.
Everything looks sane in your code, but you are perfectly correct that dispmanx rejects the buffer. Enabling VPU side asserts I see
firing every time the dispmanx call is being made. That is a VCHI bulk receive call failing The cause appears to be the bulk transfer aborting, but I’ve not drilled down into why.
@pelwell Any immediate thoughts? vchiq_bulk_transfer in vchiq_core.c is failing through the
else if (bulk_waiter.actual == VCHIQ_BULK_ACTUAL_ABORTED) {
clause on the bulk receive on the VPU side. Is the transfer going to get upset that source and destination are both in the reloc heap?