/* SimpleInMovies Sample programs demonstrating how to open and display QuickTimeŞ Movies. SimpleInPicts.c file contains the code for a couple of procedures that take care of obtaining and displaying PICTs from a movie. Guillermo A. Ortiz Macintosh Developer Technical Support */ /* Changes log: 08/07/91 -- GetMediaHandlerDescription was not happy when receiving a track instead of a media. 12/03/91 -- Changed the track picture stuff to make it work with final version. 12/03/91 -- Changed the routine that used to show a picture of the current time, now it sets the poster if non is present. 09/15/92 -- Added DoGetMoviePicts as a sample on how to get the frames of a movie. */ #include #define pictDialog 130 #define aButton 2 #define usrItem 3 #define txtItem 4 #define noPosterAlert 131 extern void PrintThis( PicHandle ); void DoGet1MoviePict(void); void DoGetTrackPicts(void); void DoGetMoviePicts(void); extern Boolean IsAppWindow(WindowPtr); /* User Item proc, displays a picture in the dialog. */ pascal void myDrawPict(theDialog, itemNumber) WindowPtr theDialog; short itemNumber; { short itemType; Handle DItem; Rect box; PicHandle theP; GetDItem(theDialog,itemNumber,&itemType, &DItem, &box); if (itemType == userItem) { theP = (PicHandle)GetWRefCon(theDialog); DrawPicture(theP, &box); } } /* This routine gets the pict representing the current movie time and displays it in a dialog. The user can then select if the frame should be used as the movie poster. */ void DoGet1MoviePict() { WindowPtr window; DialogPtr theDialog; PicHandle moviePict; short itemType, itemHit; Handle DItem; Rect box; CGrafPtr savePort; GDHandle saveGDevice; DocRecHandle wHndl; TimeValue moovTime; TimeRecord moovTRec; OSErr err; if (window = FrontWindow()) { /* don't bother if no movies */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { GetGWorld(&savePort, &saveGDevice); theDialog = GetNewDialog(pictDialog,nil, (WindowPtr) -1); SetPort(theDialog); GetDItem(theDialog,usrItem,&itemType, &DItem, &box); if (itemType == userItem) { SetDItem(theDialog,usrItem,itemType, (Handle)&myDrawPict, &box); } moovTime = GetMovieTime((*wHndl)->wMovie, &moovTRec); moviePict = GetMoviePict((*wHndl)->wMovie,moovTime); SetWRefCon(theDialog, (long)moviePict); do { ModalDialog(nil, &itemHit); } while (itemHit != okButton && itemHit != cancelButton); if (itemHit == okButton) { /* set the poster time */ SetMoviePosterTime((*wHndl)->wMovie, moovTime); if (err = GetMoviesError() ) DebugStr("\perror trying to set poster time"); } CloseDialog(theDialog); KillPicture(moviePict); SetGWorld(savePort, saveGDevice); } } return; } /* This routine opens a dialog and displays in succession the frames of the first video track found in a movie. If the movie has no video tracks then the call just returns. The process used is the following: 1- Get a video track 2- Get begining and end of track 3- Call GetTrackNextInterestingTime to scan frames 4- if time = trackEnd duration time trackBegin 5- go back to 3 unless ok is clicked */ #define forwardNormalSpeed 0x00010000 /* normal speed (1) in fixed */ void DoGetTrackPicts() { WindowPtr window; DialogPtr theDialog; PicHandle moviePict; short itemType, itemHit; Handle DItem; Rect box; CGrafPtr savePort; GDHandle saveGDevice; DocRecHandle wHndl; TimeValue inTime, trackEnd, trackOffset; long trackCount, count; Track videoTrack = nil; Str255 creator; OSType mediaType, manuf; if (window = FrontWindow()) { /* don't bother if no movies */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { GetGWorld(&savePort, &saveGDevice); trackCount = GetMovieTrackCount((*wHndl)->wMovie); /* how many tracks are there? */ for (count = 1; count <= trackCount; count++) { videoTrack = GetMovieIndTrack((*wHndl)->wMovie,count); /**** The following does not work anymore GetMediaHandlerDescription((Media) videoTrack,&mediaType, &creator,&manuf); so I am changing it to make it work */ GetMediaHandlerDescription(GetTrackMedia(videoTrack),&mediaType, &creator,&manuf); if (mediaType == 'vide') /* type we are looking for */ break; else videoTrack = nil; } if (!videoTrack) return; /* looped through tracks with no luck */ theDialog = GetNewDialog(pictDialog,nil, (WindowPtr) -1); SetPort(theDialog); GetDItem(theDialog,aButton,&itemType, &DItem, &box); if ((itemType & 0x7F) == ctrlItem) { SetCTitle((ControlHandle) DItem,"\pNext"); } GetDItem(theDialog,txtItem,&itemType, &DItem, &box); if ((itemType & 0x7F) == statText) { SetIText(DItem, "\pClick Next to advance frame."); } GetDItem(theDialog,usrItem,&itemType, &DItem, &box); if ((itemType & 0x7F) == userItem) { SetDItem(theDialog,usrItem,itemType, (Handle)&myDrawPict, &box); } trackEnd = GetTrackDuration(videoTrack); /* end of track in movie time */ trackOffset = GetTrackOffset(videoTrack); /* begining of track in movie time */ inTime = trackOffset; do { moviePict = GetTrackPict(videoTrack,inTime); SetWRefCon(theDialog, (long)moviePict); InvalRect(&box); GetTrackNextInterestingTime(videoTrack,nextTimeMediaSample, inTime, forwardNormalSpeed, &inTime, nil); if ( inTime == -1 ) /* when we ask for the next interesting time after the end */ inTime = trackOffset; /* the result is -1; so go to beginning. */ ModalDialog(nil, &itemHit); KillPicture(moviePict); } while (itemHit != okButton); CloseDialog(theDialog); SetGWorld(savePort, saveGDevice); } } return; } /* This routine gets the poster picture and call the code that does the actual printing. If no picture is available then it present the user with an alert informing of the sad condition. */ void PrintPoster(void) { WindowPtr window; PicHandle posterPict; DocRecHandle wHndl; short itemHit; if (window = FrontWindow()) { /* don't bother if no movies */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( posterPict = GetMoviePosterPict((*wHndl)->wMovie)) { PrintThis(posterPict); KillPicture(posterPict); } else { /* Did not get pict bummer! */ SetCursor(&qd.arrow); ParamText((*wHndl)->wFileInfo.sfr.sfFile.name, nil, nil, nil); itemHit = StopAlert(noPosterAlert, nil); } } } return; } /* This routine opens a dialog and displays in succession the frames of the movie. */ #define forwardNormalSpeed 0x00010000 /* normal speed (1) in fixed */ void DoGetMoviePicts(void) { WindowPtr window; DialogPtr theDialog; PicHandle moviePict; short itemType, itemHit; Handle DItem; Rect box; CGrafPtr savePort; GDHandle saveGDevice; DocRecHandle wHndl; TimeValue inTime; OSType trackTypes[2] = {'vide', 'text'}; if (window = FrontWindow()) { /* don't bother if no movies */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { GetGWorld(&savePort, &saveGDevice); theDialog = GetNewDialog(pictDialog,nil, (WindowPtr) -1); SetPort(theDialog); GetDItem(theDialog,aButton,&itemType, &DItem, &box); if ((itemType & 0x7F) == ctrlItem) { SetCTitle((ControlHandle) DItem,"\pNext"); } GetDItem(theDialog,txtItem,&itemType, &DItem, &box); if ((itemType & 0x7F) == statText) { SetIText(DItem, "\pClick Next to advance frame."); } GetDItem(theDialog,usrItem,&itemType, &DItem, &box); if ((itemType & 0x7F) == userItem) { SetDItem(theDialog,usrItem,itemType, (Handle)&myDrawPict, &box); } inTime = 0; /* movie time always starts at zero */ /* but the video track(s) could start later, like in a movie that has sound first and then some video. So, prime the time */ GetMovieNextInterestingTime((*wHndl)->wMovie,nextTimeMediaSample+nextTimeEdgeOK,2, trackTypes, inTime, forwardNormalSpeed, &inTime, nil); do { moviePict = GetMoviePict((*wHndl)->wMovie,inTime); SetWRefCon(theDialog, (long)moviePict); InvalRect(&box); GetMovieNextInterestingTime((*wHndl)->wMovie,nextTimeMediaSample,2, trackTypes, inTime, forwardNormalSpeed, &inTime, nil); if ( inTime == -1 ) { /* when we ask for the next interesting time after the end */ inTime = 0; /* the result is -1; so go to beginning. */ GetMovieNextInterestingTime((*wHndl)->wMovie,nextTimeMediaSample+nextTimeEdgeOK,2, trackTypes, inTime, forwardNormalSpeed, &inTime, nil); } ModalDialog(nil, &itemHit); KillPicture(moviePict); } while (itemHit != okButton); CloseDialog(theDialog); SetGWorld(savePort, saveGDevice); } } return; }