AJA NTV2 SDK  17.0.1.1246
NTV2 SDK 17.0.1.1246
Capture and Playout Techniques

This page describes the basics of capturing and playing real-time video, then describes the two most popular methods:

Playout Basics

Coming soon.

Playout Demos:

Capture Basics

Coming soon.

Input Detection

Coming soon.

Capture Demos:

Ping-Pong

The “ping-pong” method is a good choice when lower latency is required. The illustration shows a scenario that captures incoming video frames, alters the captured frame in some way (e.g., “burn” an image onto it), and then plays the altered frames. One thread would, at every input VBI, flip the Input Frame between 0 and 1, and transfer the just-captured frame to the host. The other thread would, at every output VBI, flip the Output Frame between 2 and 3, and transfer a finished frame from the host to the off-screen buffer on the device. This should result in a three frame latency.

By getting “closer to the metal” with this technique, the application designer must manage every detail … making DMA transfers at the right time, keeping the audio synchronized with the video, getting/setting timecode, etc.

Any unexpected delays or slow-downs in frame processing or DMA transfers will cause visual distortion.

The low-latency model can support either field or frame mode processing. In this model, a time-critical user-mode thread is used to manage capture and/or playback in real-time.

For capture, full frames or separate fields can be transferred immediately after the VBI is received. Audio can be transferred based on the actual number of audio samples that have been written into the device audio buffer.

For playback, frames written to the device frame buffer can be set to go on-air any time before the VBI. Field-mode processing here is a little tricky, as once the first field is on-air, the second field will go on-air ready-or-not, so the application must make some real-time decisions if it needs to drop a field. Low-latency client software can be written with a delay parameter that would allow for some variation in the application’s video processing time while maintaining a fixed delay, but it may not provide the reliability of the kernel queuing model.

Some relevant API calls:

Ping-Pong Capture/Playout Demos:

AutoCirculate

AutoCirculate is an API in the CNTV2Card class which allows real-time video streaming on a non-real-time host operating system. Video frames are buffered between the application software and the AJA device driver, and the driver is responsible for playing out (or capturing) those frames at the correct time.

AutoCirculate makes it easy to stream audio & video data into and out of your application.

AutoCirculate keeps Ancillary Data such as Embedded Audio and Timecode (RP-188, SMPTE-12M) synchronized with the AutoCirculating video frames.

The AJA device driver performs the bulk of the work involved in streaming audio and video to/from the AJA hardware. It helps to synchronize the audio with the video, detect dropped frames while streaming, time-stamps the frame data, reads or writes embedded timecode, and manages many other details.

The AutoCirculate API coordinates the transfer of video and audio data between the AJA driver and the host application as the driver circulates through its designated frame set (which is a contiguous block of frames in device SDRAM). For recording, the driver cycles through its associated input frames, and on playback, the driver cycles through its associated output frames. For example, an AutoCirculate capture using 7 frames would record each incoming frame one at a time into device SDRAM in frames 0…6, 0…6, 0…6 ad infínitum, continually and repeatedly reusing those frame “slots” in its memory. The key is for the host application to continually transfer the captured frames from device memory into host memory fast enough to keep up with the incoming video being recorded on the device.

Note
AutoCirculate is intended for use in applications that require high reliability and that don’t require low latency. For low latency ingest or playout applications, the application must get “closer to the metal” and use another method, such as the Ping-Pong method.

AutoCirculate Capture

Here’s an example of how AutoCirculate works in capture mode using 10 frame buffers:

In this illustration, AutoCirculate is capturing, using 10 frame buffers. Here, captured frames 6, 7, 8, 9, 0 and 1 have already been transferred into host memory (in that order), while frame 2 is currently being transferred to the host, while frame 5 on the AJA device is currently being overwritten by the incoming frame.

As each Incoming Frame streams into the AJA device, its image data (plus audio and other Ancillary Data) is recorded into the Active Frame of the device’s frame memory.

When AutoCirculate is running, frames get transferred using Direct Memory Access (DMA) from the device frame memory to host memory.

