CustusX  15.4.0-beta
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 
55 namespace cx
56 {
57 
58 VideoImplService::VideoImplService(ctkPluginContext *context) :
59  mContext(context )
60 {
61  VideoServiceBackendPtr videoBackend;
62 
66  spaceProvider.reset(new cx::SpaceProviderImpl(tracking, pasm));
67  mBackend = VideoServiceBackend::create(pasm,tracking, spaceProvider, context);
68 
69  mEmptyVideoSource.reset(new BasicVideoSource());
70  mVideoConnection.reset(new VideoConnection(mBackend));
71  mActiveVideoSource = mEmptyVideoSource;
72  mUSAcquisitionVideoPlayback.reset(new USAcquisitionVideoPlayback(mBackend));
73 
74  connect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::autoSelectActiveVideoSource);
75  connect(mVideoConnection.get(), &VideoConnection::videoSourcesChanged, this, &VideoImplService::autoSelectActiveVideoSource);
76  connect(mVideoConnection.get(), &VideoConnection::fps, this, &VideoImplService::fpsSlot);
77  connect(mBackend->getToolManager().get(), &TrackingService::activeToolChanged, this, &VideoImplService::autoSelectActiveVideoSource);
78  connect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::connected);
79 
80  this->initServiceListener();
81 }
82 
84 {
85  // Disconnect before deleting videoconnection:
86  // The VideoConnection might emit events AND call processevents, causing
87  // recursive calls back to this during deletion.
88  disconnect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::autoSelectActiveVideoSource);
89  disconnect(mVideoConnection.get(), &VideoConnection::videoSourcesChanged, this, &VideoImplService::autoSelectActiveVideoSource);
90  disconnect(mVideoConnection.get(), &VideoConnection::fps, this, &VideoImplService::fpsSlot);
91  disconnect(mBackend->getToolManager().get(), &TrackingService::activeToolChanged, this, &VideoImplService::autoSelectActiveVideoSource);
92  disconnect(mVideoConnection.get(), &VideoConnection::connected, this, &VideoImplService::connected);
93 
94  mVideoConnection.reset();
95 }
96 
98 {
99  return mStreamerServiceListener->getService(service);
100 }
101 
102 QList<StreamerService *> VideoImplService::getStreamerServices()
103 {
104  return mStreamerServiceListener->getServices();
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->getToolManager()->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  continue;
136  probe->setActiveStream(uid);
137  }
138 
140 }
141 
142 VideoSourcePtr VideoImplService::getGuessForActiveVideoSource(VideoSourcePtr old)
143 {
144  // ask for playback stream:
145  if (mUSAcquisitionVideoPlayback->isActive())
146  return mUSAcquisitionVideoPlayback->getVideoSource();
147 
148  // ask for active stream in first probe:
149  ToolPtr tool = mBackend->getToolManager()->getFirstProbe();
150  if (tool && tool->getProbe() && tool->getProbe()->getRTSource())
151  {
152  // keep existing if present
153  if (old)
154  {
155  if (tool->getProbe()->getAvailableVideoSources().count(old->getUid()))
156  return old;
157  }
158 
159  return tool->getProbe()->getRTSource();
160  }
161 
162  // ask for anything
163  std::vector<VideoSourcePtr> allSources = this->getVideoSources();
164  // keep existing if present
165  if (old)
166  {
167  if (std::count(allSources.begin(), allSources.end(), old))
168  return old;
169  }
170  if (!allSources.empty())
171  return allSources.front();
172 
173  // give up: return empty
174  return mEmptyVideoSource;
175 }
176 
178 {
179  return mActiveVideoSource;
180 }
181 
183 {
184  mUSAcquisitionVideoPlayback->setTime(controller);
185  this->autoSelectActiveVideoSource();
186 
187  VideoSourcePtr playbackSource = mUSAcquisitionVideoPlayback->getVideoSource();
188  TrackingService::ToolMap tools = mBackend->getToolManager()->getTools();
189  for (TrackingService::ToolMap::iterator iter=tools.begin(); iter!=tools.end(); ++iter)
190  {
191  ProbePtr probe = iter->second->getProbe();
192  if (!probe)
193  continue;
194  if (mUSAcquisitionVideoPlayback->isActive())
195  probe->setRTSource(playbackSource);
196  else
197  probe->removeRTSource(playbackSource);
198  }
199  if (mUSAcquisitionVideoPlayback->isActive())
200  this->setActiveVideoSource(playbackSource->getUid());
201  else
202  this->autoSelectActiveVideoSource();
203 
204  mUSAcquisitionVideoPlayback->setRoot(mBackend->getDataManager()->getActivePatientFolder() + "/US_Acq/");
205 }
206 
207 std::vector<VideoSourcePtr> VideoImplService::getVideoSources()
208 {
209  std::vector<VideoSourcePtr> retval = mVideoConnection->getVideoSources();
210  if (mUSAcquisitionVideoPlayback->isActive())
211  retval.push_back(mUSAcquisitionVideoPlayback->getVideoSource());
212  return retval;
213 }
214 
215 void VideoImplService::fpsSlot(QString source, int val)
216 {
217  if (source==mActiveVideoSource->getUid())
218  emit fps(val);
219 }
220 
222 {
223  if (mVideoConnection->isConnected())
224  return;
225 
226  StreamerService* service = this->getStreamerService(mConnectionMethod);
227  if (!service)
228  {
229  reportError(QString("Found no streamer for method [%1]").arg(mConnectionMethod));
230  return;
231  }
232 
233  mVideoConnection->runDirectLinkClient(service);
234 }
235 
237 {
238  mVideoConnection->disconnectServer();
239 }
240 
242 {
243  return mVideoConnection->isConnected();
244 }
245 
247 {
248  return mConnectionMethod;
249 }
250 
251 void VideoImplService::setConnectionMethod(QString connectionMethod)
252 {
253  if (mConnectionMethod == connectionMethod)
254  return;
255 
256  if(connectionMethod.isEmpty())
257  {
258  reportWarning("Trying to set connection method to empty string");
259  return;
260  }
261 
262  mConnectionMethod = connectionMethod;
263 // emit connectionMethodChanged();
264 }
265 
266 std::vector<TimelineEvent> VideoImplService::getPlaybackEvents()
267 {
268  return mUSAcquisitionVideoPlayback->getEvents();
269 }
270 
271 void VideoImplService::initServiceListener()
272 {
273  mStreamerServiceListener.reset(new ServiceTrackerListener<StreamerService>(
274  mBackend->mContext,
275  boost::bind(&VideoImplService::onStreamerServiceAdded, this, _1),
276  boost::function<void (StreamerService*)>(),
277  boost::bind(&VideoImplService::onStreamerServiceRemoved, this, _1)
278  ));
279  mStreamerServiceListener->open();
280 
281 }
282 
283 void VideoImplService::onStreamerServiceAdded(StreamerService* service)
284 {
285  if (mConnectionMethod.isEmpty())
286  mConnectionMethod = service->getName();
287 
288  emit StreamerServiceAdded(service);
289 }
290 
291 void VideoImplService::onStreamerServiceRemoved(StreamerService *service)
292 {
293  emit StreamerServiceRemoved(service);
294 }
295 
296 
297 } /* 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
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 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.
virtual StreamerService * getStreamerService(QString service)
Abstract class. Interface to Streamers.
virtual void setActiveVideoSource(QString uid)
virtual void closeConnection()
boost::shared_ptr< class PlaybackTime > PlaybackTimePtr
void activeVideoSourceChanged()
virtual QList< StreamerService * > getStreamerServices()
void fps(QString source, int fps)
boost::shared_ptr< class Tool > ToolPtr