void ofxQtAudioRecorder::closeMovie(){
	
	short movieResId = movieInDataForkResID;
	AddMovieResource(movie, movieResRefNum, &movieResId, NULL);
	OSErr err = GetMoviesError();
	
	if(err != noErr){
		
		printf("error adding movie resource\n");
		return;
	}
	
	if(movieResRefNum != 0)
	{
		CloseMovieFile(movieResRefNum);
	}
	
	if(movie != NULL)
	{
		DisposeMovie(movie);
	}
	
	if(soundDesc != NULL)
	{
		DisposeHandle((Handle)soundDesc);
		soundDesc = NULL;
	}
	
	movie = NULL;
	movieResRefNum = 0;
	audioMedia = NULL;
	audioTrack = NULL;
	
	printf("closed movie file\n");
}
Ejemplo n.º 2
0
void end_qt(void) {
	OSErr err = noErr;
	short resId = movieInDataForkResID;

	if(qtexport->theMovie) {
		QT_EndCreateMyVideoTrack(NULL);

		err = AddMovieResource (qtexport->theMovie, qtexport->resRefNum, &resId, qtexport->qtfilename);
		CheckError(err, "AddMovieResource error", NULL);

		err = QT_AddUserDataTextToMovie(qtexport->theMovie, "Made with Blender", kUserDataTextInformation);
		CheckError(err, "AddUserDataTextToMovie error", NULL);

		err = UpdateMovieResource(qtexport->theMovie, qtexport->resRefNum, resId, qtexport->qtfilename);
		CheckError(err, "UpdateMovieResource error", NULL);

		if(qtexport->resRefNum) CloseMovieFile(qtexport->resRefNum);

		DisposeMovie(qtexport->theMovie);

		//printf("Finished QuickTime movie.\n");
	}

#ifdef __APPLE__
		ExitMoviesOnThread();
#endif
	
	if(qtexport) {
		MEM_freeN(qtexport);
		qtexport = NULL;
	}
}
Ejemplo n.º 3
0
static void CreateAMovie (void)
{
	Point where = {100,100};
	SFReply theSFReply;

	Movie theMovie = nil;
	FSSpec mySpec;
	short resRefNum = 0;
	short resId = movieInDataForkResID;
	OSErr err = noErr;

		SFPutFile (where, c2pstr(kPrompt), 
					c2pstr(kMovieFileName), nil, &theSFReply);
		if (!theSFReply.good) return; 

		FSMakeFSSpec(theSFReply.vRefNum, 0, theSFReply.fName, &mySpec);


		err = CreateMovieFile (&mySpec, 
							kMyCreatorType,
							smCurrentScript, 
							createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
							&resRefNum, 
							&theMovie );
		CheckError(err, "CreateMovieFile error");

		QTVideo_CreateMyVideoTrack (theMovie);
		QTSound_CreateMySoundTrack (theMovie);


		err = AddMovieResource (theMovie, resRefNum, &resId,
		 						theSFReply.fName);
		CheckError(err, "AddMovieResource error");

		if (resRefNum)

		{

			CloseMovieFile (resRefNum);

		}
		DisposeMovie (theMovie);
} 
OSErr QTWired_CreateWiredSpritesMovie (void)
{
	short					myResRefNum = 0;
	short					myResID = movieInDataForkResID;
	Movie					myMovie = NULL;
	Track					myTrack;
	Media					myMedia;
	FSSpec					myFile;
	Boolean					myIsSelected = false;
	Boolean					myIsReplacing = false;	
	StringPtr 				myPrompt = QTUtils_ConvertCToPascalString(kWiredSavePrompt);
	StringPtr 				myFileName = QTUtils_ConvertCToPascalString(kWiredSaveFileName);
	QTAtomContainer			mySample = NULL;
	QTAtomContainer			myActions = NULL;
	QTAtomContainer			myBeginButton, myPrevButton, myNextButton, myEndButton;
	QTAtomContainer			myPenguinOne, myPenguinTwo, myPenguinOneOverride;
	QTAtomContainer			myBeginActionButton, myPrevActionButton, myNextActionButton, myEndActionButton;
	QTAtomContainer			myPenguinOneAction, myPenguinTwoAction;
	RGBColor				myKeyColor;
	Point					myLocation;
	short					isVisible, myLayer, myIndex, myID, i, myDelta;
	Boolean					hasActions;
	long					myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
	OSType					myType = FOUR_CHAR_CODE('none');
	UInt32					myFrequency;
	QTAtom					myEventAtom;
	long					myLoopingFlags;
	ModifierTrackGraphicsModeRecord		myGraphicsMode;
	OSErr					myErr = noErr;

	//////////
	//
	// create a new movie file and set its controller type
	//
	//////////

	// ask the user for the name of the new movie file
	QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing);
	if (!myIsSelected)
		goto bail;

	// create a movie file for the destination movie
	myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie);
	if (myErr != noErr)
		goto bail;
	
	// select the "no controller" movie controller
	myType = EndianU32_NtoB(myType);
	SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1);
	
	//////////
	//
	// create the sprite track and media
	//
	//////////
	
	myTrack = NewMovieTrack(myMovie, ((long)kSpriteTrackWidth << 16), ((long)kSpriteTrackHeight << 16), kNoVolume);
	myMedia = NewTrackMedia(myTrack, SpriteMediaType, kSpriteMediaTimeScale, NULL, 0);

	//////////
	//
	// create a key frame sample containing six sprites and all of their shared images
	//
	//////////

	// create a new, empty key frame sample
	myErr = QTNewAtomContainer(&mySample);
	if (myErr != noErr)
		goto bail;

	myKeyColor.red = 0xffff;						// white
	myKeyColor.green = 0xffff;
	myKeyColor.blue = 0xffff;

	// add images to the key frame sample
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToBeginningButtonUp, &myKeyColor, kGoToBeginningButtonUpIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToBeginningButtonDown, &myKeyColor, kGoToBeginningButtonDownIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToEndButtonUp, &myKeyColor, kGoToEndButtonUpIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToEndButtonDown, &myKeyColor, kGoToEndButtonDownIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToPrevButtonUp, &myKeyColor, kGoToPrevButtonUpIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToPrevButtonDown, &myKeyColor, kGoToPrevButtonDownIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToNextButtonUp, &myKeyColor, kGoToNextButtonUpIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToNextButtonDown, &myKeyColor, kGoToNextButtonDownIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinForward, &myKeyColor, kPenguinForwardIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinLeft, &myKeyColor, kPenguinLeftIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinRight, &myKeyColor, kPenguinRightIndex, NULL, NULL);
	SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinClosed, &myKeyColor, kPenguinClosedIndex, NULL, NULL);

	for (myIndex = kPenguinDownRightCycleStartIndex, myID = kWalkDownRightCycleStart; myIndex <= kPenguinDownRightCycleEndIndex; myIndex++, myID++)
		SpriteUtils_AddPICTImageToKeyFrameSample(mySample, myID, &myKeyColor, myIndex, NULL, NULL);
	
	// assign group IDs to the images
	SpriteUtils_AssignImageGroupIDsToKeyFrame(mySample);
	
	//////////
	//
	// add samples to the sprite track's media
	//
	//////////
	
	BeginMediaEdits(myMedia);

	// go to beginning button with no actions
	myErr = QTNewAtomContainer(&myBeginButton);
	if (myErr != noErr)
		goto bail;
	myLocation.h	= (1 * kSpriteTrackWidth / 8) - (kStartEndButtonWidth / 2);
	myLocation.v	= (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2);
	isVisible		= false;
	myLayer			= 1;
	myIndex			= kGoToBeginningButtonUpIndex;
	myErr = SpriteUtils_SetSpriteData(myBeginButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions);
	if (myErr != noErr)
		goto bail;

	// go to previous button with no actions
	myErr = QTNewAtomContainer(&myPrevButton);
	if (myErr != noErr)
		goto bail;
	myLocation.h 	= (3 * kSpriteTrackWidth / 8) - (kNextPrevButtonWidth / 2);
	myLocation.v	= (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2);
	isVisible		= false;
	myLayer			= 1;
	myIndex			= kGoToPrevButtonUpIndex;
	myErr = SpriteUtils_SetSpriteData(myPrevButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions);
	if (myErr != noErr)
		goto bail;

	// go to next button with no actions
	myErr = QTNewAtomContainer(&myNextButton);
	if (myErr != noErr)
		goto bail;
	myLocation.h 	= (5 * kSpriteTrackWidth / 8) - (kNextPrevButtonWidth / 2);
	myLocation.v	= (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2);
	isVisible		= false;
	myLayer			= 1;
	myIndex			= kGoToNextButtonUpIndex;
	myErr = SpriteUtils_SetSpriteData(myNextButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions);
	if (myErr != noErr)
		goto bail;

	// go to end button with no actions
	myErr = QTNewAtomContainer(&myEndButton);
	if (myErr != noErr)
		goto bail;
	myLocation.h 	= (7 * kSpriteTrackWidth / 8) - (kStartEndButtonWidth / 2);
	myLocation.v	= (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2);
	isVisible		= false;
	myLayer			= 1;
	myIndex			= kGoToEndButtonUpIndex;
	myErr = SpriteUtils_SetSpriteData(myEndButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions);
	if (myErr != noErr)
		goto bail;

	// first penguin sprite with no actions
	myErr = QTNewAtomContainer(&myPenguinOne);
	if (myErr != noErr)
		goto bail;
	myLocation.h 	= (3 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2);
	myLocation.v 	= (kSpriteTrackHeight / 4) - (kPenguinHeight / 2);
	isVisible		= true;
	myLayer			= 2;
	myIndex			= kPenguinDownRightCycleStartIndex;
	myGraphicsMode.graphicsMode = blend;
	myGraphicsMode.opColor.red = myGraphicsMode.opColor.green = myGraphicsMode.opColor.blue = 0x8FFF;	// grey
	myErr = SpriteUtils_SetSpriteData(myPenguinOne, &myLocation, &isVisible, &myLayer, &myIndex, &myGraphicsMode, NULL, myActions);
	if (myErr != noErr)
		goto bail;
		
	// second penguin sprite with no actions
	myErr = QTNewAtomContainer(&myPenguinTwo);
	if (myErr != noErr)
		goto bail;
	myLocation.h 	= (5 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2);
	myLocation.v 	= (kSpriteTrackHeight / 4) - (kPenguinHeight / 2);
	isVisible		= true;
	myLayer			= 3;
	myIndex			= kPenguinForwardIndex;
	myErr = SpriteUtils_SetSpriteData(myPenguinTwo, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions);
	if (myErr != noErr)
		goto bail;

	//////////
	//
	// add actions to the six sprites
	//
	//////////

	// add go to beginning button
	myErr = QTCopyAtom(myBeginButton, kParentAtomIsContainer, &myBeginActionButton);
	if (myErr != noErr)
		goto bail;

	WiredUtils_AddSpriteSetImageIndexAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToBeginningButtonDownIndex, NULL);
	WiredUtils_AddSpriteSetImageIndexAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToBeginningButtonUpIndex, NULL);
	WiredUtils_AddMovieGoToBeginningAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton);
	WiredUtils_AddSpriteSetVisibleAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL);
	SpriteUtils_AddSpriteToSample(mySample, myBeginActionButton, kGoToBeginningSpriteID);	
	QTDisposeAtomContainer(myBeginActionButton);

	// add go to prev button
	myErr = QTCopyAtom(myPrevButton, kParentAtomIsContainer, &myPrevActionButton);
	if (myErr != noErr)
		goto bail;

	WiredUtils_AddSpriteSetImageIndexAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToPrevButtonDownIndex, NULL);
	WiredUtils_AddSpriteSetImageIndexAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToPrevButtonUpIndex, NULL);
	WiredUtils_AddMovieStepBackwardAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton);
	WiredUtils_AddSpriteSetVisibleAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL);
	SpriteUtils_AddSpriteToSample(mySample, myPrevActionButton, kGoToPrevSpriteID);
	QTDisposeAtomContainer(myPrevActionButton);

	// add go to next button
	myErr = QTCopyAtom(myNextButton, kParentAtomIsContainer, &myNextActionButton);
	if (myErr != noErr)
		goto bail;

	WiredUtils_AddSpriteSetImageIndexAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToNextButtonDownIndex, NULL);
	WiredUtils_AddSpriteSetImageIndexAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToNextButtonUpIndex, NULL);
	WiredUtils_AddMovieStepForwardAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton);
	WiredUtils_AddSpriteSetVisibleAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL);
	SpriteUtils_AddSpriteToSample(mySample, myNextActionButton, kGoToNextSpriteID);
	QTDisposeAtomContainer(myNextActionButton);

	// add go to end button
	myErr = QTCopyAtom(myEndButton, kParentAtomIsContainer, &myEndActionButton);
	if (myErr != noErr)
		goto bail;

	WiredUtils_AddSpriteSetImageIndexAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToEndButtonDownIndex, NULL);
	WiredUtils_AddSpriteSetImageIndexAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToEndButtonUpIndex, NULL);
	WiredUtils_AddMovieGoToEndAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton);
	WiredUtils_AddSpriteSetVisibleAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL);
	SpriteUtils_AddSpriteToSample(mySample, myEndActionButton, kGoToEndSpriteID);
	QTDisposeAtomContainer(myEndActionButton);

	// add penguin one
	myErr = QTCopyAtom(myPenguinOne, kParentAtomIsContainer, &myPenguinOneAction);
	if (myErr != noErr)
		goto bail;

	// show the buttons on mouse enter and hide them on mouse exit
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToBeginningSpriteID, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToBeginningSpriteID, false, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToPrevSpriteID, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToPrevSpriteID, false, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToNextSpriteID, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToNextSpriteID, false, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToEndSpriteID, true, NULL);
	WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToEndSpriteID, false, NULL);
	SpriteUtils_AddSpriteToSample(mySample, myPenguinOneAction, kPenguinOneSpriteID);
	QTWired_AddCursorChangeOnMouseOver(mySample, kPenguinOneSpriteID);
	QTDisposeAtomContainer(myPenguinOneAction);

	// add penguin two
	myErr = QTCopyAtom(myPenguinTwo, kParentAtomIsContainer, &myPenguinTwoAction);
	if (myErr != noErr)
		goto bail;

	// blink when clicked on
	WiredUtils_AddSpriteSetImageIndexAction(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kPenguinClosedIndex, NULL);
	WiredUtils_AddSpriteSetImageIndexAction(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kPenguinForwardIndex, NULL);

	WiredUtils_AddQTEventAtom(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton, &myEventAtom);

	// toggle the movie rate and both of the birds' graphics modes
	QTWired_AddPenguinTwoConditionalActions(myPenguinTwoAction, myEventAtom);

	QTWired_AddWraparoundMatrixOnIdle(myPenguinTwoAction);

	SpriteUtils_AddSpriteToSample(mySample, myPenguinTwoAction, kPenguinTwoSpriteID);
	QTDisposeAtomContainer(myPenguinTwoAction);
	
	// add an action for when the key frame is loaded, to set the movie's looping mode to palindrome;
	// note that this will actually be triggered every time the key frame is reloaded,
	// so if the operation was expensive we could use a conditional to test if we've already done it
	myLoopingFlags = loopTimeBase | palindromeLoopTimeBase;
	WiredUtils_AddMovieSetLoopingFlagsAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, myLoopingFlags);

	// add the key frame sample to the sprite track media
	//
	// to add the sample data in a compressed form, you would use a QuickTime DataCodec to perform the
	// compression; replace the call to the utility AddSpriteSampleToMedia with a call to the utility
	// AddCompressedSpriteSampleToMedia to do this
	
	SpriteUtils_AddSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, true, NULL);	
	//SpriteUtils_AddCompressedSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, true, zlibDataCompressorSubType, NULL);

	//////////
	//
	// add a few override samples to move penguin one and change its image index
	//
	//////////

	// original penguin one location
	myLocation.h 	= (3 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2);
	myLocation.v 	= (kSpriteTrackHeight / 4) - (kPenguinHeight / 2);

	myDelta = (kSpriteTrackHeight / 2) / kNumOverrideSamples;
	myIndex = kPenguinDownRightCycleStartIndex;
	
	for (i = 1; i <= kNumOverrideSamples; i++) {
		QTRemoveChildren(mySample, kParentAtomIsContainer);
		QTNewAtomContainer(&myPenguinOneOverride);

		myLocation.h += myDelta;
		myLocation.v += myDelta;
		myIndex++;
		if (myIndex > kPenguinDownRightCycleEndIndex)
			myIndex = kPenguinDownRightCycleStartIndex;
			
		SpriteUtils_SetSpriteData(myPenguinOneOverride, &myLocation, NULL, NULL, &myIndex, NULL, NULL, NULL);
		SpriteUtils_AddSpriteToSample(mySample, myPenguinOneOverride, kPenguinOneSpriteID);
		SpriteUtils_AddSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, false, NULL);	
		QTDisposeAtomContainer(myPenguinOneOverride);
	}

	EndMediaEdits(myMedia);
	
	// add the media to the track
	InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
	
	//////////
	//
	// set the sprite track properties
	//
	//////////
	{
		QTAtomContainer		myTrackProperties;
		RGBColor			myBackgroundColor;
		
		// add a background color to the sprite track
		myBackgroundColor.red = EndianU16_NtoB(0x8000);
		myBackgroundColor.green = EndianU16_NtoB(0);
		myBackgroundColor.blue = EndianU16_NtoB(0xffff);
		
		QTNewAtomContainer(&myTrackProperties);
		QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyBackgroundColor, 1, 1, sizeof(RGBColor), &myBackgroundColor, NULL);

		// tell the movie controller that this sprite track has actions, Jackson
		hasActions = true;
		QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyHasActions, 1, 1, sizeof(hasActions), &hasActions, NULL);
	
		// tell the sprite track to generate QTIdleEvents
		myFrequency = EndianU32_NtoB(2);
		QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyQTIdleEventsFrequency, 1, 1, sizeof(myFrequency), &myFrequency, NULL);
		myErr = SetMediaPropertyAtom(myMedia, myTrackProperties);
		if (myErr != noErr)
			goto bail;

		QTDisposeAtomContainer(myTrackProperties);
	}
	
	//////////
	//
	// finish up
	//
	//////////
	
	// add the movie resource to the movie file
	myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name);
	
