~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/quicktime/apple/quicktime_export.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: quicktime_export.c,v 1.12 2004/01/08 16:26:30 sgefant Exp $
 
2
 * $Id: quicktime_export.c,v 1.21 2005/04/02 15:36:57 zuster Exp $
3
3
 *
4
4
 * quicktime_export.c
5
5
 *
30
30
 *
31
31
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
32
32
 */
33
 
/*      
34
 
DONE:
35
 
 
36
 
*  structurize file & compression data
37
 
 
38
 
*  fix 23.98, 29.97, 59.94 framerates
39
 
*  fix framerate button
40
 
*  fix mac compatibility
41
 
 
42
 
*  fix fallthrough to codecselector  // buttons.c
43
 
*  fix playback qt movie             // playanim.c
44
 
*  fix setting fps thru blenderbutton as well as codec dialog
45
 
*  fix saving of compressionsettings
46
 
 
47
 
*/
48
33
 
49
34
#ifdef WITH_QUICKTIME
50
 
 
51
35
#if defined(_WIN32) || defined(__APPLE__)
52
36
 
53
 
/************************************************************
54
 
*                                                           *
55
 
*    INCLUDE FILES                                          *
56
 
*                                                           *
57
 
*************************************************************/
58
 
 
59
37
#include "BKE_global.h"
60
38
#include "BKE_scene.h"
61
39
#include "BLI_blenlib.h"
 
40
#include "BIF_toolbox.h"        /* error() */
62
41
#include "BLO_sys_types.h"
63
42
#include "IMB_imbuf.h"
64
43
#include "IMB_imbuf_types.h"
65
44
#include "MEM_guardedalloc.h"
66
45
#include "render.h"
67
 
 
 
46
#include "quicktime_import.h"
68
47
#include "quicktime_export.h"
69
48
 
70
49
#ifdef _WIN32
71
 
#include <FixMath.h>
72
50
#include <QTML.h>
73
 
#include <TextUtils.h> 
74
51
#include <Movies.h>
75
52
#include <QuicktimeComponents.h>
76
 
#include <MoviesFormat.h>
 
53
#include <TextUtils.h> 
77
54
#endif /* _WIN32 */
78
55
 
79
56
#ifdef __APPLE__
88
65
#include <sys/stat.h> /* file permissions */
89
66
#endif /* __APPLE__ */
90
67
 
91
 
 
92
 
/************************************************************
93
 
*                                                           *
94
 
*    FUNCTION PROTOTYPES                                    *
95
 
*                                                           *
96
 
*************************************************************/
 
68
#define kMyCreatorType  FOUR_CHAR_CODE('TVOD')
 
69
#define kTrackStart             0
 
70
#define kMediaStart             0
97
71
 
98
72
static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame);
99
73
static void QT_DoAddVideoSamplesToMedia (int frame);
100
74
static void QT_EndAddVideoSamplesToMedia (void);
101
75
static void QT_CreateMyVideoTrack (void);
102
76
static void QT_EndCreateMyVideoTrack (void);
103
 
 
104
77
static void check_renderbutton_framerate(void);
105
78
 
106
 
/************************************************************
107
 
*                                                           *
108
 
*    STRUCTS                                                *
109
 
*                                                           *
110
 
*************************************************************/
111
 
 
112
 
