forked from cellularmitosis/ADC-reference-library-2009-july
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlisting23.html
executable file
·840 lines (681 loc) · 30.9 KB
/
listing23.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>MakeEffectMovie - /Completed Lab/MakeEffectMovie.c</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/QuickTime/index.html">QuickTime</a> > <a href="../../samplecode/QuickTime/idxMovieCreation-date.html">Movie Creation</a> > <A HREF="javascript:location.replace('index.html');">MakeEffectMovie</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">MakeEffectMovie</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/Completed Lab/MakeEffectMovie.c</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/Application Files/ComApplication.c</option>
<option value="listing2.html">/Application Files/ComApplication.h</option>
<option value="listing3.html">/Application Files/ComResource.h</option>
<option value="listing4.html">/Clippings/AddEffectsDescription.txt</option>
<option value="listing5.html">/Clippings/AddInputMap.txt</option>
<option value="listing6.html">/Clippings/AddMovieResource.txt</option>
<option value="listing7.html">/Clippings/AddSourceName.txt</option>
<option value="listing8.html">/Clippings/CreateEffectDescription.txt</option>
<option value="listing9.html">/Clippings/CreateEffectsTrack.txt</option>
<option value="listing10.html">/Clippings/CreateInputMap.txt</option>
<option value="listing11.html">/Clippings/GetWhatKindOfEffect.txt</option>
<option value="listing12.html">/Clippings/SelectAnEffect.txt</option>
<option value="listing13.html">/Common Files/ComFramework.c</option>
<option value="listing14.html">/Common Files/ComFramework.h</option>
<option value="listing15.html">/Common Files/MacFramework.c</option>
<option value="listing16.html">/Common Files/MacFramework.h</option>
<option value="listing17.html">/Common Files/MacPrefix.h</option>
<option value="listing18.html">/Common Files/QTUtilities.c</option>
<option value="listing19.html">/Common Files/QTUtilities.h</option>
<option value="listing20.html">/Common Files/WinFramework.c</option>
<option value="listing21.html">/Common Files/WinFramework.h</option>
<option value="listing22.html">/Common Files/WinPrefix.h</option>
<option value="listing23.html">/Completed Lab/MakeEffectMovie.c</option>
<option value="listing24.html">/Completed Lab/MakeEffectMovie.h</option>
<option value="listing25.html">/Start Code/Application Files/ComApplication.c</option>
<option value="listing26.html">/Start Code/Application Files/ComApplication.h</option>
<option value="listing27.html">/Start Code/Application Files/ComResource.h</option>
<option value="listing28.html">/Start Code/Common Files/ComFramework.c</option>
<option value="listing29.html">/Start Code/Common Files/ComFramework.h</option>
<option value="listing30.html">/Start Code/Common Files/MacFramework.c</option>
<option value="listing31.html">/Start Code/Common Files/MacFramework.h</option>
<option value="listing32.html">/Start Code/Common Files/MacPrefix.h</option>
<option value="listing33.html">/Start Code/Common Files/QTUtilities.c</option>
<option value="listing34.html">/Start Code/Common Files/QTUtilities.h</option>
<option value="listing35.html">/Start Code/Common Files/WinFramework.c</option>
<option value="listing36.html">/Start Code/Common Files/WinFramework.h</option>
<option value="listing37.html">/Start Code/Common Files/WinPrefix.h</option>
<option value="listing38.html">/Start Code/MakeEffectMovie.c</option>
<option value="listing39.html">/Start Code/MakeEffectMovie.h</option></select>
</p>
</form>
<p><strong><a href="MakeEffectMovie.zip">Download Sample</a></strong> (“MakeEffectMovie.zip”, 2.34M)<BR>
<strong><a href="MakeEffectMovie.dmg">Download Sample</a></strong> (“MakeEffectMovie.dmg”, 2.76M)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">////////////// File: MakeEffectMovie.c//// Contains: QuickTime video effect support for QuickTime movies.// This file is used for BOTH MacOS and Windows.//// Written by: Tim Monroe// Based (heavily!) on the previous MakeEffectMovie code written by Sam Bushell,// which was based on ConvertToMovie.c from ConvertToMovie Jr. sample code.//// Copyright: © 1997-1999 by Apple Computer, Inc., all rights reserved.//// Change History (most recent first)://// <7> 03/20/00 rtm made changes to get things running under CarbonLib// <6> 03/03/99 rtm added support for MakeImageDescriptionForEffect (QT 4.0 and later)// <5> 03/12/98 rtm added global flag gDoneWithDialog to fix Windows dialog box problems// <4> 02/28/98 rtm revised event/message handling following QTShowEffect.c// <3> 01/08/98 rtm sync'ed with latest code from Sam: reworked QTEffects_GetFirstVideoTrackInMovie// to use GetMovieIndTrackType and fixed time scale setting code; added global flag// gCopyMovieMedia and menu commands to set that flag// <2> 11/21/97 rtm factored out QTEffects_GetFirstVideoTrackInMovie;// reworked event-loop processing: changed QTEffects_MakeEffectMovieForSources into// QTEffects_DisplayDialogForSources and QTEffects_RespondToDialogSelection.// <1> 11/06/97 rtm first file; integrated existing code with shell framework;// added endian macros where appropriate// // This application takes the video tracks from zero, one, or two movies // and creates a new movie with an effects track for them.//// Try it out: drag two short movies of the same size onto the application icon.// The QuickTime effects dialog will appear and you can select an effect to transition// from the first movie to the second. Or, drag a single movie onto the application icon// and you'll get an effects dialog for one-source effects.//// You can also launch the application and choose the Make Effect Movie menu command in// the Test menu. You'll get a file-opening dialog box for each movie you want to apply// the effects to. Just hit Cancel in the first dialog box to get zero-source effects (like fire).////////////// TO DO:// + copy sound tracks from original movie(s); add tweening of sound tracks as effect progresses// header files#include "MakeEffectMovie.h"// global variablesQTParameterDialog gEffectsDialog = 0L; // identifier for the standard parameter dialog boxQTAtomContainer gEffectSample = NULL; // effects sampleQTAtomContainer gEffectList = NULL;PicHandle gPosterA = NULL;PicHandle gPosterB = NULL;Movie gSrcMovies[kMaxNumSources] = {NULL, NULL};Track gSrcTracks[kMaxNumSources] = {NULL, NULL};UInt16 gSpecCount = 0; Boolean gCopyMovieMedia = false; // should we copy the movie media into the new effects movie?Boolean gDoneWithDialog = false; // are we done using the effects parameters dialog box?////////////// QTEffects_GetFirstVideoTrackInMovie// Return, through the theTrack parameter, the first video track in the specified movie.//// Actually, we look for the first track that has the kCharacteristicCanSendVideo characteristic,// so we can apply effects to MPEG or QD3D tracks as well.//// If no such track is found, return invalidTrack as the function result.////////////OSErr QTEffects_GetFirstVideoTrackInMovie (Movie theMovie, Track *theTrack){ *theTrack = GetMovieIndTrackType(theMovie, 1, kCharacteristicCanSendVideo, movieTrackCharacteristic | movieTrackEnabledOnly); if (*theTrack == NULL) return(invalidTrack); return(noErr);}////////////// QTEffects_DisplayDialogForSources// Display the standard effects parameters dialog box for the movies passed in.////////////OSErr QTEffects_DisplayDialogForSources (FSSpec *theSpecList, UInt16 theSpecCount){ OSErr myErr = noErr; UInt16 myMovieIter; // make sure that there aren't too many sources if (theSpecCount > kMaxNumSources) { myErr = paramErr; goto bail; } // assign source count to a global, so QTEffects_RespondToDialogSelection has access to it gSpecCount = theSpecCount; // open the source movies, get movies from them, and get the first video track from each movie for (myMovieIter = 0; myMovieIter < theSpecCount; myMovieIter++) { short myRefNum; // open a movie file using the FSSpec and create a movie from that file myErr = OpenMovieFile(&theSpecList[myMovieIter], &myRefNum, 0); BailError(myErr); myErr = NewMovieFromFile(&gSrcMovies[myMovieIter], myRefNum, NULL, NULL, newMovieActive, NULL); BailError(myErr); SetMoviePlayHints(gSrcMovies[myMovieIter], hintsHighQuality, hintsHighQuality); // we're done with the movie file, so close it CloseMovieFile(myRefNum); // find the first video track in the source movie myErr = QTEffects_GetFirstVideoTrackInMovie(gSrcMovies[myMovieIter], &gSrcTracks[myMovieIter]); BailError(myErr); } // Create an atom container to hold the parameters // for the effect. myErr = QTNewAtomContainer(&gEffectSample); BailError(myErr); // QTGetEffectsList returns a QTAtomContainer holding a // list of the currently installed effects components myErr = QTGetEffectsList(&gEffectList, theSpecCount, theSpecCount, 0); BailError(myErr); // Ask the user to select an effect. On return, the // gEffectSample atom container holds an effect description // for the effect selected by the user, including the parameter // settings. This effect description can then be added // to the media of an effect track. You will need to add // source atoms to this container for effects that require // sources. myErr = QTCreateStandardParameterDialog(gEffectList, gEffectSample, 0, &gEffectsDialog); BailError(myErr); // insert poster frames into dialog if (gSrcTracks[0] != NULL) { gPosterA = GetTrackPict(gSrcTracks[0], GetMoviePosterTime(gSrcMovies[0])); if (gPosterA != NULL) { QTParamPreviewRecord myPreviewRecord; myPreviewRecord.sourcePicture = gPosterA; myPreviewRecord.sourceID = 1; myErr = QTStandardParameterDialogDoAction(gEffectsDialog, pdActionSetPreviewPicture, &myPreviewRecord); } } if (gSrcTracks[1] != NULL) { gPosterB = GetTrackPict(gSrcTracks[1], GetMoviePosterTime(gSrcMovies[1])); if (gPosterB != NULL) { QTParamPreviewRecord myPreviewRecord; myPreviewRecord.sourcePicture = gPosterB; myPreviewRecord.sourceID = 2; myErr = QTStandardParameterDialogDoAction(gEffectsDialog, pdActionSetPreviewPicture, &myPreviewRecord); } } // now, the frontmost window is the standard effects parameter dialog box; // on the Mac, we call QTEffects_HandleEffectsDialogEvents in our main event loop // to find and process events targeted at the effects parameter dialog box; on Windows, // we need to use a different strategy: we install a modeless dialog callback procedure // that is called internally by QTML#if TARGET_OS_WIN32 gDoneWithDialog = false; // force the dialog box to be drawn { EventRecord myEvent = {0}; QTEffects_EffectsDialogCallback(&myEvent, FrontWindow(), 0); } SetModelessDialogCallbackProc(FrontWindow(), (QTModelessCallbackUPP)QTEffects_EffectsDialogCallback); QTMLSetWindowWndProc(FrontWindow(), QTEffects_CustomDialogWndProc);#endif bail: return(myErr);}////////////// QTEffects_RespondToDialogSelection// If theErr is codecParameterDialogConfirm, make an effects movie.// If theErr is userCanceledErr, do any necessary clean up.////////////void QTEffects_RespondToDialogSelection (OSErr theErr){ short myMovieRefNum = 0; short myResID = movieInDataForkResID; Boolean myDialogWasCancelled = false; OSType myEffectCode; Fixed videoTrackFXWidth, videoTrackFXHeight; TimeScale myMovieTimeScale = 600; TimeValue myEffectDuration = 0; TimeValue mySampleTime = 0; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kEffectsSaveMoviePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kEffectsSaveMovieFileName); Movie myDestMovie = NULL; Track videoTracks[kMaxNumSources] = {NULL, NULL}; Track videoTrackFX = NULL; Media videoMediaFX = NULL; UInt16 myMovieIter; long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; OSErr myErr = noErr; // standard parameter box has been dismissed, so remember that fact gEffectsDialog = 0L; myDialogWasCancelled = (theErr == userCanceledErr); // we're finished with the effect list and movie posters QTDisposeAtomContainer(gEffectList); if (gPosterA != NULL) KillPicture(gPosterA); if (gPosterB != NULL) KillPicture(gPosterB); if (myDialogWasCancelled) goto bail; // Add the atoms naming the sources for our effect { long myLong; if (gSpecCount >= 1) { myLong = EndianU32_NtoB(kSourceOneName); QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 1, 0, sizeof(myLong), &myLong, NULL); } if (gSpecCount >= 2) { myLong = EndianU32_NtoB(kSourceTwoName); QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 2, 0, sizeof(myLong), &myLong, NULL); } } // Extract the 'what' atom to find out what kind of effect it is. // This information is returned to us by the effects dialog which // is invoked using the QTStandardParameterDialogDoAction function. // We'll use this information when we build the effects description // a bit further down in the code. { QTAtom myEffectAtom; QTAtomID myEffectAtomID; long myEffectCodeSize; Ptr myEffectCodePtr; myEffectAtom = QTFindChildByIndex(gEffectSample, kParentAtomIsContainer, kParameterWhatName, kParameterWhatID, &myEffectAtomID); myErr = QTLockContainer(gEffectSample); BailError(myErr); myErr = QTGetAtomDataPtr(gEffectSample, myEffectAtom, &myEffectCodeSize, &myEffectCodePtr); BailError(myErr); if (myEffectCodeSize != sizeof(OSType)) { myErr = paramErr; goto bail; } // get the effect code myEffectCode = *(OSType *)myEffectCodePtr; // "tsk" myEffectCode = EndianU32_BtoN(myEffectCode); // because the data is read from an atom container myErr = QTUnlockContainer(gEffectSample); BailError(myErr); } // ask the user for the name of the new movie file QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // deal with user cancelling // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myMovieRefNum, &myDestMovie); BailError(myErr); // copy the user data and settings from the source to the destination movie; // these settings include information like user data if (gSpecCount > 0) CopyMovieSettings(gSrcMovies[0], myDestMovie); // convert all the movies to have a common time scale; // we pick the largest time scale out of all the source movies, with a minimum of 600 myMovieTimeScale = 600; for (myMovieIter = 0; myMovieIter < gSpecCount; myMovieIter++) { if (myMovieTimeScale < GetMovieTimeScale(gSrcMovies[myMovieIter])) myMovieTimeScale = GetMovieTimeScale(gSrcMovies[myMovieIter]); } for (myMovieIter = 0; myMovieIter < gSpecCount; myMovieIter++) { if (myMovieTimeScale != GetMovieTimeScale(gSrcMovies[myMovieIter])) SetMovieTimeScale(gSrcMovies[myMovieIter], myMovieTimeScale); } // the effect duration is the minimum of the length of the tracks if (gSpecCount == 0) myEffectDuration = myMovieTimeScale * 10; else myEffectDuration = GetTrackDuration(gSrcTracks[0]); for (myMovieIter = 1; myMovieIter < gSpecCount; myMovieIter++) { if (myEffectDuration > GetTrackDuration(gSrcTracks[myMovieIter])) myEffectDuration = GetTrackDuration(gSrcTracks[myMovieIter]); } // default size when there are no video tracks videoTrackFXWidth = 160L << 16; videoTrackFXHeight = 120L << 16; for (myMovieIter = 0; myMovieIter < kMaxNumSources; myMovieIter++) { videoTracks[myMovieIter] = NULL; } // make the video tracks for (myMovieIter = 0; myMovieIter < gSpecCount; myMovieIter++) { Fixed mySrcTrackWidth, mySrcTrackHeight; OSType mySrcMediaType = 0; Media videoMedia; // videoTracks[n] is a clone of gSrcTracks[n] GetTrackDimensions(gSrcTracks[myMovieIter], &mySrcTrackWidth, &mySrcTrackHeight); if ((myMovieIter == 0) || (videoTrackFXWidth < mySrcTrackWidth)) videoTrackFXWidth = mySrcTrackWidth; if ((myMovieIter == 0) || (videoTrackFXHeight < mySrcTrackHeight)) videoTrackFXHeight = mySrcTrackHeight; GetMediaHandlerDescription(GetTrackMedia(gSrcTracks[myMovieIter]), &mySrcMediaType, NULL, NULL); videoTracks[myMovieIter] = NewMovieTrack(myDestMovie, mySrcTrackWidth, mySrcTrackHeight, 0); BailNil(videoTracks[myMovieIter]); videoMedia = NewTrackMedia(videoTracks[myMovieIter], mySrcMediaType, myMovieTimeScale, NULL, 0); BailNil(videoMedia); if (gCopyMovieMedia) { myErr = BeginMediaEdits(videoMedia); BailError(myErr); } myErr = CopyTrackSettings(gSrcTracks[myMovieIter], videoTracks[myMovieIter]); BailError(myErr); myErr = InsertTrackSegment(gSrcTracks[myMovieIter], videoTracks[myMovieIter], 0, myEffectDuration, 0); BailError(myErr); if (gCopyMovieMedia) { myErr = EndMediaEdits(videoMedia); BailError(myErr); } } { // videoTrackFX is the special track that implements the effect videoTrackFX = NewMovieTrack(myDestMovie, videoTrackFXWidth, videoTrackFXHeight, 0); BailNil(videoTrackFX); // create the media for our effects track videoMediaFX = NewTrackMedia(videoTrackFX, VideoMediaType, myMovieTimeScale, NULL, 0); BailNil(videoMediaFX); } { ImageDescriptionHandle myDesc = NULL;#if USES_MAKE_IMAGE_DESC_FOR_EFFECT OSErr myErr = noErr; // create a new sample description for the effect - we use // the MakeImageDescriptionForEffect function if we want to // create stacked effects, where one effect track acts as a // source for another effect myErr = MakeImageDescriptionForEffect(myEffectCode, &myDesc); if (myErr != noErr) BailError(myErr);#else // create a new sample description - in this case, we'll construct // the image description ourselves using the NewHandleClear function, // since we're not going to create a stacked effect (in which case // you'd need to use MakeImageDescriptionForEffect as described above) myDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); BailNil(myDesc); (**myDesc).idSize = sizeof(ImageDescription); (**myDesc).cType = myEffectCode; (**myDesc).hRes = 72L << 16; (**myDesc).vRes = 72L << 16; (**myDesc).dataSize = 0L; (**myDesc).frameCount = 1; (**myDesc).depth = 0; (**myDesc).clutID = -1;#endif // fill in the fields of the sample description (**myDesc).vendor = kAppleManufacturer; (**myDesc).temporalQuality = codecNormalQuality; (**myDesc).spatialQuality = codecNormalQuality; (**myDesc).width = videoTrackFXWidth >> 16; (**myDesc).height = videoTrackFXHeight >> 16; // add the effects sample to the movie myErr = BeginMediaEdits(videoMediaFX); BailError(myErr); // add the sample to the media myErr = AddMediaSample(videoMediaFX, gEffectSample, 0, GetHandleSize(gEffectSample), myEffectDuration, (SampleDescriptionHandle)myDesc, 1, 0, &mySampleTime); BailError(myErr); myErr = EndMediaEdits(videoMediaFX); BailError(myErr); QTDisposeAtomContainer(gEffectSample); DisposeHandle((Handle)myDesc); // add the media to the track myErr = InsertMediaIntoTrack(videoTrackFX, 0, mySampleTime, myEffectDuration, fixed1); BailError(myErr); } { // create and add the input map - this tells the effect // which tracks in the movie are affected long myRefIndex1, myRefIndex2; QTAtomContainer myInputMap; QTAtom myInputAtom; OSType myInputType; long myLong; QTNewAtomContainer(&myInputMap); // first input if (videoTracks[0]) { // setup a reference between our effect and the first input track AddTrackReference(videoTrackFX, videoTracks[0], kTrackModifierReference, &myRefIndex1); QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex1, 0, 0, NULL, &myInputAtom); // add modifier track type ('vide') myInputType = EndianU32_NtoB(kTrackModifierTypeImage); QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL); // source name for first source - there is a corresponding // kEffectSourceName atom in the effect description to // identify the source myLong = EndianU32_NtoB(kSourceOneName); QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL); } // second input if (videoTracks[1]) { // setup a reference between our effect and the second input track AddTrackReference(videoTrackFX, videoTracks[1], kTrackModifierReference, &myRefIndex2); QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex2, 0, 0, NULL, &myInputAtom); // modifier track type ('vide') myInputType = EndianU32_NtoB(kTrackModifierTypeImage); QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL); // source name for second source - there is a corresponding // kEffectSourceName atom in the effect description to // identify the source myLong = EndianU32_NtoB(kSourceTwoName); QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL); } // set the input map for the media if (gSpecCount > 0) SetMediaInputMap(GetTrackMedia(videoTrackFX), myInputMap); QTDisposeAtomContainer(myInputMap); } // add the movie to our file myErr = AddMovieResource(myDestMovie, myMovieRefNum, &myResID, "\pMovie 1"); BailError(myErr); CloseMovieFile(myMovieRefNum); for (myMovieIter = 0; myMovieIter < gSpecCount; myMovieIter++) DisposeMovie(gSrcMovies[myMovieIter]); DisposeMovie(myDestMovie); bail: free(myPrompt); free(myFileName); return;}#if TARGET_OS_WIN32////////////// QTEffects_EffectsDialogCallback// This function is called by QTML when it processes events for the standard or custom effects parameter dialog box.// //////////static void QTEffects_EffectsDialogCallback (EventRecord *theEvent, DialogRef theDialog, DialogItemIndex theItemHit){ QTParamDialogEventRecord myRecord; myRecord.theEvent = theEvent; myRecord.whichDialog = theDialog; myRecord.itemHit = theItemHit; if (gEffectsDialog != 0L) { QTStandardParameterDialogDoAction(gEffectsDialog, pdActionModelessCallback, &myRecord); // see if the event is meant for the effects parameter dialog box QTEffects_HandleEffectsDialogEvents(theEvent, theItemHit); }}////////////// QTEffects_CustomDialogWndProc// Handle messages for the custom effects parameters dialog box.// //////////LRESULT CALLBACK QTEffects_CustomDialogWndProc (HWND theWnd, UINT theMessage, UINT wParam, LONG lParam){ EventRecord myEvent = {0}; if (!gDoneWithDialog && (theMessage == 0x7FFF)) QTEffects_EffectsDialogCallback(&myEvent, GetNativeWindowPort(theWnd), 0); return(DefWindowProc(theWnd, theMessage, wParam, lParam));}#endif////////////// QTEffects_HandleEffectsDialogEvents// Process events that might be targeted at the standard effects parameter dialog box.// Return true if the event was completely handled.// //////////Boolean QTEffects_HandleEffectsDialogEvents (EventRecord *theEvent, DialogItemIndex theItemHit){ Boolean isHandled = false; OSErr myErr = noErr; // pass the event to the standard effects parameter dialog box handler myErr = QTIsStandardParameterDialogEvent(theEvent, gEffectsDialog); // the result from QTIsStandardParameterDialogEvent tells us how to respond next switch (myErr) { case codecParameterDialogConfirm: case userCanceledErr: // the user clicked the OK or Cancel button; dismiss the dialog box and respond accordingly gDoneWithDialog = true; QTStandardParameterDialogDoAction(gEffectsDialog, pdActionConfirmDialog, NULL); QTDismissStandardParameterDialog(gEffectsDialog); gEffectsDialog = 0L; QTEffects_RespondToDialogSelection(myErr); isHandled = true; break; case noErr: // the event was completely handled by QTIsStandardParameterDialogEvent isHandled = true; break; case featureUnsupported: // the event was not handled by QTIsStandardParameterDialogEvent; // let the event be processed normally isHandled = false; break; default: // the event was not handled by QTIsStandardParameterDialogEvent; // do not let the event be processed normally isHandled = true; break; } return(isHandled);}////////////// QTEffects_PromptUserForFilesAndMakeEffect// Let the user select some movies, then apply the effect to them.//// If the user cancels the first file-open dialog box, there are zero sources.// If the user cancels the second file-open dialog box, there is one source.// //////////void QTEffects_PromptUserForFilesAndMakeEffect (void){ QTFrameFileFilterUPP myFileFilterUPP = NULL; FSSpec mySpecs[kMaxNumSources]; int mySpecCount; OSType myTypeList[] = {kQTFileTypeMovie}; short myNumTypes = 1; OSErr myErr = noErr; #if TARGET_OS_MAC myNumTypes = 0;#endif myFileFilterUPP = QTFrame_GetFileFilterUPP((ProcPtr)QTFrame_FilterFiles); // ask for up to kMaxNumSources movie files; // accept early cancels; they just mean there are fewer input movies mySpecCount = 0; while (mySpecCount < kMaxNumSources) { FSSpec myFSSpec; myTypeList[0] = MovieFileType; myErr = QTFrame_GetOneFileWithPreview(myNumTypes, (QTFrameTypeListPtr)myTypeList, &myFSSpec, myFileFilterUPP); if (myErr != noErr) break; // the user doesn't want any more source movies // save the FSSpec from the reply information mySpecs[mySpecCount] = myFSSpec; mySpecCount++; } QTEffects_DisplayDialogForSources(mySpecs, mySpecCount); if (myFileFilterUPP != NULL) DisposeNavObjectFilterUPP(myFileFilterUPP);}</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/MakeEffectMovie/listing23.html%3Fid%3DDTS10001038-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/MakeEffectMovie/listing23.html%3Fid%3DDTS10001038-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/MakeEffectMovie/listing23.html%3Fid%3DDTS10001038-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>