static OSErr SpriteUtils_GetImageGroupID (QTAtomContainer theKeySample, QTAtom theImagesContainerAtom, short theImageIndex, long *theGroupID)
{
	QTAtom			myImageAtom, myImageGroupAtom;
	OSErr			myErr = noErr;

	myImageAtom = QTFindChildByIndex(theKeySample, theImagesContainerAtom, kSpriteImageAtomType, theImageIndex, NULL);
	if (myImageAtom == 0)	{ 
		myErr = cannotFindAtomErr;
		goto bail;
	}

	myImageGroupAtom = QTFindChildByIndex(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, NULL);
	
	if (myImageGroupAtom == 0)
		*theGroupID = 0;
	else {
		myErr = QTCopyAtomDataToPtr(theKeySample, myImageGroupAtom, false, sizeof(*theGroupID), (Ptr)theGroupID, NULL);
		if (myErr != noErr)
			goto bail;

		*theGroupID = EndianU32_BtoN(*theGroupID);		// return native endian long
	}
	
bail:
	return(myErr);
}
Beispiel #2
0
void pix_videoDarwin :: brightnessMess(float X)
{

    QTAtomContainer         atomContainer;
    QTAtom                  featureAtom;
    VDIIDCFeatureSettings   settings;
    ComponentDescription    desc;
    ComponentResult         result = paramErr;

    //check if device is IIDC
    GetComponentInfo((Component)m_vdig, &desc, NULL, NULL, NULL);
    if (vdSubtypeIIDC != desc.componentSubType){

        m_brightness = (unsigned short)(65536. * X);
        VDSetBrightness(m_vdig,&m_brightness);

        VDGetBrightness(m_vdig,&m_brightness);
        post("brightness is %d",m_brightness);
    }
    else
    {
    //IIDC stuff
    //these things are as stubborn as they are stupid - find one that conforms to spec!

    //vdIIDCFeatureBrightness
    result = VDIIDCGetFeaturesForSpecifier(m_vdig, vdIIDCFeatureBrightness, &atomContainer);
    if (noErr != result) {
        error("VDIIDCGetFeaturesForSpecifier returned %d",result);
    }

    featureAtom = QTFindChildByIndex(atomContainer, kParentAtomIsContainer,
                                         vdIIDCAtomTypeFeature, 1, NULL);
    if (0 == featureAtom) error("featureAtom not found");

    result = QTCopyAtomDataToPtr(atomContainer,
                                     QTFindChildByID(atomContainer, featureAtom,
                                     vdIIDCAtomTypeFeatureSettings,
                                     vdIIDCAtomIDFeatureSettings, NULL),
                                     true, sizeof(settings), &settings, NULL);

    settings.state.flags = (vdIIDCFeatureFlagOn |
                                        vdIIDCFeatureFlagManual |
                                        vdIIDCFeatureFlagRawControl);

    settings.state.value = X;

    result = QTSetAtomData(atomContainer,
                                       QTFindChildByID(atomContainer, featureAtom,
                                       vdIIDCAtomTypeFeatureSettings,
                                       vdIIDCAtomIDFeatureSettings, NULL),
                                       sizeof(settings), &settings);

    result = VDIIDCSetFeatures(m_vdig, atomContainer);

    }
}
static OSErr SpriteUtils_GetImageDescription (QTAtomContainer theKeySample, QTAtom theImagesContainerAtom, short theImageIndex, ImageDescriptionHandle theImageDesc)
{
	QTAtom						myImageAtom, myImageDataAtom;
	UInt8						mySaveState;
	UInt32						mySize;
	OSErr						myErr = noErr;

	myImageAtom = QTFindChildByIndex(theKeySample, theImagesContainerAtom, kSpriteImageAtomType, theImageIndex, NULL);
	if (myImageAtom == 0)	{ 
		myErr = cannotFindAtomErr; 
		goto bail;
	}

	myImageDataAtom = QTFindChildByIndex(theKeySample, myImageAtom, kSpriteImageDataAtomType, 1, NULL);
	if (myImageDataAtom == 0)	{ 
		myErr = cannotFindAtomErr; 
		goto bail;
	}

	mySaveState = HGetState((Handle)theImageDesc);
	HUnlock((Handle)theImageDesc);

	// copy the data (ImageDescription followed by image data) to a handle
	myErr = QTCopyAtomDataToHandle(theKeySample, myImageDataAtom, (Handle)theImageDesc);
	if (myErr != noErr)
		goto bail;

	mySize = EndianU32_BtoN((**theImageDesc).idSize);

	// pull off anything following the image description (& its color table, if any, and any image description extensions)
	SetHandleSize((Handle)theImageDesc, mySize);

#if TARGET_RT_LITTLE_ENDIAN
	EndianUtils_ImageDescription_BtoN(theImageDesc);
#endif

	HSetState((Handle)theImageDesc, mySaveState);
	myErr = MemError();
	
bail:
	return(myErr);
}
static OSErr SpriteUtils_SetImageGroupID (QTAtomContainer theKeySample, QTAtom theImagesContainerAtom, short theImageIndex, long theGroupID)
{
	QTAtom			myImageAtom, myImageGroupAtom;
	OSErr			myErr = noErr;
	
	myImageAtom = QTFindChildByIndex(theKeySample, theImagesContainerAtom, kSpriteImageAtomType, theImageIndex, NULL);
	if (myImageAtom == 0)	{ 
		myErr = cannotFindAtomErr;
		goto bail;
	}

	myImageGroupAtom = QTFindChildByIndex(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, NULL);
	if (myImageGroupAtom == 0) {
		myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, 1, 0, NULL, &myImageGroupAtom);
		if (myErr != noErr)
			goto bail;
	}

	theGroupID = EndianU32_NtoB(theGroupID);
	myErr = QTSetAtomData(theKeySample, myImageGroupAtom, sizeof(theGroupID), &theGroupID);