typedef struct _QuicktimeExport {
 
79
typedef struct QuicktimeExport {
113
80
 
114
81
        FSSpec          theSpec;
115
82
        short           resRefNum;
116
 
        short           resId;
117
 
        short           movieResId;
118
83
        Str255          qtfilename;
119
84
 
120
85
        Media           theMedia;
121
86
        Movie           theMovie;
122
87
        Track           theTrack;
123
88
 
124
 
        GWorldPtr       theGWorld;
125
 
        PixMapHandle    thePixMap;
126
 
 
 
89
        GWorldPtr                       theGWorld;
 
90
        PixMapHandle            thePixMap;
127
91
        ImageDescription        **anImageDescription;
128
 
        ImageSequence           anImageSequence;
129
92
 
130
 
        ImBuf           *ibuf;  //for Qtime's Gworld
 
93
        ImBuf           *ibuf;  //imagedata for Quicktime's Gworld
131
94
        ImBuf           *ibuf2; //copy of renderdata, to be Y-flipped
132
95
 
133
96
} QuicktimeExport;
134
97
 
135
 
typedef struct _QuicktimeCodecDataExt {
 
98
typedef struct QuicktimeComponentData {
136
99
 
137
100
        ComponentInstance       theComponent;
138
101
        SCTemporalSettings  gTemporalSettings;
141
104
        TimeValue                       duration;
142
105
        long                            kVideoTimeScale;
143
106
 
144
 
} QuicktimeCodecDataExt;        //qtopts
145
 
 
146
 
 
147
 
struct _QuicktimeExport *qte;
148
 
struct _QuicktimeCodecDataExt *qcdx;
149
 
 
150
 
/************************************************************
151
 
*                                                           *
152
 
*    VARIABLES                                              *
153
 
*                                                           *
154
 
*************************************************************/
155
 
 
156
 
#define kMyCreatorType  FOUR_CHAR_CODE('TVOD')
157
 
#define kPixelDepth     32      /* use 32-bit depth */
158
 
#define kTrackStart             0
159
 
#define kMediaStart             0
 
107
} QuicktimeComponentData;
 
108
 
 
109
static struct QuicktimeExport *qtexport;
 
110
static struct QuicktimeComponentData *qtdata;
160
111
 
161
112
static int      sframe;
162
 
static char     qtcdname[128];
163
 
 
164
 
 
165
 
/************************************************************
166
 
*                                                           *
167
 
*    SaveExporterSettingsToMem                              *
168
 
*                                                           *
169
 
*************************************************************/
170
 
 
171
 
OSErr SaveExporterSettingsToMem (QuicktimeCodecData *qcd)
 
113
 
 
114
 
 
115
static void CheckError(OSErr err, char *msg)
 
116
{
 
117
        if(err != noErr) printf("%s: %d\n", msg, err);
 
118
}
 
119
 
 
120
 
 
121
static OSErr QT_SaveCodecSettingsToScene(void)
172
122
{       
173
123
        QTAtomContainer         myContainer = NULL;
174
124
        ComponentResult         myErr = noErr;
175
125
        Ptr                                     myPtr;
176
126
        long                            mySize = 0;
177
127
 
178
 
        // check if current scene already has qtcodec settings, and erase them
 
128
        CodecInfo                       ci;
 
129
        char str[255];
 
130
 
 
131
        QuicktimeCodecData *qcd = G.scene->r.qtcodecdata;
 
132
 
 
133
        // check if current scene already has qtcodec settings, and clear them
179
134
        if (qcd) {
180
135
                free_qtcodecdata(qcd);
181
136
        } else {
183
138
        }
184
139
 
185
140
        // obtain all current codec settings
186
 
        SCSetInfo(qcdx->theComponent, scTemporalSettingsType,   &qcdx->gTemporalSettings);
187
 
        SCSetInfo(qcdx->theComponent, scSpatialSettingsType,    &qcdx->gSpatialSettings);
188
 
        SCSetInfo(qcdx->theComponent, scDataRateSettingsType,   &qcdx->aDataRateSetting);
 
141
        SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
 
142
        SCSetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
 
143
        SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
189
144
 
190
145
        // retreive codecdata from quicktime in a atomcontainer
191
 
        myErr = SCGetSettingsAsAtomContainer(qcdx->theComponent,  &myContainer);
 
146
        myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent,  &myContainer);
192
147
        if (myErr != noErr) {
193
148
                printf("Quicktime: SCGetSettingsAsAtomContainer failed\n"); 
194
149
                goto bail;
206
161
                qcd->cdParms = MEM_mallocN(mySize, "qt.cdParms");
207
162
                memcpy(qcd->cdParms, myPtr, mySize);
208
163
                qcd->cdSize = mySize;
209
 
                sprintf(qcd->qtcodecname, qtcdname);
 
164
 
 
165
                GetCodecInfo (&ci, qtdata->gSpatialSettings.codecType, 0);
 
166
                CopyPascalStringToC(ci.typeName, str);
 
167
                sprintf(qcd->qtcodecname, "Codec: %s", str);
210
168
        } else {
211
 
                printf("Quicktime: SaveExporterSettingsToMem failed\n"); 
 
169
                printf("Quicktime: QT_SaveCodecSettingsToScene failed\n"); 
212
170
        }
213
171
 
214
172
        QTUnlockContainer(myContainer);
220
178
        return((OSErr)myErr);
221
179
}
222
180
 
223
 
/************************************************************
224
 
*                                                           *
225
 
*    GetExporterSettingsFromMem                             *
226
 
*                                                           *
227
 
*************************************************************/
228
181
 
229
 
OSErr GetExporterSettingsFromMem (QuicktimeCodecData *qcd)
 
182
static OSErr QT_GetCodecSettingsFromScene(void)
230
183
{       
231
184
        Handle                          myHandle = NULL;
232
185
        ComponentResult         myErr = noErr;
233
186
//      CodecInfo ci;
234
187
//      char str[255];
235
188
 
 
189
        QuicktimeCodecData *qcd = G.scene->r.qtcodecdata;
 
190
 
236
191
        // if there is codecdata in the blendfile, convert it to a Quicktime handle 
237
192
        if (qcd) {
238
193
                myHandle = NewHandle(qcd->cdSize);
241
196
                
242
197
        // restore codecsettings to the quicktime component
243
198
        if(qcd->cdParms && qcd->cdSize) {
244
 
                myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qcdx->theComponent, (QTAtomContainer)myHandle);
 
199
                myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle);
245
200
                if (myErr != noErr) {
246
201
                        printf("Quicktime: SCSetSettingsFromAtomContainer failed\n"); 
247
202
                        goto bail;
248
203
                }
249
204
 
250
205
                // update runtime codecsettings for use with the codec dialog
251
 
                SCGetInfo(qcdx->theComponent, scDataRateSettingsType,   &qcdx->aDataRateSetting);
252
 
                SCGetInfo(qcdx->theComponent, scSpatialSettingsType,    &qcdx->gSpatialSettings);
253
 
                SCGetInfo(qcdx->theComponent, scTemporalSettingsType,   &qcdx->gTemporalSettings);
 
206
                SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
 
207
                SCGetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
 
208
                SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
254
209
 
255
 
//              GetCodecInfo (&ci, qcdx->gSpatialSettings.codecType, 0);
 
210
//              GetCodecInfo (&ci, qtdata->gSpatialSettings.codecType, 0);
256
211
//              CopyPascalStringToC(ci.typeName, str);
257
212
//              printf("restored Codec: %s\n", str);
258
213
        } else {
259
 
                printf("Quicktime: GetExporterSettingsFromMem failed\n"); 
 
214
                printf("Quicktime: QT_GetCodecSettingsFromScene failed\n"); 
260
215
        }