bail:
	free(myPrompt);
	free(myFileName);

	if (mySample != NULL)
		QTDisposeAtomContainer(mySample);

	if (myBeginButton != NULL)
		QTDisposeAtomContainer(myBeginButton);	
			
	if (myPrevButton != NULL)
		QTDisposeAtomContainer(myPrevButton);
				
	if (myNextButton != NULL)
		QTDisposeAtomContainer(myNextButton);
				
	if (myEndButton != NULL)
		QTDisposeAtomContainer(myEndButton);		
		
	if (myResRefNum != 0)
		CloseMovieFile(myResRefNum);

	if (myMovie != NULL)
		DisposeMovie(myMovie);
		
	return(myErr);
}
//-----------------------------------------------------------------------------
void ofQtVideoSaver::finishMovie(){

	if (!bSetupForRecordingMovie) return;
	
	bSetupForRecordingMovie = false;
	
    
    EndMediaEdits (media);             /* Inform the Movie Toolbox that they */
                                       /*   can close the media container.   */


	/*  Step 5:  Insert a reference into the track that specifies which of the
    media samples to play and when to start playing them. 
    ======================================================================  */
    
    InsertMediaIntoTrack 
      (
      track,                           /* the track to update.               */
      0,                               /* time in track where the specified  */
                                       /*   media samples should start playg */
                                       /*   using movie time scale.          */
      0,                               /* time in media samples of the first */
                                       /*   sample to play using media time  */
                                       /*   scale.                           */
      GetMediaDuration (media),        /* duration of media samples to play  */
                                       /*   using media time scale.          */
      1L<<16 //fixed1                  /* rate at which to play the samples. */
      );


/*  Step 6:  Append the movie atom to the movie file (AddMovieResource).
    ====================================================================  */
    
    sResId = movieInDataForkResID;
    osErr = AddMovieResource
      (
      movie,                           /* movie to create moov atom from     */
      sResRefNum,                      /* file to receive the moov atom      */
      &sResId,                         /* id num of movie resource (res fork)*/
      (unsigned char *) fileName.c_str()                      /* name of movie resource (res fork)  */
      );
    if (osErr) 
      { 
      printf ("AddMovieResource failed %d\n", osErr); 
      goto bail; 
      }

    if (sResRefNum != 0) 
      {
      CloseMovieFile (sResRefNum);     /* close file CreateMovieFile opened  */
      sResRefNum = 0;
      }


	/*  Step 7 (optional):  Place the movie atom as the first atom in a new 
    movie file, and interleave the media data (FlattenMovieData).        
    ===================================================================  */
    
    // no flattening necessary I think .....  
	//if (true) flatten_my_movie (movie, pszFlatFilename);


	/*  Step 8:  Close the movie file that CreateMovieFile opened (if necessary) 
    and dispose of the movie memory structures (DisposeMovie). 
    ========================================================================  */
    


	SetGWorld (pSavedPort, hSavedDevice);
    DisposeMovie (movie);
	if (hImageDescription != NULL) DisposeHandle ((Handle) hImageDescription);
    if (hCompressedData   != NULL) DisposeHandle (hCompressedData);
    if (pMovieGWorld      != NULL) DisposeGWorld (pMovieGWorld);

  bail:    

    if (sResRefNum != 0) CloseMovieFile (sResRefNum);
    if (movie     != NULL) DisposeMovie (movie);

}
OSErr QTTarg_MakeDualVRControllerMovie (void)
{
	Movie					myMovie = NULL;
	Track					myTrack = NULL;
	Media					myMedia = NULL;
	RGBColor				myKeyColor;
	Fixed					myWidth, myHeight;
	FSSpec					myFile;
	Boolean					myIsSelected = false;
	Boolean					myIsReplacing = false;	
	StringPtr 				myPrompt = QTUtils_ConvertCToPascalString(kSpriteSavePrompt);
	StringPtr 				myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName);
	long					myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
	short					myResRefNum = 0;
	short					myResID = movieInDataForkResID;
	OSType					myType = FOUR_CHAR_CODE('none');
	OSErr					myErr = noErr;

	//////////
	//
	// create a new movie file
	//
	//////////

	// prompt the user for the destination file name
	QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing);
	myErr = myIsSelected ? noErr : userCanceledErr;
	if (!myIsSelected)
		goto bail;

	// create a movie file for the destination movie
	myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie);
	if (myErr != noErr)
		goto bail;
	
	// select the "no-interface" movie controller
	myType = EndianU32_NtoB(myType);
	SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1);

	//////////
	//
	// get some information about the target movie
	//
	//////////

	myWidth = Long2Fix(kVRControlMovieWidth);
	myHeight = Long2Fix(kVRControlMovieHeight);
	
	//////////
	//
	// create a new sprite track in the target movie
	//
	//////////
	
	myTrack = NewMovieTrack(myMovie, myWidth, myHeight, kNoVolume);
	myMedia = NewTrackMedia(myTrack, SpriteMediaType, kVRControlMovieDuration, NULL, 0);

	myErr = BeginMediaEdits(myMedia);
	if (myErr != noErr)
		goto bail;
	
	//////////
	//
	// add sprite images and sprites to the sprite track; add actions to the sprites
	//
	//////////
	
	QTTarg_AddVRControllerButtonSamplesToMedia(myMedia, kVRControlMovieWidth, kVRControlMovieHeight, kVRControlMovieDuration);
	
	//////////
	//
	// insert media into track
	//
	//////////
	
	myErr = EndMediaEdits(myMedia);
	if (myErr != noErr)
		goto bail;
	
	// add the media to the track
	InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
		
	//////////
	//
	// set the sprite track properties
	//
	//////////
	
	QTTarg_SetTrackProperties(myMedia, 0);								// idle as fast as possible
	
	myKeyColor.red = myKeyColor.green = myKeyColor.blue = 0xffff;		// white
	MediaSetGraphicsMode(GetMediaHandler(myMedia), transparent, &myKeyColor);
	
	//////////
	//
	// add the movie resource to the movie file
	//
	//////////
	
	myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name);
		