bail:
	return(myErr);
}
Beispiel #5
0
void pix_videoDarwin :: gainMess(float X)
{

    QTAtomContainer         atomContainer;
    QTAtom                  featureAtom;
    VDIIDCFeatureSettings   settings;
    ComponentDescription    desc;
    ComponentResult         result = paramErr;

    //check if device is IIDC
    GetComponentInfo((Component)m_vdig, &desc, NULL, NULL, NULL);
    if (vdSubtypeIIDC == desc.componentSubType){

    //IIDC stuff
    //vdIIDCFeatureGain
    result = VDIIDCGetFeaturesForSpecifier(m_vdig, vdIIDCFeatureWhiteBalanceU, &atomContainer);
    if (noErr != result) {
        error("VDIIDCGetFeaturesForSpecifier vdIIDCFeatureExposure returned %d",result);
    }

    featureAtom = QTFindChildByIndex(atomContainer, kParentAtomIsContainer,
                                         vdIIDCAtomTypeFeature, 1, NULL);
    if (0 == featureAtom) error("featureAtom vdIIDCFeatureExposure not found");

    result = QTCopyAtomDataToPtr(atomContainer,
                                     QTFindChildByID(atomContainer, featureAtom,
                                     vdIIDCAtomTypeFeatureSettings,
                                     vdIIDCAtomIDFeatureSettings, NULL),
                                     true, sizeof(settings), &settings, NULL);

    settings.state.flags = (vdIIDCFeatureFlagOn |
                                        vdIIDCFeatureFlagManual |
                                        vdIIDCFeatureFlagRawControl);

    settings.state.value = X;

    result = QTSetAtomData(atomContainer,
                                       QTFindChildByID(atomContainer, featureAtom,
                                       vdIIDCAtomTypeFeatureSettings,
                                       vdIIDCAtomIDFeatureSettings, NULL),
                                       sizeof(settings), &settings);

    result = VDIIDCSetFeatures(m_vdig, atomContainer);

    }
}
OSErr SpriteUtils_AssignImageGroupIDsToKeyFrame (QTAtomContainer theKeySample)
{
	QTAtom						myDefaultsAtom, myImagesContainerAtom;
	ImageDescriptionHandle		myFirstImageDesc = NULL;
	ImageDescriptionHandle		mySecondImageDesc = NULL;
	short						myFirstIndex, mySecondIndex, myNumImages;
	CodecType					myFirstImageType, mySecondImageType;
	long						myGroupID = 0, myTestID;
	OSErr						myErr = noErr;
	
	myDefaultsAtom = QTFindChildByIndex(theKeySample, 0, kSpriteSharedDataAtomType, 1, NULL);
	if (myDefaultsAtom == 0)
		goto bail;
	
	myImagesContainerAtom = QTFindChildByIndex(theKeySample, myDefaultsAtom, kSpriteImagesContainerAtomType, 1, NULL);
	if (myImagesContainerAtom == 0)
		goto bail;
	
	myFirstImageDesc = (ImageDescriptionHandle)NewHandle(0);
	if (myFirstImageDesc == NULL) {
		myErr = memFullErr;
		goto bail; 
	}

	mySecondImageDesc = (ImageDescriptionHandle)NewHandle(0);
	if (mySecondImageDesc == NULL) {
		myErr = memFullErr;
		goto bail; 
	}

	myNumImages = QTCountChildrenOfType(theKeySample, myImagesContainerAtom, kSpriteImageAtomType);
	for (myFirstIndex = 1; myFirstIndex <= myNumImages; myFirstIndex++) {
		myErr = SpriteUtils_SetImageGroupID(theKeySample, myImagesContainerAtom, myFirstIndex, 0);
		if (myErr != noErr)
			goto bail;
	}
	
	for (myFirstIndex = 1; myFirstIndex <= (myNumImages - 1); myFirstIndex++) {
		myErr = SpriteUtils_GetImageGroupID(theKeySample, myImagesContainerAtom, myFirstIndex, &myTestID);
		if (myErr != noErr)
			goto bail;
		
		if (myTestID == 0) {
			myGroupID++;
			myErr = SpriteUtils_SetImageGroupID(theKeySample, myImagesContainerAtom, myFirstIndex, myGroupID);
			if (myErr != noErr)
				goto bail;
			
			myErr = SpriteUtils_GetImageDescription(theKeySample, myImagesContainerAtom, myFirstIndex, myFirstImageDesc);
			myFirstImageType = (**myFirstImageDesc).cType;
			if (myErr != noErr)
				goto bail;

			for (mySecondIndex = (myFirstIndex + 1); mySecondIndex <= myNumImages; mySecondIndex++) {
				myErr = SpriteUtils_GetImageGroupID(theKeySample, myImagesContainerAtom, mySecondIndex, &myTestID);
				if (myErr != noErr)
					goto bail;
					
				if (myTestID == 0) {
					myErr = SpriteUtils_GetImageDescription(theKeySample, myImagesContainerAtom, mySecondIndex, mySecondImageDesc);
					if (myErr != noErr)
						goto bail;
					mySecondImageType = (**mySecondImageDesc).cType;
				
					if (myFirstImageType == mySecondImageType) {
						ImageSequence	mySeqID;
						Boolean			isEquivalent;
						
						myErr = DecompressSequenceBegin(&mySeqID, myFirstImageDesc, NULL, NULL, NULL, NULL, ditherCopy, (RgnHandle)NULL,  0, codecNormalQuality, anyCodec);
						if (myErr != noErr)
							goto bail;
									 
						CDSequenceEquivalentImageDescription(mySeqID, mySecondImageDesc, &isEquivalent);
						CDSequenceEnd(mySeqID);
						
						if (isEquivalent) {
							myErr = SpriteUtils_SetImageGroupID(theKeySample, myImagesContainerAtom, mySecondIndex, myGroupID);
							if (myErr != noErr)
								goto bail;
						}
					}
				}
			}
		}
	}
	
	// assign an ID to the last image
	myErr = SpriteUtils_GetImageGroupID(theKeySample, myImagesContainerAtom, myNumImages, &myTestID);
	if (myErr != noErr)
		goto bail;
		
	if (myTestID == 0) {
		myGroupID++;
		myErr = SpriteUtils_SetImageGroupID(theKeySample, myImagesContainerAtom, myNumImages, myGroupID);
	}
	
bail:
	if (myFirstImageDesc != NULL)
		DisposeHandle((Handle)myFirstImageDesc);
		
	if (mySecondImageDesc != NULL)
		DisposeHandle((Handle)mySecondImageDesc);
		
	return(myErr);
}
OSErr SpriteUtils_AddCompressedImageToKeyFrameSample (QTAtomContainer theKeySample, ImageDescriptionHandle theImageDesc, long theDataSize, Ptr theCompressedDataPtr, QTAtomID theImageID, FixedPoint *theRegistrationPoint, StringPtr theImageName)
{
	Handle						myImageData = NULL;
	QTAtom						myDefaultsAtom, myImagesContainerAtom, myImageAtom;
	ImageDescriptionHandle		myImageDesc = NULL;
	OSErr						myErr = noErr;

#if TARGET_RT_LITTLE_ENDIAN
	myImageDesc = (ImageDescriptionHandle)NewHandle(GetHandleSize((Handle)theImageDesc));
	BlockMoveData(*theImageDesc, *myImageDesc, GetHandleSize((Handle)theImageDesc));
	EndianUtils_ImageDescription_NtoB(myImageDesc);
#else
	myImageDesc = theImageDesc;			// already is big endian
#endif

	// append compressed picture data to myImageDesc to obtain sprite image data
	myImageData = NewHandle(0);
	myErr = MemError();
	if (myErr != noErr)
		goto bail;
	
	myErr = HandAndHand((Handle)myImageDesc, myImageData);
	if (myErr != noErr)
		goto bail;
	
	myErr = PtrAndHand(theCompressedDataPtr, myImageData, theDataSize);
	if (myErr != noErr)
		goto bail;
	
	myDefaultsAtom = QTFindChildByIndex(theKeySample, 0, kSpriteSharedDataAtomType, 1, NULL);
	if (myDefaultsAtom == 0) {
		myErr = QTInsertChild(theKeySample, kParentAtomIsContainer, kSpriteSharedDataAtomType, 1, 0, 0, NULL, &myDefaultsAtom);
		if (myErr != noErr)
			goto bail;
	}
		
	myImagesContainerAtom = QTFindChildByIndex(theKeySample, myDefaultsAtom, kSpriteImagesContainerAtomType, 1, NULL);
	if (myImagesContainerAtom == 0) {
		myErr = QTInsertChild(theKeySample, myDefaultsAtom, kSpriteImagesContainerAtomType, 1, 0, 0, NULL, &myImagesContainerAtom);
		if (myErr != noErr)
			goto bail;
	}

	myErr = QTInsertChild(theKeySample, myImagesContainerAtom, kSpriteImageAtomType, theImageID, 0, 0, NULL, &myImageAtom);
	if (myErr != noErr)
		goto bail;

	HLock(myImageData);
	myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageDataAtomType, 1, 0, GetHandleSize(myImageData), *myImageData, NULL);
	if (myErr != noErr)
		goto bail;
	HUnlock(myImageData);
	
	if (theRegistrationPoint != NULL) {
		FixedPoint 			myRegistrationPoint;
		
		myRegistrationPoint.x = EndianS32_NtoB(theRegistrationPoint->x);
		myRegistrationPoint.y = EndianS32_NtoB(theRegistrationPoint->y);
		
		myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageRegistrationAtomType, 1, 0, sizeof(myRegistrationPoint), &myRegistrationPoint, NULL);
		if (myErr != noErr)
			goto bail;
	} else {
		FixedPoint 			myRegistrationPoint = { 0, 0 };		// flipping {0,0} doesn't change anything so we don't flip
		
		myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageRegistrationAtomType, 1, 0, sizeof(myRegistrationPoint), &myRegistrationPoint, NULL);
		if (myErr != noErr)
			goto bail;
	}
	
	if (theImageName != NULL) {
		myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageNameAtomType, 1, 0, theImageName[0], &theImageName[1], NULL);
		if (myErr != noErr)
			goto bail;
	}

