Free now2sdk Core is completely free — no license key required   See what's included →
SDK Modules Docs Release Notes Pricing GitHub
Get the SDK →

LSignal Reference Manual & Test Signal Generator Guide

The LSignal class is the background video signal generator of the now2sdk framework, derived from the LObject base class. It is designed to act as a fallback program source or test generator that continuously yields video frames at a precise target frame rate.

LSignal can generate:

  1. Solid Color Frames: Generated mathematically using BT.601 RGB-to-YUV color conversion space mappings.
  2. Static Test Pattern Slides: Loaded, decoded, and scaled from local image files (PNG, JPG, BMP).

To minimize CPU usage, generated frames are cached in memory (m_cachedFrame) and cloned on subsequent cycles rather than being re-generated or re-decoded.


1. Mathematical & Decoded Generation Pipeline

graph TD
    A[LSignal Start] --> B{Source Type?}
    
    B -->|setColor hex| C[1. Parse hex R G B values]
    C --> D[2. Convert using BT.601 YUV formulas]
    D --> E[3. Allocate YUV420P AVFrame & fill Y, U, V buffers]
    
    B -->|setImage path| F[1. Open image using avformat]
    F --> G[2. Decode image frame to AVFrame]
    G --> H[3. Scale and convert to YUV420P using SwsContext]
    H --> E
    
    E --> I[Clone frame to m_cachedFrame cache]
    
    J[signalLoop Thread] -->|At precise frame durations| K[Clone m_cachedFrame]
    K --> L[Call distributeVideoFrame to Sinks]

YUV Color Conversion Formula

For solid colors, LSignal converts RGB colors from hexadecimal string values to YUV420p space using standard BT.601 formulas: $Y = 0.299R + 0.587G + 0.114B$ $U = -0.1687R - 0.3313G + 0.5B + 128$ $V = 0.5R - 0.4187G - 0.0813B + 128$


2. API Reference & Public Methods

All public methods available in the LSignal class:

📌 Generator Control & Initializations

LSignal();

Constructor. Sets the default video format to 720p50 (vF_HD720_50p) and background color to black ("#000000").

virtual ~LSignal();

Destructor. Stops the background thread loop and releases cached frame resources.

bool Start();

Spawns the background generator thread (signalLoop) to begin distributing frames to downstream sinks.

void Stop();

Stops the background thread loop and cleans up memory buffers.


📌 Properties Setup Methods

Since LSignal is a lightweight signal generator, it does not implement a setProps(key, value) dictionary interface. Instead, settings are configured directly using the following type-safe C++ methods:

Method Parameters / Types Description
setColor(hex) const std::string& hex Sets the solid color value (e.g. "#0000FF" for blue). Clears any loaded image path and resets the frame cache.
setImage(path) const std::string& path Loads a local image path (PNG, JPG, BMP). Clears the solid color and resets the frame cache.
setVideoFormat(props) const videoFormatProps& props Configures the target resolution and frame rate. If standard standard enums are set, it automatically resolves physical resolutions and FPS before resetting the frame cache.
getVideoFormat(props) videoFormatProps& props Populates the output structure with the current target specifications.

3. Ingestion Fallback Integration Example

The following example demonstrates how to set up LSignal as a backup "No Signal" blue screen or custom slide in a vision mixing pipeline. If the main camera capture feed fails or disconnects, the pipeline automatically routes the generator's frames to the program output.

#include "LLive.h"
#include "LSignal.h"
#include "LPreview.h"
#include "LOutput.h"
#include <iostream>

class FallbackBroadcaster {
public:
    FallbackBroadcaster() 
        : m_liveInput(new LLive()),
          m_backupSignal(new LSignal()),
          m_preview(new LPreview())
    {
        // 1. Configure standard video standard properties (1080p50)
        videoFormatProps format;
        format.setVideoFormat = vF::HD1080_50p;

        // 2. Configure Backup Signal Generator
        m_backupSignal->setVideoFormat(format);
        
        // Option A: Solid Blue screen background
        m_backupSignal->setColor("#000080"); 
        
        // Option B: Custom slide image (uncomment to use)
        // m_backupSignal->setImage("/var/broadcasting/images/no_signal_slide.png");

        m_backupSignal->Start(); // Start generating backup frames

        // 3. Configure Camera Live capture
        m_liveInput->setProps("device_type", "decklink");
        m_liveInput->DeviceSet(0);
        m_liveInput->setVideoFormat(format);
        m_liveInput->Start();

        // 4. Bind preview screen and listen to live camera
        m_preview->previewEnable(nullptr, true, true);
        m_preview->previewObject(m_liveInput);
    }

    ~FallbackBroadcaster() {
        m_liveInput->Stop();
        m_backupSignal->Stop();
        
        delete m_preview;
        delete m_backupSignal;
        delete m_liveInput;
    }

    // Dynamic pipeline routing triggered by signal watchdog check
    void verifySignalWatchdog() {
        bool cameraDisconnected = m_liveInput->noSignalGet();

        if (cameraDisconnected) {
            std::cout << "[Watchdog] Camera signal lost! Routing fallback test signal..." << std::endl;
            
            // Route preview and output lines to backup signal generator
            m_preview->previewObject(m_backupSignal);
        } else {
            // Restore live camera feed
            m_preview->previewObject(m_liveInput);
        }
    }

private:
    LLive* m_liveInput;
    LSignal* m_backupSignal;
    LPreview* m_preview;
};