Color composite video code from ESP_8_BIT as an Arduino library

ESP_8_BIT Color Composite Video Out Library

Purpose

The composite video generation code from ESP_8_BIT extracted and packaged into a standalone Arduino library so everyone can write Arduino sketches that output a color composite video signal. NTSC and PAL are both supported.

Huge thanks to Peter Barrett / rossumur for ESP_8_BIT, without which this library would not have been possible.

For more behind-the-scenes information on how this library came to be, see the development diary which has all the details anyone would ever want plus even more that nobody ever asked for.

Hardware requirement

  • ESP32 (tested on ESP32 DevKitC)
  • Composite video connector to ESP32 GPIO25 video signal pin.
  • Display device with composite video input port. (Usually an old-school tube TV.)

Arduino requirement

Installation

This library can now be installed from within the Arduino desktop IDE via the Library Manager. Listed as "ESP_8_BIT Color Composite Video Library"

It can also be installed from this GitHub repository if desired:

  1. Download into a folder named "ESP_8_BIT_composite" under your Arduino IDE's libraries folder.
  2. Restart Arduino IDE.

Classes

  1. ESP_8_BIT_GFX offers high-level drawing commands via the Adafruit GFX API. Easy to use, but not the highest performance.
  2. ESP_8_BIT_composite exposes low-level frame buffer for those who prefer to manipulate bytes directly. Maximum performance, but not very easy to use.

Examples

  1. GFX_HelloWorld draws animated rectangles and text, both in changing colors, using the Adafruit GFX API exposed by ESP_8_BIT_GFX.
  2. RGB332_Colors draws all 256 available colors directly to frame buffer allocated by ESP_8_BIT_composite. Draws once, no updates.
  3. RGB332_PulseB draws 64 blocks of colors (8x8) representing different combinations of red (vertical axis) and green (horizontal axis). Uses the frame buffer of ESP_8_BIT_composite directly. Every second, the entire screen is redrawn with one of four possible values of blue in a pulsing cycle.
  4. GFX_Screen_Fillers demonstrates several of the common ways to put graphics on screen. Includes the following APIS: fillRect, fillCircle, drawFastVLine, and drawFastHLine.
  5. AnimatedGIF demonstrates how to use this video out library with the AnimatedGIF decoder library by Larry Bank. Art used in this example is Cat and Galactic Squid by Emily Velasco (CC BY-SA 4.0)

Screen Size

  • Inherited from ESP_8_BIT, the addressible screen size is 256 pixels wide and 240 pixels tall. This means valid X values of 0 to 255 inclusive, and valid Y values of 0 to 239 inclusive.
    • When displayed on a standard analog TV with 4:3 aspect ratio, these pixels are not square. So drawCircle() will look like a squat wide oval on screen and not a perfect circle. This is inherent to the system and not considered a bug.
    • When displayed on a standard analog TV, the visible image will be slightly cropped due to overscan. This is inherent to analog televisions and not considered a bug.
  • The developer-friendly ESP_8_BIT_GFX class checks for valid coordinates and will only draw within the valid range. So if X is too large (say, 300) drawPixel() will ignore the command and silently do nothing.
  • The raw ESP_8_BIT_composite class gives max performance power, but with great power comes great responsibility. Caller is responsible for making sure X and Y stay within bounds when manipulating frame buffer bytes via getFrameBufferLines()[Y][X]. Any bugs that use out of range array index may garble the image, or trigger a memory access violation and cause your ESP32 to reset, or other general memory corruption nastiness including the potential for security vulnerabilities.

8-Bit Color

Inherited from ESP_8_BIT is a fixed 8-bit color palette in RGB332 format. The underlying composite video out code always works with this set of colors. (See Examples.)

  • The developer-friendly ESP_8_BIT_GFX class constructor can be initialized in either 8-bit (native) or 16-bit (compatibility) color mode.
    • Adafruit GFX was written for 16-bit color in RGB565 format. ESP_8_BIT_GFX in 16-bit mode is compatible with existing Adafruit GFX code by automatically downconverting color while drawing. The resulting colors will be approximate, but they should closely resemble the original. Using RGB332 color values while in this mode will result in wrong colors on screen due to interpretation as RGB565 colors.
    • In 8-bit mode, color values given to GFX APIs will be treated as native 8-bit RGB332 values. This is faster because it skips the color conversion process. Using RGB565 color values while in this mode will result in wrong colors on screen due to the higher 8 bits being ignored.
  • The raw ESP_8_BIT_composite class always works in 8-bit RGB332 color.

