QTVideo.c

/*
    File:       QTVideo.c
    
    Contains:   Code to create video tracks for QuickTime CreateMovie sample
    
    Written by: Scott Kuechle
                (based heavily on QuickTime sample code in Inside Macintosh: QuickTime)
 
    Copyright:  © 1998 by Apple Computer, Inc. All rights reserved
    
    Change History (most recent first)
    
        <1>     6/26/98     srk     first file
 
 
*/
 
/************************************************************
*                                                           *
*    INCLUDE FILES                                          *
*                                                           *
*************************************************************/
 
 
#include "ConditionalMacros.h"
 
#if TARGET_OS_WIN32
    #include <QTML.h>
#endif
 
#include <MacTypes.h>
#include <MacErrors.h>
#include <Fonts.h>
#include <QuickDraw.h>
#include <FixMath.h>
#include <Sound.h>
#include <Movies.h>
#include <ImageCompression.h>
#include <NumberFormatting.h>
 
#include "CreateMovie.h"
#include "QTVideo.h"
 
/************************************************************
*                                                           *
*    FUNCTION PROTOTYPES                                    *
*                                                           *
*************************************************************/
 
static void QTVideo_AddVideoSamplesToMedia (Media theMedia, const Rect *trackFrame);
static void QTVideo_DrawFrame (const Rect *trackFrame, long curSample);
 
/************************************************************
*                                                           *
*    CONSTANTS                                              *
*                                                           *
*************************************************************/
 
#define     kVideoTimeScale     600
#define     kNumVideoFrames     70
#define     kPixelDepth         8   /* use 8-bit depth */
#define     kNoOffset           0
#define     kMgrChoose          0
#define     kSyncSample         0
#define     kAddOneVideoSample  1
#define     kSampleDuration     60  /* frame duration = 1/10 sec */
#define     kTrackStart         0
#define     kMediaStart         0
 
 
/************************************************************
*                                                           *
*    QTVideo_CreateMyVideoTrack()                           *
*                                                           *
*    Creates a video track for a given QuickTime movie      *
*                                                           *
*************************************************************/
 
void QTVideo_CreateMyVideoTrack(Movie theMovie)
{
    Track theTrack;
    Media theMedia;
    OSErr err = noErr;
    Rect trackFrame = {0,0,100,320};
 
        theTrack = NewMovieTrack (theMovie, 
                                FixRatio(trackFrame.right,1),
                                FixRatio(trackFrame.bottom,1), 
                                kNoVolume);
        CheckError( GetMoviesError(), "NewMovieTrack error" );
 
        theMedia = NewTrackMedia (theTrack, VideoMediaType,
                                kVideoTimeScale, /* Video Time Scale */
                                nil, 0);
        CheckError( GetMoviesError(), "NewTrackMedia error" );
 
        err = BeginMediaEdits (theMedia);
        CheckError( err, "BeginMediaEdits error" );
 
        QTVideo_AddVideoSamplesToMedia (theMedia, &trackFrame);
 
        err = EndMediaEdits (theMedia);
        CheckError( err, "EndMediaEdits error" );
 
        err = InsertMediaIntoTrack (theTrack, kTrackStart,/* track start time */
                                    kMediaStart, /* media start time */
                                    GetMediaDuration (theMedia),
                                    fixed1);
        CheckError( err, "InsertMediaIntoTrack error" );
} 
 
/************************************************************
*                                                           *
*    QTVideo_AddVideoSamplesToMedia()                       *
*                                                           *
*    Creates video samples for the media in a track         *
*                                                           *
*************************************************************/
 
static void QTVideo_AddVideoSamplesToMedia (Media theMedia, const Rect *trackFrame)
{
    long maxCompressedSize;
    GWorldPtr theGWorld = nil;
    long curSample;
    Handle compressedData = nil;
    Ptr compressedDataPtr;
    ImageDescriptionHandle imageDesc = nil;
    CGrafPtr oldPort;
    GDHandle oldGDeviceH;
    OSErr err = noErr;
 
 
 
        err = NewGWorld (&theGWorld, 
                        kPixelDepth,    /* pixel depth */
                        trackFrame, 
                        nil, 
                        nil, 
                        (GWorldFlags) 0 );
        CheckError (err, "NewGWorld error");
 
        LockPixels (theGWorld->portPixMap);
        err = GetMaxCompressionSize(theGWorld->portPixMap,
                                    trackFrame, 
                                    kMgrChoose, /* let ICM choose depth */
                                    codecNormalQuality, 
                                    kAnimationCodecType, 
                                    (CompressorComponent) anyCodec,
                                    &maxCompressedSize);
        CheckError (err, "GetMaxCompressionSize error" );
 
        compressedData = NewHandle(maxCompressedSize);
        CheckError( MemError(), "NewHandle error" );
 
        MoveHHi( compressedData );
        HLock( compressedData );
        compressedDataPtr = StripAddress( *compressedData );
 
        imageDesc = (ImageDescriptionHandle)NewHandle(4);
        CheckError( MemError(), "NewHandle error" );
 
        GetGWorld (&oldPort, &oldGDeviceH);
        SetGWorld (theGWorld, nil);
 
        for (curSample = 1; curSample <= kNumVideoFrames; curSample++) 
        {
            EraseRect (trackFrame);
 
            QTVideo_DrawFrame(trackFrame, curSample);
 
            err = CompressImage (theGWorld->portPixMap, 
                                trackFrame, 
                                codecNormalQuality,
                                kAnimationCodecType,
                                imageDesc, 
                                compressedDataPtr );
            CheckError( err, "CompressImage error" );
 
            err = AddMediaSample(theMedia, 
                                compressedData,
                                kNoOffset,  /* no offset in data */
                                (**imageDesc).dataSize, 
                                kSampleDuration,    /* frame duration = 1/10 sec */
                                (SampleDescriptionHandle)imageDesc, 
                                kAddOneVideoSample, /* one sample */
                                kSyncSample,    /* self-contained samples */
                                nil);
            CheckError( err, "AddMediaSample error" );
        }
        SetGWorld (oldPort, oldGDeviceH);
 
        if (imageDesc)
        {
            DisposeHandle ((Handle)imageDesc);
        }
        if (compressedData)
        {
            DisposeHandle (compressedData);
        }
        if (theGWorld)
        {
            DisposeGWorld (theGWorld);
        }
} 
 
 
/************************************************************
*                                                           *
*    QTVideo_DrawFrame()                                    *
*                                                           *
*    contains code to "draw" a video frame                  *
*                                                           *
*************************************************************/
 
static void QTVideo_DrawFrame (const Rect *trackFrame, long curSample)
{
    Str255 numStr;
 
        ForeColor( redColor );
        PaintRect( trackFrame );
 
        ForeColor( blueColor );
        NumToString (curSample, numStr);
        MoveTo ( (short)(trackFrame->right / 2), (short)(trackFrame->bottom / 2));
        TextSize ( (short)(trackFrame->bottom / 3));
        DrawString (numStr);
}