1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkMILVideoSource.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkMILVideoSource.h"
16 #include "vtkTimerLog.h"
17 #include "vtkObjectFactory.h"
18 #include "vtkCriticalSection.h"
19
20 #include <mil.h>
21 #include <cctype>
22 #include <cstring>
23
24 vtkStandardNewMacro(vtkMILVideoSource);
25
26 //----------------------------------------------------------------------------
vtkMILVideoSource()27 vtkMILVideoSource::vtkMILVideoSource()
28 {
29 this->Initialized = 0;
30
31 this->FatalMILError = 0;
32
33 this->ContrastLevel = 1.0;
34 this->BrightnessLevel = 128;
35 this->HueLevel = 0.0;
36 this->SaturationLevel = 1.0;
37 this->BlackLevel = 0.0;
38 this->WhiteLevel = 255.0;
39
40 this->VideoChannel = 0;
41 this->VideoInput = VTK_MIL_MONO;
42 this->VideoInputForColor = VTK_MIL_YC;
43 this->VideoFormat = VTK_MIL_RS170;
44
45 this->FrameMaxSize[0] = 640;
46 this->FrameMaxSize[1] = 480;
47
48 this->OldHookFunction = 0;
49 this->OldUserDataPtr = 0;
50
51 this->MILAppID = 0;
52 this->MILSysID = 0;
53 this->MILDigID = 0;
54 this->MILBufID = 0;
55 //this->MILDispBufID = 0;
56 //this->MILDispID = 0;
57
58 this->MILAppInternallyAllocated = 0;
59 this->MILSysInternallyAllocated = 0;
60
61 this->MILSystemType = VTK_MIL_DEFAULT;
62 this->MILSystemNumber = M_DEFAULT;
63
64 this->MILDigitizerNumber = M_DEFAULT;
65 this->MILDigitizerDCF = nullptr;
66
67 this->MILErrorMessages = 1;
68
69 this->FlipFrames = 1; //apply vertical flip to each frame
70
71 // for accurate timing
72 this->LastTimeStamp = 0;
73 this->LastFrameCount = 0;
74 this->EstimatedFramePeriod = 0.033;
75 this->NextFramePeriod = 0.033;
76 }
77
78 //----------------------------------------------------------------------------
~vtkMILVideoSource()79 vtkMILVideoSource::~vtkMILVideoSource()
80 {
81 this->vtkMILVideoSource::ReleaseSystemResources();
82
83 delete [] this->MILDigitizerDCF;
84 this->MILDigitizerDCF = nullptr;
85
86 this->SetMILSystemType(0);
87 }
88
89 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)90 void vtkMILVideoSource::PrintSelf(ostream& os, vtkIndent indent)
91 {
92 this->Superclass::PrintSelf(os,indent);
93
94 os << indent << "VideoChannel: " << this->VideoChannel << "\n";
95
96 os << indent << "ContrastLevel: " << this->ContrastLevel << "\n";
97
98 os << indent << "BrightnessLevel: " << this->BrightnessLevel << "\n";
99
100 os << indent << "HueLevel: " << this->HueLevel << "\n";
101
102 os << indent << "SaturationLevel: " << this->SaturationLevel << "\n";
103
104 os << indent << "BlackLevel: " << this->BlackLevel << "\n";
105
106 os << indent << "WhiteLevel: " << this->WhiteLevel << "\n";
107
108 os << indent << "VideoInput: ";
109 switch (this->VideoInput)
110 {
111 case VTK_MIL_MONO:
112 os << "Mono\n";
113 break;
114 case VTK_MIL_COMPOSITE:
115 os << "Mono\n";
116 break;
117 case VTK_MIL_YC:
118 os << "Mono\n";
119 break;
120 case VTK_MIL_RGB:
121 os << "Mono\n";
122 break;
123 case VTK_MIL_DIGITAL:
124 os << "Mono\n";
125 break;
126 default:
127 os << "Unrecognized\n";
128 break;
129 }
130
131 os << indent << "VideoFormat: ";
132 switch (this->VideoFormat)
133 {
134 case VTK_MIL_RS170:
135 os << "RS170\n";
136 break;
137 case VTK_MIL_NTSC:
138 os << "NTSC\n";
139 break;
140 case VTK_MIL_CCIR:
141 os << "CCIR\n";
142 break;
143 case VTK_MIL_PAL:
144 os << "PAL\n";
145 break;
146 case VTK_MIL_SECAM:
147 os << "SECAM\n";
148 break;
149 default:
150 os << "Unrecognized\n";
151 break;
152 }
153
154 os << indent << "MILSystemType: " <<
155 (this->MILSystemType ? this->MILSystemType : "Default") << "\n";
156
157 os << indent << "MILSystemNumber: " << this->MILSystemNumber << "\n";
158
159 os << indent << "MILDigitizerDCF: " << (this->MILDigitizerDCF ?
160 this->MILDigitizerDCF : "nullptr") << "\n";
161
162 os << indent << "MILDigitizerNumber: " << this->MILDigitizerNumber << "\n";
163
164 os << indent << "MILErrorMessages: " << (this->MILErrorMessages ? "On\n" : "Off\n");
165
166 os << indent << "MILAppID: " << this->MILAppID << "\n";
167 os << indent << "MILSysID: " << this->MILSysID << "\n";
168 os << indent << "MILDigID: " << this->MILDigID << "\n";
169 os << indent << "MILBufID: " << this->MILBufID << "\n";
170 // os << indent << "MILDispBufID: " << this->MILDispBufID << "\n";
171 // os << indent << "MILDispID: " << this->MILDispID << "\n";
172 }
173
174 //----------------------------------------------------------------------------
175 // load the DLL for the specified Matrox digitizer, for MIL 5 and MIL 6
MILInterpreterForSystem(const char * system)176 char *vtkMILVideoSource::MILInterpreterForSystem(const char *system)
177 {
178 char *dll_name;
179 char *func_name;
180
181 if (strcmp(system,VTK_MIL_CORONA) == 0)
182 {
183 dll_name = "milcor";
184 func_name = "MDCoronaCommandDecoder";
185 }
186 else if (strcmp(system,VTK_MIL_METEOR) == 0)
187 {
188 dll_name = "milmet";
189 func_name = "MDMeteorCommandDecoder";
190 }
191 else if (strcmp(system,VTK_MIL_METEOR_II) == 0)
192 {
193 dll_name = "milmet2";
194 func_name = "MDMeteorIICommandDecoder";
195 }
196 else if (strcmp(system,VTK_MIL_METEOR_II_DIG) == 0)
197 {
198 dll_name = "milmet2d";
199 func_name = "MDMeteorIIDigCommandDecoder";
200 }
201 else if (strcmp(system,VTK_MIL_PULSAR) == 0)
202 {
203 dll_name = "milpul";
204 func_name = "MDPulsarCommandDecoder";
205 }
206 else if (strcmp(system,VTK_MIL_GENESIS) == 0)
207 {
208 dll_name = "milgen";
209 func_name = "MDGenesisCommandDecoder";
210 }
211 else if (strcmp(system,VTK_MIL_ORION) == 0)
212 {
213 dll_name = "milorion";
214 func_name = "MDOrionCommandDecoder";
215 }
216 else
217 {
218 dll_name = "unknown";
219 func_name = "unknown";
220 }
221
222 // first try mil.dll (for later versions of mil)
223 this->MILInterpreterDLL = "mil";
224 HINSTANCE mil_lib = LoadLibrary("mil");
225 if (mil_lib == 0)
226 {
227 return nullptr;
228 }
229 void *proc_address = (void *)GetProcAddress(mil_lib,func_name);
230 if (proc_address)
231 {
232 return proc_address;
233 }
234
235 // then try the device-specific dll
236 this->MILInterpreterDLL = dll_name;
237 mil_lib = LoadLibrary(dll_name);
238
239 if (mil_lib == 0)
240 {
241 return nullptr;
242 }
243
244 return (char *)GetProcAddress(mil_lib,func_name);
245 }
246
247 //----------------------------------------------------------------------------
vtkMILVideoSourceSetChannel(long digID,int channel)248 static void vtkMILVideoSourceSetChannel(long digID, int channel)
249 {
250 if (digID == 0)
251 {
252 return;
253 }
254
255 int mil_channel = M_DEFAULT;
256
257 switch(channel)
258 {
259 case 0:
260 mil_channel = M_CH0;
261 break;
262 case 1:
263 mil_channel = M_CH1;
264 break;
265 case 2:
266 mil_channel = M_CH2;
267 break;
268 case 3:
269 mil_channel = M_CH3;
270 break;
271 }
272
273 MdigChannel(digID,mil_channel);
274 }
275
276 //----------------------------------------------------------------------------
vtkMILVideoSourceSetLevel(long digID,int ref,float level)277 static void vtkMILVideoSourceSetLevel(long digID, int ref, float level)
278 {
279 if (digID == 0)
280 {
281 return;
282 }
283
284 long int_level = M_MIN_LEVEL + level*(M_MAX_LEVEL-M_MIN_LEVEL);
285
286 if (int_level < M_MIN_LEVEL)
287 {
288 int_level = M_MIN_LEVEL;
289 }
290
291 if (int_level > M_MAX_LEVEL)
292 {
293 int_level = M_MAX_LEVEL;
294 }
295
296 MdigReference(digID,ref,int_level);
297 }
298
299 //----------------------------------------------------------------------------
vtkMILVideoSourceSetSize(long digID,int size[3],int maxSize[2])300 static void vtkMILVideoSourceSetSize(long digID, int size[3], int maxSize[2])
301 {
302 if (digID == 0)
303 {
304 return;
305 }
306
307 int shrink_x = maxSize[0]/size[0];
308 int shrink_y = maxSize[1]/size[1];
309 if (shrink_x < 1)
310 {
311 shrink_x = 1;
312 }
313 if (shrink_y < 1)
314 {
315 shrink_y = 1;
316 }
317
318 // convert shrink_x, shrink_y to power of 2
319 int i;
320 for (i = 0; shrink_x; i++)
321 {
322 shrink_x = shrink_x >> 1;
323 }
324 shrink_x = 1 << (i-1);
325 for (i = 0; shrink_y; i++)
326 {
327 shrink_y = shrink_y >> 1;
328 }
329 shrink_y = 1 << (i-1);
330
331 MdigControl(digID,M_GRAB_SCALE_X,1.0/shrink_x);
332 MdigControl(digID,M_GRAB_SCALE_Y,1.0/shrink_y);
333 }
334
335 //----------------------------------------------------------------------------
Initialize()336 void vtkMILVideoSource::Initialize()
337 {
338 static char *system_types[] = { VTK_MIL_METEOR, VTK_MIL_METEOR_II,
339 VTK_MIL_METEOR_II_DIG, VTK_MIL_METEOR_II_CL,
340 VTK_MIL_METEOR_II_1394, VTK_MIL_CORONA_II,
341 VTK_MIL_CORONA, VTK_MIL_PULSAR,
342 VTK_MIL_GENESIS, VTK_MIL_GENESIS_PLUS,
343 VTK_MIL_ORION, VTK_MIL_CRONOS,
344 VTK_MIL_ODYSSEY, 0 };
345
346 if (this->Initialized || this->FatalMILError)
347 {
348 return;
349 }
350
351 this->Initialized = 1;
352
353 // update the frame buffer now just in case there is an error
354 this->UpdateFrameBuffer();
355
356 if (this->MILAppID == 0)
357 {
358 this->MILAppID = MappAlloc(M_DEFAULT,M_NULL);
359 if (this->MILAppID == 0)
360 {
361 this->ReleaseSystemResources();
362 vtkErrorMacro(<< "Initialize: couldn't open MIL application\n");
363 return;
364 }
365 this->MILAppInternallyAllocated = 1;
366 }
367
368 long version = MappInquire(M_VERSION,M_NULL);
369
370 if (this->MILSysID == 0)
371 {
372 char *systemType;
373 if (this->MILSystemType != VTK_MIL_DEFAULT)
374 { // asked for a particular system by name
375 if (version >= 7)
376 { // try MIL 7 style of allocation
377 char tmptext[256];
378 strncpy(tmptext,"\\\\.\\",4);
379 strncpy(&tmptext[4],this->MILSystemType,252);
380 this->MILSysID = MsysAlloc(tmptext,this->MILSystemNumber,
381 M_DEFAULT,M_NULL);
382 }
383 else
384 { // try MIL 5, MIL 6 which requires loading the appropriate DLL
385 systemType = this->MILInterpreterForSystem(this->MILSystemType);
386 if (systemType)
387 {
388 this->MILSysID = MsysAlloc(systemType, this->MILSystemNumber,
389 M_DEFAULT,M_NULL);
390 }
391 }
392
393 if (this->MILSysID == 0)
394 {
395 this->ReleaseSystemResources();
396 vtkErrorMacro(<< "Initialize: couldn't find " << this->MILInterpreterDLL << ".dll\n");
397 return;
398 }
399 }
400 else
401 { // try for any known MIL system
402 MappControl(M_ERROR,M_PRINT_DISABLE);
403 int i;
404 for (i = 0; this->MILSysID == 0 && system_types[i] != 0; i++)
405 {
406 if (version >= 7)
407 {
408 // try MIL 7 style of allocation
409 char tmptext[256];
410 snprintf(tmptext,sizeof(tmptext),"\\\\.\\%s",system_types[i]);
411 this->MILSysID = MsysAlloc(tmptext,this->MILSystemNumber,
412 M_DEFAULT,M_NULL);
413 }
414 else
415 { // try MIL 5, MIL 6 which requires loading the appropriate DLL
416 systemType = this->MILInterpreterForSystem(system_types[i]);
417 if (systemType)
418 {
419 this->MILSysID = MsysAlloc(systemType,this->MILSystemNumber,
420 M_DEFAULT,M_NULL);
421 }
422 }
423 }
424 if (system_types[i] == 0)
425 {
426 this->ReleaseSystemResources();
427 vtkErrorMacro(<< "Initialize: Couldn't find a Matrox frame grabber on the system\n");
428 return;
429 }
430 MappControl(M_ERROR,M_PRINT_ENABLE);
431 }
432 this->MILSysInternallyAllocated = 1;
433 }
434
435 this->AllocateMILBuffer();
436
437 this->AllocateMILDigitizer();
438
439 MappControl(M_ERROR,
440 ( this->MILErrorMessages ? M_PRINT_ENABLE : M_PRINT_DISABLE ));
441
442 // update frame buffer again to reflect any changes
443 this->UpdateFrameBuffer();
444 }
445
446 //----------------------------------------------------------------------------
ReleaseSystemResources()447 void vtkMILVideoSource::ReleaseSystemResources()
448 {
449 if (this->MILAppID != 0)
450 {
451 MappControl(M_ERROR, M_PRINT_DISABLE);
452 }
453 if (this->MILDigID)
454 {
455 if (this->Recording)
456 {
457 MdigHalt(this->MILDigID);
458 }
459 MdigGrabWait(this->MILDigID,M_GRAB_END);
460 this->Recording = 0;
461 }
462 /*
463 if (this->MILDispID != 0)
464 {
465 MdispDeselect(this->MILDispID,this->MILDispBufID);
466 MdispFree(this->MILDispID);
467 this->MILDispID = 0;
468 }
469 if (this->MILDispBufID != 0)
470 {
471 MbufFree(this->MILDispBufID);
472 this->MILDispBufID = 0;
473 }
474 */
475 if (this->MILBufID != 0)
476 {
477 MbufFree(this->MILBufID);
478 this->MILBufID = 0;
479 }
480 if (this->MILDigID != 0)
481 {
482 // The MdigFree call never returns if it is called by atexit(),
483 // and it doesn't seem to hurt anything if it isn't called.
484 MdigFree(this->MILDigID);
485 this->MILDigID = 0;
486 }
487 if (this->MILSysInternallyAllocated && this->MILSysID != 0)
488 {
489 MsysFree(this->MILSysID);
490 this->MILSysID = 0;
491 }
492 if (this->MILAppInternallyAllocated && this->MILAppID != 0)
493 {
494 MappFree(this->MILAppID);
495 this->MILAppID = 0;
496 }
497 this->Initialized = 0;
498 this->FatalMILError = 0;
499 }
500
501 //----------------------------------------------------------------------------
vtkMILVideoSourceHook(long HookType,MIL_ID EventID,void * UserPtr)502 long MFTYPE vtkMILVideoSourceHook(long HookType, MIL_ID EventID, void *UserPtr)
503 {
504 vtkMILVideoSource *self = (vtkMILVideoSource *)UserPtr;
505
506 if (HookType == M_GRAB_FRAME_END)
507 {
508 double time = 1000;
509 float rate = self->GetFrameRate();
510 int format = self->GetVideoFormat();
511 int frame_stride;
512 if (rate > 0)
513 {
514 frame_stride = (int)(30/rate);
515 if (format == VTK_MIL_CCIR ||
516 format == VTK_MIL_PAL ||
517 format == VTK_MIL_SECAM)
518 {
519 frame_stride = (int)(25/rate);
520 }
521 }
522 if ((rate > 0 && ++(self->FrameCounter) >= frame_stride) ||
523 self->ForceGrab)
524 {
525 self->InternalGrab();
526 self->FrameCounter = 0;
527 self->ForceGrab = 0;
528 }
529 }
530 if (self->OldHookFunction)
531 {
532 return ((MDIGHOOKFCTPTR)self->OldHookFunction)(HookType,EventID,
533 self->OldUserDataPtr);
534 }
535 else
536 {
537 return M_NULL;
538 }
539 }
540
541 //----------------------------------------------------------------------------
InternalGrab()542 void vtkMILVideoSource::InternalGrab()
543 {
544 this->FrameBufferMutex->Lock();
545
546 if (this->AutoAdvance)
547 {
548 this->AdvanceFrameBuffer(1);
549 if (this->FrameIndex + 1 < this->FrameBufferSize)
550 {
551 this->FrameIndex++;
552 }
553 }
554
555 int index = this->FrameBufferIndex;
556
557 this->FrameBufferTimeStamps[index] =
558 this->CreateTimeStampForFrame(this->LastFrameCount + 1);
559 if (this->FrameCount++ == 0)
560 {
561 this->StartTimeStamp = this->FrameBufferTimeStamps[index];
562 }
563
564 void *ptr = ((reinterpret_cast<vtkDataArray *>( \
565 this->FrameBuffer[index]))->GetVoidPointer(0));
566 int depth = this->FrameBufferBitsPerPixel/8;
567
568 int offsetX = this->FrameBufferExtent[0];
569 int offsetY = this->FrameBufferExtent[2];
570
571 int sizeX = this->FrameBufferExtent[1] - this->FrameBufferExtent[0] + 1;
572 int sizeY = this->FrameBufferExtent[3] - this->FrameBufferExtent[2] + 1;
573
574 if (sizeX > 0 && sizeY > 0)
575 {
576 if (depth == 1)
577 {
578 MbufGet2d(this->MILBufID,offsetX,offsetY,sizeX,sizeY,ptr);
579 }
580 else if (depth == 3)
581 {
582 MbufGetColor2d(this->MILBufID,M_RGB24+M_PACKED,M_ALL_BAND,
583 offsetX,offsetY,sizeX,sizeY,ptr);
584 }
585 else if (depth == 4)
586 {
587 MbufGetColor2d(this->MILBufID,M_RGB32+M_PACKED,M_ALL_BAND,
588 offsetX,offsetY,sizeX,sizeY,ptr);
589 }
590 }
591
592 this->Modified();
593
594 this->FrameBufferMutex->Unlock();
595 }
596
597 //----------------------------------------------------------------------------
598 // for accurate timing of the transformation: this solves a differential
599 // equation that works to smooth out the jitter in the times that
600 // are returned by vtkTimerLog::GetUniversalTime() i.e. the system clock.
CreateTimeStampForFrame(unsigned long framecount)601 double vtkMILVideoSource::CreateTimeStampForFrame(unsigned long framecount)
602 {
603 double timestamp = vtkTimerLog::GetUniversalTime();
604
605 double frameperiod = ((timestamp - this->LastTimeStamp)/
606 (framecount - this->LastFrameCount));
607 double deltaperiod = (frameperiod - this->EstimatedFramePeriod)*0.01;
608
609 this->EstimatedFramePeriod += deltaperiod;
610 this->LastTimeStamp += ((framecount - this->LastFrameCount)*
611 this->NextFramePeriod);
612 this->LastFrameCount = framecount;
613
614 double diffperiod = (timestamp - this->LastTimeStamp);
615
616 if (diffperiod < -0.2 || diffperiod > 0.2)
617 { // time is off by more than 0.2 seconds: reset the clock
618 this->EstimatedFramePeriod -= deltaperiod;
619 this->NextFramePeriod = this->EstimatedFramePeriod;
620 this->LastTimeStamp = timestamp;
621 return timestamp;
622 }
623
624 diffperiod *= 0.1;
625 double maxdiff = 0.001;
626 if (diffperiod < -maxdiff)
627 {
628 diffperiod = -maxdiff;
629 }
630 else if (diffperiod > maxdiff)
631 {
632 diffperiod = maxdiff;
633 }
634
635 this->NextFramePeriod = this->EstimatedFramePeriod + diffperiod;
636
637 return this->LastTimeStamp;
638 }
639
640 //----------------------------------------------------------------------------
641 // Circulate the buffer and grab a frame.
642 // This particular implementation just copies random noise into the frames,
643 // you will certainly want to override this method (also note that this
644 // is the only method which you really have to override)
Grab()645 void vtkMILVideoSource::Grab()
646 {
647 // ensure that the hardware is initialized.
648 this->Initialize();
649 if (!this->Initialized)
650 {
651 return;
652 }
653
654 if (!this->Recording)
655 {
656 MdigGrab(this->MILDigID,this->MILBufID);
657 MdigGrabWait(this->MILDigID,M_GRAB_END);
658 this->InternalGrab();
659 }
660 else
661 {
662 this->ForceGrab = 1;
663 }
664 }
665
666 //----------------------------------------------------------------------------
Play()667 void vtkMILVideoSource::Play()
668 {
669 vtkVideoSource::Play();
670 }
671
672 //----------------------------------------------------------------------------
Record()673 void vtkMILVideoSource::Record()
674 {
675 this->Initialize();
676 if (!this->Initialized)
677 {
678 return;
679 }
680
681 if (this->Playing)
682 {
683 this->Stop();
684 }
685
686 if (this->Recording)
687 {
688 return;
689 }
690
691 this->Recording = 1;
692 this->FrameCount = 0;
693
694 MdigInquire(this->MILDigID,M_GRAB_FRAME_END_HANDLER_PTR,
695 &this->OldHookFunction);
696 MdigInquire(this->MILDigID,M_GRAB_FRAME_END_HANDLER_USER_PTR,
697 &this->OldUserDataPtr);
698 MdigHookFunction(this->MILDigID,M_GRAB_FRAME_END,
699 &vtkMILVideoSourceHook,
700 (void *)this);
701 this->FrameCounter = 0;
702 this->ForceGrab = 0;
703
704 // for accurate timing
705 this->LastTimeStamp = vtkTimerLog::GetUniversalTime();
706
707 // this will call the hook function on every frame
708 MdigGrabContinuous(this->MILDigID,this->MILBufID);
709
710 this->Modified();
711 }
712
713 //----------------------------------------------------------------------------
Stop()714 void vtkMILVideoSource::Stop()
715 {
716 if (this->Playing)
717 {
718 vtkVideoSource::Stop();
719 }
720
721 if (!this->Recording)
722 {
723 return;
724 }
725
726 this->Recording = 0;
727
728 MdigHalt(this->MILDigID);
729 MdigHookFunction(this->MILDigID,M_GRAB_FRAME_END,
730 (MDIGHOOKFCTPTR)this->OldHookFunction,
731 this->OldUserDataPtr);
732 this->OldHookFunction = 0;
733 MdigGrabWait(this->MILDigID,M_GRAB_END);
734
735 this->Modified();
736 }
737
738 //----------------------------------------------------------------------------
SetMILErrorMessages(int yesno)739 void vtkMILVideoSource::SetMILErrorMessages(int yesno)
740 {
741 if (this->MILErrorMessages == yesno)
742 {
743 return;
744 }
745
746 this->MILErrorMessages = yesno;
747 this->Modified();
748
749 if (this->Initialized)
750 {
751 MappControl(M_ERROR,( yesno ? M_PRINT_ENABLE : M_PRINT_DISABLE ));
752 }
753 }
754
755 //----------------------------------------------------------------------------
SetFrameSize(int x,int y,int z)756 void vtkMILVideoSource::SetFrameSize(int x, int y, int z)
757 {
758 if (x == this->FrameSize[0] &&
759 y == this->FrameSize[1] &&
760 z == this->FrameSize[2])
761 {
762 return;
763 }
764
765 if (x < 1 || y < 1 || z != 1)
766 {
767 vtkErrorMacro(<< "SetFrameSize: Illegal frame size");
768 return;
769 }
770
771 this->FrameSize[0] = x;
772 this->FrameSize[1] = y;
773 this->FrameSize[2] = z;
774
775 if (this->Initialized)
776 {
777 this->FrameBufferMutex->Lock();
778 this->UpdateFrameBuffer();
779 vtkMILVideoSourceSetSize(this->MILDigID,
780 this->FrameSize,this->FrameMaxSize);
781 this->AllocateMILBuffer();
782 this->FrameBufferMutex->Unlock();
783 }
784
785 this->Modified();
786 }
787
788 //----------------------------------------------------------------------------
SetOutputFormat(int format)789 void vtkMILVideoSource::SetOutputFormat(int format)
790 {
791 if (format == this->OutputFormat)
792 {
793 return;
794 }
795
796 this->OutputFormat = format;
797
798 // convert color format to number of scalar components
799 int numComponents;
800
801 switch (this->OutputFormat)
802 {
803 case VTK_RGBA:
804 numComponents = 4;
805 break;
806 case VTK_RGB:
807 numComponents = 3;
808 break;
809 case VTK_LUMINANCE:
810 numComponents = 1;
811 break;
812 default:
813 vtkErrorMacro(<< "SetOutputFormat: Unrecognized color format.");
814 break;
815 }
816 this->NumberOfScalarComponents = numComponents;
817
818 if (this->FrameBufferBitsPerPixel != numComponents*8)
819 {
820 this->FrameBufferMutex->Lock();
821 this->FrameBufferBitsPerPixel = numComponents*8;
822 if (this->Initialized)
823 {
824 this->UpdateFrameBuffer();
825 this->AllocateMILBuffer();
826 }
827 this->FrameBufferMutex->Unlock();
828 }
829
830 // set video format to match the output format
831 if (this->OutputFormat == VTK_RGB || this->OutputFormat == VTK_RGBA)
832 {
833 if (this->VideoFormat == VTK_MIL_RS170)
834 {
835 this->SetVideoFormat(VTK_MIL_NTSC);
836 }
837 if (this->VideoFormat == VTK_MIL_CCIR)
838 {
839 this->SetVideoFormat(VTK_MIL_PAL);
840 }
841 if (this->VideoInput == VTK_MIL_MONO)
842 {
843 this->SetVideoInput(this->VideoInputForColor);
844 }
845 }
846 if (this->OutputFormat == VTK_LUMINANCE)
847 {
848 if (this->VideoFormat == VTK_MIL_NTSC)
849 {
850 this->SetVideoFormat(VTK_MIL_RS170);
851 }
852 if (this->VideoFormat == VTK_MIL_PAL)
853 {
854 this->SetVideoFormat(VTK_MIL_CCIR);
855 }
856 if (this->VideoInput == VTK_MIL_YC || this->VideoInput == VTK_MIL_COMPOSITE)
857 {
858 this->VideoInputForColor = this->VideoInput;
859 this->SetVideoInput(VTK_MIL_MONO);
860 }
861 }
862
863 this->Modified();
864 }
865
866 //----------------------------------------------------------------------------
SetVideoFormat(int format)867 void vtkMILVideoSource::SetVideoFormat(int format)
868 {
869 if (this->VideoFormat == format)
870 {
871 return;
872 }
873
874 this->VideoFormat = format;
875
876 // don't do anything if the digitizer isn't initialized
877 if (this->Initialized)
878 {
879 this->AllocateMILDigitizer();
880 }
881 }
882
883 //----------------------------------------------------------------------------
SetVideoInput(int input)884 void vtkMILVideoSource::SetVideoInput(int input)
885 {
886 if (this->VideoInput == input)
887 {
888 return;
889 }
890
891 this->VideoInput = input;
892
893 // don't do anything if the digitizer isn't initialized
894 if (this->Initialized)
895 {
896 this->AllocateMILDigitizer();
897 }
898 }
899
900 //----------------------------------------------------------------------------
SetVideoChannel(int channel)901 void vtkMILVideoSource::SetVideoChannel(int channel)
902 {
903 if (this->VideoChannel == channel)
904 {
905 return;
906 }
907
908 this->VideoChannel = channel;
909 this->Modified();
910
911 vtkMILVideoSourceSetChannel(this->MILDigID,channel);
912 }
913
914 //----------------------------------------------------------------------------
SetBrightnessLevel(float brightness)915 void vtkMILVideoSource::SetBrightnessLevel(float brightness)
916 {
917 if (this->BrightnessLevel == brightness)
918 {
919 return;
920 }
921
922 this->BrightnessLevel = brightness;
923 this->Modified();
924
925 vtkMILVideoSourceSetLevel(this->MILDigID,M_BRIGHTNESS_REF,brightness/255.0);
926 }
927
928 //----------------------------------------------------------------------------
SetContrastLevel(float contrast)929 void vtkMILVideoSource::SetContrastLevel(float contrast)
930 {
931 if (this->ContrastLevel == contrast)
932 {
933 return;
934 }
935
936 this->ContrastLevel = contrast;
937 this->Modified();
938
939 vtkMILVideoSourceSetLevel(this->MILDigID,M_CONTRAST_REF,contrast/2.0);
940 }
941
942 //----------------------------------------------------------------------------
SetHueLevel(float hue)943 void vtkMILVideoSource::SetHueLevel(float hue)
944 {
945 if (this->HueLevel == hue)
946 {
947 return;
948 }
949
950 this->HueLevel = hue;
951 this->Modified();
952
953 vtkMILVideoSourceSetLevel(this->MILDigID,M_HUE_REF,0.5+hue);
954 }
955
956 //----------------------------------------------------------------------------
SetSaturationLevel(float saturation)957 void vtkMILVideoSource::SetSaturationLevel(float saturation)
958 {
959 if (this->SaturationLevel == saturation)
960 {
961 return;
962 }
963
964 this->SaturationLevel = saturation;
965 this->Modified();
966
967 vtkMILVideoSourceSetLevel(this->MILDigID,M_SATURATION_REF,saturation/2.0);
968 }
969
970 //----------------------------------------------------------------------------
SetBlackLevel(float black)971 void vtkMILVideoSource::SetBlackLevel(float black)
972 {
973 if (this->BlackLevel == black)
974 {
975 return;
976 }
977
978 this->BlackLevel = black;
979 this->Modified();
980
981 vtkMILVideoSourceSetLevel(this->MILDigID,M_BLACK_REF,black/255);
982 }
983
984 //----------------------------------------------------------------------------
SetWhiteLevel(float white)985 void vtkMILVideoSource::SetWhiteLevel(float white)
986 {
987 if (this->WhiteLevel == white)
988 {
989 return;
990 }
991
992 this->WhiteLevel = white;
993 this->Modified();
994
995 vtkMILVideoSourceSetLevel(this->MILDigID,M_WHITE_REF,white/255);
996 }
997
998 //----------------------------------------------------------------------------
AllocateMILDigitizer()999 void vtkMILVideoSource::AllocateMILDigitizer()
1000 {
1001 char *format = "M_NTSC";
1002 int recording = this->Recording;
1003
1004 if (this->MILDigID)
1005 {
1006 if (recording)
1007 {
1008 this->Stop();
1009 }
1010 }
1011
1012 if (this->MILDigID != 0)
1013 {
1014 MdigFree(this->MILDigID);
1015 }
1016
1017 switch (this->VideoFormat)
1018 {
1019 case VTK_MIL_RS170:
1020 format = "M_RS170";
1021 if (this->VideoInput == VTK_MIL_RGB)
1022 {
1023 format = "M_RS170_VIA_RGB";
1024 }
1025 break;
1026 case VTK_MIL_NTSC:
1027 format = "M_NTSC";
1028 if (this->VideoInput == VTK_MIL_YC)
1029 {
1030 format = "M_NTSC_YC";
1031 }
1032 if (this->VideoInput == VTK_MIL_RGB)
1033 {
1034 format = "M_NTSC_RGB";
1035 }
1036 break;
1037 case VTK_MIL_CCIR:
1038 format = "M_CCIR";
1039 if (this->VideoInput == VTK_MIL_RGB)
1040 {
1041 format = "M_CCIR_VIA_RGB";
1042 }
1043 this->FrameMaxSize[0] = 768;
1044 this->FrameMaxSize[1] = 576;
1045 break;
1046 case VTK_MIL_PAL:
1047 case VTK_MIL_SECAM:
1048 format = "M_PAL";
1049 if (this->VideoInput == VTK_MIL_YC)
1050 {
1051 format = "M_PAL_YC";
1052 }
1053 if (this->VideoInput == VTK_MIL_RGB)
1054 {
1055 format = "M_PAL_RGB";
1056 }
1057 this->FrameMaxSize[0] = 768;
1058 this->FrameMaxSize[1] = 576;
1059 break;
1060 case VTK_MIL_NONSTANDARD:
1061 this->FrameMaxSize[0] = 0;
1062 this->FrameMaxSize[1] = 0;
1063 break;
1064 default:
1065 vtkWarningMacro(<< "AllocateMILDigitizer: Unknown video format");
1066 }
1067
1068 if (this->MILDigitizerDCF)
1069 {
1070 format = this->MILDigitizerDCF;
1071 }
1072
1073 this->MILDigID = MdigAlloc(this->MILSysID,this->MILDigitizerNumber,format,
1074 M_DEFAULT,M_NULL);
1075
1076 if (this->MILDigID == 0)
1077 {
1078 vtkErrorMacro(<< "AllocateMILDigitizer: Couldn't allocate MIL Digitizer\n");
1079 return;
1080 }
1081
1082 vtkMILVideoSourceSetSize(this->MILDigID,this->FrameSize,this->FrameMaxSize);
1083
1084 vtkMILVideoSourceSetChannel(this->MILDigID,this->VideoChannel);
1085
1086 if (this->BrightnessLevel != 128)
1087 {
1088 vtkMILVideoSourceSetLevel(this->MILDigID,M_BRIGHTNESS_REF,
1089 this->BrightnessLevel/255);
1090 }
1091 if (this->ContrastLevel != 1.0)
1092 {
1093 vtkMILVideoSourceSetLevel(this->MILDigID,M_CONTRAST_REF,
1094 this->ContrastLevel/2.0);
1095 }
1096 if (this->HueLevel != 0.0)
1097 {
1098 vtkMILVideoSourceSetLevel(this->MILDigID,M_HUE_REF,
1099 0.5+this->HueLevel);
1100 }
1101 if (this->SaturationLevel != 1.0)
1102 {
1103 vtkMILVideoSourceSetLevel(this->MILDigID,M_SATURATION_REF,
1104 this->SaturationLevel/2.0);
1105 }
1106 if (this->BlackLevel != 0.0)
1107 {
1108 vtkMILVideoSourceSetLevel(this->MILDigID,M_BLACK_REF,
1109 this->BlackLevel/255);
1110 }
1111 if (this->WhiteLevel != 255.0)
1112 {
1113 vtkMILVideoSourceSetLevel(this->MILDigID,M_WHITE_REF,
1114 this->WhiteLevel/255);
1115 }
1116
1117 if (this->MILDigID && this->MILBufID)
1118 {
1119 if (recording)
1120 {
1121 this->Record();
1122 }
1123 }
1124 }
1125
1126 //----------------------------------------------------------------------------
AllocateMILBuffer()1127 void vtkMILVideoSource::AllocateMILBuffer()
1128 {
1129 int recording = this->Recording;
1130
1131 if (this->MILDigID != 0)
1132 {
1133 if (recording)
1134 {
1135 this->Stop();
1136 }
1137 }
1138
1139 if (this->MILBufID != 0)
1140 {
1141 MbufFree(this->MILBufID);
1142 }
1143
1144 if (this->OutputFormat != VTK_LUMINANCE &&
1145 this->OutputFormat != VTK_RGB &&
1146 this->OutputFormat != VTK_RGBA)
1147 {
1148 vtkWarningMacro(<< "Initialize: unsupported OutputFormat");
1149 this->vtkVideoSource::SetOutputFormat(VTK_LUMINANCE);
1150 }
1151
1152 if (this->OutputFormat == VTK_LUMINANCE)
1153 {
1154 this->MILBufID = MbufAlloc2d(this->MILSysID,this->FrameSize[0],
1155 this->FrameSize[1],
1156 8+M_UNSIGNED,M_IMAGE+M_GRAB,M_NULL);
1157 }
1158 else if (this->OutputFormat == VTK_RGB)
1159 {
1160 this->MILBufID = MbufAllocColor(this->MILSysID,3,this->FrameSize[0],
1161 this->FrameSize[1],
1162 8+M_UNSIGNED,M_IMAGE+M_GRAB+ \
1163 M_RGB24+M_PACKED,
1164 M_NULL);
1165 }
1166 else if (this->OutputFormat == VTK_RGBA)
1167 {
1168 this->MILBufID = MbufAllocColor(this->MILSysID,3,this->FrameSize[0],
1169 this->FrameSize[1],
1170 8+M_UNSIGNED,M_IMAGE+M_GRAB+M_RGB32+ \
1171 M_PACKED,
1172 M_NULL);
1173 }
1174
1175 if (this->MILBufID == 0)
1176 {
1177 vtkErrorMacro(<< "AllocateMILBuffer: Couldn't allocate MIL Buffer\n");
1178 return;
1179 }
1180
1181 if (this->MILDigID != 0 && this->MILBufID != 0)
1182 {
1183 if (recording)
1184 {
1185 this->Record();
1186 }
1187 }
1188 }
1189
1190
1191
1192