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.
moviecontrol.c
/* |
File: moviecontrol.c |
Contains: |
Written by: Jason Hodges-Harris |
Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/28/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <MediaHandlers.h> |
#ifndef __COLORPICKER__ |
#include <ColorPicker.h> |
#endif |
#ifndef __MOVIES__ |
#include <Movies.h> |
#endif |
#ifndef __QDOFFSCREEN__ |
#include <QDOffscreen.h> |
#endif |
#ifndef __RESOURCES__ |
#include <Resources.h> |
#endif |
#ifndef __TOOLUTILS__ |
#include <ToolUtils.h> |
#endif |
#ifndef __TYPES__ |
#include <Types.h> |
#endif |
// Program headers |
#ifndef __CHROMAPPHEADER__ |
#include "ChromaKeyMovie.h" |
#endif |
// Global Variables |
/* Global GWorld storage for the QuickTime movie. |
If multiple windows are to be implemented, then these |
declarations should be moved into the window document |
structure, as each movie requires 3 offscreen ports*/ |
GWorldPtr gOffscreenPort, |
gBackGroundPort, |
gBackGroundPicture; |
PixMapHandle gMoviePixmap, |
gBackGndPixmap, |
gBackGndPictPM; |
extern RGBColor kRGBWhite, |
kRGBBlack, |
gKeyColor; |
extern Boolean gMovieBackGrnd; |
extern Boolean gDone; |
extern Boolean gMovieOpen; |
/* The PlayMovieChroma() function, is called by Open menu item and |
initialises the movie's offscreen environments and window port */ |
#pragma segment Test |
Boolean PlayMovieChroma(void) |
{ |
PicHandle thePict; |
GDHandle oldGDev; |
CWindowPtr oldPort, |
theWindow; |
MovieDocHndl theDocHndl; |
OSErr theError; |
QDErr error; |
Rect theRect; |
Fixed theData = 0xEFFF; |
GetGWorld(&oldPort,&oldGDev); |
thePict = GetPicture(rBackGroundPict); // load the background picture |
theWindow = OpenCWindow(); |
theDocHndl=(MovieDocHndl)GetWRefCon((WindowPtr)theWindow); |
HLock((Handle)theDocHndl); |
theError = LoadOneMovie(theDocHndl); // load a QuickTime movie |
// Check if the QuickTime movie was successfully loaded. |
if (theError) |
{ |
if (theError == kappDefErr) |
DisplayAlert (rGenAlert,rErrMessages,1); |
// return gracefully as cancel button selected or load error occurred |
DisposeHandle((Handle)theDocHndl); |
DisposeWindow((WindowPtr)theWindow); |
return false; |
} |
// get movie frame dimensions |
GetMovieBox((**theDocHndl).theMovie,&theRect); |
/* create the offscreen GWorlds to store the background image, |
the current movie frame and the composite image for transferring to the screen */ |
error = NewGWorld(&gOffscreenPort,0,&theRect,nil,nil,0); |
error |= NewGWorld(&gBackGroundPort,0,&theRect,nil,nil,0); |
error |= NewGWorld(&gBackGroundPicture,1,&(**thePict).picFrame,nil,nil,0); |
// Check if the GWorlds created successfully. |
if (error != noErr) |
{ |
/* failed to allocate GWorlds, Alert user of |
problem and exit application as can't continue. */ |
DisplayAlert (rGenAlert,rErrMessages,2); |
gDone = true; |
return false; |
} |
/* Get the GWorld PixMaps and lock down the offscreen ports. */ |
gMoviePixmap = GetGWorldPixMap(gOffscreenPort); |
gBackGndPixmap = GetGWorldPixMap(gBackGroundPort); |
gBackGndPictPM = GetGWorldPixMap(gBackGroundPicture); |
LockPixels(gMoviePixmap); |
LockPixels(gBackGndPixmap); |
LockPixels(gBackGndPictPM); |
SetGWorld(gBackGroundPicture,nil); |
/* Draw PICT resource into its GWorld. This saves time having |
to reload and draw the PICT for each frame. */ |
HLock((Handle)thePict); |
DrawPicture(thePict,&(*gBackGroundPicture).portRect); |
HUnlock((Handle)thePict); |
ReleaseResource((Handle)thePict); |
SetGWorld(oldPort,oldGDev); |
/* Create a movie controller for the movie, get the controller |
dimensions and its port to that of the visible window */ |
(**theDocHndl).theController = |
NewMovieController((**theDocHndl).theMovie,&theRect,mcTopLeftMovie); |
theError = MCGetControllerBoundsRect((**theDocHndl).theController,&theRect); |
theError = MCSetControllerPort((**theDocHndl).theController,(CGrafPtr)theWindow); |
SetMovieGWorld((**theDocHndl).theMovie,gOffscreenPort,nil); |
SizeWindow((WindowPtr)theWindow,theRect.right,theRect.bottom,true); |
SetWTitle((WindowPtr)theWindow,(**theDocHndl).theFileSpec.name); |
ShowWindow((WindowPtr)theWindow); |
gMovieOpen = true; |
HUnlock((Handle)theDocHndl); |
return true; |
} |
/* Simple function to load a QuickTime movie and |
place the reference into the movie window document*/ |
#pragma segment Test |
OSErr LoadOneMovie(MovieDocHndl theDocH) |
{ |
StandardFileReply theMovieFile; |
SFTypeList myTypes = {MovieFileType}; |
OSErr error; |
short myMovieResFile; |
Boolean movieChanged; |
StandardGetFilePreview(nil,1,myTypes,&theMovieFile); |
if (theMovieFile.sfGood) |
{ |
error = OpenMovieFile(&theMovieFile.sfFile,&myMovieResFile,fsRdPerm); |
if (error == noErr) |
{ |
(**theDocH).theMovieResID = 0; // get first movie |
error = NewMovieFromFile(&(**theDocH).theMovie,myMovieResFile,&(**theDocH).theMovieResID, |
nil,newMovieActive,&movieChanged); |
if(error == noErr) |
{ |
(**theDocH).theFileSpec = theMovieFile.sfFile; |
CloseMovieFile (myMovieResFile); |
return noErr; |
} |
} |
return kappDefErr; // error loading movie |
} |
return -kappDefErr; // cancel selected |
} |
/* When the TransparentColor() function is called, |
it displays the Color Picker and sets the key |
color to the value returned by the Picker */ |
#pragma segment Test |
void TransparentColor() |
{ |
RGBColor theNewColor; |
Point thePoint = {0,0}; |
// alter the key color if OK selected |
if (GetColor(thePoint,"\pSelect Color",&gKeyColor,&theNewColor)) |
gKeyColor = theNewColor; |
return; |
} |
/* The SetPlayAllFrames() function is called by the "Play |
every frame" menu item, in the "Movie Options" Menu. |
This calls a movie controller action to */ |
#pragma segment Test |
Boolean SetPlayAllFrames(Boolean playAllFrames) |
{ |
MovieDocHndl theDocH; |
WindowPtr theWindow; |
ComponentResult theResult; |
playAllFrames = !playAllFrames; |
if (gMovieOpen) |
{ |
theWindow = FrontWindow(); |
theDocH = (MovieDocHndl)GetWRefCon(theWindow); |
if (playAllFrames) |
theResult = MCDoAction((**theDocH).theController,mcActionSetPlayEveryFrame,(Ptr)true); |
else |
theResult = MCDoAction((**theDocH).theController,mcActionSetPlayEveryFrame,(Ptr)false); |
if (theResult != noErr) |
DisplayAlert (rGenAlert,rErrMessages,1); |
} |
return playAllFrames; |
} |
#pragma segment Test |
Boolean SetLoopMovie(Boolean loopMovie) |
{ |
MovieDocHndl theDocH; |
WindowPtr theWindow; |
ComponentResult theResult; |
loopMovie = !loopMovie; |
if (gMovieOpen) |
{ |
theWindow = FrontWindow(); |
theDocH=(MovieDocHndl)GetWRefCon(theWindow); |
if (loopMovie) |
theResult = MCDoAction((**theDocH).theController,mcActionSetLooping,(Ptr)true); |
else |
theResult = MCDoAction((**theDocH).theController,mcActionSetLooping,(Ptr)false); |
if (theResult !=noErr) |
DisplayAlert (rGenAlert,rErrMessages,1); |
} |
return loopMovie; |
} |
#pragma segment Test |
void TransparentKeyMode(WindowPtr theWindow) |
{ |
MovieDocHndl theDocHndl; |
CGrafPtr oldPort; |
GDHandle oldDevice; |
Rect theRect; |
theRect = (*gOffscreenPort).portRect; |
theDocHndl = (MovieDocHndl)GetWRefCon(theWindow); |
GetGWorld(&oldPort,&oldDevice); |
// use CopyBits()to perform croma keying |
SetGWorld(gBackGroundPort,nil); |
RGBForeColor(&kRGBBlack); |
RGBBackColor(&kRGBWhite); |
CopyBits((BitMap*)(*gBackGndPictPM), |
(BitMap*)(*gBackGndPixmap), |
&(*gBackGroundPicture).portRect,&theRect,srcCopy,nil); |
if (gMovieBackGrnd) |
{ |
SetGWorld(gOffscreenPort,nil); |
RGBForeColor(&kRGBBlack); |
RGBBackColor(&gKeyColor); |
CopyBits((BitMap*)(*gBackGndPixmap), |
(BitMap*)(*gMoviePixmap), |
&theRect,&theRect,transparent,nil); |
SetGWorld((CWindowPtr)theWindow,oldDevice); |
RGBForeColor(&kRGBBlack); |
RGBBackColor(&kRGBWhite); |
CopyBits((BitMap*)(*gMoviePixmap), |
(BitMap*)&((*theWindow).portBits), |
&theRect,&theRect,srcCopy,nil); |
} |
else |
{ |
SetGWorld(gBackGroundPort,nil); |
RGBForeColor(&kRGBBlack); |
RGBBackColor(&gKeyColor); |
CopyBits((BitMap*)(*gMoviePixmap), |
(BitMap*)(*gBackGndPixmap), |
&theRect,&theRect,transparent,nil); |
SetGWorld((CWindowPtr)theWindow,oldDevice); |
RGBForeColor(&kRGBBlack); |
RGBBackColor(&kRGBWhite); |
CopyBits((BitMap*)(*gBackGndPixmap), |
(BitMap*)&((*theWindow).portBits), |
&theRect,&theRect,srcCopy,nil); |
} |
return; |
} |
#pragma segment Test |
void ModifierTrackMode(WindowPtr theWindow) |
{ |
MovieDocHndl theDocHndl; |
ModifierTrackGraphicsModeRecord theModifierStruct; |
long theTrackIndex, |
theTrackCount; |
Track theTrack, |
theModifierTrack; |
Media theMedia; |
QTAtomContainer inputMap; |
QTAtom inputAtom; |
OSType theMediaType, |
inputType; |
short resRefNum, |
count; |
if (gMovieOpen) |
{ |
theDocHndl = (MovieDocHndl)GetWRefCon(theWindow); |
SetMovieGWorld((**theDocHndl).theMovie,(CGrafPtr)theWindow,nil); |
theTrackCount = GetMovieTrackCount((**theDocHndl).theMovie); |
theModifierStruct.graphicsMode = transparent; |
theModifierStruct.opColor = gKeyColor; |
theModifierTrack = GetMovieIndTrack((**theDocHndl).theMovie,theTrackCount+1); |
// step thru until first video track found |
for (count=1;count <=theTrackCount;count++) |
{ |
theTrack = GetMovieIndTrack((**theDocHndl).theMovie,count); |
theMedia = GetTrackMedia(theTrack); |
GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil); |
if (theMediaType == VideoMediaType) |
{ |
AddTrackReference(theTrack,theModifierTrack, |
kTrackModifierTypeGraphicsMode,&theTrackIndex); |
count = theTrackCount; // bump track count |
} |
// create and add the input map |
GetMediaInputMap(theMedia,&inputMap); |
QTInsertChild( inputMap, kParentAtomIsContainer, kTrackModifierInput, theTrackIndex, |
0, 0, nil,&inputAtom); |
QTInsertChild( inputMap, inputAtom, kTrackModifierType, 1, 0, |
sizeof(kTrackModifierTypeGraphicsMode), &inputType, nil ); |
SetMediaInputMap(theMedia, inputMap ); |
QTDisposeAtomContainer(inputMap ); |
} |
// save changes to movie |
OpenMovieFile(&(**theDocHndl).theFileSpec,&resRefNum,fsRdWrPerm); |
UpdateMovieResource((**theDocHndl).theMovie,resRefNum,(**theDocHndl).theMovieResID,nil); |
CloseMovieFile(resRefNum); |
} |
return; |
} |
#pragma segment Test |
void VideoGraphicsMode(WindowPtr theWindow, Boolean SetVGM) |
{ |
MovieDocHndl theDocHndl; |
long theTrackCount; |
Media theMedia; |
Track movieTrack = nil; |
OSType theMediaType; |
short count; |
if (gMovieOpen) |
{ |
theDocHndl = (MovieDocHndl)GetWRefCon(theWindow); |
SetMovieGWorld((**theDocHndl).theMovie,(CGrafPtr)theWindow,nil); |
theTrackCount = GetMovieTrackCount((**theDocHndl).theMovie); |
for (count=1;count <=theTrackCount;count++) |
{ |
movieTrack = GetMovieIndTrack((**theDocHndl).theMovie,count); |
theMedia = GetTrackMedia(movieTrack); |
GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil); |
if (theMediaType == VideoMediaType) |
{ |
if (SetVGM) |
{ |
if (MediaSetGraphicsMode(GetMediaHandler(theMedia),transparent,&gKeyColor)) |
DisplayAlert (rGenAlert,rErrMessages,1); |
} |
else if (!SetVGM) |
{ |
if (MediaSetGraphicsMode(GetMediaHandler(theMedia),srcCopy,&kRGBWhite)) |
DisplayAlert (rGenAlert,rErrMessages,1); |
} |
} |
} |
} |
return; |
} |
#pragma segment Test |
OSErr DestroyModifierTrack(MovieDocHndl theDocH) |
{ |
long theTrackCount; |
Track theTrack, |
theModifierTrack; |
Media theMedia; |
OSType theMediaType; |
OSErr theError; |
short resRefNum, |
count; |
theError = OpenMovieFile(&(**theDocH).theFileSpec,&resRefNum,fsRdWrPerm); |
theTrackCount = GetMovieTrackCount((**theDocH).theMovie); |
theModifierTrack = GetMovieIndTrack((**theDocH).theMovie,theTrackCount); |
theError |= GetMoviesError(); |
// step thru until first video track found |
for (count=1;count <=theTrackCount;count++) |
{ |
theTrack = GetMovieIndTrack((**theDocH).theMovie,count); |
theMedia = GetTrackMedia(theTrack); |
GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil); |
if (theMediaType == VideoMediaType) |
{ |
SetMediaInputMap(theMedia,nil); |
count = theTrackCount; // bump track count |
} |
} |
theError |= UpdateMovieResource((**theDocH).theMovie,resRefNum, |
(**theDocH).theMovieResID,nil); |
CloseMovieFile(resRefNum); |
return theError; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14