Color composite video code from ESP_8_BIT as an Arduino library

Overview

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.

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.

    help wanted 
    opened by Roger-random 13
  • 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
    opened by todbot 8
  • 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.

    opened by riraosan 6
  • 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.

    opened by vandenzel 4
  • 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

    opened by jhonrputra 4
  • 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?

    opened by alex1115alex 3
  • 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.

    enhancement 
    opened by emilyvelasco 3
  • 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

    opened by limaomerces 1
  • 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.

    bug 
    opened by Roger-random 1
  • 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.

    enhancement 
    opened by Roger-random 1
  • 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.

    bug 
    opened by Roger-random 1
Releases(v1.3.2)
  • v1.3.2(Jun 27, 2022)

    Bug Fix

    • Fix coordinate math errors in drawRect() and fillRect() support for setRotation(). (#27)
    • Compiler warning for printf() formatting. (#24)
    • Compiler warning for switch() fallthrough. (#35)

    New Example

    • Example named GFX_RotatedRect has been added to illustrate animating a rectangle's X/Y/Width/Height (one of four, cycles every second) in all four orientations.

    Maintenance

    • Verified to work with updated Adafruit_GFX (1.11.2) and ESP32 Arduino Core (2.0.3)
    Source code(tar.gz)
    Source code(zip)
  • v1.3.1(Dec 3, 2021)

    Version 1.3.0 was tagged and published without corresponding adjustments to libraries.properties file for Arduino Library Manager. Now everything should be in sync as v1.3.1

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Dec 2, 2021)

    Bug Fix

    • Previously a sketch could call Adafruit_GFX::setRotation(), but there would be no effect: this library's frame buffer code neglected to account for rotation. (#21)

    New Example

    • Example named GFX_RotatedText has been added to illustrate how to use the now-working setRotation() to print text in one of four orientations, in one of three sizes.
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(May 17, 2021)

    New Features

    • Some drawing algorithms like the AnimatedGIF decoder library depends on the frame buffer being preserved from one frame to the next. However, this is not true in double-buffering. (#11) Setting the new flag copyAfterSwap to true will copy frame buffers so they stay in sync from one frame to the next. This flag is false by default to avoid unnecessary copy when not needed.
    • ESP_8_BIT_GFX class now tracks how much time is spent in waitForFrame() which can be used as an approximation for idle time. This is in turn an approximation for performance, as faster code will leave more time between frames idle. In order to keep this tracking code lightweight, there are caveats on how these numbers should be interpreted. See comment block in ESP_8_BIT_GFX.h (initial version also copied in #4 ) for details.

    New Example

    • Example named AnimatedGIF illustrates how to use this color composite video out library with the AnimatedGIF library by Larry Bank / bitbank2. This is a light modification of example project ESP32_LEDMatrix_I2S from that library.
    • The animated art is Cat and Galactic Squid by Emily Velasco (CC BY-SA 4.0)

    Bug Fixes

    • Fixed PAL output error where the blanking lines were not blank. With this fix for #1, PAL support is now fully on par with NTSC.
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(May 10, 2021)

    Major feature: we now have double-buffering on both ESP_8_BIT_composite and ESP_8_BIT_GFX classes.

    Before this feature, we only had a single buffer for both render and display. Meaning all render had to be completed within non-active scanlines (vertical blanking interval, etc.) for glitch-free display. That limitation has been removed. Composite video signals are generated from front buffer data, and all rendering operations are now done to the back buffer. The back and front buffer are swapped when waitForFrame() is called. And if a frame takes too long to render, it just means the previous frame would be shown for longer. A missed frame may mean a visible motion stutter but would no longer result in annoying flickers.

    Plus miscellaneous bug fixes and performance enhancements.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Apr 25, 2021)

Owner
Roger Cheng
Tinker, build, make, share.
Roger Cheng
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.

NVIDIA DesignWorks Samples 132 Dec 15, 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 Contents General Info Installation To Do General Info Video stabilization is a software-based approach in real-time to eliminating

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

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

Chen and Sim 7 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

Twitter 875 Jan 2, 2023
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

Fire Falcom 2 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.

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.

Josef Nemec 4.8k Jan 3, 2023
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

Ange Yaghi 133 Dec 30, 2022
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

struktur AG 1.4k Dec 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 Team 6.7k Dec 31, 2022
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

Core 2 Extreme 130 Jan 6, 2023
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

null 675 Dec 25, 2022
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

krishna kumar T 10 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

Home Of VapourSynth Evolution 78 Dec 24, 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.

ossrs 20.4k Jan 5, 2023
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

Filipp Volodin 15 Jan 3, 2023
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.

Maya Posch 2.2k Jan 4, 2023
Shotcut - a free, open source, cross-platform video editor

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

MLT Framework 7.3k Dec 29, 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.

Techainer 10 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

Rinnegatamante 22 Nov 8, 2022