The Transfer Frame — the frame being transferred to the host at the host’s request — “chases” the Active Frame, with the gap between them called the Buffer Level.

To prevent “torn” or malformed images, the host application must ensure that the Transfer Frame never coincides with the Active Frame being recorded.

Assuming a 29.97 fps full-frame rate, the AJA driver will bump the Active Frame to the next frame slot every 33 milliseconds. As long as the host application that’s transferring frames takes less than 33 milliseconds (including the DMA transfer time) to consume each frame, all will be well. If the host takes longer than 33 milliseconds to consume a frame, the Transfer Frame will start to fall behind, and the Buffer Level will increase. If this is allowed to continue, the Active Frame will overtake the Transfer Frame, which will result in “dropped” frames that never get transferred to the host. The dropped frame count is available from the AUTOCIRCULATE_STATUS::GetDroppedFrameCount function. (See AUTOCIRCULATE_STATUS and CNTV2Card::AutoCirculateGetStatus for more information.)

If the AutoCirculate channel was configured to capture audio, it will continuously monitor the incoming Audio/Video sync. If it detects a difference of more than about 10 milliseconds, it will attempt to resync the audio to the video. This resynchronization requires restarting the audio engine, which often results in a click or pop in the captured audio.

(See Timecode (RP-188, SMPTE-12M) for more information about timecode capture and AutoCirculate.)

Per-Frame “Time Budget”

To prevent dropping frames, the application must stay within its per-frame “time budget”.

  • The video frame rate determines the per-frame “time budget”.
  • If the budget is exceeded long enough, the application will drop frames.
  • The “time budget” is spent doing three things:
    • DMA Transfer: The elapsed time spent in the CNTV2Card::AutoCirculateTransfer function.
    • Processing: The elapsed time from the moment CNTV2Card::AutoCirculateTransfer returns and the next time it’s about to be called (minus any Waiting time … see next item).
    • Waiting: The time spent waiting for a new frame to become ready to transfer from the device.
      • If the application has fallen behind (i.e. the Buffer Level exceeds 1), this wait time should be zero.
      • If the application has caught up, this wait time will be non-zero.
  • It’s a good practice to add code that always measures the above elapsed times.
  • The sum of the Processing and DMA Transfer times must remain within the per-frame “time budget” (i.e. below frame time).
  • The proper action to take if the per-frame “time budget” is exceeded is application-dependent, and could include:
    • log a message to the application or host logging facility;
    • trigger an event;
    • set an alarm;
    • etc.
  • Occasionally exceeding the “time budget” for one or more frames can be tolerated…
    • …if the application can catch up by sustained sub-frame-time DMA and frame processing, and…
    • …the number of AutoCirculate device frame buffers is large enough to give the application time to catch up.

Frame Count Considerations (Capture)

The more device frames dedicated to an AutoCirculate channel (specified by inFrameCount or inStartFrameNumber/inEndFrameNumber in CNTV2Card::AutoCirculateInitForInput or CNTV2Card::AutoCirculateInitForOutput), the more time the client application can be held off from transferring the next frame from the device. This increases latency, but also decreases the likelihood of frame drops.

The capture processing loop should be coded to transfer a frame whenever a frame is ready to be transferred, and should wait a frame if not. The capture Demonstration Applications provide good examples of how to do this, for example (generally):

