Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
allow_monitoring: A flag to allow monitoring of the sender.DEFINE_GUID(CLSID_NdiSourceFilter, 0x90f86efc, 0x87cf, 0x4097,
0x9f, 0xce, 0xc, 0x11, 0xd5, 0x73, 0xff, 0x8f);bool NDIlib_send_advertiser_add_sender(
NDIlib_send_advertiser_instance_t p_instance,
NDIlib_send_instance_t p_sender,
bool allow_monitoring
);bool NDIlib_send_advertiser_del_sender(
NDIlib_send_advertiser_instance_t p_instance,
NDIlib_send_instance_t p_sender
);// Create an unconnected sender that will be set up for advertising.
NDIlib_send_instance_t pNDI_sender = NDIlib_send_create();
if (!pNDI_sender) {
// Handle error
}
// Create an instance of the sender advertiser
NDIlib_send_advertiser_instance_t pNDI_send_advertiser = NDIlib_send_advertiser_create();
if (!pNDI_send_advertiser) {
// Handle error
}
// Register the sender with the advertiser
NDIlib_send_advertiser_add_sender(pNDI_send_advertiser, pNDI_sender, true);
// Do stuff
...
// Remove the sender from the advertiser before destroying it
NDIlib_send_advertiser_del_sender(pNDI_send_advertiser, pNDI_sender);
// Destroy the sender advertiser
NDIlib_send_advertiser_destroy(pNDI_send_advertiser);
// Destroy the sender
NDIlib_send_destroy(pNDI_sender);// Create the descriptor of the object to create
NDIlib_find_create_t find_create;
find_create.show_local_sources = true;
find_create.p_groups = NULL;
// Create the instance
NDIlib_find_instance_t pFind = NDIlib_find_create_v2(&find_create);
if (!pFind)
/* Error */;
while (true) // You would not loop forever of course !
{
// Wait up till 5 seconds to check for new sources to be added or removed
if (!NDIlib_find_wait_for_sources(pFind, 5000))
{
// No new sources added!
printf("No change to the sources found.\n");
}
else
{
// Get the updated list of sources
uint32_t no_sources = 0;
const NDIlib_source_t* p_sources =
NDIlib_find_get_current_sources(pFind, &no_sources);
// Display all the sources.
printf("Network sources (%u found).\n", no_sources);
for (uint32_t i = 0; i < no_sources; i++)
printf("%u. %s\n", i + 1, p_sources[i].p_ndi_name);
}
}
// Destroy the finder when you’re all done finding things
NDIlib_find_destroy(pFind);// // HDR require metadata information in video frame
// note 'transfer' have two possible values for HDR: bt_2100_pq or bt_2100_hlg
NDI_video_frame_16bit.p_metadata =
"<ndi_color_info "
" transfer=\"bt_2100_hlg\" "
" matrix=\"bt_2020\" "
" primaries=\"bt_2020\" "
"/> ";
<ndi_color_info primaries="bt_2020" transfer="bt_2100_hlg" matrix="bt_2020" /><ndi_metadata_group>
<ndi_color_info primaries="bt_2020" transfer="bt_2100_hlg" matrix="bt_2020" />
</ndi_metadata_group>NDIlib_recv_create_v3_t NDI_recv_create_desc;
NDI_recv_create_desc.source_to_connect_to = *p_hdr_source;
NDI_recv_create_desc.color_format = NDIlib_recv_color_format_best;
// Create the receiver
NDIlib_recv_instance_t pNDI_recv = NDIlib_recv_create_v3(&NDI_recv_create_desc);
If the incoming NDI stream is high bit depth then the video frame received via NDIlib_recv_capture_v2 will have a fourCC of either NDIlib_FourCC_video_type_P216 or NDIlib_FourCC_video_type_PA16.NDIlib_routing_instance_t NDIlib_routing_create(
const NDIlib_routing_create_t* p_create_settings);bool NDIlib_routing_change(NDIlib_routing_instance_t p_instance,
const NDIlib_source_t* p_source);bool NDIlib_routing_clear(NDIlib_routing_instance_t p_instance);void NDIlib_routing_destroy(NDIlib_routing_instance_t p_instance);// Create the descriptor of the object to create
NDIlib_send_listener_create_t sender_listener_create;
// The URL address of the discovery server to connect to
sender_listener_create.p_url_address = "127.0.0.1";
// Create an instance of the sender listener
NDIlib_send_listener_instance_t pNDI_send_listener = NDIlib_send_listener_create(&sender_listener_create);
if (!pNDI_send_listener) {
return 0; // Handle error
}
// To remember the last connected state
bool last_connected = false;
while (true) { // You would not loop forever in a real application!
// Check if the sender listener is currently connected
bool curr_connected = NDIlib_send_listener_is_connected(pNDI_send_listener);
// Has the connection state changed?
if (last_connected != curr_connected) {
printf("The listener is now %s.\n", curr_connected ? "connected" : "disconnected");
last_connected = curr_connected;
}
// Wait up to 5 seconds to check for new senders
if (!NDIlib_send_listener_wait_for_senders(pNDI_send_listener, 5000)) {
// No new senders added
printf("No change to the senders found.\n");
}
else
{
// Get the updated list of senders
uint32_t num_senders = 0;
const NDIlib_sender_t* p_senders = NDIlib_send_listener_get_senders(pNDI_send_listener, &num_senders);
// Display all of the found senders
printf("Network senders (%u found).\n", num_senders);
for (uint32_t i = 0; i != num_senders; i++) {
printf("%u. %s\n", i + 1, p_senders[i].p_name);
}
}
}
// Destroy the sender listener
NDIlib_send_listener_destroy(pNDI_send_listener);Updated as of Version 6.2
{
"ndi": {
"vendor": {
"name": "SKU LAST 4, Customer name first4,dateofissuance 6digits mmddyy",
"id": "Generated License"
},
"machinename": "MachineName",
"send": {
"metadata": "<My very cool source/>"
},
"networks": {
"ips": "192.168.1.92,",
"discovery": "65.52.14.139,65.52.14.138"
},
"groups": {
"send": "Public",
"recv": "Public"
},
"sourcefilter": {
"regex": "MACHINE .*"
},
"adapters": {
"allowed": [
"10.28.2.10",
"10.28.2.11"
]
},
"tcp": {
"recv": {
"enable": true
}
},
"rudp": {
"recv": {
"enable": true
}
},
"unicast": {
"recv": {
"enable": true
}
},
"multicast": {
"send": {
"ttl": 1,
"enable": false,
"netmask": "255.255.0.0",
"netprefix": "239.255.0.0"
}
},
"codec": {
"shq": {
"quality": 100,
"mode": "auto"
}
},
"bridge": {
"host": true,
"join": false,
"address": "127.0.0.1",
"port": 5990,
"secure": "123abc",
"ntk": true,
"reflect": true,
"srcgroups": "0ca7b4fd-4bbe-41d8-b263-b8cbeec1188c",
"bufferdelay": 0,
"diag": "info",
"id": "NiceCamera"
}
}
}
allow_controlling: A flag to allow controlling of the receiver.bool NDIlib_recv_advertiser_add_receiver(
NDIlib_recv_advertiser_instance_t p_instance,
NDIlib_recv_instance_t p_receiver,
bool allow_controlling, bool allow_monitoring,
const char* p_input_group_name NDILIB_CPP_DEFAULT_VALUE(NULL)
);bool NDIlib_recv_advertiser_del_receiver(
NDIlib_recv_advertiser_instance_t p_instance,
NDIlib_recv_instance_t p_receiver
);// Create an unconnected receiver that will be set up for advertising. NDIlib_recv_instance_t pNDI_recv = NDIlib_recv_create_v3();
if (!pNDI_recv) {
// Handle error
}
// Create an instance of the receiver advertiser
NDIlib_recv_advertiser_instance_t pNDI_recv_advertiser = NDIlib_recv_advertiser_create();
if (!pNDI_recv_advertiser) {
// Handle error
}
// Register the receiver with the advertiser
NDIlib_recv_advertiser_add_receiver(pNDI_recv_advertiser, pNDI_recv, true, true);
// Do stuff
...
// Remove the receiver from the advertiser before destroying it
NDIlib_recv_advertiser_del_receiver(pNDI_recv_advertiser, pNDI_recv);
// Destroy the receiver advertiser NDIlib_recv_advertiser_destroy(pNDI_recv_advertiser);
// Destroy the receiver NDIlib_recv_destroy(pNDI_recv);// Create the descriptor of the object to create
NDIlib_recv_listener_create_t listener_create;
// The URL address of the discovery server to connect to
listener_create.p_url_address = "127.0.0.1";
// Create an instance of the receiver listener
NDIlib_recv_listener_instance_t pNDI_recv_listener = NDIlib_recv_listener_create(&listener_create);
if (!pNDI_recv_listener) { return 0; // Handle error
}
// To remember the last connected state
bool last_connected = false;
while (true) { // You would not loop forever in a real application!
// Check if the listener is currently connected
bool curr_connected = NDIlib_recv_listener_is_connected(pNDI_recv_listener);
// Has the connection state changed?
if (last_connected != curr_connected) {
printf("The listener is now %s.\n", curr_connected ? "connected" : "disconnected");
last_connected = curr_connected;
}
// Wait up to 5 seconds to check for new receivers
if (!NDIlib_recv_listener_wait_for_receivers(pNDI_recv_listener, 5000)) {
// No new receivers added
printf("No change to the receivers found.\n");
}
else
{
// Get the updated list of receivers
uint32_t num_receivers = 0;
const NDIlib_receiver_t* p_receivers =
NDIlib_recv_listener_get_receivers(pNDI_recv_listener, &num_receivers);
// Display all of the found receivers
printf("Network receivers (%u found).\n", num_receivers);
for (uint32_t i = 0; i != num_receivers; i++) {
printf("%u. %s\n", i + 1, p_receivers[i].p_name);
}
}
}
// Destroy the receiver listener NDIlib_recv_listener_destroy(pNDI_recv_listener);{
"ndi": {
"machinename": "Hello World","send": {
"metadata": "<My very cool source/>"
},"networks": {
"ips": "192.168.86.32,",
"discovery": "127.0.0.1,127.0.0.1"
},"groups": {
"send": "Public",
"recv": "Public"
},"sourcefilter": {
"regex": "MACHINE .*"
},"adapters": {
"allowed": ["10.28.2.10","10.28.2.11"]
},"rudp": {
"send": {
"enable": true
},
"recv": {
"enable": true
}
},"multicast": {
"send": {
"ttl": 1,
"enable": false,
"netmask": "255.255.0.0",
"netprefix": "239.255.0.0"
},
"recv": {
"enable": true
}
},"tcp": {
"send": {
"enable": false
},
"recv": {
"enable": false
}
},"unicast": {
"send": {
"enable": false
},
"recv": {
"enable": false
}
},"codec": {
"shq": {
"quality": 100,
"mode": "auto"
}
},
}
}NDI Stream Record v1.00
Copyright (C) 2023 Vizrt NDI AB. All rights reserved.
[14:20:24.138]: <record_started filename="e:\Temp 2.mov" filename_pvw="e:\Temp 2.mov.preview" frame_rate_n="60000" frame_rate_d="1001"/>
[14:20:24.178]: <recording no_frames="0" timecode="732241356791" vu_dB="-23.999269" start_timecode="732241356791"/>
[14:20:24.209]: <recording no_frames="0" timecode="732241690457" vu_dB="-26.976938"/>
[14:20:24.244]: <recording no_frames="2" timecode="732242024123" vu_dB="-20.638922"/>
[14:20:24.277]: <recording no_frames="4" timecode="732242357789" vu_dB="-20.638922"/>
[14:20:24.309]: <recording no_frames="7" timecode="732242691455" vu_dB="-17.237122"/>
[14:20:24.344]: <recording no_frames="9" timecode="732243025121" vu_dB="-19.268487"/>
...
[14:20:27.696]: <record_stopped no_frames="229" last_timecode="732273722393"/>{
"binding": "127.0.0.1",
"port_no": "5959"
}NDIlib_send_createNDIlib_send_create_t send_create;
send_create.p_ndi_name = "My Video";
send_create.p_groups = NULL;
send_create.clock_video = true;
send_create.clock_audio = true;
NDIlib_send_instance_t pSend = NDIlib_send_create(&send_create);
if (!pSend)
printf("Error creating NDI sender");// Allocate a video frame (you would do something smarter than this!)
uint8_t* p_frame = (uint8_t*)malloc(1920*1080*4);
memset(p_frame, 255, 1920*1080*4);
// Now send it!
NDIlib_video_frame_v2_t video_frame;
video_frame.xres = 1920;
video_frame.yres = 1080;
video_frame.FourCC = NDIlib_FourCC_type_BGRA; video_frame.frame_rate_N = 30000;
video_frame.frame_rate_D = 1001;
video_frame.picture_aspect_ratio = 16.0f/9.0f;
video_frame.frame_format_type = NDIlib_frame_format_type_progressive;
video_frame.timecode = 0;
video_frame.p_data = p_frame;
video_frame.line_stride_in_bytes = 1920*4;
video_frame.p_metadata = "<Hello/>";
// Submit the buffer
NDIlib_send_send_video_v2(pSend, &video_frame);
// Free video memory
free(p_frame);
// In a similar fashion, audio can be submitted for NDI audio sending,
// the following will submit 1920 quad-channel silent audio samples
// at 48 kHz
// Allocate an audio frame (you would do something smarter than this!)
float* p_frame = (float*)malloc(sizeof(float)*1920*4)
memset(p_frame, 0, sizeof(float)*1920*4);
// describe the buffer
NDIlib_audio_frame_v3_t audio_frame;
audio_frame.sample_rate = 48000;
audio_frame.no_channels = 4;
audio_frame.no_samples = 1920;
audio_frame.timecode = 0;
audio_frame.p_data = p_frame;
audio_frame.channel_stride_in_bytes = sizeof(float)*1920;
audio_frame.p_metadata = NULL; // No metadata on this example!
// Submit the buffer
NDIlib_send_send_audio_v3(pSend, &audio_frame);
// Free the audio memory
free(p_frame);// Wait for 1 second to see if there is a metadata message available
NDIlib_metadata_frame_t metadata;
if (NDIlib_send_capture(pSend, &metadata, 1000) == NDIlib_frame_type_metadata)
{
// Do something with the metadata here
// ...
// Free the metadata message
NDIlib_recv_free_metadata(pSend, &meta_data);
}// Wait for 1 second to see if there is a tally change notification.
NDIlib_tally_t tally_data;
if (NDIlib_send_get_tally(pSend, &tally_data)
{
// The tally state changed and you can now
// read the new state from tally_data.
}// Provide a metadata registration that allows people to know what we are.
NDIlib_metadata_frame_t NDI_product_type;
NDI_product_type.p_data = "<ndi_product long_name=\"NDILib Send Example.\" "
" short_name=\"NDILib Send\" "
" manufacturer=\"CoolCo, inc.\" "
" model_name=\"PBX-15M\" "
" version=\"1.000.000\" "
" serial=\"ABCDEFG\" "
" session_name=\"My Midday Show\" />";
NDIlib_send_add_connection_metadata(pSend, &NDI_product_type);while(!done())
{
render_frame();
NDIlib_send_send_video_v2_async(pSend, &frame_data);
}
NDIlib_send_send_video_v2_async(pSend, NULL); // Sync herevoid NDIlib_send_set_failover(NDIlib_send_instance_t p_instance,
const NDIlib_source_t* p_failover_source);NDIlib_metadata_frame_t NDI_capabilities;
NDI_capabilities.p_data = "<ndi_capabilities web_control=\"http://ndi.video/\" "
" ntk_ptz=\"true\" "
" ntk_exposure_v2=\"true\" />";
NDIlib_send_add_connection_metadata(pNDI_send, &NDI_capabilities_type);NDI sending and receiving use common structures to define video, audio, and metadata types. The parameters of these structures are documented below.
uint8_t *p_uyvy = (uint8_t*)p_data;
uint8_t *p_alpha = p_uyvy + stride*yres;// Create an instance of the sender listener.
NDIlib_send_listener_instance_t pNDI_sender_listener = NDIlib_send_listener_create_ex(nullptr, p_ndi_config);
if (!pNDI_sender_listener) {
// Handle error
}
// Get the list of advertised senders.
uint32_t num_senders = 0;
const NDIlib_sender_t* p_senders = NDIlib_send_listener_get_senders(pNDI_send_listener, &num_senders);
// Display the found senders.
printf("Network senders (%u found).\n", num_senders);
for (uint32_t i = 0; i < num_senders; i++) {
printf("%u. %s\n", i + 1, p_senders[i].p_name);
// If the sender is not currently subscribed, subscribe to it.
if (!p_sender[i].events_subscribed) {
NDIlib_send_listener_subscribe_events(pNDI_send_listener, p_senders[i].p_uuid);
}
// Perform operations with the subscribed sender...
…
// Unsubscribe from the sender after processing.
NDIlib_send_listener_unsubscribe_events(pNDI_send_listener, p_senders[i].p_uuid);
} const NDIlib_send_listener_event*
NDIlib_send_listener_get_events(NDIlib_send_listener_instance_t p_instance, uint32_t* p_num_events, uint32_t timeout_in_ms); uint32_t num_events;
const NDIlib_send_listener_event* events = NDIlib_send_listener_get_events(p_instance, &num_events, 1000);
if (events != NULL) {
for (uint32_t i = 0; i < num_events; ++i) {
printf("Event UUID: %s\n", events[i].p_uuid);
printf("Event Name: %s\n", events[i].p_name);
printf("Event Value: %s\n", events[i].p_value);
}
// Free the events after processing
NDIlib_send_listener_free_events(events);
} else {
printf("No events received within the timeout period.\n");
} uint16_t *p_y = (uint16_t*)p_data;
uint16_t *p_uv = (uint16_t*)(p_data + stride*yres); uint16_t *p_y = (uint16_t*)p_data;
uint16_t *p_uv = p_y + stride*yres;
uint16_t *p_alpha = p_uv + stride*yres; uint8_t *p_y = (uint8_t*)p_data;
uint8_t *p_v = p_y + stride*yres;
uint8_t *p_u = p_v + (stride/2)*(yres/2); uint8_t *p_y = (uint8_t*)p_data;
uint8_t *p_v = p_y + stride*yres;
uint8_t *p_u = p_v + (stride/2)*(yres/2); uint8_t *p_y = (uint8_t*)p_data;
uint8_t *p_uv = p_y + stride*yres;NDIlib_recv_color_format_fastest, this format will always deliver individual fields, implicitly assuming the allow_video_fields option as true.NDIlib_video_frame_v2_t video_frame;
NDIlib_audio_frame_v3_t audio_frame;
NDIlib_metadata_frame_t metadata_frame;
switch (NDIlib_recv_capture_v3(pRecv, &video_frame, &audio_frame, &metadata_frame, 1000))
{
// We received video.
case NDIlib_frame_type_video:
// Process video here
// Free the video.
NDIlib_recv_free_video_v2(pRecv, &video_frame);
break;
// We received audio.
case NDIlib_frame_type_audio:
// Process audio here
// Free the audio.
NDIlib_recv_free_audio_v3(pRecv, &audio_frame);
break;
// We received a metadata packet
case NDIlib_frame_type_metadata:
// Do what you want with the metadata message here.
// Free the message
NDIlib_recv_free_metadata(pRecv, &metadata_frame);
break;
// No audio or video has been received in the time-period.
case NDIlib_frame_type_none:
break;
// The device has changed status in some way (see notes below)
case NDIlib_frame_type_status_change:
break;
} // Provide a metadata registration that allows people to know what we are.
NDIlib_metadata_frame_t NDI_product_type;
NDI_product_type.p_data = "<ndi_product long_name=\"NDILib Receive Example.\" "
" short_name=\"NDILib Receive\" "
" manufacturer=\"CoolCo, inc.\" "
" version=\"1.000.000\" "
" model_name=\"PBX-42Q\" "
" session_name=\"My Midday Show\" "
" serial=\"ABCDEFG\" />";
NDIlib_recv_add_connection_metadata(pRecv, &NDI_product_type);const char* p_url = NDIlib_recv_get_web_control(pRecv);
if (p_url)
{
// You now have a URL that you can embed in your user interface if you want!
// Do what you want with it here and when done, call:
NDIlib_recv_free_string(pRecv, p_url);
}
else
{
// This device does not currently support a configuration user interface.
}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.void NDIlib_framesync_free_audio(NDIlib_framesync_instance_t p_instance,
NDIlib_audio_frame_v2_t* p_audio_data);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 prefervoid NDIlib_framesync_free_video(NDIlib_framesync_instance_t p_instance,
NDIlib_video_frame_v2_t* p_video_data);