Sample colors in 8-bit RGB332 format:

Name RGB332 (binary) RGB332 (hexadecimal)
Black 0b00000000 0x00
Blue 0b00000011 0x03
Green 0b00011100 0x1C
Cyan 0b00011111 0x1F
Red 0b11100000 0xE0
Magenta 0b11100011 0xE3
Yellow 0b11111100 0xFC
White 0b11111111 0xFF

8-bit RGB332 Color Picker Utility

CLICK HERE for an interactive color picker web app. It shows all 256 possible 8-bit RGB332 colors in either a HSV (hue/saturation/value) color cylinder or a RGB (red/green/blue) color cube.

Questions?

Please post to discussions and see if anyone knows the answer. Note there's no guarantee of an answer.

Bugs?

Please open an issue to see if it can be fixed. Note there's no guarantee of support.

Tip jar

Just like its predecessor ESP_8_BIT, this project is shared freely with the world. Under the MIT license, you don't owe me anything.

But if you want to toss a few coins my way, you can do so by using my Amazon Associates link to buy your ESP32 development boards or composite video cables. You'll pay the same price, but I get a small percentage. As an Amazon Associate I earn from qualifying purchases.

Owner
Roger Cheng
Tinker, build, make, share.
Roger Cheng
Comments
  • Need to verify PAL functionality

    Need to verify PAL functionality

    When I extracted the video signal generation code from ESP_8_BIT, I tried to preserve PAL support. Since I only have a NTSC TV, I couldn't verify that PAL support is still functional. I would appreciate one of the following:

    1. Someone to test PAL and verify it works.
    2. Someone to fix any PAL problems and create a pull request.

    Note that I can't do anything about "PAL doesn't work" absent a fix, as I have no way to diagnose, debug, or verify fixes without a PAL TV.

  • What version of the Arduino ESP32 core to use?

    What version of the Arduino ESP32 core to use?

    Hi, I've tried this on an Espressif ESP32 Dev Module and it seems to hang in loop(). I've tried versions 2.0.2, 2.0.1, 1.0.6, and 1.0.4 of the ESP32 Arduino core. All on Arduino IDE 1.8.19.

    Also, what settings for things like CPU frequency, core, flash speed, etc. are you using?

    Screen Shot 2022-02-28 at 1 47 23p
  • For LovyanGFX

    For LovyanGFX

    @Roger-random

    Hi. Thank you for your Contributions.

    I have merged LovyanGFX and ESP_8_BIT_composite in my project. In doing so, I wanted to output signals to GPIO26 (ATOM Lite), so I modified your source. I decided to define the output port with #define as I don't change it often. Please merge if you like. I'll commit it for now.

  • Compiler warning: format '%s' expects argument of type 'char*', but argument 2 has type 'int' [-Wformat=] [73, 46]

    Compiler warning: format '%s' expects argument of type 'char*', but argument 2 has type 'int' [-Wformat=] [73, 46]

    Hi,

    I was trying to use this library for testing, and my compiler warns about this:

    format '%s' expects argument of type 'char*', but argument 2 has type 'int' [-Wformat=] [73, 46]
    

    https://github.com/Roger-random/ESP_8_BIT_composite/blob/001174d6b526de45c6792b26d53042dcc9f6de22/ESP_8_BIT_composite.cpp#L71-L75

    The compiler could be right, as far as I know you can't use %s on an int.

    Compiler: xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-97-gc752ad5) 5.2.0 (platformio-ide on vscode, reasonably up-to-date)

    Regards, Alex.

  • Compilation Error

    Compilation Error

    Hi...

    I've tried the library and got this error:

    SP_8_BIT_composite.cpp:178:33: error: pal_yuyv causes a section type conflict with _sync_type const static DRAM_ATTR uint32_t pal_yuyv[] = {

    Any advise, please....?

    Regards, Jhon R Putra

  • Bluetooth classic stops working after running .begin()

    Bluetooth classic stops working after running .begin()

    I'm trying to use Bluetooth (classic, not BLE) and display composite video at the same time, but it seems as if Bluetooth stops working once the video output starts.

    Has anyone run into a similar issue? If so, how did you work around this limitation?

  • setRotation support

    setRotation support

    Would it be possible to support the setRotation function present in the Adafruit GFX library in this library? There might be occasions where someone would need to display an image on a composite video monitor rotated to 90, 180 or 270 degrees.

  • Warning when compiling.

    Warning when compiling.

    ESP_8_BIT_composite-main\ESP_8_BIT_GFX.cpp: In member function 'uint8_t ESP_8_BIT_GFX::getColor8(uint16_t)':
    ESP_8_BIT_composite-main\ESP_8_BIT_GFX.cpp:262:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    

    This message is displayed whenever I launch the IDE to check the code. I imagine it is not desirable. So I'm bringing it for you to review.

    Arduino IDE 1.8.19 Esp Board (Arduino IDE): 2.0.3 -RC1

  • Need a way to keep double buffers in sync with each other

    Need a way to keep double buffers in sync with each other

    Bug introduced by double-buffering (v1.1.0)

    Instead of clearing the screen and redrawing everything on every frame, some rendering libraries are optimized so that they only draw what is changed from one frame to the next. But with two buffers, the default behavior results in each frame being drawn on top of the image data from TWO frames ago. Such libraries require the two buffers be kept in sync so the image deltas are applied correctly.

  • Reduce importance level of X/Y clamp logs

    Reduce importance level of X/Y clamp logs

    Design change from version 1.0.0 based on feedback from @emilyvelasco

    While investigating #8 it became obvious that clamping X/Y coordinate to fit on screen is not an error condition. Clamping can occur as part of normal operation, such as drawing a circle close to the edge of the screen.

    However, there are still occasions when it is useful to know when clamping has occurred, because it still represent unnecessary work that is wasted.

    Compromise: Drop "value has been clamped" logging messages from "Error" to "Verbose" level of importance.

  • Negative X or Y coordinates cause core panic

    Negative X or Y coordinates cause core panic

    Bug in version 1.0.0 found by @emilyvelasco

    My code originally used unsigned integers, where negative numbers were impossible by definition. So for bounds checking it only checked the high end, that X did not exceed 255 and Y did not exceed 239.

    When it was adapted to use signed integers in conformance to Adafruit GFX declarations, negative numbers became possible, but there were no checks to ensure X and Y were positive numbers.

    Using negative coordinates would then step outside of allocated frame buffer memory, an access violation causing core panic.

Vulkan Video Sample Application demonstrating an end-to-end, all-Vulkan, processing of h.264/5 compressed video content.
Vulkan Video Sample Application demonstrating an end-to-end, all-Vulkan, processing of h.264/5 compressed video content.

This project is a Vulkan Video Sample Application demonstrating an end-to-end, all-Vulkan, processing of h.264/5 compressed video content. The application decodes the h.264/5 compressed content using an HW accelerated decoder, the decoded YCbCr frames are processed with Vulkan Graphics and then presented via the Vulkan WSI.

Nov 21, 2022
Video stabilization is a software-based approach in real-time to eliminating environmental effects (wind, heavy vehicle etc.) and enhance the visual performance that degrade video streaming quality.
Video stabilization is a software-based approach in real-time to eliminating environmental effects (wind, heavy vehicle etc.) and enhance the visual performance that degrade video streaming quality.

Video Stabilization Contents General Info Installation To Do General Info Video stabilization is a software-based approach in real-time to eliminating

Nov 23, 2022
Minimalist video maker -- simplify your music score video making process!

VisualScores 极简视频制作程序,简化你的乐谱视频制作! 如果需要编译,请解压 lib 文件夹中压缩包。 使用前请参考 manual 文件夹中的用户手册。 请勿修改、移动或删除 resource 文件夹中的任何文件。 VisualScores Minimalist video maker

Sep 7, 2022
Vireo is a lightweight and versatile video processing library written in C++11

Overview Vireo is a lightweight and versatile video processing library that powers our video transcoding service, deep learning recognition systems an

Nov 27, 2022
theora-player is an embeddable theora video player C++ library based on the libtheora sample. It has no audio support at this moment.

theora-player Description theora-player is an embeddable theora video player C++ library based on the libtheora sample. It has no audio support at thi

Jun 18, 2022
Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games.
Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games.

An open source video game library manager and launcher with support for 3rd party libraries like Steam, GOG, Origin, Battle.net and Uplay. Includes game emulation support, providing one unified interface for your games.

Dec 2, 2022
DTV is a library that provides a simple interface for generating video files from a C++ application
DTV is a library that provides a simple interface for generating video files from a C++ application

Direct to Video (DTV) What does DTV do? DTV is a library that provides a simple interface for generating video files from a C++ application. It uses F

Nov 30, 2022
Open h.265 video codec implementation.
Open h.265 video codec implementation.

libde265 - open h.265 codec implementation libde265 is an open source implementation of the h.265 video codec. It is written from scratch and has a pl

Nov 30, 2022
Olive is a free non-linear video editor for Windows, macOS, and Linux.
Olive is a free non-linear video editor for Windows, macOS, and Linux.

Olive is a free non-linear video editor for Windows, macOS, and Linux.

Nov 30, 2022
Video player for 3ds
Video player for 3ds

Video player for 3DS Patch note v1.0.1 Added allow skip frames option v1.0.0 Initial release Summary Video player for 3DS Performance 256x144(144p)@30

Nov 21, 2022
Plugin for VLC that pauses/plays video on mouse click

Pause Click plugin for VLC VLC plugin that allows you to pause/play a video by clicking on the video image. Can be configured to work nicely with doub

Nov 29, 2022
A WFH utility to visually indicate user engagement of audio and video
A WFH utility to visually indicate user engagement of audio and video

DIY: In meeting indicator - WFH Utility The need for in meeting indicator at home So many of you have gotten accustomed to work from home by now. This

Jun 28, 2021
Real-Time Intermediate Flow Estimation for Video Frame Interpolation filter for VapourSynth

Description RIFE filter for VapourSynth, based on rife-ncnn-vulkan. Usage rife.RIFE(clip clip[, int model=0, int gpu_id=auto, int gpu_thread=2, bint t

Nov 23, 2022
SRS is a simple, high efficiency and realtime video server, supports RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28181.
SRS is a simple, high efficiency and realtime video server, supports RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28181.

SRS is a simple, high efficiency and realtime video server, supports RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28181.

Dec 5, 2022
Anki-like app for spaced repetition of video clips
Anki-like app for spaced repetition of video clips

ReeePlayer The ReeePlayer application is designed for spaced repetition of fragments (clips) of video and audio files with similar principle as in Ank

Oct 28, 2022
NymphCast is a audio and video casting system with support for custom applications.
NymphCast is a audio and video casting system with support for custom applications.

NymphCast is a software solution which turns your choice of Linux-capable hardware into an audio and video source for a television or powered speakers. It enables the streaming of audio and video over the network from a wide range of client devices, as well as the streaming of internet media to a NymphCast server, controlled by a client device.

Dec 1, 2022
Shotcut - a free, open source, cross-platform video editor
 Shotcut - a free, open source, cross-platform video editor

cross-platform (Qt), open-source (GPLv3) video editor

Nov 27, 2022
SortNode is a JS binding for SORT: Simple, online, and real-time tracking of multiple objects in a video sequence.

SortNode is a JS binding for SORT: Simple, online, and real-time tracking of multiple objects in a video sequence.

Aug 2, 2022
Vita Recorder is a plugin that allows to record video clips during your play sessions.

Vita Recorder Vita Recorder is a plugin that allows to record video clips during your play sessions. The code is based off VITA2PC at which has been a

Nov 8, 2022