fieldOfView / WLED-video

A tool to stream video to WLED matrix displays
MIT License
26 stars 3 forks source link

Problems when using more than 4 modules (16x16px each) #3

Open JLoTech opened 5 months ago

JLoTech commented 5 months ago

Is there a limit on the number of used modules?

I tried different configurations with more than four modules. But every time, when there are more than 1024 leds, the video lags on some modules.

In my project I want to use 12 modules (4x3) and I am using a ESP32 with 4 outputs. each row of the matrix uses three modules. All effects from WLED are working well, but the video only runs smoth on some modules. Power supply is 5V 25A and I tried also with Gamma 0.4 / 0.3. Very bright effects in WLED are working good. Also WLED pixel art is working fine.

Thank you very much. JLoTech

fieldOfView commented 5 months ago

I think you are running into the limitations of UDP packet handling on the ESP32. I have seen the same thing as you with >1024 LEDs (and sometimes even with 1024 LEDs). The limit is likeley at 1440 LEDs.

My script (ab)uses a protocol that was never intended for streaming video, but it is available and enabled with WLED by default. It sends information for each pixel as three bytes, packing 480 pixels into one UDP packet, since a UDP packet can not be longer than 1500 bytes. Some additional bytes are used for a header and the "address" of the first pixel in the packet.

Due to the nature of UDP packets, if the ESP32 is not opening them as fast as they arrive, the packet is just dropped without the sender being notified. There is also no guarantee of in what order the packets arrive, but most of the time the first packet that gets sent is the first that gets processed. Between frames there's a small "pause" of packets arriving, which gives the ESP32 time to catch up. That's why the first panels seem to work ok, but the ones after 1440 pixels do not.

I have briefly experimented with sending the packets in a random order, so it is not the same modules that get information on every frame. It could also be worthwhile to experiment with sending just N random packets per frame out of the packets required for a full frame (eg 3). That way the ESP32 will get less overwhelmed, and you should get some updates on all modules over time. However there will be significant tearing in the display.

If WLED supported a compressed format, that could help in certain types of video. However the ESP32 would have to do decoding too and that could again hinder receiving packets in time.

Another solution would be to use multiple ESP32 modules; one per 4 16x16 px LED panel. The script already supports sending different crops of the source to different receivers.

Unfortunately, I only have 2 of these modules myself (and they are connected to a Raspberry Pi, not a WLED instance), so testing workarounds is hard at the moment.

JLoTech commented 5 months ago

Thank you very much for your detailed answer.

I think the mentioned option of sending the stream to different ESP32 is good. It's quick to rebuild and try out. What is the exact syntax for this? Can you please give me an example? Then I will report here my configuration and wiring to help other makers ;-)

Greetings

fieldOfView commented 5 months ago

The easiest way at the moment is to use a configuration file to describe your setup to the script: https://github.com/fieldOfView/WLED-video?tab=readme-ov-file#configuration-files

In that example, one of the targets is using serial communication, but you can also use as many UDP targets as your wifi network will allow.

JLoTech commented 5 months ago

I had seen and even tested the example using the config file. But I didn't understand that the data can be sent at the same time to several Boards. I will test it immediately and report back. Thanks!

JLoTech commented 5 months ago

So, I ran further tests: With two separate ESP32 (each with 3 modules 16x16px) together with the config file, there are no problems with stability and refresh rate. But the crop parameter is not clear to me. According to the debug output, the YouTube video is processed in 360p, so 640x360 pixels arrive, right? How should the values then be specified?

[[wled]] host = 192.168.1.18 width = 16 height = 48 crop = [0,0,0,320]

[[wled]] host = 192.168.1.19 width = 16 height = 48 crop = [0,0,320,0]

Defining four values mean up/down/left/right?

fieldOfView commented 5 months ago

With two separate ESP32 together with the config file, there are no problems with stability and refresh rate.

Awesome!

If you have a single stream coming in as 640x360, and you want to have the left side sent to one ESP32 and the right side to another, you can use these crop values:

left: [0,0,320,0] right: [320,0,0,0]

The order is left, top, right, bottom. So for the left, you crop away half from the right, for the right you crop away half from the left.

If you wanted to do a top/bottom arrangement, you would use

top: [0,0,0,180] bottom: [0,180,0,0]

It sort of sucks having to know the resolution of the source video. Perhaps I should change it or add the option to crop to a factor of the width/height.

JLoTech commented 5 months ago

It works now!

Finally, I now use three ESP32, each connected to 4 modules 16x16 in a horizontal line. Together 64x48 pixel.

debug = true
source = 'https://www.youtube.com/watch?v=ZPJlyRv_IGI'
loop = true
scale = 'fit'

[[wled]]
host = "192.168.178.67"
width = 64
height = 16
crop = [0,0,0,240]

[[wled]]
host = "192.168.178.76"
width = 64
height = 16
crop = [0,120,0,120]

[[wled]]
host = "192.168.178.79"
width = 64
height = 16
crop = [0,240,0,0]

Unfortunately you can't use the Scale parameter at the same time, right? Is there also a way to get the sound from the video?

Thank you very much for your help!

fieldOfView commented 5 months ago

Got any neat pictures or video?

you can't use the Scale parameter at the same time

You can. The video segments are first cropped and then scaled. The trick is that the scale parameter should be in each of the [[wled]] parts.

fieldOfView commented 5 months ago

Unfortunately I don't have a solution for sound at this time. The video is played back with OpenCV, and that just does not handle sound at all.

JLoTech commented 5 months ago

Great! I will test this again in make some pictures / a video. Thanks