Fraxinus  18.10
An IGT application
cxVideoImplService.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxVideoImplService.h"
13 
14 #include <ctkPluginContext.h>
15 #include "boost/bind.hpp"
16 #include "cxData.h"
17 
19 
21 #include "cxVideoConnection.h"
22 #include "cxBasicVideoSource.h"
23 #include "cxTypeConversions.h"
24 #include "cxTrackingService.h"
25 #include "cxVideoServiceBackend.h"
26 
27 #include "cxLogger.h"
28 #include "cxTrackingServiceProxy.h"
30 #include "cxFileHelpers.h"
31 #include "cxSpaceProviderImpl.h"
32 #include "cxVideoServiceBackend.h"
33 #include "cxStreamerService.h"
34 #include "cxStreamerServiceProxy.h"
35 #include "cxStreamerServiceNull.h"
36 #include "cxNullDeleter.h"
37 
38 namespace cx
39 {
40 
41 VideoImplService::VideoImplService(ctkPluginContext *context) :
42  mContext(context )
43 {
44  VideoServiceBackendPtr videoBackend;
45 
48  SpaceProviderPtr spaceProvider;
49  spaceProvider.reset(new cx::SpaceProviderImpl(tracking, pasm));
50  mBackend = VideoServiceBackend::create(pasm,tracking, spaceProvider, context);
51 
52  mEmptyVideoSource.reset(new BasicVideoSource());
53  mVideoConnection.reset(new VideoConnection(mBackend));
54  mActiveVideoSource = mEmptyVideoSource;
55 
56  connect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::autoSelectActiveVideoSource);
57  connect(mVideoConnection.get(), &VideoConnection::videoSourcesChanged, this, &VideoImplService::autoSelectActiveVideoSource);
58  connect(mVideoConnection.get(), &VideoConnection::fps, this, &VideoImplService::fpsSlot);
59  connect(mBackend->tracking().get(), &TrackingService::activeToolChanged, this, &VideoImplService::autoSelectActiveVideoSource);
60  connect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::connected);
61 
62  this->initServiceListener();
63 }
64 
66 {
67  // Disconnect before deleting videoconnection:
68  // The VideoConnection might emit events AND call processevents, causing
69  // recursive calls back to this during deletion.
70  disconnect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::autoSelectActiveVideoSource);
71  disconnect(mVideoConnection.get(), &VideoConnection::videoSourcesChanged, this, &VideoImplService::autoSelectActiveVideoSource);
72  disconnect(mVideoConnection.get(), &VideoConnection::fps, this, &VideoImplService::fpsSlot);
73  disconnect(mBackend->tracking().get(), &TrackingService::activeToolChanged, this, &VideoImplService::autoSelectActiveVideoSource);
74  disconnect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::connected);
75 
76  mVideoConnection.reset();
77 }
78 
80 {
81  QList<StreamerServicePtr> services = this->getStreamerServices();
82  foreach(StreamerServicePtr service, services)
83  {
84  if (service->getType()==uid)
85  {
86  return service;
87  }
88  }
90 }
91 
92 QList<StreamerServicePtr> VideoImplService::getStreamerServices()
93 {
94  QList<StreamerServicePtr> retval;
95  QList<StreamerService *> services = mStreamerServiceListener->getServices();
96  foreach(StreamerService* service, services)
97  {
98  if(service)
99  {
100  StreamerServicePtr temp(new StreamerServiceProxy(mBackend->mContext, service->getName()), null_deleter());
101  retval.append(temp);
102  }
103  }
104  return retval;
105 }
106 
108 {
109  return false;
110 }
111 
112 void VideoImplService::autoSelectActiveVideoSource()
113 {
114  VideoSourcePtr suggestion = this->getGuessForActiveVideoSource(mActiveVideoSource);
115  this->setActiveVideoSource(suggestion->getUid());
116 }
117 
119 {
120  mActiveVideoSource = mEmptyVideoSource;
121 
122  std::vector<VideoSourcePtr> sources = this->getVideoSources();
123  for (unsigned i=0; i<sources.size(); ++i)
124  if (sources[i]->getUid()==uid)
125  mActiveVideoSource = sources[i];
126 
127  // set active stream in all probes if stream is present:
128  TrackingService::ToolMap tools = mBackend->tracking()->getTools();
129  for (TrackingService::ToolMap::iterator iter=tools.begin(); iter!=tools.end(); ++iter)
130  {
131  ProbePtr probe = iter->second->getProbe();
132  if (!probe)
133  continue;
134  if (!probe->getAvailableVideoSources().count(uid)){
135  report("No active streams");
136  continue;
137  }
138  probe->setActiveStream(uid);
139  }
140 
142 }
143 
144 VideoSourcePtr VideoImplService::getGuessForActiveVideoSource(VideoSourcePtr old)
145 {
146 
147  if(old && old->getUid().contains("playback"))
148  return old;
149 
150  QStringList nameFilters;
151  nameFilters << "TissueAngio.fts" << "TissueFlow.fts" << "ScanConverted.fts";
152  // ask for playback stream:
153  foreach(USAcquisitionVideoPlaybackPtr uSAcquisitionVideoPlayback,mUSAcquisitionVideoPlaybacks)
154  {
155  if (uSAcquisitionVideoPlayback->isActive() && nameFilters.contains(uSAcquisitionVideoPlayback->getType()) )
156  return uSAcquisitionVideoPlayback->getVideoSource();
157  }
158 
159  // ask for playback stream:
160  foreach(USAcquisitionVideoPlaybackPtr uSAcquisitionVideoPlayback,mUSAcquisitionVideoPlaybacks)
161  {
162  if (uSAcquisitionVideoPlayback->isActive())
163  return uSAcquisitionVideoPlayback->getVideoSource();
164  }
165 
166  // ask for active stream in first probe:
167  ToolPtr tool = mBackend->tracking()->getFirstProbe();
168  if (tool && tool->getProbe() && tool->getProbe()->getRTSource())
169  {
170  // keep existing if present
171  if (old)
172  {
173  if (tool->getProbe()->getAvailableVideoSources().count(old->getUid()))
174  return old;
175  }
176 
177  return tool->getProbe()->getRTSource();
178  }
179 
180  std::vector<VideoSourcePtr> allSources = this->getVideoSources();
181  // keep existing if present
182  if (old)
183  {
184  if (std::count(allSources.begin(), allSources.end(), old))
185  return old;
186  }
187  // ask for anything
188  if (!allSources.empty())
189  return allSources.front();
190 
191  // give up: return empty
192  return mEmptyVideoSource;
193 }
194 
196 {
197  return mActiveVideoSource;
198 }
199 
201 {
202 
203  QStringList res = getAbsolutePathToFiles( mBackend->getDataManager()->getActivePatientFolder() + "/US_Acq/",QStringList("*.fts"), true);
204  QSet<QString> types;
205  foreach (const QString &acq, res)
206  {
207  types.insert(acq.split("_").back());
208  }
209  USAcquisitionVideoPlaybackPtr tempUSAcquisitionVideoPlayback;
210  foreach(const QString type, types.toList() ){
211 
212  tempUSAcquisitionVideoPlayback.reset(new USAcquisitionVideoPlayback(mBackend,type));
213  mUSAcquisitionVideoPlaybacks.push_back(tempUSAcquisitionVideoPlayback );
214 
215 
216  mUSAcquisitionVideoPlaybacks.back()->setTime(controller);
217 
218  VideoSourcePtr playbackSource = mUSAcquisitionVideoPlaybacks.back()->getVideoSource();
219  TrackingService::ToolMap tools = mBackend->tracking()->getTools();
220  for (TrackingService::ToolMap::iterator iter=tools.begin(); iter!=tools.end(); ++iter)
221  {
222  ProbePtr probe = iter->second->getProbe();
223  if (!probe)
224  continue;
225  if (mUSAcquisitionVideoPlaybacks.back()->isActive())
226  probe->setRTSource(playbackSource);
227  else
228  probe->removeRTSource(playbackSource);
229  }
230  mUSAcquisitionVideoPlaybacks.back()->setRoot(mBackend->getDataManager()->getActivePatientFolder() + "/US_Acq/");
231  }
232  this->autoSelectActiveVideoSource();
233 }
234 
235 std::vector<VideoSourcePtr> VideoImplService::getVideoSources()
236 {
237  std::vector<VideoSourcePtr> retval = mVideoConnection->getVideoSources();
238  foreach(USAcquisitionVideoPlaybackPtr uSAcquisitionVideoPlayback,mUSAcquisitionVideoPlaybacks)
239  {
240  if (uSAcquisitionVideoPlayback->isActive())
241  retval.push_back(uSAcquisitionVideoPlayback->getVideoSource());
242  }
243  return retval;
244 }
245 
246 void VideoImplService::fpsSlot(QString source, int val)
247 {
248  if (source==mActiveVideoSource->getUid())
249  emit fps(val);
250 }
251 
253 {
254  if (mVideoConnection->isConnected())
255  return;
256 
257  //StreamerService* service = this->getStreamerService(mConnectionMethod);
258  StreamerServicePtr service = this->getStreamerService(mConnectionMethod);
259  if (!service)
260  {
261  reportError(QString("Found no streamer for method [%1]").arg(mConnectionMethod));
262  return;
263  }
264 
265  mVideoConnection->runDirectLinkClient(service);
266 }
267 
269 {
270  mVideoConnection->disconnectServer();
271 }
272 
274 {
275  return mVideoConnection->isConnected();
276 }
277 
279 {
280  return mConnectionMethod;
281 }
282 
283 void VideoImplService::setConnectionMethod(QString connectionMethod)
284 {
285  if (mConnectionMethod == connectionMethod)
286  return;
287 
288  if(connectionMethod.isEmpty())
289  {
290  reportWarning("Trying to set connection method to empty string");
291  return;
292  }
293 
294  mConnectionMethod = connectionMethod;
296 }
297 
298 std::vector<TimelineEvent> VideoImplService::getPlaybackEvents()
299 {
300  std::vector<TimelineEvent> retval;
301  foreach(USAcquisitionVideoPlaybackPtr uSAcquisitionVideoPlayback,mUSAcquisitionVideoPlaybacks)
302  {
303  std::vector<TimelineEvent> events = uSAcquisitionVideoPlayback->getEvents();
304  retval.reserve(retval.size() + events.size());
305  retval.insert( retval.end(), events.begin(), events.end() );
306  }
307 
308  return retval;
309 }
310 
311 void VideoImplService::initServiceListener()
312 {
313  mStreamerServiceListener.reset(new ServiceTrackerListener<StreamerService>(
314  mBackend->mContext,
315  boost::bind(&VideoImplService::onStreamerServiceAdded, this, _1),
316  boost::function<void (StreamerService*)>(),
317  boost::bind(&VideoImplService::onStreamerServiceRemoved, this, _1)
318  ));
319  mStreamerServiceListener->open();
320 
321 }
322 
323 void VideoImplService::onStreamerServiceAdded(StreamerService* service)
324 {
325  if (mConnectionMethod.isEmpty())
326  mConnectionMethod = service->getType();
327 
328  emit StreamerServiceAdded(service);
329 }
330 
331 void VideoImplService::onStreamerServiceRemoved(StreamerService *service)
332 {
333  emit StreamerServiceRemoved(service);
334 }
335 
336 
337 } /* namespace cx */
bool connected(bool)
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
virtual QString getConnectionMethod()
void reportError(QString msg)
Definition: cxLogger.cpp:71
virtual void setPlaybackMode(PlaybackTimePtr controller)
void connected(bool on)
virtual VideoSourcePtr getActiveVideoSource()
virtual QString getType() const =0
void StreamerServiceRemoved(StreamerService *service)
boost::shared_ptr< class TrackingService > TrackingServicePtr
Proxy for StreamerServices.
VideoImplService(ctkPluginContext *context)
virtual std::vector< TimelineEvent > getPlaybackEvents()
void StreamerServiceAdded(StreamerService *service)
virtual bool isConnected() const
Handler for playback of US image data from a US recording session.
boost::shared_ptr< class VideoServiceBackend > VideoServiceBackendPtr
static TrackingServicePtr create(ctkPluginContext *pluginContext)
boost::shared_ptr< class PlaybackTime > PlaybackTimePtr
boost::shared_ptr< Probe > ProbePtr
Definition: cxProbe.h:72
static PatientModelServicePtr create(ctkPluginContext *pluginContext)
void activeToolChanged(const QString &uId)
void connectionMethodChanged()
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
boost::shared_ptr< USAcquisitionVideoPlayback > USAcquisitionVideoPlaybackPtr
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
boost::shared_ptr< class VideoSource > VideoSourcePtr
virtual QString getName()=0
virtual StreamerServicePtr getStreamerService(QString uid)
virtual void setConnectionMethod(QString connectionMethod)
virtual std::vector< VideoSourcePtr > getVideoSources()
VideoSource controlled by a vtkImageData.
Helper class for listening to services being added, modified and removed.
std::map< QString, ToolPtr > ToolMap
QStringList getAbsolutePathToFiles(QString path, QStringList nameFilters, bool includeSubDirs)
void report(QString msg)
Definition: cxLogger.cpp:69
static VideoServiceBackendPtr create(PatientModelServicePtr dataManager, TrackingServicePtr trackingService, SpaceProviderPtr spaceProvider, ctkPluginContext *context)
Represent one video grabber connection.
boost::shared_ptr< class StreamerService > StreamerServicePtr
Abstract class. Interface to Streamers.
virtual void setActiveVideoSource(QString uid)
virtual void closeConnection()
virtual QList< StreamerServicePtr > getStreamerServices()
void activeVideoSourceChanged()
void fps(QString source, int fps)
Null implementation of the StreamerService.
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr