C++ Application Code

A set of example applications are provided which illustrate the use of the FPGA based NDI IP cores with the Advanced NDI SDK. For full details and a theory of operation covering the entire system (software, hardware, and OS), refer to "Theory of Operation" in the "NFI FPGA Reference Design" section.

Directory structure

Source code for the C++ Application examples is organized into the following subdirectories under the fpga_reference_design/src/cpp/ directory:

Directory
Contents

ndi_common/

Files common to all NDI applications

ndi_decode/

Example NDI Decoder application (eg: TV or Monitor)

ndi_encode/

Example NDI Encoder application (eg: Camera or NDI Source)

ndi_util/

Debug and utility applications

Getting Started

Prerequisites

The following prerequisites must be installed before you can build the example applications.

libuio

libuio is used to access the FPGA hardware via entries in the device-tree

The available uSD card images have libuio packages compiled from source (see ~/libuio) and the debian packages installed. For other platforms, libuio will need to be compiled and installed manually.

NDI Advanced SDK Library

The NDI Advanced SDK allows the sending and receiving of compressed frames, which is required to use the FPGA encoder. To install the library, simply copy the files to an appropriate location for your system. The example uSD card images have the NDI library files already installed in /usr/local/lib and /usr/local/include.

Building and Installing

Once the prerequisites have been installed, building the applications is straight-forward:

The applications will be installed with setuid privileges to the /usr/local/bin/ directory.

ndi_encode

The ndi_encode utility is an example application illustrating the use of the FPGA based NDI encoder IP and the Advanced NDI SDK to create an NDI sender.

he ndi_encode program is simply launched from the command line, eg:

Note that this will launch the version installed in /usr/local/bin/. Alternatively, the program can be run from the build directory. Note that root permissions are required so it is necessary to use sudo:

Run Time Commands

Once running, the program will listen for commands on stdin. These commands are intended to modify the running behavior of the program and illustrate how to integrate with a separate utility monitoring the physical video input source (eg: an HDMI or SDI input) as a signal is acquired, locked, or lost.

The commands which change the raw video parameters (resolution, frame rate, format, alpha) only apply when running in pattern generator mode. With a real video input, format details are determined automatically by the tracking logic.

  • start | stop

    Start or stop streaming video and audio. This would correspond with the acquisition (start) or loss (stop) of a stable signal.

  • 720 | 1080 | 4k

    Change the video resolution

  • 24 | 25 | 30 | 50 | 60

    Set the primary video frame rate

  • 1000 | 1001

    Set the secondary frame rate: 1000=exact (eg: 60.00), 1001=NTSC (eg: 59.94)

  • UYVY | YUYV | NV16 | UYVW | Y216 | P216 | 420 | NV12 | 420W | P016

    Set the raw video format

  • Alpha+ | Alpha-

    Enable / Disable alpha (4:2:2 modes only)

  • exit

    Quit the program

Command Line Options

Various command line switches are available to control the program's behavior:

General Options

  • Set default video resolution

    • -1 1080p60 (default)

    • -7 720p60

    • -4 4Kp60

  • Video options

    • -P Pattern generator

      Use the built-in pattern generator instead of live video input.

    • -v Increase verbosity

      Output more detailed information. This switch may be provided multiple times to further increase the debugging output. The available levels are:

      • Fatal

      • Error (default)

      • Warning

      • Information

      • Debugging

    • -q Decrease verbosity (quiet)

      Decrease the amount of output generated. This switch may be provided multiple times. See the discussion of -v (above) for details.

  • Audio Options

    • -h HDMI input

      Use embedded audio from the HDMI stream.

    • -l Line input

      Use analog audio input.

    • -p Pattern generator

      The audio input hardware includes a simple saw-tooth pattern generator that can be used as an input source for testing.

