LogoLogo
🛠️ Tools🗂️ SDK📄 White Paper
  • Getting Started
    • 🟣What is NDI?
    • 🆕Release Notes
    • 📄White Paper
      • Discovery & Registration
        • mDNS
        • Discovery Service
        • Manual Connection
        • NDI Groups
      • NDI Protocols
        • Reliable UDP - NDI 5
        • Multipath TCP - NDI 4
        • UDP with Forward Error Correction – NDI 3
        • Single TCP – NDI 1
      • NDI Related Network Ports
      • Getting video across the network
      • Network Layout
      • Bandwidth
        • NDI High Bandwidth based on SpeedHQ2 (8bit 4:2:2)
        • NDI High Bandwidth based on SpeedHQ7 (8bit 4:2:2:4)
        • NDI HX2 h.264 (8bit 4:2:0)
        • NDI HX2 h.265 (8bit 4:2:0)
        • NDI HX3 h.264 (8bit 4:2:0)
        • NDI HX3 h.265 (8bit 4:2:0)
        • NDI Proxy and bandwidth optimization
      • Network Interface Settings
      • NIC Selection
      • Encoding and Decoding
      • Multicast
      • NDI Administrative Settings
      • Synchronization
      • NDI in the Cloud
    • Glossary
      • NDI Terminology
      • Industry Terminology
  • Using NDI
    • Introduction
    • NDI for Video
      • Digital Video Basics
      • NDI Video Codecs and Format Matrix
      • NDI Encoding Support Matrix
        • Practical NDI Receivers Format Support
        • Practical NDI Transmitters Support
        • Summary Table
      • Interoperability Scenarios
    • NDI for Audio
      • Digital Audio Fundamentals
      • Audio Over IP
      • Technical Facts About NDI for Audio
      • Use Cases
      • Products Using NDI for Audio
    • ⚒️NDI Tools
      • Release Notes
      • Installing NDI Tools
        • Software License Agreement
        • Privacy Policy
      • NDI Tools Launcher
      • NDI Tools for Windows
        • Access Manager
        • Bridge
          • NDI Bridge automation
          • Configuring Port Forwarding
          • Bridge Tool Logging
        • Remote
        • Router
        • Screen Capture
        • Screen Capture HX
        • Studio Monitor
        • Test Patterns
        • Webcam Input
        • Discovery
          • Getting Started with Discovery
          • Discovery Server Additional Information
      • NDI Tools for Mac
        • Access Manager
        • Scan Converter
        • Router
        • Test Patterns
        • Video Monitor
        • Virtual Input
        • Discovery
          • Getting Started with Discovery Service
          • Discovery Server Additional Information
          • Launch Discovery Server using Command Line for MacOS
      • Plugins
        • NDI for After Effects
        • NDI for Premiere Pro
        • NDI Output for Final Cut Pro
        • NDI for VLC
        • Audio Direct
        • OBS
    • Utilities
      • Analysis
    • Using NDI with Software
      • Getting Started with NDI in OBS for Windows or Mac
      • Using OBS Studio as a Commentary System
      • Using NDI Tools as a virtual camera in Mac
      • Using NDI and Dante on the same Network
      • Use OBS video + audio on Zoom with macOS
    • Using NDI with Hardware
      • NDI HX upgrades for cameras
      • How to Activate Panasonic Cameras for NDI HX1 — Step-by-Step
      • Recommended Network Switch Settings for NDI
  • Developing with NDI
    • Introduction
    • 📂SDK
      • Release Notes
      • Licensing
      • Software Distribution
        • Header Files
        • Binary Files
        • Redistributables
        • Content Files
        • Libraries
        • NDI-SEND
        • NDI-FIND
        • NDI-RECEIVE
        • Utilities
        • Command Line Tools
      • CPU Requirements
      • Dynamic Loading of NDI Libraries
      • Performance and Implementation
      • Startup and Shutdown
      • Example Code
      • Port Numbers
      • 🔧Configuration Files
      • Platform Considerations
      • NDI-SEND
      • NDI-FIND
      • NDI-RECV
      • NDI-Recv Discovery, Monitor, and Control
      • NDI Routing
      • HDR
      • Command Line Tools
      • Frame Types
        • Video Frames
        • Audio Frames
        • Metadata Frames
      • Windows DirectShow Filter
      • 3rd Party Rights
      • Support
    • Advanced SDK
      • Release Notes
      • Licensing
      • Overview
      • Configuration Files
      • NDI SDK Review
        • Sending
          • Asynchronous Sending Completions
          • NDI Sending On High Latency Connections
        • Receiving
          • Custom Allocators
            • Video Allocators
            • Audio Allocators
          • Dynamic Bandwidth Adjustment
          • NDI RECV Event Monitoring and Commands
        • Finding
        • Video Formats
          • Receiver Codec Support Level
          • Frame Synchronization
      • Genlock
      • AV Sync
        • Guidelines
        • Creating and Destroying Devices
        • Recovering Audio
      • Using H.264, H.265, and AAC Codecs
        • Sending Audio Frames
        • Sending Video Frames
        • H.264 Support
        • H.265 Support
        • AAC Support
        • OPUS Support
        • Latency of Compressed Streams
        • Stream Validation
      • External Tally Support
      • KVM Support
      • NDI Advanced SDK FPGA Example Designs
        • Prebuilt uSD Images
        • NDI FPGA Reference Design
          • FPGA Projects
            • Changelog
          • C++ Application Code
            • Changelog
          • linux_kernel
            • Changelog
          • uSD Image Builder
            • Changelog
        • Changelog
    • Utilities
      • Unreal Engine SDK
        • Release Notes
        • Licensing
        • NDI Plugin Installation
        • Simple Setup of Broadcast and Receivers
        • NDI Broadcast Actor
        • NDI Receiver Actor
        • NDI Media Assets
        • Getting Started with Example Blueprint Projects
        • Advanced
      • Free Audio
      • Bridge Service
        • Installation
          • Silent Installation
        • Configuration
          • Web UI
          • Configuration File
          • Manual API Key Management
        • Webhooks
        • WebSockets
        • API
    • NDI Certified
      • Certification Guidelines
        • Interoperability Requirements
        • Technical Requirements
      • Certification Process
        • Pre-certification Checklist
        • Device Testing Methods
          • Camera
          • HDMI Encoder
          • SDI Encoder
          • Decoder
          • NDI Controller
          • NDI Monitor
          • Multicast Testing
        • Detailed process
    • Metadata
      • Metadata Sources
      • Metadata for XML
      • XML Validation
      • Metadata Elements
      • Proposed New Metadata Messages
      • PTZ and Control Messages
      • Undocumented Mysteries
  • Developer Guides
    • Decoding with NDI
    • NDI Bridge Deployment
    • Receiver Discoverability, Monitoring, and Control Overview
  • FAQ
    • Index
    • NDI Tools
      • What is the NDI Analysis Tool and where do I get it from?
      • Why does my NDI connection stay active once the source is offline?
      • Why are my changes to the NDI JSON configuration file not being saved?
      • Why is the license for my Panasonic camera not active?
      • How does registration for NDI Tools work?
      • The time code on my file is incorrect, how do I change it?
      • How can I make NDI Tools launch automatically?
      • What is the NDI ECCN?
      • How Do I Uninstall NDI Software?
      • Does Discovery Server support Command Line on MacOS?
      • How do I use NDI output with Microsoft Teams
      • Where is Screen Capture (HX) for Mac?
    • NDI Certified
      • What is the NDI Certification Program?
      • Why did you start this certification program?​
      • What happens to my device after it's certified?
      • Is certification mandatory to be a partner of NDI?​
      • I am an OEM manufacturer, can my products be certified?​
      • How long does the certification process take?
      • How do I become certified?​
      • What happens if my product doesn’t meet the requirements for Certification?​
      • Are there any fees to become NDI Certified?
    • Common Issues
      • I'm having trouble getting multicast set up.
      • I'm having trouble with my NDI HX License
      • Why can't I find my Android 14-based NDI devices on my network?
      • Why won’t NDI Tools install on my Windows PC?
      • How do I enable NDI in “New” Microsoft Teams (Windows only)?
      • Why can’t HX Capture display the full resolution of my iPad or iPhone?
      • The NDI HX Camera app won't launch on older phones and iOS
      • Why won't MacOS Sonoma (14.1) recognize NDI Tools as a virtual camera?
      • I'm having issues with Virtual Input for macOS
      • I'm having issues with Final Cut Pro
      • NDI Camera App Issue
    • SDK
      • Where can I find the source code for the FPGA board?
      • What system resources are required to support a design including the NDI FPGA Codecs?
      • Why can’t my h264/265 video be received by an NDI receiver when using the embedded SDK?
      • I haven't received the email with the download.
      • Can I use the Unreal SDK on Mac?
      • What are the Differences Between the NDI SDK and the NDI Advanced SDK
    • ✨NDI 6
      • Do I need to upgrade to NDI 6 if I'm not using the new features?
      • Is there a fee to upgrade to NDI 6
      • Why doesn't my existing Vendor ID work with NDI 6?
      • How can I get a previous version of NDI Tools or the SDK?
    • NDI HX License Upgrades
      • What is happening with NDI HX Upgrades?
      • Will my existing HX-upgraded camera be affected?
      • I bought a camera before June 30, 2025, but didn't buy an HX license. Can I still get one?
      • I bought a license and a camera but didn't redeem it until after. Can I still get an HX license?
      • If my HX upgrade fails can I transfer the license?
      • Can I sell my upgraded HX camera and keep the license?
      • Will my NDI version work with my current HX license?
      • What does the HX upgrade sunset program mean for camera manufacturers?
      • What will NDI Support do for licenses after the sunset date?
      • I factory reset my camera and forgot the license. Can you help me get it back?