AUTOCIRCULATE_TRANSFER inputXfer; // AutoCirculate input transfer info
mDevice.AutoCirculateInitForInput (NTV2_CHANNEL1, /* numFrames */ 10, NTV2_AUDIOSYSTEM_1);
mDevice.AutoCirculateStart (NTV2_CHANNEL1);
// Ingest frames til Quit signaled...
while (!mGlobalQuit)
{
mDevice.AutoCirculateGetStatus (NTV2_CHANNEL1, acStatus);
if (acStatus.IsRunning() && acStatus.HasAvailableInputFrame())
{
// At this point, there's at least one fully-formed frame available in the device's
// frame buffer to transfer to the host. Reserve an NTV2FrameData to "produce", and
// use it in the next transfer from the device...
NTV2FrameData * pFrameData (mAVCircularBuffer.StartProduceNextBuffer());
NTV2FrameData & frameData (*pFrameData);
inputXfer.SetVideoBuffer (frameData.VideoBuffer(), frameData.VideoBufferSize());
inputXfer.SetAudioBuffer (frameData.AudioBuffer(), frameData.AudioBufferSize());
inputXfer.SetAncBuffers (frameData.AncBuffer(), frameData.AncBufferSize(),
frameData.AncBuffer2(), frameData.AncBuffer2Size());
// Transfer video/audio/anc from the device into our host buffers...
mDevice.AutoCirculateTransfer (NTV2_CHANNEL1, inputXfer);
// Remember the actual amount of audio captured...
if (acStatus.WithAudio())
frameData.fNumAudioBytes = inputXfer.GetCapturedAudioByteCount();
if (acStatus.WithCustomAnc() && frameData.AncBuffer())
frameData.fNumAncBytes = inputXfer.GetCapturedAncByteCount(/*isF2*/false);
if (acStatus.WithCustomAnc() && frameData.AncBuffer2())
frameData.fNumAnc2Bytes = inputXfer.GetCapturedAncByteCount(/*isF2*/true);
// Signal that we're done "producing" the frame, making it available for future "consumption"...
mAVCircularBuffer.EndProduceNextBuffer();
} // if A/C running and frame(s) are available for transfer
else
mDevice.WaitForInputVerticalInterrupt (NTV2_CHANNEL1); // Wait for a frame to become available
} // loop til quit signaled
// Stop AutoCirculate...
mDevice.AutoCirculateStop (NTV2_CHANNEL1);

The number of buffers waiting to be transferred from the board is available from AUTOCIRCULATE_TRANSFER_STATUS::acBufferLevel.

If the application is held off for longer than the number of frames allocated, one or more captured frames will be lost (dropped).

AutoCirculate capture demos:

AutoCirculate Playout

Here, AutoCirculate is in playout mode, using 10 frame buffers. Frames 6, 7, 8, 9 and 0 already played through the output jack (in that order), while frame 1 is currently being played, while frame 5 is being transferred from host memory to the AJA device.

In playout, the AJA device firmware continually streams the video content of the Active Frame buffer to the output jack.

When AutoCirculate is running, frames get transferred (DMA’d) from host memory to the Transfer Frame of the AJA device’s frame memory.

The Active Frame “chases” the Transfer Frame, with the frame gap between them called the Buffer Level.

To prevent repeated images, the host application must ensure that the Transfer Frame never collides with the Active Frame being played.

Assuming a 29.97 fps full-frame rate, the AJA driver will bump the Active Frame to the next frame slot every 33 milliseconds. As long as the host application that’s transferring frames takes less than 33 milliseconds (including the DMA transfer time) to produce each frame, all will be well. If the host takes longer than 33 milliseconds to produce a frame, the Transfer Frame will start to fall behind, and the Buffer Level will decrease. If this is allowed to continue, the Active Frame will overtake the Transfer Frame, which will result in “dropped” frames that will end up being played more than once.

The Per-Frame “Time Budget” discussed in the AutoCirculate Capture section applies equally for playout.

AutoCirculate assumes that the video and audio being transferred via CNTV2Card::AutoCirculateTransfer should be played together in-sync. It continuously monitors the sync, and if it detects a difference of more than about 10 milliseconds, it will resync the audio to the video. This resync involves restarting the audio engine, so a click or pop may be heard when it happens. The resync usually only happens when frames are dropped, during which the audio will be disabled until newly-transferred data arrives. (See Audio Playout for more information.)

