Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
QTInternals.c
/* |
File: QTInternals.c |
Contains: Functions dealing with dumping internal movie information. |
Written by: DTS |
Copyright: © 1995 by Apple Computer, Inc., all rights reserved. |
Change History (most recent first): |
<1> 1/4/95 khs first file |
*/ |
// INCLUDES |
#include "QTInternals.h" |
#include "DTSQTUtilities.h" |
// ______________________________________________________________________ |
// FUNCTIONS |
// ______________________________________________________________________ |
void ShowGlobalMovieInfo(Movie theMovie) |
{ |
OSErr anErr = noErr; |
Str255 tmpStr; |
TimeValue tv, ts; |
Fixed mr; |
long movieSize = 0L; |
DebugAssert(aMovie != NULL); |
GetWTitle(FrontWindow(), tmpStr); |
printf("\nGlobal System Information for %s:\n", p2cstr(tmpStr)); |
// Memory related information. |
anErr = QTUCalculateMovieMemorySize(theMovie, &movieSize); |
if(anErr == noErr) |
{ |
printf("This movie allocates %ld bytes in the current application heap.\n", movieSize); |
printf("Note that any possible associated movie controllers take each 10k or so.\n\n"); |
} |
// Global Time Information |
ts = GetMovieTimeScale(theMovie); |
tv = GetMovieDuration(theMovie); |
printf("The time scale for this movie is %ld.\n", ts); |
printf("The movie duration (TimeValue) = %ld\n", tv); |
printf("The movie duration in seconds = %7.2f\n", (float) tv / ts); |
printf("The current movie position (in seconds) = %7.2f\n", (float) GetMovieTime(theMovie, NULL) / ts); |
mr = GetMovieRate(theMovie); |
printf("The current movie rate is %7.2f (0 means movie is not running, < 0 going backwards).\n", (float) mr /fixed1); |
} |
// ______________________________________________________________________ |
void ShowMovieTrackInfo(Movie theMovie) |
{ |
OSErr anErr = noErr; |
long aTrackCount, index; |
Track aTrack; |
long aTrackUsage; |
Str255 tmpStr; |
Fixed height, width; |
short trackVol; |
MatrixRecord mr; |
long nVideoTracks = 0; |
long nSoundTracks = 0; |
long nTextTracks = 0; |
long nMusicTracks = 0; |
GetWTitle(FrontWindow(), tmpStr); |
printf("\nTrack Information for %s:\n", p2cstr(tmpStr)); |
// TRACK COUNT |
aTrackCount = GetMovieTrackCount(theMovie); |
anErr = GetMoviesError(); DebugAssert(anErr == noErr); |
if(anErr != noErr) return; |
if(aTrackCount == 0) |
{ |
printf("The Movie has no tracks.\n"); |
return; |
} |
else |
printf("The Movie has %d track(s).\n", aTrackCount); |
// Parse through each track and get more information: |
for(index = 1; index <= aTrackCount; index++) |
{ |
OSType aTrackType; |
Media aMedia; |
printf("\n"); |
aTrack = GetMovieIndTrack(theMovie, index); |
// TRACK TYPE |
aMedia = GetTrackMedia(aTrack); |
GetMediaHandlerDescription(aMedia, &aTrackType, 0, 0); |
switch (aTrackType) |
{ |
case SoundMediaType: printf("This is a sound track.\n"); |
nSoundTracks++; |
break; |
case VideoMediaType: printf("This is a video track.\n"); |
nVideoTracks++; |
break; |
case TextMediaType: printf("This is a text track.\n"); |
nTextTracks++; |
break; |
case MPEGMediaType: printf("This is an MPEG track.\n"); |
break; |
case MusicMediaType: printf("This is a music track.\n"); |
nMusicTracks++; |
break; |
case TimeCodeMediaType: printf("This is a time code track.\n"); |
break; |
default: |
{ |
Byte *bp = (Byte *)&aTrackType; |
printf("The track is of type '%c%c%c%c' format.\n", bp[0], bp[1], bp[2], bp[3]); |
break; |
} |
} |
// TRACK ID |
printf("Track ID: %d\n", GetTrackID(aTrack)); |
// TRACK ENABLED |
if(GetTrackEnabled(aTrack)) |
printf("Track is enabled.\n"); |
else |
printf("Track is disabled.\n"); |
// TRACK LAYER |
printf("Track Layer: %d\n", GetTrackLayer(aTrack)); |
// TRACK USAGE |
aTrackUsage = GetTrackUsage(aTrack); |
if(aTrackUsage & trackUsageInMovie) |
printf("Track is used in Movie.\n"); |
if(aTrackUsage & trackUsageInPreview) |
printf("Track is used in a preview.\n"); |
if(aTrackUsage & trackUsageInPoster) |
printf("Track is used in a poster.\n"); |
// TRACK DURATION |
printf("Duration of the track = %ld\n", GetTrackDuration(aTrack)); |
// TRACK DIMENSIONS |
GetTrackDimensions(aTrack, &width, &height); |
printf("Track width = %ld, Track height = %ld\n", Fix2Long(width), Fix2Long(height)); |
// TRACK MATRIX |
GetTrackMatrix(aTrack, &mr); |
printf("Matrix record, row 0 = [%ld], [%ld], [%ld]\n", Fix2Long(*mr.matrix[0,0]), |
Fix2Long(*mr.matrix[0,1]), Fix2Long(*mr.matrix[0,2])); |
printf("Matrix record, row 1 = [%ld], [%ld], [%ld]\n", Fix2Long(*mr.matrix[1,0]), |
Fix2Long(*mr.matrix[1,1]), Fix2Long(*mr.matrix[1,2])); |
printf("Matrix record, row 2 = [%ld], [%ld], [%ld]\n", Fix2Long(*mr.matrix[2,0]), |
Fix2Long(*mr.matrix[2,1]), Fix2Long(*mr.matrix[2,2])); |
// TRACK VOLUME |
trackVol = GetTrackVolume(aTrack); |
if(trackVol == 255) |
printf("Track Volume is 1.0\n"); |
else |
printf("Track Volume = %d.%d\n", (signed short)(trackVol >> 8) , (trackVol & 0xFF)); |
} |
// Check how many similar tracks, if too many of same warn (crossplatform issues) |
if(nVideoTracks > 1) |
printf("NOTE! You have more than one video track (%ld tracks), this will be a problem with QuickTime for Windows.\n", nVideoTracks); |
if(nSoundTracks > 1) |
printf("NOTE! You have more than one sound track (%ld tracks), you need to enable just one at a time under QuickTime for Windows (2.0.1 forward).\n", nSoundTracks); |
if(nTextTracks > 1) |
printf("NOTE! You have more than one text track (%ld tracks), this will be a problem with QuickTime for Windows.\n", nTextTracks); |
if(nMusicTracks > 1) |
printf("NOTE! You have more than one music track (%ld tracks), this will be a problem with QuickTime for Windows.\n", nMusicTracks); |
} |
// ______________________________________________________________________ |
void ShowMovieVideoInfo(Movie theMovie) |
{ |
OSErr anErr = noErr; |
Str255 tmpStr; |
short trackCount, index; |
long nSamples; |
float nSeconds; |
DebugAssert(aMovie != NULL); |
GetWTitle(FrontWindow(), tmpStr); |
printf("\nVideo Media Information for %s:\n", p2cstr(tmpStr)); |
// VIDEO FRAMES/SAMPLES |
nSamples = QTUCountMediaSamples(theMovie, VideoMediaType); |
printf("The movie has %ld video frames (samples) ", nSamples); |
printf("of which %ld are key frames\n", QTUCountKeySamples(theMovie, VideoMediaType) ); |
printf("The duration of the first video sample is %ld\n", QTUGetDurationOfFirstMovieSample(theMovie, VideoMediaType)); |
nSeconds = GetMovieDuration(theMovie)/ GetMovieTimeScale(theMovie); |
printf("Frames per second (assuming that each video sample is of the same length) = %7.2f fps\n", (float) nSamples/nSeconds ); |
// Get the Image Description Structure and present the values. |
trackCount = GetMovieTrackCount(theMovie); |
for(index = 1; index <= trackCount; index++) |
{ |
Track aTrack = NULL; |
Media aMedia = NULL; |
OSType aMediaType; |
aTrack = GetMovieIndTrack(theMovie, index); DebugAssert(aTrack != NULL); |
aMedia = GetTrackMedia(aTrack); DebugAssert(aMedia != NULL); |
anErr = GetMoviesError(); DebugAssert(anErr == noErr); |
if(anErr != noErr) |
{ |
printf("Problems with getting trackmedia = %d\n", anErr); |
return; |
} |
GetMediaHandlerDescription(aMedia, &aMediaType, 0, 0); |
if(aMediaType == VideoMediaType) // We just want to check the video media samples. |
{ |
SampleDescriptionHandle anImageDesc = NULL; |
anImageDesc = (SampleDescriptionHandle)NewHandle(sizeof(SampleDescription)); |
DebugAssert(GetMemErr == noErr); |
GetMediaSampleDescription(aMedia, 1, anImageDesc); |
anErr = GetMoviesError(); DebugAssert(anErr == noErr); |
MoveHHi((Handle)anImageDesc); HLock((Handle)anImageDesc); // Really would not need to, but printf (don't trust that one |
// due to the MetroWerks Sioux environment). |
if(anErr != noErr) |
{ |
DisposeHandle((Handle)anImageDesc); |
continue; |
} |
// OK, we have the Image Description, now present the values (see IM:QuickTime, page 3-50 for more |
// information about the ImageDescription structure). |
printf("The video track has a pixel depth of %d.\n", (*(ImageDescriptionHandle)anImageDesc)->depth); |
// Get the image description height and width values, test if these are multiple of 4 (if not there's a performance penalty). |
{ |
long rest; |
printf("The video track has a source image height of %d.\n", (*(ImageDescriptionHandle)anImageDesc)->height); |
rest = (*(ImageDescriptionHandle)anImageDesc)->height % 4; |
if (rest != 0) |
printf("NOTE! The source image height is not a multiple of 4, this means a performance hit.\n"); |
printf("The video track has a source image width of %d.\n", (*(ImageDescriptionHandle)anImageDesc)->width); |
rest = (*(ImageDescriptionHandle)anImageDesc)->width % 4; |
if (rest != 0) |
printf("NOTE! The source image width is not a multiple of 4, this means a performance hit.\n"); |
} |
printf("The video track has a horizontal resolution of %ld.\n", Fix2Long( (*(ImageDescriptionHandle)anImageDesc)->hRes) ); |
printf("The video track has a vertical resolution of %ld.\n", Fix2Long( (*(ImageDescriptionHandle)anImageDesc)->vRes) ); |
printf("The codec used to compress the video samples: %s\n", p2cstr( (*(ImageDescriptionHandle)anImageDesc)->name) ); |
printf("Note that this is the codec for the first video sample, the video samples in the movie might have various codecs used...\n"); |
{ |
Byte *bp = (Byte *)&(*(ImageDescriptionHandle)anImageDesc)->vendor; |
printf("The video track was compressed by codec provided by '%c%c%c%c'.\n", bp[0], bp[1], bp[2], bp[3]); |
} |
printf("The temporal compression setting is %ld\n", (*(ImageDescriptionHandle)anImageDesc)->temporalQuality); |
printf("The spatial compression setting is %ld\n", (*(ImageDescriptionHandle)anImageDesc)->spatialQuality); |
printf("The image description structure is %ld bytes in size.\n", |
(*(ImageDescriptionHandle)anImageDesc)->idSize); |
DisposeHandle((Handle)anImageDesc); |
} |
} |
} |
// ______________________________________________________________________ |
void ShowMovieSoundInfo(Movie theMovie) |
{ |
Str255 tmpStr; |
short trackCount, index; |
OSErr anErr = noErr; |
DebugAssert(aMovie != NULL); |
GetWTitle(FrontWindow(), tmpStr); |
printf("\nSound Media Information for %s:\n", p2cstr(tmpStr)); |
#ifdef THIS_WILL_TAKE_LONG |
printf("The movie has %d sound samples (samples)\n", QTUCountMediaSamples(theMovie, SoundMediaType)); |
#endif // THIS_WILL_TAKE_LONG |
// Get the sound description handle and munch it: |
trackCount = GetMovieTrackCount(theMovie); |
for(index = 1; index <= trackCount; index++) |
{ |
Track aTrack = NULL; |
Media aMedia = NULL; |
OSType aMediaType; |
aTrack = GetMovieIndTrack(theMovie, index); DebugAssert(aTrack != NULL); |
aMedia = GetTrackMedia(aTrack); DebugAssert(aMedia != NULL); |
anErr = GetMoviesError(); DebugAssert(anErr == noErr); |
if(anErr != noErr) |
{ |
printf("Problems with getting trackmedia = %d\n", anErr); |
return; |
} |
GetMediaHandlerDescription(aMedia, &aMediaType, 0, 0); |
if(aMediaType == SoundMediaType) // We just want to check out the sound description handles. |
{ |
SampleDescriptionHandle aDesc = NULL; |
aDesc = (SampleDescriptionHandle)NewHandle(sizeof(SampleDescription)); |
DebugAssert(GetMemErr() == noErr); |
GetMediaSampleDescription(aMedia, 1, aDesc); |
anErr = GetMoviesError(); DebugAssert(anErr == noErr); |
MoveHHi((Handle)aDesc); HLock((Handle)aDesc); // Really would not need to, but printf (don't trust that one |
// due to the MetroWerks Sioux environment). |
if(anErr != noErr) |
{ |
DisposeHandle((Handle)aDesc); |
continue; |
} |
// OK, we have the sound description handle now, present the values |
printf("The sound track rate is %d Hz.\n", (*(SoundDescriptionHandle)aDesc)->sampleRate >> 16); |
{ |
long soundRate = (*(SoundDescriptionHandle)aDesc)->sampleRate >> 16; |
if (soundRate < 30000) |
if( (soundRate != 22050) && (soundRate != 11025) ) |
printf("NOTE! The movie has a sound rate that will maybe cause performance problems with certain PC sound boards. If possible use 22050 or 11025 kHz instead\n"); |
} |
printf("The sound track size is %d bit.\n", (*(SoundDescriptionHandle)aDesc)->sampleSize); |
printf("The sound track has %d channel(s).\n", (*(SoundDescriptionHandle)aDesc)->numChannels); |
{ |
Byte *bp = (Byte *)&(*(SoundDescriptionHandle)aDesc)->dataFormat; |
printf("The sound track has the '%c%c%c%c' format.\n", bp[0], bp[1], bp[2], bp[3]); |
} |
printf("The sound description structure is %ld bytes in size.\n", |
(*(SoundDescriptionHandle)aDesc)->descSize); |
} |
} |
} |
// ______________________________________________________________________ |
// This is a variation function of the QTUCountMediaSamples one, we want to figure out how |
// many key frames we have in the movie. |
pascal long QTUCountKeySamples(Movie theMovie, OSType theMediaType) |
{ |
long numFrames = 0; |
short flags = nextTimeEdgeOK + nextTimeSyncSample; |
TimeValue aDuration = 0; |
TimeValue theTime = 0; |
GetMovieNextInterestingTime(theMovie, flags, 1, &theMediaType, theTime, 0, &theTime, &aDuration); |
if(theTime == -1) return numFrames; |
flags = nextTimeSyncSample; // Don't include the nudge after the first interesting time. |
while(theTime != -1) // When the returned time equals -1, then there were no more interesting times. |
{ |
numFrames++; |
GetMovieNextInterestingTime(theMovie, flags, 1, &theMediaType, theTime, 0, &theTime, &aDuration); |
} |
return numFrames; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14