106 if( CreateDummyGLWindowWin32( &hWnd, &hGLRC ) ==
false )
118 LOG_ERROR(
"Could not load OpenGL Video Capture extension." );
124 LOG_ERROR(
"Could not load OpenGL timer query extension." );
130 LOG_ERROR(
"Could not load OpenGL buffer object extension." );
135 NVVIOTOPOLOGY l_vioTopos;
136 NvAPI_Status ret = NVAPI_OK;
139 if ( NvAPI_Initialize() != NVAPI_OK )
141 LOG_ERROR(
"Error Initializing NVAPI." );
146 memset( &l_vioTopos, 0,
sizeof( l_vioTopos ) );
147 l_vioTopos.version = NVVIOTOPOLOGY_VER;
148 if ( NvAPI_VIO_QueryTopology( &l_vioTopos ) != NVAPI_OK )
150 LOG_ERROR(
"Video I/O Unsupported." );
158 while (
i < l_vioTopos.vioTotalDeviceCount )
161 memset( &l_vioCaps, 0,
sizeof( l_vioCaps ) );
162 l_vioCaps.version = NVVIOCAPS_VER;
163 if ( NvAPI_VIO_GetCapabilities( l_vioTopos.vioTarget[
i].hVioHandle, &l_vioCaps ) != NVAPI_OK )
170 if ( l_vioCaps.adapterCaps & NVVIOCAPS_VIDIN_SDI )
184 if( DestroyGLWindowWin32( &hWnd, &hGLRC ) ==
false )
244 memcpy(
m_cscMat, cscMat,
sizeof( GLfloat ) * 16 );
245 memcpy(
m_cscOffset, cscOffset,
sizeof( GLfloat ) * 4 );
246 memcpy(
m_cscMin, cscMin,
sizeof( GLfloat ) * 4 );
247 memcpy(
m_cscMax, cscMax,
sizeof( GLfloat ) * 4 );
272 LOG_INFO(
"SMPTE 352: " << jack.smpte352 );
276 LOG_INFO(
"Bits Per Component: " << jack.bitsPerComponent );
277 LOG_INFO(
"SMPTE 352 Payload ID: " << jack.smpte352 );
283 LOG_INFO(
"Links: " );
284 for(
unsigned int i = 0;
i < stream.numLinks;
i++ )
286 LOG_INFO(
"Jack: " << stream.links[
i].jack <<
" Channel: " << stream.links[
i].channel );
289 LOG_INFO(
"Expansion Enable: " << stream.expansionEnable );
290 LOG_INFO(
"Bits Per Component: " << stream.bitsPerComponent );
321 NvAPI_Status ret = NVAPI_OK;
323 memset( vioStatus, 0,
sizeof( NVVIOSTATUS ) );
324 vioStatus->version = NVVIOSTATUS_VER;
325 if ( NvAPI_VIO_Status(
m_vioHandle, vioStatus ) != NVAPI_OK )
327 LOG_ERROR(
"Cannot get status of SDI input device." );
332 for (
unsigned int i = 0;
i < NVAPI_MAX_VIO_JACKS;
i++ )
334 for (
unsigned int j = 0; j < NVAPI_MAX_VIO_CHANNELS_PER_JACK; j++ )
341 memset( vioConfig, 0,
sizeof( NVVIOCONFIG_V1 ) );
342 vioConfig->version = NVVIOCONFIG_VER1;
343 vioConfig->nvvioConfigType = NVVIOCONFIGTYPE_IN;
344 vioConfig->fields = NVVIOCONFIG_SIGNALFORMAT | NVVIOCONFIG_STREAMS;
345 if ( NvAPI_VIO_GetConfig(
m_vioHandle, ( NVVIOCONFIG* )vioConfig ) != NVAPI_OK )
347 LOG_ERROR(
"Cannot get configuration of SDI input device." );
352 LOG_DEBUG(
"Number of Streams: " << vioConfig->vioConfig.inConfig.numStreams );
353 LOG_DEBUG(
"Signal Format: " <<
SignalFormatToString( vioConfig->vioConfig.inConfig.signalFormat ).c_str() );
356 for (
unsigned int i = 0;
i < vioConfig->vioConfig.inConfig.numStreams;
i++ )
367 NVVIOCONFIG_V1 l_vioConfig;
368 NVVIOSTATUS l_vioStatus;
376 for (
unsigned int i = 0;
i < NVAPI_MAX_VIO_JACKS;
i++ )
378 if ( l_vioStatus.vioStatus.inStatus.vidIn[
i][0].signalFormat != NVVIOSIGNALFORMAT_NONE )
388 LOG_ERROR(
"No active video input input streams detected." );
393 memset( &l_vioConfig, 0,
sizeof( l_vioConfig ) );
394 l_vioConfig.version = NVVIOCONFIG_VER1;
395 l_vioConfig.nvvioConfigType = NVVIOCONFIGTYPE_IN;
399 for (
unsigned int i = 0;
i < NVAPI_MAX_VIO_JACKS;
i++ )
401 for (
unsigned int j = 0; j < NVAPI_MAX_VIO_CHANNELS_PER_JACK; j++ )
403 if ( l_vioStatus.vioStatus.inStatus.vidIn[
i][j].signalFormat != NVVIOSIGNALFORMAT_NONE )
405 l_vioConfig.vioConfig.inConfig.signalFormat = l_vioStatus.vioStatus.inStatus.vidIn[
i][j].signalFormat;
417 l_vioConfig.fields = NVVIOCONFIG_SIGNALFORMAT;
420 l_vioConfig.vioConfig.inConfig.numStreams =
m_numStreams;
422 l_vioConfig.fields |= NVVIOCONFIG_STREAMS;
423 l_vioConfig.vioConfig.inConfig.numRawCaptureImages = NVAPI_GVI_DEFAULT_RAW_CAPTURE_IMAGES;
425 switch( l_vioConfig.vioConfig.inConfig.signalFormat )
427 case NVVIOSIGNALFORMAT_1080P_50_00_SMPTE274_3G_LEVEL_A:
428 case NVVIOSIGNALFORMAT_1080P_59_94_SMPTE274_3G_LEVEL_A:
429 case NVVIOSIGNALFORMAT_1080P_60_00_SMPTE274_3G_LEVEL_A:
430 case NVVIOSIGNALFORMAT_1080P_60_00_SMPTE274_3G_LEVEL_B:
431 case NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274_3G_LEVEL_B:
432 case NVVIOSIGNALFORMAT_2048I_60_00_SMPTE372_3G_LEVEL_B:
433 case NVVIOSIGNALFORMAT_1080P_50_00_SMPTE274_3G_LEVEL_B:
434 case NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274_3G_LEVEL_B:
435 case NVVIOSIGNALFORMAT_2048I_50_00_SMPTE372_3G_LEVEL_B:
436 case NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274_3G_LEVEL_B:
437 case NVVIOSIGNALFORMAT_2048P_30_00_SMPTE372_3G_LEVEL_B:
438 case NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274_3G_LEVEL_B:
439 case NVVIOSIGNALFORMAT_2048P_25_00_SMPTE372_3G_LEVEL_B:
440 case NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274_3G_LEVEL_B:
441 case NVVIOSIGNALFORMAT_2048P_24_00_SMPTE372_3G_LEVEL_B:
442 case NVVIOSIGNALFORMAT_1080I_48_00_SMPTE274_3G_LEVEL_B:
443 case NVVIOSIGNALFORMAT_2048I_48_00_SMPTE372_3G_LEVEL_B:
444 case NVVIOSIGNALFORMAT_1080P_59_94_SMPTE274_3G_LEVEL_B:
445 case NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274_3G_LEVEL_B:
446 case NVVIOSIGNALFORMAT_2048I_59_94_SMPTE372_3G_LEVEL_B:
447 case NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274_3G_LEVEL_B:
448 case NVVIOSIGNALFORMAT_2048P_29_97_SMPTE372_3G_LEVEL_B:
449 case NVVIOSIGNALFORMAT_1080P_23_98_SMPTE274_3G_LEVEL_B:
450 case NVVIOSIGNALFORMAT_2048P_23_98_SMPTE372_3G_LEVEL_B:
451 case NVVIOSIGNALFORMAT_1080I_47_96_SMPTE274_3G_LEVEL_B:
452 case NVVIOSIGNALFORMAT_2048I_47_96_SMPTE372_3G_LEVEL_B:
459 LOG_WARNING(
"3G capture supported on Jacks 1 and 3 only." );
464 l_vioConfig.vioConfig.inConfig.streams[
i].sampling =
m_Sampling;
467 l_vioConfig.vioConfig.inConfig.streams[
i].numLinks = 2;
468 l_vioConfig.vioConfig.inConfig.streams[
i].links[0].jack =
m_activeJacks[
i];
469 l_vioConfig.vioConfig.inConfig.streams[
i].links[0].channel = 0;
470 l_vioConfig.vioConfig.inConfig.streams[
i].links[1].jack =
m_activeJacks[
i];
471 l_vioConfig.vioConfig.inConfig.streams[
i].links[1].channel = 1;
479 l_vioConfig.vioConfig.inConfig.streams[3].sampling =
m_Sampling;
482 l_vioConfig.vioConfig.inConfig.streams[3].numLinks = 1;
483 l_vioConfig.vioConfig.inConfig.streams[3].links[0].jack = 3;
484 l_vioConfig.vioConfig.inConfig.streams[3].links[0].channel = 0;
486 l_vioConfig.vioConfig.inConfig.streams[2].sampling =
m_Sampling;
489 l_vioConfig.vioConfig.inConfig.streams[2].numLinks = 1;
490 l_vioConfig.vioConfig.inConfig.streams[2].links[0].jack =
m_activeJacks[2];
491 l_vioConfig.vioConfig.inConfig.streams[2].links[0].channel = 0;
493 l_vioConfig.vioConfig.inConfig.streams[1].sampling =
m_Sampling;
496 l_vioConfig.vioConfig.inConfig.streams[1].numLinks = numLinks;
499 l_vioConfig.vioConfig.inConfig.streams[1].links[1].jack = 3;
500 l_vioConfig.vioConfig.inConfig.streams[1].links[1].channel = 0;
501 l_vioConfig.vioConfig.inConfig.streams[1].links[0].jack = 2;
502 l_vioConfig.vioConfig.inConfig.streams[1].links[0].channel = 0;
506 l_vioConfig.vioConfig.inConfig.streams[1].links[0].jack =
m_activeJacks[1];
507 l_vioConfig.vioConfig.inConfig.streams[1].links[0].channel = 0;
510 l_vioConfig.vioConfig.inConfig.streams[0].sampling =
m_Sampling;
513 l_vioConfig.vioConfig.inConfig.streams[0].numLinks = numLinks;
516 l_vioConfig.vioConfig.inConfig.streams[0].links[1].jack = 1;
517 l_vioConfig.vioConfig.inConfig.streams[0].links[1].channel = 0;
518 l_vioConfig.vioConfig.inConfig.streams[0].links[0].jack = 0;
519 l_vioConfig.vioConfig.inConfig.streams[0].links[0].channel = 0;
523 l_vioConfig.vioConfig.inConfig.streams[0].links[0].jack =
m_activeJacks[0];
524 l_vioConfig.vioConfig.inConfig.streams[0].links[0].channel = 0;
529 LOG_ERROR(
"Cannot configure streams, no active inputs detected." );
536 NvAPI_Status stat = NVAPI_OK;
537 stat = NvAPI_VIO_SetConfig(
m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig );
538 if ( stat != NVAPI_OK )
540 LOG_ERROR(
"Cannot set configuration of SDI input device." );
544 if ( ( NvAPI_VIO_GetConfig(
m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig ) != NVAPI_OK ) )
546 LOG_ERROR(
"Cannot get configuration of SDI input device." );
556 NVVIOCONFIG_V1 l_vioConfig;
557 NVVIOSTATUS l_vioStatus;
558 NvAPI_Status ret = NVAPI_OK;
562 LOG_ERROR(
"No SDI video input devices found." );
569 LOG_ERROR(
"Unable to set the selected device." );
591 NVVIOSIGNALFORMATDETAIL l_vioSignalFormatDetail;
592 memset( &l_vioSignalFormatDetail, 0,
sizeof( l_vioSignalFormatDetail ) );
594 ULONG l_vioSignalFormatIndex = (
ULONG )NVVIOSIGNALFORMAT_NONE;
601 l_vioSignalFormatIndex,
602 &l_vioSignalFormatDetail );
603 if ( ret == NVAPI_END_ENUMERATION || ret != NVAPI_OK )
607 l_vioSignalFormatIndex++;
610 if ( l_vioSignalFormatDetail.signalFormat ==
611 l_vioConfig.vioConfig.inConfig.signalFormat )
622 if ( l_vioSignalFormatDetail.videoMode.interlaceMode == NVVIOINTERLACEMODE_INTERLACE )
624 m_fFrameRate = l_vioSignalFormatDetail.videoMode.fFrameRate / 2.0f;
628 m_fFrameRate = l_vioSignalFormatDetail.videoMode.fFrameRate;
633 m_videoWidth = l_vioSignalFormatDetail.videoMode.horizontalPixels;
634 m_videoHeight = l_vioSignalFormatDetail.videoMode.verticalLines;
644 HVIDEOINPUTDEVICENV* videoDevices;
648 if ( numDevices <= 0 )
650 LOG_ERROR(
"wglEnumerateVideoDevicesNV() did not return any devices." );
654 assert( glGetError() == GL_NO_ERROR );
656 videoDevices = ( HVIDEOINPUTDEVICENV* )malloc( numDevices *
657 sizeof( videoDevices[0] ) );
661 LOG_ERROR(
"Memory allocation failed." );
665 assert( glGetError() == GL_NO_ERROR );
669 free( videoDevices );
670 LOG_ERROR(
"Inconsistent results from wglEnumerateVideoDevicesNV()" );
675 for ( UINT
i = 0;
i < numDevices; ++
i )
679 WGL_UNIQUE_ID_NV, &uniqueID );
680 if( bRet && uniqueID ==
m_vioID )
684 assert( glGetError() == GL_NO_ERROR );
693 free( videoDevices );
699 LOG_ERROR(
"No lockable video capture device found." );
706 GLenum err = glGetError();
708 assert( bRet &&
"Failed trying to bind the video capture device!" );
709 return bRet ? S_OK : E_FAIL;
907 assert( glGetError() == GL_NO_ERROR );
918 assert( glGetError() == GL_NO_ERROR );
930 GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV,
931 &videoBufferFormat );
932 assert( glGetError() == GL_NO_ERROR );
934 assert( glGetError() == GL_NO_ERROR );
936 assert( glGetError() == GL_NO_ERROR );
945 GLint bufferPitch = 0;
951 assert( glGetError() == GL_NO_ERROR );
982 GL_VIDEO_COLOR_CONVERSION_MATRIX_NV,
984 assert( glGetError() == GL_NO_ERROR );
987 GL_VIDEO_COLOR_CONVERSION_MAX_NV, &
m_cscMax[0] );
988 assert( glGetError() == GL_NO_ERROR );
991 GL_VIDEO_COLOR_CONVERSION_MIN_NV, &
m_cscMin[0] );
992 assert( glGetError() == GL_NO_ERROR );
995 GL_VIDEO_COLOR_CONVERSION_OFFSET_NV, &
m_cscOffset[0] );
996 assert( glGetError() == GL_NO_ERROR );
1002 GLenum err = glGetError();
1003 assert( err == GL_NO_ERROR );
1004 if( err == GL_NO_ERROR )
1015 #ifdef MEASURE_PERFORMANCE 1016 GLuint64EXT captureTimeStart;
1017 GLuint64EXT captureTimeEnd;
1021 #ifdef MEASURE_PERFORMANCE 1030 #ifdef MEASURE_PERFORMANCE 1033 m_gviTime = ( captureTimeEnd - *captureTime ) * .000000001;
1038 assert( glGetError() == GL_NO_ERROR );
1049 assert( glGetError() == GL_NO_ERROR );
1062 assert( bRet &&
"Failed trying to unbind the video capture device!" );
1064 assert( bRet &&
"Failed trying to release the video capture device!" );
PFNGLVIDEOCAPTURENVPROC glVideoCaptureNV
HRESULT GetFrameRate(float *rate)
PFNGLBEGINVIDEOCAPTURENVPROC glBeginVideoCaptureNV
NVVIOCOMPONENTSAMPLING m_Sampling
virtual ~CNvSDIinTopology()
PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glVideoCaptureStreamParameterfvNV
std::string LinkIDToString(NVVIOLINKID id)
PFNGLGETINTEGER64VPROC glGetInteger64v
GLenum Capture(GLuint *sequenceNum, GLuint64EXT *captureTime)
PFNGLENDVIDEOCAPTURENVPROC glEndVideoCaptureNV
HRESULT UnbindVideoFrameBuffer(unsigned int stream)
PFNGLGENQUERIESPROC glGenQueries
static CNvSDIinTopology & Instance()
unsigned int m_videoWidth
HRESULT BindDevice(GLuint videoSlot, HDC hDC)
HRESULT SetupDevice(int deviceNumber=0)
HRESULT GetVideoInState(NVVIOCONFIG_V1 *vioConfig, NVVIOSTATUS *vioStatus)
NVVIOSIGNALFORMAT GetSignalFormat()
unsigned int m_videoHeight
NvVioHandle GetVioHandle()
PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC wglLockVideoCaptureDeviceNV
PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glBindVideoCaptureStreamTextureNV
bool loadBufferObjectExtension()
NVVIOSIGNALFORMATDETAIL m_signalFormatDetail
NVVIOCOMPONENTSAMPLING sampling
bool loadTimerQueryExtension()
void DumpChannelStatus(NVVIOCHANNELSTATUS jack)
PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glGetVideoCaptureStreamivNV
HRESULT BindVideoFrameBuffer(GLuint videoBuffer, GLint videoBufferFormat, unsigned int stream)
HRESULT Init(nvOptions *options=NULL)
PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glVideoCaptureStreamParameterivNV
std::string ColorSpaceToString(NVVIOCOLORSPACE space)
unsigned int m_activeJacks[NVAPI_MAX_VIO_JACKS]
NVVIOTOPOLOGYTARGET * m_lDevice[NVAPI_MAX_VIO_DEVICES]
PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC wglEnumerateVideoCaptureDevicesNV
GLuint m_captureTimeQuery
PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC wglReleaseVideoCaptureDeviceNV
PFNGLDELETEQUERIESPROC glDeleteQueries
PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC wglQueryVideoCaptureDeviceNV
HRESULT UnbindVideoTexture(unsigned int stream)
HRESULT BindVideoTexture(GLuint videoTexture, unsigned int stream)
unsigned int GetNumStreams()
void SetCSCParams(GLfloat *cscMat, GLfloat *cscOffset, GLfloat *cscMin, GLfloat *cscMax)
std::string SignalFormatToString(NVVIOSIGNALFORMAT format)
bool loadCaptureVideoExtension()
std::string ComponentSamplingFormatToString(NVVIOCOMPONENTSAMPLING sampling)
unsigned int m_numStreams
int GetBufferObjectPitch(unsigned int streamIndex)
PFNWGLQUERYCURRENTCONTEXTNVPROC wglQueryCurrentContextNV
NVVIOSIGNALFORMAT m_videoFormat
PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glBindVideoCaptureStreamBufferNV
NVVIOTOPOLOGYTARGET * GetDevice(int index)
PFNGLBINDBUFFERARBPROC glBindBuffer
void DumpStreamStatus(NVVIOSTREAM stream)
PFNWGLBINDVIDEOCAPTUREDEVICENVPROC wglBindVideoCaptureDeviceNV
HVIDEOINPUTDEVICENV m_device