Fraxinus  16.5.0-fx-rc6
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxImageReceiverThread.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 "cxImageReceiverThread.h"
34 
35 #include "cxCyclicActionLogger.h"
36 #include "cxXmlOptionItem.h"
37 #include "cxStreamer.h"
38 #include "cxStreamerService.h"
39 #include "cxDirectlyLinkedSender.h"
40 #include "cxLogger.h"
41 #include "cxProfile.h"
42 
43 namespace cx
44 {
45 
46 ImageReceiverThread::ImageReceiverThread(StreamerServicePtr streamerInterface, QObject* parent) :
47  QObject(parent),
48  mStreamerInterface(streamerInterface)
49 {
50  this->setObjectName("imagereceiver worker");
51 }
52 
54 {
55  if (!this->attemptInitialize())
56  {
57  // cleanup here in order to do less in the destructor... ??
58  mImageStreamer.reset();
59  mSender.reset();
60 
61  emit finished();
62  }
63 }
64 
65 bool ImageReceiverThread::attemptInitialize()
66 {
67  XmlOptionFile xmlFile = profile()->getXmlSettings().descend("video");
68  QDomElement element = xmlFile.getElement("video");
69  mImageStreamer = mStreamerInterface->createStreamer(element);
70  report(QString("Starting streamer: [%1]").arg(this->hostDescription()));
71 
72  if(!mImageStreamer)
73  {
74  return false;
75  }
76  mSender.reset(new DirectlyLinkedSender());
77 
78  connect(mSender.get(), &DirectlyLinkedSender::newImage, this, &ImageReceiverThread::addImageToQueueSlot, Qt::DirectConnection);
79  connect(mSender.get(), &DirectlyLinkedSender::newUSStatus, this, &ImageReceiverThread::addSonixStatusToQueueSlot, Qt::DirectConnection);
80 
81  mImageStreamer->startStreaming(mSender);
82 
83  return true;
84 }
85 
87 {
88  if (mImageStreamer)
89  {
90  report(QString("Stopping streamer: [%1]...").arg(this->hostDescription()));
91  mImageStreamer->stopStreaming();
92  report(QString("Stopped streamer: [%1]").arg(this->hostDescription()));
93  mImageStreamer.reset();
94  mSender.reset();
95  }
96 
97  emit finished();
98 }
99 
100 void ImageReceiverThread::addImageToQueueSlot()
101 {
102  this->addImageToQueue(mSender->popImage());
103 }
104 
105 void ImageReceiverThread::addSonixStatusToQueueSlot()
106 {
107  this->addSonixStatusToQueue(mSender->popUSStatus());
108 }
109 
110 
112 {
113  this->reportFPS(imgMsg->getUid());
114 
115 // bool needToCalibrateMsgTimeStamp = this->imageComesFromSonix(imgMsg);
116 
117 // moved to IGTLinkClientStreamer
118 // //Should only be needed if time stamp is set on another computer that is
119 // //not synched with the one running this code: e.g. The Ultrasonix scanner
120 // if (needToCalibrateMsgTimeStamp)
121 // mStreamSynchronizer.syncToCurrentTime(imgMsg);
122 
123  QMutexLocker sentry(&mImageMutex);
124  mMutexedImageMessageQueue.push_back(imgMsg);
125  sentry.unlock();
126 
127  emit imageReceived(); // emit signal outside lock, catch possibly in another thread
128 }
129 
131 {
132  QMutexLocker sentry(&mSonixStatusMutex);
133  mMutexedSonixStatusMessageQueue.push_back(msg);
134  sentry.unlock();
135  emit sonixStatusReceived(); // emit signal outside lock, catch possibly in another thread
136 }
137 
139 {
140  QMutexLocker sentry(&mImageMutex);
141  if (mMutexedImageMessageQueue.empty())
142  return ImagePtr();
143  ImagePtr retval = mMutexedImageMessageQueue.front();
144  mMutexedImageMessageQueue.pop_front();
145 
146  return retval;
147 }
148 
150 {
151  QMutexLocker sentry(&mSonixStatusMutex);
152  if (mMutexedSonixStatusMessageQueue.empty())
153  return ProbeDefinitionPtr();
154  ProbeDefinitionPtr retval = mMutexedSonixStatusMessageQueue.front();
155  mMutexedSonixStatusMessageQueue.pop_front();
156  return retval;
157 }
158 
159 void ImageReceiverThread::reportFPS(QString streamUid)
160 {
161  int timeout = 2000;
162  if (!mFPSTimer.count(streamUid))
163  {
164  mFPSTimer[streamUid].reset(new CyclicActionLogger());
165  mFPSTimer[streamUid]->reset(timeout);
166  }
167 
168  CyclicActionLoggerPtr logger = mFPSTimer[streamUid];
169 
170  logger->begin();
171  if (logger->intervalPassed())
172  {
173  emit fps(streamUid, logger->getFPS());
174  logger->reset(timeout);
175  }
176 }
177 
178 //bool ImageReceiverThread::imageComesFromSonix(ImagePtr imgMsg)
179 //{
180 // return imgMsg->getUid().contains("Sonix", Qt::CaseInsensitive);
181 //}
182 
184 {
185  if (!mStreamerInterface)
186  return "none";
187  return mStreamerInterface->getName();
188 }
189 
190 
191 } /* namespace cx */
cxResource_EXPORT ProfilePtr profile()
Definition: cxProfile.cpp:176
void fps(QString, double)
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
QDomElement getElement()
return the current element
virtual ImagePtr getLastImageMessage()
boost::shared_ptr< class CyclicActionLogger > CyclicActionLoggerPtr
void addSonixStatusToQueue(ProbeDefinitionPtr msg)
add the message to a thread-safe queue
virtual QString hostDescription() const
ImageReceiverThread(StreamerServicePtr streamerInterface, QObject *parent=NULL)
void report(QString msg)
Definition: cxLogger.cpp:90
virtual ProbeDefinitionPtr getLastSonixStatusMessage()
boost::shared_ptr< class StreamerService > StreamerServicePtr
void addImageToQueue(ImagePtr imgMsg)
boost::shared_ptr< class ProbeDefinition > ProbeDefinitionPtr
Helper class for xml files used to store ssc/cx data.