261
216
bail:
262
217
        if (myHandle != NULL)
266
221
}
267
222
 
268
223
 
269
 
/************************************************************
270
 
*                                                           *
271
 
*    CheckError(OSErr err, char *msg)                       *
272
 
*                                                           *
273
 
*    prints errors in console, doesnt interrupt Blender     *
274
 
*                                                           *
275
 
*************************************************************/
276
 
 
277
 
void CheckError(OSErr err, char *msg)
 
224
static OSErr QT_AddUserDataTextToMovie (Movie theMovie, char *theText, OSType theType)
278
225
{
279
 
        if(err != noErr) printf("%s: %d\n", msg, err);
 
226
        UserData                                        myUserData = NULL;
 
227
        Handle                                          myHandle = NULL;
 
228
        long                                            myLength = strlen(theText);
 
229
        OSErr                                           myErr = noErr;
 
230
 
 
231
        // get the movie's user data list
 
232
        myUserData = GetMovieUserData(theMovie);
 
233
        if (myUserData == NULL)
 
234
                return(paramErr);
 
235
        
 
236
        // copy the specified text into a new handle
 
237
        myHandle = NewHandleClear(myLength);
 
238
        if (myHandle == NULL)
 
239
                return(MemError());
 
240
 
 
241
        BlockMoveData(theText, *myHandle, myLength);
 
242
 
 
243
        // add the data to the movie's user data
 
244
        myErr = AddUserDataText(myUserData, myHandle, theType, 1, (short)GetScriptManagerVariable(smRegionCode));
 
245
 
 
246
        // clean up
 
247
        DisposeHandle(myHandle);
 
248
        return(myErr);
280
249
}
281
250
 
282
251
 
283
 