During a very long playback (occurring over many hours), if too many or too few samples are transferred, the sync may drift, which may require a correction. A classic example of this would be playing a sequence of MP4 videos that have no notion of, say, the NTSC 5-frame cadence sequence. It can also easily happen when loop-playing a very short clip. One way to handle this is to track the number of video frames and audio samples delivered to AutoCirculate over the long term, then add or drop samples in the breaks between clips. Remember to reset the tracked frame and sample counts whenever the AUTOCIRCULATE_STATUS::GetDroppedFrameCount or AUTOCIRCULATE_TRANSFER_STATUS::acFramesDropped value changes (increases). See Correlating Audio Samples to Video Frames for more information.

(See Timecode (RP-188, SMPTE-12M) for more information about timecode playout and AutoCirculate.)

AutoCirculate playout demos:

AutoCirculate Capture and Playout

Here, AutoCirculate is simultaneously capturing from a device input and playing through a device output, while still using 10 frame buffers in all.

For this to work, two independent “channels” must be used, each with its own reserved range of frame buffers on the device, each having its own Active Frame, Transfer Frame and Buffer Level measuring the gap, if any, between them.

The client application would typically use two execution threads for performing the DMA transfers — one for capture, the other for playout.

Note
It’s possible to have other Frame Stores writing into (or reading from) device frame buffer memory being used by an AutoCirculate channel, its corresponding Frame Store, and the frame buffers being used. This can wreak havoc with the quality of the video being streamed. See the When FrameStores Access the Same Frame Buffer Memory discussion for more details.
It’s also possible to miscalculate the device frame buffer range being used for AutoCirculate such that the last frame or two encroach on the audio buffers. On capture, this can result in sporadically bad video frames and/or noise in the captured audio. On playout, this can cause sporadically bad video frames to be transmitted, and/or noise in the transmitted audio. See Audio Buffer Corruption for more information.

AutoCirculate Capture/Playout Demos:

AutoCirculate API Functions

There are five principal member functions that comprise the AutoCirculate API in the CNTV2Card class:

In addition, there are several special-purpose methods that are available for more specialized applications, including:

Recommended Program Flow

This illustrates the recommended program flow for using AutoCirculate to capture video and audio. For a GUI application, the “Main” flow of execution on the left would handle the user interface implementation. The “Wait for Quit Request” step would respond to user inputs and display capture/playout status. For a command-line utility, the “Wait for Quit Request” box would implement a loop that sleeps, waiting for a global “quit” flag to become logically “true” (and perhaps periodically emit some status information to the standard output stream).

Once the device has been acquired and configured, the main thread then creates and starts the capture thread.

The program flow surrounded by the dashed line is the capture thread. When it starts, CNTV2Card::AutoCirculateInitForInput is called to set up the AutoCirculate parameters for a specific NTV2Channel, which allocates a contiguous block of frame buffers on the card to be used by the AutoCirculate mechanism. At this point, it is started by calling CNTV2Card::AutoCirculateStart. Once started, it remains in a loop, calling CNTV2Card::AutoCirculateGetStatus to determine if AutoCirculate is in the “running” state and if at least one frame is ready to transfer. If so, AutoCirculateTransfer is called to transfer the captured frame to host memory; otherwise the thread sleeps in CNTV2Card::WaitForInputVerticalInterrupt until the next VBI occurs. This process continues until a global quit flag is set, at which point the thread calls CNTV2Card::AutoCirculateStop and exits.

After CNTV2Card::AutoCirculateStart is called, the AJA device’s Active Frame will automatically change at every VBI to cycle continuously from the starting frame to the ending frame and back again until CNTV2Card::AutoCirculateStop is called. CNTV2Card::AutoCirculateTransfer is called repeatedly to transfer a buffered video frame (plus any associated audio, timecode, Ancillary Data, etc.) between the driver and the application. The Active Frame, buffer level, etc. are advanced automatically by the AJA device driver.

CNTV2Card::AutoCirculateGetStatus is used to determine whether a given channel is currently AutoCirculating, and if so, to report its current buffer level. It also supplies other data, such as its frame range (starting and ending frames) and its Active Frame.

