### NTV2Capture8K setup and thread methods Source: https://sdkdocs.aja.com/public/ntv2/current/dc/d6a/ntv2capture8k_8cpp_source.html These are the core methods of the NTV2Capture8K class that set up and run the 8K capture pipeline. SetupAudio configures the audio system based on the input channel in multiformat mode. SetupHostBuffers allocates and page-locks video, audio, and ancillary buffers for the circular buffer. RouteInputSignal applies the 8K input routing. Run starts the consumer and producer threads. StartConsumerThread and StartProducerThread create and start the respective threads. ConsumerThreadStatic is the static thread entry that calls ConsumeFrames. ConsumeFrames waits for frames, processes them (placeholder), and releases them. StartProducerThread is the producer thread start. ```cpp return AJA_STATUS_SUCCESS; } // SetupVideo ``` ```cpp AJAStatus NTV2Capture8K::SetupAudio (void) { // In multiformat mode, base the audio system on the channel... if (mConfig.fDoMultiFormat) if (mDevice.features().GetNumAudioSystems() > 1) if (UWord(mConfig.fInputChannel) < mDevice.features().GetNumAudioSystems()) mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fInputChannel); NTV2AudioSystemSet audSystems (::NTV2MakeAudioSystemSet (mAudioSystem, 1)); CNTV2DemoCommon::ConfigureAudioSystems (mDevice, mConfig, audSystems); return AJA_STATUS_SUCCESS; } // SetupAudio ``` ```cpp void NTV2Capture8K::SetupHostBuffers (void) { // Let my circular buffer know when it's time to quit... mAVCircularBuffer.SetAbortFlag(&mGlobalQuit); ULWord F1AncSize(0), F2AncSize(0); if (mConfig.fWithAnc) { // Use the max anc size stipulated by the AncFieldOffset VReg values... ULWord F1OffsetFromEnd(0), F2OffsetFromEnd(0); mDevice.ReadRegister(kVRegAncField1Offset, F1OffsetFromEnd); // # bytes from end of 8MB/16MB frame mDevice.ReadRegister(kVRegAncField2Offset, F2OffsetFromEnd); // # bytes from end of 8MB/16MB frame // Based on the offsets, calculate the max anc capacity F1AncSize = F2OffsetFromEnd > F1OffsetFromEnd ? 0 : F1OffsetFromEnd - F2OffsetFromEnd; F2AncSize = F2OffsetFromEnd > F1OffsetFromEnd ? F2OffsetFromEnd - F1OffsetFromEnd : F2OffsetFromEnd; } // Allocate and add each in-host NTV2FrameData to my circular buffer member variable... const size_t audioBufferSize (NTV2_AUDIOSIZE_MAX); mHostBuffers.reserve(size_t(CIRCULAR_BUFFER_SIZE)); cout << "## NOTE: Buffer size: vid=" << mFormatDesc.GetVideoWriteSize() << " aud=" << audioBufferSize << " anc=" << F1AncSize << endl; while (mHostBuffers.size() < size_t(CIRCULAR_BUFFER_SIZE)) { mHostBuffers.push_back(NTV2FrameData()); NTV2FrameData & frameData(mHostBuffers.back()); frameData.fVideoBuffer.Allocate(mFormatDesc.GetVideoWriteSize()); frameData.fAudioBuffer.Allocate(NTV2_IS_VALID_AUDIO_SYSTEM(mAudioSystem) ? audioBufferSize : 0); frameData.fAncBuffer.Allocate(F1AncSize); frameData.fAncBuffer2.Allocate(F2AncSize); mAVCircularBuffer.Add(&frameData); // 8K requires page-locked buffers if (frameData.fVideoBuffer) mDevice.DMABufferLock(frameData.fVideoBuffer, true); if (frameData.fAudioBuffer) mDevice.DMABufferLock(frameData.fAudioBuffer, true); if (frameData.fAncBuffer) mDevice.DMABufferLock(frameData.fAncBuffer, true); } // for each NTV2FrameData } // SetupHostBuffers ``` ```cpp bool NTV2Capture8K::RouteInputSignal (void) { NTV2XptConnections connections; return CNTV2DemoCommon::GetInputRouting8K (connections, mConfig, mVideoFormat) && mDevice.ApplySignalRoute(connections, !mConfig.fDoMultiFormat); } // RouteInputSignal ``` ```cpp AJAStatus NTV2Capture8K::Run (void) { // Start the playout and capture threads... StartConsumerThread(); StartProducerThread(); return AJA_STATUS_SUCCESS; } // Run ``` ```cpp void NTV2Capture8K::StartConsumerThread (void) { // Create and start the consumer thread... mConsumerThread.Attach(ConsumerThreadStatic, this); mConsumerThread.SetPriority(AJA_ThreadPriority_High); mConsumerThread.Start(); } // StartConsumerThread ``` ```cpp void NTV2Capture8K::ConsumerThreadStatic (AJAThread * pThread, void * pContext) // static { (void) pThread; // Grab the NTV2Capture instance pointer from the pContext parameter, // then call its ConsumeFrames method... NTV2Capture8K * pApp (reinterpret_cast(pContext)); pApp->ConsumeFrames(); } // ConsumerThreadStatic ``` ```cpp void NTV2Capture8K::ConsumeFrames (void) { CAPNOTE("Thread started"); while (!mGlobalQuit) { // Wait for the next frame to become ready to "consume"... NTV2FrameData * pFrameData(mAVCircularBuffer.StartConsumeNextBuffer()); if (pFrameData) { // Do something useful with the frame data... // . . . . . . . . . . . . // . . . . . . . . . . . . // . . . . . . . . . . . . // Now release and recycle the buffer... mAVCircularBuffer.EndConsumeNextBuffer(); } // if pFrameData } // loop til quit signaled CAPNOTE("Thread completed, will exit"); } // ConsumeFrames ``` ```cpp void NTV2Capture8K::StartProducerThread (void) { // Create and start the capture thread... mProducerThread.Attach(ProducerThreadStatic, this); mProducerThread.SetPriority(AJA_ThreadPriority_High); mProducerThread.Start(); } // StartProducerThread ``` -------------------------------- ### Main function with command-line option setup Source: https://sdkdocs.aja.com/public/ntv2/current/d3/dbe/ntv2ccgrabber_2main_8cpp_source.html Initializes variables, sets locale, installs plug-and-play callback, and defines the command-line option table for the ntv2ccgrabber application. ```cpp int main (int argc, const char ** argv) { const string legalChannels (NTV2CCGrabber::GetLine21ChannelNames("|")); const string legal608Sources (CCGrabberConfig::CaptionDataSrcToString(kCaptionDataSrc_INVALID)); const string legalOutputModes(CCGrabberConfig::OutputModeToString(kOutputMode_INVALID)); const string legalFramesSpec ("{frameCount}[@{firstFrameNum}] or {firstFrameNum}-{lastFrameNum}"); char * pDeviceSpec (AJA_NULL); // Device spec char * pInputSrcSpec (AJA_NULL); // SDI source spec char * pTcSource (AJA_NULL); // Timecode source spec char * pPixelFormat (AJA_NULL); // Pixel format spec char * pCaptionChannel (AJA_NULL); // Caption channel of interest (cc1, cc2 ... text1, text2, ...) char * pCaptionSource (AJA_NULL); // Caption source of interest (line21, 608vanc, 608anc ...) char * pOutputMode (AJA_NULL); // Output mode (stream, screen, file ...) char * pFramesSpec (AJA_NULL); // AutoCirculate frames spec int channelNumber (1); // Channel (framestore) spec int burnCaptions (0); // Burn-in captions? int doMultiFormat (0); // MultiFormat mode? int useVanc (0); // Use Vanc (tall frame) geometry? int grabAudio (0); // Grab audio? int showVersion (0); // Show version? AJADebug::Open(); ::setlocale (LC_ALL, ""); // Might have to emit UTF-8 Unicode gPlugAndPlay.Install (PnpCallback, 0, AJA_Pnp_PciVideoDevices); // Command line option descriptions: const CNTV2DemoCommon::PoptOpts optionsTable [] = { {"version", 0, POPT_ARG_NONE, &showVersion, 0, "show version & exit", AJA_NULL }, {"device", 'd', POPT_ARG_STRING, &pDeviceSpec, 0, "device to use", "index#, serial#, or model" }, {"channel", 'c', POPT_ARG_INT, &channelNumber, 0, "channel to use", "1-8" }, {"multiFormat", 'm', POPT_ARG_NONE, &doMultiFormat, 0, "use multi-format/channel", AJA_NULL } }; ``` -------------------------------- ### SetupInputVideo: enable input interrupt for NTV2Burn4KQuadrant Source: https://sdkdocs.aja.com/public/ntv2/current/d0/dc9/ntv2burn4kquadrant_8cpp_source.html Starts the SetupInputVideo method for the 4K quadrant example. It enables the input interrupt for the configured input channel; the surrounding comments explain that the video format is matched to the incoming signal and that the reference source is locked to one input assuming all quadrants are timed. ```cpp AJAStatus NTV2Burn4KQuadrant::SetupInputVideo (void) { // Set the video format to match the incoming video format. // Does the device support the desired input source? // Since this is a 4k Quadrant example, look at one of the inputs and deduce the 4k geometry from the quadrant geometry... // Determine the input video signal format, and set the device's reference source to that input. // If you want to look at one of the quadrants, say on the HDMI output, then lock to one of the // inputs (this assumes all quadrants are timed)... // First, enable all of the necessary interrupts, and subscribe to the interrupts for the channel to be used... mInputDevice.EnableInputInterrupt (mConfig.fInputChannel); ``` -------------------------------- ### StartPlayThread and PlayFrames: Playout thread setup and loop Source: https://sdkdocs.aja.com/public/ntv2/current/d9/dca/ntv2ccgrabber_8cpp_source.html Starts the playout thread and runs the playout loop. StartPlayThread asserts mConfig.fBurnCaptions, attaches PlayThreadStatic, sets high priority, and starts the thread. PlayThreadStatic casts the context to NTV2CCGrabber and calls PlayFrames. PlayFrames sets up output video and routing, initializes auto-circulate, allocates a host buffer for caption burn-in (failing with a note if allocation fails), clears ping/pong buffers, and enters a loop waiting for frames to consume. ```cpp AJAStatus NTV2CCGrabber::StartPlayThread (void) { // Create and start the playout thread... NTV2_ASSERT(mConfig.fBurnCaptions); AJAStatus result (mPlayoutThread.Attach(PlayThreadStatic, this)); if (AJA_SUCCESS(result)) result = mPlayoutThread.SetPriority(AJA_ThreadPriority_High); if (AJA_SUCCESS(result)) result = mPlayoutThread.Start(); return result; } // StartPlayThread ``` ```cpp void NTV2CCGrabber::PlayThreadStatic (AJAThread * pThread, void * pContext) // static { (void) pThread; // Grab the NTV2Burn instance pointer from the pContext parameter, // then call its PlayFrames method... NTV2CCGrabber * pApp (reinterpret_cast (pContext)); pApp->PlayFrames (); } // PlayThreadStatic ``` ```cpp void NTV2CCGrabber::PlayFrames (void) { const NTV2VideoFormat videoFormat (mDevice.GetInputVideoFormat(mConfig.fInputSource)); NTV2VANCMode vancMode (NTV2_VANCMODE_INVALID); ULWord fbNum (10); // Bounce between frames 10 & 11 const string indicators [] = {"/", "-", "\\", "|", ""}; AUTOCIRCULATE_STATUS acStatus; CAPNOTE("Thread started"); SetupOutputVideo (videoFormat); // Set up device output RouteOutputSignal (videoFormat); // Set up output signal routing mDevice.GetVANCMode (vancMode, mConfig.fInputChannel); if (mDevice.AutoCirculateInitForOutput (mOutputChannel, 2) && mDevice.AutoCirculateGetStatus (mOutputChannel, acStatus)) // Find out which buffers we got fbNum = ULWord(acStatus.acStartFrame); // Use them else if (mDevice.AutoCirculateGetStatus(mConfig.fInputChannel, acStatus)) // Use the frame just past the last input A/C frame fbNum = ULWord(acStatus.GetEndFrame()) + 1; const NTV2FormatDesc formatDesc (videoFormat, mPlayoutFBF, vancMode); const uint32_t bufferSizeBytes (formatDesc.GetTotalRasterBytes ()); const uint32_t activeSizeBytes (formatDesc.GetVisibleRasterBytes ()); ULWord pingPong (0); // Bounce between 0 and 1 UWord consecSyncErrs (0); // Caption status head-up-display... static uint64_t frameTally (0); const string strVideoFormat (CNTV2DemoCommon::StripFormatString (::NTV2VideoFormatToString (videoFormat))); ULWord lastErrorTally (0); // Allocate host frame buffer for blitting captions into... NTV2Buffer hostBuffer; if (!hostBuffer.Allocate(bufferSizeBytes, /*pageAligned*/true)) {cerr << "## NOTE: Caption burn-in failed -- unable to allocate " << bufferSizeBytes << "-byte caption video buffer" << endl; return;} NTV2Buffer visibleRgn (formatDesc.GetTopVisibleRowAddress(AsUBytePtr(hostBuffer.GetHostPointer())),activeSizeBytes); // Clear both device ping/pong buffers to fully transparent, all black... hostBuffer.Fill(ULWord(0)); mDevice.DMAWriteFrame (fbNum + 0, AsULWordPtr(hostBuffer.GetHostPointer()), bufferSizeBytes); mDevice.DMAWriteFrame (fbNum + 1, AsULWordPtr(hostBuffer.GetHostPointer()), bufferSizeBytes); mDevice.SetOutputFrame (mOutputChannel, fbNum + pingPong); pingPong = pingPong ? 0 : 1; // Do forever (until Quit)... while (!mGlobalQuit) { // Wait for the next frame to become ready to "consume"... NTV2FrameData * pFrameData(mCircularBuffer.StartConsumeNextBuffer()); ``` -------------------------------- ### main.cpp: Kona IP JSON setup command-line entry point Source: https://sdkdocs.aja.com/public/ntv2/current/d1/d61/ntv2konaipjsonsetup_2main_8cpp_source.html Entry point for the ntv2konaipjsonsetup demo. Parses command-line options -d/-b for device selection, -k to print supported JSON keywords, and expects exactly one positional JSON file argument. Opens the JSON with CKonaIpJsonSetup::openJson, prints "Failed to parse JSON" and exits -1 on parse failure, otherwise calls setupBoard with the device string. ```cpp /* SPDX-License-Identifier: MIT */ #include #include #include "konaipjsonsetup.h" #include "QDebug" #include "keywords.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QCommandLineParser parser; parser.setApplicationDescription("Kona IP Json Setup"); parser.addHelpOption(); parser.addVersionOption(); const QCommandLineOption deviceOption("d", "device to use", "device"); parser.addOption(deviceOption); const QCommandLineOption boardOption("b", "device to use", "board"); parser.addOption(boardOption); const QCommandLineOption keywordsOption("k", "list supported JSON keywords"); parser.addOption(keywordsOption); parser.addPositionalArgument("InputJsonFile", QCoreApplication::translate("main", "Json File to Open.")); parser.process(a); if (parser.isSet(keywordsOption)) { std::cout << keywordList.toStdString() << std::endl; exit(0); } QString device = "0"; if (parser.isSet(deviceOption)) { device = parser.value(deviceOption); } if (parser.isSet(boardOption)) { device = parser.value(boardOption); } std::string devStr = device.toUtf8().constData(); const QStringList args = parser.positionalArguments(); if ( args.size() == 1 ) { qDebug() << args.at(0); CKonaIpJsonSetup jsonSetup; bool rv = jsonSetup.openJson(args.at(0)); if (!rv) { std::cout << "Failed to parse JSON" << std::endl; exit (-1); } jsonSetup.setupBoard(devStr); } else { parser.showHelp(); exit (-2); } exit(0); } ``` -------------------------------- ### NTV2StreamPreview constructor: connect signals, start grabber, install PnP callback Source: https://sdkdocs.aja.com/public/ntv2/current/dc/dca/ntv2streampreview_8cpp_source.html Constructor of NTV2StreamPreview: connects the stream grabber's status signal to the video preview widget, sets an invalid input source, starts the grabber, starts a 100 ms timer, and installs a PnP callback for PCI video devices. ```cpp connect (mStreamGrabber, SIGNAL (newStatusString (const QString)), mVideoPreviewWidget, SLOT (updateStatusString (const QString))); ``` ```cpp mStreamGrabber->SetInputSource (NTV2_NUM_INPUTSOURCES); mStreamGrabber->start (); mTimerID = startTimer (100); ``` ```cpp mPnp.Install (PnpCallback, this, AJA_Pnp_PciVideoDevices); ``` -------------------------------- ### Get elapsed time since timer start Source: https://sdkdocs.aja.com/public/ntv2/current/dc/d33/ntv2mailbox_8cpp_source.html Returns the difference between the current system time and the recorded start time in milliseconds. ```cpp uint64_t CNTV2MailBox::getElapsedTime() { return (getSystemMilliseconds() - _startTime); } ``` -------------------------------- ### Setup board with device specification Source: https://sdkdocs.aja.com/public/ntv2/current/d2/d90/konaipj2ksetup_8cpp_source.html Opens the first device matching the given argument, waits for the system to become ready, and validates the board firmware. Returns false on errors. ```cpp bool CKonaIpEncoderSetup::setupBoard(std::string pDeviceSpec, KonaIPParamJ2KSetupStruct* pKonaIpJ2kParams) { CNTV2Card mDevice; CNTV2DeviceScanner::GetFirstDeviceFromArgument (pDeviceSpec, mDevice); if (!mDevice.IsOpen()) { std::cerr << "## ERROR: No devices found" << std::endl; return false; } //if (!mDevice.IsIPDevice()) //{std::cerr << "## ERROR: Not an IP device" << std::endl; return false;} // Wait for ready while (!mDevice.IsMBSystemReady()) { std::cout << "## NOTE: Waiting for device to become ready... (Ctrl-C will abort)" << std::endl; AJATime::Sleep(1000); if (mDevice.IsMBSystemReady ()) { std::cout << "## NOTE: Device is ready" << std::endl; } } if (!mDevice.IsMBSystemValid()) { std::cerr << "## ERROR: board firmware package is incompatible with this application" << std::endl; return false; } } ``` -------------------------------- ### SetUpHostBuffers() Source: https://sdkdocs.aja.com/public/ntv2/current/d8/d6d/class_n_t_v2_player4_k.html Sets up host video and audio buffers. ```APIDOC ## SetUpHostBuffers() ### Description Sets up my host video & audio buffers. ### Method SetUpHostBuffers ### Signature `AJAStatus NTV2Player4K::SetUpHostBuffers(void)` ### Parameters None ### Return Value AJAStatus - Status of the host buffer setup. ``` -------------------------------- ### AUTOCIRCULATE_STATUS::GetStartFrame Source: https://sdkdocs.aja.com/public/ntv2/current/d7/d6f/ntv2player_8cpp_source.html Gets the start frame of the AutoCirculate status. ```APIDOC ## AUTOCIRCULATE_STATUS::GetStartFrame ### Description Gets the start frame of the AutoCirculate status. ### Method uint16_t GetStartFrame(void) const ### Returns - **uint16_t** - The start frame number. ``` -------------------------------- ### SetUpAudio() Source: https://sdkdocs.aja.com/public/ntv2/current/d8/d6d/class_n_t_v2_player4_k.html Performs all audio setup for the player. ```APIDOC ## SetUpAudio() ### Description Performs all audio setup. ### Method SetUpAudio ### Signature `AJAStatus NTV2Player4K::SetUpAudio(void)` ### Parameters None ### Return Value AJAStatus - Status of the audio setup. ``` -------------------------------- ### NTV2Burn::Run: Start playout and capture threads Source: https://sdkdocs.aja.com/public/ntv2/current/d5/dd5/ntv2burn_8cpp_source.html Starts the playout and capture threads and returns AJA_STATUS_SUCCESS. This is the main entry point for the NTV2Burn example after initialization. ```cpp AJAStatus NTV2Burn::Run (void) { // Start the playout and capture threads... StartPlayThread(); StartCaptureThread(); return AJA_STATUS_SUCCESS; } // Run ``` -------------------------------- ### Init method: device configuration and setup Source: https://sdkdocs.aja.com/public/ntv2/current/d2/de1/ntv2streamplayer_8cpp_source.html Configures the output channel, checks device capabilities, sets task mode, and prepares video and host buffers. Returns AJA_STATUS_UNSUPPORTED if the channel is invalid, AJA_STATUS_BUSY if the device is in use, and AJA_STATUS_SUCCESS on success. ```cpp if (UWord(mConfig.fOutputChannel) >= maxNumChannels) { cerr << "## ERROR: '" << mDevice.GetDisplayName() << "' can't use Ch" << DEC(mConfig.fOutputChannel+1) << " -- only supports Ch1" << (maxNumChannels > 1 ? string("-Ch") + string(1, char(maxNumChannels+'0')) : "") << endl; return AJA_STATUS_UNSUPPORTED; } if (!mConfig.fDoMultiFormat) { mDevice.GetTaskMode(mSavedTaskMode); // Save the current task mode if (!mDevice.AcquireStreamForApplication (kDemoAppSignature, int32_t(AJAProcess::GetPid()))) return AJA_STATUS_BUSY; // Device is in use by another app -- fail } mDevice.SetTaskMode(NTV2_OEM_TASKS); // Set OEM service level if (mDevice.features().CanDoMultiFormat()) mDevice.SetMultiFormatMode(mConfig.fDoMultiFormat); else mConfig.fDoMultiFormat = false; // Set up the video and audio... status = SetUpVideo(); if (AJA_FAILURE(status)) return status; // Set up the circular buffers, and the test pattern buffers... status = SetUpHostBuffers(); if (AJA_FAILURE(status)) return status; status = SetUpTestPatternBuffers(); if (AJA_FAILURE(status)) return status; // Set up the device signal routing... if (!RouteOutputSignal()) return AJA_STATUS_FAIL; // Lastly, prepare my AJATimeCodeBurn instance... if (!mTCBurner.RenderTimeCodeFont (CNTV2DemoCommon::GetAJAPixelFormat(mConfig.fPixelFormat), mFormatDesc.numPixels, mFormatDesc.numLines)) {cerr << "## ERROR: RenderTimeCodeFont failed for: " << mFormatDesc << endl; return AJA_STATUS_UNSUPPORTED;} // Ready to go... #if defined(_DEBUG) cerr << mConfig << endl; #endif // defined(_DEBUG) return AJA_STATUS_SUCCESS; } // Init ``` -------------------------------- ### ntv2firmwareinstaller firmware install example Source: https://sdkdocs.aja.com/public/ntv2/current/db/d02/toolsandutilities.html Re-installs the T-Tap Pro firmware on a macOS computer. The command uses the -dttappro device flag and --progress to show installation progress. After installation, the host and/or device must be power-cycled for the new firmware to load. ```text % path/to/ntv2firmwareinstaller -dttappro --progress "/Library/Application Support/AJA/Firmware/ttappro.bit" Running FW Rev: 0x04(4) Running Bitfile: 2021/08/11 10:38:22 Main Bitfile: 't_tap_pro' 2021/08/11 12:00:14 Failsafe Bitfile: 't_tap_pro' 2020/07/14 11:42:00 Serial Number: '02092022' Installing firmware... ## NOTE: CNTV2FirmwareInstallerThread: Firmware update started bitfile: /Library/Application Support/AJA/Firmware/ttappro.bit device: TTapPro '02092022' on 'localhost' at index 0, S/N 02092022 firmware: /Library/Application Support/AJA/Firmware/ttappro.bit - 2021/08/11 12:00:14 Erase status: 100% Program status: 100% Program verify: 100% ## NOTE: CNTV2FirmwareInstallerThread: Firmware update completed bitfile: /Library/Application Support/AJA/Firmware/ttappro.bit device: TTapPro '02092022' on 'localhost' at index 0, S/N 02092022 firmware: /Library/Application Support/AJA/Firmware/ttappro.bit - 2021/08/11 12:00:14 Verifying... Running FW Rev: 0x04(4) Running Bitfile: 2021/08/11 10:38:22 Main Bitfile: 't_tap_pro' 2021/08/11 12:00:14 Failsafe Bitfile: 't_tap_pro' 2020/07/14 11:42:00 Serial Number: '02092022' ## NOTE: This host and/or AJA device must be power-cycled for the new firmware to load. Firmware installed - OK ``` -------------------------------- ### SetupAudio() Source: https://sdkdocs.aja.com/public/ntv2/current/d2/dad/class_n_t_v2_encode_h_e_v_c_vif_ac.html Sets up everything needed for capturing audio. This method is protected and virtual. ```APIDOC ## SetupAudio() ### Description Sets up everything I need for capturing audio. ### Method SetupAudio ### Signature `protected virtual AJAStatus NTV2EncodeHEVCVifAc::SetupAudio(void)` ### Parameters None ### Returns AJAStatus - Status of the audio setup. ### Notes - Definition at line 551 of file ntv2encodehevcvifac.cpp. ``` -------------------------------- ### Get row address pointer Source: https://sdkdocs.aja.com/public/ntv2/current/d3/de0/ntv2formatdescriptor_8cpp_source.html Returns a pointer to the start of a row within a plane, or AJA_NULL if the row/plane index is invalid or the start address is NULL. Adds plane raster sizes and row offset to the base address. ```cpp const void * NTV2FormatDescriptor::GetRowAddress (const void * pInStartAddress, const ULWord inRowIndex0, const UWord inPlaneIndex0) const { if (inRowIndex0 >= numLines) return AJA_NULL; if (inPlaneIndex0 >= mNumPlanes) return AJA_NULL; if (!pInStartAddress) return AJA_NULL; const UByte * pStart (AsConstUBytePtr(pInStartAddress)); NTV2_ASSERT(pStart); if (inPlaneIndex0 > 0) pStart += GetTotalRasterBytes(0); if (inPlaneIndex0 > 1) pStart += GetTotalRasterBytes(1); if (inPlaneIndex0 > 2) pStart += GetTotalRasterBytes(2); return pStart + inRowIndex0 * GetBytesPerRow(inPlaneIndex0); } ``` -------------------------------- ### main.cpp: Kona IP J2K setup entry point Source: https://sdkdocs.aja.com/public/ntv2/current/d5/d3c/ntv2konaipj2ksetup_2main_8cpp_source.html Entry point for the ntv2konaipj2ksetup demo. Parses command-line options -d (device), -b (board), and -l (list video formats). If -l is set, prints the video format map; otherwise, requires exactly one positional JSON file argument and applies its parameters to both encoder and decoder setup. Uses CKonaIpJ2kJsonReader, CKonaIpEncoderSetup, and CKonaIpDecoderSetup. ```cpp /* SPDX-License-Identifier: MIT */ #include #include #include "konaipj2ksetup.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QCommandLineParser parser; parser.setApplicationDescription("Kona IP J2K Setup"); parser.addHelpOption(); parser.addVersionOption(); const QCommandLineOption deviceOption("d", "which device to use", "device"); parser.addOption(deviceOption); const QCommandLineOption boardOption("b", "which device to use", "board"); parser.addOption(boardOption); const QCommandLineOption listOption("l", "list video formats", ""); parser.addOption(listOption); parser.addPositionalArgument("InputJsonFile", QCoreApplication::translate("main", "Json File to Open.")); parser.process(a); if (parser.isSet(listOption)) { CKonaIpJ2kJsonReader readJson; readJson.printVideoFormatMap(); } else { QString device = "0"; if (parser.isSet(deviceOption)) { device = parser.value(deviceOption); } if (parser.isSet(boardOption)) { device = parser.value(boardOption); } std::string devStr = device.toUtf8().constData(); const QStringList args = parser.positionalArguments(); if ( args.size() == 1 ) { CKonaIpJ2kJsonReader readJson; readJson.openJson(args.at(0)); CKonaIpEncoderSetup ipEncoderSetup; ipEncoderSetup.setupBoard(devStr.c_str(), readJson.getKonaIpJ2kParams ()); CKonaIpDecoderSetup ipDecoderSetup; ipDecoderSetup.setupBoard(devStr.c_str(), readJson.getKonaIpJ2kParams ()); } else parser.showHelp(); } } ``` -------------------------------- ### GetNumCompleteCaptionChannelPacketInfo(int *pCompleteCount=0, int *pStartedCount=0) Source: https://sdkdocs.aja.com/public/ntv2/current/dc/d4b/class_c_n_t_v2_caption_decoder708.html Gets the number of complete and started caption channel packet information entries. ```APIDOC ## GetNumCompleteCaptionChannelPacketInfo(int *pCompleteCount=0, int *pStartedCount=0) ### Description Gets the number of complete and started caption channel packet information entries. ### Method Member function ### Signature `virtual int GetNumCompleteCaptionChannelPacketInfo(int *pCompleteCount=0, int *pStartedCount=0)` ### Parameters - **pCompleteCount** (int*) - Optional - Output pointer to receive the number of complete entries. - **pStartedCount** (int*) - Optional - Output pointer to receive the number of started entries. ### Returns - **int** - The number of complete caption channel packet information entries. ``` -------------------------------- ### NTV2Player4K::ConsumerThreadStatic() Source: https://sdkdocs.aja.com/public/ntv2/current/d8/d6d/class_n_t_v2_player4_k.html Static callback function for the consumer thread. Gets called when the consumer thread starts and is attached to the AJAThread instance. ```APIDOC ## ConsumerThreadStatic() ### Description This is the consumer thread's static callback function that gets called when the consumer thread starts. This function gets "Attached" to the consumer thread's AJAThread instance. ### Method Static protected member function ### Signature `static void ConsumerThreadStatic(AJAThread* pThread, void* pContext)` ### Parameters - **pThread** (AJAThread*) - [in] A valid pointer to the consumer thread's AJAThread instance. - **pContext** (void*) - [in] Context information to pass to the thread (the NTV2Player4K instance). ### Returns None ### Definition Line 1208 of ntv2player4k.cpp. ``` -------------------------------- ### SetUpAudio Method Source: https://sdkdocs.aja.com/public/ntv2/current/d5/d9e/ntv2dolbyplayer_8cpp_source.html Initializes the audio system, sets channel counts, rates, buffer sizes, and configures HDMI audio output settings. ```cpp AJAStatus NTV2DolbyPlayer::SetUpAudio (void) { mAudioSystem = NTV2_AUDIOSYSTEM_1; // Use NTV2_AUDIOSYSTEM_1... if (mDevice.features().GetNumAudioSystems() > 1) // ...but if the device has more than one audio system... mAudioSystem = ::NTV2ChannelToAudioSystem(mConfig.fOutputChannel); // ...base it on the channel // However, there are a few older devices that have only 1 audio system, // yet 2 frame stores (or must use channel 2 for playout)... if (!mDevice.features().CanDoFrameStore1Display()) mAudioSystem = NTV2_AUDIOSYSTEM_1; mDevice.SetNumberAudioChannels (8, mAudioSystem); // This demo uses 8 channels -- no more, no less mDevice.SetAudioRate (mAudioRate, mAudioSystem); // How big should the on-device audio buffer be? 1MB? 2MB? 4MB? 8MB? // For this demo, 4MB will work best across all platforms (Windows, Mac & Linux)... mDevice.SetAudioBufferSize (NTV2_AUDIO_BUFFER_BIG, mAudioSystem); // Set the SDI output audio embedders to embed audio samples from the output of mAudioSystem... mDevice.SetHDMIOutAudioSource2Channel (NTV2_AudioChannel1_2, mAudioSystem); mDevice.SetHDMIOutAudioRate(mAudioRate); mDevice.SetHDMIOutAudioFormat(mDolbyFileIO.IsOpen() ? NTV2_AUDIO_FORMAT_DOLBY : NTV2_AUDIO_FORMAT_LPCM); // If the last app using the device left it in end-to-end mode (input passthru), // then loopback must be disabled, or else the output will contain whatever audio // is present in whatever signal is feeding the device's SDI input... mDevice.SetAudioLoopBack (NTV2_AUDIO_LOOPBACK_OFF, mAudioSystem); return AJA_STATUS_SUCCESS; } // SetUpAudio ``` -------------------------------- ### SetupVideo: Device reference and interrupt setup Source: https://sdkdocs.aja.com/public/ntv2/current/d4/d1e/ntv2encodehevcvifac_8cpp_source.html Sets the device reference to free-run in multiformat mode or to the input source reference otherwise, and enables/subscribes to input interrupts for the input channel. Also sets up timecode burn. ```cpp // Set the device reference to the input... if (mMultiStream) { mDevice.SetReference (NTV2_REFERENCE_FREERUN); } else { mDevice.SetReference (::NTV2InputSourceToReferenceSource (mInputSource)); } // Enable and subscribe to the interrupts for the channel to be used... mDevice.EnableInputInterrupt (mInputChannel); mDevice.SubscribeInputVerticalEvent (mInputChannel); // Setup for timecode burn mTimeBase.SetAJAFrameRate (mHevcCommon->GetAJAFrameRate(GetNTV2FrameRateFromVideoFormat (mVideoFormat))); mTimeCodeBurn.RenderTimeCodeFont (mHevcCommon->GetAJAPixelFormat (mPixelFormat), GetDisplayWidth (mVideoFormat), GetDisplayHeight (mVideoFormat)); return AJA_STATUS_SUCCESS; } // SetupVideo ``` -------------------------------- ### Get items array from dictionary (truncated) Source: https://sdkdocs.aja.com/public/ntv2/current/d7/d4a/infoimpl_8mm_source.html Starts a helper that extracts an array from a dictionary. The source is truncated, so only the opening lines are shown. ```cpp static CFArrayRef get_items_array_from_dict(const CFDictionaryRef inDictionary) { ``` -------------------------------- ### NTV2Capture4K::SetupAudio() Source: https://sdkdocs.aja.com/public/ntv2/current/dc/d03/ntv2capture4k_8h_source.html Sets up everything needed for capturing audio. ```APIDOC ## NTV2Capture4K::SetupAudio() ### Description Sets up everything needed for capturing audio. ### Return Type AJAStatus ### Signature virtual AJAStatus SetupAudio(void) ### Definition ntv2capture4k.cpp:227 ``` -------------------------------- ### CaptureFrames: AutoCirculate capture loop setup Source: https://sdkdocs.aja.com/public/ntv2/current/dc/df1/ntv2fieldburn_8cpp_source.html Starts the capture thread's main loop, initializing transfer info structures and options for AutoCirculate capture. The code shown is the beginning of the CaptureFrames method, setting up variables and logging thread start. ```cpp void NTV2FieldBurn::CaptureFrames (void) { AUTOCIRCULATE_TRANSFER inputXferInfo; // F1 transfer info AUTOCIRCULATE_TRANSFER inputXferInfo2; // F2 transfer info (unused in Field Mode) NTV2TCIndexes F1TCIndexes, F2TCIndexes; const ULWord acOptions ((mConfig.WithTimecode() ? AUTOCIRCULATE_WITH_RP188 : 0) | (mConfig.FieldMode() ? AUTOCIRCULATE_WITH_FIELDS : 0)); ULWord goodXfers(0), badXfers(0), ringFulls(0), devWaits(0); BURNNOTE("Thread started"); ``` -------------------------------- ### SetUpVideo Method Source: https://sdkdocs.aja.com/public/ntv2/current/d5/d9e/ntv2dolbyplayer_8cpp_source.html Configures the video format, frame buffer, and output vertical event subscription for the device. ```cpp mDevice.SetVideoFormat (mConfig.fVideoFormat, false, false, mConfig.fOutputChannel); // Set the frame buffer pixel format for the device FrameStore... mDevice.SetFrameBufferFormat (mConfig.fOutputChannel, mConfig.fPixelFormat); // The output interrupt is Enabled by default, but on some platforms, you must subscribe to it // in order to be able to wait on its event/semaphore... mDevice.SubscribeOutputVerticalEvent (mConfig.fOutputChannel); // Set output clock reference... mDevice.SetReference(mDevice.features().CanDo2110() ? NTV2_REFERENCE_SFP1_PTP : NTV2_REFERENCE_FREERUN); return AJA_STATUS_SUCCESS; } // SetUpVideo ``` -------------------------------- ### Get installed Mac driver version from Info.plist Source: https://sdkdocs.aja.com/public/ntv2/current/d6/d9b/ntv2utils_8cpp_source.html Reads the installed AJA Mac driver version from the Info.plist file at /Library/Extensions/AJANTV2.kext/Contents/Info.plist. Parses the CFBundleShortVersionString key and splits it into components; returns false if the file cannot be opened or is not good. Fails for binary plist files. ```cpp #if defined (AJAMac) #include #include "ajabase/common/common.h" // Poor man's plist reader // Fetches version components out of CFBundleShortVersionString // Returns true if the Info.plist exists; otherwise false // NOTE: This will fail for binary plist files! static const string AJAMacDriverInfoPlistPath ("/Library/Extensions/AJANTV2.kext/Contents/Info.plist"); bool GetInstalledMacDriverVersion (UWord & outMaj, UWord & outMin, UWord & outPt, UWord & outBld, UWord & outType) { outMaj = outMin = outPt = outBld = outType = 0; ifstream ifs; ifs.open(AJAMacDriverInfoPlistPath.c_str(), std::ios::in); if (!ifs.is_open()) return false; if (!ifs.good()) return false; const string key("CFBundleShortVersionString"); for (string line; std::getline(ifs, line); ) { size_t keyPos(line.find(key)); if (keyPos == string::npos) continue; if (!std::getline(ifs, line)) break; //"16.1.0b58" or "16.0.1" size_t startPos(line.find("")), endPos(line.find("")); if (startPos == string::npos || endPos == string::npos) continue; startPos += 8; if (endPos < startPos) continue; string versStr(line.substr(startPos, endPos-startPos)); // "16.1.0b58" or "16.0.1" NTV2StringList versComps; aja::split(versStr, '.', versComps); if (versComps.size() < 3 || versComps.size() > 4) continue; } ``` -------------------------------- ### SetupBoard method implementation Source: https://sdkdocs.aja.com/public/ntv2/current/df/d10/ntv2linuxdriverinterface_8cpp_source.html Sets up the board via ioctl with IOCTL_NTV2_SETUP_BOARD. Returns true on success, false on failure. The ioctl call includes extra arguments to suppress valgrind errors. ```cpp bool CNTV2LinuxDriverInterface::SetupBoard (void) { if (IsRemote()) return false; NTV2_ASSERT( (_hDevice != INVALID_HANDLE_VALUE) && (_hDevice != 0) ); if (ioctl(int(_hDevice), IOCTL_NTV2_SETUP_BOARD, 0, 0)) // Suppress valgrind errors { LDIFAIL("IOCTL_NTV2_SETUP_BOARD failed"); return false; } return true; } ``` -------------------------------- ### FetchAudioLog: Get device audio capabilities Source: https://sdkdocs.aja.com/public/ntv2/current/dd/d5a/ntv2supportlogger_8cpp_source.html Starts the FetchAudioLog method by retrieving the device ID, maximum number of audio channels, and number of audio systems. This is the beginning of the method; the rest is not shown. ```cpp 802 void CNTV2SupportLogger::FetchAudioLog (ostringstream & oss) const 803 { 804 const NTV2DeviceID devID (mDevice.GetDeviceID()); 805 const UWord maxNumChannels (::NTV2DeviceGetMaxAudioChannels(devID)); 806 const UWord numAudSys (::NTV2DeviceGetNumAudioSystems(devID)); ``` -------------------------------- ### main.cpp: NTV2QtPreview demo entry point Source: https://sdkdocs.aja.com/public/ntv2/current/d9/d81/ntv2qtpreview_2main_8cpp_source.html Entry point for the NTV2 Qt Preview demo. Creates a QApplication, opens AJADebug, instantiates NTV2QtPreview, sets the window title to "NTV2 Qt Preview", shows it, and runs the event loop. Includes QtWidgets for Qt 5+ and QtGui for older versions. ```cpp #include "ntv2qtpreview.h" #include "ajabase/system/debug.h" #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #include #else #include #endif int main (int argc, char * argv []) { QApplication app (argc, argv); AJADebug::Open(); NTV2QtPreview window; window.setWindowTitle ("NTV2 Qt Preview"); window.show (); return app.exec (); } // main ``` -------------------------------- ### Get Sector Size for Sector Number Source: https://sdkdocs.aja.com/public/ntv2/current/d4/db6/ntv2spiinterface_8cpp_source.html Returns the size of a given sector. For the first 32 sectors when 4K start sectors are enabled, returns 4KB; otherwise returns the reported sector size. ```cpp static uint32_t size_for_sector_number(const uint32_t reportedSectorSize, const uint32_t sector) { if (has_4k_start_sectors(reportedSectorSize) && sector < 32) return 4 * 1024; else return reportedSectorSize; } ``` -------------------------------- ### Measure elapsed time with Msr_Start and MsrStop Source: https://sdkdocs.aja.com/public/ntv2/current/d1/d9c/measure_8h_source.html Measures elapsed time between a start and stop call. The example shows timing an MPEG B-frame decode; note the stop call is MsrStop (not Msr_Stop) in the source. ```c // To measure an elapsed time e.g. time taken to decode an MPEG B-frame Msr_Start(Id2); // e.g. "Starting to decode MPEG B-frame" . . . MsrStop(Id2); // "Finished MPEG decode" ``` -------------------------------- ### SetupJ2KForEncode function reading config and initializing variables Source: https://sdkdocs.aja.com/public/ntv2/current/d6/ddd/ntv2configts2022_8cpp_source.html Starts SetupJ2KForEncode by declaring variables and reading configuration registers, then uses video format to calculate width and height. Contains hard-coded values for subband removal, codeblock size, regulator settings, and quantization tables. ```cpp bool CNTV2ConfigTs2022::SetupJ2KForEncode(const NTV2Channel channel) { NTV2VideoFormat videoFormat; uint32_t ullMode; uint32_t bitDepth; J2KChromaSubSampling subSamp; uint32_t mbps; uint32_t bitRateMsb; uint32_t bitRateLsb; uint32_t rtConstant; uint32_t ull; // Subband removal Component 0, 1 and 2 uint32_t sb_rmv_c0 = 0; uint32_t sb_rmv_c1 = 0; uint32_t sb_rmv_c2 = 0; J2KCodeBlocksize codeBlocksize = kJ2KCodeBlocksize_32x32; uint32_t regulator_type = 0; uint32_t Rsiz = 258; uint32_t reg_cap = 0; uint32_t clk_fx_freq = 200; uint32_t marker = 0x02; uint32_t guard_bit = 1; uint32_t prog_order = 0; uint32_t fdwt_type = 1; uint32_t mct = 0; uint32_t num_comp = 3; uint32_t num_levels = 5; uint32_t GOB[8] = {03, 03, 03, 03, 03, 03, 03, 03}; uint32_t QS_C0[8] = {12, 13, 14, 15, 16, 16, 16, 16}; uint32_t QS_C1[8] = {12, 13, 14, 15, 16, 16, 16, 16}; uint32_t QS_C2[8] = {12, 13, 14, 15, 16, 16, 16, 16}; // Get our variable user params ReadJ2KConfigReg(channel, kRegSarekEncodeVideoFormat1, (uint32_t*) &videoFormat); ReadJ2KConfigReg(channel, kRegSarekEncodeUllMode1, &ullMode); ReadJ2KConfigReg(channel, kRegSarekEncodeBitDepth1, &bitDepth); ReadJ2KConfigReg(channel, kRegSarekEncodeChromaSubSamp1, (uint32_t *) &subSamp); ReadJ2KConfigReg(channel, kRegSarekEncodeMbps1, &mbps); // Calculate height and width based on video format NTV2Standard standard = GetNTV2StandardFromVideoFormat(videoFormat); NTV2FormatDescriptor fd (standard, NTV2_FBF_10BIT_YCBCR); uint32_t width = fd.GetRasterWidth(); uint32_t height = fd.GetVisibleRasterHeight(); // Calculate framerate based on video format // TODO: Calculate framerate implementation } ``` -------------------------------- ### IOCTL_NTV2_SETUP_BOARD Source: https://sdkdocs.aja.com/public/ntv2/current/d7/d83/ntv2linuxpublicinterface_8h.html Sets up the board. ```APIDOC ## IOCTL_NTV2_SETUP_BOARD ### Description Sets up the board. ### Method IOCTL ### Endpoint IOCTL_NTV2_SETUP_BOARD ### Parameters None ### Request Example ```c ioctl(fd, IOCTL_NTV2_SETUP_BOARD); ``` ### Response #### Success Response No return value on success. #### Response Example No response data. ``` -------------------------------- ### FetchRegisterLog: Get device registers Source: https://sdkdocs.aja.com/public/ntv2/current/dd/d5a/ntv2supportlogger_8cpp_source.html Starts the FetchRegisterLog method by obtaining the device ID and the set of registers for that device via CNTV2RegisterExpert::GetRegistersForDevice. The snippet is incomplete as shown in the source; it only includes the opening lines of the function. ```cpp void CNTV2SupportLogger::FetchRegisterLog (ostringstream & oss) const { NTV2RegisterReads regs; const NTV2DeviceID deviceID (mDevice.GetDeviceID()); NTV2RegNumSet deviceRegs (CNTV2RegisterExpert::GetRegistersForDevice (deviceID)); ```