Chapter 31. Using the Movie Library with QuickTime Movies

This chapter describes how to create, edit, and play uncompressed QuickTime movies on a Silicon Graphics computer using the Movie Library. Silicon Graphics also provides a separate option, the QuickTime Compressor Library, under license from Apple Computer, Inc. for use with the Movie Library, that supports Apple Animation and Apple Video compression for QuickTime movies.


Note: To use the Apple Animation and Apple Video compression discussed in this chapter, you must purchase and install the Silicon Graphics QuickTime Compressor Library.



Note: Apple QuickTime software for the Macintosh that is mentioned in this chapter is available from Apple Computer, Inc. in the Apple QuickTime Starter Kit.


QuickTime Basics

This section presents basic concepts for using QuickTime movies with the Movie Library.

QuickTime is an Apple Macintosh system software extension that can be installed in the Macintosh to extend its capabilities so as to allow time-based (audio, video, and animation) data for multimedia applications.

QuickTime movies store and play picture tracks and soundtracks independently of each other, analogous to the way the Movie Library stores separate image and audio tracks. You can't work with pictures and sound as separate entities using the QuickTime Starter Kit utilities on the Macintosh, but you can use the Silicon Graphics Movie Library to work with the individual image and audio tracks in a QuickTime movie.

QuickTime Sound

QuickTime movie soundtracks are playable on both Macintosh and Silicon Graphics computers, but each has its own unique audio data format, so audio playback is most efficient when using the native data format and rate for the computer on which the movie is playing.

When playing a QuickTime movie soundtrack on a Silicon Graphics computer, the Movie Library chooses the nearest appropriate audio sample rate during playback and file format conversion of nonnative movies, so no performance penalty is incurred for rate conversion. This may change the pitch of some sounds slightly, but usually not enough to cause an audible difference. The Movie Library supports 8-bit and 16-bit uncompressed audio in either two's complement or unsigned format. The native rates for Silicon Graphics audio hardware are 8000, 11025, 16000, 22050, 32000, 44100, and 48000 Hz.

When playing a QuickTime movie soundtrack on a Macintosh, the Macintosh QuickTime software converts nonnative audio to the native Macintosh 8-bit format and performs the necessary rate conversions for playing the nonnative soundtrack; but if you use the Movie Library to write audio data to a QuickTime movie that is intended for playback only on the Macintosh, use a format and sampling rate suitable for the Macintosh. QuickTime supports the AIFF sound file format and both signed and unsigned audio, at any rate up to 65 KHz. The native format for Macintosh audio hardware is 8-bit, unsigned audio at either 11127 Hz or 22254 Hz.

QuickTime Compression

The Macintosh QuickTime system software extension includes five compressors, two of which are compatible with the Movie Library:

  • Apple None (uncompressed)

  • Apple Photo (JPEG standard)

and two of which are compatible with the Movie Library only when you purchase and install the Silicon Graphics QuickTime Compressor Library:

  • Apple Animation

  • Apple Video

You can use a QuickTime movie saved with either Apple Animation or Apple Video compression with the Movie Library if you have purchased and installed the Silicon Graphics QuickTime Compressor Library; otherwise, you must save the movie without compression or use JPEG.

When creating QuickTime movies on a Macintosh for use with the Movie Library, you can select the compression settings using one of the following methods:

  1. Use the Macintosh QuickTime Movie Recorder, which gives you two options for compressing a movie:

    • accepting the default setting, “Use Simple Compression,” which automatically applies Apple Video compression when you save the movie

    • selecting an appropriate type of compression from the Compression Settings dialog box and then choosing “Compress” from the Movie menu before saving the movie

  2. Use the Macintosh QuickTime Movie Converter to change compression settings for existing movies

Compression settings and the applications for which each setting is best suited are summarized in the sections that follow.

Apple None

Apple None creates an uncompressed movie and can be used to change the number of colors in the images and/or the recording quality. Both the number of colors and the recording quality can affect the size of the movie.