bail:
#if TARGET_RT_LITTLE_ENDIAN
	if (myImageDesc != NULL)
		DisposeHandle((Handle)myImageDesc);
#else
	// myImageDesc is still theImageDesc, so don't dispose of it
#endif

	if (myImageData != NULL)
		DisposeHandle(myImageData);
		
	return(myErr);
}
OSErr SpriteUtils_SetSpriteData (QTAtomContainer theSprite, Point *theLocation, short *theVisible, short *theLayer, short *theImageIndex, ModifierTrackGraphicsModeRecord *theGraphicsMode, StringPtr theSpriteName, QTAtomContainer theActionAtoms)
{
	QTAtom				myPropertyAtom;
	OSErr				myErr = noErr;
	
	if (theSprite == NULL)
		return(paramErr);
		
	// set the sprite location data
	if (theLocation != NULL) {
		MatrixRecord	myMatrix;
		
		SetIdentityMatrix(&myMatrix);
		myMatrix.matrix[2][0] = ((long)theLocation->h << 16);
		myMatrix.matrix[2][1] = ((long)theLocation->v << 16);
		EndianUtils_MatrixRecord_NtoB(&myMatrix);

		myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyMatrix, 1, NULL);
		if (myPropertyAtom == 0)
			myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyMatrix, 1, 0, sizeof(MatrixRecord), &myMatrix, NULL);
		else
			myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(MatrixRecord), &myMatrix);
			
		if (myErr != noErr)
			goto bail;
	}
	
	// set the sprite visibility state
	if (theVisible != NULL) {
		short 			myVisible = *theVisible;
		
		myVisible = EndianS16_NtoB(myVisible);
		
		myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyVisible, 1, NULL);
		if (myPropertyAtom == 0)
			myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyVisible, 1, 0, sizeof(short), &myVisible, NULL);
		else
			myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myVisible);
			
		if (myErr != noErr)
			goto bail;
	}
	
	// set the sprite layer
	if (theLayer != NULL) {
		short 			myLayer = *theLayer;
		
		myLayer = EndianS16_NtoB(myLayer);

		myPropertyAtom = QTFindChildByIndex(theSprite, 0, kSpritePropertyLayer, 1, NULL);
		if (myPropertyAtom == 0)
			myErr = QTInsertChild(theSprite, 0, kSpritePropertyLayer, 1, 0, sizeof(short), &myLayer, NULL);
		else
			myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myLayer);
			
		if (myErr != noErr)
			goto bail;
	}
	
	// set the sprite image index
	if (theImageIndex != NULL) {
		short 			myImageIndex = *theImageIndex;

		myImageIndex = EndianS16_NtoB(myImageIndex);
		
		myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyImageIndex, 1, NULL);
		if (myPropertyAtom == 0)
			myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyImageIndex, 1, 0, sizeof(short), &myImageIndex, NULL);
		else
			myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myImageIndex);
			
		if (myErr != noErr)
			goto bail;
	}
	
	// set the sprite graphics mode
	if (theGraphicsMode != NULL) {
		ModifierTrackGraphicsModeRecord		myGraphicsMode;
		
		myGraphicsMode.graphicsMode = EndianU32_NtoB(theGraphicsMode->graphicsMode);
		myGraphicsMode.opColor.red = EndianU16_NtoB(theGraphicsMode->opColor.red);
		myGraphicsMode.opColor.green = EndianU16_NtoB(theGraphicsMode->opColor.green);
		myGraphicsMode.opColor.blue = EndianU16_NtoB(theGraphicsMode->opColor.blue);

		myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyGraphicsMode, 1, NULL);
		if (myPropertyAtom == 0)
			myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyGraphicsMode, 1, 0, sizeof(myGraphicsMode), &myGraphicsMode, NULL);
		else
			myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(myGraphicsMode), &myGraphicsMode);
			
		if (myErr != noErr)
			goto bail;
	}
	
	// set the sprite name
	if (theSpriteName != NULL) {
		QTAtom 		mySpriteNameAtom;
		
		mySpriteNameAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpriteNameAtomType, 1, NULL);
		if (mySpriteNameAtom == 0)
			myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpriteNameAtomType, 1, 0, theSpriteName[0] + 1, theSpriteName, NULL);
		else
			myErr = QTSetAtomData(theSprite, mySpriteNameAtom, theSpriteName[0] + 1, theSpriteName);

		if (myErr != noErr)
			goto bail;
	}
	
	// set the action atoms
	if (theActionAtoms != NULL)
		myErr = QTInsertChildren(theSprite, kParentAtomIsContainer, theActionAtoms);
	