Because AutoCirculate is wholly implemented in the driver, and is completely independent of any CNTV2Card instance that started it or that could be monitoring or controlling it, there is no provision to automatically stop AutoCirculating when any/all CNTV2Card instances have been destroyed. The driver will continue to AutoCirculate, blissfully unaware that nobody is monitoring the activity. OEMs are encouraged to be good citizens and call CNTV2Card::AutoCirculateStop at exit to reduce unnecessary driver activity.

AutoCirculate Channel

The NTV2Channel passed to CNTV2Card::AutoCirculateInitForInput (or CNTV2Card::AutoCirculateInitForOutput) identifies the device FrameStore Operation that is to be configured and operated by AutoCirculate in the device driver (i.e. NTV2_CHANNEL1 == 0 == FrameStore 1 == NTV2_WgtFrameBuffer1, NTV2_CHANNEL2 == 1 == FrameStore 2 == NTV2_WgtFrameBuffer2, etc.).

AutoCirculate is driven by vertical blanking interrupts (VBIs) received by the channel’s FrameStore Operation. If these interrupts aren’t received by the hardware, the driver’s ISR won’t get called, and AutoCirculate (for that channel) will be stuck.

To obtain the size of your host-based video buffer, in bytes (to accommodate a single frame), try…

To determine the maximum number of frame buffers a given device can accommodate for a given frame geometry and buffer format, call NTV2DeviceGetNumberFrameBuffers.

Pre-Loading Frames For Playback

When AutoCirculate starts in playout mode (without yet transferring frames), the device firmware immediately starts playing the contents of the Active Frame to the output jack, displaying whatever YCbCr/RGB data was in the device’s frame buffer memory.

If CNTV2Card::AutoCirculateTransfer has not been called, the Active Frame and Transfer Frame remain stuck at frame zero, the Buffer Level remains at zero, and the Frames Dropped tally increments at the current frame rate.

To prevent displaying unpredictable frame(s) at playout startup (and to prevent frame drops caused by this initial frame starvation), it’s best to “preload” one or more frames before calling CNTV2Card::AutoCirculateStart.

To do this, call CNTV2Card::AutoCirculateTransfer for each frame you wish to preload into the device frame buffer. After each such call, the Transfer Frame will “bump” to the next frame slot, and the Buffer Level will increment. After preloading, you can safely call CNTV2Card::AutoCirculateStart, and continue to transfer additional frames to the device, with the goal of keeping the Transfer Frame ahead of the Active Frame being played by the hardware.

Interlaced Versus Progressive Video

In capture mode, with a progressive video signal, immediately after the input VBI, the last-written video frame in the device’s frame buffer is guaranteed to be fully-composed. With interlaced video, this is only true after every other VBI. The following code snippet allows this phenomenon to be visualized:

. . .
AUTOCIRCULATE_TRANSFER xferInfo;
while (true)
{
mDevice.AutoCirculateGetStatus (NTV2_CHANNEL1, status);
if (status.IsRunning())
{
if (status.HasAvailableInputFrame())
{
cout << '1';
mDevice.AutoCirculateTransfer (NTV2_CHANNEL1, xferInfo);
}
else
cout << '0';
} // if A/C running
mDevice.WaitForInputVerticalInterrupt (NTV2_CHANNEL1);
} // loop
. . .

With interlaced video, the standard output stream will contain a ...010101010101... pattern, whereas progressive video results in a ...111111111111... pattern.

When AutoCirculating interlaced video, the driver will not “bump” the Active Frame until it has been completely composed (i.e., until immediately after the “Field 1” VBI occurs).

It is possible (and sometimes even desireable) to transfer each field of interlaced video separately, which can be done by calling CNTV2Card::AutoCirculateTransfer every time through the loop (without checking the Buffer Level). See the NTV2FieldBurn demonstration application for more details.

Field-Based Operation

Historically, AutoCirculate was always frame-based, but many customers requested the ability to operate in Field Mode. Field Mode was added in SDK 15.2.

Latency Considerations

AutoCirculate’s kernel queuing model doesn’t support low-latency very well. It’s very good at reliably capturing and playing frames without dropping, as long as the frame queue is large enough to absorb user-mode latency. The kernel queue is managed once per frame just after the video VBI. This gives the client software an entire frame-time to program the hardware for the next frame.

