21 const string fileName,
22 const uint32_t frameWidth,
23 const uint32_t frameHeight,
34 mDeviceSpecifier (inDeviceSpecifier),
36 mFrameWidth (frameWidth),
37 mFrameHeight (frameHeight),
48 mLastFrameInput (
false),
49 mLastFrameRaw (
false),
50 mLastFrameHevc (
false),
51 mLastFrameVideo (
false),
53 mVideoInputFrameCount (0),
54 mVideoProcessFrameCount (0),
55 mCodecRawFrameCount (0),
56 mCodecHevcFrameCount (0),
57 mVideoFileFrameCount (0)
59 ::memset (mFileInputBuffer, 0x0,
sizeof (mFileInputBuffer));
60 ::memset (mVideoRawBuffer, 0x0,
sizeof (mVideoRawBuffer));
61 ::memset (mVideoHevcBuffer, 0x0,
sizeof (mVideoHevcBuffer));
86 if (mFileInputBuffer[bufferNdx].pVideoBuffer)
91 if (mFileInputBuffer[bufferNdx].pInfoBuffer)
97 if (mVideoRawBuffer[bufferNdx].pVideoBuffer)
102 if (mVideoRawBuffer[bufferNdx].pInfoBuffer)
108 if (mVideoHevcBuffer[bufferNdx].pVideoBuffer)
113 if (mVideoHevcBuffer[bufferNdx].pInfoBuffer)
125 if (mM31 && !mLastFrame && !mGlobalQuit)
133 for (i = 0; i < timeout; i++)
135 if (mLastFrameVideo)
break;
139 { cerr <<
"## ERROR: Wait for last frame timeout" << endl; }
143 { cerr <<
"## ERROR: ChangeEHState ready to stop failed" << endl; }
146 { cerr <<
"## ERROR: ChangeEHState stop failed" << endl; }
150 { cerr <<
"## ERROR: ChangeVInState stop failed" << endl; }
156 { cerr <<
"## ERROR: ChangeMainState to init failed" << endl; }
163 while (mFileInputThread.
Active())
166 while (mVideoProcessThread.
Active())
169 while (mCodecRawThread.
Active())
172 while (mCodecHevcThread.
Active())
175 while (mVideoFileThread.
Active())
200 { cerr <<
"## ERROR: Device '" << mDeviceSpecifier <<
"' not found" << endl;
return AJA_STATUS_OPEN; }
216 cerr <<
"## ERROR: M31 not found" << endl;
221 mM31 =
new CNTV2m31 (&mDevice);
232 if (CNTV2m31::IsPresetVIF(mPreset))
236 mVideoFormat = CNTV2m31::GetPresetVideoFormat(mPreset);
237 mPixelFormat = CNTV2m31::GetPresetFrameBufferFormat(mPreset);
238 mQuad = CNTV2m31::IsPresetUHD(mPreset);
239 mInterlaced = CNTV2m31::IsPresetInterlaced(mPreset);
250 switch (mInputChannel)
261 status = mHevcCommon->
SetupHEVC (mM31, mPreset, mEncodeChannel, mMultiStream,
false);
272 cerr <<
"OpenYuv420File " << mFileName <<
" failed " << status << endl;
278 ostringstream fileName;
280 fileName <<
"raw_" << (mInputChannel+1) <<
".hevc";
282 fileName <<
"raw.hevc";
306 for (
unsigned bufferNdx = 0; bufferNdx <
VIDEO_RING_SIZE; bufferNdx++ )
309 mFileInputBuffer[bufferNdx].
pVideoBuffer =
new uint32_t [mVideoBufferSize/4];
313 mFileInputBuffer[bufferNdx].
pInfoBuffer =
new uint32_t [mPicInfoBufferSize/4];
317 mFileInputCircularBuffer.
Add (& mFileInputBuffer[bufferNdx]);
322 for (
unsigned bufferNdx = 0; bufferNdx <
VIDEO_RING_SIZE; bufferNdx++ )
325 mVideoRawBuffer[bufferNdx].
pVideoBuffer =
new uint32_t [mVideoBufferSize/4];
329 mVideoRawBuffer[bufferNdx].
pInfoBuffer =
new uint32_t [mPicInfoBufferSize/4];
333 mVideoRawCircularBuffer.
Add (& mVideoRawBuffer[bufferNdx]);
338 for (
unsigned bufferNdx = 0; bufferNdx <
VIDEO_RING_SIZE; bufferNdx++ )
341 mVideoHevcBuffer[bufferNdx].
pVideoBuffer =
new uint32_t [mVideoBufferSize/4];
345 mVideoHevcBuffer[bufferNdx].
pInfoBuffer =
new uint32_t [mEncInfoBufferSize/4];
349 mVideoHevcCircularBuffer.
Add (& mVideoHevcBuffer[bufferNdx]);
374 mFileInputThread.
Start();
397 if (mVideoInputFrameCount < mHevcCommon->YuvNumFrames())
404 status = mHevcCommon->
ReadYuv420Frame(pVideoData->pVideoBuffer, mVideoInputFrameCount);
407 printf(
"Error reading frame %d\n", mVideoInputFrameCount);
410 pVideoData->videoDataSize = pVideoData->videoBufferSize;
411 pVideoData->videoDataSize2 = 0;
414 if (mVideoInputFrameCount == mHevcCommon->
YuvNumFrames())
416 pVideoData->lastFrame =
true;
419 if(pVideoData->lastFrame && !mLastFrameInput)
421 printf (
"Read last frame number %d\n", mVideoInputFrameCount );
422 mLastFrameInput =
true;
424 mVideoInputFrameCount++;
444 mVideoProcessThread.
Start();
475 mVideoProcessFrameCount++;
495 mCodecRawThread.
Start();
518 { cerr <<
"## ERROR: Device '" << mDeviceSpecifier <<
"' not found" << endl;
return; }
521 m31 =
new CNTV2m31 (&ntv2Device);
534 m31->RawTransfer(mPreset, mEncodeChannel,
535 (uint8_t*)pFrameData->pVideoBuffer,
536 pFrameData->videoDataSize,
539 m31->RawTransfer(mPreset, mEncodeChannel,
540 (uint8_t*)pFrameData->pVideoBuffer,
541 pFrameData->videoDataSize,
542 true, pFrameData->lastFrame);
546 m31->RawTransfer(mEncodeChannel,
547 (uint8_t*)pFrameData->pVideoBuffer,
548 pFrameData->videoDataSize,
549 pFrameData->lastFrame);
551 if (pFrameData->lastFrame)
553 mLastFrameRaw =
true;
556 mCodecRawFrameCount++;
574 mCodecHevcThread.
Start();
597 { cerr <<
"## ERROR: Device '" << mDeviceSpecifier <<
"' not found" << endl;
return; }
600 m31 =
new CNTV2m31 (&ntv2Device);
613 uint8_t* pVideoBuffer = (uint8_t*)pFrameData->
pVideoBuffer;
614 uint8_t* pInfoBuffer = (uint8_t*)pFrameData->pInfoBuffer;
615 uint32_t videoBufferSize = pFrameData->videoBufferSize;
619 m31->EncTransfer(mEncodeChannel,
624 pFrameData->videoDataSize,
625 pFrameData->infoDataSize,
626 pFrameData->lastFrame);
631 pFrameData->videoDataSize,
636 pFrameData->infoDataSize,
640 pVideoBuffer = ((uint8_t*)pFrameData->pVideoBuffer) + pFrameData->videoDataSize;
641 pInfoBuffer = ((uint8_t*)pFrameData->pInfoBuffer) +
sizeof(
HevcEncodedInfo);
642 videoBufferSize = pFrameData->videoBufferSize - pFrameData->videoDataSize;
646 m31->EncTransfer(mEncodeChannel,
651 pFrameData->videoDataSize2,
652 pFrameData->infoDataSize2,
653 pFrameData->lastFrame);
656 pFrameData->videoDataSize2 = mHevcCommon->
AlignDataBuffer(pVideoBuffer,
658 pFrameData->videoDataSize2,
663 pFrameData->infoDataSize2,
669 m31->EncTransfer(mEncodeChannel,
670 (uint8_t*)pFrameData->pVideoBuffer,
671 pFrameData->videoBufferSize,
672 (uint8_t*)pFrameData->pInfoBuffer,
673 pFrameData->infoBufferSize,
674 pFrameData->videoDataSize,
675 pFrameData->infoDataSize,
676 pFrameData->lastFrame);
679 pFrameData->videoDataSize = mHevcCommon->
AlignDataBuffer(pFrameData->pVideoBuffer,
680 pFrameData->videoBufferSize,
681 pFrameData->videoDataSize,
684 pFrameData->infoDataSize = mHevcCommon->
AlignDataBuffer(pFrameData->pInfoBuffer,
685 pFrameData->infoBufferSize,
686 pFrameData->infoDataSize,
690 if (pFrameData->lastFrame)
692 mLastFrameHevc =
true;
695 mCodecHevcFrameCount++;
712 mVideoFileThread.
Start();
736 if (!mLastFrameVideo)
739 mHevcCommon->
WriteHevcData(pFrameData->pVideoBuffer, pFrameData->videoDataSize + pFrameData->videoDataSize2);
741 if (pFrameData->lastFrame)
743 printf (
"Video file last frame number %d\n", mVideoFileFrameCount );
744 mLastFrameVideo =
true;
747 mVideoFileFrameCount++;
virtual void CodecHevcWorker(void)
Repeatedly transfers hevc frames from the codec and adds them to the hevc ring.
void CloseYuv420File(void)
virtual void StartCodecHevcThread(void)
Start the codec hevc thread.
virtual bool ReleaseStreamForApplication(ULWord inApplicationType, int32_t inProcessID)
Releases exclusive use of the AJA device for the given process, permitting other processes to acquire...
AJAStatus Add(FrameDataPtr pInFrameData)
Appends a new frame buffer to me, increasing my frame storage capacity by one frame.
I interrogate and control an AJA video/audio capture/playout device.
static void CodecHevcThreadStatic(AJAThread *pThread, void *pContext)
This is the codec hevc thread's static callback function that gets called when the thread starts...
Declares the NTV2EncodeHEVCFile class.
#define AJA_FAILURE(_status_)
static void VideoFileThreadStatic(AJAThread *pThread, void *pContext)
This is the video file writer thread's static callback function that gets called when the thread star...
Instances of me capture frames in real time from a video signal provided to an input of an AJA device...
static void CodecRawThreadStatic(AJAThread *pThread, void *pContext)
This is the codec raw thread's static callback function that gets called when the thread starts...
uint32_t videoBufferSize
Size of host video buffer (bytes)
struct HevcEncodedInfo HevcEncodedInfo
Declares the AJATime class.
virtual AJAStatus SetPriority(AJAThreadPriority priority)
virtual void VideoFileWorker(void)
Repeatedly removes hevc frame from the hevc ring and writes them to the hevc output file...
FrameDataPtr StartConsumeNextBuffer(void)
The thread that's responsible for processing incoming frames – the consumer – calls this function t...
virtual void Quit(void)
Gracefully stops me from running.
virtual AJAStatus Run(void)
Runs me.
virtual AJAStatus Start()
void EndConsumeNextBuffer(void)
The consumer thread calls this function to signal that it has finished processing the frame it obtain...
NTV2Channel
These enum values are mostly used to identify a specific widget_framestore. They're also commonly use...
virtual M31VideoPreset GetCodecPreset(void)
Get the codec preset.
virtual class DeviceCapabilities & features(void)
static void VideoInputThreadStatic(AJAThread *pThread, void *pContext)
This is the video input thread's static callback function that gets called when the thread starts...
uint32_t infoBufferSize
Size of the host information buffer (bytes)
virtual void StartVideoProcessThread(void)
Start the video process thread.
static bool GetFirstDeviceFromArgument(const std::string &inArgument, CNTV2Card &outDevice)
Rescans the host, and returns an open CNTV2Card instance for the AJA device that matches a command li...
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 ...
void SetAbortFlag(const bool *pAbortFlag)
Tells me the boolean variable I should monitor such that when it gets set to "true" will cause any th...
AJAStatus SetupHEVC(CNTV2m31 *pM31, M31VideoPreset preset, M31Channel encodeChannel, bool multiStream, bool withInfo)
ULWord GetVideoActiveSize(const NTV2VideoFormat inVideoFormat, const NTV2FrameBufferFormat inFBFormat, const NTV2VANCMode inVancMode=NTV2_VANCMODE_OFF)
virtual bool SetEveryFrameServices(const NTV2TaskMode m)
static void Sleep(const int32_t inMilliseconds)
Suspends execution of the current thread for a given number of milliseconds.
2: OEM (recommended): device configured by client application(s) with some driver involvement...
uint32_t AlignDataBuffer(void *pBuffer, uint32_t bufferSize, uint32_t dataSize, uint32_t alignBytes, uint8_t fill)
virtual void VideoProcessWorker(void)
Repeatedly removes video frames from the video input ring, calls a custom video process method and ad...
struct HevcPictureInfo HevcPictureInfo
static void VideoProcessThreadStatic(AJAThread *pThread, void *pContext)
This is the video process thread's static callback function that gets called when the thread starts...
virtual void SetupHostBuffers(void)
Sets up my circular buffers.
Specifies channel or FrameStore 2 (or the 2nd item).
virtual NTV2DeviceID GetDeviceID(void)
void WriteHevcData(void *pBuffer, uint32_t bufferSize)
AJAStatus ReadYuv420Frame(void *pBuffer, uint32_t numFrame)
Declares the AJAProcess class.
NTV2EncodeHEVCFile(const std::string inDeviceSpecifier="0", const NTV2Channel inChannel=NTV2_CHANNEL1, const std::string inFilePath="", const uint32_t inFrameWidth=0, const uint32_t inFrameHeight=0, const M31VideoPreset inM31Preset=M31_FILE_1920X1080_420_8_24p)
Constructs me using the given settings.
virtual bool GetEveryFrameServices(NTV2TaskMode &m)
void EndProduceNextBuffer(void)
The producer thread calls this function to signal that it has finished populating the frame it obtain...
virtual void GetStatus(AVHevcStatus &outStatus)
Provides status information about my input (capture) process.
virtual void CodecRawWorker(void)
Repeatedly removes video frames from the raw video ring and transfers them to the codec...
virtual ~NTV2EncodeHEVCFile()
static const ULWord kDemoAppSignature((((uint32_t)( 'D'))<< 24)|(((uint32_t)( 'E'))<< 16)|(((uint32_t)( 'M'))<< 8)|(((uint32_t)( 'O'))<< 0))
Declares numerous NTV2 utility functions.
uint32_t videoDataSize2
Size of field 2 video data (bytes)
virtual AJAStatus Attach(AJAThreadFunction *pThreadFunction, void *pUserContext)
FrameDataPtr StartProduceNextBuffer(void)
The thread that's responsible for providing frames – the producer – calls this function to populate...
bool lastFrame
Indicates last captured frame.
1: Standard/Retail: device configured by AJA ControlPanel, service/daemon, and driver.
Specifies channel or FrameStore 1 (or the first item).
uint32_t * pVideoBuffer
Pointer to host video buffer.
This structure encapsulates the video and audio buffers used by the HEVC demo applications. The demo programs that employ producer/consumer threads use a fixed number of these buffers.
AJAStatus OpenYuv420File(const std::string &inFileName, const uint32_t width, const uint32_t height)
uint32_t * pInfoBuffer
Picture information (raw) or encode information (hevc)
Specifies channel or FrameStore 4 (or the 4th item).
virtual AJAStatus Init(void)
Initializes me and prepares me to Run.
virtual AJAStatus ProcessVideoFrame(AVHevcDataBuffer *pSrcFrame, AVHevcDataBuffer *pDstFrame)
Default do-nothing function for processing the captured frames.
AJAStatus ConvertYuv420FrameToNV12(void *pSrcBuffer, void *pDstBuffer, uint32_t bufferSize)
uint32_t videoDataSize
Size of video data (bytes)
virtual void VideoInputWorker(void)
Repeatedly captures video frames using AutoCirculate and add them to the video input ring...
virtual void StartCodecRawThread(void)
Start the codec raw thread.
uint32_t infoDataSize2
Size of the field 2 information data (bytes)
8-Bit 4:2:0 2-Plane YCbCr
virtual void StartVideoInputThread(void)
Start the video input thread.
uint32_t infoDataSize
Size of the information data (bytes)
AJAStatus CreateHevcFile(const std::string &inFileName, uint32_t maxFrames)
virtual void StartVideoFileThread(void)
Start the video file writer thread.
Declares device capability functions.
This identifies the mode in which there are no VANC lines in the frame buffer.
Specifies channel or FrameStore 3 (or the 3rd item).