LED - 3. Let's make a large led display - Part 7 (Tunning)

I covered playing the video in the previous post. I also recommend using Rasbian Jessie to avoid poor screen quality due to unstable brightness.
In this article, I'll show you some ways to improve the quality of your RGB LED matrix output.


OS selection

In the latest Buster Rasibian, the previous article explained that the LED brightness fluctuates because of kernel problems. This does not mean that there is a problem with the Buster kernel. It only means that the accuracy of real-time processing is inferior to the previous version. However, since the human eye is very sensitive to changes in color, this problem causes a decrease in image output quality. Since the Linux OS is not a real-time OS, there is always a chance that this can happen. Just select the appropriate OS to avoid some of these problems. Fortunately, older Jessie versions rarely have this problem, so use Jessie instead of Buster. See the previous post for the Jessie Lite image preparation.


Process debugging

You can develop products in C or Python using Henner Jeller's package. But I will focus on Python(Python 3 exactly).

First run the nbym.py scripts.

root@raspberrypi:/usr/local/src/rpi-rgb-led-matrix/bindings/python/samples# python3 nbym_video.py --horizontal=2 --vertical=2 --video=Frozen.y4m
Matrix H:32 W:256
Image size H:64 W:128                                                                                                          163.3Hz


While the process is running, check the thread counts of the python process like this.


pi@raspberrypi:~ $ sudo ps -eLf|grep python3
daemon    1301   665  1301 17    2 13:28 pts/0    00:00:02 python3 nbym_video.py --horizontal=2 --vertical=2 --video=Frozen.y4m
daemon    1301   665  1302 76    2 13:28 pts/0    00:00:09 python3 nbym_video.py --horizontal=2 --vertical=2 --video=Frozen.y4m
pi        1220   881  1220  0    1 13:28 pts/1    00:00:00 grep --color=auto python3

And also check the process status with "htop -p 1301" command

From the above, we can know the following.

  • There are 2 threads in the same process(process id : 1301)
  • The 2 threads occupies the CPU 1 and 4
  • python3 process is running with Priority 20, Nice 0(This is the normal value)

As shown in the following figure, the two threads do different things. The first main thread is the Python program we run, which is responsible for extracting and converting frames from the video file and storing the images in a buffer.
In the nbym_video.py file, double_buffer.SetImage function stores the image information.
And the second thread do displaying the image that the first thread stored. The RGB LED Matrix must do multiplexing, so the second thread infinitely loops and sens the information to the LED. If the second thread's performance is poor, the loop speed will be decreased, and the multiplexing does not work properly.
So it is very important to allow the second thread to run in real time and keep the loop cycle stable. The reason Zeller recommends Jessie above is that Jessie outperforms Buster in this regard.


<S/W Diagram>

If the CPU load is high due to video frame decoding, you might consider increasing the process priority. By monitoring the refresh rate described below, python program's priority boosting up can be considered when the value is too low. But this is not a fundamental solution.
I used the nice command to give it a priority of -20(realtime priority).


nice -n -20 python3 nbym_video.py --video=Frozen_s.y4m --horizontal=2 --vertical=2

Becareful : To give real-time priority using the nice command, you must run with root privileges.

Monitoring the refresh rate

Checking the refresh rate of the LED Matrix while displaying the video image is a great help in verifying the performance of the current program.

There is an useful option for this purpose. it is "show_refresh_rate" option.


# Configuration for the matrix
options = RGBMatrixOptions()
options.cols = 64
options.rows = 32
options.chain_length = args.horizontal * args.vertical
options.parallel = 1
options.brightness = 80
options.pwm_bits = 11
options.gpio_slowdown = 1.0
options.show_refresh_rate = 1
options.hardware_mapping = 'adafruit-hat-pwm'  # If you have an Adafruit HAT: 'adafruit-hat'
#options.hardware_mapping = 'adafruit-hat'  # If you have an Adafruit HAT: 'adafruit-hat'
options.pwm_dither_bits = 0

matrix = RGBMatrix(options = options)

If you set this parameter to 1, then the realtime refresh rate is printed on the console.

Monitoring Environment

  • OS : Rasbian Jessie
  • Raspberry Pi : 3B

If the show_refresh_rate option is enabled, you can see the refresh rate of LED matrix on the console. The higher this value, the better the screen quality.

<refresh rate>



Video file optimization

Let's take a look at some of these changes using some formats of video.


Video file name
Video file size
Compressed
File Size (Byte)
Refresh Rate (Hz)
Frozen2.mp4
1280X720
Y
10,876,010
60 ~ 180
Frozen_s.mp4
128X64
Y
3,684,201
140 ~ 190
Frozen.y4m
256X128
N
223,128,228
150 ~ 190
Frozen_s.y4m
128X64
N
55,802,531
160 ~ 190
 

The uncompressed y4m format has the largest file size but the most stable refresh rate.
The Frozen2.mp4 file has a high CPU load because it needs to decode a large frame size. In particular, the refresh rate's fluctuation range is large because it requires a lot of CPU resources during key frame processing.

Conclusion

  • Prepare a movie of the same frame size as the display size of the RGB Matrix.
  • Use uncompressed video format

This video was recorded under the following conditions:
  • OS:Rasbian Jessie, 
  • H/W: Raspberry 3B
  • Video Size: 256X128 
  • Video Format: y4m(uncompressed)
  • RGB LED Matrix : 32X64 Matrix 4EA
 

Wrapping up

There is a C++ video viewer in the util directory. If you are familiar with C/C++, see the page https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/utils.  This page explains how to build an image viewer, video viewer using C++, and how to use.
But I'm a big fan of python and OpenCV.  C++ requires dozens of lines of coding, but with OpenCV in Python, you can process video frames in just a few lines of coding. Using Python has the disadvantage of slowing performance compared to C ++, but many functions of numpy and OpenCV APIs call C / C ++ functions internally to minimize performance degradation. It's a pity that you can't take advantage of the latest high-performance Raspberry Pi 4 when dealing with CPU-intensive video because you use Rasbian Jessie. The Raspberry Pi 3B can handle 256x128 video without any problems, so if you don't have a large LED, you can use it without a problem.
In the next post, I'll show you how to use different HATs that support three chains at the same time.

Realtime OS

I modified the Rasberry 4's Rasbian Buster kernel and tested it. With the help of the next page(https://lemariva.com/blog/2019/09/raspberry-pi-4b-preempt-rt-kernel-419y-performance-test), I updated Buster's kernel to enable realtime. Because you only update the kernel without reinstalling the OS, your previous work will not be lost. But just in case, you should back up your important data before updating your kernel. The unstable display is much better compared to the previous standard Buster. However, sometimes the brightness fluctuates and the performance seems to be worse than before. The Raspberry Pi3's screen quality was clearly superior compared to Raspberry 4 with Raspbian Buster with kernel optimized. If you are interested, please give it a try.

























































댓글

이 블로그의 인기 게시물

LED-12. Displaying HDMI Contents

LED - 5. Raspberry Pi 4 + DietPi Buster + Electrodragon HAT - Part 1

LED-11. Make a very big size 384 X 512 RGB Matrix #6(final)