For capture, the frame written to the device frame buffer during the previous frame time is available for transfer after the vertical interrupt is received. However, audio can’t be transferred immediately, since audio is captured continuously, and all audio for the previous frame may not have been flushed to the device frame buffer yet. For this reason, AJA usually recommends transferring video and audio when there’s at least two frames in the queue — which may be unacceptable for low latency applications.

For playback, when the frame interrupt is received, the frame to display after the next VBI must be set in the hardware. Since this is a whole frame early, you essentially end up with two frames in the queue for playback as well. This is why we wrote the NTV2LLBurn Demo, a low-latency demo that works without AutoCirculate.

How many frames to circulate? This choice can depend on a number of factors that each affect how many frames are available for buffering on the device:

  • The application’s frame-dropping tolerance;
  • The application’s latency requirement (always at odds with frame-dropping tolerance);
  • The hardware devices it may need to run on (some devices have smaller amounts of SDRAM);
  • The largest video raster expected;
  • The frame buffer (pixel) format to be used. See Frame Buffer Indexing for more information.
Note
Modern NTV2 devices have a large enough SDRAM complement such that it’s possible to buffer several seconds of video frames on the device, which can readily exceed the maximum 1.37 seconds of audio that’s typically buffered on the device. When CNTV2Card::AutoCirculateInitForInput or CNTV2Card::AutoCirculateInitForOutput are called, and the requested number of video frames to buffer exceeds the maximum frames buffered for audio, a warning message will be logged in “AJA Logger” or the ‘logreader’ Command-Line Utility (assuming the AutoCirculate_39 message group is enabled). For example:
AutoCirculate channel 3: 85 frames (10 thru 94) exceeds 40-frame max audio buffer capacity

Monitoring AutoCirculate Activity with NTV2Watcher Tool

“NTV2Watcher” has an AutoCirculate Inspector that shows AutoCirculate activity in near-real-time for all possible channels on any AJA device attached to the host.

You can right-click in the AutoCirculate Channel column to pop up a menu to control AutoCirculate activity on that channel. This is handy for manually pausing, resuming, stopping or restarting AutoCirculate while your application runs.

While AutoCirculate is paused, you can inspect, in great detail…

AutoCirculate Diagnostic Messages

