b88c72bfb5425f5a9099a1838fd97bfd8e9a9978
[blender.git] / source / blender / quicktime / apple / quicktime_export.c
1 /**
2  * $Id$
3  *
4  * quicktime_export.c
5  *
6  * Code to create QuickTime Movies with Blender
7  *
8  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version. The Blender
13  * Foundation also sells licenses for use in proprietary software under
14  * the Blender License.  See http://www.blender.org/BL/ for information
15  * about this.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  *
27  * The Original Code is written by Rob Haarsma (phase)
28  *
29  * Contributor(s): Stefan Gartner (sgefant)
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32  */
33 /*      
34 TODO:
35
36 -  fix saving of compressionsettings
37
38 This should be fixed because:
39
40 - currently only one quicktime codec is used for all scenes
41 - this single codecsetting gets only initialised from the codec dialog
42
43 - the codecsettings have to get stored in the blendfile for background
44   rendering. blender -b crashes when it wants to popup the qt codec dialog
45   to retrieve a valid codec.
46 (quicktime isnt initialised yet when blender -b requests a rendering codec)
47
48 Some references to store the codec settings are placed at the end of this file.
49
50 DONE:
51
52 *  structurize file & compression data
53
54 *  fix 23.98, 29.97, 59.94 framerates
55 *  fix framerate button
56 *  fix mac compatibility
57
58 *  fix fallthrough to codecselector  // buttons.c
59 *  fix playback qt movie             // playanim.c
60 *  fix setting fps thru blenderbutton as well as codec dialog
61
62 */
63
64 #ifdef WITH_QUICKTIME
65
66 #if defined(_WIN32) || defined(__APPLE__)
67
68 /************************************************************
69 *                                                           *
70 *    INCLUDE FILES                                          *
71 *                                                           *
72 *************************************************************/
73
74 #include "BKE_global.h"
75 #include "BKE_scene.h"
76 #include "BLI_blenlib.h"
77 #include "BLO_sys_types.h"
78 #include "IMB_imbuf.h"
79 #include "IMB_imbuf_types.h"
80 #include "MEM_guardedalloc.h"
81 #include "render.h"
82
83 #include "quicktime_export.h"
84
85 #ifdef _WIN32
86 #include <FixMath.h>
87 #include <QTML.h>
88 #include <TextUtils.h> 
89 #include <Movies.h>
90 #include <QuicktimeComponents.h>
91 #endif /* _WIN32 */
92
93 #ifdef __APPLE__
94 #undef NDEBUG
95 #include <QuickTime/Movies.h>
96 #include <QuickTime/QuicktimeComponents.h>
97 #include <fcntl.h> /* open() */
98 #include <unistd.h> /* close() */
99 #include <sys/stat.h> /* file permissions */
100 #endif /* __APPLE__ */
101
102
103 /************************************************************
104 *                                                           *
105 *    FUNCTION PROTOTYPES                                    *
106 *                                                           *
107 *************************************************************/
108
109 static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame);
110 static void QT_DoAddVideoSamplesToMedia (int frame);
111 static void QT_EndAddVideoSamplesToMedia (void);
112 static void QT_CreateMyVideoTrack (void);
113 static void QT_EndCreateMyVideoTrack (void);
114
115 static void check_renderbutton_framerate(void);
116
117 /************************************************************
118 *                                                           *
119 *    STRUCTS                                                *
120 *                                                           *
121 *************************************************************/
122
123 typedef struct _QuicktimeExport {
124
125         FSSpec          theSpec;
126         short           resRefNum;
127         short           resId;
128         short           movieResId;
129         Str255          qtfilename;
130
131         Media           theMedia;
132         Movie           theMovie;
133         Track           theTrack;
134
135         GWorldPtr       theGWorld;
136         PixMapHandle    thePixMap;
137
138         ImageDescription        **anImageDescription;
139         ImageSequence           anImageSequence;
140
141         ImBuf           *ibuf;
142
143 } QuicktimeExport;
144
145 typedef struct _QuicktimeCodecDataExt {
146
147         ComponentInstance       theComponent;
148         SCTemporalSettings  gTemporalSettings;
149         SCSpatialSettings   gSpatialSettings;
150         SCDataRateSettings  aDataRateSetting;
151         TimeValue                       duration;
152         long                            kVideoTimeScale;
153
154 } QuicktimeCodecDataExt;
155
156 struct _QuicktimeExport *qte;
157 struct _QuicktimeCodecDataExt *qcdx;
158
159 /************************************************************
160 *                                                           *
161 *    VARIABLES                                              *
162 *                                                           *
163 *************************************************************/
164
165 #define kMyCreatorType  FOUR_CHAR_CODE('TVOD')
166 #define kPixelDepth     32      /* use 32-bit depth */
167 #define kTrackStart             0
168 #define kMediaStart             0
169
170 static int sframe;
171
172 int have_qtcodec;
173
174 /************************************************************
175 *                                                           *
176 *    CheckError(OSErr err, char *msg)                       *
177 *                                                           *
178 *    prints errors in console, doesnt interrupt Blender     *
179 *                                                           *
180 *************************************************************/
181
182 void CheckError(OSErr err, char *msg)
183 {
184         if(err != noErr) printf("%s: %d\n", msg, err);
185 }
186
187
188 /************************************************************
189 *                                                           *
190 *    QT_CreateMyVideoTrack()                                *
191 *    QT_EndCreateMyVideoTrack()                             *
192 *                                                           *
193 *    Creates/finishes a video track for the QuickTime movie *
194 *                                                           *
195 *************************************************************/
196
197 static void QT_CreateMyVideoTrack(void)
198 {
199         OSErr err = noErr;
200         Rect trackFrame;
201
202         trackFrame.top = 0;
203         trackFrame.left = 0;
204         trackFrame.bottom = R.recty;
205         trackFrame.right = R.rectx;
206         
207         qte->theTrack = NewMovieTrack (qte->theMovie, 
208                                                         FixRatio(trackFrame.right,1),
209                                                         FixRatio(trackFrame.bottom,1), 
210                                                         kNoVolume);
211         CheckError( GetMoviesError(), "NewMovieTrack error" );
212
213         qte->theMedia = NewTrackMedia (qte->theTrack,
214                                                         VideoMediaType,
215                                                         qcdx->kVideoTimeScale,
216                                                         nil,
217                                                         0);
218         CheckError( GetMoviesError(), "NewTrackMedia error" );
219
220         err = BeginMediaEdits (qte->theMedia);
221         CheckError( err, "BeginMediaEdits error" );
222
223         QT_StartAddVideoSamplesToMedia (&trackFrame);
224
225
226
227 static void QT_EndCreateMyVideoTrack(void)
228 {
229         OSErr err = noErr;
230
231         QT_EndAddVideoSamplesToMedia ();
232
233         err = EndMediaEdits (qte->theMedia);
234         CheckError( err, "EndMediaEdits error" );
235
236         err = InsertMediaIntoTrack (qte->theTrack,
237                                                                 kTrackStart,/* track start time */
238                                                                 kMediaStart,/* media start time */
239                                                                 GetMediaDuration (qte->theMedia),
240                                                                 fixed1);
241         CheckError( err, "InsertMediaIntoTrack error" );
242
243
244
245 /************************************************************
246 *                                                           *
247 *    QT_StartAddVideoSamplesToMedia()                       *
248 *    QT_DoAddVideoSamplesToMedia()                          *
249 *    QT_EndAddVideoSamplesToMedia()                         *
250 *                                                           *
251 *    Creates video samples for the media in a track         *
252 *                                                           *
253 *************************************************************/
254
255 static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame)
256 {
257         OSErr err = noErr;
258
259         qte->ibuf = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
260
261         err = NewGWorldFromPtr( &qte->theGWorld,
262                                                         k32ARGBPixelFormat,
263                                                         trackFrame,
264                                                         NULL, NULL, 0,
265                                                         (unsigned char *)qte->ibuf->rect,
266                                                         R.rectx * 4 );
267         CheckError (err, "NewGWorldFromPtr error");
268
269         qte->thePixMap = GetGWorldPixMap(qte->theGWorld);
270         LockPixels(qte->thePixMap);
271
272         SCDefaultPixMapSettings (qcdx->theComponent, qte->thePixMap, true);
273
274         SCSetInfo(qcdx->theComponent, scTemporalSettingsType,   &qcdx->gTemporalSettings);
275         SCSetInfo(qcdx->theComponent, scSpatialSettingsType,    &qcdx->gSpatialSettings);
276         SCSetInfo(qcdx->theComponent, scDataRateSettingsType,   &qcdx->aDataRateSetting);
277
278         err = SCCompressSequenceBegin(qcdx->theComponent, qte->thePixMap, NULL, &qte->anImageDescription); 
279         CheckError (err, "SCCompressSequenceBegin error" );
280 }
281
282
283 static void QT_DoAddVideoSamplesToMedia (int frame)
284 {
285         OSErr   err = noErr;
286         Rect    imageRect;
287
288         register int            index;
289         register int            boxsize;
290         register uint32_t       *readPos;
291         register uint32_t       *changePos;
292         Ptr                                     myPtr;
293
294         short   syncFlag;
295         long    dataSize;
296         Handle  compressedData;
297
298 // flip rendered data for quicktime
299 // NOTE: we flip the original renderdata !
300         short x,y,backx;
301         unsigned int *top,*bottom,temp;
302
303         x = R.rectx; y = R.recty; backx = x<<1;
304         top = R.rectot; bottom = top + ((y-1) * x);     y >>= 1;
305
306         for(;y>0;y--){
307                 for(x = R.rectx; x > 0; x--){
308                         temp = *top;
309                         *(top++) = *bottom;
310                         *(bottom++) = temp;
311                 }
312                 bottom -= backx;
313         }
314
315 //get pointers to parse bitmapdata
316         myPtr = GetPixBaseAddr(qte->thePixMap);
317         imageRect = (**qte->thePixMap).bounds;
318
319         boxsize = R.rectx * R.recty;
320         readPos = (uint32_t *) R.rectot;
321         changePos = (uint32_t *) myPtr;
322
323 #ifdef __APPLE__
324 // Swap alpha byte to the end, so ARGB become RGBA; note this is big endian-centric.
325         for( index = 0; index < boxsize; index++, changePos++, readPos++ )
326                 *( changePos ) = ( ( *readPos & 0xFFFFFFFF ) >> 8 ) |
327                          ( ( *readPos << 24 ) & 0xFF );
328 #endif
329
330 #ifdef _WIN32
331 // poked around a little... this seems to work for windows, dunno if it's legal
332         for( index = 0; index < boxsize; index++, changePos++, readPos++ )
333                 *( changePos ) = ( ( *readPos & 0xFFFFFFFF ) << 8 ) |
334                                                  ( ( *readPos >> 24 ) & 0xFF ); // & ( ( *readPos << 8 ) & 0xFF );
335 #endif
336
337         err = SCCompressSequenceFrame(qcdx->theComponent,
338                 qte->thePixMap,
339                 &imageRect,
340                 &compressedData,
341                 &dataSize,
342                 &syncFlag);
343         CheckError(err, "SCCompressSequenceFrame error");
344
345         err = AddMediaSample(qte->theMedia,
346                 compressedData,
347                 0,
348                 dataSize,
349                 qcdx->duration,
350                 (SampleDescriptionHandle)qte->anImageDescription,
351                 1,
352                 syncFlag,
353                 NULL);
354         CheckError(err, "AddMediaSample error");
355
356         printf ("added frame %3d (frame %3d in movie): ", frame, frame-sframe);
357 }
358
359
360 static void QT_EndAddVideoSamplesToMedia (void)
361 {
362         
363         SCCompressSequenceEnd(qcdx->theComponent);
364
365         UnlockPixels(qte->thePixMap);
366         if (qte->theGWorld)     DisposeGWorld (qte->theGWorld);
367         if (qte->ibuf) IMB_freeImBuf(qte->ibuf);
368
369
370
371 /************************************************************
372 *                                                           *
373 *    makeqtstring (char *string)                            *
374 *                                                           *
375 *    Function to generate output filename                   *
376 *                                                           *
377 *************************************************************/
378
379 void makeqtstring (char *string) {
380         char txt[64];
381
382         if (string==0) return;
383
384         strcpy(string, G.scene->r.pic);
385         BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
386
387         RE_make_existing_file(string);
388
389         if (strcasecmp(string + strlen(string) - 4, ".mov")) {
390                 sprintf(txt, "%04d_%04d.mov", (G.scene->r.sfra) , (G.scene->r.efra) );
391                 strcat(string, txt);
392         }
393 }
394
395
396 /************************************************************
397 *                                                           *
398 *    start_qt(void)                                         *
399 *    append_qt(int frame)                                   *
400 *    end_qt(int frame)                                      *
401 *                                                           *
402 *    Quicktime Export functions for Blender's initrender.c  *
403 *                                                           *
404 ************************************************************/
405
406 void start_qt(void) {
407         OSErr err = noErr;
408
409         char name[2048];
410         char theFullPath[255];
411
412 #ifdef __APPLE__
413         int             myFile;
414         FSRef   myRef;
415 #endif
416
417         if(qte == NULL) qte = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
418         if(qcdx == NULL || have_qtcodec == FALSE) get_qtcodec_settings();
419         
420         if (G.afbreek != 1) {
421                 sframe = (G.scene->r.sfra);
422
423                 makeqtstring(name);
424                 sprintf(theFullPath, "%s", name);
425
426 #ifdef __APPLE__
427                 /* hack: create an empty file to make FSPathMakeRef() happy */
428                 myFile = open(theFullPath, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRUSR|S_IWUSR);
429                 if (myFile < 0) {
430                         printf("error while creating file!\n");
431                         /* do something? */
432                 }
433                 close(myFile);
434                 err = FSPathMakeRef(theFullPath, &myRef, 0);
435                 CheckError(err, "FsPathMakeRef error");
436                 err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qte->theSpec, NULL);
437                 CheckError(err, "FsGetCatalogInfoRef error");
438 #else
439                 CopyCStringToPascal(theFullPath, qte->qtfilename);
440                 err = FSMakeFSSpec(0, 0L, qte->qtfilename, &qte->theSpec);
441 #endif
442
443                 err = CreateMovieFile (&qte->theSpec, 
444                                                         kMyCreatorType,
445                                                         smCurrentScript, 
446                                                         createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
447                                                         &qte->resRefNum, 
448                                                         &qte->theMovie );
449                 CheckError(err, "CreateMovieFile error");
450
451                 printf("Created QuickTime movie: %s\n", name);
452
453                 check_renderbutton_framerate();
454
455                 QT_CreateMyVideoTrack();
456         }
457 }
458
459
460 void append_qt(int frame) {
461         QT_DoAddVideoSamplesToMedia(frame);
462 }
463
464 void end_qt(void) {
465         OSErr err = noErr;
466
467         short x,y,backx;
468         unsigned int *top,*bottom,temp;
469
470         if(qte->theMovie) {
471                 QT_EndCreateMyVideoTrack ();
472
473                 qte->resId = movieInDataForkResID;
474                 err = AddMovieResource (qte->theMovie, qte->resRefNum, &qte->resId, qte->qtfilename);
475                 CheckError(err, "AddMovieResource error");
476
477                 if (qte->resRefNum)     CloseMovieFile (qte->resRefNum);
478
479                 DisposeMovie (qte->theMovie);
480
481                 //flip back rendered data when done exporting quicktime
482
483                 x = R.rectx; y = R.recty; backx = x<<1;
484                 top = R.rectot; bottom = top + ((y-1) * x);     y >>= 1;
485
486                 for(;y>0;y--){
487                         for(x = R.rectx; x > 0; x--){
488                                 temp = *top;
489                                 *(top++) = *bottom;
490                                 *(bottom++) = temp;
491                         }
492                         bottom -= backx;
493                 }
494         }
495
496         if(qte) {
497                 MEM_freeN(qte);
498                 qte = NULL;
499         }
500 };
501
502
503 /************************************************************
504 *                                                           *
505 *    free_qtcodecdataExt(void)                              *
506 *                                                           *
507 *    Function to release codec memory, since it remains     *
508 *    resident after allocation.                             *
509 *                                                           *
510 *************************************************************/
511
512 void free_qtcodecdataExt(void) {
513         if(qcdx) {
514                 MEM_freeN(qcdx);
515                 qcdx = NULL;
516         }
517 }
518
519
520 /************************************************************
521 *                                                           *
522 *    check_renderbutton_framerate ( void )                  *
523 *                                                           *
524 *    To keep float framerates consistent between the codec  *
525 *    dialog and frs/sec button.                             *
526 *                                                           *
527 *************************************************************/
528
529 static void check_renderbutton_framerate(void) {
530         OSErr   err;    
531
532         err = SCGetInfo(qcdx->theComponent, scTemporalSettingsType,     &qcdx->gTemporalSettings);
533         CheckError(err, "SCGetInfo error");
534
535         if( (G.scene->r.frs_sec == 24 || G.scene->r.frs_sec == 30 || G.scene->r.frs_sec == 60) &&
536                 (qcdx->gTemporalSettings.frameRate == 1571553 ||
537                  qcdx->gTemporalSettings.frameRate == 1964113 ||
538                  qcdx->gTemporalSettings.frameRate == 3928227)) {;} else
539         qcdx->gTemporalSettings.frameRate = G.scene->r.frs_sec << 16;
540
541         err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType,     &qcdx->gTemporalSettings);
542         CheckError( err, "SCSetInfo error" );
543
544         if(qcdx->gTemporalSettings.frameRate == 1571553) {                      // 23.98 fps
545                 qcdx->kVideoTimeScale = 2398;
546                 qcdx->duration = 100;
547         } else if (qcdx->gTemporalSettings.frameRate == 1964113) {      // 29.97 fps
548                 qcdx->kVideoTimeScale = 2997;
549                 qcdx->duration = 100;
550         } else if (qcdx->gTemporalSettings.frameRate == 3928227) {      // 59.94 fps
551                 qcdx->kVideoTimeScale = 5994;
552                 qcdx->duration = 100;
553         } else {
554                 qcdx->kVideoTimeScale = (qcdx->gTemporalSettings.frameRate >> 16) * 100;
555                 qcdx->duration = 100;
556         }
557 }
558 /********************************************************************
559 *                                                                   *
560 *    get_qtcodec_settings()                                         *
561 *                                                                   *
562 *    Displays Codec Dialog and retrieves Quicktime Codec settings.  *
563 *                                                                   *
564 ********************************************************************/
565
566 int get_qtcodec_settings(void) 
567 {
568         OSErr   err = noErr;
569 //      Component c = 0;
570 //      ComponentDescription cd;
571
572 //      cd.componentType = StandardCompressionType;
573 //      cd.componentSubType = StandardCompressionSubType;
574 //      cd.componentManufacturer = 0;
575 //      cd.componentFlags = 0;
576 //      cd.componentFlagsMask = 0;
577
578         if(qcdx == NULL) {
579                 qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");
580                 have_qtcodec = FALSE;
581         }
582
583         // configure the standard image compression dialog box
584
585         if (qcdx->theComponent == NULL) {
586                 qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
587 //              c = FindNextComponent(c, &cd);
588 //              qcdx->theComponent = OpenComponent(c);
589
590                 qcdx->gSpatialSettings.codecType = nil;     
591                 qcdx->gSpatialSettings.codec = anyCodec;         
592 //              qcdx->gSpatialSettings.depth;         
593                 qcdx->gSpatialSettings.spatialQuality = codecMaxQuality;
594
595                 qcdx->gTemporalSettings.temporalQuality = codecMaxQuality;
596 //              qcdx->gTemporalSettings.frameRate;      
597                 qcdx->gTemporalSettings.keyFrameRate = 24;   
598
599                 qcdx->aDataRateSetting.dataRate = 90 * 1024;          
600 //              qcdx->aDataRateSetting.frameDuration;     
601 //              qcdx->aDataRateSetting.minSpatialQuality; 
602 //              qcdx->aDataRateSetting.minTemporalQuality;
603
604
605                 err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType,     &qcdx->gTemporalSettings);
606                 CheckError(err, "SCSetInfo1 error");
607                 err = SCSetInfo(qcdx->theComponent, scSpatialSettingsType,      &qcdx->gSpatialSettings);
608                 CheckError(err, "SCSetInfo2 error");
609                 err = SCSetInfo(qcdx->theComponent, scDataRateSettingsType,     &qcdx->aDataRateSetting);
610                 CheckError(err, "SCSetInfo3 error");
611         }
612
613         check_renderbutton_framerate();
614
615         // put up the dialog box
616
617         err = SCRequestSequenceSettings(qcdx->theComponent);
618
619         if (err == scUserCancelled) {
620                 G.afbreek = 1;
621                 return 0;
622         }
623
624         have_qtcodec = TRUE;
625
626         // get user selected data
627
628         SCGetInfo(qcdx->theComponent, scTemporalSettingsType,   &qcdx->gTemporalSettings);
629         SCGetInfo(qcdx->theComponent, scSpatialSettingsType,    &qcdx->gSpatialSettings);
630         SCGetInfo(qcdx->theComponent, scDataRateSettingsType,   &qcdx->aDataRateSetting);
631
632         // framerate jugglin'
633
634         if(qcdx->gTemporalSettings.frameRate == 1571553) {                      // 23.98 fps
635                 qcdx->kVideoTimeScale = 2398;
636                 qcdx->duration = 100;
637
638                 G.scene->r.frs_sec = 24;
639         } else if (qcdx->gTemporalSettings.frameRate == 1964113) {      // 29.97 fps
640                 qcdx->kVideoTimeScale = 2997;
641                 qcdx->duration = 100;
642
643                 G.scene->r.frs_sec = 30;
644         } else if (qcdx->gTemporalSettings.frameRate == 3928227) {      // 59.94 fps
645                 qcdx->kVideoTimeScale = 5994;
646                 qcdx->duration = 100;
647
648                 G.scene->r.frs_sec = 60;
649         } else {
650                 qcdx->kVideoTimeScale = 600;
651                 qcdx->duration = qcdx->kVideoTimeScale / (qcdx->gTemporalSettings.frameRate / 65536);
652
653                 G.scene->r.frs_sec = (qcdx->gTemporalSettings.frameRate / 65536);
654         }
655
656         return 1;
657 }
658
659 #endif /* _WIN32 || __APPLE__ */
660
661 #endif /* WITH_QUICKTIME */
662
663
664
665 #if 0
666
667 /************************************************************
668 *                                                           *
669 *    References for future codec handling                   *
670 *                                                           *
671 *************************************************************/
672
673 these are from mplayer sourcecode:
674
675 struct ComponentRecord {
676     long                            data[1];
677 };
678 typedef struct ComponentRecord          ComponentRecord;
679 typedef ComponentRecord *               Component;
680 typedef long OSErr;
681 typedef int OSType;
682 typedef long ComponentResult;
683 typedef long                            Fixed;
684
685
686 these are from quicktime:
687
688
689 typedef Component                       CodecComponent;
690 typedef OSType                          CodecType;
691 typedef unsigned short                  CodecFlags;
692 typedef unsigned long                   CodecQ;
693
694 typedef struct {
695    CodecType      codecType;        /* compressor type */
696    CodecComponent codec;            /* compressor */
697    short          depth;            /* pixel depth */
698    CodecQ         spatialQuality;   /* desired quality */
699 } SCSpatialSettings;
700
701 /* temporal options structure with the temporal settings request */
702 typedef struct {
703    CodecQ   temporalQuality;           /* desired quality */
704    Fixed    frameRate;                 /* frame rate */
705    long     keyFrameRate;              /* key frame rate */
706 } SCTemporalSettings;
707
708 /* data rate options with the data rate settings request */
709 typedef struct {
710    long     dataRate;               /* desired data rate */
711    long     frameDuration;          /* frame duration */
712    CodecQ   minSpatialQuality;      /* minimum value */
713    CodecQ   minTemporalQuality;     /* minimum value */
714 } SCDataRateSettings;
715
716
717 would look like this ???
718
719 typedef struct {
720    int                codecType;        /* compressor type */
721 //here is the prob
722    long                  *codec;            /* compressor */
723    short          depth;            /* pixel depth */
724    unsigned long  spatialQuality;   /* desired quality */
725 } SCSpatialSettings;
726
727 /* temporal options structure with the temporal settings request */
728 typedef struct {
729    unsigned long  temporalQuality;  /* desired quality */
730    long           frameRate;        /* frame rate */
731    long           keyFrameRate;     /* key frame rate */
732 } SCTemporalSettings;
733
734 /* data rate options with the data rate settings request */
735 typedef struct {
736    long           dataRate;               /* desired data rate */
737    long           frameDuration;          /* frame duration */
738    unsigned long  minSpatialQuality;      /* minimum value */
739    unsigned long  minTemporalQuality;     /* minimum value */
740 } SCDataRateSettings;
741
742
743 stuff to use quicktime Atoms (doesnt work) heh
744
745         long size;
746         Ptr     thePtr;
747         QTAtomContainer         myContainer = NULL;
748         QTAtom                          myAtom;
749 QTAtomContainer SettingsAtom;
750
751 atom -> component
752 SCSetSettingsFromAtomContainer(qcdx->theComponent, SettingsAtom);
753
754 component -> atom
755 SCGetSettingsAsAtomContainer(qcdx->theComponent, SettingsAtom);
756
757 QTCopyAtomDataToPtr(container, atom, 0, size, &targetPtr, &actualsize);
758 QTGetAtomDataPtr(container, atom, &size, &ptr);
759
760 kParentAtomIsContainer
761 #endif /* 0 */