AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
Sharing AJA Devices With Other Applications

If itʼs possible that your OEM application might coexist with another AJA-aware application on the host computer, itʼs likely neither application will run correctly if they both attempt to control the same AJA device at the same time.

Once your application has found the device it needs to use, AJA strongly recommends obtaining exclusive use of it to prevent collisions with other applications, including AJAʼs own utilities and applications.

The AJA “Retail” Agent

When AJA’s “retail” software is installed, it provides an agent that manages device ownership and provides convenient device widget routing and configuration services to “retail” client applications (e.g., Adobe, Avid, QuickTime, 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.

The ControlPanel provides a user interface for end-users to set default routing, conversions, and other device settings. It communicates configuration changes to the AJA agent through a database stored on the hostʼs file system. The agent enforces the settings stored in the database in an “every frame” task that’s called at every VBI interval.

Prior to AJA software version 17.0, the agent was implemented as a separate process:

  • an agent on macOS;
  • a system service on Windows;
  • a daemon on Linux.

In AJA software version 17.0, the agent service was moved into the ControlPanel application.

  • It presents an icon and context menu in the system “tray” (Windows, Linux) or menu bar (macOS).
  • The AJA “retail” installer configures the host operating system to automatically launch the ControlPanel upon user login.
  • It starts and runs one agent thread per attached device.
  • The device agent (thread) continues to run, even if the ControlPanel window is closed.

If an application sets the task mode (using CNTV2Card::SetEveryFrameServices) to NTV2_OEM_TASKS for a particular device, the agent servicing that device bows out, and stops controlling it.

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(s) to meet their application requirements using APIs provided in the NTV2 SDK.

Some OEM developers require their application to operate on Linux or Windows without AJA “retail” software installed. This is still supported in version 17.0.

Determining if an AJA Device is Being Used

To determine if an AJA device is being used by another application, whether it be an OEM application, or one that uses the Control Panel services, application writers should call CNTV2Card::GetStreamingApplication.

CNTV2Card theDevice;
. . .
// Is an application using the device?
ULWord appFourCC (AJA_FOURCC ('?', '?', '?', '?'));
int32_t appPID (0);
theDevice.GetStreamingApplication (&appFourCC, &appPID);
if (appPID)
{
cout << "Device is being used by process " << appPID << endl;
// Note that the "appFourCC" typically contains a human-readable 4-character "string" that identifies the
// application thatʼs controlling the device, e.g., 'EnGr' is AJA Control Room, 'AJAT' is AJA System Test, etc.
}
else
cout << "Device is available" << endl;

Acquiring Exclusive Use of an AJA Device

To acquire and release exclusive use of an AJA device, OEM application writers must call CNTV2Card::AcquireStreamForApplication or CNTV2Card::ReleaseStreamForApplication, respectively.

// Give my application a unique 4-character "signature"...
const uint32_t kAppSignature (AJA_FOURCC ('s','i','g','n'));
// Attempt to gain exclusive use of the AJA device...
const uint32_t appPID (static_cast <uint32_t> (AJAProcess::GetPid ()));
{
// My app now has exclusive use of the AJA device!
RunMyApplicationUsingDevice (theDevice);
// Iʼm done, so I can relinquish my exclusive use of it...
} // if acquired ok

Getting Full Control Over Device Configuration

In addition to ensuring that other applications wonʼt use use the same AJA device, many applications often need to configure the device differently than the Control Panel settings dictate. These applications must disable the retail (AJA ControlPanel) services by running in “OEM mode”, which is done by calling CNTV2Card::SetEveryFrameServices, passing it NTV2_OEM_TASKS. To be a good citizen, before changing this setting, the old setting should be saved (by calling CNTV2Card::GetEveryFrameServices) and restored when the device is released.

NTV2EveryFrameTaskMode savedTaskMode;
. . .
theDevice.GetEveryFrameServices (&savedTaskMode);
// My app can now configure the AJA device any way it wants,
// without any interference from the retail services!
RunMyApplicationUsingDevice (theDevice);
// I'm done, so I can restore the previous task mode...
theDevice.GetEveryFrameServices (savedTaskMode);

The demonstration applications all use these techniques, and can be used as “best practice” examples.

Reserving Exclusive Use of a Device by a “Process Family”

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 AutoCirculate channel thatʼs available on the device.

In this case, AJA recommends using a controlling (parent) process that does the following:

  • Acquires the AJA device.
  • Launches subordinate per-channel capture/playout (child) processes, including allocating AutoCirculate channels and device frame buffers to child processes (and communicating these parameters to them).
  • Detects if/when child processes terminate (or crash), including deallocating AutoCirculate channels and device frame buffers.
  • Releases the AJA device only when all child processes using it have terminated.
CNTV2MacDriverInterface::ReleaseStreamForApplication
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
Definition: ntv2macdriverinterface.cpp:832
AJA_FOURCC
#define AJA_FOURCC(a, b, c, d)
Definition: types.h:344
CNTV2MacDriverInterface::GetStreamingApplication
virtual bool GetStreamingApplication(ULWord &outAppType, int32_t &outProcessID)
Answers with the four-CC type and process ID of the application that currently "owns" the AJA device ...
Definition: ntv2macdriverinterface.cpp:944
AJAProcess::GetPid
static uint64_t GetPid()
Definition: process.cpp:35
CNTV2Card
I interrogate and control an AJA video/audio capture/playout device.
Definition: ntv2card.h:262
CNTV2Card::SetEveryFrameServices
virtual bool SetEveryFrameServices(const NTV2EveryFrameTaskMode inMode)
Sets the device's task mode.
Definition: ntv2register.cpp:179
CNTV2MacDriverInterface::AcquireStreamForApplication
virtual bool AcquireStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Reserves exclusive use of the AJA device for a given process, preventing other processes on the host ...
Definition: ntv2macdriverinterface.cpp:808
NTV2EveryFrameTaskMode
NTV2EveryFrameTaskMode
Describes the task mode state. See also: Sharing AJA Devices With Other Applications.
Definition: ntv2publicinterface.h:4257
CNTV2Card::GetEveryFrameServices
virtual bool GetEveryFrameServices(NTV2EveryFrameTaskMode &outMode)
Retrieves the device's current "retail service" task mode.
Definition: ntv2register.cpp:184
kAppSignature
static const uint32_t kAppSignature(((((uint32_t)( 'B'))<< 24)|(((uint32_t)( 'u'))<< 16)|(((uint32_t)( 'r'))<< 8)|(((uint32_t)( 'n'))<< 0)))
NTV2_OEM_TASKS
@ NTV2_OEM_TASKS
2: OEM: Device is configured by controlling application(s), with minimal driver involvement.
Definition: ntv2publicinterface.h:4261