Skip to content

Vertically scaled dispmanx elements cause image corruption #277

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

Closed
julianscheel opened this issue May 16, 2014 · 17 comments
Closed

Vertically scaled dispmanx elements cause image corruption #277

julianscheel opened this issue May 16, 2014 · 17 comments

Comments

@julianscheel
Copy link

We ran into a quite odd issue using scaled dispmanx resources:
When we display more than 3 resources which are vertically scaled we get image distortions on the left half of the screen.
We can reproduce it with a clean raspbian which is just booted and shows the login prompt.

For demonstration we prepared a little tool, which draws a 4 "line" checkerboard, where each line is a dispmanx element. So when the fourth line appears the issue is triggered. To show the relation to scaling vertically the tool runs in 4 test modes:

  1. display unscaled
  2. display horizontally scaled
  3. display fully scaled
  4. display vertically scaled

Test 3 and 4 trigger the issue while 1 and 2 run without problems. Interestingly when running omxplayer the issue does either not occur or (what I think is more likely) the garbled content is covered by the video output. Unfortunaltely with our VLC mmal and omx plugins the video output does not cover the garbled content. We played around with the dispmanx layers but found no way to work around it.

You can find the code here: https://gist.github.com/julianscheel/96682459fcd6edb09ac5
And a precompiled binary here: http://jusst.de/files/dispman-test
And a picture showing the problem on stock raspian: 2014-05-16 10 08 14

This issue is especially painful when using VLC+mmal+DVB subtitles where frequently more than 3 layers are required and where we use dispmanx scaling capabilities.

@popcornmix
Copy link
Contributor

I haven't run the testcode yet, but can you try:

dispmanx_offline=1

in config.txt?

@julianscheel
Copy link
Author

Activating dispmanx_offline does not improve the behaviour.

Actually activating it introduces additional distortion in the checkerboard pattern itself when omxplayer is running in parallel.
But for the simple test, where only a framebuffer console is displayed when the test runs the distortions are the same.

@julianscheel
Copy link
Author

Have you been able to reproduce the issue?

@popcornmix
Copy link
Contributor

I can reproduce the issue. We are running out of context memory in the HVS.
The framebuffer is getting garbled because of this.

My understanding is that with dispmanx_offline=0, this behaviour is (probably) expected.
With dispmanx_offline=1 it shouldn't happen, so there is a problem here. (Note: the fallback for lack of context memory is multipass composition to an offscreen buffer which may have some memory/performance impact, so finding an alternative solution would be better).

If you don't require the framebuffer, it is always worth removing it (even when obscured it is still using normal memory, HVS context memory, and memory/HVS bandwidth).

One way of removing the framebuffer is:

tvservice -o && tvservice -p

and you can restore it with

fbset -depth 8 && fbset -depth 16

The amount of HVS context memory required if proportional to the number of layers on screen, with scaled layers requiring more context memory. The size of layers doesn't (I believe) affect it.
If you are able to combine the 3 subtitle layers into a single larger one, then that will reduce HVS context memory usage.

I'll talk to HVS expert about what's happening tomorrow and see why the offline case is failing, and whether there are any other solutions.

@julianscheel
Copy link
Author

Thanks for the details. Using dispmanx_offline, even if it wouldn't suffer this problem, doesn't seem to be a solution for us, as the video rendering performance breaks almost completely when enabling offline compositing.
So if there is no chance to increase the number of scaled layers we will probably have no other choice than merging the elements into a single layer in software. For the corner-case of dvb subtitles that shouldn't be too complicated. For other situations it might be more complex though. I will take a look at it tomorrow.

Is there an option to increase HVS context memory size? What stands HVS for, btw?

@popcornmix
Copy link
Contributor

HVS is hardware video scaler. The context memory is fixed in hardware (and 48K).
I'm a little surprised you are hitting the limit with such a simple scene (5 layers).
I've had dozens of (unscaled) layers without hitting this.

Perhaps the resize has a significant effect, or perhaps there is something else which is using context memory. I'll try to get some more answers tomorrow.

@julianscheel
Copy link
Author

What I find especially confusing is that only vertical scaling seems to have such a high impact. Using only horizontal scaling I am unable to reproduce the problem...
Looking forward to more details tomorrow :)

@popcornmix
Copy link
Contributor

I think the issue is you can horizontally scale in hardware with just a few pixels of context.
To vertically scale you require a number of complete rows (assuming memory is read linearly).
And short, wide rows are the worst shape.

@julianscheel
Copy link
Author

Merging subtitles into a single region in software turns out to be more complicated than I had hoped due to VLC architecture... So finding any workaround to increase the number of scalable elements to 5 or 6 would be really a major help for us...

@popcornmix
Copy link
Contributor

I've spoken to the expert. HVS context memory requires 16 bytes * min(src_width, dst_width) when vertically resizing (plus some much smaller contributions).
There is 96K of memory initially.

If alpha is not used that reduces to 12 bytes * min(src_width, dst_width).

Now it turns out that if the layers don't intersect vertically (as in your example code), then the context memory could in theory be reused. There is no code to support this special case, but the HVS guy said he'd think about adding that. No promises, but a possibility for the future.

