root/OpenSceneGraph/trunk/src/osgPlugins/quicktime/QuicktimeLiveImageStream.cpp @ 13041

Revision 13041, 22.1 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2007 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <cstdlib>
15
16#include <osg/Notify>
17#include <osg/Image>
18#include <osg/Timer>
19#include <osg/ref_ptr>
20#include <osg/Referenced>
21#include <osg/Notify>
22#include <osgDB/Registry>
23#include <osg/GL>
24#include <osg/Endian>
25#include <osg/Timer>
26#include <osgDB/FileNameUtils>
27
28#include <OpenThreads/ScopedLock>
29#include <OpenThreads/Thread>
30
31#include "QuicktimeLiveImageStream.h"
32#include "QTLiveUtils.h"
33
34// Constructor: setup and start thread
35QuicktimeLiveImageStream::QuicktimeLiveImageStream(std::string fileName) : ImageStream()
36{
37    setOrigin(osg::Image::TOP_LEFT);
38    _status = ImageStream::PAUSED;
39
40    //probe_video_digitizer_components();
41    //probe_sequence_grabber_components();
42
43    // Initialise QT
44    //    initialize_quicktime_qtml();
45    //    enter_quicktime_movies();
46    //
47    load(fileName);
48}
49
50
51// Deconstructor: stop and terminate thread
52QuicktimeLiveImageStream::~QuicktimeLiveImageStream()
53{
54    // Terminate QT
55    //    leave_quicktime_movies();
56    //    terminite_quicktime_qtml();
57}
58
59/// Start or continue stream.
60void QuicktimeLiveImageStream::play()
61{
62   OSG_DEBUG<<"Sending play"<<this<<std::endl;
63  /* if (g_s_use_sg)
64   {
65       ComponentResult result = noErr;
66       result = SGStartPreview(m_gSeqGrabber);
67       if (result != noErr)
68           OSG_FATAL << "SGStartPreview : error" << std::endl;
69   }*/
70}
71/// Pause stream at current position.
72void QuicktimeLiveImageStream::pause()
73{
74   OSG_DEBUG<<"Sending pause"<<this<<std::endl;
75}
76/// stop playing
77void QuicktimeLiveImageStream::quit(bool wiatForThreadToExit)
78{
79   OSG_DEBUG<<"Sending quit"<<this<<std::endl;
80}
81
82//
83// PRIVATE
84//
85
86// Use the Sequence Grabber or the raw Video Digitizer
87// If using SG then use it in Preview or Record option
88// Thre options - VD Play Through, SG Preview or SG Record
89static bool g_s_use_sg        = true ; // 1a
90static bool g_s_use_sg_record = false; // 1b
91
92// load
93void QuicktimeLiveImageStream::load(std::string fileName)
94{
95   OSG_DEBUG<<"QuicktimeLive Loading..."<<this<<std::endl;
96   // CreateAndRunWithSequenceGrabber
97   if (g_s_use_sg)
98       createAndRunWithSequenceGrabber(fileName);
99   else
100       createAndRunWithVideoDigitizer(fileName);
101}
102
103// Create the Image
104void QuicktimeLiveImageStream::createImage()
105{
106    // Old
107    // char* pointer = (char*)malloc(4 * m_videoRectWidth*m_videoRectHeight + 32);
108    // void* buffer  = (void*)(((unsigned long)(pointer + 31) >> 5) << 5);
109    // New
110    int* buffer = new int [m_videoRectWidth*m_videoRectHeight]; // 1024*1024*4 bytes (32bit RGBA)
111    //
112    GLenum internalFormat  = (osg::getCpuByteOrder()==osg::BigEndian)?
113                              GL_UNSIGNED_INT_8_8_8_8_REV :
114                              GL_UNSIGNED_INT_8_8_8_8;
115
116    setImage(m_videoRectWidth,m_videoRectHeight,1,
117            (GLint) GL_RGBA8, (GLenum)GL_BGRA, internalFormat,
118            (unsigned char*)buffer,osg::Image::NO_DELETE,4);
119}
120
121// Create the offscreen GWorld (using Image  as target memory)
122void QuicktimeLiveImageStream::createGWorld()
123{
124    Rect         destinationBounds;
125    OSStatus     err;
126    GDHandle     origDevice;
127    CGrafPtr     origPort;
128    destinationBounds.left   = 0;
129    destinationBounds.top    = 0;
130    destinationBounds.right  = m_videoRectWidth;
131    destinationBounds.bottom = m_videoRectHeight;
132    err = QTNewGWorldFromPtr(&m_gw, k32ARGBPixelFormat, &destinationBounds,
133                             NULL, NULL, 0, (Ptr)data(), 4*m_videoRectWidth);
134    if (err !=0 )
135    {
136        OSG_DEBUG << "Could not create gWorld" << std::endl;
137    }
138    else
139    {
140        // Query
141        GetGWorld (&origPort, &origDevice);
142        SetGWorld (m_gw, NULL); // set current graphics port to offscreen
143        m_pixmap = GetGWorldPixMap(m_gw);
144        if (m_pixmap)
145         {
146             if (!LockPixels (m_pixmap)) // lock offscreen pixel map
147             {
148                 OSG_FATAL << "Could not lock PixMap" << std::endl;
149             }
150         }
151        // Set back
152        SetGWorld(origPort, origDevice);
153    }
154}
155
156// 1.
157// CreateAndRunWithSequenceGrabber
158void QuicktimeLiveImageStream::createAndRunWithSequenceGrabber(std::string fileName)
159{
160   std::string::size_type idx = fileName.find(':');
161   if (idx == std::string::npos)
162   {
163       OSG_FATAL << "Error while parsing deviceID:deviceInputID.live path : " << fileName << std::endl;
164   }
165   // Better c++ code is to use istrstream
166   std::string deviceIDStr      = fileName.substr(0,idx);
167   std::string deviceInputIDStr = fileName.substr(idx+1);
168   m_videoDeviceID      = static_cast<short>(atoi(deviceIDStr.c_str()));
169   m_videoDeviceInputID = static_cast<short>(atoi(deviceInputIDStr.c_str()));
170   // Get Video Digitizer Rectangle bounds from a Sequence Grabber proxy (using IDs)
171   get_video_device_bounds_idstr(m_videoDeviceID, m_videoDeviceInputID, m_videoRectWidth, m_videoRectHeight, m_videoDeviceIDStr);
172   // Sound
173   m_soundDeviceID = 2; m_soundDeviceInputID = 0;
174   //get_sound_device_idstr(m_soundDeviceID, m_soundDeviceInputID, m_soundDeviceIDStr);
175   // Create the Image
176   createImage();
177   // Create the offscreen GWorld (using Image  as target memory)
178   createGWorld();
179   // Create the Sequence Grabber (using GWorld as target memory)
180   createSequenceGrabber();
181   // Create the Sequence Grabber Video Channel
182   createSequenceGrabberVideoChannel();
183   if (g_s_use_sg_record)
184   {
185       // Create the Sequence Grabber DataProc setup for Record
186       createSequenceGrabberDataProc();
187   }
188   // Create the Sequence Grabber Audio Channel
189   createSequenceGrabberAudioChannel();
190   // Start the engine Jack!
191   // Callbacks
192   createSequenceGrabberVideoBottlenecks();
193
194   ComponentResult result = noErr;
195   result = SGPrepare( m_gSeqGrabber, TRUE, FALSE);
196   if (result != noErr)
197   {
198       OSG_FATAL << "SGPrepare : error" << std::endl;
199   }
200
201   if (g_s_use_sg_record)
202   {
203       result = SGStartRecord(m_gSeqGrabber);
204       if (result != noErr)
205       {
206           OSG_FATAL << "SGStartRecord : error" << std::endl;
207       }
208   }
209   else
210   {
211       result = SGStartPreview(m_gSeqGrabber);
212       if (result != noErr)
213       {
214           OSG_FATAL << "SGStartPreview : error" << std::endl;
215       }
216   }
217
218   _status = ImageStream::PLAYING;
219   // Ticker
220   start();
221}
222
223
224// 1.
225// Create the Sequence Grabber (using GWorld as target memory)
226void QuicktimeLiveImageStream::createSequenceGrabber()
227{
228    ComponentDescription sg_component_description;
229    sg_component_description.componentType         = SeqGrabComponentType; /* A unique 4-byte code indentifying the command set */
230    sg_component_description.componentSubType      = 0L;      /* Particular flavor of this instance */
231    sg_component_description.componentManufacturer = 'appl';  /* Vendor indentification */
232    sg_component_description.componentFlags        = 0L;      /* 8 each for Component,Type,SubType,Manuf/revision */
233    sg_component_description.componentFlagsMask    = 0L;      /* Mask for specifying which flags to consider in search, zero during registration */
234    long num_sg_components = CountComponents (&sg_component_description);
235    if (num_sg_components)
236    {
237        Component aComponent = 0;
238        ComponentDescription full_sg_component_description = sg_component_description;
239        aComponent = FindNextComponent(aComponent, &full_sg_component_description);
240        if (aComponent)
241        {
242            m_gSeqGrabber = OpenComponent(aComponent);
243            // If we got a sequence grabber, set it up
244            if (m_gSeqGrabber != 0L)
245            {
246                // Check capability and setting of Sequence Grabber
247                GDHandle origDevice;
248                CGrafPtr origPort;
249                // Create GWorld
250                GetGWorld (&origPort, &origDevice);
251                SetGWorld (m_gw, NULL); // set current graphics port to offscreen
252                // Initialize the sequence grabber
253                ComponentResult result = noErr;
254                result = SGInitialize (m_gSeqGrabber);
255                if (result == noErr)
256                {
257                    // Set GWorld
258                    result = SGSetGWorld(m_gSeqGrabber, (CGrafPtr)m_gw, 0);
259                    if (result != noErr)
260                    {
261                        OSG_FATAL << "Could not set GWorld on SG" << std::endl;
262                    }
263                }
264                // Set GWorld back
265                SetGWorld(origPort, origDevice);
266            }
267        }
268    }
269}
270
271// Create the Sequence Grabber Video Channel
272void QuicktimeLiveImageStream::createSequenceGrabberVideoChannel()
273{
274    // Check capability and setting of Sequence Grabber
275    GDHandle origDevice;
276    CGrafPtr origPort;
277    // Create GWorld
278    GetGWorld (&origPort, &origDevice);
279    SetGWorld (m_gw, NULL); // set current graphics port to offscreen
280    // Setup
281    // Get a video channel
282    ComponentResult result = SGNewChannel (m_gSeqGrabber, VideoMediaType, &m_gVideoChannel);
283    if ((m_gVideoChannel != nil) && (result == noErr))
284    {
285        result = SGInitChannel(m_gVideoChannel, m_gSeqGrabber);
286        Rect gActiveVideoRect;
287        // Usage
288        if (g_s_use_sg_record)
289            result = SGSetChannelUsage (m_gVideoChannel, seqGrabRecord | seqGrabLowLatencyCapture);
290        else
291        {
292            result = SGSetChannelUsage (m_gVideoChannel, seqGrabPreview);
293        }
294        //  result = SGSetUseScreenBuffer(m_gVideoChannel, FALSE);
295        // Set
296        OSG_DEBUG << "Setting up vdig from input prefs" << std::endl;
297        result = SGSetChannelDevice     ( m_gVideoChannel, m_videoDeviceIDStr);
298        result = SGSetChannelDeviceInput( m_gVideoChannel, m_videoDeviceInputID);
299        // result = SGSetChannelPlayFlags  ( m_gVideoChannel, channelPlayFast | channelPlayHighQuality | channelPlayAllData);
300        result = SGSetChannelPlayFlags  ( m_gVideoChannel, channelPlayFast );
301
302        VideoDigitizerComponent vdig = SGGetVideoDigitizerComponent(m_gVideoChannel);
303        VideoDigitizerError vid_err;
304        vid_err = VDSetInputStandard (vdig, palIn);
305        OSG_DEBUG << "Setup vdig from input prefs:" << std::endl;
306        print_video_component_capability(vdig);
307
308        result = SGVideoDigitizerChanged( m_gVideoChannel);
309        result = SGGetSrcVideoBounds    ( m_gVideoChannel, &gActiveVideoRect);
310        result = SGSetChannelBounds     ( m_gVideoChannel, &gActiveVideoRect);
311
312        result = SGChangedSource (m_gSeqGrabber, m_gVideoChannel);
313
314        Fixed frame_rate;
315        result = SGGetFrameRate (m_gVideoChannel, &frame_rate);
316        result = SGSetFrameRate (m_gVideoChannel, 100);
317        //
318        // Sound
319        /*
320        long                sound_id;
321        Str255              sound_driver_name;
322        char*               sound_driver_name_cstr;
323        vid_err = VDGetSoundInputSource(vdig, (long)m_videoDeviceInputID, &sound_id);
324        vid_err = VDGetSoundInputDriver(vdig, sound_driver_name);
325        sound_driver_name_cstr = pstr_printable(sound_driver_name);
326        OSG_DEBUG << "vdig sound driver name :" << sound_driver_name_cstr << std::endl;
327        OSG_DEBUG << "vdig sound driver id   :" << sound_id << std::endl;
328        */
329    }
330    else
331    {
332        OSG_FATAL << "Could not create SGNewChannel for Video Channel" << std::endl;
333    }
334    // Set GWorld back
335    SetGWorld(origPort, origDevice);
336}
337
338
339static OSErr MySGDataProc (SGChannel c,Ptr p,long len,long *offset,long chRefCon,TimeValue time,short writeType,long refCon )
340{
341    QuicktimeLiveImageStream* p_is = (QuicktimeLiveImageStream*)refCon;
342    return p_is->dataProcCallback(c,p,len,offset,chRefCon,time,writeType,refCon);
343}
344
345OSErr QuicktimeLiveImageStream::dataProcCallback( SGChannel c,Ptr p,long len,long *offset,long chRefCon,TimeValue time,short writeType,long refCon )
346{
347    OSErr err = noErr;
348    //
349    OSG_INFO << " Video " << refCon << std::endl;
350    dirty();
351    //
352    return err;
353}
354
355// Create the Sequence Grabber DataProc setup for Record
356void QuicktimeLiveImageStream::createSequenceGrabberDataProc()
357{
358    OSErr err;
359    err = SGSetDataRef(m_gSeqGrabber, 0, 0, seqGrabToMemory | seqGrabDontMakeMovie);
360    if (err != noErr)
361    {
362       OSG_FATAL << "SGSetDataRef : error" << std::endl;
363    }
364
365    // specify a sequence grabber data function
366    err = SGSetDataProc(m_gSeqGrabber, NewSGDataUPP(MySGDataProc), (long)this);
367    if (err != noErr)
368    {
369       OSG_FATAL << "SGSetDataProc : error" << std::endl;
370    }
371}
372
373
374// Create the Sequence Grabber Audio Channel
375void QuicktimeLiveImageStream::createSequenceGrabberAudioChannel()
376{
377  // Check capability and setting of Sequence Grabber
378    GDHandle origDevice;
379    CGrafPtr origPort;
380    // Create GWorld
381    GetGWorld (&origPort, &origDevice);
382    SetGWorld (m_gw, NULL); // set current graphics port to offscreen
383    // Setup
384    // Get a video channel
385    ComponentResult result = SGNewChannel (m_gSeqGrabber, SoundMediaType, &m_gSoundChannel);
386    if ((m_gSoundChannel != nil) && (result == noErr))
387    {
388        result = SGInitChannel(m_gSoundChannel, m_gSeqGrabber);
389        // result = SGSetChannelUsage (m_gSoundChannel, seqGrabPreview );
390        // Usage
391        if (g_s_use_sg_record)
392            result = SGSetChannelUsage (m_gSoundChannel, seqGrabRecord | seqGrabLowLatencyCapture);
393        else
394        {
395            result = SGSetChannelUsage (m_gSoundChannel, seqGrabPreview | seqGrabRecord | seqGrabLowLatencyCapture);
396        }
397
398        // Get
399        Str255 deviceName;
400        Str255 inputName;
401        short  inputNumber;
402        result = SGGetChannelDeviceAndInputNames( m_gSoundChannel, deviceName, inputName, &inputNumber);
403
404        // Set
405        // OSG_DEBUG << "Setting up audio component from input prefs" << std::endl;
406        result = SGSetChannelDevice     ( m_gSoundChannel, m_soundDeviceIDStr);
407        result = SGSetChannelDeviceInput( m_gSoundChannel, m_soundDeviceInputID);
408        // Set the volume low to prevent feedback when we start the preview,
409        // in case the mic is anywhere near the speaker.
410        short volume = 0;
411        result = SGGetChannelVolume (m_gSoundChannel, &volume );
412        // result = SGSetChannelVolume (m_gSoundChannel, 255);
413        // Inform
414        result = SGChangedSource        ( m_gSeqGrabber,   m_gSoundChannel);
415    }
416    else
417    {
418        OSG_FATAL << "Could not create SGNewChannel for Sound Channel" << std::endl;
419    }
420    // Set GWorld back
421    SetGWorld(origPort, origDevice);
422}
423
424// GrabFrameCompleteProc (QT callback)
425static ComponentResult GrabFrameCompleteProc(SGChannel sgChan, short nBufferNum, Boolean *pbDone, long lRefCon)
426{
427    QuicktimeLiveImageStream* p_is = (QuicktimeLiveImageStream*)lRefCon;
428    return p_is->grabFrameCompleteProc(sgChan, nBufferNum, pbDone, lRefCon);
429}
430
431// GrabFrameCompleteProc (QuicktimeLiveImageStream)
432ComponentResult QuicktimeLiveImageStream::grabFrameCompleteProc(SGChannel sgChan, short nBufferNum, Boolean *pbDone, long lRefCon)
433{
434   ComponentResult err = noErr;
435
436   // call the default grab-complete function
437   err = SGGrabFrameComplete(sgChan,      // channel reference
438                             nBufferNum,  // buffer identifier, provided for you
439                             pbDone);     // pointer to a boolean, has the frame been completely captured? provided for you
440
441   static unsigned int fps_counter = 0;
442   static osg::Timer_t start, finish;
443
444   if (fps_counter == 0)
445       start = osg::Timer::instance()->tick();
446   // if the frame is done, make sure the Image is replaced
447   if (*pbDone && (sgChan == m_gVideoChannel))
448   {
449        dirty();
450        ++fps_counter;
451        if (fps_counter == 100)
452        {
453            finish = osg::Timer::instance()->tick();
454            double dur = osg::Timer::instance()->delta_s(start, finish);
455            double fps = 100.0 / dur;
456            OSG_NOTICE << "Executed 100 frames in " << dur << " seconds : ~" << fps << " fps" << std::endl;
457            fps_counter = 0;
458        }
459   }
460
461   return err;
462}
463
464
465// Create callbacks
466void QuicktimeLiveImageStream::createSequenceGrabberVideoBottlenecks()
467{
468    OSErr  err = noErr;
469    // set the value of a reference constant that is passed to the callback functions
470    err = SGSetChannelRefCon(m_gVideoChannel, (long)this);
471    if (err == noErr)
472    {
473        VideoBottles  vb;
474        // get the current bottlenecks
475        vb.procCount = 9;
476        err = SGGetVideoBottlenecks(m_gVideoChannel, &vb);
477        if (err == noErr)
478        {
479            // add our GrabFrameComplete function
480            vb.grabCompleteProc = NewSGGrabCompleteBottleUPP(GrabFrameCompleteProc);
481            err = SGSetVideoBottlenecks(m_gVideoChannel, &vb);
482        }
483    }
484}
485
486
487// 2.
488// CreateAndRunWithVideoDigitizer
489void QuicktimeLiveImageStream::createAndRunWithVideoDigitizer(std::string fileName)
490{
491   std::string::size_type idx = fileName.find(':');
492   if (idx == std::string::npos)
493   {
494       OSG_FATAL << "Error while parsing deviceID:deviceInputID.live path : " << fileName << std::endl;
495   }
496   // Better c++ code is to use istrstream
497   std::string deviceIDStr      = fileName.substr(0,idx);
498   std::string deviceInputIDStr = fileName.substr(idx+1);
499   m_videoDeviceID      = static_cast<short>(atoi(deviceIDStr.c_str()));
500   m_videoDeviceInputID = static_cast<short>(atoi(deviceInputIDStr.c_str()));
501   // Get Video Digitizer Rectangle bounds from a Sequence Grabber proxy (using IDs)
502   get_video_device_bounds_idstr(m_videoDeviceID, m_videoDeviceInputID, m_videoRectWidth, m_videoRectHeight, m_videoDeviceIDStr);
503   // Create the Image
504   createImage();
505   // Create the offscreen GWorld (using Image  as target memory)
506   createGWorld();
507   // Create the Sequence Grabber (using GWorld as target memory)
508   createVideoDigitizer();
509   // Go
510   _status = ImageStream::PLAYING;
511
512   VideoDigitizerError error = VDSetPlayThruOnOff(m_vdig, vdPlayThruOn);
513   if (error != noErr)
514   {
515       OSG_FATAL << "VDSetPlayThruOnOff : error" << std::endl;
516   }
517   // Ticker
518   start();
519}
520
521// 2.
522// Create the Video Digitizer (using GWorld Pixmap as target mamory)
523void QuicktimeLiveImageStream::createVideoDigitizer()
524{
525    // #define videoDigitizerComponentType = 'vdig'
526    ComponentDescription video_component_description;
527    video_component_description.componentType         = 'vdig'; /* A unique 4-byte code indentifying the command set */
528    video_component_description.componentSubType      = 0;      /* Particular flavor of this instance */
529    video_component_description.componentManufacturer = 0;      /* Vendor indentification */
530    video_component_description.componentFlags        = 0;      /* 8 each for Component,Type,SubType,Manuf/revision */
531    video_component_description.componentFlagsMask    = 0;      /* Mask for specifying which flags to consider in search, zero during registration */
532    long num_video_components = CountComponents (&video_component_description);
533    OSG_DEBUG << " available Video DigitizerComponents : " << num_video_components << std::endl;
534    if (num_video_components)
535    {
536        Component aComponent = 0;
537        short     aDeviceID  = 0;
538        do
539        {
540            ComponentDescription full_video_component_description = video_component_description;
541            aComponent = FindNextComponent(aComponent, &full_video_component_description);
542            if (aComponent && (aDeviceID == m_videoDeviceID))
543            {
544                OSG_DEBUG << "Component" << std::endl;
545                OSErr                err;
546                Handle compName = NewHandle(256);
547                Handle compInfo = NewHandle(256);
548                err = GetComponentInfo( aComponent, &full_video_component_description, compName,compInfo,0);
549                OSG_DEBUG << "    Name: " << pstr_printable((StringPtr)*compName) << std::endl;
550                OSG_DEBUG << "    Desc: " << pstr_printable((StringPtr)*compInfo) << std::endl;
551                //Capabilities
552                VideoDigitizerComponent component_instance = OpenComponent(aComponent);
553                m_vdig = component_instance;
554                //Setup
555                // Onscreen
556                // Check capability and setting of Sequence Grabber
557                GDHandle origDevice;
558                CGrafPtr origPort;
559                GetGWorld (&origPort, &origDevice);
560                VideoDigitizerError error;
561                Rect                destinationBounds;
562                destinationBounds.left   = 0;
563                destinationBounds.top    = 0;
564                destinationBounds.right  = m_videoRectWidth;
565                destinationBounds.bottom = m_videoRectHeight;
566                error = VDSetPlayThruDestination(m_vdig, m_pixmap, &destinationBounds, 0, 0);
567                //error = VDSetPlayThruGlobalRect(m_vdig, (GrafPtr)origPort, &destinationBounds);
568                if (error != noErr)
569                {
570                    OSG_FATAL << "VDSetPlayThruDestination : error" << std::endl;
571                }
572                print_video_component_capability(component_instance);
573                break;
574            }
575            ++aDeviceID;
576        }
577        while (0 != aComponent);
578     }
579}
580
581
582// Thread run method
583void QuicktimeLiveImageStream::run()
584{
585   ComponentResult result = noErr;
586   bool            done   = false;
587
588   //memset( data(), 255, 720*250*4);
589
590   while (!done)
591   {
592       // Do some funky rotational memset
593       // void * memset ( void * ptr, int value, size_t num );
594       //memset
595       // dirty();
596       if (g_s_use_sg)
597       {
598           result = SGIdle(m_gSeqGrabber);
599           if (result != noErr)
600           {
601               OSG_FATAL << "SGIdle : error" << std::endl;
602           }
603       }
604       //OpenThreads::Thread::microSleep(250000); // 25fps (1,000,000 = 1 fps)
605       //OpenThreads::Thread::microSleep(50000); // 200fps (1,000,000 = 1 fps)
606       //OpenThreads::Thread::microSleep(25000); // 400fps (1,000,000 = 1 fps)
607       // Ridiculous
608       OpenThreads::Thread::microSleep(10000); // 1000fps (1,000,000 = 1 fps)
609   }
610}
611
612
613
Note: See TracBrowser for help on using the browser.