/************************************************************
284
 
*                                                           *
285
 
*    QT_CreateMyVideoTrack()                                *
286
 
*    QT_EndCreateMyVideoTrack()                             *
287
 
*                                                           *
288
 
*    Creates/finishes a video track for the QuickTime movie *
289
 
*                                                           *
290
 
*************************************************************/
291
 
 
292
252
static void QT_CreateMyVideoTrack(void)
293
253
{
294
254
        OSErr err = noErr;
295
255
        Rect trackFrame;
 
256
//      MatrixRecord myMatrix;
296
257
 
297
258
        trackFrame.top = 0;
298
259
        trackFrame.left = 0;
299
260
        trackFrame.bottom = R.recty;
300
261
        trackFrame.right = R.rectx;
301
262
        
302
 
        qte->theTrack = NewMovieTrack (qte->theMovie, 
 
263
        qtexport->theTrack = NewMovieTrack (qtexport->theMovie, 
303
264
                                                        FixRatio(trackFrame.right,1),
304
265
                                                        FixRatio(trackFrame.bottom,1), 
305
266
                                                        kNoVolume);
306
267
        CheckError( GetMoviesError(), "NewMovieTrack error" );
307
268
 
308
 
        qte->theMedia = NewTrackMedia (qte->theTrack,
 
269
//      SetIdentityMatrix(&myMatrix);
 
270
//      ScaleMatrix(&myMatrix, fixed1, Long2Fix(-1), 0, 0);
 
271
//      TranslateMatrix(&myMatrix, 0, Long2Fix(trackFrame.bottom));
 
272
//      SetMovieMatrix(qtexport->theMovie, &myMatrix);
 
273
 
 
274
        qtexport->theMedia = NewTrackMedia (qtexport->theTrack,
309
275
                                                        VideoMediaType,
310
 
                                                        qcdx->kVideoTimeScale,
 
276
                                                        qtdata->kVideoTimeScale,
311
277
                                                        nil,
312
278
                                                        0);
313
279
        CheckError( GetMoviesError(), "NewTrackMedia error" );
314
280
 
315
 
        err = BeginMediaEdits (qte->theMedia);
 
281
        err = BeginMediaEdits (qtexport->theMedia);
316
282
        CheckError( err, "BeginMediaEdits error" );
317
283
 
318
284
        QT_StartAddVideoSamplesToMedia (&trackFrame);
325
291
 
326
292
        QT_EndAddVideoSamplesToMedia ();
327
293
 
328
 
        err = EndMediaEdits (qte->theMedia);
 
294
        err = EndMediaEdits (qtexport->theMedia);
329
295
        CheckError( err, "EndMediaEdits error" );
330
296
 
331
 
        err = InsertMediaIntoTrack (qte->theTrack,
 
297
        err = InsertMediaIntoTrack (qtexport->theTrack,
332
298
                                                                kTrackStart,/* track start time */
333
299
                                                                kMediaStart,/* media start time */
334
 
                                                                GetMediaDuration (qte->theMedia),
 
300
                                                                GetMediaDuration (qtexport->theMedia),
335
301
                                                                fixed1);
336
302
        CheckError( err, "InsertMediaIntoTrack error" );
337
303
338
304
 
339
305
 
340
 
/************************************************************
341
 
*                                                           *
342
 
*    QT_StartAddVideoSamplesToMedia()                       *
343
 
*    QT_DoAddVideoSamplesToMedia()                          *
344
 
*    QT_EndAddVideoSamplesToMedia()                         *
345
 
*                                                           *
346
 
*    Creates video samples for the media in a track         *
347
 
*                                                           *
348
 
*************************************************************/
349
 
 
350
306
static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame)
351
307
{
352
308
        OSErr err = noErr;
353
309
 
354
 
        qte->ibuf = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
355
 
        qte->ibuf2 = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
 
310
        qtexport->ibuf = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
 
311
        qtexport->ibuf2 = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
356
312
 
357
 
        err = NewGWorldFromPtr( &qte->theGWorld,
 
313
        err = NewGWorldFromPtr( &qtexport->theGWorld,
358
314
                                                        k32ARGBPixelFormat,
359
315
                                                        trackFrame,
360
316
                                                        NULL, NULL, 0,
361
 
                                                        (unsigned char *)qte->ibuf->rect,
 
317
                                                        (unsigned char *)qtexport->ibuf->rect,
362
318
                                                        R.rectx * 4 );
363
319
        CheckError (err, "NewGWorldFromPtr error");
364
320
 
365
 
        qte->thePixMap = GetGWorldPixMap(qte->theGWorld);
366
 
        LockPixels(qte->thePixMap);
367
 
 
368
 
        SCDefaultPixMapSettings (qcdx->theComponent, qte->thePixMap, true);
369
 
 
370
 
        SCSetInfo(qcdx->theComponent, scTemporalSettingsType,   &qcdx->gTemporalSettings);
371
 
        SCSetInfo(qcdx->theComponent, scSpatialSettingsType,    &qcdx->gSpatialSettings);
372
 
        SCSetInfo(qcdx->theComponent, scDataRateSettingsType,   &qcdx->aDataRateSetting);
373
 
 
374
 
        err = SCCompressSequenceBegin(qcdx->theComponent, qte->thePixMap, NULL, &qte->anImageDescription); 
 
321
        qtexport->thePixMap = GetGWorldPixMap(qtexport->theGWorld);
 
322
        LockPixels(qtexport->thePixMap);
 
323
 
 
324
        SCDefaultPixMapSettings (qtdata->theComponent, qtexport->thePixMap, true);
 
325
 
 
326
        SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
 
327
        SCSetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
 
328
        SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
 
329
 
 
330
        err = SCCompressSequenceBegin(qtdata->theComponent, qtexport->thePixMap, NULL, &qtexport->anImageDescription); 
375
331
        CheckError (err, "SCCompressSequenceBegin error" );
376
332
}
377
333
 
381
337
        OSErr   err = noErr;
382
338
        Rect    imageRect;
383
339
 
384
 
        register int            index;
385
 
        register int            boxsize;
386
 
        register uint32_t       *readPos;
387
 
        register uint32_t       *changePos;
388
 
        Ptr                                     myPtr;
 
340
        int             index;
 
341
        int             boxsize;
 
342
        unsigned char *from, *to;
389
343
 
390
344
        short   syncFlag;
391
345
        long    dataSize;
392
346
        Handle  compressedData;
393
 
 
394
 
// copy and flip the renderdata
395
 
        if(qte->ibuf2) {
396
 
                memcpy(qte->ibuf2->rect, R.rectot, 4*R.rectx*R.recty);
397
 
                IMB_flipy(qte->ibuf2);
398
 
        }
399
 
 
400
 
//get pointers to parse bitmapdata
401
 
        myPtr = GetPixBaseAddr(qte->thePixMap);
402
 
        imageRect = (**qte->thePixMap).bounds;
403
 
 
 
347
        Ptr             myPtr;
 
348
 
 
349
 
 
350
        //copy and flip renderdata
 
351
        memcpy(qtexport->ibuf2->rect, R.rectot, 4*R.rectx*R.recty);
 
352
        IMB_flipy(qtexport->ibuf2);
 
353
 
 
354
        //get pointers to parse bitmapdata
 
355
        myPtr = GetPixBaseAddr(qtexport->thePixMap);
 
356
        imageRect = (**qtexport->thePixMap).bounds;
 
357
 
 
358
        from = (unsigned char *) qtexport->ibuf2->rect;
 
359
        to = (unsigned char *) myPtr;
 
360
 
 
361
        //parse RGBA bitmap into Quicktime's ARGB GWorld
404
362
        boxsize = R.rectx * R.recty;
405
 
        readPos = (uint32_t *) qte->ibuf2->rect;
406
 
        changePos = (uint32_t *) myPtr;
407
 
 
408
 
#ifdef __APPLE__
409
 
// Swap alpha byte to the end, so ARGB become RGBA; note this is big endian-centric.
410
 
        for( index = 0; index < boxsize; index++, changePos++, readPos++ )
411
 
                *( changePos ) = ( ( *readPos & 0xFFFFFFFF ) >> 8 ) |
412
 
                         ( ( *readPos << 24 ) & 0xFF );
413
 
#endif
414
 
 
415
 
#ifdef _WIN32
416
 
// poked around a little... this seems to work for windows, dunno if it's legal
417
 
        for( index = 0; index < boxsize; index++, changePos++, readPos++ )
418
 
                *( changePos ) = ( ( *readPos & 0xFFFFFFFF ) << 8 ) |
419
 
                                                 ( ( *readPos >> 24 ) & 0xFF ); // & ( ( *readPos << 8 ) & 0xFF );
420
 
#endif
421
 
 
422
 
        err = SCCompressSequenceFrame(qcdx->theComponent,
423
 
                qte->thePixMap,
 
363
        for( index = 0; index < boxsize; index++) {
 
364
                to[0] = from[3];
 
365
                to[1] = from[0];
 
366
                to[2] = from[1];
 
367
                to[3] = from[2];
 
368
                to +=4, from += 4;
 
369
        }
 
370
 
 
371
        err = SCCompressSequenceFrame(qtdata->theComponent,
 
372
                qtexport->thePixMap,
424
373
                &imageRect,
425
374
                &compressedData,
426
375
                &dataSize,
427
376
                &syncFlag);
428
377
        CheckError(err, "SCCompressSequenceFrame error");
429
378
 
430
 
        err = AddMediaSample(qte->theMedia,
 
379
        err = AddMediaSample(qtexport->theMedia,
431
380
                compressedData,
432
381
                0,
433
382
                dataSize,
434
 
                qcdx->duration,
435
 
                (SampleDescriptionHandle)qte->anImageDescription,
 
383
                qtdata->duration,
 
384
                (SampleDescriptionHandle)qtexport->anImageDescription,
436
385
                1,
437
386
                syncFlag,
438
387
                NULL);
444
393
 
445
394
static void QT_EndAddVideoSamplesToMedia (void)
446
395
{
447
 
        SCCompressSequenceEnd(qcdx->theComponent);
448
 
 
449
 
        UnlockPixels(qte->thePixMap);
450
 
        if (qte->theGWorld)     DisposeGWorld (qte->theGWorld);
451
 
        if (qte->ibuf)          IMB_freeImBuf(qte->ibuf);
452
 
        if (qte->ibuf2)         IMB_freeImBuf(qte->ibuf2);
 
396
        SCCompressSequenceEnd(qtdata->theComponent);
 
397
 
 
398
        UnlockPixels(qtexport->thePixMap);
 
399
        if (qtexport->theGWorld)
 
400
                DisposeGWorld (qtexport->theGWorld);
 
401
 
 
402
        if (qtexport->ibuf)
 
403
                IMB_freeImBuf(qtexport->ibuf);
 
404
 
 
405
        if (qtexport->ibuf2)
 
406
                IMB_freeImBuf(qtexport->ibuf2);
453
407
454
408
 
455
409
 
456
 
/************************************************************
457
 
*                                                           *
458
 
*    makeqtstring (char *string)                            *
459
 
*                                                           *
460
 
*    Function to generate output filename                   *
461
 
*                                                           *
462
 
*************************************************************/
463
 
 
464
410
void makeqtstring (char *string) {
465
411
        char txt[64];
466
412
 
471
417
 
472
418
        RE_make_existing_file(string);
473
419
 
474
 
        if (strcasecmp(string + strlen(string) - 4, ".mov")) {
 
420
        if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) {
475
421
                sprintf(txt, "%04d_%04d.mov", (G.scene->r.sfra) , (G.scene->r.efra) );
476
422
                strcat(string, txt);
477
423
        }
478
424
}
479
425
 
480
426
 
481
 
/************************************************************
482
 
*                                                           *
483
 
*    start_qt(void)                                         *
484
 
*    append_qt(int frame)                                   *
485
 
*    end_qt(int frame)                                      *
486
 
*                                                           *
487
 
*    Quicktime Export functions for Blender's initrender.c  *
488
 
*                                                           *
489
 
************************************************************/
490
 
 
491
427
void start_qt(void) {
492
428
        OSErr err = noErr;
493
429
 
497
433
#ifdef __APPLE__
498
434
        int             myFile;
499
435
        FSRef   myRef;
 
436
#else
 
437
        char    *qtname;
500
438
#endif
501
439
 
502
 
        if(qte == NULL) qte = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
 
440
        if(qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
503
441
 
504
 
        if(qcdx) {
505
 
                if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
506
 
                free_qtcodecdataExt();
 
442
        if(qtdata) {
 
443
                if(qtdata->theComponent) CloseComponent(qtdata->theComponent);
 
444
                free_qtcomponentdata();
507
445
        }
508
446
 
509
 
        qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");
 
447
        qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeCodecDataExt");
510
448
 
511
449
        if(G.scene->r.qtcodecdata == NULL && G.scene->r.qtcodecdata->cdParms == NULL) {
512
450
                get_qtcodec_settings();
513
451
        } else {
514
 
                qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
 
452
                qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
515
453
 
516
 
//              printf("getting from blend\n");
517
 
                GetExporterSettingsFromMem (G.scene->r.qtcodecdata);
 
454
                QT_GetCodecSettingsFromScene();
518
455
                check_renderbutton_framerate();
519
456
        }
520
457
        
522
459
                sframe = (G.scene->r.sfra);
523
460
 
524
461
                makeqtstring(name);
 
462
 
 
463
#ifdef __APPLE__
525
464
                sprintf(theFullPath, "%s", name);
526
465
 
527
 
#ifdef __APPLE__
528
466
                /* hack: create an empty file to make FSPathMakeRef() happy */
529
467
                myFile = open(theFullPath, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRUSR|S_IWUSR);
530
468
                if (myFile < 0) {
534
472
                close(myFile);
535
473
                err = FSPathMakeRef(theFullPath, &myRef, 0);
536
474
                CheckError(err, "FsPathMakeRef error");
537
 
                err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qte->theSpec, NULL);
 
475
                err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL);
538
476
                CheckError(err, "FsGetCatalogInfoRef error");
539
 
#else
540
 
                CopyCStringToPascal(theFullPath, qte->qtfilename);
541
 
                err = FSMakeFSSpec(0, 0L, qte->qtfilename, &qte->theSpec);
 
477
#endif
 
478
#ifdef _WIN32
 
479
                qtname = get_valid_qtname(name);
 
480
                sprintf(theFullPath, "%s", qtname);
 
481
                strcpy(name, qtname);
 
482
                MEM_freeN(qtname);
 
483
                
 
484
                CopyCStringToPascal(theFullPath, qtexport->qtfilename);
 
485
                err = FSMakeFSSpec(0, 0L, qtexport->qtfilename, &qtexport->theSpec);
542
486
#endif
543
487
 
544
 
                err = CreateMovieFile (&qte->theSpec, 
 
488
                err = CreateMovieFile (&qtexport->theSpec, 
545
489
                                                        kMyCreatorType,
546
490
                                                        smCurrentScript, 
547
491
                                                        createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
548
 
                                                        &qte->resRefNum, 
549
 
                                                        &qte->theMovie );
 
492
                                                        &qtexport->resRefNum, 
 
493
                                                        &qtexport->theMovie );
550
494
                CheckError(err, "CreateMovieFile error");
551
495
 
552
 
                printf("Created QuickTime movie: %s\n", name);
 
496
                if(err != noErr) {
 
497
                        G.afbreek = 1;
 
498
                        error("Unable to create Quicktime movie: %s\n", name);
 
499
                } else {
 
500
                        printf("Created QuickTime movie: %s\n", name);
553
501
 
554
 
                QT_CreateMyVideoTrack();
 
502
                        QT_CreateMyVideoTrack();
 
503
                }
555
504
        }
556
505
}
557
506
 
560
509
        QT_DoAddVideoSamplesToMedia(frame);
561
510
}
562
511
 
 
512
 
563
513
void end_qt(void) {
564
514
        OSErr err = noErr;
565
 
 
566
 
        if(qte->theMovie) {
567
 
                QT_EndCreateMyVideoTrack ();
568
 
 
569
 
                qte->resId = movieInDataForkResID;
570
 
                err = AddMovieResource (qte->theMovie, qte->resRefNum, &qte->resId, qte->qtfilename);
 
515
        short resId = movieInDataForkResID;
 
516
 
 
517
        if(qtexport->theMovie) {
 
518
                QT_EndCreateMyVideoTrack();
 
519
 
 
520
                err = AddMovieResource (qtexport->theMovie, qtexport->resRefNum, &resId, qtexport->qtfilename);
571
521
                CheckError(err, "AddMovieResource error");
572
522
 
573
 
                if (qte->resRefNum)     CloseMovieFile (qte->resRefNum);
574
 
 
575
 
                DisposeMovie (qte->theMovie);
576
 
        }
577
 
 
578
 
        if(qte) {
579
 
                MEM_freeN(qte);
580
 
                qte = NULL;
581
 
        }
582
 
};
583
 
 
584
 
 
585
 
/************************************************************
586
 
*                                                           *
587
 
*    free_qtcodecdataExt(void)                              *
588
 
*                                                           *
589
 
*    Function to release codec memory, since it remains     *
590
 
*    resident after allocation.                             *
591
 
*                                                           *
592
 
*************************************************************/
593
 
 
594
 
void free_qtcodecdataExt(void) {
595
 
        if(qcdx) {
596
 
                if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
597
 
                MEM_freeN(qcdx);
598
 
                qcdx = NULL;
599
 
        }
600
 
}
601
 
 
602
 
 
603
 
/************************************************************
604
 
*                                                           *
605
 
*    check_renderbutton_framerate ( void )                  *
606
 
*                                                           *
607
 
*    To keep float framerates consistent between the codec  *
608
 
*    dialog and frs/sec button.                             *
609
 
*                                                           *
610
 
*************************************************************/
 
523
                err = QT_AddUserDataTextToMovie(qtexport->theMovie, "Made with Blender", kUserDataTextInformation);
 
524
                CheckError(err, "AddUserDataTextToMovie error");
 
525
 
 
526
                err = UpdateMovieResource(qtexport->theMovie, qtexport->resRefNum, resId, qtexport->qtfilename);
 
527
                CheckError(err, "UpdateMovieResource error");
 
528
 
 
529
                if(qtexport->resRefNum) CloseMovieFile(qtexport->resRefNum);
 
530
 
 
531
                DisposeMovie(qtexport->theMovie);
 
532
 
 
533
                printf("Finished QuickTime movie.\n");
 
534
        }
 
535
 
 
536
        if(qtexport) {
 
537
                MEM_freeN(qtexport);
 
538
                qtexport = NULL;
 
539
        }
 
540
}
 
541
 
 
542
 
 
543
void free_qtcomponentdata(void) {
 
544
        if(qtdata) {
 
545
                if(qtdata->theComponent) CloseComponent(qtdata->theComponent);
 
546
                MEM_freeN(qtdata);
 
547
                qtdata = NULL;
 
548
        }
 
549
}
 
550
 
611
551
 
612
552
static void check_renderbutton_framerate(void) {
 
553
        // to keep float framerates consistent between the codec dialog and frs/sec button.
613
554
        OSErr   err;    
614
555
 
615
 
        err = SCGetInfo(qcdx->theComponent, scTemporalSettingsType,     &qcdx->gTemporalSettings);
 
556
        err = SCGetInfo(qtdata->theComponent, scTemporalSettingsType,   &qtdata->gTemporalSettings);
616
557
        CheckError(err, "SCGetInfo fr error");
617
558
 
618
559
        if( (G.scene->r.frs_sec == 24 || G.scene->r.frs_sec == 30 || G.scene->r.frs_sec == 60) &&
619
 
                (qcdx->gTemporalSettings.frameRate == 1571553 ||
620
 
                 qcdx->gTemporalSettings.frameRate == 1964113 ||
621
 
                 qcdx->gTemporalSettings.frameRate == 3928227)) {;} else
622
 
        qcdx->gTemporalSettings.frameRate = G.scene->r.frs_sec << 16;
 
560
                (qtdata->gTemporalSettings.frameRate == 1571553 ||
 
561
                 qtdata->gTemporalSettings.frameRate == 1964113 ||
 
562
                 qtdata->gTemporalSettings.frameRate == 3928227)) {;} else
 
563
        qtdata->gTemporalSettings.frameRate = G.scene->r.frs_sec << 16;
623
564
 
624
 
        err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType,     &qcdx->gTemporalSettings);
 
565
        err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType,   &qtdata->gTemporalSettings);
625
566
        CheckError( err, "SCSetInfo error" );
626
567
 
627
 
        if(qcdx->gTemporalSettings.frameRate == 1571553) {                      // 23.98 fps
628
 
                qcdx->kVideoTimeScale = 2398;
629
 
                qcdx->duration = 100;
630
 
        } else if (qcdx->gTemporalSettings.frameRate == 1964113) {      // 29.97 fps
631
 
                qcdx->kVideoTimeScale = 2997;
632
 
                qcdx->duration = 100;
633
 
        } else if (qcdx->gTemporalSettings.frameRate == 3928227) {      // 59.94 fps
634
 
                qcdx->kVideoTimeScale = 5994;
635
 
                qcdx->duration = 100;
 
568
        if(qtdata->gTemporalSettings.frameRate == 1571553) {                    // 23.98 fps
 
569
                qtdata->kVideoTimeScale = 2398;
 
570
                qtdata->duration = 100;
 
571
        } else if (qtdata->gTemporalSettings.frameRate == 1964113) {    // 29.97 fps
 
572
                qtdata->kVideoTimeScale = 2997;
 
573
                qtdata->duration = 100;
 
574
        } else if (qtdata->gTemporalSettings.frameRate == 3928227) {    // 59.94 fps
 
575
                qtdata->kVideoTimeScale = 5994;
 
576
                qtdata->duration = 100;
636
577
        } else {
637
 
                qcdx->kVideoTimeScale = (qcdx->gTemporalSettings.frameRate >> 16) * 100;
638
 
                qcdx->duration = 100;
 
578
                qtdata->kVideoTimeScale = (qtdata->gTemporalSettings.frameRate >> 16) * 100;
 
579
                qtdata->duration = 100;
639
580
        }
640
581
}
641
582
 
642
 
/********************************************************************
643
 
*                                                                   *
644
 
*    get_qtcodec_settings()                                         *
645
 
*                                                                   *
646
 
*    Displays Codec Dialog and retrieves Quicktime Codec settings.  *
647
 
*                                                                   *
648
 
********************************************************************/
649
583
 
650
584
int get_qtcodec_settings(void) 
651
585
{
652
586
        OSErr   err = noErr;
653
 
        CodecInfo ci;
654
 
        char str[255];
655
587
 
656
588
        // erase any existing codecsetting
657
 
        if(qcdx) {
658
 
                if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
659
 
                free_qtcodecdataExt();
 
589
        if(qtdata) {
 
590
                if(qtdata->theComponent) CloseComponent(qtdata->theComponent);
 
591
                free_qtcomponentdata();
660
592
        }
661
593
 
662
594
        // allocate new
663
 
        qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");
664
 
        qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
 
595
        qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData");
 
596
        qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
665
597
 
666
598
        // get previous selected codecsetting, if any 
667
599
        if(G.scene->r.qtcodecdata && G.scene->r.qtcodecdata->cdParms) {
668
 
//              printf("getting from MEM\n");
669
 
                GetExporterSettingsFromMem (G.scene->r.qtcodecdata);
 
600
                QT_GetCodecSettingsFromScene();
670
601
                check_renderbutton_framerate();
671
602
        } else {
672
 
 
673
 
        // configure the standard image compression dialog box
674
 
        // set some default settings
675
 
//              qcdx->gSpatialSettings.codecType = nil;     
676
 
                qcdx->gSpatialSettings.codec = anyCodec;         
677
 
//              qcdx->gSpatialSettings.depth;         
678
 
                qcdx->gSpatialSettings.spatialQuality = codecMaxQuality;
679
 
 
680
 
                qcdx->gTemporalSettings.temporalQuality = codecMaxQuality;
681
 
//              qcdx->gTemporalSettings.frameRate;      
682
 
                qcdx->gTemporalSettings.keyFrameRate = 25;   
683
 
 
684
 
                qcdx->aDataRateSetting.dataRate = 90 * 1024;          
685
 
//              qcdx->aDataRateSetting.frameDuration;     
686
 
//              qcdx->aDataRateSetting.minSpatialQuality; 
687
 
//              qcdx->aDataRateSetting.minTemporalQuality;
688
 
 
689
 
                err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType,     &qcdx->gTemporalSettings);
 
603
                // configure the standard image compression dialog box
 
604
                // set some default settings
 
605
                qtdata->gSpatialSettings.codec = anyCodec;         
 
606
                qtdata->gSpatialSettings.spatialQuality = codecMaxQuality;
 
607
                qtdata->gTemporalSettings.temporalQuality = codecMaxQuality;
 
608
                qtdata->gTemporalSettings.keyFrameRate = 25;   
 
609
                qtdata->aDataRateSetting.dataRate = 90 * 1024;          
 
610
 
 
611
                err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType,   &qtdata->gTemporalSettings);
690
612
                CheckError(err, "SCSetInfo1 error");
691
 
                err = SCSetInfo(qcdx->theComponent, scSpatialSettingsType,      &qcdx->gSpatialSettings);
 
613
                err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType,    &qtdata->gSpatialSettings);
692
614
                CheckError(err, "SCSetInfo2 error");
693
 
                err = SCSetInfo(qcdx->theComponent, scDataRateSettingsType,     &qcdx->aDataRateSetting);
 
615
                err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType,   &qtdata->aDataRateSetting);
694
616
                CheckError(err, "SCSetInfo3 error");
695
617
        }
696
618
 
697
619
        check_renderbutton_framerate();
698
620
 
699
621
        // put up the dialog box
700
 
        err = SCRequestSequenceSettings(qcdx->theComponent);
 
622
        err = SCRequestSequenceSettings(qtdata->theComponent);
701
623
 
702
624
        if (err == scUserCancelled) {
703
625
                G.afbreek = 1;
705
627
        }
706
628
 
707
629
        // get user selected data
708
 
        SCGetInfo(qcdx->theComponent, scTemporalSettingsType,   &qcdx->gTemporalSettings);
709
 
        SCGetInfo(qcdx->theComponent, scSpatialSettingsType,    &qcdx->gSpatialSettings);
710
 
        SCGetInfo(qcdx->theComponent, scDataRateSettingsType,   &qcdx->aDataRateSetting);
711
 
 
712
 
        GetCodecInfo (&ci, qcdx->gSpatialSettings.codecType, 0);
713
 
        CopyPascalStringToC(ci.typeName, str);
714
 
        sprintf(qtcdname,"Codec: %s", str);
715
 
 
716
 
        SaveExporterSettingsToMem(G.scene->r.qtcodecdata);
 
630
        SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
 
631
        SCGetInfo(qtdata->theComponent, scSpatialSettingsType,  &qtdata->gSpatialSettings);
 
632
        SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting);
 
