PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
nvSDIout.cpp
Go to the documentation of this file.
1 /***************************************************************************\
2 |* *|
3 |* Copyright 2007 NVIDIA Corporation. All rights reserved. *|
4 |* *|
5 |* NOTICE TO USER: *|
6 |* *|
7 |* This source code is subject to NVIDIA ownership rights under U.S. *|
8 |* and international Copyright laws. Users and possessors of this *|
9 |* source code are hereby granted a nonexclusive, royalty-free *|
10 |* license to use this code in individual and commercial software. *|
11 |* *|
12 |* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE *|
13 |* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR *|
14 |* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH *|
15 |* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF *|
16 |* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR *|
17 |* PURPOSE. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, *|
18 |* INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES *|
19 |* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN *|
20 |* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *|
21 |* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE *|
22 |* CODE. *|
23 |* *|
24 |* U.S. Government End Users. This source code is a "commercial item" *|
25 |* as that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting *|
26 |* of "commercial computer software" and "commercial computer software *|
27 |* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) *|
28 |* and is provided to the U.S. Government only as a commercial end item. *|
29 |* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through *|
30 |* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the *|
31 |* source code with only those rights set forth herein. *|
32 |* *|
33 |* Any use of this source code in individual and commercial software must *|
34 |* include, in the user documentation and internal comments to the code, *|
35 |* the above Disclaimer and U.S. Government End Users Notice. *|
36 |* *|
37 |* *|
38 \***************************************************************************/
39 
40 #include "PlusCommon.h"
41 #include "glExtensions.h"
42 #include "nvCommon.h"
43 #include "nvSDIout.h"
44 #include "nvSDIutil.h"
45 
46 //----------------------------------------------------------------------------
48 {
49  m_vioHandle = NULL;
50 }
51 
52 //----------------------------------------------------------------------------
54 {
55 }
56 
57 //----------------------------------------------------------------------------
58 HRESULT CNvSDIout::Init( nvOptions* options, CNvSDIoutGpu* SDIoutGpu )
59 {
60  NvAPI_Status l_ret;
61 
62  if( SDIoutGpu == NULL || SDIoutGpu->IsSDIoutput() != true )
63  {
64  //If the application didn't scan the system topology and selected a
65  // gpu for output the the scanning has to be done here.
66  // Initialize NVAPI
67  if ( NvAPI_Initialize() != NVAPI_OK )
68  {
69  return E_FAIL;
70  }
71 
72  // Query available VIO topologies.
73  // Fail if there are no VIO topologies or devices available.
74  NVVIOTOPOLOGY l_vioTopologies;
75  memset( &l_vioTopologies, 0, sizeof( l_vioTopologies ) );
76  l_vioTopologies.version = NVVIOTOPOLOGY_VER;
77 
78  if ( NvAPI_VIO_QueryTopology( &l_vioTopologies ) != NVAPI_OK )
79  {
80  return E_FAIL;
81  }
82 
83  if ( l_vioTopologies.vioTotalDeviceCount == 0 )
84  {
85  return E_FAIL;
86  }
87 
88  // Cycle through all SDI topologies looking for the first
89  // available SDI output device topology.
90  BOOL l_bFound = FALSE;
91  unsigned int i = 0;
92  NVVIOCAPS l_vioCaps;
93  while ( ( i < l_vioTopologies.vioTotalDeviceCount ) && ( !l_bFound ) )
94  {
95  // Get video I/O capabilities for current video I/O target.
96  memset( &l_vioCaps, 0, sizeof( l_vioCaps ) );
97  l_vioCaps.version = NVVIOCAPS_VER;
98  if ( NvAPI_VIO_GetCapabilities( l_vioTopologies.vioTarget[i].hVioHandle,
99  &l_vioCaps ) != NVAPI_OK )
100  {
101  LOG_ERROR( "Video I/O Unsupported." );
102  return E_FAIL;
103  }
104 
105  // If video output device found, save VIO handle and set flag.
106  if ( l_vioCaps.adapterCaps & NVVIOCAPS_VIDOUT_SDI )
107  {
108  m_vioHandle = l_vioTopologies.vioTarget[i].hVioHandle;
109  l_bFound = TRUE;
110  }
111  else
112  {
113  i++;
114  }
115  } // while i < vioTotalDeviceCount
116 
117  // If no video output device found, return error.
118  if ( !l_bFound )
119  {
120  LOG_ERROR( "No SDI video output devices found." );
121  return E_FAIL;
122  }
123  }
124  else
125  {
126  m_vioHandle = SDIoutGpu->GetVioHandle();
127  }
128  // Open the SDI device
129  if ( NvAPI_VIO_Open( m_vioHandle, NVVIOCLASS_SDI, NVVIOOWNERTYPE_APPLICATION ) != NVAPI_OK )
130  {
131  return E_FAIL;
132  }
133 
134  // Configure the SDI GVO device
135  NVVIOCONFIG_V1 l_vioConfig;
136  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
137  l_vioConfig.version = NVVIOCONFIG_VER1;
138  l_vioConfig.fields = 0;
139  l_vioConfig.nvvioConfigType = NVVIOCONFIGTYPE_OUT;
140 
141  // Configure signal and data format
142  l_vioConfig.fields = NVVIOCONFIG_SIGNALFORMAT;
143  l_vioConfig.vioConfig.outConfig.signalFormat = options->videoFormat;
144  l_vioConfig.fields |= NVVIOCONFIG_DATAFORMAT;
145  l_vioConfig.vioConfig.outConfig.dataFormat = options->dataFormat;
146 
147  // Send 8-bit colorbars as YCrCb on both channels, overriding any user settings.
148  if ( ( options->testPattern == TEST_PATTERN_COLORBARS8_75 ) ||
149  ( options->testPattern == TEST_PATTERN_COLORBARS8_100 ) ||
150  ( options->testPattern == TEST_PATTERN_YCRCB_COLORBARS ) )
151  {
152  l_vioConfig.vioConfig.outConfig.dataFormat = NVVIODATAFORMAT_DUAL_X8X8X8_TO_DUAL_422_PASSTHRU;
153  }
154 
155  // Send 10-bit colorbars as 10-bit YCrCb on a single channel, overriding any user settings.
156  if ( ( options->testPattern == TEST_PATTERN_COLORBARS10_75 ) ||
157  ( options->testPattern == TEST_PATTERN_COLORBARS10_100 ) )
158  {
159  l_vioConfig.vioConfig.outConfig.dataFormat = NVVIODATAFORMAT_X10X10X10_444_PASSTHRU;
160  }
161 
162  // Send 8-bit ramp as 8-bit YCrCbA4224
163  if ( options->testPattern == TEST_PATTERN_RAMP8 )
164  {
165  l_vioConfig.vioConfig.outConfig.dataFormat = NVVIODATAFORMAT_R8G8B8A8_TO_YCRCBA4224;
166  }
167 
168  // Send 16-bit ramp as 16-bit YCrCb444
169  if ( options->testPattern == TEST_PATTERN_RAMP16 )
170  {
171  l_vioConfig.vioConfig.outConfig.dataFormat = NVVIODATAFORMAT_R10G10B10_TO_YCRCB422;
172  }
173 
174  // Set sync source if specified. The sync source must be set
175  // before a valid sync can be detected.
176  if ( options->syncEnable )
177  {
178  l_vioConfig.vioConfig.outConfig.syncEnable = options->syncEnable;
179  l_vioConfig.vioConfig.outConfig.syncSource = options->syncSource;
180 
181  switch( options->syncSource )
182  {
183  case NVVIOSYNCSOURCE_SDISYNC:
184  l_vioConfig.fields |= NVVIOCONFIG_SYNCSOURCEENABLE;
185  break;
186  case NVVIOSYNCSOURCE_COMPSYNC:
187  l_vioConfig.vioConfig.outConfig.compositeSyncType = NVVIOCOMPSYNCTYPE_AUTO;
188  l_vioConfig.fields |= ( NVVIOCONFIG_SYNCSOURCEENABLE | NVVIOCONFIG_COMPOSITESYNCTYPE );
189  break;
190  } // switch
191  }
192 
193  // Colorspace Conversion
194  if ( options->cscEnable )
195  {
196  l_vioConfig.fields |= NVVIOCONFIG_CSCOVERRIDE;
197  l_vioConfig.vioConfig.outConfig.cscOverride = TRUE;
198  l_vioConfig.fields |= NVVIOCONFIG_COLORCONVERSION;
199 
200  // Offset
201  l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[0] = options->cscOffset[0];
202  l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[1] = options->cscOffset[1];
203  l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[2] = options->cscOffset[2];
204 
205  // Scale
206  l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[0] = options->cscScale[0];
207  l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[1] = options->cscScale[1];
208  l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[2] = options->cscScale[2];
209  l_vioConfig.vioConfig.outConfig.colorConversion.compositeSafe = TRUE;
210 
211  // Matrix
212  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][0] = options->cscMatrix[0][0];
213  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][1] = options->cscMatrix[0][1];
214  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][2] = options->cscMatrix[0][2];
215  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][0] = options->cscMatrix[1][0];
216  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][1] = options->cscMatrix[1][1];
217  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][2] = options->cscMatrix[1][2];
218  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][0] = options->cscMatrix[2][0];
219  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][1] = options->cscMatrix[2][1];
220  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][2] = options->cscMatrix[2][2];
221  }
222  else
223  {
224  l_vioConfig.fields |= NVVIOCONFIG_CSCOVERRIDE;
225  l_vioConfig.vioConfig.outConfig.cscOverride = FALSE;
226  }
227 
228  // Gamma correction
229  l_vioConfig.vioConfig.outConfig.gammaCorrection.version = NVVIOGAMMACORRECTION_VER;
230  l_vioConfig.vioConfig.outConfig.gammaCorrection.fGammaValueR = options->gamma[0];
231  l_vioConfig.vioConfig.outConfig.gammaCorrection.fGammaValueG = options->gamma[1];
232  l_vioConfig.vioConfig.outConfig.gammaCorrection.fGammaValueB = options->gamma[2];
233  l_vioConfig.fields |= NVVIOCONFIG_GAMMACORRECTION;
234 
235  // Set flip queue length
236  l_vioConfig.fields |= NVVIOCONFIG_FLIPQUEUELENGTH;
237  l_vioConfig.vioConfig.outConfig.flipQueueLength = options->flipQueueLength;
238 
239  // Set full color range
240  l_vioConfig.fields |= NVVIOCONFIG_FULL_COLOR_RANGE;
241  l_vioConfig.vioConfig.outConfig.enableFullColorRange = TRUE;
242 
243  // Set configuration.
244  l_ret = NvAPI_VIO_SetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig );
245  if ( l_ret != NVAPI_OK )
246  {
247  return E_FAIL;
248  }
249 
250  //
251  // Setup external sync here.
252  //
253  // Configure external sync parameters
254  if ( options->syncEnable )
255  {
256  NvU32 l_wait;
257  NVVIOSTATUS l_vioStatus;
258  l_vioConfig.fields = 0; // reset fields
259 
260  // Trigger redetection of sync format
261  if ( NvAPI_VIO_SyncFormatDetect( m_vioHandle, &l_wait ) != NVAPI_OK )
262  {
263  return E_FAIL;
264  }
265 
266  // Wait for sync detection to complete
267  Sleep( l_wait );
268 
269  // Get sync signal format
270  l_vioStatus.version = NVVIOSTATUS_VER;
271  if ( NvAPI_VIO_Status( m_vioHandle, &l_vioStatus ) != NVAPI_OK )
272  {
273  return E_FAIL;
274  }
275 
276  // Verify that incoming sync signal is compatible outgoing video signal
277  if ( !options->frameLock )
278  {
279  if ( l_vioStatus.vioStatus.outStatus.syncFormat !=
280  l_vioConfig.vioConfig.outConfig.signalFormat )
281  {
282  LOG_ERROR( "Incoming sync does not match outgoing video signal." );
283  return E_FAIL;
284  }
285  l_vioConfig.vioConfig.outConfig.frameLockEnable = FALSE;
286  l_vioConfig.fields |= NVVIOCONFIG_FRAMELOCKENABLE;
287  }
288  else // Framelock Case
289  {
290  NvU32 l_compatible;
291  if ( NvAPI_VIO_IsFrameLockModeCompatible( m_vioHandle,
292  l_vioStatus.vioStatus.outStatus.syncFormat,
293  l_vioConfig.vioConfig.outConfig.signalFormat,
294  &l_compatible ) != NVAPI_OK )
295  {
296  return E_FAIL;
297  }
298 
299  if ( l_compatible )
300  {
301  l_vioConfig.vioConfig.outConfig.frameLockEnable = TRUE;
302  l_vioConfig.fields |= NVVIOCONFIG_FRAMELOCKENABLE;
303  }
304  else
305  {
306  LOG_ERROR( "Incoming sync not compatible with outgoing video format." );
307  return E_FAIL;
308  }
309  }
310 
311  l_vioConfig.vioConfig.outConfig.syncEnable = l_vioStatus.vioStatus.outStatus.syncEnable;
312  l_vioConfig.vioConfig.outConfig.syncSource = l_vioStatus.vioStatus.outStatus.syncSource;
313 
314  switch( l_vioStatus.vioStatus.outStatus.syncSource )
315  {
316  case NVVIOSYNCSOURCE_SDISYNC:
317  l_vioConfig.fields |= NVVIOCONFIG_SYNCSOURCEENABLE;
318  break;
319  case NVVIOSYNCSOURCE_COMPSYNC:
320  l_vioConfig.vioConfig.outConfig.compositeSyncType = NVVIOCOMPSYNCTYPE_AUTO;
321  l_vioConfig.fields |= ( NVVIOCONFIG_SYNCSOURCEENABLE | NVVIOCONFIG_COMPOSITESYNCTYPE );
322  break;
323  } // switch
324 
325  // Sync delay
326  NVVIOSYNCDELAY l_vioSyncDelay;
327  memset( &l_vioSyncDelay, 0, sizeof( l_vioSyncDelay ) );
328  l_vioSyncDelay.version = NVVIOSYNCDELAY_VER;
329  l_vioSyncDelay.horizontalDelay = options->hDelay;
330  l_vioSyncDelay.verticalDelay = options->vDelay;
331  l_vioConfig.fields |= NVVIOCONFIG_SYNCDELAY;
332  l_vioConfig.vioConfig.outConfig.syncDelay = l_vioSyncDelay;
333 
334  // Setup external sync
335  if ( NvAPI_VIO_SetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig ) != NVAPI_OK )
336  {
337  return E_FAIL;
338  }
339  }
340 
341  // Get video configuration.
342  NVVIOSIGNALFORMATDETAIL l_vioSignalFormatDetail;
343  memset( &l_vioSignalFormatDetail, 0, sizeof( l_vioSignalFormatDetail ) );
344 
345  ULONG l_vioSignalFormatIndex = ( ULONG )NVVIOSIGNALFORMAT_NONE;
346 
347  // Enumerate all signal formats until we find the one we are looking
348  // for, the enumeration ends, or there is an error.
349  while( 1 )
350  {
351  l_ret = NvAPI_VIO_EnumSignalFormats( m_vioHandle,
352  l_vioSignalFormatIndex,
353  &l_vioSignalFormatDetail );
354  if ( l_ret == NVAPI_END_ENUMERATION || l_ret != NVAPI_OK )
355  {
356  return E_FAIL;
357  }
358 
359  // We found the signal format that we were looking for so break.
360  if ( l_vioSignalFormatDetail.signalFormat ==
361  l_vioConfig.vioConfig.outConfig.signalFormat )
362  {
363  break;
364  }
365 
366  l_vioSignalFormatIndex++;
367  }
368 
369  // Set frame rate. In the case of an interlaced signal format,
370  // divide by 2.0 to calculate the frame rate.
371  if ( l_vioSignalFormatDetail.videoMode.interlaceMode == NVVIOINTERLACEMODE_INTERLACE )
372  {
373  m_frameRate = l_vioSignalFormatDetail.videoMode.fFrameRate / 2.0f;
374  }
375  else
376  {
377  m_frameRate = l_vioSignalFormatDetail.videoMode.fFrameRate;
378  }
379 
380  // Set width and height
381  m_videoWidth = l_vioSignalFormatDetail.videoMode.horizontalPixels;
382  m_videoHeight = l_vioSignalFormatDetail.videoMode.verticalLines;
383 
384  // Set interlace flag.
385  if ( ( l_vioSignalFormatDetail.videoMode.interlaceMode == NVVIOINTERLACEMODE_INTERLACE ) ||
386  ( l_vioSignalFormatDetail.videoMode.interlaceMode == NVVIOINTERLACEMODE_PSF ) )
387  {
388  m_bInterlaced = TRUE;
389  }
390  else
391  {
392  m_bInterlaced = FALSE;
393  }
394 
395  return S_OK;
396 }
397 
398 //----------------------------------------------------------------------------
400 {
401  if ( NvAPI_VIO_Close( m_vioHandle, TRUE ) != NVAPI_OK )
402  {
403  return E_FAIL;
404  }
405 
406  m_vioHandle = NULL;
407 
408  return S_OK;
409 }
410 
411 //----------------------------------------------------------------------------
412 NvVioHandle CNvSDIout::GetHandle()
413 {
414  return m_vioHandle;
415 }
416 
417 //----------------------------------------------------------------------------
418 unsigned int CNvSDIout::GetWidth()
419 {
420  return m_videoWidth;
421 }
422 
423 //----------------------------------------------------------------------------
424 unsigned int CNvSDIout::GetHeight()
425 {
426  return m_videoHeight;
427 }
428 
429 //----------------------------------------------------------------------------
431 {
432  std::stringstream ss;
433 
434  // Get running state
435  ss << "NvAPI_VIO_IsRunning(): ";
436 
437  if ( NvAPI_VIO_IsRunning( m_vioHandle ) == NVAPI_DRIVER_RUNNING )
438  {
439  ss << "NVAPI_DRIVER_RUNNING";
440  }
441  else if ( NvAPI_VIO_IsRunning( m_vioHandle ) == NVAPI_DRIVER_NOTRUNNING )
442  {
443  ss << "NVAPI_DRIVER_NOTRUNNING";
444  }
445  else
446  {
447  ss << "undefined";
448  }
449 
450  // Query milliseconds to wait before getting incoming sync format
451  NvU32 l_wait;
452 
453  // Trigger redetection of sync format
454  if ( NvAPI_VIO_SyncFormatDetect( m_vioHandle, &l_wait ) != NVAPI_OK )
455  {
456  return E_FAIL;
457  }
458 
459  // Wait for sync detection to complete
460  Sleep( l_wait );
461 
462  // Get sync signal format
463  NVVIOSTATUS l_vioStatus;
464  l_vioStatus.version = NVVIOSTATUS_VER;
465  if ( NvAPI_VIO_Status( m_vioHandle, &l_vioStatus ) != NVAPI_OK )
466  {
467  return E_FAIL;
468  }
469 
470  ss << ". Video 1 Out: ";
471  switch( l_vioStatus.vioStatus.outStatus.vid1Out )
472  {
473  case NVINPUTOUTPUTSTATUS_OFF:
474  ss << "NVINPUTOUTPUTSTATUS_OFF";
475  break;
476  case NVINPUTOUTPUTSTATUS_ERROR:
477  ss << "NVINPUTOUTPUTSTATUS_ERROR";
478  break;
479  case NVINPUTOUTPUTSTATUS_SDI_SD:
480  ss << "NVINPUTOUTPUTSTATUS_SDI_SD";
481  break;
482  case NVINPUTOUTPUTSTATUS_SDI_HD:
483  ss << "NVINPUTOUTPUTSTATUS_SDI_HD";
484  break;
485  default:
486  ss << "undefined";
487  }
488 
489  ss << ". Video 2 Out: ";
490  switch( l_vioStatus.vioStatus.outStatus.vid2Out )
491  {
492  case NVINPUTOUTPUTSTATUS_OFF:
493  ss << "NVINPUTOUTPUTSTATUS_OFF";
494  break;
495  case NVINPUTOUTPUTSTATUS_ERROR:
496  ss << "NVINPUTOUTPUTSTATUS_ERROR";
497  break;
498  case NVINPUTOUTPUTSTATUS_SDI_SD:
499  ss << "NVINPUTOUTPUTSTATUS_SDI_SD";
500  break;
501  case NVINPUTOUTPUTSTATUS_SDI_HD:
502  ss << "NVINPUTOUTPUTSTATUS_SDI_HD";
503  break;
504  default:
505  ss << "undefined";
506  }
507 
508  if ( l_vioStatus.vioStatus.outStatus.syncEnable )
509  {
510  ss << ". Sync Source: ";
511  switch( l_vioStatus.vioStatus.outStatus.syncSource )
512  {
513  case NVVIOSYNCSOURCE_SDISYNC:
514  ss << "NVVIOSYNCSOURCE_SDISYNC";
515  break;
516  case NVVIOSYNCSOURCE_COMPSYNC:
517  ss << "NVVIOSYNCSOURCE_COMPSYNC";
518  break;
519  default:
520  ss << "undefined";
521  }
522 
523  ss << ". Sync Format: ";
524  switch( l_vioStatus.vioStatus.outStatus.syncFormat )
525  {
526  case NVVIOSIGNALFORMAT_NONE:
527  ss << "NVVIOSIGNALFORMAT_NONE";
528  break;
529  case NVVIOSIGNALFORMAT_487I_59_94_SMPTE259_NTSC:
530  ss << "NVVIOSIGNALFORMAT_487I_59_94_SMPTE259_NTSC";
531  break;
532  case NVVIOSIGNALFORMAT_576I_50_00_SMPTE259_PAL:
533  ss << "NVVIOSIGNALFORMAT_576I_50_00_SMPTE259_PAL";
534  break;
535  case NVVIOSIGNALFORMAT_720P_59_94_SMPTE296:
536  ss << "NVVIOSIGNALFORMAT_720P_59_94_SMPTE296";
537  break;
538  case NVVIOSIGNALFORMAT_720P_60_00_SMPTE296:
539  ss << "NVVIOSIGNALFORMAT_720P_60_00_SMPTE296";
540  break;
541  case NVVIOSIGNALFORMAT_1035I_59_94_SMPTE260:
542  ss << "NVVIOSIGNALFORMAT_1035I_59_94_SMPTE26";
543  break;
544  case NVVIOSIGNALFORMAT_1035I_60_00_SMPTE260:
545  ss << "NVVIOSIGNALFORMAT_1035I_60_00_SMPTE260";
546  break;
547  case NVVIOSIGNALFORMAT_1080I_50_00_SMPTE295:
548  ss << "NVVIOSIGNALFORMAT_1080I_50_00_SMPTE295";
549  break;
550  case NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274:
551  ss << "NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274";
552  break;
553  case NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274:
554  ss << "NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274";
555  break;
556  case NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274:
557  ss << "NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274";
558  break;
559  case NVVIOSIGNALFORMAT_1080PSF_23_98_SMPTE274:
560  ss << "NVVIOSIGNALFORMAT_1080PSF_23_98_SMPTE274";
561  break;
562  case NVVIOSIGNALFORMAT_1080PSF_24_00_SMPTE274:
563  ss << "NVVIOSIGNALFORMAT_1080PSF_24_00_SMPTE274";
564  break;
565  case NVVIOSIGNALFORMAT_1080PSF_25_00_SMPTE274:
566  ss << "NVVIOSIGNALFORMAT_1080PSF_25_00_SMPTE274";
567  break;
568  case NVVIOSIGNALFORMAT_1080P_23_976_SMPTE274:
569  ss << "NVVIOSIGNALFORMAT_1080P_23_976_SMPTE274";
570  break;
571  case NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274:
572  ss << "NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274";
573  break;
574  case NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274:
575  ss << "NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274";
576  break;
577  case NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274:
578  ss << "NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274";
579  break;
580  case NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274:
581  ss << "NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274";
582  break;
583  default:
584  ss << "undefined";
585  }
586 
587  ss << ". Composite Sync In: ";
588  switch( l_vioStatus.vioStatus.outStatus.compSyncIn )
589  {
590  case NVVIOSYNCSTATUS_OFF:
591  ss << "NVVIOSYNCSTATUS_OFF";
592  break;
593  case NVVIOSYNCSTATUS_ERROR:
594  ss << "NVVIOSYNCSTATUS_ERROR";
595  break;
596  case NVVIOSYNCSTATUS_SYNCLOSS:
597  ss << "NVVIOSYNCSTATUS_SYNCLOSS";
598  break;
599  case NVVIOSYNCSTATUS_COMPOSITE:
600  ss << "NVVIOSYNCSTATUS_COMPOSITE";
601  break;
602  case NVVIOSYNCSTATUS_SDI_SD:
603  ss << "NVVIOSYNCSTATUS_SDI_SD";
604  break;
605  case NVVIOSYNCSTATUS_SDI_HD:
606  ss << "NVVIOSYNCSTATUS_SDI_HD";
607  break;
608  }
609 
610  ss << ". SDI Sync In: ";
611  switch( l_vioStatus.vioStatus.outStatus.sdiSyncIn )
612  {
613  case NVVIOSYNCSTATUS_OFF:
614  ss << "NVVIOSYNCSTATUS_OFF";
615  break;
616  case NVVIOSYNCSTATUS_ERROR:
617  ss << "NVVIOSYNCSTATUS_ERROR";
618  break;
619  case NVVIOSYNCSTATUS_SYNCLOSS:
620  ss << "NVVIOSYNCSTATUS_SYNCLOSS";
621  break;
622  case NVVIOSYNCSTATUS_COMPOSITE:
623  ss << "NVVIOSYNCSTATUS_COMPOSITE";
624  break;
625  case NVVIOSYNCSTATUS_SDI_SD:
626  ss << "NVVIOSYNCSTATUS_SDI_SD";
627  break;
628  case NVVIOSYNCSTATUS_SDI_HD:
629  ss << "NVVIOSYNCSTATUS_SDI_HD";
630  break;
631  }
632  }
633  else
634  {
635  ss << ". Sync Source: Disabled";
636  }
637 
638  if ( l_vioStatus.vioStatus.outStatus.frameLockEnable )
639  {
640  ss << ". Framelock: Enabled";
641  }
642  else
643  {
644  ss << ". Framelock: Disabled";
645  }
646 
647  if ( l_vioStatus.vioStatus.outStatus.outputVideoLocked )
648  {
649  ss << ". Output Video: Locked";
650  }
651  else
652  {
653  ss << ". Output Video: Not Locked";
654  }
655 
656  LOG_INFO( ss.str() );
657 
658  return S_OK;
659 }
660 
661 //----------------------------------------------------------------------------
663 {
664  // Get signal format from GVO config.
665  NVVIOCONFIG_V1 l_vioConfig;
666  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
667  l_vioConfig.version = NVVIOCONFIG_VER1;
668  l_vioConfig.fields = NVVIOCONFIG_SIGNALFORMAT;
669  if ( NvAPI_VIO_GetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig ) != NVAPI_OK )
670  {
671  LOG_ERROR( "Unable to get video config." );
672  return E_FAIL;
673  }
674 
675  // Get signal format detail.
676  NVVIOSIGNALFORMATDETAIL l_vioSignalFormatDetail;
677  memset( &l_vioSignalFormatDetail, 0, sizeof( l_vioSignalFormatDetail ) );
678 
679  ULONG l_vioSignalFormatIndex = ( ULONG )NVVIOSIGNALFORMAT_NONE;
680 
681  // Enumerate all signal formats until we find the one we are looking
682  // for, the enumeration ends, or there is an error.
683  NvAPI_Status l_ret;
684  while( 1 )
685  {
686  l_ret = NvAPI_VIO_EnumSignalFormats( m_vioHandle,
687  l_vioSignalFormatIndex,
688  &l_vioSignalFormatDetail );
689  if ( l_ret == NVAPI_END_ENUMERATION || l_ret != NVAPI_OK )
690  {
691  return E_FAIL;
692  } // if
693 
694  // We found the signal format that we were looking for so break.
695  if ( l_vioSignalFormatDetail.signalFormat ==
696  l_vioConfig.vioConfig.outConfig.signalFormat )
697  {
698  break;
699  } // if
700 
701  l_vioSignalFormatIndex++;
702  } // while
703 
704  std::stringstream ss;
705  ss << SignalFormatToString( l_vioConfig.vioConfig.outConfig.signalFormat ).c_str();
706  ss << ". Horizontal Pixels = " << l_vioSignalFormatDetail.videoMode.horizontalPixels;
707  ss << ". Vertical Lines = " << l_vioSignalFormatDetail.videoMode.verticalLines;
708  ss << ". Frame Rate = " << l_vioSignalFormatDetail.videoMode.fFrameRate;
709 
710  switch ( l_vioSignalFormatDetail.videoMode.interlaceMode )
711  {
712  case NVVIOINTERLACEMODE_PROGRESSIVE:
713  ss << ". Interlace mode: Progressive";
714  break;
715 
716  case NVVIOINTERLACEMODE_INTERLACE:
717  ss << ". Interlace mode: Interlace";
718  break;
719 
720  case NVVIOINTERLACEMODE_PSF:
721  ss << ". Interlace mode: Progressive Segment Frame";
722  break;
723  }
724 
725  switch ( l_vioSignalFormatDetail.videoMode.videoStandard )
726  {
727  case NVVIOVIDEOSTANDARD_SMPTE259:
728  ss << ". Video standard: SMPTE259";
729  break;
730 
731  case NVVIOVIDEOSTANDARD_SMPTE260:
732  ss << ". Video standard: SMPTE260";
733  break;
734 
735  case NVVIOVIDEOSTANDARD_SMPTE274:
736  ss << ". Video standard: SMPTE274";
737  break;
738 
739  case NVVIOVIDEOSTANDARD_SMPTE295:
740  ss << ". Video standard: SMPTE295";
741  break;
742 
743  case NVVIOVIDEOSTANDARD_SMPTE296:
744  ss << ". Video standard: SMPTE296";
745  break;
746 
747  case NVVIOVIDEOSTANDARD_SMPTE372:
748  ss << ". Video standard: SMPTE372";
749  break;
750  }
751 
752  switch ( l_vioSignalFormatDetail.videoMode.videoType )
753  {
754  case NVVIOVIDEOTYPE_HD:
755  ss << ". Video type: High-Definition";
756  break;
757 
758  case NVVIOVIDEOTYPE_SD:
759  ss << ". Video type: Standard-Definition";
760  break;
761  }
762 
763  LOG_INFO( ss.str() );
764 
765  return S_OK;
766 }
767 
768 //----------------------------------------------------------------------------
770 {
771  // Get data format from GVO config.
772  NVVIOCONFIG_V1 l_vioConfig;
773  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
774  l_vioConfig.version = NVVIOCONFIG_VER1;
775  l_vioConfig.fields = NVVIOCONFIG_ALLFIELDS; //NVVIOCONFIG_DATAFORMAT;
776  if ( NvAPI_VIO_GetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig ) != NVAPI_OK )
777  {
778  LOG_ERROR( "Unable to get video config." );
779  return E_FAIL;
780  }
781 
782  // Get data format detail.
783  NVVIODATAFORMATDETAIL l_dataFormatDetail;
784  if ( NvAPI_VIO_EnumDataFormats( m_vioHandle,
785  l_vioConfig.vioConfig.outConfig.dataFormat,
786  &l_dataFormatDetail ) != NVAPI_OK )
787  {
788  LOG_ERROR( "Unable to enum video data formats." );
789  return E_FAIL;
790  }
791 
792  std::stringstream ss;
793  if ( l_dataFormatDetail.vioCaps != 0 )
794  {
795  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_VIDOUT_SDI )
796  {
797  ss << "VIDOUT_SDI" << std::endl;
798  }
799  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_OUTPUTMODE_DESKTOP )
800  {
801  ss << "OUTPUTMODE_DESKTOP" << std::endl;
802  }
803  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_OUTPUTMODE_OPENGL )
804  {
805  ss << "OUTPUTMODE_OPENGL" << std::endl;
806  }
807  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_SYNC_INTERNAL )
808  {
809  ss << "SYNC_INTERNAL" << std::endl;
810  }
811  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_SYNC_GENLOCK )
812  {
813  ss << "SYNC_GENLOCK" << std::endl;
814  }
815  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_SYNCSRC_SDI )
816  {
817  ss << "SYNCSRC_SDI" << std::endl;
818  }
819  if ( l_dataFormatDetail.vioCaps & NVVIOCAPS_SYNCSRC_COMP )
820  {
821  ss << "SYNCSRC_COMP" << std::endl;
822  }
823  }
824 
825  ss << DataFormatToString( l_dataFormatDetail.dataFormat ).c_str();
826 
827  LOG_INFO( ss.str() );
828 
829  return S_OK;
830 }
831 
832 //----------------------------------------------------------------------------
833 HRESULT CNvSDIout::GetFrameRate( float* rate )
834 {
835  *rate = 0.0f;
836 
837  // Get signal format from GVO config.
838  NVVIOCONFIG_V1 l_vioConfig;
839  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
840  l_vioConfig.version = NVVIOCONFIG_VER1;
841  l_vioConfig.fields = NVVIOCONFIG_SIGNALFORMAT;
842  if ( NvAPI_VIO_GetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig ) != NVAPI_OK )
843  {
844  LOG_ERROR( "Unable to get video config." );
845  return E_FAIL;
846  }
847 
848  // Enumerate all signal formats until we find the one we are looking
849  // for, the enumeration ends, or there is an error.
850  NVVIOSIGNALFORMATDETAIL l_vioSignalFormatDetail;
851  memset( &l_vioSignalFormatDetail, 0, sizeof( l_vioSignalFormatDetail ) );
852 
853  ULONG l_vioSignalFormatIndex = ( ULONG )NVVIOSIGNALFORMAT_NONE;
854 
855  while( 1 )
856  {
857  NvAPI_Status l_ret = NVAPI_OK;
858  l_ret = NvAPI_VIO_EnumSignalFormats( m_vioHandle,
859  l_vioSignalFormatIndex,
860  &l_vioSignalFormatDetail );
861  if ( l_ret == NVAPI_END_ENUMERATION || l_ret != NVAPI_OK )
862  {
863  return E_FAIL;
864  }
865 
866  // We found the signal format that we were looking for so break.
867  if ( l_vioSignalFormatDetail.signalFormat ==
868  l_vioConfig.vioConfig.outConfig.signalFormat )
869  {
870  break;
871  }
872 
873  l_vioSignalFormatIndex++;
874  }
875 
876  // Set rate
877  *rate = l_vioSignalFormatDetail.videoMode.fFrameRate;
878 
879  return S_OK;
880 }
881 
882 //----------------------------------------------------------------------------
884 {
885  return m_frameRate;
886 }
887 
888 //----------------------------------------------------------------------------
890 {
891  return m_bInterlaced;
892 }
893 
894 //----------------------------------------------------------------------------
895 HRESULT CNvSDIout::SetCSC( NVVIOCOLORCONVERSION* csc, bool enable )
896 {
897  NVVIOCONFIG_V1 l_vioConfig;
898  NvAPI_Status l_ret;
899 
900  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
901  l_vioConfig.version = NVVIOCONFIG_VER1;
902 
903  l_vioConfig.fields = NVVIOCONFIG_CSCOVERRIDE;
904 
905  // If not enabled, simply set as disabled.
906  // Otherwise, enable and set values.
907  if ( !enable )
908  {
909  l_vioConfig.vioConfig.outConfig.cscOverride = FALSE;
910  }
911  else
912  {
913  l_vioConfig.vioConfig.outConfig.cscOverride = TRUE;
914 
915  l_vioConfig.fields |= NVVIOCONFIG_COLORCONVERSION;
916 
917  // Offset
918  l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[0] = csc->colorOffset[0];
919  l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[1] = csc->colorOffset[1];
920  l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[2] = csc->colorOffset[2];
921 
922  // Scale
923  l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[0] = csc->colorScale[0];
924  l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[1] = csc->colorScale[1];
925  l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[2] = csc->colorScale[2];
926  l_vioConfig.vioConfig.outConfig.colorConversion.compositeSafe = TRUE;
927 
928  // Matrix
929  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][0] = csc->colorMatrix[0][0];
930  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][1] = csc->colorMatrix[0][1];
931  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][2] = csc->colorMatrix[0][2];
932  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][0] = csc->colorMatrix[1][0];
933  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][1] = csc->colorMatrix[1][1];
934  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][2] = csc->colorMatrix[1][2];
935  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][0] = csc->colorMatrix[2][0];
936  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][1] = csc->colorMatrix[2][1];
937  l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][2] = csc->colorMatrix[2][2];
938  }
939 
940  // Set configuration.
941  l_ret = NvAPI_VIO_SetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig );
942  if ( l_ret != NVAPI_OK )
943  {
944  // Display NVAPI error.
945  NvAPI_ShortString l_desc;
946  NvAPI_GetErrorMessage( l_ret, l_desc );
947  LOG_ERROR( l_desc );
948 
949  return E_FAIL;
950  }
951 
952  return S_OK;
953 }
954 
955 //----------------------------------------------------------------------------
956 HRESULT CNvSDIout::GetCSC( NVVIOCOLORCONVERSION* csc, bool* enable )
957 {
958  NVVIOCONFIG_V1 l_vioConfig;
959  NvAPI_Status l_ret;
960 
961  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
962  l_vioConfig.version = NVVIOCONFIG_VER1;
963  l_vioConfig.fields = NVVIOCONFIG_COLORCONVERSION | NVVIOCONFIG_CSCOVERRIDE;
964 
965  // Get configuration.
966  l_ret = NvAPI_VIO_GetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig );
967  if ( l_ret != NVAPI_OK )
968  {
969  return E_FAIL;
970  }
971 
972  // Enable / disable state
973  *enable = l_vioConfig.vioConfig.outConfig.cscOverride;
974 
975  // Offset
976  csc->colorOffset[0] = l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[0];
977  csc->colorOffset[1] = l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[1];
978  csc->colorOffset[2] = l_vioConfig.vioConfig.outConfig.colorConversion.colorOffset[2];
979 
980  // Scale
981  csc->colorScale[0] = l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[0];
982  csc->colorScale[1] = l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[1];
983  csc->colorScale[2] = l_vioConfig.vioConfig.outConfig.colorConversion.colorScale[2];
984 
985  // Composite safe?
986  csc->compositeSafe = l_vioConfig.vioConfig.outConfig.colorConversion.compositeSafe;
987 
988  // Matrix
989  csc->colorMatrix[0][0] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][0];
990  csc->colorMatrix[0][1] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][1];
991  csc->colorMatrix[0][2] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[0][2];
992  csc->colorMatrix[1][0] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][0];
993  csc->colorMatrix[1][1] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][1];
994  csc->colorMatrix[1][2] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[1][2];
995  csc->colorMatrix[2][0] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][0];
996  csc->colorMatrix[2][1] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][1];
997  csc->colorMatrix[2][2] = l_vioConfig.vioConfig.outConfig.colorConversion.colorMatrix[2][2];
998 
999  return S_OK;
1000 }
1001 
1002 //----------------------------------------------------------------------------
1003 HRESULT CNvSDIout::SetSyncDelay( NVVIOSYNCDELAY* delay )
1004 {
1005  NVVIOCONFIG_V1 l_vioConfig;
1006  NvAPI_Status l_ret;
1007 
1008  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
1009  l_vioConfig.version = NVVIOCONFIG_VER1;
1010  l_vioConfig.fields = NVVIOCONFIG_SYNCDELAY;
1011 
1012  // Set delay
1013  l_vioConfig.vioConfig.outConfig.syncDelay.version = delay->version;
1014  l_vioConfig.vioConfig.outConfig.syncDelay.horizontalDelay = delay->horizontalDelay;
1015  l_vioConfig.vioConfig.outConfig.syncDelay.verticalDelay = delay->verticalDelay;
1016 
1017  // Set configuration.
1018  l_ret = NvAPI_VIO_SetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig );
1019  if ( l_ret != NVAPI_OK )
1020  {
1021  return E_FAIL;
1022  }
1023 
1024  return S_OK;
1025 }
1026 
1027 //----------------------------------------------------------------------------
1028 HRESULT CNvSDIout::GetSyncDelay( NVVIOSYNCDELAY* delay )
1029 {
1030  NVVIOCONFIG_V1 l_vioConfig;
1031  NvAPI_Status l_ret;
1032 
1033  memset( &l_vioConfig, 0, sizeof( l_vioConfig ) );
1034  l_vioConfig.version = NVVIOCONFIG_VER1;
1035  l_vioConfig.fields = NVVIOCONFIG_SYNCDELAY;
1036 
1037  // Get configuration.
1038  l_ret = NvAPI_VIO_GetConfig( m_vioHandle, ( NVVIOCONFIG* )&l_vioConfig );
1039  if ( l_ret != NVAPI_OK )
1040  {
1041  return E_FAIL;
1042  }
1043 
1044  // Get delay
1045  delay->version = l_vioConfig.vioConfig.outConfig.syncDelay.version;
1046  delay->horizontalDelay = l_vioConfig.vioConfig.outConfig.syncDelay.horizontalDelay;
1047  delay->verticalDelay = l_vioConfig.vioConfig.outConfig.syncDelay.verticalDelay;
1048 
1049  return S_OK;
1050 }
1051 
1052 //----------------------------------------------------------------------------
1054 {
1055  m_bInitialized = false;
1056  m_nGpu = 0;
1057  if( Init() )
1058  {
1059  m_bInitialized = true;
1060  }
1061 }
1062 
1063 //----------------------------------------------------------------------------
1065 {
1066  if( m_bInitialized == false )
1067  {
1068  return;
1069  }
1070  for( int i = 0; i < m_nGpu; i++ )
1071  {
1072  delete dynamic_cast<CNvSDIoutGpu*>( m_lGpu[i] );
1073  m_lGpu[i] = NULL;
1074  }
1075 }
1076 
1077 //----------------------------------------------------------------------------
1079 {
1080  if( m_bInitialized )
1081  {
1082  return true;
1083  }
1084 
1085 #if WIN32
1086  HWND hWnd;
1087  HGLRC hGLRC;
1088  if( CreateDummyGLWindowWin32( &hWnd, &hGLRC ) == false )
1089  {
1090  return false;
1091  }
1092 #elif __linux__
1093 
1094 #endif
1095 
1096  if( !loadAffinityExtension() )
1097  {
1098  LOG_ERROR( "Could not load OpenGL Affinity extension" );
1099  return false;
1100  }
1101 
1102  // Query available VIO topologies.
1103  // Initialize NVAPI
1104  if ( NvAPI_Initialize() != NVAPI_OK )
1105  {
1106  return false;
1107  }
1108  // Fail if there are no VIO topologies or devices available.
1109  NVVIOTOPOLOGY l_vioTopologies;
1110  memset( &l_vioTopologies, 0, sizeof( l_vioTopologies ) );
1111  l_vioTopologies.version = NVVIOTOPOLOGY_VER;
1112 
1113  if ( NvAPI_VIO_QueryTopology( &l_vioTopologies ) != NVAPI_OK )
1114  {
1115  return false;
1116  }
1117 
1118  if ( l_vioTopologies.vioTotalDeviceCount == 0 )
1119  {
1120  return false;
1121  }
1122 
1123  LOG_INFO( "Listing GPUs available for OpenGL GPU Affinity" );
1124 
1125  unsigned int GPUIdx = 0;
1126 
1127  GPU_DEVICE gpuDevice;
1128  gpuDevice.cb = sizeof( gpuDevice );
1129  HGPUNV hGPU;
1130  bool bDisplay;
1131  bool bPrimary;
1132  bool bSDIoutput;
1133  NvVioHandle hVioHandle;
1134  while( wglEnumGpusNV( GPUIdx, &hGPU ) ) // First call this function to get a handle to the gpu
1135  {
1136  // wglEnumPGUsNV will fails if DeviceIdx > the available devices
1137  LOG_DEBUG( "GPU# " << GPUIdx << ":" );
1138  bDisplay = false;
1139  bPrimary = false;
1140  bSDIoutput = false;
1141  hVioHandle = NULL;
1142 
1143  // Now get the detailed information about this device:
1144  // How many displays it's attached to and whether any of them
1145  int DisplayDeviceIdx = 0;
1146  while( wglEnumGpuDevicesNV( hGPU, DisplayDeviceIdx, &gpuDevice ) )
1147  {
1148  LOG_DEBUG( " Display# " << DisplayDeviceIdx );
1149  LOG_DEBUG( " Name: " << gpuDevice.DeviceName );
1150  LOG_DEBUG( " String: " << gpuDevice.DeviceString );
1151 
1152  bDisplay = true;
1153 
1154  if ( gpuDevice.Flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP )
1155  {
1156  LOG_DEBUG( " Attached to the desktop: LEFT=" << gpuDevice.rcVirtualScreen.left << ", RIGHT=" << gpuDevice.rcVirtualScreen.right
1157  << ", TOP=" << gpuDevice.rcVirtualScreen.top << ", BOTTOM=" << gpuDevice.rcVirtualScreen.bottom );
1158  }
1159  else
1160  {
1161  LOG_DEBUG( " Not attached to the desktop." );
1162  }
1163 
1164  // See if it's the primary GPU
1165  if ( gpuDevice.Flags & DISPLAY_DEVICE_PRIMARY_DEVICE )
1166  {
1167  LOG_DEBUG( " This is the PRIMARY Display Device." );
1168  bPrimary = true;
1169  }
1170  DisplayDeviceIdx++;
1171 
1172  NvDisplayHandle hNvDisplay;
1173  NvAPI_Status status;
1174  status = NvAPI_GetAssociatedNvidiaDisplayHandle( gpuDevice.DeviceName, &hNvDisplay );
1175  if( status != NVAPI_OK )
1176  {
1177  break;
1178  }
1179 
1180  NvU32 count = 0;
1181  NvPhysicalGpuHandle hNvPhysicalGPU;
1182  status = NvAPI_GetPhysicalGPUsFromDisplay( hNvDisplay, &hNvPhysicalGPU, &count );
1183  if( status != NVAPI_OK )
1184  {
1185  break;
1186  }
1187 
1188  // Cycle through all SDI topologies looking for the first
1189  // available SDI output device topology.
1190  BOOL l_bFound = FALSE;
1191  unsigned int i = 0;
1192  NVVIOCAPS l_vioCaps;
1193  while ( ( i < l_vioTopologies.vioTotalDeviceCount ) && ( !l_bFound ) )
1194  {
1195  if( l_vioTopologies.vioTarget[i].hPhysicalGpu == hNvPhysicalGPU )
1196  {
1197  // Get video I/O capabilities for current video I/O target.
1198  memset( &l_vioCaps, 0, sizeof( l_vioCaps ) );
1199  l_vioCaps.version = NVVIOCAPS_VER;
1200  if ( NvAPI_VIO_GetCapabilities( l_vioTopologies.vioTarget[i].hVioHandle,
1201  &l_vioCaps ) != NVAPI_OK )
1202  {
1203  continue;
1204  }
1205 
1206  // If video output device found, save VIO handle and set flag.
1207  if ( l_vioCaps.adapterCaps & NVVIOCAPS_VIDOUT_SDI )
1208  {
1209  bSDIoutput = true;
1210  hVioHandle = l_vioTopologies.vioTarget[i].hVioHandle;
1211  l_bFound = TRUE;
1212  }
1213  else
1214  {
1215  i++;
1216  }
1217  }
1218  else
1219  {
1220  i++;
1221  }
1222  }
1223 
1224  if( l_bFound )
1225  {
1226  LOG_DEBUG( " SDI out: yes" );
1227  }
1228  else
1229  {
1230  LOG_DEBUG( " SDI out: no" );
1231  }
1232  if( gpuDevice.Flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP )
1233  {
1234  LOG_DEBUG( " Attached to the desktop: LEFT=" << gpuDevice.rcVirtualScreen.left << ", RIGHT=" << gpuDevice.rcVirtualScreen.right
1235  << ", TOP=" << gpuDevice.rcVirtualScreen.top << ", BOTTOM=" << gpuDevice.rcVirtualScreen.bottom );
1236  }
1237  else
1238  {
1239  LOG_DEBUG( " Not attached to the desktop." );
1240  }
1241  }
1242  CNvSDIoutGpu* gpu = new CNvSDIoutGpu();
1243  gpu->Init( hGPU, bPrimary, bDisplay, bSDIoutput, hVioHandle );
1244 
1245  m_lGpu[GPUIdx] = gpu;
1246 
1247  GPUIdx++;
1248  }
1249 
1250  m_nGpu = GPUIdx;
1251  m_bInitialized = true;
1252 #if WIN32
1253  // We can kill the dummy window now
1254  if( DestroyGLWindowWin32( &hWnd, &hGLRC ) == false )
1255  {
1256  return false;
1257  }
1258 #elif __linux__
1259 
1260 #endif
1261 
1262  return true;
1263 }
1264 
1265 //----------------------------------------------------------------------------
1267 {
1268  static CNvSDIoutGpuTopology instance;
1269  instance.Init();
1270  return instance;
1271 }
1272 
1273 //----------------------------------------------------------------------------
1275 {
1276  if( index >= 0 && index < m_nGpu )
1277  {
1278  return dynamic_cast<CNvSDIoutGpu*>( m_lGpu[index] );
1279  }
1280  return NULL;
1281 }
1282 
1283 //----------------------------------------------------------------------------
1285 {
1286  for( int i = 0; i < m_nGpu; i++ )
1287  {
1288  if( m_lGpu[i]->isPrimary() )
1289  {
1290  return dynamic_cast<CNvSDIoutGpu*>( m_lGpu[i] );
1291  }
1292  }
1293  return NULL;
1294 }
1295 
1296 //----------------------------------------------------------------------------
1298 {
1299 
1300 }
1301 
1302 //----------------------------------------------------------------------------
1304 {
1305 
1306 }
1307 
1308 //----------------------------------------------------------------------------
1309 bool CNvSDIoutGpu::Init( HGPUNV gpuAffinityHandle, bool bPrimary, bool bDisplay, bool bSDIoutput, NvVioHandle hVioHandle )
1310 {
1311  CNvGpu::Init( gpuAffinityHandle, bPrimary, bDisplay );
1312  m_bSDIoutput = bSDIoutput;
1313  m_hVioHandle = hVioHandle;
1314  return true;
1315 }
1316 
1317 //----------------------------------------------------------------------------
1319 {
1320  return m_bSDIoutput;
1321 }
1322 
1323 //----------------------------------------------------------------------------
1325 {
1326  return m_hVioHandle;
1327 }
int hDelay
Definition: nvCommon.h:81
PFNWGLENUMGPUSNVPROC wglEnumGpusNV
BOOL IsInterlaced()
Definition: nvSDIout.cpp:889
HRESULT DisplaySignalFormatInfo()
Definition: nvSDIout.cpp:662
~CNvSDIout()
Definition: nvSDIout.cpp:53
double cscScale[3]
Definition: nvCommon.h:89
NVVIODATAFORMAT dataFormat
Definition: nvCommon.h:68
float gamma[3]
Definition: nvCommon.h:91
NVVIOSYNCSOURCE syncSource
Definition: nvCommon.h:70
virtual CNvSDIoutGpu * GetGpu(int index)
Definition: nvSDIout.cpp:1274
std::string DataFormatToString(NVVIODATAFORMAT format)
Definition: nvSDIutil.cpp:316
CNvSDIoutGpu CNvSDIoutGpu
virtual ~CNvSDIoutGpu()
Definition: nvSDIout.cpp:1303
float cscMatrix[3][3]
Definition: nvCommon.h:90
for i
bool frameLock
Definition: nvCommon.h:73
bool m_bSDIoutput
Definition: nvSDIout.h:69
bool cscEnable
Definition: nvCommon.h:87
#define FALSE
Definition: ATC3DGm.h:220
CNvGpu * m_lGpu[MAX_GPUS]
Definition: nvGPUutil.h:91
HRESULT SetCSC(NVVIOCOLORCONVERSION *csc, bool enable)
Definition: nvSDIout.cpp:895
bool Init(HGPUNV gpuAffinityHandle, bool bPrimary, bool bDisplay, bool bSDIOutput, NvVioHandle hVioHandle)
Definition: nvSDIout.cpp:1309
NvVioHandle GetHandle()
Definition: nvSDIout.cpp:412
float GetFrameRate()
Definition: nvSDIout.cpp:883
bool m_bInitialized
Definition: nvGPUutil.h:93
HRESULT GetCSC(NVVIOCOLORCONVERSION *csc, bool *enable)
Definition: nvSDIout.cpp:956
int flipQueueLength
Definition: nvCommon.h:83
unsigned int GetWidth()
Definition: nvSDIout.cpp:418
bool Init(HGPUNV gpuAffinityHandle, bool bPrimary, bool bDisplay)
Definition: nvGPUutil.cpp:319
NvVioHandle m_hVioHandle
Definition: nvSDIout.h:70
NVVIOSIGNALFORMAT videoFormat
Definition: nvCommon.h:67
unsigned long ULONG
Definition: ATC3DGm.h:432
Phidget_ChannelClass uint32_t * count
Definition: phidget22.h:1321
PFNWGLENUMGPUDEVICESNVPROC wglEnumGpuDevicesNV
bool syncEnable
Definition: nvCommon.h:72
HRESULT DisplayDataFormatInfo()
Definition: nvSDIout.cpp:769
static CNvSDIoutGpuTopology & Instance()
Definition: nvSDIout.cpp:1266
bool IsSDIoutput()
Definition: nvSDIout.cpp:1318
eTestPattern testPattern
Definition: nvCommon.h:71
virtual ~CNvSDIoutGpuTopology()
Definition: nvSDIout.cpp:1064
NvVioHandle GetVioHandle()
Definition: nvSDIout.cpp:1324
#define TRUE
Definition: ATC3DGm.h:219
std::string SignalFormatToString(NVVIOSIGNALFORMAT format)
Definition: nvSDIutil.cpp:42
HRESULT Cleanup()
Definition: nvSDIout.cpp:399
bool loadAffinityExtension()
HRESULT SetSyncDelay(NVVIOSYNCDELAY *delay)
Definition: nvSDIout.cpp:1003
HRESULT DisplayVideoStatus()
Definition: nvSDIout.cpp:430
HRESULT GetSyncDelay(NVVIOSYNCDELAY *delay)
Definition: nvSDIout.cpp:1028
int BOOL
Definition: ATC3DGm.h:446
HRESULT Init(nvOptions *options, CNvSDIoutGpu *SdiOutGpu=NULL)
Definition: nvSDIout.cpp:58
virtual CNvSDIoutGpu * GetPrimaryGpu()
Definition: nvSDIout.cpp:1284
int vDelay
Definition: nvCommon.h:82
double cscOffset[3]
Definition: nvCommon.h:88
unsigned int GetHeight()
Definition: nvSDIout.cpp:424