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

Revision 13041, 43.4 kB (checked in by robert, 3 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
15#include <cstdio>
16#include <cstdlib>
17#include <string>
18#include <sstream>
19
20#include "osg/Image"
21#include "osg/Notify"
22#include "osg/Geode"
23#include "osg/GL"
24
25#include "osgDB/FileNameUtils"
26#include "osgDB/Registry"
27#include "osgDB/FileUtils"
28
29#ifdef __APPLE__
30    #include <QuickTime/QuickTime.h>
31    #include <Carbon/Carbon.h>
32    #define QT_HANDLE_IMAGES_ALSO
33#else
34    #include <QTML.h>
35    #include <Movies.h>
36    #include <Quickdraw.h>
37    #include <QDOffscreen.h>
38    #include <QuicktimeComponents.h>
39    #include <FixMath.h>
40    #include <CGBitmapContext.h>
41    #include <CGImage.h>
42    #include <CGColorSpace.h>
43    #include <ImageCompression.h>
44    #include <TextUtils.h>
45#endif
46
47#include "QTLiveUtils.h"
48
49
50// Utils
51char* pstr_printable(StringPtr src_pstr)
52{
53    char* dst_cstr = new char[256];
54    p2cstrcpy(dst_cstr, src_pstr);
55    return dst_cstr;
56}
57
58
59void initialize_quicktime_qtml()
60{
61    OSG_NOTICE << "QT QTML: Starting up... " << std::endl;
62    OSErr err;
63#ifndef __APPLE__
64    err = InitializeQTML(0);
65    if (err!=0)
66    {
67        OSG_FATAL << "Error while initializing quicktime QTML: " << err << std::endl;
68    }
69    else
70    {
71        OSG_NOTICE << "QT QTML: initialized successfully"  << std::endl;
72    }
73#endif
74}
75
76void terminite_quicktime_qtml()
77{
78    OSG_NOTICE << "QT QTML: Closing down... " << std::endl;
79#ifndef __APPLE__
80    TerminateQTML();
81#endif
82    OSG_NOTICE << "QT QTML: Closed successfully"  << std::endl;
83}
84
85void enter_quicktime_movies()
86{
87    OSG_NOTICE << "QT Movies: Starting up... " << std::endl;
88    OSErr err;
89    err = EnterMovies();
90    if (err!=0)
91    {
92        OSG_FATAL << "Error while initializing Movies: " << err << std::endl;
93    }
94    else
95    {
96        OSG_NOTICE << "QT Movies: initialized successfully"  << std::endl;
97    }
98}
99
100void leave_quicktime_movies()
101{
102    OSG_NOTICE << "QT Movies: Closing down... " << std::endl;
103#ifndef __APPLE__
104    ExitMovies();
105#endif
106    OSG_NOTICE << "QT Movies: closed successfully"  << std::endl;
107}
108
109#if TARGET_OS_MAC
110void enter_quicktime_movies_mt()
111{
112    OSG_NOTICE << "QT Movies MT: Starting up... " << std::endl;
113    OSErr err;
114    err = EnterMoviesOnThread(0);
115    if (err!=0)
116    {
117        OSG_FATAL << "Error while initializing Movies MT: " << err << std::endl;
118    }
119    else
120    {
121        OSG_NOTICE << "QT Movies MT: initialized successfully"  << std::endl;
122    }
123}
124
125void leave_quicktime_movies_mt()
126{
127    OSG_NOTICE << "QT Movies MT: Closing down... " << std::endl;
128#ifndef __APPLE__
129    ExitMoviesOnThread();
130#endif
131    OSG_NOTICE << "QT Movies MT: closed successfully"  << std::endl;
132}
133#endif
134
135
136
137QTScopedQTMLInitialiser::QTScopedQTMLInitialiser()
138{
139    initialize_quicktime_qtml();
140}
141QTScopedQTMLInitialiser::~QTScopedQTMLInitialiser()
142{
143    terminite_quicktime_qtml();
144}
145
146
147QTScopedMovieInitialiser::QTScopedMovieInitialiser()
148{
149    enter_quicktime_movies();
150}
151QTScopedMovieInitialiser::~QTScopedMovieInitialiser()
152{
153    leave_quicktime_movies();
154}
155
156
157#if TARGET_OS_MAC
158QTScopedMovieInitialiser_MT::QTScopedMovieInitialiser_MT()
159{
160    enter_quicktime_movies_mt();
161}
162QTScopedMovieInitialiser_MT::~QTScopedMovieInitialiser_MT()
163{
164    leave_quicktime_movies_mt();
165}
166#endif
167
168
169// DigitizerInfo input/output Capability checker
170bool supports_capability( long input_flags, long option_flags )
171{
172    long result_l = (input_flags & option_flags);
173    return result_l == option_flags;
174}
175
176// Capability
177void print_video_component_capability(VideoDigitizerComponent aComponent)
178{
179    // Returns capability and status information about a specified video digitizer component.
180    VideoDigitizerError vid_err;
181    DigitizerInfo       vid_info;
182    // Capability flags
183    OSG_NOTICE << std::endl;
184    vid_err = VDGetDigitizerInfo(aComponent, &vid_info);
185    if (vid_err)
186    {
187        OSG_NOTICE << "VDGetDigitizerInfo(aComponent, &vid_info) - ERROR" << std::endl;
188    }
189    else
190    {
191        OSG_NOTICE << "DigitizerInfo:" << std::endl;
192        short vdigType = vid_info.vdigType;
193        if (vdigType == vdTypeBasic) { OSG_NOTICE << "Digitizer Type : Basic (no clipping)" << std::endl; }
194        if (vdigType == vdTypeAlpha) { OSG_NOTICE << "Digitizer Type : Alpha clipping" << std::endl; }
195        if (vdigType == vdTypeMask)  { OSG_NOTICE << "Digitizer Type : Mask Plane clipping" << std::endl; }
196        if (vdigType == vdTypeKey)   { OSG_NOTICE << "Digitizer Type : Key Color(s) clipping" << std::endl; }
197        short vdigSlot = vid_info.slot;
198        OSG_NOTICE << "Hardwre Slot : " << vdigSlot << std::endl;
199        OSG_NOTICE << "Input Capability:" << std::endl << std::boolalpha;
200        long inputCapabilityFlags = vid_info.inputCapabilityFlags;
201        OSG_NOTICE << "    NTSC      : " << supports_capability(inputCapabilityFlags, digiInDoesNTSC) << std::endl;
202        OSG_NOTICE << "    PAL       : " << supports_capability(inputCapabilityFlags, digiInDoesPAL)  << std::endl;
203        OSG_NOTICE << "    Composite : " << supports_capability(inputCapabilityFlags, digiInDoesComposite) << std::endl;
204        OSG_NOTICE << "    Component : " << supports_capability(inputCapabilityFlags, digiInDoesComponent) << std::endl;
205        OSG_NOTICE << "    SVideo    : " << supports_capability(inputCapabilityFlags, digiInDoesSVideo) << std::endl;
206        OSG_NOTICE << "Input Current:" << std::endl;
207        long inputCurrentFlags = vid_info.inputCurrentFlags;
208        OSG_NOTICE << "    NTSC      : " << supports_capability(inputCurrentFlags, digiInDoesNTSC) << std::endl;
209        OSG_NOTICE << "    PAL       : " << supports_capability(inputCurrentFlags, digiInDoesPAL)  << std::endl;
210        OSG_NOTICE << "    Composite : " << supports_capability(inputCurrentFlags, digiInDoesComposite) << std::endl;
211        OSG_NOTICE << "    Component : " << supports_capability(inputCurrentFlags, digiInDoesComponent) << std::endl;
212        OSG_NOTICE << "    SVideo    : " << supports_capability(inputCurrentFlags, digiInDoesSVideo) << std::endl;
213        // Heights
214        short minDestHeight = vid_info.minDestHeight;
215        short minDestWidth  = vid_info.minDestWidth;
216        short maxDestWidth  = vid_info.maxDestWidth;
217        short maxDestHeight = vid_info.maxDestHeight;
218        OSG_NOTICE << "Min destination width,height :  " << minDestWidth << "  " << minDestHeight << std::endl;
219        OSG_NOTICE << "Max destination width,height :  " << maxDestWidth << "  " << maxDestHeight << std::endl;
220        // Current Status
221        long inputFlags, outputFlags;
222        vid_err = VDGetCurrentFlags(aComponent, &inputFlags, &outputFlags);
223        OSG_NOTICE << "    NTSC          : " << supports_capability(inputFlags, digiInDoesNTSC) << std::endl;
224        OSG_NOTICE << "    PAL           : " << supports_capability(inputFlags, digiInDoesPAL)  << std::endl;
225        OSG_NOTICE << "    Composite     : " << supports_capability(inputFlags, digiInDoesComposite) << std::endl;
226        OSG_NOTICE << "    Component     : " << supports_capability(inputFlags, digiInDoesComponent) << std::endl;
227        OSG_NOTICE << "    SVideo        : " << supports_capability(inputFlags, digiInDoesSVideo) << std::endl;
228        OSG_NOTICE << "    GenLock       : " << supports_capability(inputFlags, digiInDoesGenLock) << std::endl;
229        OSG_NOTICE << "    SECAM         : " << supports_capability(inputFlags, digiInDoesSECAM) << std::endl;
230        OSG_NOTICE << "    VTR_Broadcast : " << supports_capability(inputFlags, digiInVTR_Broadcast) << std::endl;
231        OSG_NOTICE << "    Color         : " << supports_capability(inputFlags, digiInDoesColor) << std::endl;
232        OSG_NOTICE << "    BW            : " << supports_capability(inputFlags, digiInDoesBW) << std::endl;
233        OSG_NOTICE << "   *SignalLock*   : " << supports_capability(inputFlags, digiInSignalLock) << std::endl;
234        // Preferrd Width Height
235        long pref_width, pref_height;
236        vid_err = VDGetPreferredImageDimensions(aComponent, &pref_width, &pref_height);
237        if (vid_err) { OSG_NOTICE << "VDGetPreferredImageDimensions(aComponent, &pref_width, &pref_height) - ERROR" << std::endl; }
238        else         { OSG_NOTICE << "Preferrred width,height :  " << pref_width << "  " << pref_height << std::endl; }
239
240        // Inputs
241        short inputs;
242        vid_err = VDGetNumberOfInputs(aComponent, &inputs);
243        if (vid_err) { OSG_NOTICE << "VDGetNumberOfInputs(aComponent, &inputs) - ERROR" << std::endl; }
244        else         { OSG_NOTICE << "Number of inputs        :  " << inputs << std::endl; }
245
246        for (short i=0; i <= inputs; ++i)
247        {
248            Str255 name;
249            vid_err = VDGetInputName(aComponent,(long)i, name);
250            if (vid_err) { OSG_NOTICE << "VDGetInputName(aComponent,(long)i, name) - ERROR" << std::endl; }
251            else         { OSG_NOTICE << "Name of input   " << i << " :  " << pstr_printable(name) << std::endl; }
252            short input_format;
253            vid_err = VDGetInputFormat(aComponent,(long)i, &input_format);
254            if (vid_err) { OSG_NOTICE << "VDGetInputFormat(aComponent,(long)i, &input_format) - ERROR" << std::endl; }
255            else
256            {
257                if (input_format == compositeIn)        { OSG_NOTICE << "Format of input :  compositeIn" << std::endl; }
258                if (input_format == sVideoIn)           { OSG_NOTICE << "Format of input :  sVideoIn" << std::endl; }
259                if (input_format == rgbComponentIn)     { OSG_NOTICE << "Format of input :  rgbComponentIn" << std::endl; }
260                if (input_format == rgbComponentSyncIn) { OSG_NOTICE << "Format of input :  rgbComponentSyncIn" << std::endl; }
261                if (input_format == yuvComponentIn)     { OSG_NOTICE << "Format of input :  yuvComponentIn" << std::endl; }
262                if (input_format == yuvComponentSyncIn) { OSG_NOTICE << "Format of input :  yuvComponentSyncIn" << std::endl; }
263                if (input_format == sdiIn)              { OSG_NOTICE << "Format of input :  sdiIn" << std::endl; }
264            }
265        }
266        // CURRENT Input
267        short active_input;
268        vid_err = VDGetInput(aComponent, &active_input);
269        if (vid_err) { OSG_NOTICE << "VDGetInput(aComponent, &active_input) - ERROR" << std::endl; }
270        else         { OSG_NOTICE << "Currently active input :  " << active_input << std::endl; }
271    }
272}
273
274void probe_video_digitizer_components()
275{
276      // Extra scopes for DEBUG and breakpoint/stack checking plus QT init/destroy
277      {
278          // Begin QuickTime
279          QTScopedQTMLInitialiser  qt_init;
280          QTScopedMovieInitialiser qt_movie_init;
281
282          // #define videoDigitizerComponentType = 'vdig'
283          ComponentDescription video_component_description;
284          video_component_description.componentType         = 'vdig'; /* A unique 4-byte code indentifying the command set */
285          video_component_description.componentSubType      = 0;      /* Particular flavor of this instance */
286          video_component_description.componentManufacturer = 0;      /* Vendor indentification */
287          video_component_description.componentFlags        = 0;      /* 8 each for Component,Type,SubType,Manuf/revision */
288          video_component_description.componentFlagsMask    = 0;      /* Mask for specifying which flags to consider in search, zero during registration */
289          long num_video_components = CountComponents (&video_component_description);
290          OSG_NOTICE << " available Video DigitizerComponents : " << num_video_components << std::endl;
291          if (num_video_components)
292          {
293              Component aComponent = 0;
294              do
295              {
296                  ComponentDescription full_video_component_description = video_component_description;
297                  aComponent = FindNextComponent(aComponent, &full_video_component_description);
298                  if (aComponent)
299                  {
300                      OSG_NOTICE << "Component" << std::endl;
301                      OSErr                err;
302                      Handle compName = NewHandle(256);
303                      Handle compInfo = NewHandle(256);
304                      err = GetComponentInfo( aComponent, &full_video_component_description, compName,compInfo,0);
305                      OSG_NOTICE << "    Name: " << pstr_printable((StringPtr)*compName) << std::endl;
306                      OSG_NOTICE << "    Desc: " << pstr_printable((StringPtr)*compInfo) << std::endl;
307                      //Capabilities
308                      VideoDigitizerComponent component_instance = OpenComponent(aComponent);
309                      print_video_component_capability(component_instance);
310                      CloseComponent(component_instance);
311                  }
312              }
313              while (0 != aComponent);
314          }
315          // End QuickTime
316      }
317}
318
319OSG_SGDeviceList print_sequence_grabber_device_list(SGDeviceList deviceList)
320{
321    short count         = (*deviceList)->count;
322    short selectedIndex = (*deviceList)->selectedIndex;
323    OSG_NOTICE << "DeviceList : " << count << " devices in total" << std::endl;
324    OSG_NOTICE << "DeviceList : " << selectedIndex << " is current device" << std::endl;
325
326    // Create List
327    OSG_SGDeviceList device_list;
328    OSG_SGDevicePair device_pair;
329    for (short i=0; i<count; ++i)
330    {
331        // Devices
332        OSG_NOTICE << std::endl;
333        SGDeviceName deviceNameRec = (*deviceList)->entry[i];
334        Str63        deviceNameStr;
335        memcpy(deviceNameStr, deviceNameRec.name, sizeof(Str63));
336        OSG_NOTICE << "    " << "Device ID : " << i << "  : DeviceNameStr : " << pstr_printable(deviceNameStr) << std::endl;
337        SGDeviceInputList deviceInputList = deviceNameRec.inputs;
338        if (deviceInputList)
339        {
340            // Inputs
341            short inputCount         = (*deviceInputList)->count;
342            short inputSelectedIndex = (*deviceInputList)->selectedIndex;
343            OSG_NOTICE << "    " << "InputList : " << inputCount << " inputs in total" << std::endl;
344            OSG_NOTICE << "    " << "InputList : " << inputSelectedIndex << " is current input" << std::endl;
345            for (short inp=0; inp<inputCount; ++inp)
346            {
347                SGDeviceInputName inputNameRec = (*deviceInputList)->entry[inp];
348                Str63             inputNameStr;
349                memcpy(inputNameStr, inputNameRec.name, sizeof(Str63));
350                OSG_NOTICE << "        " << "InputNameStr : " << inp << " " << pstr_printable(inputNameStr) << std::endl;
351                // Build up device list
352                std::ostringstream os;
353                os << i << ":" << inp << ".live";
354                device_pair.first  = os.str();
355                device_pair.second = std::string(pstr_printable(deviceNameStr)) + std::string("    ") + std::string(pstr_printable(inputNameStr));
356                // Append
357                device_list.push_back(device_pair);
358            }
359        }
360        else
361        {
362            OSG_NOTICE << "    InputList is empty!" << std::endl;
363        }
364    }
365    return device_list;
366}
367
368std::vector<OSG_SGDeviceList> probe_sequence_grabber_components()
369{
370      // Create List
371      std::vector<OSG_SGDeviceList> devices_list;
372      OSG_SGDeviceList              device_list;
373      // Extra scopes for DEBUG and breakpoint/stack checking plus QT init/destroy
374      {
375          // Begin QuickTime
376          QTScopedQTMLInitialiser  qt_init;
377          QTScopedMovieInitialiser qt_movie_init;
378
379          // #define videoDigitizerComponentType = 'vdig'
380          ComponentDescription sg_component_description;
381          sg_component_description.componentType         = SeqGrabComponentType; /* A unique 4-byte code indentifying the command set */
382          sg_component_description.componentSubType      = 0L;      /* Particular flavor of this instance */
383          sg_component_description.componentManufacturer = 'appl';  /* Vendor indentification */
384          sg_component_description.componentFlags        = 0L;      /* 8 each for Component,Type,SubType,Manuf/revision */
385          sg_component_description.componentFlagsMask    = 0L;      /* Mask for specifying which flags to consider in search, zero during registration */
386          long num_sg_components = CountComponents (&sg_component_description);
387          OSG_NOTICE << " available SequenceGrabber Components : " << num_sg_components << std::endl;
388          if (num_sg_components)
389          {
390              Component aComponent = 0;
391              do
392              {
393                  ComponentDescription full_sg_component_description = sg_component_description;
394                  aComponent = FindNextComponent(aComponent, &full_sg_component_description);
395                  if (aComponent)
396                  {
397                      OSG_NOTICE << "Component" << std::endl;
398                      OSErr                err;
399                      Handle compName = NewHandle(256);
400                      Handle compInfo = NewHandle(256);
401                      err = GetComponentInfo( aComponent, &full_sg_component_description, compName,compInfo,0);
402                      OSG_NOTICE << "    Name: " << pstr_printable((StringPtr)*compName) << std::endl;
403                      OSG_NOTICE << "    Desc: " << pstr_printable((StringPtr)*compInfo) << std::endl;
404                      SeqGrabComponent gSeqGrabber;
405                      SGChannel           gVideoChannel;
406                      SGChannel           gSoundChannel;
407                      Rect               gActiveVideoRect;
408                      gSeqGrabber = OpenComponent (aComponent);
409                      // If we got a sequence grabber, set it up
410                      if (gSeqGrabber != 0L)
411                      {
412                          ComponentResult result = noErr;
413                          // Initialize the sequence grabber
414                          result = SGInitialize (gSeqGrabber);
415                          if (result == noErr)
416                          {
417                              // Check capability and setting of Sequence Grabber
418                              Rect         destinationBounds;
419                              OSStatus     err;
420                              GDHandle     origDevice;
421                              CGrafPtr     origPort;
422                              GWorldPtr    gw;
423                              PixMapHandle pixmap = NULL;
424                              int*         destinationData = new int [1024*1024]; // 1024*1024*4 bytes (32bit RGBA)
425                              destinationBounds.left   = 0;
426                              destinationBounds.top    = 0;
427                              destinationBounds.right  = 2048;
428                              destinationBounds.bottom = 2048;
429                              err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &destinationBounds,
430                                                       NULL, NULL, 0, (Ptr)destinationData, 4*1024);
431                              if (err !=0 )
432                              {
433                                  OSG_FATAL << "Could not create gWorld" << std::endl;
434                              }
435                              else
436                              {
437                                  // Create GWorld
438                                  GetGWorld (&origPort, &origDevice);
439                                  SetGWorld (gw, NULL); // set current graphics port to offscreen
440                                  pixmap = GetGWorldPixMap (gw);
441                                  if (pixmap)
442                                  {
443                                      if (!LockPixels (pixmap)) // lock offscreen pixel map
444                                      {
445                                          OSG_FATAL << "Could not lock PixMap" << std::endl;
446                                      }
447                                  }
448                                  // Set GWorld
449                                  result = SGSetGWorld(gSeqGrabber, (CGrafPtr)gw, 0);
450                                  // Set GWorld back
451                                  // SetGWorld(origPort, origDevice);
452                                  if (result != noErr)
453                                  {
454                                      OSG_FATAL << "Could not set GWorld on SG" << std::endl;
455                                  }
456                                  else
457                                  {
458                                      // Get a video channel
459                                      result = SGNewChannel (gSeqGrabber, VideoMediaType, &gVideoChannel);
460                                      if ((gVideoChannel != nil) && (result == noErr))
461                                      {
462                                          // Init
463                                          // result = SGInitChannel(gVideoChannel, gSeqGrabber);
464//                                           if (result != noErr)
465//                                           {
466//                                               OSG_NOTICE << "SGInitChannel - failed!" << std::endl;
467//                                           }
468                                          // Usage
469                                          result = SGSetChannelUsage (gVideoChannel, seqGrabPreview);
470                                          // Bounds
471                                          result = SGGetSrcVideoBounds (gVideoChannel, &gActiveVideoRect);
472                                          OSG_NOTICE << "SrcVideoBounds: " << gActiveVideoRect.right << " " << gActiveVideoRect.bottom << std::endl;
473                                          Str255 deviceName;
474                                          Str255 inputName;
475                                          short  inputNumber;
476                                          result = SGGetChannelDeviceAndInputNames( gVideoChannel, deviceName, inputName, &inputNumber);
477                                          if (result != noErr)
478                                          {
479                                              OSG_NOTICE << "Could not get DeviceAndInput names from Video SG" << std::endl;
480                                          }
481                                          OSG_NOTICE << "ChannelDeviceAndInputNamesNumber: " << pstr_printable(deviceName) << " : " << pstr_printable(inputName) << " : " << inputNumber << std::endl;
482                                          SGDeviceList deviceList;
483                                          result = SGGetChannelDeviceList( gVideoChannel, sgDeviceListIncludeInputs, &deviceList);
484                                          if (result != noErr)
485                                          {
486                                              OSG_NOTICE << "Could not get DeviceList from Video SG" << std::endl;
487                                          }
488                                          else
489                                          {
490                                              OSG_NOTICE << "DeviceList from Video SG ok" << std::endl;
491                                              device_list = print_sequence_grabber_device_list(deviceList);
492                                              devices_list.push_back(device_list);
493                                          }
494                                      }
495                                      // Get a sound channel
496                                      result = SGNewChannel (gSeqGrabber, SoundMediaType, &gSoundChannel);
497                                      if ((gSoundChannel != nil) && (result == noErr))
498                                      {
499                                          // Usage
500                                          result = SGSetChannelUsage (gSoundChannel, seqGrabPreview);
501                                          Str255 deviceName;
502                                          Str255 inputName;
503                                          short  inputNumber;
504                                          result = SGGetChannelDeviceAndInputNames( gVideoChannel, deviceName, inputName, &inputNumber);
505                                          if (result != noErr)
506                                          {
507                                              OSG_NOTICE << "Could not get DeviceAndInput names from Sound SG" << std::endl;
508                                          }
509                                          OSG_NOTICE << "ChannelDeviceAndInputNamesNumber: " << pstr_printable(deviceName) << " : " << pstr_printable(inputName) << " : " << inputNumber << std::endl;
510                                          SGDeviceList deviceList;
511                                          result = SGGetChannelDeviceList( gSoundChannel, sgDeviceListIncludeInputs, &deviceList);
512                                          if (result != noErr)
513                                          {
514                                              OSG_NOTICE << "Could not get DeviceList from Sound SG" << std::endl;
515                                          }
516                                          else
517                                          {
518                                              OSG_NOTICE << "DeviceList from Sound SG ok" << std::endl;
519                                              device_list = print_sequence_grabber_device_list(deviceList);
520                                              devices_list.push_back(device_list);
521                                          }
522                                      }
523                                  }
524                              SetGWorld(origPort, origDevice);
525                              DisposeGWorld(gw);
526                              }
527                          }
528                      }
529                      SGDisposeChannel(gSeqGrabber, gVideoChannel);
530                      CloseComponent(gSeqGrabber);
531                  }
532              }
533              while (0 != aComponent);
534          }
535      // End QuickTime
536      }
537      return devices_list;
538}
539
540
541void get_video_device_bounds_idstr(short deviceID, short deviceInputID, short& out_width, short& out_height, Str63& out_deviceIDStr)
542{
543      // Extra scopes for DEBUG and breakpoint/stack checking plus QT init/destroy
544      {
545          // Begin QuickTime
546          QTScopedQTMLInitialiser  qt_init;
547          QTScopedMovieInitialiser qt_movie_init;
548
549          ComponentDescription sg_component_description;
550          sg_component_description.componentType         = SeqGrabComponentType; /* A unique 4-byte code indentifying the command set */
551          sg_component_description.componentSubType      = 0L;      /* Particular flavor of this instance */
552          sg_component_description.componentManufacturer = 0L;      /* Vendor indentification */
553          sg_component_description.componentFlags        = 0L;      /* 8 each for Component,Type,SubType,Manuf/revision */
554          sg_component_description.componentFlagsMask    = 0L;      /* Mask for specifying which flags to consider in search, zero during registration */
555          long num_sg_components = CountComponents (&sg_component_description);
556          if (num_sg_components)
557          {
558              Component aComponent = 0;
559              do
560              {
561                  ComponentDescription full_sg_component_description = sg_component_description;
562                  aComponent = FindNextComponent(aComponent, &full_sg_component_description);
563                  if (aComponent)
564                  {
565                      SeqGrabComponent gSeqGrabber;
566                      SGChannel           gVideoChannel;
567                      Rect               gActiveVideoRect;
568                      gSeqGrabber = OpenComponent (aComponent);
569                      // If we got a sequence grabber, set it up
570                      if (gSeqGrabber != 0L)
571                      {
572                          ComponentResult result = noErr;
573                          // Initialize the sequence grabber
574                          result = SGInitialize (gSeqGrabber);
575                          if (result == noErr)
576                          {
577                              // Check capability and setting of Sequence Grabber
578                              Rect         destinationBounds;
579                              OSStatus     err;
580                              GDHandle     origDevice;
581                              CGrafPtr     origPort;
582                              GWorldPtr    gw;
583                              PixMapHandle pixmap = NULL;
584                              int*         destinationData = new int [1024*1024]; // 1024*1024*4 bytes (32bit RGBA)
585                              destinationBounds.left   = 0;
586                              destinationBounds.top    = 0;
587                              destinationBounds.right  = 256;
588                              destinationBounds.bottom = 256;
589                              err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &destinationBounds,
590                                                       NULL, NULL, 0, (Ptr)destinationData, 4*256);
591                              if (err !=0 )
592                                  OSG_NOTICE << "Could not create gWorld" << std::endl;
593                              else
594                              {
595                                  // Create GWorld
596                                  GetGWorld (&origPort, &origDevice);
597                                  SetGWorld (gw, NULL); // set current graphics port to offscreen
598                                  pixmap = GetGWorldPixMap (gw);
599                                  if (pixmap)
600                                  {
601                                      if (!LockPixels (pixmap))
602                                      {
603                                          // lock offscreen pixel map
604                                          OSG_FATAL << "Could not lock PixMap" << std::endl;
605                                      }
606                                  }
607                                  // Set GWorld
608                                  result = SGSetGWorld(gSeqGrabber, (CGrafPtr)gw, 0);
609                                  // Set GWorld back
610                                  // SetGWorld(origPort, origDevice);
611                                  if (result != noErr)
612                                  {
613                                      OSG_FATAL << "Could not set GWorld on SG" << std::endl;
614                                  }
615                                  else
616                                  {
617                                      // Get a video channel
618                                      result = SGNewChannel (gSeqGrabber, VideoMediaType, &gVideoChannel);
619                                      if ((gVideoChannel != nil) && (result == noErr))
620                                      {
621                                          result = SGSetChannelUsage (gVideoChannel, seqGrabPreview);
622                                          Str255 deviceName;
623                                          Str255 inputName;
624                                          short  inputNumber;
625                                          result = SGGetChannelDeviceAndInputNames( gVideoChannel, deviceName, inputName, &inputNumber);
626                                          SGDeviceList deviceList;
627                                          result = SGGetChannelDeviceList( gVideoChannel, sgDeviceListIncludeInputs, &deviceList);
628                                          short count = (*deviceList)->count;
629                                          if (deviceID >= count)
630                                          {
631                                              OSG_FATAL << "DeviceID : " << deviceID << " too large - we only have " << count << " devices" << std::endl;
632                                          }
633                                          SGDeviceName deviceNameRec = (*deviceList)->entry[deviceID];
634                                          SGDeviceInputList deviceInputList = deviceNameRec.inputs;
635                                          if (deviceInputList == 0)
636                                          {
637                                              OSG_FATAL << "DeviceInputList is empty!" << std::endl;
638                                          }
639                                          else
640                                          {
641                                              short inputCount = (*deviceInputList)->count;
642                                              if (deviceInputID >= inputCount)
643                                              {
644                                                  OSG_FATAL << "DeviceInputID : " << deviceInputID << " too large - we only have " << inputCount << " inputs for device" << std::endl;
645                                              }
646                                          }
647                                          // Ok
648                                          Str63 deviceNameStr;
649                                          memcpy(deviceNameStr, deviceNameRec.name, sizeof(Str63));
650                                          // Set
651                                          result = SGSetChannelDevice     ( gVideoChannel, deviceNameStr);
652                                          result = SGSetChannelDeviceInput( gVideoChannel, deviceInputID);
653
654                                          VideoDigitizerComponent vdig = SGGetVideoDigitizerComponent(gVideoChannel);
655                                          VideoDigitizerError vid_err;
656                                          vid_err = VDSetInputStandard (vdig, palIn);
657                                          result = SGVideoDigitizerChanged( gVideoChannel);
658
659                                          result = SGGetSrcVideoBounds    ( gVideoChannel, &gActiveVideoRect);
660                                          OSG_NOTICE << "SrcVideoBounds: " << gActiveVideoRect.right << " " << gActiveVideoRect.bottom << std::endl;
661                                          // Out
662                                          out_width  = gActiveVideoRect.right;
663                                          out_height = gActiveVideoRect.bottom;
664                                          memcpy(out_deviceIDStr, deviceNameRec.name, sizeof(Str63));
665                                      }
666                                  }
667                              SetGWorld(origPort, origDevice);
668                              DisposeGWorld(gw);
669                              }
670                          }
671                      }
672                      SGDisposeChannel(gSeqGrabber, gVideoChannel);
673                      CloseComponent(gSeqGrabber);
674                  }
675              }
676              while (0 != aComponent);
677          }
678      // End QuickTime
679      }
680}
681
682void get_sound_device_idstr(short soundDeviceID, short soundDeviceInputID, Str63& out_soundDeviceIDStr)
683{
684          // Extra scopes for DEBUG and breakpoint/stack checking plus QT init/destroy
685      {
686          // Begin QuickTime
687          QTScopedQTMLInitialiser  qt_init;
688          QTScopedMovieInitialiser qt_movie_init;
689
690          // #define videoDigitizerComponentType = 'vdig'
691          ComponentDescription sg_component_description;
692          sg_component_description.componentType         = SeqGrabComponentType; /* A unique 4-byte code indentifying the command set */
693          sg_component_description.componentSubType      = 0L;      /* Particular flavor of this instance */
694          sg_component_description.componentManufacturer = 0L;      /* Vendor indentification */
695          sg_component_description.componentFlags        = 0L;      /* 8 each for Component,Type,SubType,Manuf/revision */
696          sg_component_description.componentFlagsMask    = 0L;      /* Mask for specifying which flags to consider in search, zero during registration */
697          long num_sg_components = CountComponents (&sg_component_description);
698          if (num_sg_components)
699          {
700              Component aComponent = 0;
701              do
702              {
703                  ComponentDescription full_sg_component_description = sg_component_description;
704                  aComponent = FindNextComponent(aComponent, &full_sg_component_description);
705                  if (aComponent)
706                  {
707                      SeqGrabComponent gSeqGrabber;
708                      SGChannel           gSoundChannel;
709                      gSeqGrabber = OpenComponent (aComponent);
710                      // If we got a sequence grabber, set it up
711                      if (gSeqGrabber != 0L)
712                      {
713                          ComponentResult result = noErr;
714                          // Initialize the sequence grabber
715                          result = SGInitialize (gSeqGrabber);
716                          if (result == noErr)
717                          {
718                              // Check capability and setting of Sequence Grabber
719                              // Get a sound channel
720                              result = SGNewChannel (gSeqGrabber, SoundMediaType, &gSoundChannel);
721                              if ((gSoundChannel != nil) && (result == noErr))
722                              {
723                                  result = SGSetChannelUsage (gSoundChannel, seqGrabPreview);
724                                  Str255 deviceName;
725                                  Str255 inputName;
726                                  short  inputNumber;
727                                  result = SGGetChannelDeviceAndInputNames( gSoundChannel, deviceName, inputName, &inputNumber);
728                                  SGDeviceList deviceList;
729                                  result = SGGetChannelDeviceList( gSoundChannel, sgDeviceListIncludeInputs, &deviceList);
730                                  short count = (*deviceList)->count;
731                                  if (soundDeviceID >= count)
732                                  {
733                                      OSG_FATAL << "DeviceID : " << soundDeviceID << " too large - we only have " << count << " devices" << std::endl;
734                                  }
735                                  SGDeviceName deviceNameRec = (*deviceList)->entry[soundDeviceID];
736                                  SGDeviceInputList deviceInputList = deviceNameRec.inputs;
737                                  short inputCount = (*deviceInputList)->count;
738                                  if (soundDeviceInputID >= inputCount)
739                                  {
740                                      OSG_FATAL << "DeviceInputID : " << soundDeviceInputID << " too large - we only have " << inputCount << " inputs for device" << std::endl;
741                                  }
742                                  // Ok
743                                  Str63 deviceNameStr;
744                                  memcpy(deviceNameStr, deviceNameRec.name, sizeof(Str63));
745                                  // Set
746                                  result = SGSetChannelDevice     ( gSoundChannel, deviceNameStr);
747                                  result = SGSetChannelDeviceInput( gSoundChannel, soundDeviceInputID);
748                                  // Out
749                                  memcpy(out_soundDeviceIDStr, deviceNameRec.name, sizeof(Str63));
750
751                                  SGDisposeChannel(gSeqGrabber, gSoundChannel);
752                              }
753                          }
754                          CloseComponent(gSeqGrabber);
755                      }
756                  }
757              }
758              while (0 != aComponent);
759          }
760      // End QuickTime
761      }
762}
763
764
765
766// Getting Information About Video Digitizer Components
767// You can use the VDGetDigitizerInfo function in your application to retrieve
768// information about the capabilities of a video digitizer component. You can use
769// the VDGetCurrentFlags function to obtain current status information from a video digitizer component.
770
771// Setting Source Characteristics
772// You can use the VDGetMaxSrcRect function in your application to get the size and location of the maximum
773// source rectangle. Similarly, the VDGetActiveSrcRect function allows you to get this information about
774// the active source rectangle, and the VDGetVBlankRect function enables you to obtain information about the vertical blanking rectangle.
775// You can use the VDSetDigitizerRect function to set the size and location of the digitizer rectangle.
776// The VDGetDigitizerRect function lets you retrieve the size and location of this rectangle.
777
778// Imput Source
779// Some of these functions provide information about the available video inputs. Applications can use
780// the VDGetNumberOfInputs function to determine the number of video inputs supported by the digitizer component.
781// The VDGetInputFormat function allows applications to find out the video format (composite, s-video, or component) employed by a specified input.
782// You can use the VDSetInput function in your application to specify the input to be used by the digitizer component.
783// The VDGetInput function returns the currently selected input.
784// The VDSetInputStandard function allows you to specify the video signaling standard to be used by the video digitizer component.
785
786/*
787QTVideoOutputRestoreState
788QTVideoOutputSaveState
789
790 Selecting an Input Source
791VDGetInput
792VDGetInputFormat
793VDGetNumberOfInputs
794VDSetInput
795VDSetInputStandard
796 Setting Source Characteristics
797VDGetActiveSrcRect
798VDGetDigitizerRect
799VDGetMaxSrcRect
800VDGetVBlankRect
801VDSetDigitizerRect
802 Setting Video Destinations
803VDGetMaxAuxBuffer
804VDGetPlayThruDestination
805VDPreflightDestination
806VDPreflightGlobalRect
807VDSetPlayThruDestination
808VDSetPlayThruGlobalRect
809 Video Clipping
810VDClearClipRgn
811VDGetClipState
812VDSetClipRgn
813VDSetClipState
814*/
815
816/*
817QTVideoOutputCopyIndAudioOutputDeviceUID
818QTVideoOutputGetIndImageDecompressor
819VDGetInputGammaRecord
820VDGetInputName
821VDGetPreferredImageDimensions
822VDIIDCGetCSRData
823VDIIDCGetDefaultFeatures
824VDIIDCGetFeatures
825VDIIDCGetFeaturesForSpecifier
826VDIIDCSetCSRData
827VDIIDCSetFeatures
828VDSetDestinationPort
829VDSetInputGammaRecord
830VDSetPreferredImageDimensions
831VDUseSafeBuffers
832*/
833
834//void test ()
835//{
836//if ((i == count-1) && (inp == inputCount-1))
837//{
838//    OSG_NOTICE << "    * TEST SGSetChannelDevice(..) : " << pstr_printable(deviceNameRec.name) << std::endl;
839//    result = SGSetChannelDevice (gVideoChannel, deviceNameStr);
840//    if (result == noErr)
841//    {
842//        result = SGSetChannelDeviceInput( gVideoChannel, 0 );
843//        result = SGGetSrcVideoBounds (gVideoChannel, &gActiveVideoRect);
844//        OSG_NOTICE << "SrcVideoBounds: " << gActiveVideoRect.right << " " << gActiveVideoRect.bottom << std::endl;
845//        Str255 deviceName2;
846//        Str255 inputName2;
847//        short  inputNumber2;
848//        result = SGGetChannelDeviceAndInputNames( gVideoChannel, deviceName2, inputName2, &inputNumber2);
849//        OSG_NOTICE << "ChannelDeviceAndInputNamesNumber: " << pstr_printable(deviceName2) << " : " << pstr_printable(inputName2) << " : " << inputNumber2 << std::endl;
850//        result = SGGetChannelDeviceList( gVideoChannel, sgDeviceListIncludeInputs, &deviceList);
851//        if (result != noErr)
852//        {
853//            OSG_NOTICE << "Could not get DeviceList from Video SG" << std::endl;
854//        }
855//        else
856//        {
857//            OSG_NOTICE << "DeviceList from Video SG ok" << std::endl;
858//            short count         = (*deviceList)->count;
859//            short selectedIndex = (*deviceList)->selectedIndex;
860//            OSG_NOTICE << "DeviceList : " << count << " devices in total" << std::endl;
861//            OSG_NOTICE << "DeviceList : " << selectedIndex << " is current device" << std::endl;
862//        }
863//    }
864//    else
865//    {
866//        OSG_NOTICE << "SGSetChannelDevice - failed!" << std::endl;
867//    }
868//    OSG_NOTICE << "    * TEST SGSetChannelDevice(..) end" << std::endl;
869//}
Note: See TracBrowser for help on using the browser.