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

Revision 10891, 22.5 kB (checked in by robert, 5 years ago)

Changed GL_BGRA_EXT to GL_BGRA and added include of include/osg/Image to make sure define is declared

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>
[10891]17#include <osg/Image>
[7586]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::notify(osg::DEBUG_INFO)<<"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::notify(osg::FATAL) << "SGStartPreview : error" << std::endl;
69   }*/
70}
71/// Pause stream at current position.
72void QuicktimeLiveImageStream::pause()
73{
74   osg::notify(osg::DEBUG_INFO)<<"Sending pause"<<this<<std::endl;
75}
76/// stop playing
77void QuicktimeLiveImageStream::quit(bool wiatForThreadToExit)
78{
79   osg::notify(osg::DEBUG_INFO)<<"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::notify(osg::DEBUG_INFO)<<"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,
[10891]117            (GLint) GL_RGBA8, (GLenum)GL_BGRA, internalFormat,
[7586]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::notify(osg::DEBUG_INFO) << "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::notify(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::notify(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       osg::notify(osg::FATAL) << "SGPrepare : error" << std::endl;
198   if (g_s_use_sg_record)
199   {
200       result = SGStartRecord(m_gSeqGrabber);
201       if (result != noErr)
202           osg::notify(osg::FATAL) << "SGStartRecord : error" << std::endl;
203   }
204   else
205   {
206       result = SGStartPreview(m_gSeqGrabber);
207       if (result != noErr)
208           osg::notify(osg::FATAL) << "SGStartPreview : error" << std::endl;
209   }
210 
211   _status = ImageStream::PLAYING;
212   // Ticker
213   start();
214}
215
216
217// 1.
218// Create the Sequence Grabber (using GWorld as target memory)
219void QuicktimeLiveImageStream::createSequenceGrabber()
220{
221    ComponentDescription sg_component_description;
222    sg_component_description.componentType         = SeqGrabComponentType; /* A unique 4-byte code indentifying the command set */
223    sg_component_description.componentSubType      = 0L;      /* Particular flavor of this instance */
224    sg_component_description.componentManufacturer = 'appl';  /* Vendor indentification */
225    sg_component_description.componentFlags        = 0L;      /* 8 each for Component,Type,SubType,Manuf/revision */
226    sg_component_description.componentFlagsMask    = 0L;      /* Mask for specifying which flags to consider in search, zero during registration */
227    long num_sg_components = CountComponents (&sg_component_description);
228    if (num_sg_components)
229    {
230        Component aComponent = 0;
231        ComponentDescription full_sg_component_description = sg_component_description;
232        aComponent = FindNextComponent(aComponent, &full_sg_component_description);
233        if (aComponent)
234        {
235            m_gSeqGrabber = OpenComponent(aComponent);
236            // If we got a sequence grabber, set it up
237            if (m_gSeqGrabber != 0L)
238            {
239                // Check capability and setting of Sequence Grabber
240                GDHandle origDevice;
241                CGrafPtr origPort;
242                // Create GWorld
243                GetGWorld (&origPort, &origDevice);
244                SetGWorld (m_gw, NULL); // set current graphics port to offscreen
245                // Initialize the sequence grabber
246                ComponentResult result = noErr;
247                result = SGInitialize (m_gSeqGrabber);
248                if (result == noErr)
249                {
250                    // Set GWorld
251                    result = SGSetGWorld(m_gSeqGrabber, (CGrafPtr)m_gw, 0);
252                    if (result != noErr)
253                    {
254                        osg::notify(osg::FATAL) << "Could not set GWorld on SG" << std::endl;
255                    }
256                }
257                // Set GWorld back
258                SetGWorld(origPort, origDevice);
259            }
260        }
261    }
262}
263
264// Create the Sequence Grabber Video Channel
265void QuicktimeLiveImageStream::createSequenceGrabberVideoChannel()
266{
267    // Check capability and setting of Sequence Grabber
268    GDHandle origDevice;
269    CGrafPtr origPort;
270    // Create GWorld
271    GetGWorld (&origPort, &origDevice);
272    SetGWorld (m_gw, NULL); // set current graphics port to offscreen
273    // Setup
274    // Get a video channel
275    ComponentResult result = SGNewChannel (m_gSeqGrabber, VideoMediaType, &m_gVideoChannel);
276    if ((m_gVideoChannel != nil) && (result == noErr))
277    {
278        result = SGInitChannel(m_gVideoChannel, m_gSeqGrabber);
279        Rect gActiveVideoRect;
280        // Usage
281        if (g_s_use_sg_record)
282            result = SGSetChannelUsage (m_gVideoChannel, seqGrabRecord | seqGrabLowLatencyCapture);
283        else
284        {
285            result = SGSetChannelUsage (m_gVideoChannel, seqGrabPreview);
286        }
287        //  result = SGSetUseScreenBuffer(m_gVideoChannel, FALSE);
288        // Set
289        osg::notify(osg::DEBUG_INFO) << "Setting up vdig from input prefs" << std::endl;
290        result = SGSetChannelDevice     ( m_gVideoChannel, m_videoDeviceIDStr);
291        result = SGSetChannelDeviceInput( m_gVideoChannel, m_videoDeviceInputID);
292        // result = SGSetChannelPlayFlags  ( m_gVideoChannel, channelPlayFast | channelPlayHighQuality | channelPlayAllData);
293        result = SGSetChannelPlayFlags  ( m_gVideoChannel, channelPlayFast );
294
295        VideoDigitizerComponent vdig = SGGetVideoDigitizerComponent(m_gVideoChannel);
296        VideoDigitizerError vid_err;
297        vid_err = VDSetInputStandard (vdig, palIn);
298        osg::notify(osg::DEBUG_INFO) << "Setup vdig from input prefs:" << std::endl;
299        print_video_component_capability(vdig);
300
301        result = SGVideoDigitizerChanged( m_gVideoChannel);
302        result = SGGetSrcVideoBounds    ( m_gVideoChannel, &gActiveVideoRect);     
303        result = SGSetChannelBounds     ( m_gVideoChannel, &gActiveVideoRect);
304       
305        result = SGChangedSource (m_gSeqGrabber, m_gVideoChannel);
306
307        Fixed frame_rate;
308        result = SGGetFrameRate (m_gVideoChannel, &frame_rate);
309        int zx = 0;
310        result = SGSetFrameRate (m_gVideoChannel, 100);
311        //
312        // Sound
313        /*
314        long                sound_id;
315        Str255              sound_driver_name;
316        char*               sound_driver_name_cstr;
317        vid_err = VDGetSoundInputSource(vdig, (long)m_videoDeviceInputID, &sound_id);
318        vid_err = VDGetSoundInputDriver(vdig, sound_driver_name);
319        sound_driver_name_cstr = pstr_printable(sound_driver_name);
320        osg::notify(osg::DEBUG_INFO) << "vdig sound driver name :" << sound_driver_name_cstr << std::endl;
321        osg::notify(osg::DEBUG_INFO) << "vdig sound driver id   :" << sound_id << std::endl;
322        */
323    }
324    else
325    {
326        osg::notify(osg::FATAL) << "Could not create SGNewChannel for Video Channel" << std::endl;
327    }
328    // Set GWorld back
329    SetGWorld(origPort, origDevice);
330}
331
332
333static OSErr MySGDataProc (SGChannel c,Ptr p,long len,long *offset,long chRefCon,TimeValue time,short writeType,long refCon )
334{
335    QuicktimeLiveImageStream* p_is = (QuicktimeLiveImageStream*)refCon;
336    return p_is->dataProcCallback(c,p,len,offset,chRefCon,time,writeType,refCon);
337}
338
339OSErr QuicktimeLiveImageStream::dataProcCallback( SGChannel c,Ptr p,long len,long *offset,long chRefCon,TimeValue time,short writeType,long refCon )
340{
341    OSErr err = noErr;
342    //
343    osg::notify(osg::INFO) << " Video " << refCon << std::endl;
344    dirty();
345    //
346    return err;
347}
348
349// Create the Sequence Grabber DataProc setup for Record
350void QuicktimeLiveImageStream::createSequenceGrabberDataProc()
351{
352    OSErr err;
353    err = SGSetDataRef(m_gSeqGrabber, 0, 0, seqGrabToMemory | seqGrabDontMakeMovie);
354    if (err != noErr)
355       osg::notify(osg::FATAL) << "SGSetDataRef : error" << std::endl;
356    // specify a sequence grabber data function
357    err = SGSetDataProc(m_gSeqGrabber, NewSGDataUPP(MySGDataProc), (long)this);
358    if (err != noErr)
359       osg::notify(osg::FATAL) << "SGSetDataProc : error" << std::endl;
360}
361
362
363// Create the Sequence Grabber Audio Channel
364void QuicktimeLiveImageStream::createSequenceGrabberAudioChannel()
365{
366  // Check capability and setting of Sequence Grabber
367    GDHandle origDevice;
368    CGrafPtr origPort;
369    // Create GWorld
370    GetGWorld (&origPort, &origDevice);
371    SetGWorld (m_gw, NULL); // set current graphics port to offscreen
372    // Setup
373    // Get a video channel
374    ComponentResult result = SGNewChannel (m_gSeqGrabber, SoundMediaType, &m_gSoundChannel);
375    if ((m_gSoundChannel != nil) && (result == noErr))
376    {
377        result = SGInitChannel(m_gSoundChannel, m_gSeqGrabber);
378        // result = SGSetChannelUsage (m_gSoundChannel, seqGrabPreview );
379        // Usage
380        if (g_s_use_sg_record)
381            result = SGSetChannelUsage (m_gSoundChannel, seqGrabRecord | seqGrabLowLatencyCapture);
382        else
383        {
384            result = SGSetChannelUsage (m_gSoundChannel, seqGrabPreview | seqGrabRecord | seqGrabLowLatencyCapture);
385        }
386
387        // Get
388        Str255 deviceName;
389        Str255 inputName;
390        short  inputNumber;
391        result = SGGetChannelDeviceAndInputNames( m_gSoundChannel, deviceName, inputName, &inputNumber);
392
393        // Set
394        // osg::notify(osg::DEBUG_INFO) << "Setting up audio component from input prefs" << std::endl;
395        result = SGSetChannelDevice     ( m_gSoundChannel, m_soundDeviceIDStr);
396        result = SGSetChannelDeviceInput( m_gSoundChannel, m_soundDeviceInputID);
397        // Set the volume low to prevent feedback when we start the preview,
398        // in case the mic is anywhere near the speaker.
399        short volume = 0;
400        result = SGGetChannelVolume (m_gSoundChannel, &volume );
401        // result = SGSetChannelVolume (m_gSoundChannel, 255);
402        // Inform
403        result = SGChangedSource        ( m_gSeqGrabber,   m_gSoundChannel);
404    }
405    else
406    {
407        osg::notify(osg::FATAL) << "Could not create SGNewChannel for Sound Channel" << std::endl;
408    }
409    // Set GWorld back
410    SetGWorld(origPort, origDevice);
411}
412
413// GrabFrameCompleteProc (QT callback)
414static ComponentResult GrabFrameCompleteProc(SGChannel sgChan, short nBufferNum, Boolean *pbDone, long lRefCon)
415{
416    QuicktimeLiveImageStream* p_is = (QuicktimeLiveImageStream*)lRefCon;
417    return p_is->grabFrameCompleteProc(sgChan, nBufferNum, pbDone, lRefCon);
418}
419
420// GrabFrameCompleteProc (QuicktimeLiveImageStream)
421ComponentResult QuicktimeLiveImageStream::grabFrameCompleteProc(SGChannel sgChan, short nBufferNum, Boolean *pbDone, long lRefCon)
422{
423   ComponentResult err = noErr;
424 
425   // call the default grab-complete function
426   err = SGGrabFrameComplete(sgChan,      // channel reference
427                             nBufferNum,  // buffer identifier, provided for you
428                             pbDone);     // pointer to a boolean, has the frame been completely captured? provided for you
429   
430   static unsigned int fps_counter = 0;
431   static osg::Timer_t start, finish;
432
433   if (fps_counter == 0)
434       start = osg::Timer::instance()->tick();
435   // if the frame is done, make sure the Image is replaced
436   if (*pbDone && (sgChan == m_gVideoChannel))
437   {
438        dirty();
439        ++fps_counter;
440        if (fps_counter == 100)
441        {
442            finish = osg::Timer::instance()->tick();
443            double dur = osg::Timer::instance()->delta_s(start, finish);
444            double fps = 100.0 / dur;
445            osg::notify(osg::NOTICE) << "Executed 100 frames in " << dur << " seconds : ~" << fps << " fps" << std::endl;
446            fps_counter = 0;
447        }
448   }
449 
450   return err;
451}
452
453
454// Create callbacks
455void QuicktimeLiveImageStream::createSequenceGrabberVideoBottlenecks()
456{
457    OSErr  err = noErr;
458    // set the value of a reference constant that is passed to the callback functions
459    err = SGSetChannelRefCon(m_gVideoChannel, (long)this);
460    if (err == noErr)
461    {
462        VideoBottles  vb;
463        // get the current bottlenecks
464        vb.procCount = 9;
465        err = SGGetVideoBottlenecks(m_gVideoChannel, &vb);
466        if (err == noErr)
467        {
468            // add our GrabFrameComplete function
469            vb.grabCompleteProc = NewSGGrabCompleteBottleUPP(GrabFrameCompleteProc);
470            err = SGSetVideoBottlenecks(m_gVideoChannel, &vb);
471        }
472    }
473}
474
475
476// 2.
477// CreateAndRunWithVideoDigitizer
478void QuicktimeLiveImageStream::createAndRunWithVideoDigitizer(std::string fileName)
479{
480   std::string::size_type idx = fileName.find(':');
481   if (idx == std::string::npos)
482   {
483       osg::notify(osg::FATAL) << "Error while parsing deviceID:deviceInputID.live path : " << fileName << std::endl;       
484   }
485   // Better c++ code is to use istrstream
486   std::string deviceIDStr      = fileName.substr(0,idx);
487   std::string deviceInputIDStr = fileName.substr(idx+1);
488   m_videoDeviceID      = static_cast<short>(atoi(deviceIDStr.c_str()));
489   m_videoDeviceInputID = static_cast<short>(atoi(deviceInputIDStr.c_str()));
490   // Get Video Digitizer Rectangle bounds from a Sequence Grabber proxy (using IDs)
491   get_video_device_bounds_idstr(m_videoDeviceID, m_videoDeviceInputID, m_videoRectWidth, m_videoRectHeight, m_videoDeviceIDStr);
492   // Create the Image
493   createImage();
494   // Create the offscreen GWorld (using Image  as target memory)
495   createGWorld();
496   // Create the Sequence Grabber (using GWorld as target memory)
497   createVideoDigitizer();
498   // Go
499   _status = ImageStream::PLAYING;
500
501   VideoDigitizerError error = VDSetPlayThruOnOff(m_vdig, vdPlayThruOn);
502   if (error != noErr)
503       osg::notify(osg::FATAL) << "VDSetPlayThruOnOff : error" << std::endl;
504   // Ticker
505   start();
506}
507
508// 2.
509// Create the Video Digitizer (using GWorld Pixmap as target mamory)
510void QuicktimeLiveImageStream::createVideoDigitizer()
511{
512    // #define videoDigitizerComponentType = 'vdig'
513    ComponentDescription video_component_description;
514    video_component_description.componentType         = 'vdig'; /* A unique 4-byte code indentifying the command set */
515    video_component_description.componentSubType      = 0;      /* Particular flavor of this instance */
516    video_component_description.componentManufacturer = 0;      /* Vendor indentification */
517    video_component_description.componentFlags        = 0;      /* 8 each for Component,Type,SubType,Manuf/revision */
518    video_component_description.componentFlagsMask    = 0;      /* Mask for specifying which flags to consider in search, zero during registration */
519    long num_video_components = CountComponents (&video_component_description);
520    osg::notify(osg::DEBUG_INFO) << " available Video DigitizerComponents : " << num_video_components << std::endl;
521    if (num_video_components)
522    {
523        Component aComponent = 0;
524        short     aDeviceID  = 0;
525        do
526        {
527            ComponentDescription full_video_component_description = video_component_description;
528            aComponent = FindNextComponent(aComponent, &full_video_component_description);
529            if (aComponent && (aDeviceID == m_videoDeviceID))
530            {
531                osg::notify(osg::DEBUG_INFO) << "Component" << std::endl;
532                OSErr                err;
533                Handle compName = NewHandle(256);
534                Handle compInfo = NewHandle(256);
535                err = GetComponentInfo( aComponent, &full_video_component_description, compName,compInfo,0);
536                osg::notify(osg::DEBUG_INFO) << "    Name: " << pstr_printable((StringPtr)*compName) << std::endl;
537                osg::notify(osg::DEBUG_INFO) << "    Desc: " << pstr_printable((StringPtr)*compInfo) << std::endl;
538                //Capabilities
539                VideoDigitizerComponent component_instance = OpenComponent(aComponent);
540                m_vdig = component_instance;
541                //Setup
542                // Onscreen
543                // Check capability and setting of Sequence Grabber
544                GDHandle origDevice;
545                CGrafPtr origPort;
546                GetGWorld (&origPort, &origDevice);
547                VideoDigitizerError error;
548                Rect                destinationBounds;
549                destinationBounds.left   = 0;
550                destinationBounds.top    = 0;
551                destinationBounds.right  = m_videoRectWidth;
552                destinationBounds.bottom = m_videoRectHeight;                   
553                error = VDSetPlayThruDestination(m_vdig, m_pixmap, &destinationBounds, 0, 0);
554                //error = VDSetPlayThruGlobalRect(m_vdig, (GrafPtr)origPort, &destinationBounds);
555                if (error != noErr)
556                    osg::notify(osg::FATAL) << "VDSetPlayThruDestination : error" << std::endl;
557                print_video_component_capability(component_instance);
558                break;
559            }
560            ++aDeviceID;
561        }
562        while (0 != aComponent);
563     }
564}
565
566
567// Thread run method
568void QuicktimeLiveImageStream::run()
569{
570   ComponentResult result = noErr;
571   bool            done   = false;
572
573   //memset( data(), 255, 720*250*4);
574
575   while (!done)
576   {
577       // Do some funky rotational memset
578       // void * memset ( void * ptr, int value, size_t num );
579       //memset
580       // dirty();
581       if (g_s_use_sg)
582       {
583           result = SGIdle(m_gSeqGrabber);
584           if (result != noErr)
585               osg::notify(osg::FATAL) << "SGIdle : error" << std::endl;
586       }
587       //OpenThreads::Thread::microSleep(250000); // 25fps (1,000,000 = 1 fps)
588       //OpenThreads::Thread::microSleep(50000); // 200fps (1,000,000 = 1 fps)
589       //OpenThreads::Thread::microSleep(25000); // 400fps (1,000,000 = 1 fps)
590       // Ridiculous
591       OpenThreads::Thread::microSleep(10000); // 1000fps (1,000,000 = 1 fps)
592   }
593}
594
595
596
Note: See TracBrowser for help on using the browser.