Powered by GitBook

2024 @ NDI Vizrt AB.

  1. Developing with NDI
  2. Advanced SDK
  3. NDI SDK Review
  4. Video Formats

Frame Synchronization

When using video, it is important to realize that often you are using different clocks for different parts of the signal chain.

Within NDI, the sender can send at the clock rate it wants, and the receiver will receive it at that rate. In many cases, however, the sender and receiver are extremely unlikely to share the exact same clock rate. Bear in mind that computer clocks rely on crystals which -- while notionally rated for the same frequency -- are seldom truly identical.

For example, your sending computer might have an audio clock rated to operate at 48000 Hz. It might well actually run at 48001 Hz, or perhaps 47998 Hz, however. And similar variances affect receivers. While the differences appear miniscule, they accumulate -- causing audio sync to drift over time. A receiver may receive more samples than it plays back; or audible glitches can occur because too few audio samples are sent in each timespan. Naturally, the same problem affects video sources.

It is very common to address these timing discrepancies by having a "frame buffer" and displaying the most recently received video frame. Unfortunately, the deviations in clock-timing prevent this from being a perfect solution. Frequently, for example, video will appear to 'jitter' when the sending and receiving clocks are almost aligned (which is the most common case).

A "time base corrector" (TBC) or frame-synchronizer for the video clock provides another mechanism to handle these issues. This approach uses hysteresis to determine the best time to either drop or insert a video frame to achieve smooth video playback (audio should be dynamically sampled with a high order resampling filter to adaptively track clocking differences).