To create an uncompressed QuickTime movie on the Macintosh, click on the “Apple None” choice in the QuickTime Compression Settings dialog box.


Note: Because the Macintosh compresses QuickTime movies by default, you must set the compression to Apple None and save the movie again to create an uncompressed movie.


Apple Photo

Apple Photo uses the JPEG standard. The Movie Library supports the JPEG standard through the Compression Library. JPEG is best suited for compressing individual still frames, because decompressing a JPEG image can be a time-consuming task, especially if the decompression is performed in software. JPEG is typically used to compress each still frame during the writing or editing process, with the intention to apply another type of compression to the final version of the movie or to leave it uncompressed. JPEG works better on high-resolution continuous-tone images, such as photographs, than on crisp-edged, high-contrast images like line drawings.

Apple Animation

Apple Animation uses a lossy run-length encoding (RLE) method, which compresses images by storing a color and its run-length (the number of pixels of that color) every time the color changes. Apple Animation is not a true lossless RLE method because it stores colors that are close to the same value as one color. This method is most appropriate for compressing images such as line drawings that have highly contrasting color transitions and few color variations.

Apple Video

Apple Video uses a method developed by Apple Computer whose objective is to decompress and display movie frames as fast as possible. It compresses individual frames and works better on movies recorded from a video source than on animations.


Note: The Apple Video compressor has a restriction that the image width and height be a multiple of 4. Before transferring a movie from a Macintosh to a Silicon Graphics computer, make sure that the image size is a multiple of 4.


QuickTime Frame Differencing (Keyframes)

QuickTime provides a feature called frame differencing, which allows you to save only the changes from one movie frame to the next, rather than store each individual frame for the entire movie. When frame differencing is used, the entire contents of every nth frame are compressed and stored in a keyframe, while only the differences from frame to frame are stored for the frames between keyframes. (On the Macintosh, you enable frame differencing by clicking on the “Key frame every n frames” box in the Motion area of the Compression Settings dialog box.)

Reducing the time between keyframes increases the performance when scrubbing to a particular frame (because of the increased likelihood of landing on a keyframe) but increases the size of the movie.

You can open and play keyframe movies with the Movie Library. You can't use the mvPasteFrames() editing function to paste frames into the middle of a keyframe movie because the Movie Library does not support the recomputing of frame differencing. For the same reason, you cannot delete frames from a keyframe movie. To create a movie using Apple Animation or Apple Video, you must use mvInsertFrames() to add the frames in order from beginning to end.

Movie Library QuickTime Compatibility Requirements

QuickTime movies must be single-fork and self-contained in order to be compatible between Apple Macintosh and Silicon Graphics computers. This section describes how to make QuickTime movies that meet these requirements.

Making a Single-fork Movie

Files on an Apple computer are double-fork, containing both a data fork and a resource fork. Only Apple computers use the double-fork file system; the file system on Silicon Graphics computers does not use double-fork files.

Macintosh computers convert a double-fork file into a single-fork file by writing the resource fork into the data fork. You must perform this conversion on the Macintosh for any movie files that you plan on using with the Movie Library before transferring them to the Silicon Graphics computer.