bail:
	if (myResRefNum != 0)
		CloseMovieFile(myResRefNum);

	if (myMovie != NULL)
		DisposeMovie(myMovie);
		
	free(myPrompt);
	free(myFileName);

	return(myErr);
}
OSErr QTTarg_CreateTwinSpritesMovie (void)
{
	Movie					myMovie = NULL;
	Track					myTrack = NULL;
	Media					myMedia = NULL;
	FSSpec					myFile;
	Boolean					myIsSelected = false;
	Boolean					myIsReplacing = false;	
	Fixed					myHeight = 0;
	Fixed					myWidth = 0;
	StringPtr 				myPrompt = QTUtils_ConvertCToPascalString(kSpriteSavePrompt);
	StringPtr 				myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName);
	long					myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
	OSType					myType = FOUR_CHAR_CODE('none');
	short					myResRefNum = 0;
	short					myResID = movieInDataForkResID;
	OSErr					myErr = noErr;

	//////////
	//
	// create a new movie file
	//
	//////////

	// prompt the user for the destination file name
	QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing);
	myErr = myIsSelected ? noErr : userCanceledErr;
	if (!myIsSelected)
		goto bail;

	// create a movie file for the destination movie
	myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie);
	if (myErr != noErr)
		goto bail;
	
	// select the "no-interface" movie controller
	myType = EndianU32_NtoB(myType);
	SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1);
	
	//////////
	//
	// create the sprite track and media
	//
	//////////
	
	myWidth = Long2Fix(kIconSpriteTrackWidth);
	myHeight = Long2Fix(kIconSpriteTrackHeight);

	myTrack = NewMovieTrack(myMovie, myWidth, myHeight, kNoVolume);
	myMedia = NewTrackMedia(myTrack, SpriteMediaType, kSpriteMediaTimeScale, NULL, 0);

	myErr = BeginMediaEdits(myMedia);
	if (myErr != noErr)
		goto bail;

	//////////
	//
	// add the appropriate samples to the sprite media
	//
	//////////
	
	myErr = QTTarg_AddIconMovieSamplesToMedia(myMedia);
	if (myErr != noErr)
		goto bail;
	
	myErr = EndMediaEdits(myMedia);
	if (myErr != noErr)
		goto bail;
	
	// add the media to the track
	InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
		
	//////////
	//
	// set the sprite track properties
	//
	//////////
	
	QTTarg_SetTrackProperties(myMedia, 1);
	
	//////////
	//
	// add the movie resource to the movie file
	//
	//////////
	
	myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name);
		
