PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusDeckLinkVideoSource.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 
9 // Local includes
10 #include "PlusOutputVideoFrame.h"
11 #include "vtkIGSIOAccurateTimer.h"
12 #include "vtkPlusDataSource.h"
14 #include <PixelCodec.h>
15 
16 // VTK includes
17 #include <vtkImageAppendComponents.h>
18 #include <vtkImageExtractComponents.h>
19 #include <vtkImageImport.h>
20 #include <vtkObject.h>
21 
22 // System includes
23 #include <string>
24 
25 // DeckLink SDK includes
26 #include "DeckLinkAPIWrapper.h"
27 
28 //----------------------------------------------------------------------------
29 // vtkPlusDeckLinkVideoSource::vtkInternal
30 //----------------------------------------------------------------------------
31 
32 class vtkPlusDeckLinkVideoSource::vtkInternal : public vtkObject
33 {
34 public:
35  static vtkPlusDeckLinkVideoSource::vtkInternal* New(vtkPlusDeckLinkVideoSource*);
36  vtkTypeMacro(vtkInternal, vtkObject);
37 
38 public:
40 
41  vtkInternal(vtkPlusDeckLinkVideoSource* external)
42  : External(external) {}
43 
44  virtual ~vtkInternal() {}
45 
46  int DeviceIndex = -1;
47  bool PreviousFrameValid = false;
48  std::string DeviceName = "";
49  FrameSizeType RequestedFrameSize = { 1920, 1080, 1 };
50  BMDPixelFormat RequestedPixelFormat = bmdFormatUnspecified;
51  BMDVideoConnection RequestedVideoConnection = bmdVideoConnectionUnspecified;
52  BMDDisplayMode RequestedDisplayMode = bmdModeUnknown;
53 
54  IDeckLink* DeckLink = nullptr;
55  IDeckLinkInput* DeckLinkInput = nullptr;
56  IDeckLinkDisplayMode* DeckLinkDisplayMode = nullptr;
57  IDeckLinkVideoConversion* DeckLinkVideoConversion = nullptr;
58 
59  PlusOutputVideoFrame* OutputFrame = nullptr;
60 
61  unsigned char* RGBBytes = nullptr;
62  unsigned char* GrayBytes = nullptr;
63 
64  std::atomic_bool COMInitialized = false;
65 
66 private:
67  static vtkPlusDeckLinkVideoSource::vtkInternal* New();
68  vtkInternal() : External(nullptr) {}
69 };
70 
71 namespace
72 {
73  //----------------------------------------------------------------------------
74  bool AreSame(double a, double b)
75  {
76  return std::abs(a - b) < 0.0001;
77  }
78 
79  //----------------------------------------------------------------------------
80  bool InitCOM(std::atomic_bool& comInit)
81  {
82 #if WIN32
83  if (!comInit)
84  {
85  // Initialize COM on this thread
86  HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
87  if (FAILED(result))
88  {
89  LOG_ERROR("Initialization of COM failed - result = " << std::hex << std::setw(8) << std::setfill('0') << result);
90  return false;
91  }
92  comInit = true;
93  }
94 #endif
95  return true;
96  }
97 
98  //----------------------------------------------------------------------------
99  void ShutdownCOM(std::atomic_bool& comInit)
100  {
101  if (comInit)
102  {
103  CoUninitialize();
104  comInit = false;
105  }
106  }
107 }
108 //----------------------------------------------------------------------------
109 // vtkPlusDeckLinkVideoSource
110 //----------------------------------------------------------------------------
111 
113 vtkStandardNewMacro(vtkPlusDeckLinkVideoSource::vtkInternal);
114 
115 //----------------------------------------------------------------------------
116 vtkPlusDeckLinkVideoSource::vtkPlusDeckLinkVideoSource::vtkInternal* vtkPlusDeckLinkVideoSource::vtkInternal::New(vtkPlusDeckLinkVideoSource* _arg)
117 {
118  vtkPlusDeckLinkVideoSource::vtkInternal* result = new vtkPlusDeckLinkVideoSource::vtkInternal();
119  result->InitializeObjectBase();
120  result->External = _arg;
121  return result;
122 }
123 
124 //----------------------------------------------------------------------------
126  : vtkPlusDevice()
127  , Internal(vtkInternal::New(this))
128  , ReferenceCount(1)
129 {
130  LOG_TRACE("vtkPlusDeckLinkVideoSource::vtkPlusDeckLinkVideoSource()");
131 
132  this->FrameNumber = 0;
133  this->StartThreadForInternalUpdates = false; // callback based device
134 }
135 
136 //----------------------------------------------------------------------------
138 {
139  LOG_TRACE("vtkPlusDeckLinkVideoSource::~vtkPlusDeckLinkVideoSource()");
140 
141  if (this->Internal->DeckLinkDisplayMode != nullptr)
142  {
143  this->Internal->DeckLinkDisplayMode->Release();
144  }
145  if (this->Internal->DeckLinkInput != nullptr)
146  {
147  this->Internal->DeckLinkInput->Release();
148  }
149  if (this->Internal->DeckLink != nullptr)
150  {
151  this->Internal->DeckLink->Release();
152  }
153 
154  ShutdownCOM(this->Internal->COMInitialized);
155 
156  this->Internal->Delete();
157  this->Internal = nullptr;
158 }
159 
160 //----------------------------------------------------------------------------
161 HRESULT STDMETHODCALLTYPE vtkPlusDeckLinkVideoSource::QueryInterface(REFIID iid, LPVOID* ppv)
162 {
163  HRESULT result = E_NOINTERFACE;
164 
165  if (ppv == NULL)
166  {
167  return E_INVALIDARG;
168  }
169 
170  // Initialize the return result
171  *ppv = NULL;
172 
173  // Obtain the IUnknown interface and compare it the provided REFIID
174  if (iid == IID_IUnknown)
175  {
176  *ppv = this;
177  AddRef();
178  result = S_OK;
179  }
180  else if (iid == IID_IDeckLinkInputCallback)
181  {
182  *ppv = (IDeckLinkInputCallback*)this;
183  AddRef();
184  result = S_OK;
185  }
186 
187  return result;
188 }
189 
190 //----------------------------------------------------------------------------
192 {
193  return ++ReferenceCount;
194 }
195 
196 //----------------------------------------------------------------------------
198 {
199  ULONG newRefValue;
200 
201  ReferenceCount--;
202  newRefValue = ReferenceCount;
203  if (newRefValue == 0)
204  {
205  delete this;
206  return 0;
207  }
208 
209  return newRefValue;
210 }
211 
212 //----------------------------------------------------------------------------
213 void vtkPlusDeckLinkVideoSource::PrintSelf(ostream& os, vtkIndent indent)
214 {
215  LOG_TRACE("vtkPlusDeckLinkVideoSource::PrintSelf(ostream& os, vtkIndent indent)");
216  Superclass::PrintSelf(os, indent);
217 }
218 
219 //----------------------------------------------------------------------------
221 {
222  return false;
223 }
224 
225 //----------------------------------------------------------------------------
227 {
228  return false;
229 }
230 
231 //----------------------------------------------------------------------------
232 PlusStatus vtkPlusDeckLinkVideoSource::ReadConfiguration(vtkXMLDataElement* rootConfigElement)
233 {
234  LOG_TRACE("vtkPlusDeckLinkVideoSource::ReadConfiguration");
235 
236  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement);
237 
238  XML_FIND_NESTED_ELEMENT_REQUIRED(dataSourcesElement, deviceConfig, "DataSources");
239 
240  int devIndex(-1);
241  XML_READ_SCALAR_ATTRIBUTE_NONMEMBER_OPTIONAL(int, DeviceIndex, devIndex, deviceConfig);
242  if (devIndex != -1)
243  {
244  this->Internal->DeviceIndex = devIndex;
245  }
246 
247  std::string devName("");
248  XML_READ_STRING_ATTRIBUTE_NONMEMBER_OPTIONAL(DeviceName, devName, deviceConfig);
249  if (!devName.empty())
250  {
251  this->Internal->DeviceName = devName;
252  }
253 
254  int size[3] = {-1, -1, -1};
255  XML_READ_VECTOR_ATTRIBUTE_NONMEMBER_OPTIONAL(int, 2, FrameSize, size, deviceConfig);
256  if (size[0] != -1 && size[1] != -1)
257  {
258  this->Internal->RequestedFrameSize[0] = static_cast<unsigned int>(size[0]);
259  this->Internal->RequestedFrameSize[1] = static_cast<unsigned int>(size[1]);
260  this->Internal->RequestedFrameSize[2] = 1;
261  }
262 
263  std::string pixelFormat("");
264  XML_READ_STRING_ATTRIBUTE_NONMEMBER_OPTIONAL(PixelFormat, pixelFormat, deviceConfig);
265  if (!pixelFormat.empty())
266  {
267  this->Internal->RequestedPixelFormat = DeckLinkAPIWrapper::PixelFormatFromString(pixelFormat);
268  if (this->Internal->RequestedPixelFormat == bmdFormatUnspecified)
269  {
270  LOG_ERROR("Unknown pixel format requested. Please see device page documentation for supported pixel formats.");
271  return PLUS_FAIL;
272  }
273  }
274 
275  std::string videoConnection("");
276  XML_READ_STRING_ATTRIBUTE_NONMEMBER_OPTIONAL(VideoConnection, videoConnection, deviceConfig);
277  if (!videoConnection.empty())
278  {
279  this->Internal->RequestedVideoConnection = DeckLinkAPIWrapper::VideoConnectionFromString(videoConnection);
280  if (this->Internal->RequestedVideoConnection == bmdVideoConnectionUnspecified)
281  {
282  LOG_ERROR("Unknown connection type requested. Please see device page documentation for supported connections.");
283  return PLUS_FAIL;
284  }
285  }
286 
287  std::string displayMode("");
288  XML_READ_STRING_ATTRIBUTE_NONMEMBER_OPTIONAL(DisplayMode, displayMode, deviceConfig);
289  if (!displayMode.empty())
290  {
291  this->Internal->RequestedDisplayMode = DeckLinkAPIWrapper::DisplayModeFromString(displayMode);
292  if (this->Internal->RequestedDisplayMode == bmdModeUnknown)
293  {
294  LOG_ERROR("Unable to recognize requested display mode. Please see device documentation for valid entries.");
295  return PLUS_FAIL;
296  }
297  }
298 
299  return PLUS_SUCCESS;
300 }
301 
302 //----------------------------------------------------------------------------
303 PlusStatus vtkPlusDeckLinkVideoSource::WriteConfiguration(vtkXMLDataElement* rootConfigElement)
304 {
305  LOG_TRACE("vtkPlusDeckLinkVideoSource::WriteConfiguration");
306  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement);
307  return PLUS_FAIL;
308 }
309 
310 //----------------------------------------------------------------------------
312 {
313  LOG_TRACE("vtkPlusDeckLinkVideoSource::InternalConnect");
314 
315  IDeckLink* deckLink(nullptr);
316  IDeckLinkIterator* deckLinkIterator(nullptr);
317  IDeckLinkInput* deckLinkInput(nullptr);
318  IDeckLinkDisplayModeIterator* deckLinkDisplayModeIterator(nullptr);
319  IDeckLinkDisplayMode* deckLinkDisplayMode(nullptr);
320  HRESULT result;
321 
322  if (!InitCOM(this->Internal->COMInitialized))
323  {
324  goto out;
325  }
326 
327  this->Internal->DeckLinkVideoConversion = DeckLinkAPIWrapper::CreateVideoConversion();
328 
329  deckLinkIterator = DeckLinkAPIWrapper::CreateDeckLinkIterator();
330 
331  // Enumerate all cards in this system
332  int count = 0;
333  while (deckLinkIterator->Next(&deckLink) == S_OK)
334  {
335  if (this->Internal->DeviceIndex == -1 || count == this->Internal->DeviceIndex)
336  {
337  // Query the DeckLink for its input interface
338  result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
339  if (result != S_OK)
340  {
341  LOG_ERROR("Could not obtain the IDeckLinkInput interface - result = " << std::hex << std::setw(8) << std::setfill('0') << result);
342  goto out;
343  }
344 
345  if (deckLinkInput->GetDisplayModeIterator(&deckLinkDisplayModeIterator) != S_OK)
346  {
347  LOG_ERROR("Unable to iterate display modes. Cannot select input display mode.");
348  return PLUS_FAIL;
349  }
350 
351  while (deckLinkDisplayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
352  {
353  if (this->Internal->RequestedDisplayMode != bmdModeUnknown && deckLinkDisplayMode->GetDisplayMode() == this->Internal->RequestedDisplayMode)
354  {
355  BOOL supported;
356  if (deckLinkInput->DoesSupportVideoMode(this->Internal->RequestedVideoConnection, this->Internal->RequestedDisplayMode, this->Internal->RequestedPixelFormat, bmdSupportedVideoModeDefault, &supported) == S_OK && supported)
357  {
358  // Found by display mode
359  this->Internal->DeckLink = deckLink;
360  this->Internal->DeckLinkInput = deckLinkInput;
361  this->Internal->DeckLinkDisplayMode = deckLinkDisplayMode;
362  goto out;
363  }
364  }
365  else if (this->Internal->RequestedDisplayMode == bmdModeUnknown)
366  {
367  BMDTimeValue frameDuration;
368  BMDTimeScale timeScale;
369  if (deckLinkDisplayMode->GetFrameRate(&frameDuration, &timeScale) != S_OK)
370  {
371  LOG_WARNING("Unable to retrieve frame rate for display mode. Skipping.");
372  continue;
373  }
374 
375  double frameRate = (double)timeScale / (double)frameDuration;
376  if (deckLinkDisplayMode->GetWidth() == this->Internal->RequestedFrameSize[0] &&
377  deckLinkDisplayMode->GetHeight() == this->Internal->RequestedFrameSize[1] &&
378  AreSame(frameRate, this->AcquisitionRate))
379  {
380  BOOL supported;
381  if (deckLinkInput->DoesSupportVideoMode(bmdVideoConnectionUnspecified, deckLinkDisplayMode->GetDisplayMode(), bmdFormatUnspecified, bmdSupportedVideoModeDefault, &supported) && supported)
382  {
383  // Found by frame details
384  this->Internal->DeckLink = deckLink;
385  this->Internal->DeckLinkInput = deckLinkInput;
386  this->Internal->DeckLinkDisplayMode = deckLinkDisplayMode;
387  goto out;
388  }
389  }
390  }
391  deckLinkDisplayMode->Release();
392  }
393 
394  deckLinkDisplayModeIterator->Release();
395  deckLinkInput->Release();
396  deckLink->Release();
397  }
398 
399  count++;
400  }
401 
402  LOG_ERROR("Unable to locate requested capture parameters.")
403 
404 out:
405  if (deckLinkDisplayModeIterator)
406  {
407  deckLinkDisplayModeIterator->Release();
408  }
409  if (deckLinkIterator)
410  {
411  deckLinkIterator->Release();
412  }
413 
414  if (this->Internal->DeckLinkInput)
415  {
416  // Confirm data source is correctly configured. If not, abort
417  BMDTimeValue frameDuration;
418  BMDTimeScale timeScale;
419  this->Internal->DeckLinkDisplayMode->GetFrameRate(&frameDuration, &timeScale);
421  this->GetFirstVideoSource(source);
422  source->SetInputFrameSize(this->Internal->RequestedFrameSize);
423  source->SetPixelType(VTK_UNSIGNED_CHAR);
424 
425  if (source->GetImageType() == US_IMG_RGB_COLOR)
426  {
427  source->SetNumberOfScalarComponents(3);
428  this->Internal->RGBBytes = (unsigned char*)malloc(this->Internal->RequestedFrameSize[0] * this->Internal->RequestedFrameSize[1] * 3 * sizeof(unsigned char));
429  }
430  else
431  {
432  source->SetNumberOfScalarComponents(1);
433  this->Internal->GrayBytes = (unsigned char*)malloc(this->Internal->RequestedFrameSize[0] * this->Internal->RequestedFrameSize[1] * 1 * sizeof(unsigned char));
434  }
435 
436  this->Internal->DeckLinkInput->SetCallback(this);
437  this->Internal->DeckLinkInput->SetScreenPreviewCallback(nullptr);
438  this->Internal->DeckLinkInput->DisableAudioInput();
439 
440  HRESULT res = this->Internal->DeckLinkInput->EnableVideoInput(this->Internal->DeckLinkDisplayMode->GetDisplayMode(), this->Internal->RequestedPixelFormat, bmdVideoInputFlagDefault);
441  if (res != S_OK)
442  {
443  LPTSTR errorMsgPtr = 0;
444  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, res, 0, (LPTSTR)&errorMsgPtr, 0, NULL);
445  LOG_ERROR("Unable to convert video frame: " << errorMsgPtr);
446  LocalFree(errorMsgPtr);
447  this->Internal->DeckLinkDisplayMode->Release();
448  this->Internal->DeckLinkDisplayMode = nullptr;
449  this->Internal->DeckLinkInput->Release();
450  this->Internal->DeckLinkInput = nullptr;
451  this->Internal->DeckLink->Release();
452  this->Internal->DeckLink = nullptr;
453  return PLUS_FAIL;
454  }
455 
456  this->Internal->OutputFrame = new PlusOutputVideoFrame(this->Internal->DeckLinkDisplayMode->GetWidth(), this->Internal->DeckLinkDisplayMode->GetHeight(), bmdFormat8BitBGRA, bmdFrameFlagDefault);
457  }
458 
459  return this->Internal->DeckLinkInput == nullptr ? PLUS_FAIL : PLUS_SUCCESS;
460 }
461 
462 //----------------------------------------------------------------------------
464 {
465  LOG_TRACE("vtkPlusDeckLinkVideoSource::InternalDisconnect");
466 
467  free(this->Internal->RGBBytes);
468  free(this->Internal->GrayBytes);
469 
470  this->Internal->DeckLinkVideoConversion->Release();
471  this->Internal->DeckLinkVideoConversion = nullptr;
472 
473  if (this->Internal->OutputFrame != nullptr)
474  {
475  delete this->Internal->OutputFrame;
476  this->Internal->OutputFrame = nullptr;
477  }
478 
479  this->StopRecording();
480  this->Internal->DeckLinkInput->SetScreenPreviewCallback(NULL);
481  this->Internal->DeckLinkInput->SetCallback(NULL);
482 
483  if (this->Internal->DeckLinkDisplayMode != nullptr)
484  {
485  this->Internal->DeckLinkDisplayMode->Release();
486  this->Internal->DeckLinkDisplayMode = nullptr;
487  }
488  if (this->Internal->DeckLinkInput != nullptr)
489  {
490  this->Internal->DeckLinkInput->Release();
491  this->Internal->DeckLinkInput = nullptr;
492  }
493  if (this->Internal->DeckLink != nullptr)
494  {
495  this->Internal->DeckLink->Release();
496  this->Internal->DeckLink = nullptr;
497  }
498 
499  ShutdownCOM(this->Internal->COMInitialized);
500 
501  return PLUS_FAIL;
502 }
503 
504 //----------------------------------------------------------------------------
506 {
507  LOG_TRACE("vtkPlusDeckLinkVideoSource::InternalStartRecording");
508 
509  if (this->Internal->DeckLinkInput != nullptr)
510  {
511  if (this->Internal->DeckLinkInput->StartStreams() != S_OK)
512  {
513  return PLUS_FAIL;
514  }
515  }
516  else
517  {
518  return PLUS_FAIL;
519  }
520 
521  return PLUS_SUCCESS;
522 }
523 
524 //----------------------------------------------------------------------------
526 {
527  LOG_TRACE("vtkPlusDeckLinkVideoSource::InternalStopRecording");
528 
529  if (this->Internal->DeckLinkInput != nullptr)
530  {
531  if (this->Internal->DeckLinkInput->StopStreams() != S_OK)
532  {
533  return PLUS_FAIL;
534  }
535  }
536  else
537  {
538  return PLUS_FAIL;
539  }
540 
541  return PLUS_SUCCESS;
542 }
543 
544 //----------------------------------------------------------------------------
546 {
547  LOG_TRACE("vtkPlusDeckLinkVideoSource::Probe");
548 
549  bool comInit = this->Internal->COMInitialized;
550  if (!InitCOM(this->Internal->COMInitialized))
551  {
552  return PLUS_FAIL;
553  }
554 
555  // Do stuff
556  IDeckLinkIterator* deckLinkIterator = DeckLinkAPIWrapper::CreateDeckLinkIterator();
557  IDeckLink* deckLink(nullptr);
558 
559  if (deckLinkIterator == nullptr)
560  {
561  return PLUS_FAIL;
562  }
563 
564  // Does this system contain any DeckLink device?
565  bool result(false);
566  if (deckLinkIterator->Next(&deckLink) == S_OK)
567  {
568  result = true;
569  }
570 
571  if (!comInit)
572  {
573  ShutdownCOM(this->Internal->COMInitialized);
574  }
575 
576  return result ? PLUS_SUCCESS : PLUS_FAIL;
577 }
578 
579 //----------------------------------------------------------------------------
581 {
582  if (this->GetNumberOfVideoSources() == 0)
583  {
584  LOG_ERROR("DeckLinkVideoSource requires at least one video source. Please correct configuration file.");
585  return PLUS_FAIL;
586  }
587 
588  if (this->OutputChannelCount() == 0)
589  {
590  LOG_ERROR("DeckLinkVideoSource requires at least one output channel. Please correct configuration file.");
591  return PLUS_FAIL;
592  }
593 
594  return PLUS_SUCCESS;
595 }
596 
597 //----------------------------------------------------------------------------
598 HRESULT STDMETHODCALLTYPE vtkPlusDeckLinkVideoSource::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode* newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags)
599 {
600  return S_OK;
601 }
602 
603 //----------------------------------------------------------------------------
604 HRESULT STDMETHODCALLTYPE vtkPlusDeckLinkVideoSource::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioPacket)
605 {
606  if (!this->IsRecording())
607  {
608  return S_OK;
609  }
610 
611  if (videoFrame)
612  {
613  this->Internal->OutputFrame->SetFlags(videoFrame->GetFlags());
614 
615  bool inputFrameValid = ((videoFrame->GetFlags() & bmdFrameHasNoInputSource) == 0);
616 
617  if (inputFrameValid && !this->Internal->PreviousFrameValid)
618  {
619  this->Internal->DeckLinkInput->StopStreams();
620  this->Internal->DeckLinkInput->FlushStreams();
621  this->Internal->DeckLinkInput->StartStreams();
622  }
623 
624  if (inputFrameValid)
625  {
626  HRESULT res = this->Internal->DeckLinkVideoConversion->ConvertFrame(videoFrame, this->Internal->OutputFrame);
627  if (res != S_OK)
628  {
629  LPTSTR errorMsgPtr = 0;
630  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, res, 0, (LPTSTR)&errorMsgPtr, 0, NULL);
631  LOG_ERROR("Unable to convert video frame: " << errorMsgPtr);
632  LocalFree(errorMsgPtr);
633  }
634 
635  if (this->Internal->PreviousFrameValid && res == S_OK)
636  {
637  void* buffer;
638  if (this->Internal->OutputFrame->GetBytes(&buffer) == S_OK)
639  {
641  this->GetFirstVideoSource(source);
642 
643  if (source->GetImageType() == US_IMG_RGB_COLOR)
644  {
645  // Flip BGRA to RGB
646  PixelCodec::BGRA32ToRGB24(this->Internal->RequestedFrameSize[0], this->Internal->RequestedFrameSize[1], (unsigned char*)buffer, this->Internal->RGBBytes);
647  }
648  else
649  {
650  PixelCodec::RGBA32ToGray(this->Internal->RequestedFrameSize[0], this->Internal->RequestedFrameSize[1], (unsigned char*)buffer, this->Internal->GrayBytes);
651  }
652 
653  if (source->AddItem(source->GetImageType() == US_IMG_RGB_COLOR ? this->Internal->RGBBytes : this->Internal->GrayBytes,
654  source->GetInputImageOrientation(),
655  this->Internal->RequestedFrameSize,
656  VTK_UNSIGNED_CHAR, source->GetNumberOfScalarComponents(),
657  source->GetImageType(),
658  0,
659  this->FrameNumber) != PLUS_SUCCESS)
660  {
661  LOG_ERROR("Unable to add video item to buffer.");
662  return PLUS_FAIL;
663  }
664  this->FrameNumber++;
665  }
666  }
667  }
668 
669  this->Internal->PreviousFrameValid = inputFrameValid;
670  }
671  return S_OK;
672 }
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
static void BGRA32ToRGB24(int width, int height, unsigned char *s, unsigned char *d)
Definition: PixelCodec.h:260
static IDeckLinkIterator *BMD_PUBLIC CreateDeckLinkIterator()
virtual int GetNumberOfVideoSources() const
const char * source
Definition: phidget22.h:2461
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
igsioStatus PlusStatus
Definition: PlusCommon.h:40
static BMDVideoConnection VideoConnectionFromString(const std::string &)
double AcquisitionRate
#define PLUS_FAIL
Definition: PlusCommon.h:43
static IDeckLinkVideoConversion *BMD_PUBLIC CreateVideoConversion()
static void RGBA32ToGray(int width, int height, unsigned char *s, unsigned char *d)
Definition: PixelCodec.h:317
Initial rotation matrix b
Definition: algo3.m:25
PlusStatus GetFirstVideoSource(vtkPlusDataSource *&anImage)
virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioPacket)
virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode *newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags)
static vtkPlusDeckLinkVideoSource * New()
unsigned long FrameNumber
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
vtkStandardNewMacro(vtkPlusDeckLinkVideoSource)
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv)
virtual PlusStatus StopRecording()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
void PrintSelf(ostream &os, vtkIndent indent)
unsigned long ULONG
Definition: ATC3DGm.h:432
Phidget_ChannelClass uint32_t * count
Definition: phidget22.h:1321
virtual bool IsRecording() const
bool StartThreadForInternalUpdates
static BMDDisplayMode DisplayModeFromString(const std::string &)
virtual ULONG STDMETHODCALLTYPE Release()
static BMDPixelFormat PixelFormatFromString(const std::string &)
virtual ULONG STDMETHODCALLTYPE AddRef()
Interface to a BlackMagic DeckLink capture card.
virtual int OutputChannelCount() const
int BOOL
Definition: ATC3DGm.h:446
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
Interface to a 3D positioning tool, video source, or generalized data stream.