bail:
	if ((myErr != noErr) && (theSprite != NULL))
		QTRemoveChildren(theSprite, 0);

	return(myErr);
}
void QTEffects_RespondToDialogSelection (OSErr theErr)
{
	Boolean					myDialogWasCancelled = false;
	short					myResID = movieInDataForkResID;
	UInt16					myMovieIter;
	short					mySrcMovieRefNum = 0;
	Movie					myPrevSrcMovie = NULL;
	Track					myPrevSrcTrack = NULL;
	Movie					myNextSrcMovie = NULL;
	Track					myNextSrcTrack = NULL;
	short					myDestMovieRefNum = 0;
	FSSpec					myFile;
	Boolean					myIsSelected = false;
	Boolean					myIsReplacing = false;	
	StringPtr 				myPrompt = QTUtils_ConvertCToPascalString(kEffectsSaveMoviePrompt);
	StringPtr 				myFileName = QTUtils_ConvertCToPascalString(kEffectsSaveMovieFileName);
	Movie					myDestMovie = NULL;
	Fixed					myDestMovieWidth, myDestMovieHeight;
	ImageDescriptionHandle	myDesc = NULL;
	Track					videoTrackFX, videoTrackA, videoTrackB;
	Media					videoMediaFX, videoMediaA, videoMediaB;
	TimeValue				myCurrentDuration = 0;
	TimeValue				myReturnedDuration;
	Boolean					isFirstTransition = true;
	TimeValue				myMediaTransitionDuration;
	TimeValue				myMediaFXStartTime, myMediaFXDuration;
	OSType					myEffectCode;
	long					myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
	long					myLong;
	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);
	
	// when the sign says stop, then stop
	if (myDialogWasCancelled)
		goto bail;

	// add atoms naming the sources to gEffectSample
	myLong = EndianU32_NtoB(kSourceOneName);
	QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 1, 0, sizeof(myLong), &myLong, NULL);

	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
	{
		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;
		}
		
		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'), 0, myFlags, &myDestMovieRefNum, &myDestMovie);
	BailError(myErr);
	
	// open the first file as a movie; call the first movie myPrevSrcMovie
	myErr = OpenMovieFile(&gSpecList[0], &mySrcMovieRefNum, fsRdPerm);
	BailError(myErr);
	
	myErr = NewMovieFromFile(&myPrevSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL);
	BailError(myErr);
	
	myErr = CloseMovieFile(mySrcMovieRefNum);
	BailError(myErr);
	
	// if the movie is shorter than kMinimumDuration, scale it to that length
	SetMovieTimeScale(myPrevSrcMovie, kTimeScale);
	myErr = QTEffects_GetFirstVideoTrackInMovie(myPrevSrcMovie, &myPrevSrcTrack);
	BailNil(myPrevSrcTrack);
	
	if (GetTrackDuration(myPrevSrcTrack) < kMinimumDuration) {
		myErr = ScaleTrackSegment(myPrevSrcTrack, 0, GetTrackDuration(myPrevSrcTrack), kMinimumDuration);
		BailError(myErr);
	}
	
	// find out how big the first movie is; we'll use it as the size of all our tracks
	GetTrackDimensions(myPrevSrcTrack, &myDestMovieWidth, &myDestMovieHeight);
	
