CustusX  2023.01.05-dev+develop.0da12
An IGT application
vtkSonixVideoSource.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Module: $RCSfile: vtkSonixVideoSource.cxx,v $
4  \author Siddharth Vikal, Queens School Of Computing
5 
6 Copyright (c) 2008, Queen's University, Kingston, Ontario, Canada
7 All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12 
13  * Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 
16  * Redistributions in binary form must reproduce the above copyright
17  notice, this list of conditions and the following disclaimer in
18  the documentation and/or other materials provided with the
19  distribution.
20 
21  * Neither the name of Queen's University nor the names of any
22  contributors may be used to endorse or promote products derived
23  from this software without specific prior written permission.
24 
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 POSSIBILITY OF SUCH DAMAGE.
37 
38 =========================================================================*/
39 
40 #ifdef CX_WIN32
41 #include "vtkSonixVideoSource.h"
42 
43 #include "vtkImageData.h"
44 #include "vtkCriticalSection.h"
45 #include "vtkObjectFactory.h"
46 #include "vtkTimerLog.h"
47 #include "vtkInformation.h"
48 #include "vtkInformationVector.h"
49 #include "vtkStreamingDemandDrivenPipeline.h"
50 #include "vtkUnsignedCharArray.h"
51 #include "vtksys/SystemTools.hxx"
52 #include <ctype.h>
53 #include "cxTime.h"
54 #include <igtlImageMessage.h>
55 
56 #include "cxSonixProbeFileReader.h"
57 
58 
59 // because of warnings in windows header push and pop the warning level
60 #ifdef _MSC_VER
61 #pragma warning (push, 3)
62 #endif
63 
64 #include <vector>
65 #include <string>
66 #include "ulterius.h"
67 #include "ulterius_def.h"
68 #include "ImagingModes.h"
69 
70 #ifdef _MSC_VER
71 #pragma warning (pop)
72 #endif
73 
74 
75 
76 vtkCxxRevisionMacro(vtkSonixVideoSource, "$Revision: 1.0$");
77 //vtkStandardNewMacro(vtkWin32VideoSource);
78 //----------------------------------------------------------------------------
79 // Needed when we don't use the vtkStandardNewMacro.
80 vtkInstantiatorNewMacro(vtkSonixVideoSource);
81 
82 //----------------------------------------------------------------------------
83 
84 vtkSonixVideoSource* vtkSonixVideoSource::Instance = 0;
86 
87 
88 //sonic param ids
89 #define VARID_FREQ "b image"
90 #define VARID_DEPTH "b-depth"
91 #define VARID_GAIN "b-gain"
92 #define VARID_CGAIN "color-gain"
93 #define VARID_PGAIN "pw-gain"
94 #define VARID_TGC "gain curve"
95 #define VARID_ZOOM "zoom user"
96 #define VARID_CPRF "color-prp"
97 #define VARID_PPRF "pw-prp"
98 #define VARID_SECTOR "sector"
99 #define VARID_BCHROMA "b-chroma"
100 #define VARID_MCHROMA "m-chroma"
101 #define VARID_DYNRANGE "b-pulse index a"
102 #define VARID_CFOCUS "b-focus count"
103 #define VARID_CFOCUSCOLOR "color-focus count"
104 #define VARID_SFOCUS "focus span"
105 #define VARID_DFOCUS "focus depth"
106 #define VARID_FRATE "b frame rate"
107 #define VARID_MSWEEP 101
108 #define VARID_CLARITY 1112
109 #define VARID_CMAP 1082
110 #define VARID_BMAP 601
111 
112 #if ( _MSC_VER >= 1300 ) // Visual studio .NET
113 #pragma warning ( disable : 4311 )
114 #pragma warning ( disable : 4312 )
115 # define vtkGetWindowLong GetWindowLongPtr
116 # define vtkSetWindowLong SetWindowLongPtr
117 # define vtkGWL_USERDATA GWLP_USERDATA
118 #else // regular Visual studio
119 # define vtkGetWindowLong GetWindowLong
120 # define vtkSetWindowLong SetWindowLong
121 # define vtkGWL_USERDATA GWL_USERDATA
122 #endif //
123 
124 
126 {
127 }
128 
130 {
131  // Destroy any remaining output window.
132  //vtkSonixVideoSource::SetInstance(NULL);
133 }
134 //----------------------------------------------------------------------------
136 {
137  this->ult = new ulterius;
138  this->DataDescriptor = new uDataDesc;
139  this->Initialized = 0;
140 
141  this->FrameSize[0] = 800;
142  this->FrameSize[1] = 600;
143  this->FrameSize[2] = 1;
144 
145  this->SonixHostIP = "";
146  this->FrameRate = 13; // in fps
147  this->Frequency = 1; //in Mhz
148  this->Depth = 150; //in mm
149  this->AcquisitionDataType = 0x00000004; //corresponds to type: BPost 8-bit
150  this->ImagingMode = 0; //corresponds to BMode imaging
151 
152  //note, input data i.e. data from sonix machine is always uncompressed rgb
153  //so, by default we set the output format as rgb
154  this->OutputFormat = VTK_LUMINANCE;
155  this->NumberOfScalarComponents = 1;
156  this->FrameBufferBitsPerPixel = 8;
157  this->FlipFrames = 1;
158  this->FrameBufferRowAlignment = 1;
159 
160 // this->mSonixHelper = new SonixHelper;
161  this->mSonixHelper = NULL;
162  this->lastFrameNum = 0;
163  this->totalMissedFrames = 0;
164 
165  this->lastRoiUlx = 0;
166  this->lastRoiBry = 0;
167 
168  this->mFirstConnect = true;
169  this->mDebugOutput = false;
170  this->mUseSharedMemory = true;
171 }
172 
173 //----------------------------------------------------------------------------
175 {
177  delete this->ult;
178 }
179 
181 {
182  this->mSonixHelper = sonixHelper;
183 }
184 
185 // Up the reference count so it behaves like New
187 {
189  ret->Register(NULL);
190  return ret;
191 }
192 
193 
194 // Return the single instance of the vtkOutputWindow
196 {
197  if(!vtkSonixVideoSource::Instance)
198  {
199  // Try the factory first
200  vtkSonixVideoSource::Instance = dynamic_cast<vtkSonixVideoSource*>(vtkObjectFactory::CreateInstance("vtkSonixVideoSource"));
201  if(!vtkSonixVideoSource::Instance)
202  {
203  vtkSonixVideoSource::Instance = new vtkSonixVideoSource();
204  }
205  if(!vtkSonixVideoSource::Instance)
206  {
207 // int error = 0;
208  }
209  }
210  // return the instance
211  return vtkSonixVideoSource::Instance;
212 }
213 
215 {
216  if (vtkSonixVideoSource::Instance==instance)
217  {
218  return;
219  }
220  // preferably this will be NULL
221  if (vtkSonixVideoSource::Instance)
222  {
223  vtkSonixVideoSource::Instance->Delete();;
224  }
225  vtkSonixVideoSource::Instance = instance;
226  if (!instance)
227  {
228  return;
229  }
230  // user will call ->Delete() after setting instance
231  instance->Register(NULL);
232 }
233 //----------------------------------------------------------------------------
234 void vtkSonixVideoSource::PrintSelf(ostream& os, vtkIndent indent)
235 {
236  this->Superclass::PrintSelf(os,indent);
237 
238  os << indent << "Imaging mode: " << this->ImagingMode << "\n";
239  os << indent << "Frequency: " << this->Frequency << "MHz\n";
240  os << indent << "Frame rate: " << this->FrameRate << "fps\n";
241 
242 }
243 
244 
245 // the callback function used when there is a new frame of data received
246 bool vtkSonixVideoSource::vtkSonixVideoSourceNewFrameCallback(void * data, int type, int sz, bool cine, int frmnum)
247 {
248  if(!data || !sz)
249  {
250  printf("Error: no actual frame data received\n");
251  return false;
252  }
253 
254  /*if(BUFFERSIZE < sz)
255  {
256  printf("Error: frame too large for current buffer\n");
257  return false;
258  }
259  */
260  //printf("[Rx] type:(%d) size:(%d) cine:(%d) tag:(%d)\n", type, sz, cine, ((int*)data)[0]);
261 
262  // make sure we dont do an operation that takes longer than the acquisition frame rate
263  //memcpy(gBuffer, data, sz);
264  if(data)
265  {
266  vtkSonixVideoSource::GetInstance()->LocalInternalGrab(data, type, sz, cine, frmnum);
267  }
268  return true;;
269 }
270 
271 //----------------------------------------------------------------------------
272 // copy the Device Independent Bitmap from the VFW framebuffer into the
273 // vtkVideoSource framebuffer (don't do the unpacking yet)
274 void vtkSonixVideoSource::LocalInternalGrab(void* dataPtr, int type, int sz, bool cine, int frmnum)
275 {
276  int missedFrames = frmnum - lastFrameNum +1;
277  if (missedFrames < 0)
278  {
279  std::cout << "Missed frames: " << missedFrames << " " << std::endl;
280  //totalMissedFrames =+ missedFrames;
281  //std::cout << "Total missed frames: " << totalMissedFrames << std::endl;
282  }
283  else
284  {
285  //std::cout << "No missed frames. Frame nr: " << frmnum << std::endl;
286  }
287 
288 
289  //to do
290  // 1) Do frame buffer indices maintenance
291  // 2) Do time stamping
292  // 3) decode the data according to type
293  // 4) copy data to the local vtk frame buffer
294 
295 
296  // get the pointer to data
297  // use the information about data type and frmnum to do cross checking that you are maintaining correct frame index, & receiving
298  // expected data type
299 
300 
301  // get a thread lock on the frame buffer
302  this->FrameBufferMutex->Lock();
303 
304  //error check for data type, size
305  if ((uData)type!= (uData)this->AcquisitionDataType)
306  {
307  vtkErrorMacro(<< "Received data type is different than expected");
308  }
309  // 1) Do the frame buffer indices maintenance
310  if (this->AutoAdvance)
311  {
312  this->AdvanceFrameBuffer(1);
313  if (this->FrameIndex + 1 < this->FrameBufferSize)
314  {
315  this->FrameIndex++;
316  }
317  }
318  int index = this->FrameBufferIndex;
319 
320  // error check, if the frame indices mismatch, then it indicates, we have missed the frame?
321  //if ( frmnum != index+1)
322  // {
323  // error ??
324  // std::cout << "Frame goes missing"<< std::endl;
325  // what is to be done in this case??
326  // }
327 
328  // 2) Do the time stamping
329  this->FrameBufferTimeStamps[index] = vtkTimerLog::GetUniversalTime();
330 
331  if (this->FrameCount++ == 0)
332  {
333  this->StartTimeStamp = this->FrameBufferTimeStamps[index];
334  }
335 
336 
337  // 3) read the data, based on the data type and clip region information, which is reflected in frame buffer extents
338  // this is necessary as there would be cases when there is a clip region defined i.e. only data from the desired extents should be copied
339  // to the local buffer, which demands necessary advancement of deviceDataPtr
340 
341 
342  // first do the error check that whether the type arrived is same as the type requested?
343  if (type != this->AcquisitionDataType)
344  {
345  // error: data being acquired is not the same as requested
346  // do what?
347  std::cout << "Error incorrect data type" << std::endl;
348  }
349 
350  // get the pointer to actual incoming data on to a local pointer
351  unsigned char *deviceDataPtr = static_cast<unsigned char*>(dataPtr);
352 
353  // get the pointer to the correct location in the frame buffer, where this data needs to be copied
354  unsigned char *frameBufferPtr = (unsigned char *)((reinterpret_cast<vtkUnsignedCharArray*>(this->FrameBuffer[index]))->GetPointer(0));
355 
356  // Get ROI. Use this to clip video before sending
357  uROI roi = this->DataDescriptor->roi;
358  //std::cout << "FrameBufferExtent: " << this->FrameBufferExtent[0] << " " << this->FrameBufferExtent[1] << " " ;
359  //std::cout << this->FrameBufferExtent[2] << " " << this->FrameBufferExtent[3] << std::endl;
360 
361  int imagingDepth = 0;
362  int sectorPercent = 0;
363  bool linearProbe = true;
364 
365  if(!this->ult->getParamValue("b-depth", imagingDepth))
366  std::cout << "Couldn't request the BMode imaging depth." << std::endl;
367 
368  if(!this->ult->getParamValue("sector", sectorPercent))
369  std::cout << "Couldn't request the sector percent." << std::endl;
370 
371  char probeName[200];
372  if(!this->ult->getActiveProbe(probeName, 200))
373  std::cout << "Couldn't request probe name." << std::endl;
374 
375  //Path to probes.xml on on ultrasonix scanner:
376  QString probeFile = "C:/Program Files/Ultrasonix/Exam/config/probes.xml";
377  cx::SonixProbeFileReader reader(probeFile);
378  if(!reader.init())
379  {
380  std::cout << "Failed to initialize probe xml reader" << std::endl;
381  }
382  else
383  {
384  QDomNode probeNode = reader.getProbeNode(probeName);
385  linearProbe = reader.isProbeLinear(probeNode);
386 // long radius = reader.getProbeParam(probeNode, "radius"); // in microns
387 // long probeLenght = reader.getProbeLenght(probeNode); // in microns
388  }
389 
390 
391  //roi is only correct for linear probe
392  if(linearProbe)
393  this->UpdateFrameBufferExtent(roi);
394  else
395  this->ResetFrameBufferExtent();
396 
397  //std::cout << "new FrameBufferExtent: " << this->FrameBufferExtent[0] << " " << this->FrameBufferExtent[1] << " " ;
398  //std::cout << this->FrameBufferExtent[2] << " " << this->FrameBufferExtent[3] << std::endl;
399 
400  int outBytesPerRow = ((this->FrameBufferExtent[1]- this->FrameBufferExtent[0]+1)* this->FrameBufferBitsPerPixel + 7)/8;
401  outBytesPerRow += outBytesPerRow % this->FrameBufferRowAlignment;
402 
403  int inBytesPerRow = this->FrameSize[0] * this->FrameBufferBitsPerPixel/8;
404 
405  int rows = this->FrameBufferExtent[3]-this->FrameBufferExtent[2]+1;
406 
407  //check if the data received has the same size in bytes as expected
408  if (sz != inBytesPerRow*rows)
409  {
410  //error; data discrepancy!
411  //what to do?
412  if (mDebugOutput)
413  {
414  std::cout << "Data discrepancy! size: " << sz << " inBytesPerRow: " << inBytesPerRow <<" rows: " << rows << std::endl;
415  std::cout << "FrameSize[0]: " << this->FrameSize[0] << " * FrameBufferBitsPerPixel: " << this->FrameBufferBitsPerPixel << std::endl;
416  }
417  if (rows > sz / inBytesPerRow)
418  {
419  rows = sz / inBytesPerRow;
420  if (mDebugOutput)
421  std::cout << "Trying to fix this by setting rows = " << rows << std::endl;
422  }
423  else
424  {
425  if (mDebugOutput)
426  std::cout << "Keeping rows = " << rows << std::endl;
427  }
428  //TODO: more work is needed here to make sure this works for all probes and depths
429  }
430 
431  // for frame containing FC (frame count) in the beginning for data coming from cine, jump 2 bytes
432  if( (type == udtBPre) || (type == udtRF)
433  || (type == udtMPre) || (type == udtPWRF)
434  || (type == udtColorRF)
435  )
436  {
437  deviceDataPtr +=4;
438  }
439 
440 
441  deviceDataPtr += this->FrameBufferExtent[0]* this->FrameBufferBitsPerPixel/8;
442  deviceDataPtr += this->FrameBufferExtent[2]*inBytesPerRow;
443 
444  // 4) copy data to the local vtk frame buffer
445  if (outBytesPerRow == inBytesPerRow)
446  {
447  memcpy(frameBufferPtr,deviceDataPtr,inBytesPerRow*rows);
448  }
449  else
450  {
451  //std::cout << "outBytesPerRow: " << outBytesPerRow;
452  //std::cout << " rows: " << rows;
453  //std::cout << " inBytesPerRow: " << inBytesPerRow << std::endl;
454  while (--rows >= 0)
455  {
456  memcpy(frameBufferPtr,deviceDataPtr,outBytesPerRow);
457  frameBufferPtr += outBytesPerRow;
458  deviceDataPtr += inBytesPerRow;
459  }
460  }
461 
462  this->Modified();
463 
464  //TODO: Move the following into a publishFrame() function
465  //this->publishFrame();
466 
467 // boost::shared_ptr<unsigned char> dataPtr(new char[dataSize]);
468 // memcpy(dataPtr, frameBufferPtr, dataSize);
469 // emit newFrame(dataPtr);
471 
472  Frame frame;
473  frame.mTimestamp = cx::getMilliSecondsSinceEpoch()/1000; //resmapling the timestamp because we cannot find convert the original timestamp into epoch time
474 
475  //TODO: Create an enum value that identifies the pixel format
476  // Must also be implementd in cxMacGrabber.mm captureOutput() and the different formats handed by
477  // OpenIGTLinkSender::convertFrame() and by the OpenIGTLink client
478 // frame.mPixelFormat = igtl::ImageMessage::TYPE_UINT8;//Find correct value. TYPE_UINT8 = 3, TYPE_UINT32 = 7 in igtlImageMessage.h
479 
480  if (this->OutputFormat == VTK_LUMINANCE)
481  {
482  //std::cout << "8 bit" << std::endl;
483  frame.mPixelFormat = igtl::ImageMessage::TYPE_UINT8;
484  }
485  else if (this->OutputFormat == VTK_LUMINANCE_ALPHA)
486  {
487  //std::cout << "16 bit" << std::endl;
488  frame.mPixelFormat = igtl::ImageMessage::TYPE_UINT16;
489  }
490  else if (this->OutputFormat == VTK_RGBA)
491  {
492  //std::cout << "32 bit" << std::endl;
493  frame.mPixelFormat = igtl::ImageMessage::TYPE_UINT32;
494  }
495  else
496  std::cout << "Unknown pixel format (not 8 or 32)" << std::endl;
497 
498  //These values may be modified. Refresh
499  rows = this->FrameBufferExtent[3]-this->FrameBufferExtent[2]+1;
500  frameBufferPtr = (unsigned char *)((reinterpret_cast<vtkUnsignedCharArray*>(this->FrameBuffer[index]))->GetPointer(0));
501 
502  frame.mWidth = outBytesPerRow / this->NumberOfScalarComponents;
503  frame.mHeight = rows;
504  frame.mFirstPixel = frameBufferPtr;
505 
506  //This also updates the data descriptor
507  this->calculateSpacingAndOrigin();
508 
509  frame.mSpacing[0] = this->DataSpacing[0];
510  frame.mSpacing[1] = this->DataSpacing[1];
511  //frame.mOrigin[0] = this->DataOrigin[0];
512  //frame.mOrigin[1] = this->DataOrigin[1];
513  //Modify origin by ROI
514  frame.mOrigin[0] = this->DataOrigin[0] - this->FrameBufferExtent[0];//roi.ulx;
515  frame.mOrigin[1] = this->DataOrigin[1] - this->FrameBufferExtent[2];//roi.uly;
516 
517  frame.mImagingDepth = imagingDepth;
518  frame.mSectorSizeInPercent = sectorPercent;
519 
520  if(mDebugOutput)
521  {
522  //std::cout << "frame.mOrigin: " << frame.mOrigin[0] << ", " << frame.mOrigin[1];
523  //std::cout << " roi ulx, uly: " << roi.ulx << ", " << roi.uly << std::endl;
524  //std::cout << "spacing: " << this->DataSpacing[0] << ", " << this->DataSpacing[1] << std::endl;
525  //std::cout << "origin: " << this->DataOrigin[0] << ", " << this->DataOrigin[1] << std::endl;
526  }
527 
528  //Don't seem to be the correct parameter
529  //Read probe angle (0 = linear probe)
530 // int angle;
531 // if(!this->ult->getParamValue("cw-tx angle", angle))
532 // vtkErrorMacro("Couldn't request the angle.");
533 // std::cout << "cx-tx angle =" << angle << std::endl;
534 
535  //std::cout << "bottom left" << this->DataDescriptor->roi.blx << std::endl;
536  //std::cout << "bottom right" << this->DataDescriptor->roi.brx << std::endl;
537 // std::cout << "ulx: " << roi.ulx << " uly: " << roi.uly << " urx: " << roi.urx << " ury: " << roi.ury << std::endl;
538 // std::cout << "blx: " << roi.blx << " bly: " << roi.bly << " brx: " << roi.brx << " bry: " << roi.bry << std::endl;
539 
540  //Copy ROI info
541  //frame.ulx = roi.ulx;
542  //frame.uly = roi.uly;
543  //frame.urx = roi.urx;
544  //frame.ury = roi.ury;
545  //frame.brx = roi.brx;
546  //frame.bry = roi.bry;
547  //frame.blx = roi.blx;
548  //frame.bly = roi.bly;
549 
550  frame.probeName = probeName;
551 
552  // Just set ROI to FrameBufferExtent
553  frame.ulx = this->FrameBufferExtent[0] - this->FrameBufferExtent[0];
554  frame.uly = this->FrameBufferExtent[2] - this->FrameBufferExtent[2];
555  frame.urx = this->FrameBufferExtent[1] - this->FrameBufferExtent[0];
556  frame.ury = this->FrameBufferExtent[2] - this->FrameBufferExtent[2];
557  frame.brx = this->FrameBufferExtent[1] - this->FrameBufferExtent[0];
558  frame.bry = this->FrameBufferExtent[3] - this->FrameBufferExtent[2];
559  frame.blx = this->FrameBufferExtent[0] - this->FrameBufferExtent[0];
560  frame.bly = this->FrameBufferExtent[3] - this->FrameBufferExtent[2];
561 
562  // Test if the sonix status message is sent
563  //Only send status message when info is changed
564  if (lastRoiUlx != roi.ulx || lastRoiBry != roi.bry)//Initially: Check if ROI is changed
565  {
566  frame.mNewStatus = true;
567  lastRoiUlx = roi.ulx;
568  lastRoiBry = roi.bry;
569  }
570  else
571  frame.mNewStatus = false;
572 
573 // emit newFrame(frame);
574  if (this->mSonixHelper)
575  this->mSonixHelper->emitFrame(frame);
576 
577  this->FrameBufferMutex->Unlock();
578 }
579 
581 {
582  return this->Initialized;
583 }
585 {
586  // Also return false if data is not available, as freeze state is set
587  // when Sonix exam is not in research state
588  if(!this->ult->isDataAvailable((uData)(AcquisitionDataType)))
589  return false;
590 
591  if (!this->Initialized)
592  return false;
593  else
594  return this->ult->getFreezeState();
595 }
596 
597 void vtkSonixVideoSource::waitForSonixWindow()
598 {
599  HWND phandle = FindWindow(NULL, "Sonix: No connections");
600  if(phandle)
601  {
602  if (mFirstConnect)
603  {
604  std::cout << "Found Sonix window. First connect - Waiting "<< mSonixConnectionDelay << " sec to connect" << std::endl;
605  //Need to delay to make sure the Sonix exam is finished initializing...
606  vtksys::SystemTools::Delay(mSonixConnectionDelay * 1000);
607  mFirstConnect = false;
608  }
609  else
610  {
611  std::cout << "Found Sonix window. Reconnect - Waiting 3 sec to connect" << std::endl;
612  vtksys::SystemTools::Delay(3000);
613  }
614  } else
615  {
616  std::cout << "Didn't find Sonix window" << std::endl;
617  return;
618  }
619 }
620 
621 //----------------------------------------------------------------------------
623 {
624  //to do:
625  //1) connect to sonix machine using the ip address provided earlier
626  //2) set the imaging mode
627  //3) set the data acquisition type
628  //4) get the data descriptor corresponding to the data type requested
629  //5) set up the frame buffer accordingly
630  //6) set parameters like: frequency, frame rate, depth
631  //7) set the callback function which gets invoked upon arrival of new frame
632  //8) update frame buffer
633  if (this->Initialized)
634  {
635  return;
636  }
637  if(this->mUseSharedMemory)
638  this->waitForSonixWindow();
639 
640  // 1) connect to sonix machine.
641  if(!this->ult->connect(this->SonixHostIP))
642  {
643  std::cout << "Try to connect to: " << this->SonixHostIP << std::endl;
644  char *err = new char[256];
645  int sz = 256;
646  this->ult->getLastError(err,sz);
647 // vtkErrorMacro(<< "Initialize: couldn't connect to Sonix RP"<<" (" << err << ")");
648  std::cout << "Initialize: couldn't connect to Sonix RP"<<" (" << err << ")" << std::endl;
649  this->ReleaseSystemResources();
650  return;
651  }
652 
653  // 2) set the imaging mode
654  if (!this->ult->selectMode(this->ImagingMode))
655  {
656  char *err = new char[256];
657  int sz = 256;
658  this->ult->getLastError(err,sz);
659 // vtkErrorMacro(<< "Initialize: couldn't select imaging mode (" << err << ")");
660  std::cout << "Initialize: couldn't select imaging mode (" << err << ")" << std::endl;
661  this->ReleaseSystemResources();
662  return;
663  }
664 
665  // do we need to wait for a little while before the mode actually gets selected??
666  // like a thread sleep or something??
667 
668  vtksys::SystemTools::Delay(2000);
669 
670  // double-check to see if the mode has actually been set
671  if (this->ImagingMode != this->ult->getActiveImagingMode())
672  {
673  char *err = new char[256];
674  int sz = 256;
675  this->ult->getLastError(err,sz);
676 // vtkErrorMacro(<< "Initialize: Requested imaging mode could not be selected(" << err << ")");
677  std::cout << "Initialize: Requested imaging mode could not be selected(" << err << ")" << std::endl;
678  this->ReleaseSystemResources();
679  return;
680  }
681 
682  // 3) set the data acquisition type
683  // check if the desired acquisition type is actually available on desired imaging mode
684  if (!this->ult->isDataAvailable((uData)(AcquisitionDataType)))
685  {
686  char *err = new char[256];
687  int sz = 256;
688  this->ult->getLastError(err,sz);
689 // vtkErrorMacro(<< "Initialize: Requested the data aquisition type not available for selected imaging mode(" << err << ")");
690  std::cout << "Initialize: Requested the data aquisition type not available for selected imaging mode(" << err << ")" << std::endl;
691  this->ReleaseSystemResources();
692  return;
693  }
694  // actually request data, now that its available
695  if (!this->ult->setDataToAcquire(AcquisitionDataType))
696  {
697  char *err = new char[256];
698  int sz = 256;
699  this->ult->getLastError(err,sz);
700 // vtkErrorMacro(<< "Initialize: couldn't request the data aquisition type (" << err << ")");
701  std::cout << "Initialize: couldn't request the data aquisition type (" << err << ")" << std::endl;
702  this->ReleaseSystemResources();
703  return;
704  }
705 
706  // 4) get the data descriptor
707  if (!this->ult->getDataDescriptor((uData)AcquisitionDataType, *this->DataDescriptor))
708  {
709  char *err = new char[256];
710  int sz = 256;
711  this->ult->getLastError(err,sz);
712 // vtkErrorMacro(<< "Initialize: couldn't retrieve data descriptor (" << err << ")");
713  std::cout << "Initialize: couldn't retrieve data descriptor (" << err << ")" << std::endl;
714  this->ReleaseSystemResources();
715  return;
716  }
717 
718  // 5) set up the frame buffer
719  this->FrameBufferMutex->Lock();
720  this->DoFormatSetup();
721  this->FrameBufferMutex->Unlock();
722 
723 
724 
725  // 6) set parameters, currently: frequency, frame rate, depth
726  /*if (!this->ult->setParamValue(VARID_FREQ, Frequency))
727  {
728  char *err = new char[256];
729  int sz = 256;
730  this->ult->getLastError(err,sz);
731  vtkErrorMacro(<< "Initialize: couldn't set desired frequency (" << err << ")");
732  this->ReleaseSystemResources();
733  return;
734  }
735 
736  if (!this->ult->setParamValue(VARID_FRATE, FrameRate))
737  {
738  char *err = new char[256];
739  int sz = 256;
740  this->ult->getLastError(err,sz);
741  vtkErrorMacro(<< "Initialize: couldn't set desired frame rate (" << err << ")");
742  this->ReleaseSystemResources();
743  return;
744  }
745 
746  if (!this->ult->setParamValue(VARID_DEPTH, Depth))
747  {
748  char *err = new char[256];
749  int sz = 256;
750  this->ult->getLastError(err,sz);
751  vtkErrorMacro(<< "Initialize: couldn't set desired depth (" << err << ")");
752  this->ReleaseSystemResources();
753  return;
754  }*/
755 
756  // 7) set callback for receiving new frames
757  this->ult->setCallback(vtkSonixVideoSourceNewFrameCallback);
758 
759  // 8)update framebuffer
760  this->UpdateFrameBuffer();
761 
762  //ult->setSharedMemoryStatus(1);
763  ult->setSharedMemoryStatus(0);
764 
765  this->Initialized = 1;
766 }
767 
768 //----------------------------------------------------------------------------
770 {
771  this->ult->disconnect();
772  // Set system to not initialized after release
773  this->Initialized = 0;
774 }
775 
776 //----------------------------------------------------------------------------
778 {
779  if (this->Recording)
780  {
781  return;
782  }
783 
784  // ensure that the frame buffer is properly initialized
785  this->Initialize();
786  if (!this->Initialized)
787  {
788  return;
789  }
790 
791  // just do the grab, the callback does the rest
792  //this->SetStartTimeStamp(vtkTimerLog::GetUniversalTime());
793 // capGrabFrameNoStop(this->Internal->CapWnd);
794 }
795 
796 //----------------------------------------------------------------------------
798 {
799  this->Initialize();
800  if (!this->Initialized)
801  {
802  return;
803  }
804 
805  if (this->Playing)
806  {
807  this->Stop();
808  }
809 
810  if (!this->Recording)
811  {
812  this->Recording = 1;
813  this->Modified();
814  //Don't mess with freeze
815 // if(this->ult->getFreezeState())
816 // this->ult->toggleFreeze();
817  }
818 }
819 
820 //----------------------------------------------------------------------------
822 {
823  this->vtkVideoSource::Play();
824 }
825 
826 //----------------------------------------------------------------------------
828 {
829  if (this->Recording)
830  {
831  this->Recording = 0;
832  this->Modified();
833 
834 // if (!this->ult->getFreezeState())
835 // this->ult->toggleFreeze();
836  }
837  else if (this->Playing)
838  {
839  this->vtkVideoSource::Stop();
840  }
841 }
842 
843 
844 //----------------------------------------------------------------------------
846  vtkInformation * vtkNotUsed(request),
847  vtkInformationVector **vtkNotUsed(inputVector),
848  vtkInformationVector *outputVector)
849 {
850  // get the info objects
851  vtkInformation* outInfo = outputVector->GetInformationObject(0);
852 
853  int i;
854  int extent[6];
855 
856  // ensure that the hardware is initialized.
857  this->Initialize();
858 
859  for (i = 0; i < 3; i++)
860  {
861  // initially set extent to the OutputWholeExtent
862  extent[2*i] = this->OutputWholeExtent[2*i];
863  extent[2*i+1] = this->OutputWholeExtent[2*i+1];
864  // if 'flag' is set in output extent, use the FrameBufferExtent instead
865  if (extent[2*i+1] < extent[2*i])
866  {
867  extent[2*i] = 0;
868  extent[2*i+1] = \
869  this->FrameBufferExtent[2*i+1] - this->FrameBufferExtent[2*i];
870  }
871  this->FrameOutputExtent[2*i] = extent[2*i];
872  this->FrameOutputExtent[2*i+1] = extent[2*i+1];
873  }
874 
875  int numFrames = this->NumberOfOutputFrames;
876  if (numFrames < 1)
877  {
878  numFrames = 1;
879  }
880  if (numFrames > this->FrameBufferSize)
881  {
882  numFrames = this->FrameBufferSize;
883  }
884 
885  // multiply Z extent by number of frames to output
886  extent[5] = extent[4] + (extent[5]-extent[4]+1) * numFrames - 1;
887 
888  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);
889 
890  outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),extent,6);
891  // set the spacing
892  outInfo->Set(vtkDataObject::SPACING(),this->DataSpacing,3);
893 
894  // set the origin.
895  outInfo->Set(vtkDataObject::ORIGIN(),this->DataOrigin,3);
896 
897  if((this->AcquisitionDataType == udtRF) || (this->AcquisitionDataType == udtColorRF) || (this->AcquisitionDataType == udtPWRF))
898  {
899  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_SHORT,
900  this->NumberOfScalarComponents);
901  }
902  else
903  {
904  // set default data type (8 bit greyscale)
905  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR,
906  this->NumberOfScalarComponents);
907  }
908  return 1;
909 }
910 
911 
912 //----------------------------------------------------------------------------
914  vtkInformation *request,
915  vtkInformationVector **vtkNotUsed(inputVector),
916  vtkInformationVector *vtkNotUsed(outputVector))
917 {
918  vtkImageData *data = this->AllocateOutputData(this->GetOutput(), request);
919  int i,j;
920 
921  int outputExtent[6]; // will later be clipped in Z to a single frame
922  int saveOutputExtent[6]; // will possibly contain multiple frames
923  data->GetExtent(outputExtent);
924  for (i = 0; i < 6; i++)
925  {
926  saveOutputExtent[i] = outputExtent[i];
927  }
928  // clip to extent to the Z size of one frame
929  outputExtent[4] = this->FrameOutputExtent[4];
930  outputExtent[5] = this->FrameOutputExtent[5];
931 
932  int frameExtentX = this->FrameBufferExtent[1]-this->FrameBufferExtent[0]+1;
933  int frameExtentY = this->FrameBufferExtent[3]-this->FrameBufferExtent[2]+1;
934  int frameExtentZ = this->FrameBufferExtent[5]-this->FrameBufferExtent[4]+1;
935 
936  int extentX = outputExtent[1]-outputExtent[0]+1;
937  int extentY = outputExtent[3]-outputExtent[2]+1;
938  int extentZ = outputExtent[5]-outputExtent[4]+1;
939 
940  // if the output is more than a single frame,
941  // then the output will cover a partial or full first frame,
942  // several full frames, and a partial or full last frame
943 
944  // index and Z size of the first frame in the output extent
945  int firstFrame = (saveOutputExtent[4]-outputExtent[4])/extentZ;
946  int firstOutputExtent4 = saveOutputExtent[4] - extentZ*firstFrame;
947 
948  // index and Z size of the final frame in the output extent
949  int finalFrame = (saveOutputExtent[5]-outputExtent[4])/extentZ;
950  int finalOutputExtent5 = saveOutputExtent[5] - extentZ*finalFrame;
951 
952  char *outPtr = (char *)data->GetScalarPointer();
953  char *outPtrTmp;
954 
955  int inIncY = (frameExtentX*this->FrameBufferBitsPerPixel + 7)/8;
956  inIncY = ((inIncY + this->FrameBufferRowAlignment - 1)/
957  this->FrameBufferRowAlignment)*this->FrameBufferRowAlignment;
958  int inIncZ = inIncY*frameExtentY;
959 
960  int outIncX = this->FrameBufferBitsPerPixel/8;
961  int outIncY = outIncX*extentX;
962  int outIncZ = outIncY*extentY;
963 
964  int inPadX = 0;
965  int inPadY = 0;
966  // do inPadZ later
967 
968  int outPadX = -outputExtent[0];
969  int outPadY = -outputExtent[2];
970  // do outPadZ later
971 
972  if (outPadX < 0)
973  {
974  inPadX -= outPadX;
975  outPadX = 0;
976  }
977 
978  if (outPadY < 0)
979  {
980  inPadY -= outPadY;
981  outPadY = 0;
982  }
983 
984  int outX = frameExtentX - inPadX;
985  int outY = frameExtentY - inPadY;
986  // do outZ later
987 
988  if (outX > extentX - outPadX)
989  {
990  outX = extentX - outPadX;
991  }
992  if (outY > extentY - outPadY)
993  {
994  outY = extentY - outPadY;
995  }
996 
997  // if output extent has changed, need to initialize output to black
998  for (i = 0; i < 3; i++)
999  {
1000  if (saveOutputExtent[i] != this->LastOutputExtent[i])
1001  {
1002  this->LastOutputExtent[i] = saveOutputExtent[i];
1003  this->OutputNeedsInitialization = 1;
1004  }
1005  }
1006 
1007  // ditto for number of scalar components
1008  if (data->GetNumberOfScalarComponents() !=
1009  this->LastNumberOfScalarComponents)
1010  {
1011  this->LastNumberOfScalarComponents = data->GetNumberOfScalarComponents();
1012  this->OutputNeedsInitialization = 1;
1013  }
1014 
1015  // initialize output to zero only when necessary
1016  if (this->OutputNeedsInitialization)
1017  {
1018  memset(outPtr,0,
1019  (saveOutputExtent[1]-saveOutputExtent[0]+1)*
1020  (saveOutputExtent[3]-saveOutputExtent[2]+1)*
1021  (saveOutputExtent[5]-saveOutputExtent[4]+1)*outIncX);
1022  this->OutputNeedsInitialization = 0;
1023  }
1024 
1025  // we have to modify the outputExtent of the first frame,
1026  // because it might be complete (it will be restored after
1027  // the first frame has been copied to the output)
1028  int saveOutputExtent4 = outputExtent[4];
1029  outputExtent[4] = firstOutputExtent4;
1030 
1031  this->FrameBufferMutex->Lock();
1032 
1033  int index = this->FrameBufferIndex;
1034  this->FrameTimeStamp =
1035  this->FrameBufferTimeStamps[index % this->FrameBufferSize];
1036 
1037  int frame;
1038  for (frame = firstFrame; frame <= finalFrame; frame++)
1039  {
1040  if (frame == finalFrame)
1041  {
1042  outputExtent[5] = finalOutputExtent5;
1043  }
1044 
1045  vtkDataArray *frameBuffer = reinterpret_cast<vtkDataArray *>(this->FrameBuffer[(index + frame) % this->FrameBufferSize]);
1046 
1047  char *inPtr = reinterpret_cast<char*>(frameBuffer->GetVoidPointer(0));
1048  char *inPtrTmp ;
1049 
1050  extentZ = outputExtent[5]-outputExtent[4]+1;
1051  int inPadZ = 0;
1052  int outPadZ = -outputExtent[4];
1053 
1054  if (outPadZ < 0)
1055  {
1056  inPadZ -= outPadZ;
1057  outPadZ = 0;
1058  }
1059 
1060  int outZ = frameExtentZ - inPadZ;
1061 
1062  if (outZ > extentZ - outPadZ)
1063  {
1064  outZ = extentZ - outPadZ;
1065  }
1066 
1067  if (this->FlipFrames)
1068  { // apply a vertical flip while copying to output
1069  outPtr += outIncZ*outPadZ+outIncY*outPadY+outIncX*outPadX;
1070  inPtr += inIncZ*inPadZ+inIncY*(frameExtentY-inPadY-outY);
1071 
1072  for (i = 0; i < outZ; i++)
1073  {
1074  inPtrTmp = inPtr;
1075  outPtrTmp = outPtr + outIncY*outY;
1076  for (j = 0; j < outY; j++)
1077  {
1078  outPtrTmp -= outIncY;
1079  if (outX > 0)
1080  {
1081  this->UnpackRasterLine(outPtrTmp,inPtrTmp,inPadX,outX);
1082  }
1083  inPtrTmp += inIncY;
1084  }
1085  outPtr += outIncZ;
1086  inPtr += inIncZ;
1087  }
1088  }
1089  else
1090  { // don't apply a vertical flip
1091  outPtr += outIncZ*outPadZ+outIncY*outPadY+outIncX*outPadX;
1092  inPtr += inIncZ*inPadZ+inIncY*inPadY;
1093 
1094  for (i = 0; i < outZ; i++)
1095  {
1096  inPtrTmp = inPtr;
1097  outPtrTmp = outPtr;
1098  for (j = 0; j < outY; j++)
1099  {
1100  if (outX > 0)
1101  {
1102  this->UnpackRasterLine(outPtrTmp,inPtrTmp,inPadX,outX);
1103  }
1104  outPtrTmp += outIncY;
1105  inPtrTmp += inIncY;
1106  }
1107  outPtr += outIncZ;
1108  inPtr += inIncZ;
1109  }
1110  }
1111  // restore the output extent once the first frame is done
1112  outputExtent[4] = saveOutputExtent4;
1113  }
1114 
1115  this->FrameBufferMutex->Unlock();
1116 
1117  return 1;
1118 }
1119 
1120 //----------------------------------------------------------------------------
1121 // codecs
1122 
1123 
1124 //----------------------------------------------------------------------------
1125 // never run?
1126 void vtkSonixVideoSource::UnpackRasterLine(char *outptr, char *inptr,
1127  int start, int count)
1128 {
1129  char alpha = (char)(this->Opacity*255);
1130 
1131  switch (this->AcquisitionDataType)
1132  {
1133  // all these data types have 8-bit greyscale raster data
1134  case udtBPost:
1135  case udtMPost:
1136  case udtPWSpectrum:
1137  case udtElastoOverlay:
1138  {
1139  inptr += start;
1140  memcpy(outptr,inptr,count);
1141  }
1142  break;
1143 
1144  //these data types give vector data 8-bit, with FC at the start
1145  case udtBPre:
1146  case udtMPre:
1147  case udtElastoPre: //this data type does not have a FC at the start
1148  {
1149  inptr += start;
1150  memcpy(outptr,inptr,count);
1151  }
1152  break;
1153 
1154  //these data types give 16-bit vector data, to be read into int, just one component
1155  case udtColorRF:
1156  case udtPWRF:
1157  case udtRF:
1158  {
1159  inptr += 2*start;
1160  //unsigned short rawWord;
1161  //unsigned short *shInPtr = (unsigned short *)inptr;
1162  //unsigned short *shOutPtr = (unsigned short *)outptr;
1163  outptr += 2;
1164  while (--count >= 0)
1165  {
1166  *--outptr = *inptr++;
1167  *--outptr = *inptr++;
1168  outptr += 4;
1169  }
1170  //*shOutPtr++ = *shInPtr++;
1171  //*outptr++ = *inptr++;
1172 
1173 
1174  //memcpy(outptr,inptr,2*count);
1175 
1176  }
1177  break;
1178 
1179  // 16-bit vector data, but two components
1180  // don't know how to handle it as yet
1181  case udtColorVelocityVariance:
1182  this->OutputFormat = VTK_RGB;
1183  this->NumberOfScalarComponents = 2;
1184  break;
1185 
1186  //32-bit data
1187  case udtScreen:
1188  case udtBPost32:
1189  //case udtColorPost:
1190  case udtElastoCombined:
1191  case udtColorCombined:
1192  inptr += 4*start;
1193  { // must do BGRX to RGBA conversion
1194  outptr += 4;
1195  while (--count >= 0)
1196  {
1197  *--outptr = alpha;
1198  *--outptr = *inptr++;
1199  *--outptr = *inptr++;
1200  *--outptr = *inptr++;
1201  inptr++;
1202  outptr += 8;
1203  }
1204  }
1205  break;
1206 
1207  default:
1208  break;
1209 
1210  }
1211 
1212 
1213 }
1214 
1215 
1216 //----------------------------------------------------------------------------
1217 void vtkSonixVideoSource::SetOutputFormat(int format)
1218 {
1219  if (format == this->OutputFormat)
1220  {
1221  return;
1222  }
1223 
1224  this->OutputFormat = format;
1225 
1226  // convert color format to number of scalar components
1227  int numComponents;
1228 
1229  switch (this->OutputFormat)
1230  {
1231  case VTK_RGBA:
1232  numComponents = 4;
1233  break;
1234  case VTK_RGB:
1235  numComponents = 3;
1236  break;
1237  case VTK_LUMINANCE_ALPHA:
1238  numComponents = 2;
1239  break;
1240  case VTK_LUMINANCE:
1241  numComponents = 1;
1242  break;
1243  default:
1244  numComponents = 0;
1245  vtkErrorMacro(<< "SetOutputFormat: Unrecognized color format.");
1246  break;
1247  }
1248  this->NumberOfScalarComponents = numComponents;
1249 
1250  if (this->FrameBufferBitsPerPixel != numComponents*8)
1251  {
1252  this->FrameBufferMutex->Lock();
1253  this->FrameBufferBitsPerPixel = numComponents*8;
1254  if (this->Initialized)
1255  {
1256  this->UpdateFrameBuffer();
1257  this->DoFormatSetup();
1258  }
1259  this->FrameBufferMutex->Unlock();
1260  }
1261 
1262  this->Modified();
1263 }
1264 
1265 
1266 // check the current video format and set up the VTK video framebuffer to match
1268 {
1269 
1270  // use the information from the data descriptor, here's how the data descriptor looks like:
1271  // it is defined in ulterius_def.h
1272  /*
1273  class uDataDesc
1274  {
1275  public:
1277  uData type;
1279  int w;
1281  int h;
1283  int ss;
1285  uROI roi;
1286  };
1287 
1288  class uROI
1289  {
1290  public:
1292  int ulx;
1294  int uly;
1296  int urx;
1298  int ury;
1300  int brx;
1302  int bry;
1304  int blx;
1306  int bly;
1307  };
1308 
1309  */
1310 
1311 
1312  //set the frame size from the data descriptor,
1313  this->FrameSize[0] = this->DataDescriptor->w;
1314  this->FrameSize[1] = this->DataDescriptor->h;
1315  //std::cout << "width: " << this->DataDescriptor->w << " height: " << this->DataDescriptor->h << std::endl;
1316  // Set frame size based on ROI. TODO: fix for sector probes
1317  //this->FrameSize[0] = this->DataDescriptor->roi.urx - this->DataDescriptor->roi.ulx;
1318  //this->FrameSize[1] = this->DataDescriptor->roi.bly - this->DataDescriptor->roi.ury;
1319  this->FrameBufferBitsPerPixel = this->DataDescriptor->ss;
1320  switch (this->AcquisitionDataType)
1321  {
1322  // all these data types have 8-bit greyscale raster data
1323  case udtBPost:
1324  case udtMPost:
1325  case udtPWSpectrum:
1326  case udtElastoOverlay:
1327  this->OutputFormat = VTK_LUMINANCE;
1328  this->NumberOfScalarComponents = 1;
1329  break;
1330  //these data types give vector data 8-bit, with FC at the start
1331  case udtBPre:
1332  case udtMPre:
1333  case udtElastoPre: //this data type does not have a FC at the start
1334  //Not needed? Defined above
1335 // this->FrameSize[0] = this->DataDescriptor->h;
1336 // this->FrameSize[1] = this->DataDescriptor->w;
1337  this->OutputFormat = VTK_LUMINANCE;
1338  this->NumberOfScalarComponents = 1;
1339  break;
1340 
1341  //these data types give 16-bit vector data, to be read into int, just one component
1342  case udtColorRF:
1343  case udtPWRF:
1344  case udtRF:
1345  //Not needed?
1346 // this->FrameSize[0] = this->DataDescriptor->h;
1347 // this->FrameSize[1] = this->DataDescriptor->w;
1348  this->OutputFormat = VTK_LUMINANCE;
1349  this->NumberOfScalarComponents = 1;
1350  break;
1351 
1352  // 16-bit vector data, but two components
1353  // don't know how to handle it as yet
1354  case udtColorVelocityVariance:
1355  //this->OutputFormat = VTK_RGB;
1356  //this->NumberOfScalarComponents = 2;
1357  this->OutputFormat = VTK_LUMINANCE_ALPHA;
1358  this->NumberOfScalarComponents = 2;
1359  break;
1360 
1361  //32-bit data
1362  case udtScreen:
1363  case udtBPost32:
1364  //case udtColorPost:
1365  case udtElastoCombined:
1366  case udtColorCombined:
1367  this->OutputFormat = VTK_RGBA;
1368  this->NumberOfScalarComponents = 4;
1369  break;
1370  }
1371 
1372 
1373  this->calculateSpacingAndOrigin();
1374 
1375  this->Modified();
1376  this->UpdateFrameBuffer();
1377 
1378 }
1379 
1381 {
1382 // int angle;
1383 // if(!this->ult->getParamValue("cw-tx angle", angle))
1384 // vtkErrorMacro("Couldn't request the angle.");
1385 // std::cout << "cx-tx angle =" << angle << std::endl;
1386 
1387  // Update data descriptor (and region of interest descriptor)
1388  this->ult->getDataDescriptor((uData)AcquisitionDataType, *this->DataDescriptor);
1389 // uROI roi = this->DataDescriptor->roi;
1390  //std::cout << "bottom left" << this->DataDescriptor->roi.blx << std::endl;
1391  //std::cout << "bottom right" << this->DataDescriptor->roi.brx << std::endl;
1392 // std::cout << "ulx: " << roi.ulx << "uly: " << roi.uly << "urx: " << roi.urx << "ury: " << roi.ury << std::endl;
1393 // std::cout << "blx: " << roi.blx << "bly: " << roi.bly << "brx: " << roi.brx << "bry: " << roi.bry << std::endl;
1394 
1395  //Start - Added old modified code
1396 
1397  //int xO, yO;
1398  uPoint origin;
1399  if(//this->RequestGetParamValue(VARID_ORIGINX,xO) &&
1400  //this->RequestGetParamValue(VARID_ORIGINY,yO))
1401  //this->ult->getParamValue("origin x", xO) && // Do not work in sonix 5.7.1, return value is still true
1402  //this->ult->getParamValue("origin y", yO))
1403  this->ult->getParamValue("origin", origin))
1404  {
1405  //std::cout << "xO=" << xO << std::endl;
1406  //std::cout << "yO=" << yO << std::endl;
1407  }
1408  else
1409  {
1410  vtkErrorMacro("Couldn't request the origin.");
1411  }
1412  double prevOriginX = this->DataOrigin[0];
1413  double prevOriginY = this->DataOrigin[1];
1414  this->DataOrigin[0] = origin.x;//xO;
1415  this->DataOrigin[1] = origin.y;//yO;
1416  //this->DataOrigin[2] =
1417  if (mDebugOutput)
1418  if(prevOriginX != this->DataOrigin[0] || prevOriginY != this->DataOrigin[1])
1419  std::cout << "Origin: " << this->DataOrigin[0] << ", " << this->DataOrigin[1] << std::endl;
1420 
1421  //int xM, yM;
1422  uPoint microns;
1423  if(//this->RequestGetParamValue(VARID_MICRONSX,xM) &&
1424  //this->RequestGetParamValue(VARID_MICRONSY,yM))
1425  //this->ult->getParamValue("microns x", xM) && // Do not work in sonix 5.7.1
1426  //this->ult->getParamValue("microns y", yM))
1427  this->ult->getParamValue("microns", microns))
1428  {
1429  //std::cout << "xM=" << /*xM*/microns.x << std::endl;
1430  //std::cout << "yM=" << /*yM*/microns.y << std::endl;
1431  }
1432  else
1433  {
1434  vtkErrorMacro("Couldn't request the microns (spacing?).");
1435  }
1436  double prevSpacingX = this->DataSpacing[0];
1437  double prevSpacingY = this->DataSpacing[1];
1438  this->DataSpacing[0] = /*xM*/microns.x/1000.0;
1439  this->DataSpacing[1] = /*yM*/microns.y/1000.0;
1440  if(mDebugOutput && (
1441  (prevSpacingX != this->DataSpacing[0]) || (prevSpacingY != this->DataSpacing[1]) ) )
1442  {
1443  //std::cout << "Calculate spacing: x: " << microns.x << " y: " << microns.y << " result (mm): ";
1444  std::cout << "Spacing (mm): " << this->DataSpacing[0] << ", " << this->DataSpacing[1] << std::endl;
1445  }
1446  //EndAdd
1447 }
1448 
1449 void vtkSonixVideoSource::SetSonixIP(const char *SonixIP)
1450 {
1451  if (SonixIP)
1452  {
1453  this->SonixHostIP = new char[256];
1454  sprintf(this->SonixHostIP, "%s", SonixIP);
1455  std::cout << "Set SonixHostIP: " << SonixIP << std::endl;
1456  }
1457 }
1458 
1459 void vtkSonixVideoSource::setDebugOutput(bool debug)
1460 {
1461  mDebugOutput = debug;
1462 }
1464 {
1465  mSonixConnectionDelay = delay;
1466 }
1467 
1468 void vtkSonixVideoSource::setUseSharedMemory(bool useSharedMemory)
1469 {
1470  mUseSharedMemory = useSharedMemory;
1471 }
1472 
1474 {
1475  this->FrameBufferExtent[0] = max(roi.ulx, 0);
1476  this->FrameBufferExtent[1] = min(roi.urx, this->FrameSize[0] - 1);
1477  this->FrameBufferExtent[2] = max(roi.uly, 0);
1478  this->FrameBufferExtent[3] = min(roi.bly, this->FrameSize[1] - 1);
1479 }
1480 
1482 {
1483  this->FrameBufferExtent[0] = 0;
1484  this->FrameBufferExtent[1] = this->FrameSize[0] - 1;
1485  this->FrameBufferExtent[2] = 0;
1486  this->FrameBufferExtent[3] = this->FrameSize[1] - 1;
1487 }
1488 #endif // CX_WIN32
void setDebugOutput(bool debug)
Turn debug output on/off.
int brx
Definition: cxFrame.h:38
virtual void Play()
int mImagingDepth
Definition: cxFrame.h:43
void UpdateFrameBufferExtent(uROI roi)
Calculate FrameBufferExtent from roi and FrameSize.
double mTimestamp
Timestamp in seconds since 1/1/1970 (epoch)
Definition: cxFrame.h:27
Support Qt support for vtkSonixVideoSource.
Definition: SonixHelper.h:36
void setUseSharedMemory(bool useSharedMemory)
double mSpacing[2]
Definition: cxFrame.h:32
void UnpackRasterLine(char *outptr, char *inptr, int start, int count)
static vtkSonixVideoSourceCleanup Cleanup
double getMilliSecondsSinceEpoch()
Definition: cxTime.cpp:44
void ReleaseSystemResources()
void PrintSelf(ostream &os, vtkIndent indent)
int mHeight
Height in pixels.
Definition: cxFrame.h:29
std::string probeName
Definition: cxFrame.h:42
int bry
Definition: cxFrame.h:39
static vtkSonixVideoSource * GetInstance()
int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *)
void setSonixConnectionDelay(int delay)
The delay (sec) before trying to connect to sonix for the first time.
int urx
Definition: cxFrame.h:36
int mSectorSizeInPercent
Definition: cxFrame.h:44
virtual void Stop()
void setSonixHelper(SonixHelper *sonixHelper)
bool getFreezeState()
Returns true if connected to Sonix and Sonix in freeze state, false otherwise.
int blx
Definition: cxFrame.h:40
void LocalInternalGrab(void *data, int type, int sz, bool cine, int frmnum)
void SetSonixIP(const char *SonixIP)
int ulx
Definition: cxFrame.h:34
int bly
Definition: cxFrame.h:41
static void SetInstance(vtkSonixVideoSource *instance)
class VTK_ULTRASOUND_EXPORT vtkSonixVideoSource
virtual void Record()
int mWidth
Width in pixels.
Definition: cxFrame.h:28
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *)
int uly
Definition: cxFrame.h:35
void calculateSpacingAndOrigin()
Calculate spacing and origin when needed (for each frame?)
int mPixelFormat
Pixel format in OSType (FourCC)
Definition: cxFrame.h:30
int ury
Definition: cxFrame.h:37
void SetOutputFormat(int format)
void ResetFrameBufferExtent()
unsigned char * mFirstPixel
Pointer to first pixel in frame.
Definition: cxFrame.h:31
float mOrigin[2]
Definition: cxFrame.h:33
static vtkSonixVideoSource * New()
int IsInitialized()
Returns true if Sonix is initialized.
bool mNewStatus
Definition: cxFrame.h:26