Debugging and Advanced Options

  • -X Disable video capture

    This disables the video capture thread. No video frames will be captured, compressed, or sent to the NDI stack. Only audio will be processed.

  • -x Disable audio capture

    This disables the video capture thread. No audio samples will be captured, compressed, or sent to the NDI stack. Only video will be processed.

  • -F Full resolution capture only

    This option disables the preview stream and only sends full resolution frames to the NDI stack.

  • -f fflush() after each log message

    This is useful if the application is crashing to insure log error messages actually reach the terminal.

  • -A Use ACP

  • -B Bypass ACP

    These options do nothing on the current Zynq development boards and only apply to Cyclone-V based platforms.

ndi_decode

The ndi_decode utility is an example application illustrating the use of the FPGA based NDI encoder IP and the Advanced NDI SDK to create an NDI receiver.

Usage

The ndi_decode program is simply launched from the command line, eg:

Note that this will launch the version installed in /usr/local/bin/. Alternatively, the program can be run from the build directory. Note that root permissions are required so it is necessary to use sudo:

sudo /path/to/workdir/ndi_receive

Command Line Options

Various command line switches are available to control the program's behavior:

General Options

  • -s <NDI Source>

    Specify NDI source to stream. If this setting is not provided, ndi_receive will attempt to connect to the first NDI source it finds on the network.

  • Set output video resolution

    • -1 1080p (default)

    • -7 720p

    • -4 4Kp

  • Set output video framerate

    • -6 60 Hz (default)

    • -5 50 Hz

  • Select output video

    • -k Output key (alpha) data if available instead of image data

  • Select SDRAM burst mode

    • -b Disable SDRAM burst mode (e.g., 1 macroblock to SDRAM per burst transfer). Default behavior is to burst 4 macroblocks to SDRAM per burst transfer.

  • -o <output format>

    Specifies the output video format, where output format is one of the enumerated video_format_t values in hardware.h in decimal. The default is packed 4:2:2 (e.g., UYVY).

Debugging and Advanced Options

  • -v Increase verbosity

    Output more detailed information. This switch may be provided multiple times to further increase the debugging output. The available levels are:

    • Fatal

    • Error (default)

    • Warning

    • Information

    • Debugging

  • -q Decrease verbosity (quiet)

    Decrease the amount of output generated. This switch may be provided multiple times. See the discussion of -v (above) for details.

  • -f fflush() after each log message

    This is useful if the application is crashing to insure log error messages actually reach the terminal.

  • -A Use ACP

  • -B Bypass ACP

    These options do nothing on the current Zynq development boards and only apply to Cyclone-V based platforms.

  • -c <capture file>

Allows for individual frames to be captured to the filesystem. This switch is intended for debugging purposes and assumes that the stride is equal to the length of a row of image data. The default is to capture frame number 25, but this can be modified using the -n argument to select a different value. No more than one frame can be captured at a time.

  • -n <frame capture number>

If capturing video frames, indicates the frame number to capture (defaults to 25). Requires the use of the -c option to capture frames.

ndi_reg

The ndi_reg utility allows reading and writing of the NDI hardware registers. To read an NDI register, provide the register address on the command line:

To write an NDI register, provide the register address and write data on the command line:

Register Map

Each major hardware block is allocated a range of control register addresses as detailed below and implemented in the device.h and hardware.h files in the src/cpp/ndi_common/ directory.

Hardware
Base Address
Length

NDI Encoder Core 0

0x000

0x40

NDI Encoder Core 1

0x040

0x40

NDI Encoder Core 2

0x080

0x40

NDI Encoder Core 3

0x0c0

0x40

NDI Decoder Core 0

0x100

0x40

NDI Decoder Core 1

0x140

0x40

NDI Decoder Core 2

0x180

0x40

NDI Decoder Core 3

0x1c0

0x40

Video Input

0x200

0x10

Preview Input

0x210

0x10

Audio Input

0x220

0x10

Video Tracking

0x230

0x10

Video Output

0x280

0x10

Audio Output

0x290

0x10

Version (Date)

0x3fe

0x10

Version (Revision)

0x3ff

0x10

For low-level details on register settings and bit definitions refer to the specific C++ class code and headers for the hardware as described in the "Theory of Operation" section.

Last updated

Was this helpful?