|
Q: How do I calculate the static video frame rate of a QuickTime movie? And are there any special considerations for other media types such as MPEG-1 and MPEG-2?A: You can compute the static video frame rate using the following simple formula: static frame rate = (media sample count * media time scale) / media duration You can get a count of the samples in your video track media using For MPEG-1/MPEG-2 media the easiest way to get this information is with the Here is a code snippet which demonstrates this technique: Listing 1: Calculating the static video frame rate of a movie. #include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#define kCharacteristicHasVideoFrameRate FOUR_CHAR_CODE('vfrr')
#define kCharacteristicIsAnMpegTrack FOUR_CHAR_CODE('mpeg')
OSErr IsMPEGMediaHandler(MediaHandler inMediaHandler, Boolean *outIsMPEG);
ComponentResult MPEGMediaGetStaticFrameRate(MediaHandler inMPEGMediaHandler, Fixed *outStaticFrameRate);
OSErr MediaGetStaticFrameRate(Media inMovieMedia, double *outFPS);
void MovieGetVideoMediaAndMediaHandler(Movie inMovie, Media *outMedia,
MediaHandler *outMediaHandler);
void MovieGetStaticFrameRate(Movie inMovie, double *outStaticFrameRate);
/*
Calculate the static frame rate for a given movie.
*/
void MovieGetStaticFrameRate(Movie inMovie, double *outStaticFrameRate)
{
assert(inMovie != NULL);
assert(outStaticFrameRate != NULL);
*outStaticFrameRate = 0;
Media movieMedia;
MediaHandler movieMediaHandler;
/* get the media identifier for the media that contains the first
video track's sample data, and also get the media handler for
this media. */
MovieGetVideoMediaAndMediaHandler(inMovie, &movieMedia, &movieMediaHandler);
if (movieMedia && movieMediaHandler)
{
Boolean isMPEG = false;
/* is this the MPEG-1/MPEG-2 media handler? */
OSErr err = IsMPEGMediaHandler(movieMediaHandler, &isMPEG);
if (err == noErr)
{
if (isMPEG) /* working with MPEG-1/MPEG-2 media */
{
Fixed staticFrameRate;
ComponentResult err = MPEGMediaGetStaticFrameRate(movieMediaHandler, &staticFrameRate);
if (err == noErr)
{
/* convert Fixed data result to type double */
*outStaticFrameRate = Fix2X(staticFrameRate);
}
}
else /* working with non-MPEG-1/MPEG-2 media */
{
OSErr err = MediaGetStaticFrameRate(movieMedia, outStaticFrameRate);
assert(err == noErr);
}
}
}
}
/*
Get the media identifier for the media that contains the first
video track's sample data, and also get the media handler for
this media.
*/
void MovieGetVideoMediaAndMediaHandler(Movie inMovie, Media *outMedia, MediaHandler *outMediaHandler)
{
assert(inMovie != NULL);
assert(outMedia != NULL);
assert(outMediaHandler != NULL);
*outMedia = NULL;
*outMediaHandler = NULL;
/* get first video track */
Track videoTrack = GetMovieIndTrackType(inMovie, 1, kCharacteristicHasVideoFrameRate,
movieTrackCharacteristic | movieTrackEnabledOnly);
if (videoTrack != NULL)
{
/* get media ref. for track's sample data */
*outMedia = GetTrackMedia(videoTrack);
if (*outMedia)
{
/* get a reference to the media handler component */
*outMediaHandler = GetMediaHandler(*outMedia);
}
}
}
/*
Return true if media handler reference is from the MPEG-1/MPEG-2 media handler.
Return false otherwise.
*/
OSErr IsMPEGMediaHandler(MediaHandler inMediaHandler, Boolean *outIsMPEG)
{
assert(inMediaHandler != NULL);
assert(outIsMPEG != NULL);
/* is this the MPEG-1/MPEG-2 media handler? */
return(MediaHasCharacteristic(inMediaHandler,
kCharacteristicIsAnMpegTrack,
outIsMPEG));
}
/*
Given a reference to the media handler used for media in a MPEG-1/MPEG-2
track, return the static frame rate.
*/
ComponentResult MPEGMediaGetStaticFrameRate(MediaHandler inMPEGMediaHandler, Fixed *outStaticFrameRate)
{
assert(inMPEGMediaHandler != NULL);
assert(outStaticFrameRate != NULL);
*outStaticFrameRate = 0;
MHInfoEncodedFrameRateRecord encodedFrameRate;
Size encodedFrameRateSize = sizeof(encodedFrameRate);
/* get the static frame rate */
ComponentResult err = MediaGetPublicInfo(inMPEGMediaHandler,
kMHInfoEncodedFrameRate,
&encodedFrameRate,
&encodedFrameRateSize);
if (err == noErr)
{
/* return frame rate at which the track was encoded */
*outStaticFrameRate = encodedFrameRate.encodedFrameRate;
}
return err;
}
/*
Given a reference to the media that contains the sample data for a track,
calculate the static frame rate.
*/
OSErr MediaGetStaticFrameRate(Media inMovieMedia, double *outFPS)
{
assert(inMovieMedia != NULL);
assert(outFPS != NULL);
*outFPS = 0;
/* get the number of samples in the media */
long sampleCount = GetMediaSampleCount(inMovieMedia);
OSErr err = GetMoviesError();
if (sampleCount && err == noErr)
{
/* find the media duration */
TimeValue64 duration = GetMediaDisplayDuration(inMovieMedia);
err = GetMoviesError();
if (err == noErr)
{
/* get the media time scale */
TimeValue64 timeScale = GetMediaTimeScale(inMovieMedia);
err = GetMoviesError();
if (err == noErr)
{
/* calculate the frame rate:
frame rate = (sample count * media time scale) / media duration
*/
*outFPS = (double)sampleCount * (double)timeScale / (double)duration;
}
}
}
return err;
}
Alternately, you could count the MPEG-1 MPEG-2 video frames using Here is a code snippet that demonstrates this technique: Listing 2: Calculating the MPEG-1/MPEG-2 frame rate using #include <QuickTime/QuickTime.h>
long GetMPEGFrameCount (Movie theMovie)
{
assert(theMovie != NULL);
long frameCount = 0;
TimeValue curMovieTime;
curMovieTime = 0;
while( curMovieTime >= 0 )
{
GetMovieNextInterestingTime(
theMovie,
nextTimeStep,
0, NULL,
curMovieTime,
fixed1,
&curMovieTime,
NULL );
frameCount++;
}
frameCount--; // there's an extra time step at the end of the movie
return(frameCount);
}
OSErr MPEGMovieGetFrameRate(Movie theMovie, float *fps)
{
assert(theMovie != NULL);
assert(fps != NULL);
/* initialize fps value */
*fps = 0;
/* get movie duration */
float duration = GetMovieDuration(theMovie);
OSErr err = GetMoviesError();
if (err == noErr)
{
/* get movie time scale */
float timeScale = GetMovieTimeScale(theMovie);
err = GetMoviesError();
if (err == noErr)
{
/* calculate frame rate */
*fps = ((float)GetMPEGFrameCount(theMovie) * timeScale) / duration;
}
}
return(err) ;
}
Document Revision History
Posted: 2008-08-06 |
|