Sending
NDI senders are created in exactly same way that they would be in the NDI SDK, using NDIlib_send_create
or the newer function available to the Advanced SDK, NDIlib_send_create_v2
.
It is strongly recommended that your device allow its name to be configured, so that individual devices can be identified on the network.
You are also able to specify that your device exists within different NDI groups should you desire.
An example of creating a sender might be:
It is crucial that you provide XML identification for all hardware devices. This should include your vendor's name, model number, serial number and firmware version.
For example, the following XML identification would work, although it should be filled in with the correct settings for your device (serial numbers should be unique to each device manufactured):
You are now going to be able to pass compressed frames directly to the SDK. The following is a very basic example of how this might be configured.
It is important to always submit both a program stream and a preview stream to the SDK. The program stream should be the full resolution video stream. The preview stream should always be progressive, have its longest dimension as 640 pixels, and a framerate that does not exceed 45 Hz.
It is considered acceptable to simply drop every second frame to achieve the correct preview framerate when needed.
It is also acceptable to always scale down by an integer scaling factor to be close to the correct resolution. (Scaling quality is not defined, although high quality scaling is preferred.)
Examples of the preview stream are listed below:
Main Video Format | Preview Video Format |
---|---|
1920x1080, 16:9, 59.94 Hz | 640x360, 16:9, 29.97 Hz |
1920x1080, 16:9, 29.97 Hz | 640x360, 16:9, 29.97 Hz |
1080x1920, 9:16, 50 Hz | 360x640, 9:16, 25 Hz |
To submit a preview resolution frame, one would use the following header (compare with previous example).
It is common on Advanced SDK devices that you wish to have the SDK send frames without needing to wait for them to be complete. The asynchronous operations supported by the NDI SDK have been fully extended to the NDI Advanced SDK, and we recommend that these are used for best hardware performance.
The Advanced SDK has been designed to perform zero memory copy sending of frames over the network when using async operations. The SDK will assume that it can access each async buffer until either a) the next time that NDIlib_send_send_video_async_v2
is called or b) the sender is closed.
Sending and receiving low and high bandwidth frames are entirely asynchronous with each other. It is also possible to send main, preview, and audio streams from separate threads, should this be beneficial.
For instance, the following might be used as a send loop:
Sending audio is nearly identical to sending video. The following example shows how to submit an audio buffer:
It is crucial to ensure that your audio is provided to the SDK at the correct audio level, with a +4 dBU sinewave corresponding to a floating-point signal from -1.0 to +1.0. These levels can easily be debugged using the NDI Studio Monitor application.
The video bitrate should be controlled by your compressor by varying the Q level. You may determine this by calling the following function, which will return the size of the expected frame in bytes.
There are many possible mechanisms available to perform bitrate control, and it is expected that you are within 10% of the returned value. (It is understood that it is often impossible to adapt the Q value for the frame being compressed and that the update will often occur on the subsequent frame.)
The examples above show how video may be sent using NDIlib_send_send_video_v2
. By default, the SDK will not copy the memory buffers of video frames that are passed in (other than implicit copies required by your operating system for network sending events). There may be times when the video frame is composed of multiple pieces instead of a single contiguous block of memory. For the best performance, you can use one of the two scatter-gather sending functions provided to handle frames that are broken up into many pieces, either NDIlib_send_send_video_scatter
, or NDIlib_send_send_video_scatter_async
.
The NDIlib_send_send_video_scatter_async
function will allow you to schedule entirely asynchronous sends. For this purpose, please review the comments above on buffer ownership and lifetime, which are the single most common problems reported due to incorrect SDK usage.
To work with high performance on high latency connections we very strongly recommend that you implement asynchronous sending completions, which are outlined in the next two sections. These allow data to be sent with NDI that does not require any memory-copies to send onto the network, while also allowing enough frames to be "in flight" that one can achieve high performance even on high latency networks.
Sending video is currently supported in 4:2:2:4, 4:2:2, and 4:2:0 formats (4:4:4:4 will be added in a future version; this is already internally supported by the software SDK). It has been our experience that that 4:2:0 yields better video quality at resolutions above 1920x1080, since more bits are assigned in the luminance.
Last updated