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

Revision 7586, 22.5 kB (checked in by robert, 6 years ago)

From Colin Dunlop, add live video stream support

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