Many OEM applications must coexist with other NTV2 SDK client application(s) on a given host computer, whether from AJA or other third-parties. If these applications try to operate the same AJA device at the same time, it can cause one or more of them to malfunction.
This page provides an overview of device control and the recommended “best practices” to prevent malfunctions.
Contents
Device Control Overview
From the moment of power-on, the configuration state of an NTV2 device is affected by many different actors.
Power-Up
When the host computer powers-up, any AJA device that’s installed in it or attached to it will load its installed Firmware and make itself present on the host’s PCIe bus.
The device “wakes up” in a state that’s predetermined by the loaded and now-running firmware, well before the host operating system starts to load.
- Note
- OEM developers should make no assumptions as to the initial power-up state of an AJA device. Unless explicitly documented by AJA, the initial state should be considered indeterminate, and also subject to change without notice.
Driver Start
Once the host operating system has started booting, if the AJA NTV2 device driver is installed, it will probe, match, load, and start.
Driver startup performs a very minimal initialization of some aspects of the device hardware.
- Note
- OEM developers should make no assumptions as to the configuration state of the device immediately after driver startup.
Once the driver is started and running, the device will obey NTV2 SDK function calls made from user-space processes on the host.
AJA Agent
When AJA’s desktop software is installed, it provides an Agent that manages device ownership, handles device widget routing, and provides configuration services to “retail” client applications (e.g., AJA Control Room, Adobe Creative Cloud, Avid Media Composer, Apple Final Cut Pro, etc.). It also configures attached devices to a reasonable default state, or to a preferred state as configured by the user via the AJA ControlPanel application.
- In AJA desktop software version 16.2 and earlier, the agent was implemented as a separate process:
- a per-user “LaunchAgent” on macOS;
- a system-wide service on Windows;
- a system-wide daemon on Linux.
- In AJA desktop software version 17.0 and later, the agent service was moved into the AJA ControlPanel application.
- It presents an icon and context menu in the system “tray” (Windows, Linux) or menu bar (macOS).
- The AJA desktop software installer configures the host operating system to automatically launch the AJA ControlPanel at user login.
- The agent continues to run, even if the AJA ControlPanel window is closed (hidden).
Regardless of implementation, the Agent continually inventories NTV2 devices that are attached to the host, and ensures that one Device Service Thread runs for each attached device.
As devices are attached/detached to/from the host (e.g. Io (Thunderbolt) Devices ), the Agent process spawns/terminates its corresponding Device Service Thread.
Device Service Thread
The Device Service Thread maintains the device based on these state transitions:
- NTV2TaskMode becomes NTV2_STANDARD_TASKS
- The Agent process acquires exclusive use (ownership) of the device.
- The service thread restores the last-saved configuration settings established by the user as set in the AJA ControlPanel.
- The service thread continually enforces, once per output VBI, the established configuration settings.
- This transition usually occurs as a result of:
- NTV2TaskMode exits NTV2_STANDARD_TASKS
- The service thread enters idle mode, and stops enforcing the current device configuration.
- The OEM application can operate the device without any impediment or interference from the service thread.
When the Device Service Thread starts, it checks to see if an application is already using the device — i.e. if it was acquired using CNTV2DriverInterface::AcquireStreamForApplication and CNTV2Card::SetTaskMode was called with NTV2_OEM_TASKS — and if so, it exits the NTV2_STANDARD_TASKS state to leave the device alone. Otherwise, if the device was never initialized after boot-time and never seen before, it configures it to a reasonable default state and enters the NTV2_STANDARD_TASKS state to operate the device.
AJA ControlPanel
The AJA ControlPanel provides a graphical user interface (GUI) for end-users to set up a default configuration for the device as needed for input (Pass-Through) or output (Test Pattern), along with numerous other device settings.
It communicates configuration changes to the AJA Agent through a database stored on the hostʼs file system.
When the NTV2TaskMode is NTV2_OEM_TASKS or NTV2_DISABLE_TASKS, the ControlPanel stops responding to user input, and will no longer accurately display the true state of the device.
- Note
- AJA does not provide a public API for interrogating or controlling the ControlPanel settings.
- Warning
- OEM applications must not rely on ControlPanel behavior, nor on any device configuration that results from any ControlPanel settings, as these are subject to change without notice. OEM applications must configure the AJA device to meet their requirements using the APIs provided in the NTV2 SDK.
Some OEM developers require their application to operate on Linux or Windows without AJA’s desktop software installed. This will continue to be supported.
OEM & Third-Party Applications
A well-behaved OEM application should follow the strategy used in most of the Demonstration Applications.
- Obtain the current NTV2TaskMode (so it can be restored later) — call CNTV2Card::GetTaskMode.
card.GetTaskMode (savedTaskMode);
- Check if the device is being used by another application — call CNTV2DriverInterface::GetStreamingApplication … then fail if it’s in use.
card.GetStreamingApplication (appFourCC,
appPID);
{
return false;
}
cout << "Device is available" << endl;
- Take ownership of the device — call CNTV2DriverInterface::AcquireStreamForApplication.
{
cerr << "Unable to acquire device" << endl;
return false;
}
cout << "I own the device now" << endl;
- Take control of the device by setting the NTV2TaskMode to NTV2_OEM_TASKS — call CNTV2Card::SetTaskMode.
- Operate the device.
- When finished with the device, release it — call CNTV2DriverInterface::ReleaseStreamForApplication.
- Restore the original NTV2TaskMode — call CNTV2Card::SetTaskMode.
card.SetTaskMode (savedTaskMode);
Multi-Process Applications
Some applications may require several programs that run concurrently, all using the same AJA device. For example, there may be one capture or playout process instance running for each FrameStore/channel available on the device.
In this case, AJA recommends using a controlling (parent) process that does the following:
- Acquires the device and assumes control of it.
- Launches subordinate per-channel capture or playout (child) processes as required.
- If using AutoCirculate, it may want to assign the NTV2ACFrameRange to be used by the child process.
- The child process would ordinarily be responsible for widget routing and configuring the channel it operates.
- The child process would perform the frame processing (perhaps in a high-priority thread) until told to stop (by some event or signal).
- Just before exiting, the child process would clean up after itself, disconnecting the widgets it used, disabling its FrameStore, etc. (though this cleanup could be done by the manager/parent process).
- Detects when child processes terminate (or crash).
- Releases the AJA device only when all child processes using it have terminated.