bail:
	if (myResRefNum != 0)
		CloseMovieFile(myResRefNum);

	if (myMovie != NULL)
		DisposeMovie(myMovie);
		
	free(myPrompt);
	free(myFileName);

	return(myErr);
}
Ejemplo n.º 8
0
void MolDisplayWin::WriteQTMovie(wxString & filepath) {
	//Create a QuickTime movie using the standard animation codecs with normal quality, and 
	//temporal compression. The final file is flattened for cross platform compatability
	
	QTExport * QTOptions = new QTExport(this);
	//setup controls for the current data
	if (MainData->GetNumFrames() > 1) { //default to frame animation
		QTOptions->SetMovieChoice(0);
	} else {
		QTOptions->EnableFrameMovie(false);
	}
	if (MainData->cFrame->GetNumberNormalModes() <= 0) {
		QTOptions->EnableModeMovie(false);
	}
	
	if (QTOptions->ShowModal() != wxID_OK) {
		//user cancelled the operation
		QTOptions->Destroy();
		return;
	}
	//retrieve the value of each option
	int MovieType = QTOptions->GetMovieChoice();
	bool IncludeEPlot = QTOptions->AddEnergyPlot();
	int compressorChoice = QTOptions->GetCompressorChoice();
	int keyFrameRate = QTOptions->GetKeyFrameRate();
	if (keyFrameRate < 0) keyFrameRate = 0;
	
	QTOptions->Destroy();
	
	CodecType mCodec;
	switch (compressorChoice) {
		case 0:
			mCodec = kCinepakCodecType;
			break;
		case 1:
			mCodec = kGraphicsCodecType;
			break;
		case 2:
			mCodec = kAnimationCodecType;
			break;
		case 3:
		default:
			mCodec = kMPEG4VisualCodecType;
	}

	OSStatus s;
	OSErr myErr = myErr;
	FSSpec targetSpec;
	//ugh I need to get an FSSpec to hand to quicktime, but these calls only seem to work if
	//the file already exists...
	const char * t = filepath.mb_str(wxConvUTF8);
	FILE * temp = fopen(t, "wb");
	fclose(temp);

#ifdef __WXOSX_COCOA__
	//This function is not found in the wxCocoa implementation, it is probably possible to work around it
	//Otherwise the code appears to link and run currently. However, it is probably better to redue the
	//code to use the Cocoa qtKit framework rather than the old Carbon QT library.
	
	//This path is not tested as the current Cocoa code does not properly support the extended save dialog.
	//	void wxMacFilename2FSSpec( const wxString& path , FSSpec *spec )
	{
		OSStatus err = noErr;
		FSRef fsRef;
		wxMacPathToFSRef( filepath , &fsRef );
		err = FSGetCatalogInfo(&fsRef, kFSCatInfoNone, NULL, NULL, &targetSpec, NULL);
		verify_noerr( err );
	}
#else
	wxMacFilename2FSSpec(filepath, &targetSpec);
#endif
	
	Movie	theMovie = NULL;
		
	FSSpec tempSpec = targetSpec;
	strcpy((char *) &(tempSpec.name[1]), "MacMolPlt8933tempMovie");
	tempSpec.name[0] = 22;

	BeginOperation();
	ProgressInd->ChangeText("Creating movie...");
		
	myErr = EnterMovies();	//initialize the quicktime manager
	if (myErr != noErr) {
		FinishOperation();
		MessageAlert("Error initializing QuickTime!");
		return;
	}
		//Create the movie file and initialize file data
		//Use Quicktime creator code 'TVOD' instead of simpletext 'ttxt'
	short	resRefNum = 0;
	short	resId = 0;
	myErr = CreateMovieFile(&tempSpec, 'TVOD', smCurrentScript, createMovieFileDeleteCurFile,
							&resRefNum, &theMovie);
	if (myErr != noErr) {
		MessageAlert("Error creating movie file!");
	} else {
		bool KillEPlot = false;
		int width, height, savedEPlotWidth, savedEPlotHeight;
		glCanvas->GetClientSize(&width, &height);
		Rect lDisplayRect={0,0,0,0};
		lDisplayRect.right = width;
		lDisplayRect.bottom = height;
		Rect		gRect = lDisplayRect;

		Rect EPlotRect = lDisplayRect;
		//If we are including an energy plot add space for it here
		if (IncludeEPlot && (MovieType == 0)) {
			EPlotRect.left = EPlotRect.right;
			EPlotRect.right = EPlotRect.left + height;
			if (!energyPlotWindow) {
				energyPlotWindow = new EnergyPlotDialog(this);
				KillEPlot = true;
			} else {
				energyPlotWindow->GetSize(&savedEPlotWidth, &savedEPlotHeight);
			}
			gRect.right += height;
			width += height;
			energyPlotWindow->Show(false);
			energyPlotWindow->SetSize(height, height);
			energyPlotWindow->Update();	//This is needed to initialise the window if we just created it
		}

		LocalToGlobal ((Point *) &(gRect.top));
		LocalToGlobal ((Point *) &(gRect.bottom));
		WindowRef TempWindow;
		s = CreateNewWindow(kDocumentWindowClass, kWindowNoAttributes, &gRect, &TempWindow);
		if (s == noErr) {
													//Create the video track
			Track theTrack = NewMovieTrack (theMovie, FixRatio(width,1),
											FixRatio(height,1), kNoVolume);
			if ((noErr == GetMoviesError())&&theTrack) {
				Media theMedia = NewTrackMedia (theTrack, VideoMediaType,
												60, // Video Time Scale
												NULL, 0);
				if ((noErr == GetMoviesError())&&theMedia) {
					myErr = BeginMediaEdits (theMedia);
					if (myErr == noErr) {
						//create the actual movie frames
						GWorldPtr	lgWorld=NULL;
						
						if (! NewGWorld (&lgWorld, 0, &gRect, (CTabHandle) NULL, (GDHandle) NULL,
										 (GWorldFlags) (pixPurge + useTempMem))) {
							long MaxCompressedSize;
							ImageSequence seqID;
							ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(4);
							PixMapHandle myPixMap = GetPortPixMap(lgWorld);
							LockPixels (myPixMap);
							myErr = CompressSequenceBegin(&seqID, myPixMap, NULL, &gRect, &gRect, 0,
														  mCodec, bestCompressionCodec, codecNormalQuality, codecNormalQuality, keyFrameRate, NULL,
														  codecFlagUpdatePreviousComp, imageDesc);
							GetMaxCompressionSize (myPixMap, &gRect,
												   0, codecNormalQuality, mCodec, (CompressorComponent) anyCodec, &MaxCompressedSize);
							Handle Buffer = TempNewHandle(MaxCompressedSize, &myErr);
							if (!Buffer)
								Buffer = NewHandle(MaxCompressedSize);
							if (Buffer) {
								qtData myqtData = {theMedia, imageDesc, seqID, lDisplayRect, gRect};
								if (MovieType == 0) {
									CreateFrameMovie(lgWorld, Buffer, myqtData, IncludeEPlot);
								} else {
									CreateModeMovie(lgWorld, Buffer, myqtData);
								}
								DisposeHandle(Buffer);
							}
							myErr = CDSequenceEnd(seqID);
							if (lgWorld != NULL) DisposeGWorld (lgWorld);
							if (imageDesc) DisposeHandle((Handle) imageDesc);
						}
						
						myErr = EndMediaEdits (theMedia);
					}
					myErr = InsertMediaIntoTrack (theTrack, 0,/* track start time */
						0,        /* media start time */
						GetMediaDuration (theMedia),
						FixRatio(1,1));
				}
				myErr = AddMovieResource (theMovie, resRefNum, &resId, NULL);
			}
			if (resRefNum) {
						//Create the actual file as a flat data fork so it can be placed on the www
				ProgressInd->ChangeText("Flattening movieÉ");
				FlattenMovie(theMovie, flattenAddMovieToDataFork, &targetSpec, 'TVOD', smCurrentScript, 
							 createMovieFileDeleteCurFile, &resId, NULL);
				CloseMovieFile (resRefNum);
			}
			DisposeWindow(TempWindow);
		}
		DisposeMovie (theMovie);
		DeleteMovieFile (&tempSpec);	//delete the temp file after disposing of the movie

		if (energyPlotWindow) {
			if (KillEPlot) {
				delete energyPlotWindow;
				energyPlotWindow = NULL;
			} else {
				energyPlotWindow->SetSize(savedEPlotWidth, savedEPlotHeight);
				energyPlotWindow->FrameChanged();
				energyPlotWindow->Show(true);
			}
		}
	}
	ExitMovies();	//Close out quicktime as we are done with it for now
	FinishOperation();
}
Ejemplo n.º 9
0
void QTVectors_CreateVectorMovie (UInt32 theBuildAtomMethod)
{
	Handle						myHandle = NULL;
	ImageDescriptionHandle		mySampleDesc = NULL;
	short						myResRefNum = 0;
	short						myResID = movieInDataForkResID;
	Movie						myMovie = NULL;
	Track						myTrack;
	Media						myMedia;
	FSSpec						myFile;
	Boolean						myIsSelected = false;
	Boolean						myIsReplacing = false;	
	StringPtr 					myPrompt = QTUtils_ConvertCToPascalString(kVectorSavePrompt);
	StringPtr 					myFileName = QTUtils_ConvertCToPascalString(kVectorSaveMovieFileName);
	ComponentInstance			myComponent;
	ComponentResult				myResult;
	long						myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
	OSErr						myErr = noErr;
	
	// METHOD ONE: use a raw data stream
	
	if (theBuildAtomMethod == kUseRawDataStream) {
	
		// kUseRawDataStream: build the vector data using a stream of hard-coded raw data
		// NOTE: the data in the stream *must* be big-endian, since it's stored in a QuickTime atom container.

		long					myPath[] = {	
			
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveAntialiasControlAtom),
			EndianU32_NtoB(kCurveAntialiasOn),

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveFillTypeAtom),
			EndianU32_NtoB(gxEvenOddFill),

		// a big white enclosing rectangle (600 x 600)
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom),
			EndianU32_NtoB(0xffffffff),	// alpha, red
			EndianU32_NtoB(0xffffffff),	// green, blue
										// it's white!

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom),
			EndianU32_NtoB(1),			// one contour in path
			EndianU32_NtoB(4),			// four points in path
			EndianU32_NtoB(0x00000000),	// all points are on the curve: it's a rectangle! 
			EndianU32_NtoB(0x00000000), EndianU32_NtoB(0x00000000), 	// top left
			EndianU32_NtoB(0x02580000), EndianU32_NtoB(0x00000000),		// top right
			EndianU32_NtoB(0x02580000), EndianU32_NtoB(0x02580000),		// bottom right 
			EndianU32_NtoB(0x00000000), EndianU32_NtoB(0x02580000),		// bottom left

		// a black rounded square, centered at 150,150
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom),
			EndianU32_NtoB(0x00000000),	// alpha, red
			EndianU32_NtoB(0x00000000),	// green, blue
										// it's black!

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom),
			EndianU32_NtoB(1),			// one contour in path
			EndianU32_NtoB(4),			// four points in path
			EndianU32_NtoB(0xffffffff), // all points are off the curve: it's a rounded square! 
			EndianU32_NtoB(0x00640000), EndianU32_NtoB(0x00640000),
			EndianU32_NtoB(0x00C80000), EndianU32_NtoB(0x00640000),
			EndianU32_NtoB(0x00C80000), EndianU32_NtoB(0x00C80000), 
			EndianU32_NtoB(0x00640000), EndianU32_NtoB(0x00C80000),

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveFillTypeAtom),
			EndianU32_NtoB(gxEvenOddFill),

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurvePenThicknessAtom),
			EndianU32_NtoB(0x100000),
											
		// enable linear gradient for all following atoms
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveGradientTypeAtom),
			EndianU32_NtoB(kLinearGradient),
		
		// define the gradient: red -> green -> red -> blue									
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(GradientColorRecord)*4), EndianU32_NtoB(kCurveGradientRecordAtom),
										
			EndianU32_NtoB(0xffffffff),	// gradient color record 1:
			EndianU32_NtoB(0x00000000),	// red
			EndianU32_NtoB(0x00000000),	// beginning of gradient
										
			EndianU32_NtoB(0x77770000),	// gradient color record 2:
			EndianU32_NtoB(0xffff0000),	// green
			EndianU32_NtoB(0x00004000),
										
			EndianU32_NtoB(0x3333ffff),	// gradient color record 3:
			EndianU32_NtoB(0x00000000),	// red
			EndianU32_NtoB(0x0000C000),
										
			EndianU32_NtoB(0xffff0000),	// gradient color record 4:
			EndianU32_NtoB(0x0000ffff),	// blue
			EndianU32_NtoB(0x00010000),	// end of gradient

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveGradientAngleAtom),
			EndianU32_NtoB(0x00450000),	// gradient at 45û angle
		
		// a green rectangle, centered at 40,40, painted with a linear gradient									
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom),
			EndianU32_NtoB(0x00000000),	// alpha, red
			EndianU32_NtoB(0xffff0000),	// green, blue
										// it's green!

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom),
			EndianU32_NtoB(1),			// one contour in path
			EndianU32_NtoB(4),			// four points in path
			EndianU32_NtoB(0x00000000),	// all points are on the curve: it's a rectangle! 
			EndianU32_NtoB(0x00100000), EndianU32_NtoB(0x00100000),
			EndianU32_NtoB(0x00400000), EndianU32_NtoB(0x00100000),
			EndianU32_NtoB(0x00400000), EndianU32_NtoB(0x00400000),
			EndianU32_NtoB(0x00100000), EndianU32_NtoB(0x00400000),

		// disable gradient for all following atoms (since no atom data)
		EndianU32_NtoB(kSizeOfSizeAndTagFields), EndianU32_NtoB(kCurveGradientRecordAtom),
									
		// a red rounded square, centered at 50,50
		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom),
			EndianU32_NtoB(0x3333ffff),	// alpha, red
			EndianU32_NtoB(0x00000000),	// green, blue
										// it's red!

		EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom),
			EndianU32_NtoB(1L),			// one contour in path
			EndianU32_NtoB(4L),			// four points in path
			EndianU32_NtoB(0xffffffff), // all points are off the curve: it's a rounded square! 
			EndianU32_NtoB(0x001e0000), EndianU32_NtoB(0x001e0000),
			EndianU32_NtoB(0x00460000), EndianU32_NtoB(0x001e0000),
			EndianU32_NtoB(0x00460000), EndianU32_NtoB(0x00460000),
			EndianU32_NtoB(0x001e0000), EndianU32_NtoB(0x00460000),

		EndianU32_NtoB(kSizeOfZeroAtomHeader), EndianU32_NtoB(kCurveEndAtom),
	};
			
		myHandle = NewHandle(sizeof(myPath));
		if (myHandle == NULL)
			goto bail;
			
		BlockMove(myPath, *myHandle, sizeof(myPath));
	
	}	// end of kUseRawDataStream

	
	// METHOD TWO: use the Curve Utilities API
	
	if (theBuildAtomMethod == kUseCurveUtilities) {
	
		// kUseCurveUtilities: build the vector data using the Curve Utilities API		
		Handle						myPath;
		gxPoint						myPoint;
		long						myAtomData[14];
		ARGBColor					myColor;
		GradientColorRecord			myGradients[4];
	
		// open the vector codec; we'll need it for some subsequent calls
		myComponent = OpenDefaultComponent(decompressorComponentType, kVectorCodecType);
		if (myComponent == NULL)
			goto bail;

		// create a new, empty vector data stream
		myResult = CurveCreateVectorStream(myComponent, &myHandle);
		if (myResult != noErr)
			goto bail;
		
		// now start adding atoms holding the vector data
		
		// set antialiasing on
		myAtomData[0] = EndianU32_NtoB(kCurveAntialiasOn);
		CurveAddAtomToVectorStream(myComponent, kCurveAntialiasControlAtom, sizeof(long), myAtomData, myHandle);

		// set fill type
		myAtomData[0] = EndianU32_NtoB(gxEvenOddFill);
		CurveAddAtomToVectorStream(myComponent, kCurveFillTypeAtom, sizeof(long), myAtomData, myHandle);

		// a big white enclosing rectangle (600 x 600)
		myColor.alpha = EndianU16_NtoB(0xffff);
		myColor.red = EndianU16_NtoB(0xffff);
		myColor.green = EndianU16_NtoB(0xffff);
		myColor.blue = EndianU16_NtoB(0xffff);
		CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle);