He also pointed me at a commit that fixes the offline case. It also seems to avoid the corruption displayed in the non-offline case (elements just vanish when memory is exhausted). That will be in the next firmware update.

@julianscheel
Copy link
Author

Thanks for the update. The optimisation idea sounds promising as it would actually fit our real-world scenario.

Then another thought: Is it somehow possible to do manual offline composition of some elements into another one? The idea would be to offline composite all subtitle elements into one which can then be rendered without offline compositing onto the video.

@popcornmix
Copy link
Contributor

Yes, offline composition is supported. Look at:

vc_dispmanx_display_open_offscreen( DISPMANX_RESOURCE_HANDLE_T dest, DISPMANX_TRANSFORM_T orientation )

@julianscheel
Copy link
Author

Ah thanks, this is really interesting. I will try to port my hackish merge code to use that.
In an offscreen buffer it shall be possible to use more scaled elements, right? At least with the next firmware-update.

@popcornmix
Copy link
Contributor

I'm not 100% sure if this will work automatically (dispmanx_offline=1 allocates spare framebuffers in case offline composition is required, and I'm not sure if they are required for this case).

What you can do is create two offscreen dispmanx resources.
Offline-render first few elements to first resource.
Offline-render first resource plus next few elements to second resource.

and repeat this as needed to build up any complexity.

popcornmix pushed a commit that referenced this issue May 23, 2014
kernel: V4L2 padding removal, and support for H264_I_PERIOD
See: raspberrypi/linux#598

firmware: dispmanx: Limit LBM usage on any channel
See: #277

firmware: MMAL: vc_image: Fix some of the combinations for vc_image_pack
firmware: MMAL: Don't ask for YUVUV when tearing down an opaque tunnel
See: http://www.raspberrypi.org/forums/viewtopic.php?f=43&t=62364&start=300#p552913

firmware: gencmd: Add display_power command for controlling power to hdmi phy

firmware: config: Add hdmi_force_mode option to force only one mode
See: http://openelec.tv/forum/124-raspberry-pi/71222-display-issues#108236

firmware: hdmi: Make configured mode have high score, so it is respected after power on preferred

firmware: hdmi: Call the callback with current hdmi mode, not preferred
See: http://forum.stmlabs.com/showthread.php?tid=11003&pid=102973#pid102973

firmware: dispmanx: Move the offline/rotated buffer allocation into attach function.
See: raspberrypi/linux#463
popcornmix pushed a commit to Hexxeh/rpi-firmware that referenced this issue May 23, 2014
kernel: V4L2 padding removal, and support for H264_I_PERIOD
See: raspberrypi/linux#598

firmware: dispmanx: Limit LBM usage on any channel
See: raspberrypi/firmware#277

firmware: MMAL: vc_image: Fix some of the combinations for vc_image_pack
firmware: MMAL: Don't ask for YUVUV when tearing down an opaque tunnel
See: http://www.raspberrypi.org/forums/viewtopic.php?f=43&t=62364&start=300#p552913

firmware: gencmd: Add display_power command for controlling power to hdmi phy

firmware: config: Add hdmi_force_mode option to force only one mode
See: http://openelec.tv/forum/124-raspberry-pi/71222-display-issues#108236

firmware: hdmi: Make configured mode have high score, so it is respected after power on preferred

firmware: hdmi: Call the callback with current hdmi mode, not preferred
See: http://forum.stmlabs.com/showthread.php?tid=11003&pid=102973#pid102973

firmware: dispmanx: Move the offline/rotated buffer allocation into attach function.
See: raspberrypi/linux#463
@popcornmix
Copy link
Contributor

I've just pushed updated firmware. It should avoid the corruption problem, and improve offline case, but you will still get missing elements in non-offline case when context memory is full.

@julianscheel
Copy link
Author

Perfect, thank you. I'll go ahead with implementing offscreen compositing of layers, so that we will only have to scale one layer afterwards.
I'll update the bug with results and close then.

@julianscheel
Copy link
Author

Things seem to be sufficiently handled now. Thanks for the support, I'm closing the bug.

neuschaefer pushed a commit to neuschaefer/raspi-binary-firmware that referenced this issue Feb 27, 2017
kernel: V4L2 padding removal, and support for H264_I_PERIOD
See: raspberrypi/linux#598

firmware: dispmanx: Limit LBM usage on any channel
See: raspberrypi#277

firmware: MMAL: vc_image: Fix some of the combinations for vc_image_pack
firmware: MMAL: Don't ask for YUVUV when tearing down an opaque tunnel
See: http://www.raspberrypi.org/forums/viewtopic.php?f=43&t=62364&start=300#p552913

firmware: gencmd: Add display_power command for controlling power to hdmi phy

firmware: config: Add hdmi_force_mode option to force only one mode
See: http://openelec.tv/forum/124-raspberry-pi/71222-display-issues#108236

firmware: hdmi: Make configured mode have high score, so it is respected after power on preferred

firmware: hdmi: Call the callback with current hdmi mode, not preferred
See: http://forum.stmlabs.com/showthread.php?tid=11003&pid=102973#pid102973

firmware: dispmanx: Move the offline/rotated buffer allocation into attach function.
See: raspberrypi/linux#463
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