PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkMmfVideoSourceTest.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"
9 #include "vtkPlusDataSource.h"
10 #include "vtkPlusMmfVideoSource.h"
11 
12 // VTK includes
13 #include <vtkCommand.h>
14 #include <vtkImageData.h>
15 #include <vtkImageViewer2.h>
16 #include <vtkRenderWindowInteractor.h>
17 #include <vtkRenderer.h>
18 #include <vtkSmartPointer.h>
19 #include <vtksys/CommandLineArguments.hxx>
20 
21 // MF Library
22 #include <MediaFoundationVideoCaptureApi.h>
23 
24 void PrintLogsCallback(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata);
25 
26 class vtkMyCallback : public vtkCommand
27 {
28 public:
29  static vtkMyCallback* New()
30  {return new vtkMyCallback;}
31  virtual void Execute(vtkObject* caller, unsigned long, void*)
32  {
33  viewer->Render();
34 
35  //update the timer so it will trigger again
36  iren->CreateTimer(VTKI_TIMER_UPDATE);
37  }
38  vtkImageViewer2* viewer;
39  vtkRenderWindowInteractor* iren;
40 protected:
41  vtkMyCallback()
42  {
43  viewer = NULL;
44  iren = NULL;
45  }
46 };
47 
48 int main(int argc, char** argv)
49 {
50  bool printHelp(false);
51  bool renderingOff(false);
52  bool showDialogs(false);
53  FrameSizeType frameSize;
54  int deviceId = 0;
55  int streamIndex = 0;
56  std::string pixelFormatName;
57  bool listDevices = false;
58  bool listVideoFormats = false;
59 
60  vtksys::CommandLineArguments args;
61  args.Initialize(argc, argv);
62 
63  int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
64 
65  std::vector<int> frameSizeInt;
66 
67  args.AddArgument("--list-devices", vtksys::CommandLineArguments::NO_ARGUMENT, &listDevices, "Show the list of available devices and exit");
68  args.AddArgument("--list-video-formats", vtksys::CommandLineArguments::NO_ARGUMENT, &listVideoFormats, "Show the list of supported video formats for the selected device and exit");
69  args.AddArgument("--device-id", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &deviceId, "Capture device ID (default: 0)");
70  args.AddArgument("--stream-index", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &streamIndex, "Stream index (default=0; see --list-devices for available streams");
71  args.AddArgument("--frame-size", vtksys::CommandLineArguments::MULTI_ARGUMENT, &frameSizeInt, "Requested frame size from the capture device");
72  args.AddArgument("--video-format", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &pixelFormatName, "Requested video format (YUY2, ...)");
73  args.AddArgument("--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp, "Print this help.");
74  args.AddArgument("--rendering-off", vtksys::CommandLineArguments::NO_ARGUMENT, &renderingOff, "Run test without rendering.");
75  args.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
76 
77  if (!args.Parse())
78  {
79  std::cerr << "Problem parsing arguments" << std::endl;
80  std::cout << "\n\nvtkPlusMmfVideoSourceTest help:" << args.GetHelp() << std::endl;
81  exit(EXIT_FAILURE);
82  }
83 
84  vtkPlusLogger::Instance()->SetLogLevel(verboseLevel);
85 
86  if (printHelp)
87  {
88  std::cout << "\n\nvtkPlusMmfVideoSourceTest help:" << args.GetHelp() << std::endl;
89  exit(EXIT_SUCCESS);
90  }
91 
92  if (frameSize.size() < 2 || frameSize[0] < 0 || frameSize[1] < 0)
93  {
94  LOG_ERROR("Invalid frame size inputted. At least two non-negative entries required.");
95  exit(EXIT_SUCCESS);
96  }
97  vtkSmartPointer<vtkPlusMmfVideoSource> frameGrabber = vtkSmartPointer<vtkPlusMmfVideoSource>::New();
98 
99  if (listDevices)
100  {
101  frameGrabber->LogListOfCaptureDevices();
102  exit(EXIT_SUCCESS);
103  }
104 
105  frameGrabber->SetRequestedDeviceId(deviceId);
106 
107  if (listVideoFormats)
108  {
109  frameGrabber->LogListOfCaptureVideoFormats(deviceId);
110  exit(EXIT_SUCCESS);
111  }
112 
113  if (pixelFormatName.empty())
114  {
115  auto& api = MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance();
116  auto mediaType = api.GetFormat(deviceId, streamIndex, 0);
117  pixelFormatName = std::string(begin(mediaType.MF_MT_SUBTYPEName), end(mediaType.MF_MT_SUBTYPEName));
118  pixelFormatName = pixelFormatName.substr(pixelFormatName.find('_') + 1);
119  }
120 
121  frameGrabber->SetRequestedVideoFormat(std::wstring(pixelFormatName.begin(), pixelFormatName.end()));
122  frameGrabber->SetRequestedStreamIndex(streamIndex);
123 
124  if (!frameSize.empty())
125  {
126  if (frameSize.size() != 2)
127  {
128  LOG_ERROR("Frame size shall contain two numbers, separated by a space");
129  return EXIT_FAILURE;
130  }
131  FrameSizeType size;
132  for (unsigned int i = 0; i < frameSize.size(); ++i)
133  {
134  size[i] = frameSize[i];
135  }
136  frameGrabber->SetRequestedFrameSize(frameSize);
137  }
138 
139  frameGrabber->CreateDefaultOutputChannel();
140  LOG_INFO("Initialize...");
141  frameGrabber->Connect();
142 
143  if (frameGrabber->GetConnected())
144  {
145  LOG_INFO("Start recording...");
146  frameGrabber->StartRecording();
147  }
148  else
149  {
150  frameGrabber->Disconnect();
151  LOG_ERROR("Unable to disconnect from media foundation capture device.");
152  exit(EXIT_FAILURE);
153  }
154 
155  if (renderingOff)
156  {
157  LOG_INFO("No need for rendering, stop the device...");
158  frameGrabber->Disconnect();
159  LOG_INFO("Exit successfully");
160  exit(EXIT_SUCCESS);
161  }
162 
163  vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();
164 
165  viewer->SetColorWindow(255);
166  viewer->SetColorLevel(100.5);
167  vtkPlusDataSource* videoSource = NULL;
168  if (frameGrabber->GetFirstActiveOutputVideoSource(videoSource) != PLUS_SUCCESS)
169  {
170  LOG_ERROR("Unable to retrieve the video source.");
171  exit(EXIT_FAILURE);
172  }
173  viewer->SetSize(videoSource->GetOutputFrameSize()[0], videoSource->GetOutputFrameSize()[1]);
174 
175  viewer->SetInputConnection(frameGrabber->GetOutputPort());
176 
177  //Create the interactor that handles the event loop
178  vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
179  iren->SetRenderWindow(viewer->GetRenderWindow());
180  viewer->SetupInteractor(iren);
181 
182  viewer->Render();
183 
184  //establish timer event and create timer
185  vtkSmartPointer<vtkMyCallback> call = vtkSmartPointer<vtkMyCallback>::New();
186  call->iren = iren;
187  call->viewer = viewer;
188  iren->AddObserver(vtkCommand::TimerEvent, call);
189  iren->CreateTimer(VTKI_TIMER_FIRST); //VTKI_TIMER_FIRST = 0
190 
191  //iren must be initialized so that it can handle events
192  iren->Initialize();
193  iren->Start();
194 
195  LOG_INFO("Exit successfully");
196  return EXIT_SUCCESS;
197 }
vtkRenderWindowInteractor * iren
for i
int main(int argc, char **argv)
void PrintLogsCallback(vtkObject *obj, unsigned long eid, void *clientdata, void *calldata)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
vtkImageViewer * viewer
virtual FrameSizeType GetOutputFrameSize() const
static vtkIGSIOLogger * Instance()
Interface to a 3D positioning tool, video source, or generalized data stream.