#if USE_CURVE_INSERT_POINT_INTO_PATH
		// create a new, empty path
		CurveNewPath(myComponent, &myPath);

		myPoint.x = 0x00000000;
		myPoint.y = 0x00000000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, true);
		
		myPoint.x = 0x02580000;
		myPoint.y = 0x00000000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, true);
		
		myPoint.x = 0x02580000;
		myPoint.y = 0x02580000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, true);
		
		myPoint.x = 0x00000000;
		myPoint.y = 0x02580000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, true);

		// add the 'path' atom to the vector data stream
		CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle);
		DisposeHandle(myPath);
#else
		myAtomData[0] = EndianU32_NtoB(1L);
		myAtomData[1] = EndianU32_NtoB(4L);
		myAtomData[2] = EndianU32_NtoB(0x00000000);
		myAtomData[3] = EndianU32_NtoB(0x00000000);
		myAtomData[4] = EndianU32_NtoB(0x00000000);
		myAtomData[5] = EndianU32_NtoB(0x02580000);
		myAtomData[6] = EndianU32_NtoB(0x00000000);
		myAtomData[7] = EndianU32_NtoB(0x02580000);
		myAtomData[8] = EndianU32_NtoB(0x02580000);
		myAtomData[9] = EndianU32_NtoB(0x00000000);
		myAtomData[10] = EndianU32_NtoB(0x02580000);
		CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle);
#endif
		
		// a black rounded square, centered at 150,150
		myColor.alpha = EndianU16_NtoB(0x0000);
		myColor.red = EndianU16_NtoB(0x0000);
		myColor.green = EndianU16_NtoB(0x0000);
		myColor.blue = EndianU16_NtoB(0x0000);
		CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle);

#if USE_CURVE_INSERT_POINT_INTO_PATH
		// create a new, empty path
		CurveNewPath(myComponent, &myPath);

		myPoint.x = 0x00640000;
		myPoint.y = 0x00640000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, false);
		
		myPoint.x = 0x00C80000;
		myPoint.y = 0x00640000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, false);
		
		myPoint.x = 0x00C80000;
		myPoint.y = 0x00C80000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, false);
		
		myPoint.x = 0x00640000;
		myPoint.y = 0x00C80000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, false);

		// add the 'path' atom to the vector data stream
		CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle);
		DisposeHandle(myPath);
#else
		myAtomData[0] = EndianU32_NtoB(1L);
		myAtomData[1] = EndianU32_NtoB(4L);
		myAtomData[2] = EndianU32_NtoB(0xffffffff);
		myAtomData[3] = EndianU32_NtoB(0x00640000);
		myAtomData[4] = EndianU32_NtoB(0x00640000);
		myAtomData[5] = EndianU32_NtoB(0x00C80000);
		myAtomData[6] = EndianU32_NtoB(0x00640000);
		myAtomData[7] = EndianU32_NtoB(0x00C80000);
		myAtomData[8] = EndianU32_NtoB(0x00C80000);
		myAtomData[9] = EndianU32_NtoB(0x00640000);
		myAtomData[10] = EndianU32_NtoB(0x00C80000);
		CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle);
#endif

		// set fill type
		myAtomData[0] = EndianU32_NtoB(gxEvenOddFill);
		CurveAddAtomToVectorStream(myComponent, kCurveFillTypeAtom, sizeof(long), myAtomData, myHandle);

		// set pen thickness
		myAtomData[0] = EndianU32_NtoB(0x100000);
		CurveAddAtomToVectorStream(myComponent, kCurvePenThicknessAtom, sizeof(long), myAtomData, myHandle);

		// enable linear gradient for all following atoms
		myAtomData[0] = EndianU32_NtoB(kLinearGradient);
		CurveAddAtomToVectorStream(myComponent, kCurveGradientTypeAtom, sizeof(long), myAtomData, myHandle);

		// define the gradient: red -> green -> red -> blue									
		myGradients[0].thisColor.alpha = EndianU16_NtoB(0xffff);
		myGradients[0].thisColor.red = EndianU16_NtoB(0xffff);
		myGradients[0].thisColor.green = EndianU16_NtoB(0x0000);
		myGradients[0].thisColor.blue = EndianU16_NtoB(0x0000);
		myGradients[0].endingPercentage = EndianU32_NtoB(0x00000000);
		myGradients[1].thisColor.alpha = EndianU16_NtoB(0x7777);
		myGradients[1].thisColor.red = EndianU16_NtoB(0x0000);
		myGradients[1].thisColor.green = EndianU16_NtoB(0xffff);
		myGradients[1].thisColor.blue = EndianU16_NtoB(0x0000);
		myGradients[1].endingPercentage = EndianU32_NtoB(0x00004000);
		myGradients[2].thisColor.alpha = EndianU16_NtoB(0x3333);
		myGradients[2].thisColor.red = EndianU16_NtoB(0xffff);
		myGradients[2].thisColor.green = EndianU16_NtoB(0x0000);
		myGradients[2].thisColor.blue = EndianU16_NtoB(0x0000);
		myGradients[2].endingPercentage = EndianU32_NtoB(0x0000C000);
		myGradients[3].thisColor.alpha = EndianU16_NtoB(0xffff);
		myGradients[3].thisColor.red = EndianU16_NtoB(0x0000);
		myGradients[3].thisColor.green = EndianU16_NtoB(0x0000);
		myGradients[3].thisColor.blue = EndianU16_NtoB(0xffff);
		myGradients[3].endingPercentage = EndianU32_NtoB(0x00010000);
		CurveAddAtomToVectorStream(myComponent, kCurveGradientRecordAtom, sizeof(GradientColorRecord)*4, myGradients, myHandle);

		// set gradient angle
		myAtomData[0] = EndianU32_NtoB(0x00450000);
		CurveAddAtomToVectorStream(myComponent, kCurveGradientAngleAtom, sizeof(long), myAtomData, myHandle);

		// a green rectangle, centered at 40,40, painted with a linear gradient									
		myColor.alpha = EndianU16_NtoB(0x0000);
		myColor.red = EndianU16_NtoB(0x0000);
		myColor.green = EndianU16_NtoB(0xffff);
		myColor.blue = EndianU16_NtoB(0x0000);
		CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle);