To make a single-fork movie on the Macintosh:

  1. Click on the “Playable on non-Apple computers” box in the QuickTime Movie Converter Save dialog box (see the QuickTime Starter Kit User's Guide for details).

  2. Equivalently, if you are writing an application on a Macintosh using the Apple QuickTime developer kit, call the Movie Toolbox PutMovieIntoDataFork function in that application to write the movie into a single-fork file before using it in a Movie Library application (see Inside Macintosh: QuickTime for details).

Making a Self-contained Movie

Apple QuickTime movie utilities offer two ways of saving a QuickTime movie file on the Macintosh:

  • Save normally

  • Make movie self-contained

A QuickTime movie that has been saved on the Macintosh using the “Save normally” feature contains movie synchronization information, such as the location and sequence of frames in the movie, but does not itself contain the actual movie data. The movie data could have been stored in one or more separate files on the disk, on CD-ROM, or on a remote computer accessible from the network. Such a movie is said to have dependencies, because it depends on being able to locate and use other files that make up the movie. You cannot use this type of movie with the Movie Library.

Only self-contained (also called “flattened”) QuickTime movie files are compatible with the Movie Library. Self-contained QuickTime movies have both the synchronization information and the movie data in one file.

You can use the Macintosh Movie Info window to determine whether an existing movie is self-contained. If the movie is self-contained, nothing will appear in the box under “Uses data from one other file.” If anything does appear in this box, you need to convert the movie to a self-contained file.

You must convert any movie files that you plan on using with the Movie Library to self-contained movies on the Macintosh before transferring them to the Silicon Graphics computer, using one of the following methods:

  1. Click on “Make movie self-contained” from the Save dialog box that appears when you select “Save” or “Save as” from the Macintosh File menu of the QuickTime Movie Player or Movie Recorder. Because the Macintosh default is “Save normally,” you must specify “Make movie self-contained” when saving any QuickTime movie that you plan on using with the Movie Library.

  2. To convert an existing QuickTime movie, use the Macintosh QuickTime Movie Converter to open the movie, select “Make movie self-contained,” and then save the movie.

  3. Equivalently, if you are writing a Macintosh application using the Apple QuickTime developer kit, call the Movie Toolbox FlattenMovieData function in that application to make the movie file self-contained before using it in a Movie Library application.

Transferring Files Between Macintosh and Silicon Graphics Computers

You can transfer QuickTime movies between an Apple Macintosh computer and a Silicon Graphics computer by using a floppy disk or by using a network file transfer application.

Transferring Files from Floppy Disk

If you have an Indigo or an Indy with a floptical drive, you can read files from a floppy disk that was formatted on a Macintosh computer.

Transferring Files Over a Network

To transfer QuickTime movies between an Apple Macintosh computer and a Silicon Graphics computer over a network, use either ftp or the Apple Computer AppleShare network software. When using ftp, specify “binary” to ensure complete data transfer.

Adding QuickTime Capability to Your Movie Library Application

Once you know how to program a Movie Library application, adding QuickTime capability is as easy as adding two lines to your code. Only three steps are needed to create an application that can use QuickTime movies (as long as they meet the compatibility criteria):

  1. including qt.h, the QuickTime header file

  2. calling mvInitQuickTime() to initialize the Movie Library for QuickTime movies

    This step also installs the QuickTime codecs in the Movie Library if you have purchased the QuickTime Compressor Library.

  3. linking with the QuickTime Compressor Library by putting -lqt before -lmovie on the link line

QuickTime versions of many of the Movie Library sample programs are provided in the createmovieqt and miscqt directories under /usr/people/4Dgifts/examples/dmedia/movie.

Using the QuickTime Compressor Library

If you have purchased and installed the Silicon Graphics QuickTime Compressor Library, codecs for Apple Video and Apple Animation are installed into the Movie Library and are available for your application to use on either QuickTime or Silicon Graphics movies.

Creating a QuickTime Movie

You can use the Movie Library to create a QuickTime movie that is playable on both Silicon Graphics and Apple computers. Use the same steps as creating a Silicon Graphics movie, but specify QuickTime format, as in the createmovieqt.c sample program.

Example 31-1 highlights the changes that were made to the createmovie sample program to turn it into createmovieqt, which is an identical program that offers QuickTime compatibility. These excerpts are from createmovieqtArgs.c++ in the /usr/people/4Dgifts/examples/dmedia/movie/createmovieqt directory.

Example 31-1. Creating QuickTime Movies with the Movie Library

#include "createmovieArgs.h"
#include <movie.h>

#include <qt.h>
#include <audiofile.h>
#include <getopt.h>
#include <string.h>
#include <assert.h>
#include <il/ilImage.h>
#include <il/ilGenericImgFile.h>


typedef enum _compScheme
{
    unknownComp,
    none,
    mvc1,
    mvc2,
    rle,
    jpeg,
    rgb8,

    qtvideo,
    qtanim
} compScheme;

…

static compScheme   compressionScheme = qtvideo;
…

static MVfileformat movieFormat       = MV_FORMAT_QT;
…

static void      setMovieFormat( char *formatArg );
…


static DMboolean badCompressionScheme( void );

…

while(( ch = getopt( argc, argv, "f:c:l:r:s:p:o:" ) ) != -1) {
        switch ( ch ) {
            case 'f':
                setMovieFormat( optarg );
                break;
…


    if ( badCompressionScheme() ) {
        fprintf( stderr, "%s: Compression %s"
                 "unavailable for QuickTime.\n",
                  programName, getCompressionScheme() );
        exit( EXIT_FAILURE );
    }
…


    mvInitQuickTime();

…

static void usage( void )
{
    …

    fprintf( stderr, "[-f format] [-s xsize,ysize]"
                    "[-o outMovie] \n" );
    fprintf( stderr, "[-p paramType,userParam,userParamVal]"
                    " file …\n" );
    fprintf( stderr, "\n");
    fprintf( stderr, "\"compression\" = none, mvc1, mvc2,"
            " rle, jpeg, " );
    fprintf( stderr, "8rgb, qtvideo, or qtanim.\n" );
    fprintf( stderr, "Default compression scheme qtvideo.\n" );
    fprintf( stderr, "\"format\" = sgi or qt,"
             " the format of the new movie.");
    fprintf( stderr, "The default is qt.\n" );
    …
}

…

static void setMovieFormat( char *formatArg )
{
    if ( ( strcmp( formatArg, "sgi" ) == 0 ) || 
        ( strcmp( formatArg, "SGI" ) == 0 ) ) {
        movieFormat = MV_FORMAT_SGI_3;
    }
    else if ( ( strcmp( formatArg, "qt" ) == 0 ) ||
             ( strcmp( formatArg, "QT" ) == 0 ) ) {
        movieFormat = MV_FORMAT_QT;
    }
    else {
        fprintf( stderr, "%s: Unknown movie format %s.\n",
                programName, formatArg );
        usage();
    }
}
…


static DMboolean badCompressionScheme( void )
{
    if ( ( getMovieFormat() == MV_FORMAT_QT ) &&
        ( ( compressionScheme != none ) && 
         ( compressionScheme != jpeg ) && 
         ( compressionScheme != qtanim ) && 
         ( compressionScheme != qtvideo ) ) ) {
        return( DM_TRUE );
    }
    return( DM_FALSE );
}
…


static void setCompressionScheme( char *compressArg )
{
    if ( strcmp( compressArg, "none" ) == 0 ) {
        compressionScheme = none;
    }
    else if ( strcmp( compressArg, "mvc1" ) == 0 ) {
        compressionScheme = mvc1;
    }
    else if ( strcmp( compressArg, "mvc2" ) == 0 ) {
        compressionScheme = mvc2;
    }
    else if ( strcmp( compressArg, "rle" ) == 0 ) {
        compressionScheme = rle;
    }
    else if ( strcmp( compressArg, "jpeg" ) == 0 ) {
        compressionScheme = jpeg;
    }
    else if ( strcmp( compressArg, "8rgb" ) == 0 ) {
        compressionScheme = rgb8;
    }
    else if ( strcmp( compressArg, "qtvideo" ) == 0 ) {
        compressionScheme = qtvideo;
    }
    else if ( strcmp( compressArg, "qtanim" ) == 0 ) {
        compressionScheme = qtanim;
    }
    else {
        fprintf( stderr, "%s: Unknown compress scheme %s.\n",
                programName, compressArg );
        usage();
    }
}
…


schar *getCompressionScheme( void )
{
    switch( compressionScheme ) {
        case none:
            return( DM_IMAGE_UNCOMPRESSED );
        case mvc1:
            return( DM_IMAGE_MVC1 );
        case mvc2:
            return( DM_IMAGE_MVC2 );
        case jpeg:
            return( DM_IMAGE_JPEG );
        case rle:
            return( DM_IMAGE_RLE );
        case rgb8:
            return( DM_IMAGE_UNCOMPRESSED );
        case qtvideo:
            return( DM_IMAGE_QT_VIDEO );
        case qtanim:
            return( DM_IMAGE_QT_ANIM );
        case unknownComp:
            assert( DM_FALSE );
            break;
    }
}


Reading Existing QuickTime Movies

The Movie Library can read uncompressed QuickTime movies in 16- and 32-bit depths, which correspond to the “Thousands” and “Millions” of colors choices in the QuickTime compression settings on the Macintosh.

To open an uncompressed QuickTime movie, call mvOpenFile().

To read the data, call mvReadFrames(), which puts the image data into your buffer.

Converting QuickTime Image Data to Silicon Graphics Image Format

If you're working with an uncompressed QuickTime movie, you need to convert the QuickTime picture data to a Silicon Graphics image data format such as RGBX.

You can then invert it and transform it into RGBX, as shown in Example 31-2.
Example 31-2 contains a listing of createmovieConvert.c, which is located in the /usr/people/4Dgifts/examples/dmedia/movie/createmovieqt directory.

Example 31-2. Converting QuickTime Picture Data to RGBX Format

/*****************************************************************************
 *
 * File:        createmovieConvert.c
 *
 * Description: Part of createmovie. Used only in conjunction with the
 *              SGI QuickTime Library. Code for converting between
 *              QuickTime and SGI rgb image data.
 *
 *****************************************************************************/

#include <sys/types.h>
#include "createmovieConvert.h"

/*
 * Forward declarations for functions local to this module.
 */

static void InvertImage32( void* buffer, int width, int height );
static void InvertImage16( void* buffer, int width, int height );


/********
 *
 * Apple16ToRGBX
 *
 * 16-bit images are stored with 5 bits each of red, green, and blue.
 * The bit layout is: 
 *
 *             XRRRRRGG GGGBBBBB
 *
 * The bit layout for SGI 32-bit RGBX images is: 
 *
 *             XXXXXXXX BBBBBBBB GGGGGGGG RRRRRRRR
 *
 * Apple stores images from top to bottom, while SGI goes from bottom to top.
 *
 ********/
void Apple16ToRGBX( int width, int height, void* from, void* to)
{
    static unsigned char Apple16Table[32];

    unsigned short* src  = ( unsigned short* ) from;
    __uint32_t*     dst  = ( __uint32_t* )     to;
    size_t          size = ( ( size_t ) width ) * ( ( size_t ) height );
    size_t          i;

    for ( i = 0;  i < 32;  i++ ) {
        Apple16Table[i] = ( ( i << 3 ) | ( i >> 2 ) );
    }

    for ( i = 0;  i < size;  i++ ) {
        unsigned short bits = src[i];
        unsigned char  red   = Apple16Table[( ( 0x1F << 10 ) & bits ) >> 10];
        unsigned char  green = Apple16Table[( ( 0x1F <<  5 ) & bits ) >>  5];
        unsigned char  blue  = Apple16Table[( ( 0x1F <<  0 ) & bits ) >>  0];
        dst[i] = ( blue << 16 ) | ( green << 8 ) | ( red << 0 );
    }
    
    InvertImage32( to, width, height );
}

/********
 * RGBXToApple16
 ********/

void RGBXToApple16( int width, int height, void* from, void* to)
{
    __uint32_t*     src  = ( __uint32_t* )     from;
    unsigned short* dst  = ( unsigned short* ) to;
    size_t          size = ( ( size_t ) width ) * ( ( size_t ) height );
    size_t          i;
    
    for ( i = 0;  i < size;  i++ ) {
        __uint32_t bits      = src[i];
        unsigned char  red   = ( ( 0x1F <<  3 ) & bits ) >>  3;
        unsigned char  green = ( ( 0x1F << 11 ) & bits ) >> 11;
        unsigned char  blue  = ( ( 0x1F << 19 ) & bits ) >> 19;
        dst[i] = ( blue << 0 ) | ( green << 5 ) | ( red << 10 );
    }
    
    InvertImage16( to, width, height );
}
/********
 *
 * Apple32ToRGBX
 *
 * 32-bit images are stored with 8 bits each of red, green, and blue.
 * The bit layout is: 
 *
 *         XXXXXXXX RRRRRRRR GGGGGGGG BBBBBBBB
 *
 * The bit layout for SGI 32-bit RGBX images is: 
 *
 *         XXXXXXXX BBBBBBBB GGGGGGGG RRRRRRRR
 *
 * Apple stores images from top to bottom, while SGI goes from bottom to top.
 *
 ********/

void Apple32ToRGBX( int width, int height, void* from, void* to)
{
    __uint32_t*     src  = ( __uint32_t* ) from;
    __uint32_t*     dst  = ( __uint32_t* ) to;
    size_t          size = ( ( size_t ) width ) * ( ( size_t ) height );
    size_t          i;

    for ( i = 0;  i < size;  i++ ) {
        __uint32_t bits = src[i];
        dst[i] = ( ( bits & ( 0xFF << 16 ) ) >> 16 ) |
                 ( ( bits & ( 0xFF <<  8 ) ) >>  0 ) |
                 ( ( bits & ( 0xFF <<  0 ) ) << 16 );
    }
  
    InvertImage32( to, width, height );
}
/********
 * RGBXToApple32
 * Apple packs the colors in a different order than SGI does:
 ********/

void RGBXToApple32( int width, int height, void* from, void* to)
{
    __uint32_t*     src  = ( __uint32_t* ) from;
    __uint32_t*     dst  = ( __uint32_t* ) to;
    size_t          size = ( ( size_t ) width ) * ( ( size_t ) height );
    size_t          i;

    for ( i = 0;  i < size;  i++ ) {
        __uint32_t bits = src[i];
        dst[i] = ( ( bits & ( 0xFF << 16 ) ) >> 16 ) |
                 ( ( bits & ( 0xFF <<  8 ) ) >>  0 ) |
                 ( ( bits & ( 0xFF <<  0 ) ) << 16 );
    }
  
    InvertImage32( to, width, height );
}

/********
 * InvertImage32 
 * Inverts a 32-bit image.
 ********/

static void InvertImage32( void* buffer, int width, int height )
{
    __uint32_t* buff = ( __uint32_t* ) buffer;
    
    int x;
    int y1;
    for ( x = 0;  x < width;  x++ ) {
        for ( y1 = 0;  y1 < height/2; y1++ ) {
            int y2 = height - y1 - 1;
            int index1 = x + y1 * width;
            int index2 = x + y2 * width;
            
            __uint32_t t = buff[index1];
            buff[index1] = buff[index2];
            buff[index2] = t;
        }
    }
}
/********
 * InvertImage16
 * Inverts a 16-bit image.
 ********/

static void InvertImage16( void* buffer, int width, int height )
{
    unsigned short* buff = ( unsigned short* ) buffer;
    
    int x;
    int y1;
    for ( x = 0;  x < width;  x++ ) {
        for ( y1 = 0;  y1 < height/2; y1++ ) {
            int y2 = height - y1 - 1;
            int index1 = x + y1 * width;
            int index2 = x + y2 * width;
            
            unsigned short t = buff[index1];
            buff[index1]     = buff[index2];
            buff[index2]     = t;
        }
    }
}