This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
# Requirements
The library should work on any ESP32 board with Tensilica core and free GPIO25 pin. The test environment was as follows:
| Name | Value |
|------|--------|
|Chip |ESP32 |
|Cores |2 |
|RAM |520 KiB |
|FLASH |4 MiB |
|Clock |240 MHz |
No external elements are required. Composite signal is generated on **GPIO25** pin, and it can be directly connected to composite input.
It requires ESP32-IDF development environment. Version 4.4 was used.
>:information_source: Compiler optimization level must be set to **performance** (`-O2`).
# Composite video
Composite video is an analog video signal. It was commonly used before the digital era.
There are three variants of composite video: NTSC, PAL, and SECAM. NTSC generates 30 frames per second using 525 lines. PAL and SECAM generates 25 frames per seconds in 625 lines.
## Connection
Connect **GPIO25** to composite video input and board **GND** to input GND.
If you use a CINCH (RCA) cable, the video signal goes to the pin in the middle, and GND to the outside metal part.
![CINCH connection](doc/esp32_board_cinch.png)
## Modes
The library can generate any resolution in non-interlaced mode.
Here is a list of predefined commonly used resolutions:
The above command will clone the library into the `components` directory.
You can optionally launch the configuration menu with `idf.py menuconfig` on your project root directory. Go to Component config and then `Composite Video Configuration`.
To use LVGL library along composite video library add one more submodule:
Returns text description of the current video mode and resolution, e.g. `PAL 320x200`.
#### `void video_stop(void)`
Stops video generation and free resources.
#### `void video_show_stats(void)`
Writes statistics to the log. Available only if defined `CONFIG_VIDEO_DIAG_ENABLE_INTERRUPT_STATS`.
# LVGL
The library provides integration with LVGL graphics library. **Version 8.3** was tested.
To initialize library with LVGL include `lvgl_driver_video.h` file and call `lv_video_disp_init()` or `lv_video_disp_init_buf()`.
## Color depth
This is LVGL configuration setting. It defines the number of colors on the screen. Use `idf.py menuconfig` to set.
There are 3 color depths supported:
* **1 byte per pixel** – monochromatic mode
* **RGB232** – color mode 1 byte per pixel
* **RGB565** – color mode 2 bytes per pixel
*ARGB8888* mode is not supported.
## Framebuffer access mode
The library provides two methods of framebuffer update.
### Direct framebuffer access
In this mode, LVGL access directly framebuffer. No additional buffer is allocated.
You may notice parts of the screen are blinking if redrawing takes a couple of milliseconds (even if VSYNC is enabled).
Use this mode as a default one, especially if there are no time-consuming effects on the screen.
Use`lv_video_disp_init()`.
### Buffered framebuffer access
In this mode, additional buffer is used. This force LVGL to update the screen in pieces.
This results in smoother animations but consumes additional amount of memory.
The size of the buffer is an argument for `lv_video_disp_init()`. It is the number of pixels to reserve.
For example, to define 320×100 pixels buffer pass 320×100=**32000**.
Note that defining small buffer and enabling synchronization with VSYNC will result in low animation frame rate.
Use`lv_video_disp_init_buf()` and specify pointer to pixel buffer.
For `1 byte per pixel` color depth, the library uses more memory effective framebuffer mode. It stores 8 pixels in one byte.
For monochrome mode it is better to use buffered access as it saves memory. Unfortunately, additional buffer still uses 1 pixel per byte, so keep it as small as possible.
### Animations
To see smooth animations, you should enable synchronization with VSYNC. This allows the rendering to update at the same time as when your monitor updates during vertical refresh. However, you may notice tearing effect when LVGL redraw takes more time than one frame (>15–20ms) in direct framebuffer access mode. That happens for complicated content or visual effects.
To eliminate tearing effect, you may use buffered mode. But this may decrease frame rate in specific situations.
If the buffer is small and update area is big, LVGL updates the image several times one piece in a time. If update is synchronized with
VSYNC, one operation is every 20ms for PAL or 16ms for NTSC. For example, for 5 updates it always takes 100ms (PAL)
regardless of actual update time. This in effect gives maximum 10 frames per second.