#if USES_MAKE_IMAGE_DESC_FOR_EFFECT
	// create a new sample description for the effect,
	// which is just an image description specifying the effect and its dimensions
	myErr = MakeImageDescriptionForEffect(myEffectCode, &myDesc);
	if (myErr != noErr)
		BailError(myErr);
#else
	// create a new sample description for the effect,
	// which is just an image description specifying the effect and its dimensions
	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 = FixRound(myDestMovieWidth);
	(**myDesc).height = FixRound(myDestMovieHeight);

	// add three video tracks to the destination movie:
	// 	- videoTrackFX is where the effects and stills live; it's user-visible.
	//	- videoTrackA is where the "source A"s for effects live; it's hidden by the input map
	//	- videoTrackB is where the "source B"s for effects live; it's hidden by the input map
	videoTrackFX = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0);
	BailNil(videoTrackFX);
	videoMediaFX = NewTrackMedia(videoTrackFX, VideoMediaType, kTimeScale, NULL, 0);
	BailNil(videoMediaFX);
	myErr = BeginMediaEdits(videoMediaFX);
	BailError(myErr);
	
	videoTrackA = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0);
	BailNil(videoTrackA);
	videoMediaA = NewTrackMedia(videoTrackA, VideoMediaType, kTimeScale, NULL, 0);
	BailNil(videoMediaA);

	videoTrackB = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0);
	BailNil(videoTrackB);
	videoMediaB = NewTrackMedia(videoTrackB, VideoMediaType, kTimeScale, NULL, 0);
	BailNil(videoMediaB);

	// create the input map
	{
		long				myRefIndex1, myRefIndex2;
		QTAtomContainer		myInputMap;
		QTAtom				myInputAtom;
		OSType				myInputType;

		QTNewAtomContainer(&myInputMap);

		// first input
		if (videoTrackA) {
		
			AddTrackReference(videoTrackFX, videoTrackA, kTrackModifierReference, &myRefIndex1);
			QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex1, 0, 0, NULL, &myInputAtom);
	
			myInputType = EndianU32_NtoB(kTrackModifierTypeImage);
			QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL);
	
			myLong = EndianU32_NtoB(kSourceOneName);
			QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL);
		}

		// second input
		if (videoTrackB) {
		
			AddTrackReference(videoTrackFX, videoTrackB, kTrackModifierReference, &myRefIndex2);
			QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex2, 0, 0, NULL, &myInputAtom);
	
			myInputType = EndianU32_NtoB(kTrackModifierTypeImage);
			QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL);
	
			myLong = EndianU32_NtoB(kSourceTwoName);
			QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL);
		}

		// set that map
		SetMediaInputMap(GetTrackMedia(videoTrackFX), myInputMap);
		
		QTDisposeAtomContainer(myInputMap);
	}

	myCurrentDuration = 0;