While developing and debugging with AutoCirculate, it can be helpful to monitor its diagnostic messages, particularly when the channel is initialized via CNTV2Card::AutoCirculateInitForInput or CNTV2Card::AutoCirculateInitForOutput. These messages can be seen in “AJA Logger” or ‘logreader’ Command-Line Utility when the AutoCirculate_39 message group is enabled, and the client application has opened the AJADebug facility by calling AJADebug::Open (usually in main()).

  • Information Messages
    These messages are informational, and do not indicate problems of any kind.
     
    • {mode} {channel} initialized using frames {range}
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
        range: Indicates the AutoCirculate frame range (two unsigned decimal integers separated by a hyphen).
      • Example: Input Ch3 initialized using frames 0-6
      • Meaning: AutoCirculate streaming in the given direction has been initialized for the given NTV2Channel and is ready to be started with a subsequent call to CNTV2Card::AutoCirculateStart.
         
  • Warning Messages
    These messages are warnings. AutoCirculate will operate, but there may be problems.
     
    • {mode} {channel}: FrameCount {count} ignored – using start/end {range} frame numbers
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
        count: Indicates the FrameCount parameter (an unsigned decimal integer value).
        range: Indicates the AutoCirculate frame range (two unsigned decimal integers separated by a forward-slash ‘/’).
      • Example: Output Ch2: FrameCount 20 ignored – using start/end 12/45 frame numbers
      • Problem: CNTV2Card::AutoCirculateInitForInput or CNTV2Card::AutoCirculateInitForOutput was called with both a non-zero FrameCount parameter and valid StartFrame & EndFrame values.
      • Solution: Set the FrameCount parameter to zero when specifying valid StartFrame & EndFrame values; or specify zero for both StartFrame & EndFrame with a non-zero FrameCount value.
         
    • {mode} {channel}: MultiLink Audio requested, but device doesn't support it
    • {mode} {channel}: memory overlap/interference: Frms {range}: {activities}
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
        activities: One or more activities that touch device memory, each indicating the firmware entity and mode:
        • firmware entity:
          • AC indicates an active AutoCirculate Channel
          • Ch indicates an enabled FrameStore
          • Aud indicates a running NTV2AudioSystem
        • mode:
          • Read indicates the memory is being read;
          • Write indicates the memory is being written.
      • Example: Input Ch3: memory overlap/interference: Frms 5-6: AC3 Write, AC2 Read
      • Problem: One or more of the frames being used for the AutoCirculate Channel are also being used for other purposes.
      • Solution: Be sure to choose a frame range that won’t interfere with other activity on the device. See When FrameStores Access the Same Frame Buffer Memory and Audio Buffer Corruption for more information.
         
    • {mode} {channel}: {count} frames ({range}) exceeds {maxCount}-frame max buffer capacity of audioSystem
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
        count: Indicates the FrameCount parameter (an unsigned decimal integer value).
        range: Indicates the AutoCirculate frame range (two unsigned decimal integers separated by a forward-slash ‘/’).
        maxCount: Indicates the maximum number of frames the audio system can buffer.
        audioSystem: Indicates the NTV2AudioSystem being used – AudSys1AudSys8.
      • Example: Input Ch3: 51 frames (0-50) exceeds 41-frame max audio buffer capacity
      • Problem: A valid NTV2AudioSystem was specified, and based on the number of audio channels the NTV2AudioSystem is currently configured for, and given the NTV2FrameRate for the Channel/FrameStore, the number of video frames reserved for AutoCirculate exceeds the maximum number of frames of audio that the NTV2AudioSystem can buffer. This will likely cause corrupted and/or missing audio.
      • Solution: Reduce the number of frames being used for this AutoCirculate Channel.
         
    • {mode} {channel} has AUTOCIRCULATE_WITH_ANC set, but also has NTV2_VANCMODE_TALL set – this may cause anc insertion problems
    • {mode} {channel}: AUTOCIRCULATE_WITH_RP188 requested without AUTOCIRCULATE_WITH_ANC – enabled AUTOCIRCULATE_WITH_ANC anyway
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
      • Example: Output Ch2: AUTOCIRCULATE_WITH_RP188 requested without AUTOCIRCULATE_WITH_ANC – enabled AUTOCIRCULATE_WITH_ANC anyway
      • Problem: CNTV2Card::AutoCirculateInitForOutput was called for a KONA IP or Io IP device with SMPTE ST-2110 firmware with the AUTOCIRCULATE_WITH_RP188 option, but without the AUTOCIRCULATE_WITH_ANC option. Without the SMPTE ST-2110 ancillary data stream, RP188 timecode won’t be transmitted.
      • Solution: To include RP188 timecode in the outgoing SMPTE ST-2110 ancillary data stream, be sure to specify both AUTOCIRCULATE_WITH_ANC and AUTOCIRCULATE_WITH_RP188.
         
  • Error Messages
    These messages indicate failure. AutoCirculate could not be initialized.
     
    • {channel} is illegal channel value
      • …where…
        channel: Indicates the offending NTV2Channel value. Note that the actual zero-based index number of the channel will be one less than the indicated “Ch” decimal value.
      • Example: Ch9 is illegal channel value
      • Problem: An invalid NTV2Channel value was used.
      • Solution: Specify a valid NTV2Channel value (NTV2_CHANNEL1 thru NTV2_CHANNEL8).
         
    • {mode} {channel}: illegal 'inNumChannels' value '{count}' – must be 1-8
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
        count: Indicates the offending inNumChannels parameter – an unsigned decimal integer value.
      • Example: Output Ch2: illegal 'inNumChannels' value '9' – must be 1-8
      • Problem: The number of ganged channels must be at least 1, and no more than 8.
      • Solution: Specify a channel count value in the range 1 thru 8.
         
    • {mode} {channel}: FBAllocLock mutex not ready
    • {mode} {channel}: Zero frames requested
    • {mode} {channel}: EndFrame ({endFrame}) precedes StartFrame ({startFrame})
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
      • Example: Input Ch3: EndFrame(0) precedes StartFrame(6)
      • Problem: A Start/End Frame range was specified in the call to CNTV2Card::AutoCirculateInitForInput or CNTV2Card::AutoCirculateInitForOutput, but the Start frame number’s magnitude exceeded the End frame number’s magnitude.
      • Solution: When specifying Start/End frame values, be sure the Start frame value ordinally precedes the End frame value.
         
    • {mode} {channel}: Frames {range} < 2 frames
      • …where…
        mode: Indicates the NTV2Mode (Input or Output).
        channel: Indicates the NTV2Channel (Ch1Ch8).
        range: Indicates the AutoCirculate frame range (two unsigned decimal integers separated by a hyphen ‘-’).
      • Example: Input Ch3: Frames 1-1 < 2 frames
      • Problem: A Start/End Frame range was specified, each with the same value, making a single-frame AutoCirculate range.
      • Solution: When specifying Start/End frame values, be sure the range encompasses 2 or more frames in length.
         
    • {mode} {channel} initialization failed