It's quite difficult to develop something that is correct for all scenarios, so the NDI SDK provides an implementation to help you develop real time audio/video applications without assuming responsibility for the significant complexity involved. Another way to view what this component of the SDK does is to think of it as transforming 'push' sources (i.e., NDI sources in which the data is pushed from the sender to the receiver) into 'pull' sources, wherein the host application pulls the data down-stream. The frame-sync automatically tracks all clocks to achieve the best video and audio performance while doing so.

In addition to time-base correction operations the frame sync will also automatically detect and correct for timing jitter that might occur. This internally handles timing anomalies such as those caused by network, sender or receiver side timing errors related to CPU limitations, network bandwidth fluctuations, etc.

A very common application of the frame-synchronizer is to display video on screen timed to the GPU v-sync, in which case you should convert the incoming time-base to the time-base of the GPU. The following table lists some common scenarios in which you might want to use frame-synchronization:

Scenario
Recommendation

Video playback on screen or a multiviewer

Yes – you want the clock to be synced with vertical refresh. On a multi-viewer you would have a frame-sync for every video source, then call all of them on each v-sync and redraw all sources at that time.

Audio playback through sound card

Yes – the clock should be synced with your sound card clock.

Video mixing of sources

Yes – all video input clocks need to be synced to your output video clock. You can take each of the video inputs and frame-synchronize them together.