#if MAKE_STILL_SECTIONS
	// copy the first sample of the first video track of the first movie to videoTrackFX, with duration kStillDuration.
	myErr = CopyPortionOfTrackToTrack(myPrevSrcTrack, eStartPortion + eMiddlePortion, videoTrackFX, myCurrentDuration, &myReturnedDuration);
	BailError(myErr);
	
	myCurrentDuration += myReturnedDuration;
#endif 

	// now process any remaining files
	myMovieIter = 1;
	while (myMovieIter < gSpecCount) {
		
		// open the next file as a movie; call it nextSourceMovie
		myErr = OpenMovieFile(&gSpecList[myMovieIter], &mySrcMovieRefNum, fsRdPerm);
		BailError(myErr);
		
		myErr = NewMovieFromFile(&myNextSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL);
		BailError(myErr);
		
		// we're done with the movie file, so close it
		myErr = CloseMovieFile(mySrcMovieRefNum);
		BailError(myErr);
		
		// if the movie is shorter than kMinimumDuration, scale it to that length
		SetMovieTimeScale(myNextSrcMovie, kTimeScale);
		myErr = QTEffects_GetFirstVideoTrackInMovie(myNextSrcMovie, &myNextSrcTrack);
		BailNil(myNextSrcTrack);
		
		if (GetTrackDuration(myNextSrcTrack) < kMinimumDuration) {
			myErr = ScaleTrackSegment(myNextSrcTrack, 0, GetTrackDuration(myNextSrcTrack), kMinimumDuration);
			BailError(myErr);
		}

		// create a transition effect from the previous source movie's first video sample to the next source movie's first video sample
		// (the effect should have duration kEffectDuration);
		// this involves adding one sample to each of the three video tracks:
		
		//    sample from previous source movie	 -> videoTrackA
		myErr = QTEffects_CopyPortionOfTrackToTrack(myPrevSrcTrack, eFinishPortion, videoTrackA, myCurrentDuration, &myReturnedDuration);
		BailError(myErr);
		
		//    sample from next source movie    	 -> videoTrackB
		myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eStartPortion, videoTrackB, myCurrentDuration, &myReturnedDuration);
		BailError(myErr);
		
		//    effect sample                 	  -> videoTrackFX
		if (isFirstTransition) {
			myMediaTransitionDuration = myReturnedDuration;
			myMediaFXStartTime = GetMediaDuration(videoMediaFX);
			myErr = AddMediaSample(videoMediaFX, gEffectSample, 0, GetHandleSize(gEffectSample), myMediaTransitionDuration, (SampleDescriptionHandle)myDesc, 1, 0, NULL);
			BailError(myErr);
			
			myMediaFXDuration = GetMediaDuration(videoMediaFX) - myMediaFXStartTime;
			isFirstTransition = false;
		}
		
		myErr = InsertMediaIntoTrack(videoTrackFX, myCurrentDuration, myMediaFXStartTime, myMediaFXDuration, FixRatio(myReturnedDuration, myMediaTransitionDuration));
		BailError(myErr);
		
		myCurrentDuration += myReturnedDuration;
		