#if USE_CURVE_INSERT_POINT_INTO_PATH
		// create a new, empty path
		CurveNewPath(myComponent, &myPath);

		myPoint.x = 0x00100000;
		myPoint.y = 0x00100000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, true);
		
		myPoint.x = 0x00400000;
		myPoint.y = 0x00100000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, true);
		
		myPoint.x = 0x00400000;
		myPoint.y = 0x00400000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, true);
		
		myPoint.x = 0x00100000;
		myPoint.y = 0x00400000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, true);

		// add the 'path' atom to the vector data stream
		CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle);
		DisposeHandle(myPath);
#else
		myAtomData[0] = EndianU32_NtoB(1L);
		myAtomData[1] = EndianU32_NtoB(4L);
		myAtomData[2] = EndianU32_NtoB(0x00000000);
		myAtomData[3] = EndianU32_NtoB(0x00100000);
		myAtomData[4] = EndianU32_NtoB(0x00100000);
		myAtomData[5] = EndianU32_NtoB(0x00400000);
		myAtomData[6] = EndianU32_NtoB(0x00100000);
		myAtomData[7] = EndianU32_NtoB(0x00400000);
		myAtomData[8] = EndianU32_NtoB(0x00400000);
		myAtomData[9] = EndianU32_NtoB(0x00100000);
		myAtomData[10] = EndianU32_NtoB(0x00400000);
		CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle);
#endif

		// disable gradient for all following atoms (since no atom data)
		CurveAddAtomToVectorStream(myComponent, kCurveGradientTypeAtom, 0, NULL, myHandle);
		
		// a red rounded square, centered at 50,50
		myColor.alpha = EndianU16_NtoB(0x3333);
		myColor.red = EndianU16_NtoB(0xffff);
		myColor.green = EndianU16_NtoB(0x0000);
		myColor.blue = EndianU16_NtoB(0x0000);
		CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle);

#if USE_CURVE_INSERT_POINT_INTO_PATH
		// create a new, empty path
		CurveNewPath(myComponent, &myPath);

		myPoint.x = 0x001e0000;
		myPoint.y = 0x001e0000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, false);
		
		myPoint.x = 0x00460000;
		myPoint.y = 0x001e0000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, false);
		
		myPoint.x = 0x00460000;
		myPoint.y = 0x00460000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, false);
		
		myPoint.x = 0x001e0000;
		myPoint.y = 0x00460000;
		CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, false);

		// add the 'path' atom to the vector data stream
		CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle);
		DisposeHandle(myPath);
#else
		myAtomData[0] = EndianU32_NtoB(1L);
		myAtomData[1] = EndianU32_NtoB(4L);
		myAtomData[2] = EndianU32_NtoB(0xffffffff);
		myAtomData[3] = EndianU32_NtoB(0x001e0000);
		myAtomData[4] = EndianU32_NtoB(0x001e0000);
		myAtomData[5] = EndianU32_NtoB(0x00460000);
		myAtomData[6] = EndianU32_NtoB(0x001e0000);
		myAtomData[7] = EndianU32_NtoB(0x00460000);
		myAtomData[8] = EndianU32_NtoB(0x00460000);
		myAtomData[9] = EndianU32_NtoB(0x001e0000);
		myAtomData[10] = EndianU32_NtoB(0x00460000);
		CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle);
#endif

		// add the 'zero' atom to the vector data stream
		CurveAddZeroAtomToVectorStream(myComponent, myHandle);
		
	}	// end of kUseCurveUtilities
	
	// create the image description
	mySampleDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
	if (mySampleDesc == NULL)
		goto bail;
	
	// fill in the fields of the image description
	(**mySampleDesc).idSize = sizeof(ImageDescription);
	(**mySampleDesc).cType = kVectorCodecType;
	(**mySampleDesc).vendor = kAppleManufacturer;
	(**mySampleDesc).temporalQuality = codecNormalQuality;
	(**mySampleDesc).spatialQuality = codecNormalQuality;
	(**mySampleDesc).width = 300;
	(**mySampleDesc).height = 300;
	(**mySampleDesc).hRes = 72L << 16;
	(**mySampleDesc).vRes = 72L << 16;
	(**mySampleDesc).dataSize = 0L;
	(**mySampleDesc).frameCount = 1;
	(**mySampleDesc).depth = 0;
	(**mySampleDesc).clutID = -1;
		
	// prompt user for new file name
	QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing);
	if (!myIsSelected)
		goto bail;
	
	// create a movie file for the destination movie
	myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smCurrentScript, myFlags, &myResRefNum, &myMovie);
	if (myErr != noErr)
		goto bail;
	
	// create the vector track and media
	myTrack = NewMovieTrack(myMovie, FixDiv(300, 1), FixDiv(300, 1), kNoVolume);
	myMedia = NewTrackMedia(myTrack, VideoMediaType, 600, NULL, 0);
	
	// create the vector media sample
	BeginMediaEdits(myMedia);
		
	myErr = AddMediaSample(myMedia, myHandle, 0, GetHandleSize(myHandle), 600, (SampleDescriptionHandle)mySampleDesc, 1, 0, NULL);
	if (myErr != noErr)
		goto bail;
		
	EndMediaEdits(myMedia);
	
	// add the media to the track
	InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
	AddMovieResource(myMovie, myResRefNum, &myResID, NULL);