AUTOCIRCULATE_TRANSFER::GetCapturedAudioByteCount
ULWord GetCapturedAudioByteCount(void) const
Definition: ntv2publicinterface.h:8270
NTV2FrameData
I encapsulate the video, audio and anc host buffers used in the AutoCirculate demos....
Definition: ntv2democommon.h:79
AUTOCIRCULATE_TRANSFER::SetAudioBuffer
bool SetAudioBuffer(ULWord *pInAudioBuffer, const ULWord inAudioByteCount)
Sets my audio buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2614
NTV2_AUDIOSYSTEM_1
@ NTV2_AUDIOSYSTEM_1
This identifies the first Audio System.
Definition: ntv2enums.h:3811
AUTOCIRCULATE_TRANSFER::SetAncBuffers
bool SetAncBuffers(ULWord *pInANCBuffer, const ULWord inANCByteCount, ULWord *pInANCF2Buffer=NULL, const ULWord inANCF2ByteCount=0)
Sets my ancillary data buffers for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2622
NTV2_CHANNEL1
@ NTV2_CHANNEL1
Specifies channel or Frame Store 1 (or the first item).
Definition: ntv2enums.h:1307
AUTOCIRCULATE_STATUS::WithAudio
bool WithAudio(void) const
Definition: ntv2publicinterface.h:7236
AUTOCIRCULATE_STATUS
This is returned from the CNTV2Card::AutoCirculateGetStatus function.
Definition: ntv2publicinterface.h:7105
AUTOCIRCULATE_TRANSFER::GetCapturedAncByteCount
ULWord GetCapturedAncByteCount(const bool inField2=false) const
Definition: ntv2publicinterface.h:8280
AUTOCIRCULATE_TRANSFER
This object specifies the information that will be transferred to or from the AJA device in the CNTV2...
Definition: ntv2publicinterface.h:7904
AUTOCIRCULATE_TRANSFER::SetVideoBuffer
bool SetVideoBuffer(ULWord *pInVideoBuffer, const ULWord inVideoByteCount)
Sets my video buffer for use in a subsequent call to CNTV2Card::AutoCirculateTransfer.
Definition: ntv2publicinterface.cpp:2606
AUTOCIRCULATE_STATUS::IsRunning
bool IsRunning(void) const
Definition: ntv2publicinterface.h:7211
AUTOCIRCULATE_STATUS::HasAvailableInputFrame
bool HasAvailableInputFrame(void) const
Definition: ntv2publicinterface.h:7181
AUTOCIRCULATE_STATUS::WithCustomAnc
bool WithCustomAnc(void) const
Definition: ntv2publicinterface.h:7246