#if MAKE_STILL_SECTIONS
		// copy the first video sample of myNextSrcMovie to videoTrackFX, with duration kStillDuration.
		myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eMiddlePortion + (myMovieIter + 1 == theSpecCount) ? eFinishPortion : 0, videoTrackFX, myCurrentDuration, &myReturnedDuration);
		BailError(myErr);
		
		myCurrentDuration += myReturnedDuration;
#endif // MAKE_STILL_SECTIONS
		
		// dispose of previous source movie.  
		DisposeMovie(myPrevSrcMovie);
		
		myPrevSrcMovie = myNextSrcMovie;
		myPrevSrcTrack = myNextSrcTrack;
		myNextSrcMovie = NULL;
		myNextSrcTrack = NULL;
		
		myMovieIter++;
	} // while
	
	myErr = EndMediaEdits(videoMediaFX);
	BailError(myErr);

	myErr = AddMovieResource(myDestMovie, myDestMovieRefNum, &myResID, "\pMovie 1");
	BailError(myErr);
	
	CloseMovieFile(myDestMovieRefNum);
	
	if (myPrevSrcMovie != NULL)
		DisposeMovie(myPrevSrcMovie);
		
	DisposeMovie(myDestMovie);
	
bail:
	free(myPrompt);
	free(myFileName);

	QTDisposeAtomContainer(gEffectSample);
	DisposeHandle((Handle)myDesc);

	return;
}