bail:
	free(myPrompt);
	free(myFileName);

	if (mySampleDesc != NULL)
		DisposeHandle((Handle)mySampleDesc);
	
	if (myResRefNum != 0)
		CloseMovieFile(myResRefNum);

	if (myHandle != NULL)
		DisposeHandle(myHandle);

	if (myMovie != NULL)
		DisposeMovie(myMovie);

	if (myComponent != NULL)
		CloseComponent(myComponent);
}
Ejemplo n.º 10
0
OSErr QTDR_CreateReferenceCopy (Movie theSrcMovie, FSSpecPtr theDstMovieFile, FSSpecPtr theDstMediaFile)
{
	Track			mySrcTrack = NULL;
	Media			mySrcMedia = NULL;
	Movie			myDstMovie = NULL;
	Track			myDstTrack = NULL;
	Media			myDstMedia = NULL;
	Handle			myMediaRef = NULL;			// data reference for the media file
#if !USE_ADDEMPTYTRACKTOMOVIE
	Fixed			myWidth, myHeight;
	OSType			myType;
#endif
	long			myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
	short			myResRefNum = 0;
	short			myResID = movieInDataForkResID;
	OSErr			myErr = paramErr;
					
	// get the first video track and media in the source movie
	mySrcTrack = GetMovieIndTrackType(theSrcMovie, 1, VideoMediaType, movieTrackMediaType);
	if (mySrcTrack == NULL)
		goto bail;
	
	mySrcMedia = GetTrackMedia(mySrcTrack);
	if (mySrcMedia == NULL)
		goto bail;

	// create a file data reference for the new media file
	myMediaRef = QTDR_MakeFileDataRef(theDstMediaFile);
    if (myMediaRef == NULL)
    	goto bail;

	// create a file for the destination movie data
	myErr = FSpCreate(theDstMediaFile, sigMoviePlayer, MovieFileType, 0);
	if (myErr != noErr)
		goto bail;
	
	// create a file for the destination movie atom and create an empty movie
	myErr = CreateMovieFile(theDstMovieFile, sigMoviePlayer, smCurrentScript, myFlags, &myResRefNum, &myDstMovie);
	if (myErr != noErr)
		goto bail;
		
	// assign the default progress proc to the destination movie
	SetMovieProgressProc(myDstMovie, (MovieProgressUPP)-1, 0);

#if USE_ADDEMPTYTRACKTOMOVIE
	myErr = AddEmptyTrackToMovie(mySrcTrack, myDstMovie, myMediaRef, rAliasType, &myDstTrack);
	if (myErr != noErr)
		goto bail;
	
	myDstMedia = GetTrackMedia(myDstTrack);
	myErr = GetMoviesError();
	if (myErr != noErr)
		goto bail;
#else
	// get some information about the source track and media
	GetTrackDimensions(mySrcTrack, &myWidth, &myHeight);
	GetMediaHandlerDescription(mySrcMedia, &myType, 0, 0);

	// create the destination movie track and media
	myDstTrack = NewMovieTrack(myDstMovie, myWidth, myHeight, kNoVolume);
	myErr = GetMoviesError();
	if (myErr != noErr)
		goto bail;
		
	myDstMedia = NewTrackMedia(myDstTrack, myType, GetMediaTimeScale(mySrcMedia), myMediaRef, rAliasType);
	myErr = GetMoviesError();
	if (myErr != noErr)
		goto bail;

	CopyTrackSettings(mySrcTrack, myDstTrack);
#endif

	// copy the entire source track into the destination track; this copies the track's media
	// samples into the destination media file
	myErr = BeginMediaEdits(myDstMedia);
	if (myErr != noErr)
		goto bail;

	myErr = InsertTrackSegment(mySrcTrack, myDstTrack, 0, GetTrackDuration(mySrcTrack), 0);
	if (myErr != noErr)
		goto bail;

	myErr = EndMediaEdits(myDstMedia);
	if (myErr != noErr)
		goto bail;
	
	// add the movie atom to the data fork of the movie file
	myErr = AddMovieResource(myDstMovie, myResRefNum, &myResID, NULL);

bail:
	return(myErr);
}
Ejemplo n.º 11
0
OSErr QTDR_CreateMovieInRAM (void)
{
	Movie					myMovie = NULL;
	Track					myTrack = NULL;
	Media					myMedia = NULL;
	short					myResRefNum = 0;
	short					myResID = 0;
	Handle					myDataRef = NULL;
	Handle					myHandle = NULL;
	FSSpec					myFSSpec;
	OSErr					myErr = noErr;
	
	// create a new handle to hold the media data
	myHandle = NewHandleClear(0);
	if (myHandle == NULL)
		goto bail;
	
	// create a data reference to that handle
	myDataRef = QTDR_MakeHandleDataRef(myHandle);
	if (myDataRef == NULL)
		goto bail;
		
	myMovie = NewMovie(newMovieActive);
	if (myMovie == NULL)
		goto bail;
	
	myErr = SetMovieDefaultDataRef(myMovie, myDataRef, HandleDataHandlerSubType);
	if (myErr != noErr)
		goto bail;

	// create the movie track and media
	myTrack = NewMovieTrack(myMovie, FixRatio(kVideoTrackWidth, 1), FixRatio(kVideoTrackHeight, 1), kNoVolume);
	myErr = GetMoviesError();
	if (myErr != noErr)
		goto bail;
		
	myMedia = NewTrackMedia(myTrack, VideoMediaType, kVideoTimeScale, NULL, 0);
	myErr = GetMoviesError();
	if (myErr != noErr)
		goto bail;

	// create the media samples
	myErr = BeginMediaEdits(myMedia);
	if (myErr != noErr)
		goto bail;

	myErr = QTDR_AddVideoSamplesToMedia(myMedia, kVideoTrackWidth, kVideoTrackHeight);
	if (myErr != noErr)
		goto bail;

	myErr = EndMediaEdits(myMedia);
	if (myErr != noErr)
		goto bail;
	
	// add the media to the track
	myErr = InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
	if (myErr != noErr)
		goto bail;
	
	// add the movie atom to the movie file
	myErr = AddMovieResource(myMovie, myResRefNum, &myResID, NULL);

	myFSSpec.name[0] = (unsigned char)0;
	myFSSpec.parID = 0;
	myFSSpec.vRefNum = 0;
	
	QTFrame_OpenMovieInWindow(myMovie, &myFSSpec);

bail:
	if (myDataRef != NULL)
		DisposeHandle(myDataRef);
		
	return(myErr);
}
Ejemplo n.º 12
0
void QTCmpr_CompressSequence (WindowObject theWindowObject)
{
	ComponentInstance			myComponent = NULL;
	GWorldPtr					myImageWorld = NULL;		// the graphics world we draw the images in
	PixMapHandle				myPixMap = NULL;
	Movie						mySrcMovie = NULL;
	Track						mySrcTrack = NULL;
	Movie						myDstMovie = NULL;
	Track						myDstTrack = NULL;
	Media						myDstMedia = NULL;
	Rect						myRect;
	PicHandle					myPicture = NULL;
	CGrafPtr					mySavedPort = NULL;
	GDHandle					mySavedDevice = NULL;
	SCTemporalSettings			myTimeSettings;
	SCDataRateSettings			myRateSettings;
	FSSpec						myFile;
	Boolean						myIsSelected = false;
	Boolean						myIsReplacing = false;	
	short						myRefNum = -1;
	StringPtr 					myMoviePrompt = QTUtils_ConvertCToPascalString(kQTCSaveMoviePrompt);
	StringPtr 					myMovieFileName = QTUtils_ConvertCToPascalString(kQTCSaveMovieFileName);
	MatrixRecord				myMatrix;
	ImageDescriptionHandle		myImageDesc = NULL;
	TimeValue					myCurMovieTime = 0L;
	TimeValue					myOrigMovieTime = 0L;		// current movie time, when compression is begun
	short						myFrameNum;		
	long						myFlags = 0L;
	long						myNumFrames = 0L;
	long						mySrcMovieDuration = 0L;	// duration of source movie
	OSErr						myErr = noErr;
#if USE_ASYNC_COMPRESSION
	ICMCompletionProcRecord		myICMComplProcRec;
	ICMCompletionProcRecordPtr	myICMComplProcPtr = NULL;
	OSErr						myICMComplProcErr = noErr;

	myICMComplProcRec.completionProc = NULL;
	myICMComplProcRec.completionRefCon = 0L;
#endif

	if (theWindowObject == NULL)
		goto bail;

	//////////
	//
	// get the movie and the first video track in the movie
	//
	//////////
	
	mySrcMovie = (**theWindowObject).fMovie;
	if (mySrcMovie == NULL)
		goto bail;

	mySrcTrack = GetMovieIndTrackType(mySrcMovie, 1, VideoMediaType, movieTrackMediaType);
	if (mySrcTrack == NULL)
		goto bail;
	
	// stop the movie; we don't want it to be playing while we're (re)compressing it
	SetMovieRate(mySrcMovie, (Fixed)0L);

	// get the current movie time, when compression is begun; we'll restore this later
	myOrigMovieTime = GetMovieTime(mySrcMovie, NULL);

	//////////
	//
	// configure and display the Standard Image Compression dialog box
	//
	//////////
	
	// open an instance of the Standard Image Compression dialog component
	myComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
	if (myComponent == NULL)
		goto bail;

	// turn off "best depth" option in the compression dialog, because all of our
	// buffering is done at 32-bits (regardless of the depth of the source data)
	//
	// a more ambitious approach would be to loop through each of the video sample
	// descriptions in each of the video tracks looking for the deepest depth, and
	// using that for the best depth; better yet, we could find out which compressors
	// were used and set one of those as the default in the compression dialog
	SCGetInfo(myComponent, scPreferenceFlagsType, &myFlags);
	myFlags &= ~scShowBestDepth;
	SCSetInfo(myComponent, scPreferenceFlagsType, &myFlags);

	// because we are recompressing a movie that may have a variable frame rate,
	// we want to allow the user to leave the frame rate text field blank (in which
	// case we can preserve the frame durations of the source movie); if the user
	// enters a number, we will resample the movie at a new frame rate; if we don't
	// clear this flag, the compression dialog will not allow zero in the frame rate field
	//
	// NOTE: we could have set this flag above when we cleared the scShowBestDepth flag;
	// it is done here for clarity.	
	SCGetInfo(myComponent, scPreferenceFlagsType, &myFlags);
	myFlags |= scAllowZeroFrameRate;
	SCSetInfo(myComponent, scPreferenceFlagsType, &myFlags);

	// get the number of video frames in the movie
	myNumFrames = QTUtils_GetFrameCount(mySrcTrack);

	// get the bounding rectangle of the movie, create a 32-bit GWorld with those
	// dimensions, and draw the movie poster picture into it; this GWorld will be
	// used for the test image in the compression dialog box and for rendering movie
	// frames
	myPicture = GetMoviePosterPict(mySrcMovie);
	if (myPicture == NULL)
		goto bail;
		
	GetMovieBox(mySrcMovie, &myRect);

	myErr = NewGWorld(&myImageWorld, 32, &myRect, NULL, NULL, 0L);
	if (myErr != noErr)
		goto bail;
		
	// get the pixmap of the GWorld; we'll lock the pixmap, just to be safe
	myPixMap = GetGWorldPixMap(myImageWorld);
	if (!LockPixels(myPixMap))
		goto bail;

	// draw the movie poster image into the GWorld
	GetGWorld(&mySavedPort, &mySavedDevice);
	SetGWorld(myImageWorld, NULL);
	EraseRect(&myRect);
	DrawPicture(myPicture, &myRect);
	KillPicture(myPicture);
	SetGWorld(mySavedPort, mySavedDevice);

	// set the picture to be displayed in the dialog box; passing NULL for the rect
	// means use the entire image; passing 0 for the flags means to use the default
	// system method of displaying the test image, which is currently a combination
	// of cropping and scaling; personally, I prefer scaling (your mileage may vary)
	SCSetTestImagePixMap(myComponent, myPixMap, NULL, scPreferScaling);

	// install the custom procs, if requested
	// we can install two kinds of custom procedures for use in connection with
	// the standard dialog box: (1) a modal-dialog filter function, and (2) a hook
	// function to handle the custom button in the dialog box
	if (gUseExtendedProcs)
		QTCmpr_InstallExtendedProcs(myComponent, (long)myPixMap);
	
	// set up some default settings for the compression dialog
	SCDefaultPixMapSettings(myComponent, myPixMap, true);
	
	// clear out the default frame rate chosen by Standard Compression (a frame rate
	// of 0 means to use the rate of the source movie)
	myErr = SCGetInfo(myComponent, scTemporalSettingsType, &myTimeSettings);
	if (myErr != noErr)
		goto bail;

	myTimeSettings.frameRate = 0;
	SCSetInfo(myComponent, scTemporalSettingsType, &myTimeSettings);

	// request image compression settings from the user; in other words, put up the dialog box
	myErr = SCRequestSequenceSettings(myComponent);
	if (myErr == scUserCancelled)
		goto bail;

	// get a copy of the temporal settings the user entered; we'll need them for some
	// of our calculations (in a simpler application, we'd never have to look at them)	
	SCGetInfo(myComponent, scTemporalSettingsType, &myTimeSettings);

	//////////
	//
	// adjust the data rate [to be supplied][relevant only for movies that have sound tracks]
	//
	//////////

	
	//////////
	//
	// adjust the sample count
	//
	// if the user wants to resample the frame rate of the movie (as indicated a non-zero
	// value in the frame rate field) calculate the number of frames and duration for the new movie
	//
	//////////
	
	if (myTimeSettings.frameRate != 0) {
		long	myDuration = GetMovieDuration(mySrcMovie);
		long	myTimeScale = GetMovieTimeScale(mySrcMovie);
		float	myFloat = (float)myDuration * myTimeSettings.frameRate;
		
		myNumFrames = myFloat / myTimeScale / 65536;
		if (myNumFrames == 0)
			myNumFrames = 1;
	}

	//////////
	//
	// get the name and location of the new movie file
	//
	//////////

	// prompt the user for a file to put the compressed image into; in theory, the name
	// should have a file extension appropriate to the type of compressed data selected by the user;
	// this is left as an exercise for the reader
	QTFrame_PutFile(myMoviePrompt, myMovieFileName, &myFile, &myIsSelected, &myIsReplacing);
	if (!myIsSelected)
		goto bail;

	// delete any existing file of that name
	if (myIsReplacing) {
		myErr = DeleteMovieFile(&myFile);
		if (myErr != noErr)
			goto bail;
	}
		
	//////////
	//
	// create the target movie
	//
	//////////
	
	myErr = CreateMovieFile(&myFile, sigMoviePlayer, smSystemScript, 
								createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, &myRefNum, &myDstMovie);
	if (myErr != noErr)
		goto bail;
	
	// create a new video movie track with the same dimensions as the entire source movie
	myDstTrack = NewMovieTrack(myDstMovie,
								(long)(myRect.right - myRect.left) << 16,
								(long)(myRect.bottom - myRect.top) << 16, kNoVolume);
	if (myDstTrack == NULL)
		goto bail;
	
	// create a media for the new track with the same time scale as the source movie;
	// because the time scales are the same, we don't have to do any time scale conversions.
	myDstMedia = NewTrackMedia(myDstTrack, VIDEO_TYPE, GetMovieTimeScale(mySrcMovie), 0, 0);
	if (myDstMedia == NULL)
		goto bail;
	
	// copy the user data and settings from the source to the dest movie
	CopyMovieSettings(mySrcMovie, myDstMovie);
	
	// set movie matrix to identity and clear the movie clip region (because the conversion
	// process transforms and composites all video tracks into one untransformed video track)
	SetIdentityMatrix(&myMatrix);
	SetMovieMatrix(myDstMovie, &myMatrix);
	SetMovieClipRgn(myDstMovie, NULL);
	
	// set the movie to highest quality imaging
	SetMoviePlayHints(mySrcMovie, hintsHighQuality, hintsHighQuality);

	myImageDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
	if (myImageDesc == NULL)
		goto bail;

	// prepare for adding frames to the movie
	myErr = BeginMediaEdits(myDstMedia);
	if (myErr != noErr)
		goto bail;

	//////////
	//
	// compress the image sequence
	//
	// we are going to step through the source movie, compress each frame, and then add
	// the compressed frame to the destination movie
	//
	//////////
	
	myErr = SCCompressSequenceBegin(myComponent, myPixMap, NULL, &myImageDesc);
	if (myErr != noErr)
		goto bail;
	
#if USE_ASYNC_COMPRESSION
	myFlags = codecFlagUpdatePrevious + codecFlagUpdatePreviousComp + codecFlagLiveGrab;
	SCSetInfo(myComponent, scCodecFlagsType, &myFlags);
#endif

	// clear out our image GWorld and set movie to draw into it
	SetGWorld(myImageWorld, NULL);
	EraseRect(&myRect);
	SetMovieGWorld(mySrcMovie, myImageWorld, GetGWorldDevice(myImageWorld));

	// set current time value to beginning of the source movie
	myCurMovieTime = 0;

	// get a value we'll need inside the loop
	mySrcMovieDuration = GetMovieDuration(mySrcMovie);

	// loop through all of the interesting times we counted above
	for (myFrameNum = 0; myFrameNum < myNumFrames; myFrameNum++) {
		short			mySyncFlag;
		TimeValue		myDuration;
		long			myDataSize;
		Handle			myCompressedData;

		//////////
		//
		// get the next frame of the source movie
		//
		//////////
		
		// if we are resampling the movie, step to the next frame
		if (myTimeSettings.frameRate) {
			myCurMovieTime = myFrameNum * mySrcMovieDuration / (myNumFrames - 1);
			myDuration = mySrcMovieDuration / myNumFrames;
		} else {
			OSType		myMediaType = VIDEO_TYPE;
			
			myFlags = nextTimeMediaSample;

			// if this is the first frame, include the frame we are currently on		
			if (myFrameNum == 0)
				myFlags |= nextTimeEdgeOK;
			
			// if we are maintaining the frame durations of the source movie,
			// skip to the next interesting time and get the duration for that frame
			GetMovieNextInterestingTime(mySrcMovie, myFlags, 1, &myMediaType, myCurMovieTime, 0, &myCurMovieTime, &myDuration);
		}
		
		SetMovieTimeValue(mySrcMovie, myCurMovieTime);
		MoviesTask(mySrcMovie, 0);
		MoviesTask(mySrcMovie, 0);
		MoviesTask(mySrcMovie, 0);

		// if data rate constraining is being done, tell Standard Compression the
		// duration of the current frame in milliseconds; we only need to do this
		// if the frames have variable durations
		if (!SCGetInfo(myComponent, scDataRateSettingsType, &myRateSettings)) {
			myRateSettings.frameDuration = myDuration * 1000 / GetMovieTimeScale(mySrcMovie);
			SCSetInfo(myComponent, scDataRateSettingsType, &myRateSettings);
		}

		//////////
		//
		// compress the current frame of the source movie and add it to the destination movie
		//
		//////////
		
		// if SCCompressSequenceFrame completes successfully, myCompressedData will hold
		// a handle to the newly-compressed image data and myDataSize will be the size of
		// the compressed data (which will usually be different from the size of the handle);
		// also mySyncFlag will be a value that that indicates whether or not the frame is a
		// key frame (and which we pass directly to AddMediaSample); note that we do not need
		// to dispose of myCompressedData, since SCCompressSequenceEnd will do that for us
#if !USE_ASYNC_COMPRESSION
		myErr = SCCompressSequenceFrame(myComponent, myPixMap, &myRect, &myCompressedData, &myDataSize, &mySyncFlag);
		if (myErr != noErr)
			goto bail;
#else
		if (myICMComplProcPtr == NULL) {
			myICMComplProcRec.completionProc = NewICMCompletionProc(QTCmpr_CompletionProc);
			myICMComplProcRec.completionRefCon = (long)&myICMComplProcErr;
			myICMComplProcPtr = &myICMComplProcRec;
		}
		
		myICMComplProcErr = kAsyncDefaultValue;
		
		myErr = SCCompressSequenceFrameAsync(myComponent, myPixMap, &myRect, &myCompressedData, &myDataSize, &mySyncFlag, myICMComplProcPtr);
		if (myErr != noErr)
			goto bail;

		// spin our wheels while we're waiting for the compress call to complete
		while (myICMComplProcErr == kAsyncDefaultValue) {
			EventRecord			myEvent;
			
			WaitNextEvent(0, &myEvent, 60, NULL);
			SCAsyncIdle(myComponent);
		}
		myErr = myICMComplProcErr;
#endif

		myErr = AddMediaSample(myDstMedia, myCompressedData, 0, myDataSize, myDuration, (SampleDescriptionHandle)myImageDesc, 1, mySyncFlag, NULL);
		if (myErr != noErr)
			goto bail;
	}
	
	// close the compression sequence; this will dispose of the image description
	// and compressed data handles allocated by SCCompressSequenceBegin
	SCCompressSequenceEnd(myComponent);

	//////////
	//
	// add the media data to the destination movie
	//
	//////////
	
	myErr = EndMediaEdits(myDstMedia);
	if (myErr != noErr)
		goto bail;
	
	InsertMediaIntoTrack(myDstTrack, 0, 0, GetMediaDuration(myDstMedia), fixed1);

	// add the movie resource to the dst movie file.
	myErr = AddMovieResource(myDstMovie, myRefNum, NULL, NULL);
	if (myErr != noErr)
		goto bail;

	// flatten the movie data [to be supplied]
	
	// close the movie file
	CloseMovieFile(myRefNum);
	
bail:
	// close the Standard Compression component
	if (myComponent != NULL)
		CloseComponent(myComponent);

	if (mySrcMovie != NULL) {
		// restore the source movie's original graphics port and device
		SetMovieGWorld(mySrcMovie, mySavedPort, mySavedDevice);

		// restore the source movie's original movie time
		SetMovieTimeValue(mySrcMovie, myOrigMovieTime);
	}
	
	// restore the original graphics port and device
	SetGWorld(mySavedPort, mySavedDevice);

	// delete the GWorld we were drawing frames into
	if (myImageWorld != NULL)
		DisposeGWorld(myImageWorld);
	
#if USE_ASYNC_COMPRESSION
	if (myICMComplProcRec.completionProc != NULL)
		DisposeICMCompletionUPP(myICMComplProcRec.completionProc);
#endif

	free(myMoviePrompt);
	free(myMovieFileName);
}