PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusAddRecordingDeviceCommand.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 // Local includes
8 #include "PlusConfigure.h"
10 #include "vtkPlusChannel.h"
12 #include "vtkPlusDataCollector.h"
13 #include "vtkPlusDevice.h"
14 #include "vtkPlusDeviceFactory.h"
16 #include "vtkPlusVirtualCapture.h"
17 
18 //----------------------------------------------------------------------------
19 
21 
22 //----------------------------------------------------------------------------
23 
24 namespace
25 {
26  static const std::string ADD_RECORDING_DEVICE_CMD = "AddRecordingDevice";
27 }
28 
29 //----------------------------------------------------------------------------
31 {
32  // It handles only one command, set its name by default
33  this->SetName(ADD_RECORDING_DEVICE_CMD);
34 }
35 
36 //----------------------------------------------------------------------------
38 {
39 
40 }
41 
42 //----------------------------------------------------------------------------
44 {
45  this->SetName(ADD_RECORDING_DEVICE_CMD);
46 }
47 
48 //----------------------------------------------------------------------------
49 void vtkPlusAddRecordingDeviceCommand::GetCommandNames(std::list<std::string>& cmdNames)
50 {
51  cmdNames.clear();
52  cmdNames.push_back(ADD_RECORDING_DEVICE_CMD);
53 }
54 
55 //----------------------------------------------------------------------------
56 std::string vtkPlusAddRecordingDeviceCommand::GetDescription(const std::string& commandName)
57 {
58  std::string desc;
59  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, ADD_RECORDING_DEVICE_CMD))
60  {
61  desc += ADD_RECORDING_DEVICE_CMD;
62  desc += ": Add a virtual capture device with inputs defined by metadata \"InputChannels\".";
63  }
64  return desc;
65 }
66 
67 //----------------------------------------------------------------------------
69 {
70  igtl::MessageBase::MetaDataMap::iterator it = this->MetaData.find("InputChannels");
71  if (it == end(this->MetaData) || it->second.second.empty())
72  {
73  LOG_ERROR("Input channels not defined or empty, nothing to record.");
74  this->QueueCommandResponse(PLUS_FAIL, "Input channels not defined or empty.", "Please specify \"InputChannels\" metadata argument as a \"Separator\" separated list.");
75  return PLUS_FAIL;
76  }
77 
78  // Parse InputChannels to see if it's valid
79  char separator = ';';
80  if (this->MetaData.find("Separator") != end(this->MetaData) && !this->MetaData["Separator"].second.empty())
81  {
82  // Grab first character of string
83  separator = this->MetaData["Separator"].second[0];
84  }
85 
86  std::string inputChannels = it->second.second;
87  std::vector<std::string> tokens = igsioCommon::SplitStringIntoTokens(inputChannels, separator, false);
88  if (tokens.size() == 0)
89  {
90  LOG_ERROR("Input channels ill defined, nothing to record.");
91  this->QueueCommandResponse(PLUS_FAIL, "Input channels ill defined.", "Please specify \"InputChannels\" metadata argument as a \"Separator\" separated list.");
92  return PLUS_FAIL;
93  }
94 
95  std::vector<vtkPlusChannel*> channels;
96  for (std::vector<std::string>::iterator it = begin(tokens); it != end(tokens); ++it)
97  {
98  vtkPlusChannel* channel(nullptr);
99  if (this->GetDataCollector()->GetChannel(channel, *it) == PLUS_FAIL)
100  {
101  LOG_ERROR("Input channel " << *it << " not found. Aborting.");
102  this->QueueCommandResponse(PLUS_FAIL, "Input channel " + *it + " not found.", "Please use \"RequestIds\" command to retrieve list of current channels.");
103  return PLUS_FAIL;
104  }
105  channels.push_back(channel);
106  }
107 
108  // Check for a given ID, if not create a unique one
109  std::string deviceId;
110  if (this->MetaData.find("Id") == end(this->MetaData) || this->MetaData["Id"].second.empty())
111  {
112  int counter = 0;
113  while (true)
114  {
115  std::string candidateName = "VirtualCapure[" + igsioCommon::ToString<int>(counter++) + "]";
116  vtkPlusDevice* device(nullptr);
117  if (this->GetDataCollector()->GetDevice(device, candidateName) == PLUS_FAIL)
118  {
119  deviceId = candidateName;
120  break;
121  }
122  }
123  }
124  else
125  {
126  deviceId = this->MetaData["Id"].second;
127  }
128 
129  vtkPlusDevice* device(nullptr);
130  if (this->GetDataCollector()->GetDeviceFactory().CreateInstance("VirtualCapture", device, deviceId) == PLUS_FAIL)
131  {
132  LOG_ERROR("Unable to create device of type \"VirtualCapture\" with ID: " << deviceId);
133  this->QueueCommandResponse(PLUS_FAIL, "Device creation failed.", "See server log for error details.");
134  return PLUS_FAIL;
135  }
136 
137  // Configure device
138  vtkPlusVirtualCapture* captureDevice = dynamic_cast<vtkPlusVirtualCapture*>(device);
139 
140  // Configuration options
141  std::string baseFilename("GeneratedVirtualCapture.nrrd");
142  if (this->MetaData.find("BaseFilename") == end(this->MetaData) || this->MetaData["BaseFilename"].second.empty())
143  {
144  baseFilename = this->MetaData["BaseFilename"].second;
145  if (vtksys::SystemTools::GetFilenameExtension(baseFilename) == "")
146  {
147  baseFilename = baseFilename + ".nrrd";
148  }
149  }
150  captureDevice->SetBaseFilename(baseFilename);
151 
152  bool enableFileCompression(true);
153  if (this->MetaData.find("EnableFileCompression") == end(this->MetaData) || this->MetaData["EnableFileCompression"].second.empty())
154  {
155  enableFileCompression = igsioCommon::IsEqualInsensitive(this->MetaData["EnableFileCompression"].second, "TRUE");
156  }
157  captureDevice->SetEnableFileCompression(enableFileCompression);
158 
159 
160  bool enableCapturingOnStart(true);
161  if (this->MetaData.find("EnableCapturingOnStart") == end(this->MetaData) || this->MetaData["EnableCapturingOnStart"].second.empty())
162  {
163  enableCapturingOnStart = igsioCommon::IsEqualInsensitive(this->MetaData["EnableCapturingOnStart"].second, "TRUE");
164  }
165  captureDevice->SetEnableCapturing(enableCapturingOnStart);
166 
167  if (this->MetaData.find("RequestedFrameRate") == end(this->MetaData) || this->MetaData["RequestedFrameRate"].second.empty())
168  {
169  std::stringstream ss;
170  ss << this->MetaData["RequestedFrameRate"].second;
171  try
172  {
173  int requestedFrameRate(0);
174  ss >> requestedFrameRate;
175  captureDevice->SetRequestedFrameRate(requestedFrameRate);
176  }
177  catch (...) {}
178  }
179 
180  int frameBufferSize(0);
181  if (this->MetaData.find("FrameBufferSize") == end(this->MetaData) || this->MetaData["FrameBufferSize"].second.empty())
182  {
183  std::stringstream ss;
184  ss << this->MetaData["FrameBufferSize"].second;
185  try
186  {
187  ss >> frameBufferSize;
188  captureDevice->SetFrameBufferSize(frameBufferSize);
189  }
190  catch (...) {}
191  }
192 
193  for (std::vector<vtkPlusChannel*>::iterator it = begin(channels); it != end(channels); ++it)
194  {
195  captureDevice->AddInputChannel(*it);
196  }
197 
198  if (this->GetDataCollector()->AddDevice(captureDevice) == PLUS_FAIL)
199  {
200  LOG_ERROR("Unable to add capture device.");
201  this->QueueCommandResponse(PLUS_FAIL, "Unable to add capture device.", "See server log for error details.");
202  return PLUS_FAIL;
203  }
204 
205  this->QueueCommandResponse(PLUS_SUCCESS, "Success.", "");
206  return PLUS_SUCCESS;
207 }
PlusStatus AddInputChannel(vtkPlusChannel *aChannel)
int * channel
Definition: phidget22.h:1303
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
igsioStatus PlusStatus
Definition: PlusCommon.h:40
#define PLUS_FAIL
Definition: PlusCommon.h:43
virtual void GetCommandNames(std::list< std::string > &cmdNames)
void SetEnableFileCompression(bool aFileCompression)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
virtual void SetBaseFilename(std::string)
igtl::MessageBase::MetaDataMap MetaData
vtkStandardNewMacro(vtkPlusAddRecordingDeviceCommand)
virtual void SetFrameBufferSize(unsigned int)
void QueueCommandResponse(PlusStatus status, const std::string &message, const std::string &error="", const igtl::MessageBase::MetaDataMap *metaData=nullptr)
virtual vtkPlusDataCollector * GetDataCollector()
void SetEnableCapturing(bool aValue)
Contains an optional timestamped circular buffer containing the video images and a number of timestam...
virtual void SetRequestedFrameRate(double)
This command adds a virtual capture device with the attached arguments as input channels.
virtual std::string GetDescription(const std::string &commandName)