Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
MySGStuff.c
/* |
File: MySGStuff.c |
Contains: Sequence grabber code. |
Written by: John Wang |
Copyright: © 1994 by Apple Computer, Inc., all rights reserved. |
Change History (most recent first): |
<5> 07/01/94 JW 1.0 Added workaround for AV machines that don't initialize video |
settings properly. The fix is to call GetSetting and then SetSettings |
when no preferences is loaded for the channel. |
<4> 04/25/94 JW 1.0b4. Fixed minor bug in 1.0b3 where if the sound channel wasn't |
opened, then MyUpdateChannels would fail. |
<3> 04/18/94 JW 1.0b3. Support for multiple capture channels. |
<2> 04/08/94 JW 1.0b2. Support for preferences file added so that channel |
settings is preserved. |
<1> 04/04/94 JW 1.0b1 Started and created as 1.0b1. |
To Do: |
*/ |
#ifdef THINK_C |
#define applec |
#endif |
#include "MyHeaders" |
/* |
#include <Types.h> |
#include <Memory.h> |
#include <QuickDraw.h> |
#include <Palettes.h> |
#include <QDOffscreen.h> |
#include <Errors.h> |
#include <Fonts.h> |
#include <Dialogs.h> |
#include <Windows.h> |
#include <Menus.h> |
#include <Events.h> |
#include <Desk.h> |
#include <DiskInit.h> |
#include <OSUtils.h> |
#include <Resources.h> |
#include <ToolUtils.h> |
#include <AppleEvents.h> |
#include <EPPC.h> |
#include <GestaltEqu.h> |
#include <Processes.h> |
#include <Balloons.h> |
#include <Aliases.h> |
#include <MixedMode.h> |
#include <Scrap.h> |
#include <LowMem.h> |
#include <Movies.h> |
#include <QuickTimeComponents.h> |
*/ |
#include "MyCaptureAppShell.h" |
#include "MySGStuff.h" |
#include "MyUtils.h" |
/* ------------------------------------------------------------------------- */ |
// Contains application runtime variables. Stored in window refCon as handle block. |
struct WindowInfo { |
ComponentInstance theSG; |
SGChannel channel[kMAXCHANNELS]; |
Boolean recordPlayThru; |
Boolean createSeparateFiles; |
}; |
typedef struct WindowInfo WindowInfo, *WindowInfoPtr, **WindowInfoHandle; |
// Contains compression settings for the video channel. Used in SGInfo. |
struct CompressionInfo { |
OSType compressorType; |
short depth; |
CodecQ spatialQuality; |
CodecQ temporalQuality; |
long keyFrameRate; |
}; |
typedef struct CompressionInfo CompressionInfo; |
// Contains Sequence Grabber channel information. Stored as a global variable. |
struct SGInfo { |
CompressionInfo cInfo; |
OSType channelType[kMAXCHANNELS]; |
Handle channelName[kMAXCHANNELS]; |
UserData channelSettings[kMAXCHANNELS]; |
}; |
typedef struct SGInfo SGInfo; |
SGInfo gSGInfo; |
// Boolean variable. true is QuickTime 2.0 or later. false otherwise i.e. 1.6.2. |
Boolean gHasQuickTime20; |
/* ------------------------------------------------------------------------- */ |
// MyInitialize is called at init time after the toolbox is initialized. This routine is |
// called only once. |
long MyInitialize() |
{ |
long err; |
long QDfeature; |
short myRefNum; |
short i; |
ComponentDescription cd, theCD; |
Component aComponent; |
Boolean done; |
MenuHandle mHandle; |
// We require QuickTime so make sure it is available. |
err = Gestalt(gestaltQuickTime, &QDfeature); |
if ( err != noErr ) |
return ( err ); |
// Check for QuickTime 2.0 or later. |
gHasQuickTime20 = ((QDfeature >> 16) & 0xffff) >= 0x200; |
// Start the engine. |
err = EnterMovies(); |
if ( err != noErr ) |
return ( err) ; |
// Find out what sequence grabber channels are available by searching all sequence |
// grabber channel components. Get channelType[] and channelName[]. |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
gSGInfo.channelType[i] = 0; |
gSGInfo.channelName[i] = nil; |
} |
cd.componentType = SeqGrabChannelType; |
cd.componentSubType = 0; |
cd.componentManufacturer = 0; |
cd.componentFlags = 0; |
cd.componentFlagsMask = 0; |
aComponent = 0; |
for ( i=0, done=false; i<kMAXCHANNELS && !done; i++ ) { |
aComponent = FindNextComponent(aComponent, &cd); |
if (aComponent != 0) { |
gSGInfo.channelName[i] = NewHandle(4); |
GetComponentInfo(aComponent, &theCD, gSGInfo.channelName[i], nil, nil); |
gSGInfo.channelType[i] = theCD.componentSubType; |
} else |
done = true; |
} |
// Read preferences for compression settings and |
// channelSettings[] (if channel has been previously found). |
if ( (myRefNum = readPreferencesFile()) != -1 ) { |
// File opened. |
Handle myHandle; |
// Get Compression info. |
myHandle = Get1Resource('INFO', 128); |
if ( myHandle != nil ) { |
DetachResource(myHandle); |
HLock(myHandle); |
BlockMove(*myHandle, &(gSGInfo.cInfo), sizeof(CompressionInfo)); |
HUnlock(myHandle); |
DisposeHandle(myHandle); |
} else { |
// If no such resource, then manually udpate the values. |
gSGInfo.cInfo.compressorType = 'raw '; |
gSGInfo.cInfo.depth = 16; |
gSGInfo.cInfo.spatialQuality = codecLosslessQuality; |
gSGInfo.cInfo.temporalQuality = 0; |
gSGInfo.cInfo.keyFrameRate = 0; |
} |
// Get all the saved channel settings for the channels that are available. |
for ( i=0; i< kMAXCHANNELS; i++ ) { |
if (gSGInfo.channelType[i] != 0) { |
myHandle = Get1Resource(gSGInfo.channelType[i], 128); |
if ( myHandle != nil ) { |
err = NewUserDataFromHandle(myHandle, &(gSGInfo.channelSettings[i])); |
if ( err != noErr ) { |
ReportWarning("\pCould not create user data from handle: ", err); |
gSGInfo.channelSettings[i] = nil; |
} |
} else |
gSGInfo.channelSettings[i] = nil; |
} else |
gSGInfo.channelSettings[i] = nil; |
} |
// Finished. Close the preferences file. |
closePreferencesFile(myRefNum); |
} else { |
// If no preferences file, then use default values. |
gSGInfo.cInfo.compressorType = 'raw '; |
gSGInfo.cInfo.depth = 16; |
gSGInfo.cInfo.spatialQuality = codecLosslessQuality; |
gSGInfo.cInfo.temporalQuality = 0; |
gSGInfo.cInfo.keyFrameRate = 0; |
for ( i=0; i< kMAXCHANNELS; i++ ) |
gSGInfo.channelSettings[i] = nil; |
} |
// Add the channel names to the menu. |
mHandle = GetMHandle(kMENU_SETTINGSID); |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
if (gSGInfo.channelType[i] != 0) { |
Str255 myStr; |
BlockMove(" Disable", &myStr[1], 11); |
BlockMove(*(gSGInfo.channelName[i]), &myStr[11], **(gSGInfo.channelName[i]) + 1); |
myStr[0] = 11 + **(gSGInfo.channelName[0]); |
myStr[11] = ' '; |
AppendMenu(mHandle, (unsigned char *) *(gSGInfo.channelName[i])); |
AppendMenu(mHandle, myStr); |
} |
} |
return ( noErr ); |
} |
void MyFinishup() |
{ |
long err; |
short myRefNum, i; |
// Should close all windows. But, since we know this app only supports one window, we |
// don't need to loop. |
MyClose(); |
// Write preferences file for all channel settings and compression settings. |
if ((myRefNum = writePreferencesFile()) != -1) { |
Handle mySetting, myInfo; |
// Write the compressor settings to preferences file. |
myInfo = NewHandle(sizeof(CompressionInfo)); |
if ( myInfo == nil ) { |
ReportWarning("\pCound not create compressor settings handle.", 0); |
} else { |
HLock((Handle) myInfo); |
BlockMove(&(gSGInfo.cInfo), *myInfo, sizeof(CompressionInfo)); |
HUnlock((Handle) myInfo); |
AddResource(myInfo, 'INFO', 128, "\pCompression Settings."); |
} |
// Write out channel settings. |
for ( i=0; i< kMAXCHANNELS; i++ ) { |
if (gSGInfo.channelType[i] != 0 && gSGInfo.channelSettings[i] != nil ) { |
mySetting = NewHandle(4); |
if ( mySetting == nil ) { |
ReportWarning("\pCound not create settings handle.", 0); |
} else { |
PutUserDataIntoHandle(gSGInfo.channelSettings[i], mySetting); |
AddResource(mySetting, gSGInfo.channelType[i], 128, "\pSettings."); |
} |
} else |
gSGInfo.channelSettings[i] = nil; |
} |
closePreferencesFile(myRefNum); |
} else |
ReportWarning("\pSorry. Could not create preferences file.", 0); |
} |
void MyIdle() |
{ |
WindowPtr theWindow; |
theWindow = FrontWindow(); |
// Only one window allowed to be opened at a time. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
if ((**myWindowInfo).theSG != nil) |
SGIdle((**myWindowInfo).theSG); |
} |
} |
long MyYieldTime(long message) |
{ |
if ( message ) |
// Resume message |
return ( 0 ); |
else |
// Suspend message |
return ( 30 ); |
} |
void MyAdjustMenus() |
{ |
MenuHandle mHandle; |
WindowPtr theWindow; |
WindowInfoHandle myWindowInfo; |
short i; |
theWindow = FrontWindow(); |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
// File menu. |
mHandle = GetMHandle(kMENU_FILEID); |
DisableItem(mHandle, kMENU_FILENEW); |
EnableItem(mHandle, kMENU_FILECLOSE); |
// Settings menu. |
mHandle = GetMHandle(kMENU_SETTINGSID); |
EnableItem(mHandle, 0); |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
if (gSGInfo.channelType[i] != 0) { |
if ( (**myWindowInfo).channel[i] != nil ) { |
EnableItem(mHandle, i*2+1); |
EnableItem(mHandle, i*2+2); |
} else { |
DisableItem(mHandle, i*2+1); |
DisableItem(mHandle, i*2+2); |
} |
} |
} |
// Resize menu. |
mHandle = GetMHandle(kMENU_RESIZEID); |
EnableItem(mHandle, 0); |
// Special menu. |
mHandle = GetMHandle(kMENU_SPECIALID); |
EnableItem(mHandle, 0); |
CheckItem(mHandle, kMENU_SPECIALPLAYTHRU, (**myWindowInfo).recordPlayThru); |
if ( !gHasQuickTime20 ) { |
(**myWindowInfo).createSeparateFiles = false; |
DisableItem(mHandle, kMENU_SPECIALSEPARATEFILES); |
} else |
EnableItem(mHandle, kMENU_SPECIALSEPARATEFILES); |
CheckItem(mHandle, kMENU_SPECIALSEPARATEFILES, (**myWindowInfo).createSeparateFiles); |
// Record menu. |
mHandle = GetMHandle(kMENU_RECORDID); |
EnableItem(mHandle, 0); |
} else { // No window open. |
// File menu. |
mHandle = GetMHandle(kMENU_FILEID); |
EnableItem(mHandle, kMENU_FILENEW); |
DisableItem(mHandle, kMENU_FILECLOSE); |
// Settings menu. |
mHandle = GetMHandle(kMENU_SETTINGSID); |
DisableItem(mHandle, 0); |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
if (gSGInfo.channelType[i] != 0) { |
EnableItem(mHandle, i*2); |
EnableItem(mHandle, i*2+1); |
} |
} |
// Resize menu. |
mHandle = GetMHandle(kMENU_RESIZEID); |
DisableItem(mHandle, 0); |
// Special menu. |
mHandle = GetMHandle(kMENU_SPECIALID); |
DisableItem(mHandle, 0); |
CheckItem(mHandle, kMENU_SPECIALPLAYTHRU, false); |
CheckItem(mHandle, kMENU_SPECIALSEPARATEFILES, false); |
// Record menu. |
mHandle = GetMHandle(kMENU_RECORDID); |
DisableItem(mHandle, 0); |
} |
DrawMenuBar(); |
} |
/* ------------------------------------------------------------------------- */ |
void MyNew() |
{ |
long err; |
WindowPtr myWindow; |
Rect myBounds = {42, 4, 282, 324}; |
WindowInfoHandle myWindowInfo; |
short i, videoChannel, soundChannel; |
myWindow = nil; |
myWindowInfo = nil; |
// Create window along with window info record. |
myWindow = NewCWindow(0L, &myBounds, "\pCapture window", 1, documentProc, (WindowPtr) -1, true, 0L); |
if (myWindow == nil) { |
ReportWarning("\pCould not create new window.",0); |
goto bail; |
} |
SetGWorld((CGrafPtr) myWindow, GetMainDevice()); |
myWindowInfo = (WindowInfoHandle) NewHandleClear(sizeof(WindowInfo)); |
if ( myWindowInfo == nil ) { |
ReportWarning("\pCould not create window info handle.", 0); |
goto bail; |
} |
MoveHHi((Handle) myWindowInfo); |
HLock((Handle) myWindowInfo); |
SetWRefCon(myWindow, (long) myWindowInfo); |
(**myWindowInfo).recordPlayThru = false; |
(**myWindowInfo).createSeparateFiles = false; |
// Open sequence grabber and initialize the sequence grabber. |
(**myWindowInfo).theSG = OpenDefaultComponent(SeqGrabComponentType, 0); |
if ( (**myWindowInfo).theSG == nil) { |
ReportWarning("\pOpenDefaultComponent failed to open default sequence grabber component.", 0); |
goto bail; |
} |
err = SGInitialize((**myWindowInfo).theSG); |
if ( err != noErr ) { |
ReportWarning("\pCould not initialize sequence grabber: ", err); |
goto bail; |
} |
// First things first, set the GWorld to the newly created window. |
err = SGSetGWorld((**myWindowInfo).theSG, (CGrafPtr) myWindow, GetMainDevice()); |
if ( err != noErr ) { |
ReportWarning("\pCould not SGSetGWorld: ", err); |
goto bail; |
} |
// Now, let's create the different channels. |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
// If the channel type exists, then create it. |
if ( gSGInfo.channelType[i] != 0) { |
// Create channel. |
err = SGNewChannel((**myWindowInfo).theSG, gSGInfo.channelType[i], |
&((**myWindowInfo).channel[i])); |
if ( err != noErr ) { |
// Fail with this channel. |
ReportWarning("\pCould not open channel: ", err); |
(**myWindowInfo).channel[i] = 0; |
} else { |
// Set the settings retrieved from preferences file. |
if ( gSGInfo.channelSettings[i] != nil ) { |
err = SGSetChannelSettings((**myWindowInfo).theSG, (**myWindowInfo).channel[i], |
gSGInfo.channelSettings[i], 0); |
if ( err != noErr ) { |
ReportWarning("\pFailed to set channel settings: ", err); |
} |
} else { |
// Workaround for AV vdigs that don't initialize correctly. |
err = SGGetChannelSettings((**myWindowInfo).theSG, (**myWindowInfo).channel[i], |
&(gSGInfo.channelSettings[i]), 0); |
if ( err != noErr ){ |
ReportWarning("\pCould not get channel settings: ", err); |
gSGInfo.channelSettings[i] = nil; |
} |
err = SGSetChannelSettings((**myWindowInfo).theSG, (**myWindowInfo).channel[i], |
gSGInfo.channelSettings[i], 0); |
if ( err != noErr ) { |
ReportWarning("\pFailed to set channel settings: ", err); |
} |
} |
} |
} else |
(**myWindowInfo).channel[i] = 0; |
} |
// If there is a video channel, then set the compression settings. |
for ( videoChannel = -1, i=0; i<kMAXCHANNELS; i++ ) { |
if ( gSGInfo.channelType[i] == VideoMediaType ) |
videoChannel = i; |
} |
if ( videoChannel >= 0 ) { |
err = SGSetVideoCompressorType((**myWindowInfo).channel[videoChannel], gSGInfo.cInfo.compressorType); |
if ( err != noErr ) { |
ReportWarning("\pCould not set video compressor type: ", err); |
} |
err = SGSetVideoCompressor((**myWindowInfo).channel[videoChannel], gSGInfo.cInfo.depth, nil, |
gSGInfo.cInfo.spatialQuality, gSGInfo.cInfo.temporalQuality, gSGInfo.cInfo.keyFrameRate); |
if ( err != noErr ) { |
ReportWarning("\pCould not set video compressor info: ", err); |
} |
} |
// Update the channels. |
err = MyUpdateChannels(myWindow); |
if ( err != noErr ) { |
ReportWarning("\pCould not update channels: ", err); |
goto bail; |
} |
// Start the preview now that everything is set up!!! |
err = SGStartPreview((**myWindowInfo).theSG); |
if ( err != noErr ) { |
ReportWarning("\pCould not start preview.", err); |
goto bail; |
} |
return; |
bail: |
SysBeep(50); |
if ( (**myWindowInfo).theSG != nil ) |
CloseComponent((**myWindowInfo).theSG); |
if ( myWindowInfo != nil ) |
DisposHandle((Handle) myWindowInfo); |
if ( myWindow != nil ) |
DisposeWindow(myWindow); |
return; |
} |
void MyClose() |
{ |
long err; |
WindowPtr closeWindow; |
WindowInfoHandle myWindowInfo; |
short i, videoChannel; |
closeWindow = FrontWindow(); |
if ( closeWindow == nil ) |
return; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(closeWindow); |
// If there is a video channel, then get the compression settings. |
for ( videoChannel = -1, i=0; i<kMAXCHANNELS; i++ ) { |
if ( gSGInfo.channelType[i] == VideoMediaType ) |
videoChannel = i; |
} |
if ( videoChannel >= 0 ) { |
err = SGGetVideoCompressorType((**myWindowInfo).channel[videoChannel], &gSGInfo.cInfo.compressorType); |
if ( err != noErr ) |
gSGInfo.cInfo.compressorType = 'raw '; |
err = SGGetVideoCompressor((**myWindowInfo).channel[videoChannel], &gSGInfo.cInfo.depth, nil, |
&gSGInfo.cInfo.spatialQuality, &gSGInfo.cInfo.temporalQuality, |
&gSGInfo.cInfo.keyFrameRate); |
if ( err != noErr ) { |
gSGInfo.cInfo.depth = 16; |
gSGInfo.cInfo.spatialQuality = codecLosslessQuality; |
gSGInfo.cInfo.temporalQuality = 0; |
gSGInfo.cInfo.keyFrameRate = 0; |
} |
} |
// Get the video settings. |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
// Set the video settings retrieved from preferences file. |
if ( gSGInfo.channelType[i] != 0 && (**myWindowInfo).channel[i] != 0) { |
err = SGGetChannelSettings((**myWindowInfo).theSG, (**myWindowInfo).channel[i], |
&(gSGInfo.channelSettings[i]), 0); |
if ( err != noErr ){ |
ReportWarning("\pCould not get channel settings: ", err); |
gSGInfo.channelSettings[i] = nil; |
} |
} |
} |
// Close the component. |
if ( (**myWindowInfo).theSG != nil ) |
CloseComponent((**myWindowInfo).theSG); |
if ( myWindowInfo != nil ) |
DisposHandle((Handle) myWindowInfo); |
DisposeWindow(closeWindow); |
} |
/* ------------------------------------------------------------------------- */ |
void MySettings(short item) |
{ |
long err; |
WindowPtr theWindow; |
short index; |
theWindow = FrontWindow(); |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
index = (item - 1) / 2; |
if ( (item & 1) == 0 ) { |
// Pause before making changes. |
err = SGPause((**myWindowInfo).theSG, true); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
// Disable channel. |
if ( (**myWindowInfo).channel[index] != 0 ) { |
SGDisposeChannel((**myWindowInfo).theSG, (**myWindowInfo).channel[index]); |
(**myWindowInfo).channel[index] = 0; |
} |
err = SGPause((**myWindowInfo).theSG, false); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
} else { |
// Simply call SGSettingsDialog! That simple! |
SGSettingsDialog((**myWindowInfo).theSG, (**myWindowInfo).channel[index], 0, nil, DoTheRightThing, nil , 0); |
} |
} |
} |
void MyResize(short item) |
{ |
WindowPtr theWindow; |
long err; |
Boolean sizeChanged; |
short width, height; |
theWindow = FrontWindow(); |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
sizeChanged = false; |
switch ( item ) { |
case 1: |
width = 160; height = 120; |
sizeChanged = true; |
break; |
case 2: |
width = 240; height = 180; |
sizeChanged = true; |
break; |
case 3: |
width = 320; height = 240; |
sizeChanged = true; |
break; |
case 5: |
sizeChanged = GetCustomSize(&width, &height); |
break; |
} |
if ( sizeChanged ) { |
// Pause the sequence grabber before resizing window. |
err = SGPause((**myWindowInfo).theSG, true); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
// Resize and then update the video channel. |
SizeWindow(theWindow, width, height, false); |
err = MyUpdateChannels(theWindow); |
if ( err != noErr ) { |
ReportWarning("\pCould not update channels: ", err); |
} |
// OK. We can restart again. |
err = SGPause((**myWindowInfo).theSG, false); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
} |
} |
} |
void MySpecial(short item) |
{ |
WindowPtr theWindow; |
long err; |
Boolean updateFlag; |
theWindow = FrontWindow(); |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
updateFlag = false; |
switch ( item ) { |
case kMENU_SPECIALPLAYTHRU: |
(**myWindowInfo).recordPlayThru = !(**myWindowInfo).recordPlayThru; |
updateFlag = true; |
break; |
case kMENU_SPECIALSEPARATEFILES: |
(**myWindowInfo).createSeparateFiles = !(**myWindowInfo).createSeparateFiles; |
break; |
} |
// Only update if needed. |
if ( updateFlag ) { |
// Pause before changes. |
err = SGPause((**myWindowInfo).theSG, true); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
// Update the channels. |
err = MyUpdateChannels(theWindow); |
if ( err != noErr ) { |
ReportWarning("\pCould not update channels: ", err); |
} |
// OK to continue. |
err = SGPause((**myWindowInfo).theSG, false); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
} |
} |
} |
void MyRecord() |
{ |
WindowPtr theWindow; |
long err; |
StandardFileReply reply; |
ComponentInstance mySG; |
AliasHandle alias; |
SGOutput output; |
short i; |
theWindow = FrontWindow(); |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
mySG = (**myWindowInfo).theSG; |
if ( mySG != nil ) { |
if ( (**myWindowInfo).createSeparateFiles ) { |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
if ( (**myWindowInfo).channel[i] != 0) { |
StandardPutFile("\PName of multiple file:", "\pMovie #", &reply); |
if (!reply.sfGood) |
return; |
err = CreateMovieFile(&(reply.sfFile), 'TVOD', smSystemScript, |
createMovieFileDeleteCurFile | |
createMovieFileDontCreateMovie | |
createMovieFileDontOpenFile, nil, nil); |
if ( err != noErr ) { |
ReportWarning("\pCould not create movie file 1: ", err); |
goto bail; |
} |
NewAlias(nil, &(reply.sfFile), &alias); |
if ( alias == nil ) |
return; |
err = SGSetDataRef(mySG, (Handle) alias, 'alis', seqGrabToDisk); |
if ( err != noErr ) { |
ReportWarning("\pCould not set movie resource output: ", err); |
goto bail; |
} |
err = SGNewOutput(mySG, (Handle) alias, 'alis', seqGrabToDisk, &output); |
if ( err != noErr ) { |
ReportWarning("\pCould not create data output1: ", err); |
goto bail; |
} |
err = SGSetChannelOutput(mySG, (**myWindowInfo).channel[i], output); |
if ( err != noErr ) { |
ReportWarning("\pCould not set video channel output: ", err); |
goto bail; |
} |
} |
} |
} else { |
// If creating single file, then do this. |
StandardPutFile("\PName of new movie:", "\pMovie", &reply); |
if (!reply.sfGood) |
return; |
err = SGSetDataOutput(mySG, &reply.sfFile, seqGrabToDisk); |
if ( err != noErr ) { |
ReportWarning("\pCould not set data output: ", err); |
goto bail; |
} |
} |
// Set the window title so that the user knows that we are recording. |
SetWTitle(theWindow, "\pRecording... click mouse to stop."); |
// Start recording. |
err = SGStartRecord(mySG); |
if ( err != noErr ) { |
ReportWarning("\pCould not start recording. The following error was returned: ", err); |
} |
// Keep recording until the mouse button is pressed. |
while (!Button() && !err) { |
err = SGIdle(mySG); |
} |
// Stop recording. |
err = SGStop(mySG); |
if ( err != noErr ) { |
ReportWarning("\pCould not stop sequence grabber: ", err); |
goto bail; |
} else |
SetWTitle(theWindow, "\pMovie captured."); |
// Start preview again. |
err = MyUpdateChannels(theWindow); |
if ( err != noErr ) { |
ReportWarning("\pCould not update channels: ", err); |
goto bail; |
} |
err = SGStartPreview((**myWindowInfo).theSG); |
if ( err != noErr ) { |
ReportWarning("\pCould not start preview: ", err); |
goto bail; |
} |
// Reset the window title. |
SetWTitle(theWindow, "\pCapture window"); |
FlushEvents(mDownMask | mUpMask, 0); |
} |
} |
bail: |
return; |
} |
void MyDrag(WindowPtr theWindow, Point where) |
{ |
long err; |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
if ((**myWindowInfo).theSG != nil) |
// Pause preview. |
err = SGPause((**myWindowInfo).theSG, true); |
if ( err != noErr ) { |
ReportWarning("\pCould no pause preview: ", err); |
} |
// Drag window. |
DragWindow (theWindow, where, &qd.screenBits.bounds); |
// OK to restart preview. |
err = SGPause((**myWindowInfo).theSG, false); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
} |
} |
void MyUpdate(WindowPtr theWindow) |
{ |
long err; |
// Allow only one window to be opened. |
if ( theWindow != nil ) { // Yes, window open. |
WindowInfoHandle myWindowInfo; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
if ((**myWindowInfo).theSG != nil) |
// Pause and continue to reset clip. |
err = SGPause((**myWindowInfo).theSG, true); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
err = SGPause((**myWindowInfo).theSG, false); |
if ( err != noErr ) { |
ReportWarning("\pCould not pause preview: ", err); |
} |
} |
} |
long MyUpdateChannels(WindowPtr theWindow) |
{ |
long err; |
WindowInfoHandle myWindowInfo; |
long usage; |
short i, videoChannel; |
err = noErr; |
myWindowInfo = (WindowInfoHandle) GetWRefCon(theWindow); |
// Update the video channel if it exists. |
for ( videoChannel = -1, i=0; i<kMAXCHANNELS; i++ ) { |
if ( gSGInfo.channelType[i] == VideoMediaType ) |
videoChannel = i; |
} |
if ( videoChannel >= 0 ) { |
// Set the bounds to the entire portRect. |
err = SGSetChannelBounds((**myWindowInfo).channel[videoChannel], &(theWindow->portRect)); |
if ( err != noErr ) |
goto bail; |
// Set the video usage depending on whether or not there is playthru. |
usage = seqGrabPreview | seqGrabRecord; |
if ( !((**myWindowInfo).recordPlayThru) ) |
usage |= seqGrabPlayDuringRecord; |
err = SGSetChannelUsage((**myWindowInfo).channel[videoChannel], usage); |
if ( err != noErr ) |
goto bail; |
} |
for ( i=0; i<kMAXCHANNELS; i++ ) { |
// Since sound may be turned off, check before setting sound usage. |
if ( (gSGInfo.channelType[i] != VideoMediaType && gSGInfo.channelType[i] != 0) && |
(**myWindowInfo).channel[i] != 0) { |
err = SGSetChannelUsage((**myWindowInfo).channel[i], seqGrabPreview | seqGrabRecord | seqGrabPlayDuringRecord); |
if ( err != noErr ) |
goto bail; |
} |
} |
bail: |
return ( err ); |
} |
/* ------------------------------------------------------------------------- */ |
Boolean GetCustomSize(short *width, short *height) |
{ |
GrafPtr savePort; |
GDHandle saveGD; |
DialogPtr theDialog; |
short itemHit; |
Str255 myStr; |
Boolean done, ret; |
long lWidth, lHeight; |
GetPort(&savePort); |
saveGD = GetGDevice(); |
theDialog = GetNewDialog(130, nil, (WindowPtr) -1); |
SetPort(theDialog); |
SetGDevice(GetMainDevice()); |
// Reset data to begin. |
SetText(theDialog, 4, "\p640"); |
SetText(theDialog, 6, "\p480"); |
// Get membershipid and each inventory id |
done = false; |
do { |
ModalDialog(nil, &itemHit); |
GetText(theDialog, 4, myStr); |
StringToNum(myStr, &lWidth); |
GetText(theDialog, 6, myStr); |
StringToNum(myStr, &lHeight); |
if (itemHit == 1 ) { |
if (lWidth > 0 && lWidth <= 640 && lHeight >= 0 && lHeight <= 480) |
done = true; |
else |
SysBeep(50); |
} |
} while ((!done) && (itemHit != 2)); |
if ( itemHit == 1 ) { |
GetText(theDialog, 4, myStr); |
StringToNum(myStr, &lWidth); |
*width = lWidth; |
GetText(theDialog, 6, myStr); |
StringToNum(myStr, &lHeight); |
*height = lHeight; |
ret = true; |
} else { |
ret = false; |
} |
DisposeDialog(theDialog); |
SetPort(savePort); |
SetGDevice(saveGD); |
return ( ret ); |
} |
/* ------------------------------------------------------------------------- */ |
void GetText(DialogPtr theDialog, short item, Str255 myStr) |
{ |
Handle myHandle; |
Rect myRect; |
short myType; |
GetDItem(theDialog, item, &myType, &myHandle, &myRect); |
GetIText(myHandle, myStr); |
} |
void SetText(DialogPtr theDialog, short item, Str255 myStr) |
{ |
Handle myHandle; |
Rect myRect; |
short myType; |
GetDItem(theDialog, item, &myType, &myHandle, &myRect); |
SetIText(myHandle, myStr); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14