Movie cocoaqt

From The Foundry MODO SDK wiki
Revision as of 17:02, 9 September 2013 by Adissid (Talk | contribs)

Jump to: navigation, search

Movie_CocoaQT is a basic example plugin. This wiki page is intended as a walkthrough of the code in order to help you better understand the SDK.


Movie_CocoaQT is a Plug-in Cocoa QuickTime saver for movies.

Code Walkthrough

Class Declaration

class CCocoaQuickTimeMovie : public CLxImpl_Movie
        LxResult		 mov_BeginMovie (const char*,int, int, int);
        LxResult		 mov_SetFramerate (int);
        LxResult		 mov_AddImage (ILxUnknownID);
        LxResult		 mov_EndMovie (void);
        LxResult		 mov_AddAudio (ILxUnknownID);
        static LXtTagInfoDesc	 descInfo[];
        int			 frameRate;
        NSString		*nsStringPath;
        QTMovie			*mMovie;
        NSDictionary		*myDict;
        NSString		*audioFileName;

We want to have our class create a movie object, so we have our class inherit from CLxImpl_Movie.

Server Tags

LXtTagInfoDesc	 CCocoaQuickTimeMovie::descInfo[] = {
       { LXsLOD_CLASSLIST,	LXa_MOVIE         },
       { LXsLOD_DOSPATTERN,	"*.mov"           },
       { LXsSAV_DOSTYPE,	"mov"             },
       { LXsSRV_USERNAME,	"Express Quicktime" },
       { 0 }

The tags here indicate that the main class will be a server of the movie type that will have the extension .mov named Express Quicktime


initialize ()
       LXx_ADD_SERVER (Movie, CCocoaQuickTimeMovie, "quicktime");

We export a server of the movie type dependent on the CCocoaQuickTimeMovie class with the "quicktime" name.

Helper Functions

static NSImage *
cgImageToNSImage (
        CGImageRef	 image)
       NSRect		 imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
       CGContextRef	 imageContext = nil;
       NSImage		*newImage = nil;
       // Get the image dimensions.
       imageRect.size.height = CGImageGetHeight(image);
       imageRect.size.width = CGImageGetWidth(image);
       // Create a new image to receive the Quartz image data.
       newImage = [[NSImage alloc] initWithSize:imageRect.size];
       [newImage lockFocus];
       // Get the Quartz context and draw.
       imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
       CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
       [newImage unlockFocus];
       return newImage;

This function takes a cg image and transforms it into a ns image, the apple format.

static LxResult
CreateAudioTempFile (
       NSString		*filePath,
       CLxUser_Audio		*audio)
       LXtAudioMetrics		 m;
       LxResult		 res;
       OSStatus		 err;
       NSURL			*toURL;
       AudioBufferList		 audioBufferList;
       UInt32			 bufferSize;
       char			*buffer;
       ExtAudioFileRef		 outfile;
       int			 eos;
       unsigned int		 readFrames;
       toURL = [NSURL fileURLWithPath: filePath];
       audio->Metrics (&m);
       AudioStreamBasicDescription	 outFormat = {0};
       AudioFileTypeID			 audioFileType;
       outFormat.mBitsPerChannel   = m.type;
       outFormat.mSampleRate       = (Float64) m.frequency;
       outFormat.mFormatID         = kAudioFormatLinearPCM;
       outFormat.mChannelsPerFrame = m.channels;
       outFormat.mFramesPerPacket  = 1;
       outFormat.mBytesPerFrame    = outFormat.mBitsPerChannel / 8 * outFormat.mChannelsPerFrame;
       outFormat.mBytesPerPacket   = outFormat.mBytesPerFrame * outFormat.mFramesPerPacket;
       audioFileType = kAudioFileWAVEType;
       outFormat.mFormatFlags      = kAudioFormatFlagIsPacked;
       if (m.type == 16)
               outFormat.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
       else if (m.type == 32)
               outFormat.mFormatFlags |= kLinearPCMFormatFlagIsFloat;
       // Create a temp audio file.
       err = ExtAudioFileCreateWithURL ((CFURLRef) toURL, 
       if (err != noErr) {
               NSLog (@"[ExtAudioFileCreateWithURL] err %ld\n", err);
               NSLog (@"[toURL] %@\n", toURL);
               NSLog (@"mSampleRate %f\n", outFormat.mSampleRate);
               NSLog (@"mFormatID %s\n", &outFormat.mFormatID);
               NSLog (@"mFormatFlags %x\n", outFormat.mFormatFlags);
               NSLog (@"mBytesPerPacket %u\n", outFormat.mBytesPerPacket);
               NSLog (@"mFramesPerPacket %u\n", outFormat.mFramesPerPacket);
               NSLog (@"mBytesPerFrame %u\n", outFormat.mBytesPerFrame);
               NSLog (@"mChannelsPerFrame %u\n", outFormat.mChannelsPerFrame);
               NSLog (@"mBitsPerChannel %u\n", outFormat.mBitsPerChannel);
               return LXe_FAILED;
       readFrames = 1024;
       bufferSize = sizeof (char) * readFrames * outFormat.mBytesPerPacket;
       buffer = (char *) malloc (bufferSize);
       audioBufferList.mNumberBuffers = 1;
       audioBufferList.mBuffers[0].mNumberChannels = outFormat.mChannelsPerFrame;
       audioBufferList.mBuffers[0].mDataByteSize = bufferSize;
       audioBufferList.mBuffers[0].mData = buffer;
       // Read audio data from audio object and write it into the temp file.
       audio->Seek (0);
       while (1) {
               readFrames = 1024;
               res = audio->Read (&readFrames, buffer, &eos);
               if (LXx_FAIL (res))
                       return LXe_FAILED;
               if (readFrames == 0)
               err = ExtAudioFileWrite (outfile, (UInt32) readFrames, &audioBufferList);
               if (err != noErr)
                       return LXe_FAILED;
       free (buffer);
       ExtAudioFileDispose (outfile);
       return LXe_OK;

This function creates a temporary audio file with the audio object.