Audio mixing

Yes – you want all input audio clocks to be brought into sync with your output audio clock. You would create a frame-synchronizer for each audio source and – when driving the output – call each one, asking for the correct number of samples and sample-rate for your output.

Recording a single channel

No – you should record the signal in the raw form without any re-clocking.

Recording multiple channels

Maybe – If you want to sync some input channels to match a master clock so they can be ISO-edited, you might want a frame-sync for all sources except one (allowing them all to be synchronized with a single channel).

To create a frame synchronizer object, you will call the function below (that is based on an already instantiated NDI receiver from which it will get frames).

Once this receiver has been bound to a frame-sync, you should use it in order to recover video frames. You can continue to use the underlying receiver for other operations, such as tally, PTZ, metadata, etc. Remember, it remains your responsibility to destroy the receiver -- even when a frame-sync is using it (you should always destroy the receiver after the framesync has been destroyed).

NDIlib_framesync_instance_t NDIlib_framesync_create(NDIlib_recv_instance_t p_receiver);

The frame-sync is destroyed with the corresponding call:

void NDIlib_framesync_destroy(NDIlib_framesync_instance_t p_instance);

To recover audio, the following function will pull audio samples from the frame-sync queue. This function will always return data immediately, inserting silence if no current audio data is present. You should call this at the rate that you want audio, and it will automatically use dynamic audio sampling to conform the incoming audio signal to the rate at which you are calling.

Note that you have no obligation to ensure that your requested sample rate, channel count and number of samples match the incoming signal, and all combinations of conversions are supported.

Audio resampling is done with high order audio filters. Timecode and per frame metadata are inserted into the best possible audio samples. Also, if you specify the desired sample-rate as zero it will fill in the buffer (and audio data descriptor) with the original audio sample rate. And if you specify the channel count as zero, it will fill in the buffer (and audio data descriptor) with the original audio channel count.

void NDIlib_framesync_capture_audio(
    NDIlib_framesync_instance_t p_instance, // The frame sync instance
    NDIlib_audio_frame_v2_t* p_audio_data,  // The destination audio buffer
    int sample_rate, // Your desired sample rate. 0 for “use source”.
    int no_channels, // Your desired channel count. 0 for “use source”.
    int no_samples   // The number of audio samples that you wish to get.
);

The buffer returned is freed using the corresponding function:

void NDIlib_framesync_free_audio(
    NDIlib_framesync_instance_t p_instance,
    NDIlib_audio_frame_v2_t* p_audio_data
);

This function will pull video samples from the frame-sync queue. It will always immediately return a video sample by using time-based correction. You can specify the desired field type, which is then used to return the best possible frame.

Field based frame-sync means that the frame-synchronizer attempts to match the fielded input phase with the frame requests so that you have the most correct possible field ordering on output.

The same frame can be returned multiple times if duplication is needed to match the timing criteria.

It is assumed that progressive video sources can i) correctly display either a field 0 or field 1, ii) that fielded sources can correctly display progressive sources, and iii) that the display of field 1 on a field 0 (or vice versa) should be avoided at all costs.

If no video frame has ever been received, this will return NDIlib_video_frame_v2_t as an empty (all zero) structure. This allows you to determine that there has not yet been any video and act accordingly (for instance you might want to display a constant frame output at a particular video format, or black).

void NDIlib_framesync_capture_video(
    NDIlib_framesync_instance_t p_instance, // The frame-sync instance
    NDIlib_video_frame_v2_t* p_video_data, // The destination video frame
    NDIlib_frame_format_type_e field_type // The frame type that you prefer
);

The buffer returned is freed using the corresponding function:

void NDIlib_framesync_free_video(
    NDIlib_framesync_instance_t p_instance,
    NDIlib_video_frame_v2_t* p_video_data
);

Last updated 6 months ago

Was this helpful?