633
 
 
634
        QT_SaveCodecSettingsToScene();
717
635
 
718
636
        // framerate jugglin'
719
 
        if(qcdx->gTemporalSettings.frameRate == 1571553) {                      // 23.98 fps
720
 
                qcdx->kVideoTimeScale = 2398;
721
 
                qcdx->duration = 100;
 
637
        if(qtdata->gTemporalSettings.frameRate == 1571553) {                    // 23.98 fps
 
638
                qtdata->kVideoTimeScale = 2398;
 
639
                qtdata->duration = 100;
722
640
 
723
641
                G.scene->r.frs_sec = 24;
724
 
        } else if (qcdx->gTemporalSettings.frameRate == 1964113) {      // 29.97 fps
725
 
                qcdx->kVideoTimeScale = 2997;
726
 
                qcdx->duration = 100;
 
642
        } else if (qtdata->gTemporalSettings.frameRate == 1964113) {    // 29.97 fps
 
643
                qtdata->kVideoTimeScale = 2997;
 
644
                qtdata->duration = 100;
727
645
 
728
646
                G.scene->r.frs_sec = 30;
729
 
        } else if (qcdx->gTemporalSettings.frameRate == 3928227) {      // 59.94 fps
730
 
                qcdx->kVideoTimeScale = 5994;
731
 
                qcdx->duration = 100;
 
647
        } else if (qtdata->gTemporalSettings.frameRate == 3928227) {    // 59.94 fps
 
648
                qtdata->kVideoTimeScale = 5994;
 
649
                qtdata->duration = 100;
732
650
 
733
651
                G.scene->r.frs_sec = 60;
734
652
        } else {
735
 
                qcdx->kVideoTimeScale = 600;
736
 
                qcdx->duration = qcdx->kVideoTimeScale / (qcdx->gTemporalSettings.frameRate / 65536);
 
653
                qtdata->kVideoTimeScale = 600;
 
654
                qtdata->duration = qtdata->kVideoTimeScale / (qtdata->gTemporalSettings.frameRate / 65536);
737
655
 
738
 
                G.scene->r.frs_sec = (qcdx->gTemporalSettings.frameRate / 65536);
 
656
                G.scene->r.frs_sec = (qtdata->gTemporalSettings.frameRate / 65536);
739
657
        }
740
658
 
741
659
        return 1;
742
660
}
743
661
 
744
662
#endif /* _WIN32 || __APPLE__ */
745
 
 
746
663
#endif /* WITH_QUICKTIME */
747
664