CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxVideoImplService.h"
34 
35 #include <ctkPluginContext.h>
36 #include "boost/bind.hpp"
37 #include "cxData.h"
38 
40 
42 #include "cxVideoConnection.h"
43 #include "cxBasicVideoSource.h"
44 #include "cxTypeConversions.h"
45 #include "cxTrackingService.h"
46 #include "cxVideoServiceBackend.h"
47 
48 #include "cxLogger.h"
49 #include "cxTrackingServiceProxy.h"
51 #include "cxSpaceProviderImpl.h"
52 #include "cxVideoServiceBackend.h"
53 #include "cxStreamerService.h"
54 #include "cxStreamerServiceProxy.h"
55 #include "cxStreamerServiceNull.h"
56 #include "cxNullDeleter.h"
57 
58 namespace cx
59 {
60 
61 VideoImplService::VideoImplService(ctkPluginContext *context) :
62  mContext(context )
63 {
64  VideoServiceBackendPtr videoBackend;
65 
69  spaceProvider.reset(new cx::SpaceProviderImpl(tracking, pasm));
70  mBackend = VideoServiceBackend::create(pasm,tracking, spaceProvider, context);
71 
72  mEmptyVideoSource.reset(new BasicVideoSource());
73  mVideoConnection.reset(new VideoConnection(mBackend));
74  mActiveVideoSource = mEmptyVideoSource;
75  mUSAcquisitionVideoPlayback.reset(new USAcquisitionVideoPlayback(mBackend));
76 
77  connect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::autoSelectActiveVideoSource);
78  connect(mVideoConnection.get(), &VideoConnection::videoSourcesChanged, this, &VideoImplService::autoSelectActiveVideoSource);
79  connect(mVideoConnection.get(), &VideoConnection::fps, this, &VideoImplService::fpsSlot);
80  connect(mBackend->getToolManager().get(), &TrackingService::activeToolChanged, this, &VideoImplService::autoSelectActiveVideoSource);
81  connect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::connected);
82 
83  this->initServiceListener();
84 }
85 
87 {
88  // Disconnect before deleting videoconnection:
89  // The VideoConnection might emit events AND call processevents, causing
90  // recursive calls back to this during deletion.
91  disconnect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::autoSelectActiveVideoSource);
92  disconnect(mVideoConnection.get(), &VideoConnection::videoSourcesChanged, this, &VideoImplService::autoSelectActiveVideoSource);
93  disconnect(mVideoConnection.get(), &VideoConnection::fps, this, &VideoImplService::fpsSlot);
94  disconnect(mBackend->getToolManager().get(), &TrackingService::activeToolChanged, this, &VideoImplService::autoSelectActiveVideoSource);
95  disconnect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::connected);
96 
97  mVideoConnection.reset();
98 }
99 
101 {
102  QList<StreamerServicePtr> services = this->getStreamerServices();
103  foreach(StreamerServicePtr service, services)
104  {
105  if (service->getType()==uid)
106  {
107  return service;
108  }
109  }
111 }
112 
113 QList<StreamerServicePtr> VideoImplService::getStreamerServices()
114 {
115  QList<StreamerServicePtr> retval;
116  QList<StreamerService *> services = mStreamerServiceListener->getServices();
117  foreach(StreamerService* service, services)
118  {
119  if(service)
120  {
121  StreamerServicePtr temp(new StreamerServiceProxy(mBackend->mContext, service->getName()), null_deleter());
122  retval.append(temp);
123  }
124  }
125  return retval;
126 }
127 
129 {
130  return false;
131 }
132 
133 void VideoImplService::autoSelectActiveVideoSource()
134 {
135  VideoSourcePtr suggestion = this->getGuessForActiveVideoSource(mActiveVideoSource);
136  this->setActiveVideoSource(suggestion->getUid());
137 }
138 
140 {
141  mActiveVideoSource = mEmptyVideoSource;
142 
143  std::vector<VideoSourcePtr> sources = this->getVideoSources();
144  for (unsigned i=0; i<sources.size(); ++i)
145  if (sources[i]->getUid()==uid)
146  mActiveVideoSource = sources[i];
147 
148  // set active stream in all probes if stream is present:
149  TrackingService::ToolMap tools = mBackend->getToolManager()->getTools();
150  for (TrackingService::ToolMap::iterator iter=tools.begin(); iter!=tools.end(); ++iter)
151  {
152  ProbePtr probe = iter->second->getProbe();
153  if (!probe)
154  continue;
155  if (!probe->getAvailableVideoSources().count(uid))
156  continue;
157  probe->setActiveStream(uid);
158  }
159 
161 }
162 
163 VideoSourcePtr VideoImplService::getGuessForActiveVideoSource(VideoSourcePtr old)
164 {
165  // ask for playback stream:
166  if (mUSAcquisitionVideoPlayback->isActive())
167  return mUSAcquisitionVideoPlayback->getVideoSource();
168 
169  // ask for active stream in first probe:
170  ToolPtr tool = mBackend->getToolManager()->getFirstProbe();
171  if (tool && tool->getProbe() && tool->getProbe()->getRTSource())
172  {
173  // keep existing if present
174  if (old)
175  {
176  if (tool->getProbe()->getAvailableVideoSources().count(old->getUid()))
177  return old;
178  }
179 
180  return tool->getProbe()->getRTSource();
181  }
182 
183  // ask for anything
184  std::vector<VideoSourcePtr> allSources = this->getVideoSources();
185  // keep existing if present
186  if (old)
187  {
188  if (std::count(allSources.begin(), allSources.end(), old))
189  return old;
190  }
191  if (!allSources.empty())
192  return allSources.front();
193 
194  // give up: return empty
195  return mEmptyVideoSource;
196 }
197 
199 {
200  return mActiveVideoSource;
201 }
202 
204 {
205  mUSAcquisitionVideoPlayback->setTime(controller);
206  this->autoSelectActiveVideoSource();
207 
208  VideoSourcePtr playbackSource = mUSAcquisitionVideoPlayback->getVideoSource();
209  TrackingService::ToolMap tools = mBackend->getToolManager()->getTools();
210  for (TrackingService::ToolMap::iterator iter=tools.begin(); iter!=tools.end(); ++iter)
211  {
212  ProbePtr probe = iter->second->getProbe();
213  if (!probe)
214  continue;
215  if (mUSAcquisitionVideoPlayback->isActive())
216  probe->setRTSource(playbackSource);
217  else
218  probe->removeRTSource(playbackSource);
219  }
220  if (mUSAcquisitionVideoPlayback->isActive())
221  this->setActiveVideoSource(playbackSource->getUid());
222  else
223  this->autoSelectActiveVideoSource();
224 
225  mUSAcquisitionVideoPlayback->setRoot(mBackend->getDataManager()->getActivePatientFolder() + "/US_Acq/");
226 }
227 
228 std::vector<VideoSourcePtr> VideoImplService::getVideoSources()
229 {
230  std::vector<VideoSourcePtr> retval = mVideoConnection->getVideoSources();
231  if (mUSAcquisitionVideoPlayback->isActive())
232  retval.push_back(mUSAcquisitionVideoPlayback->getVideoSource());
233  return retval;
234 }
235 
236 void VideoImplService::fpsSlot(QString source, int val)
237 {
238  if (source==mActiveVideoSource->getUid())
239  emit fps(val);
240 }
241 
243 {
244  if (mVideoConnection->isConnected())
245  return;
246 
247  //StreamerService* service = this->getStreamerService(mConnectionMethod);
248  StreamerServicePtr service = this->getStreamerService(mConnectionMethod);
249  if (!service)
250  {
251  reportError(QString("Found no streamer for method [%1]").arg(mConnectionMethod));
252  return;
253  }
254 
255  mVideoConnection->runDirectLinkClient(service);
256 }
257 
259 {
260  mVideoConnection->disconnectServer();
261 }
262 
264 {
265  return mVideoConnection->isConnected();
266 }
267 
269 {
270  return mConnectionMethod;
271 }
272 
273 void VideoImplService::setConnectionMethod(QString connectionMethod)
274 {
275  if (mConnectionMethod == connectionMethod)
276  return;
277 
278  if(connectionMethod.isEmpty())
279  {
280  reportWarning("Trying to set connection method to empty string");
281  return;
282  }
283 
284  mConnectionMethod = connectionMethod;
285 // emit connectionMethodChanged();
286 }
287 
288 std::vector<TimelineEvent> VideoImplService::getPlaybackEvents()
289 {
290  return mUSAcquisitionVideoPlayback->getEvents();
291 }
292 
293 void VideoImplService::initServiceListener()
294 {
295  mStreamerServiceListener.reset(new ServiceTrackerListener<StreamerService>(
296  mBackend->mContext,
297  boost::bind(&VideoImplService::onStreamerServiceAdded, this, _1),
298  boost::function<void (StreamerService*)>(),
299  boost::bind(&VideoImplService::onStreamerServiceRemoved, this, _1)
300  ));
301  mStreamerServiceListener->open();
302 
303 }
304 
305 void VideoImplService::onStreamerServiceAdded(StreamerService* service)
306 {
307  if (mConnectionMethod.isEmpty())
308  mConnectionMethod = service->getType();
309 
310  emit StreamerServiceAdded(service);
311 }
312 
313 void VideoImplService::onStreamerServiceRemoved(StreamerService *service)
314 {
315  emit StreamerServiceRemoved(service);
316 }
317 
318 
319 } /* namespace cx */
bool connected(bool)
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
virtual QString getConnectionMethod()
void reportError(QString msg)
Definition: cxLogger.cpp:92
virtual void setPlaybackMode(PlaybackTimePtr controller)
void connected(bool on)
virtual VideoSourcePtr getActiveVideoSource()
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< Probe > ProbePtr
Definition: cxProbe.h:93
static PatientModelServicePtr create(ctkPluginContext *pluginContext)
void activeToolChanged(const QString &uId)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
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.
cxLogicManager_EXPORT SpaceProviderPtr spaceProvider()
Helper class for listening to services being added, modified and removed.
std::map< QString, ToolPtr > ToolMap
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()
boost::shared_ptr< class PlaybackTime > PlaybackTimePtr
void activeVideoSourceChanged()
void fps(QString source, int fps)
Null implementation of the StreamerService.
boost::shared_ptr< class Tool > ToolPtr