Logo Search packages:      
Sourcecode: blender version File versions

quicktime_export.c

/**
 * $Id: quicktime_export.c,v 1.14 2004/12/10 12:55:53 phase Exp $
 *
 * quicktime_export.c
 *
 * Code to create QuickTime Movies with Blender
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *
 * The Original Code is written by Rob Haarsma (phase)
 *
 * Contributor(s): Stefan Gartner (sgefant)
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
/*    
DONE:

*  structurize file & compression data

*  fix 23.98, 29.97, 59.94 framerates
*  fix framerate button
*  fix mac compatibility

*  fix fallthrough to codecselector  // buttons.c
*  fix playback qt movie             // playanim.c
*  fix setting fps thru blenderbutton as well as codec dialog
*  fix saving of compressionsettings

*/

#ifdef WITH_QUICKTIME

#if defined(_WIN32) || defined(__APPLE__)

/************************************************************
*                                                           *
*    INCLUDE FILES                                          *
*                                                           *
*************************************************************/

#include "BKE_global.h"
#include "BKE_scene.h"
#include "BLI_blenlib.h"
#include "BIF_toolbox.h"      /* error() */
#include "BLO_sys_types.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "MEM_guardedalloc.h"
#include "render.h"

#include "quicktime_import.h"
#include "quicktime_export.h"

#ifdef _WIN32
#include <FixMath.h>
#include <QTML.h>
#include <TextUtils.h> 
#include <Movies.h>
#include <QuicktimeComponents.h>
#include <MoviesFormat.h>
#endif /* _WIN32 */

#ifdef __APPLE__
/* evil */
#ifndef __AIFF__
#define __AIFF__
#endif
#include <QuickTime/Movies.h>
#include <QuickTime/QuicktimeComponents.h>
#include <fcntl.h> /* open() */
#include <unistd.h> /* close() */
#include <sys/stat.h> /* file permissions */
#endif /* __APPLE__ */


/************************************************************
*                                                           *
*    FUNCTION PROTOTYPES                                    *
*                                                           *
*************************************************************/

static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame);
static void QT_DoAddVideoSamplesToMedia (int frame);
static void QT_EndAddVideoSamplesToMedia (void);
static void QT_CreateMyVideoTrack (void);
static void QT_EndCreateMyVideoTrack (void);

static void check_renderbutton_framerate(void);

/************************************************************
*                                                           *
*    STRUCTS                                                *
*                                                           *
*************************************************************/

typedef struct _QuicktimeExport {

      FSSpec            theSpec;
      short       resRefNum;
      short       resId;
      short       movieResId;
      Str255            qtfilename;

      Media       theMedia;
      Movie       theMovie;
      Track       theTrack;

      GWorldPtr   theGWorld;
      PixMapHandle      thePixMap;

      ImageDescription  **anImageDescription;
      ImageSequence           anImageSequence;

      ImBuf       *ibuf;      //for Qtime's Gworld
      ImBuf       *ibuf2;     //copy of renderdata, to be Y-flipped

} QuicktimeExport;

typedef struct _QuicktimeCodecDataExt {

      ComponentInstance theComponent;
      SCTemporalSettings  gTemporalSettings;
      SCSpatialSettings   gSpatialSettings;
      SCDataRateSettings  aDataRateSetting;
      TimeValue               duration;
      long                    kVideoTimeScale;

} QuicktimeCodecDataExt;      //qtopts


struct _QuicktimeExport *qte;
struct _QuicktimeCodecDataExt *qcdx;

/************************************************************
*                                                           *
*    VARIABLES                                              *
*                                                           *
*************************************************************/

#define     kMyCreatorType    FOUR_CHAR_CODE('TVOD')
#define     kPixelDepth       32    /* use 32-bit depth */
#define     kTrackStart       0
#define     kMediaStart       0

static int  sframe;
static char qtcdname[128];


/************************************************************
*                                                           *
*    SaveExporterSettingsToMem                              *
*                                                           *
*************************************************************/

OSErr SaveExporterSettingsToMem (QuicktimeCodecData *qcd)
{     
      QTAtomContainer         myContainer = NULL;
      ComponentResult         myErr = noErr;
      Ptr                           myPtr;
      long                    mySize = 0;

      // check if current scene already has qtcodec settings, and erase them
      if (qcd) {
            free_qtcodecdata(qcd);
      } else {
            qcd = G.scene->r.qtcodecdata = MEM_callocN(sizeof(QuicktimeCodecData), "QuicktimeCodecData");
      }

      // obtain all current codec settings
      SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
      SCSetInfo(qcdx->theComponent, scSpatialSettingsType,  &qcdx->gSpatialSettings);
      SCSetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);

      // retreive codecdata from quicktime in a atomcontainer
      myErr = SCGetSettingsAsAtomContainer(qcdx->theComponent,  &myContainer);
      if (myErr != noErr) {
            printf("Quicktime: SCGetSettingsAsAtomContainer failed\n"); 
            goto bail;
      }

      // get the size of the atomcontainer
      mySize = GetHandleSize((Handle)myContainer);

      // lock and convert the atomcontainer to a *valid* pointer
      QTLockContainer(myContainer);
      myPtr = *(Handle)myContainer;

      // copy the Quicktime data into the blender qtcodecdata struct
      if (myPtr) {
            qcd->cdParms = MEM_mallocN(mySize, "qt.cdParms");
            memcpy(qcd->cdParms, myPtr, mySize);
            qcd->cdSize = mySize;
            sprintf(qcd->qtcodecname, qtcdname);
      } else {
            printf("Quicktime: SaveExporterSettingsToMem failed\n"); 
      }

      QTUnlockContainer(myContainer);

bail:
      if (myContainer != NULL)
            QTDisposeAtomContainer(myContainer);
            
      return((OSErr)myErr);
}

/************************************************************
*                                                           *
*    GetExporterSettingsFromMem                             *
*                                                           *
*************************************************************/

OSErr GetExporterSettingsFromMem (QuicktimeCodecData *qcd)
{     
      Handle                        myHandle = NULL;
      ComponentResult         myErr = noErr;
//    CodecInfo ci;
//    char str[255];

      // if there is codecdata in the blendfile, convert it to a Quicktime handle 
      if (qcd) {
            myHandle = NewHandle(qcd->cdSize);
            PtrToHand( qcd->cdParms, &myHandle, qcd->cdSize);
      }
            
      // restore codecsettings to the quicktime component
      if(qcd->cdParms && qcd->cdSize) {
            myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qcdx->theComponent, (QTAtomContainer)myHandle);
            if (myErr != noErr) {
                  printf("Quicktime: SCSetSettingsFromAtomContainer failed\n"); 
                  goto bail;
            }

            // update runtime codecsettings for use with the codec dialog
            SCGetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);
            SCGetInfo(qcdx->theComponent, scSpatialSettingsType,  &qcdx->gSpatialSettings);
            SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);

//          GetCodecInfo (&ci, qcdx->gSpatialSettings.codecType, 0);
//          CopyPascalStringToC(ci.typeName, str);
//          printf("restored Codec: %s\n", str);
      } else {
            printf("Quicktime: GetExporterSettingsFromMem failed\n"); 
      }
bail:
      if (myHandle != NULL)
            DisposeHandle(myHandle);
            
      return((OSErr)myErr);
}


/************************************************************
*                                                           *
*    CheckError(OSErr err, char *msg)                       *
*                                                           *
*    prints errors in console, doesnt interrupt Blender     *
*                                                           *
*************************************************************/

void CheckError(OSErr err, char *msg)
{
      if(err != noErr) printf("%s: %d\n", msg, err);
}


/************************************************************
*                                                           *
*    QT_CreateMyVideoTrack()                                *
*    QT_EndCreateMyVideoTrack()                             *
*                                                           *
*    Creates/finishes a video track for the QuickTime movie *
*                                                           *
*************************************************************/

static void QT_CreateMyVideoTrack(void)
{
      OSErr err = noErr;
      Rect trackFrame;

      trackFrame.top = 0;
      trackFrame.left = 0;
      trackFrame.bottom = R.recty;
      trackFrame.right = R.rectx;
      
      qte->theTrack = NewMovieTrack (qte->theMovie, 
                                          FixRatio(trackFrame.right,1),
                                          FixRatio(trackFrame.bottom,1), 
                                          kNoVolume);
      CheckError( GetMoviesError(), "NewMovieTrack error" );

      qte->theMedia = NewTrackMedia (qte->theTrack,
                                          VideoMediaType,
                                          qcdx->kVideoTimeScale,
                                          nil,
                                          0);
      CheckError( GetMoviesError(), "NewTrackMedia error" );

      err = BeginMediaEdits (qte->theMedia);
      CheckError( err, "BeginMediaEdits error" );

      QT_StartAddVideoSamplesToMedia (&trackFrame);
} 


static void QT_EndCreateMyVideoTrack(void)
{
      OSErr err = noErr;

      QT_EndAddVideoSamplesToMedia ();

      err = EndMediaEdits (qte->theMedia);
      CheckError( err, "EndMediaEdits error" );

      err = InsertMediaIntoTrack (qte->theTrack,
                                                kTrackStart,/* track start time */
                                                kMediaStart,/* media start time */
                                                GetMediaDuration (qte->theMedia),
                                                fixed1);
      CheckError( err, "InsertMediaIntoTrack error" );
} 


/************************************************************
*                                                           *
*    QT_StartAddVideoSamplesToMedia()                       *
*    QT_DoAddVideoSamplesToMedia()                          *
*    QT_EndAddVideoSamplesToMedia()                         *
*                                                           *
*    Creates video samples for the media in a track         *
*                                                           *
*************************************************************/

static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame)
{
      OSErr err = noErr;

      qte->ibuf = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);
      qte->ibuf2 = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0);

      err = NewGWorldFromPtr( &qte->theGWorld,
                                          k32ARGBPixelFormat,
                                          trackFrame,
                                          NULL, NULL, 0,
                                          (unsigned char *)qte->ibuf->rect,
                                          R.rectx * 4 );
      CheckError (err, "NewGWorldFromPtr error");

      qte->thePixMap = GetGWorldPixMap(qte->theGWorld);
      LockPixels(qte->thePixMap);

      SCDefaultPixMapSettings (qcdx->theComponent, qte->thePixMap, true);

      SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
      SCSetInfo(qcdx->theComponent, scSpatialSettingsType,  &qcdx->gSpatialSettings);
      SCSetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);

      err = SCCompressSequenceBegin(qcdx->theComponent, qte->thePixMap, NULL, &qte->anImageDescription); 
      CheckError (err, "SCCompressSequenceBegin error" );
}


static void QT_DoAddVideoSamplesToMedia (int frame)
{
      OSErr err = noErr;
      Rect  imageRect;

      register int            index;
      register int            boxsize;
      register uint32_t *readPos;
      register uint32_t *changePos;
      Ptr                           myPtr;

      short syncFlag;
      long  dataSize;
      Handle      compressedData;

// copy and flip the renderdata
      if(qte->ibuf2) {
            memcpy(qte->ibuf2->rect, R.rectot, 4*R.rectx*R.recty);
            IMB_flipy(qte->ibuf2);
      }

//get pointers to parse bitmapdata
      myPtr = GetPixBaseAddr(qte->thePixMap);
      imageRect = (**qte->thePixMap).bounds;

      boxsize = R.rectx * R.recty;
      readPos = (uint32_t *) qte->ibuf2->rect;
      changePos = (uint32_t *) myPtr;

#ifdef __APPLE__
// Swap alpha byte to the end, so ARGB become RGBA; note this is big endian-centric.
      for( index = 0; index < boxsize; index++, changePos++, readPos++ )
            *( changePos ) = ( ( *readPos & 0xFFFFFFFF ) >> 8 ) |
                         ( ( *readPos << 24 ) & 0xFF );
#endif

#ifdef _WIN32
// poked around a little... this seems to work for windows, dunno if it's legal
      for( index = 0; index < boxsize; index++, changePos++, readPos++ )
            *( changePos ) = ( ( *readPos & 0xFFFFFFFF ) << 8 ) |
                                     ( ( *readPos >> 24 ) & 0xFF ); // & ( ( *readPos << 8 ) & 0xFF );
#endif

      err = SCCompressSequenceFrame(qcdx->theComponent,
            qte->thePixMap,
            &imageRect,
            &compressedData,
            &dataSize,
            &syncFlag);
      CheckError(err, "SCCompressSequenceFrame error");

      err = AddMediaSample(qte->theMedia,
            compressedData,
            0,
            dataSize,
            qcdx->duration,
            (SampleDescriptionHandle)qte->anImageDescription,
            1,
            syncFlag,
            NULL);
      CheckError(err, "AddMediaSample error");

      printf ("added frame %3d (frame %3d in movie): ", frame, frame-sframe);
}


static void QT_EndAddVideoSamplesToMedia (void)
{
      SCCompressSequenceEnd(qcdx->theComponent);

      UnlockPixels(qte->thePixMap);
      if (qte->theGWorld)     DisposeGWorld (qte->theGWorld);
      if (qte->ibuf)          IMB_freeImBuf(qte->ibuf);
      if (qte->ibuf2)         IMB_freeImBuf(qte->ibuf2);
} 


/************************************************************
*                                                           *
*    makeqtstring (char *string)                            *
*                                                           *
*    Function to generate output filename                   *
*                                                           *
*************************************************************/

void makeqtstring (char *string) {
      char txt[64];

      if (string==0) return;

      strcpy(string, G.scene->r.pic);
      BLI_convertstringcode(string, G.sce, G.scene->r.cfra);

      RE_make_existing_file(string);

      if (strcasecmp(string + strlen(string) - 4, ".mov")) {
            sprintf(txt, "%04d_%04d.mov", (G.scene->r.sfra) , (G.scene->r.efra) );
            strcat(string, txt);
      }
}


/************************************************************
*                                                           *
*    start_qt(void)                                         *
*    append_qt(int frame)                                   *
*    end_qt(int frame)                                      *
*                                                           *
*    Quicktime Export functions for Blender's initrender.c  *
*                                                           *
************************************************************/

void start_qt(void) {
      OSErr err = noErr;

      char name[2048];
      char theFullPath[255];

#ifdef __APPLE__
      int         myFile;
      FSRef myRef;
#else
      char  *qtname;
#endif

      if(qte == NULL) qte = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");

      if(qcdx) {
            if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
            free_qtcodecdataExt();
      }

      qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");

      if(G.scene->r.qtcodecdata == NULL && G.scene->r.qtcodecdata->cdParms == NULL) {
            get_qtcodec_settings();
      } else {
            qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);

//          printf("getting from blend\n");
            GetExporterSettingsFromMem (G.scene->r.qtcodecdata);
            check_renderbutton_framerate();
      }
      
      if (G.afbreek != 1) {
            sframe = (G.scene->r.sfra);

            makeqtstring(name);

#ifdef __APPLE__
            sprintf(theFullPath, "%s", name);

            /* hack: create an empty file to make FSPathMakeRef() happy */
            myFile = open(theFullPath, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRUSR|S_IWUSR);
            if (myFile < 0) {
                  printf("error while creating file!\n");
                  /* do something? */
            }
            close(myFile);
            err = FSPathMakeRef(theFullPath, &myRef, 0);
            CheckError(err, "FsPathMakeRef error");
            err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qte->theSpec, NULL);
            CheckError(err, "FsGetCatalogInfoRef error");
#else
            qtname = get_valid_qtname(name);
            sprintf(theFullPath, "%s", qtname);
            
            CopyCStringToPascal(theFullPath, qte->qtfilename);
            err = FSMakeFSSpec(0, 0L, qte->qtfilename, &qte->theSpec);
#endif

            err = CreateMovieFile (&qte->theSpec, 
                                          kMyCreatorType,
                                          smCurrentScript, 
                                          createMovieFileDeleteCurFile | createMovieFileDontCreateResFile,
                                          &qte->resRefNum, 
                                          &qte->theMovie );
            CheckError(err, "CreateMovieFile error");

            if(err != noErr) {
                  G.afbreek = 1;
#ifdef __APPLE__
                  error("Unable to create Quicktime movie: %s\n", name);
#else
                  error("Unable to create Quicktime movie: %s\n", qtname);
                  MEM_freeN(qtname);
#endif
            } else {

#ifdef __APPLE__
                  printf("Created QuickTime movie: %s\n", name);
#else
                  printf("Created QuickTime movie: %s\n", qtname);
                  MEM_freeN(qtname);
#endif

                  QT_CreateMyVideoTrack();
            }
      }
}


void append_qt(int frame) {
      QT_DoAddVideoSamplesToMedia(frame);
}

void end_qt(void) {
      OSErr err = noErr;

      if(qte->theMovie) {
            QT_EndCreateMyVideoTrack ();

            qte->resId = movieInDataForkResID;
            err = AddMovieResource (qte->theMovie, qte->resRefNum, &qte->resId, qte->qtfilename);
            CheckError(err, "AddMovieResource error");

            if (qte->resRefNum)     CloseMovieFile (qte->resRefNum);

            DisposeMovie (qte->theMovie);
      }

      if(qte) {
            MEM_freeN(qte);
            qte = NULL;
      }
};


/************************************************************
*                                                           *
*    free_qtcodecdataExt(void)                              *
*                                                           *
*    Function to release codec memory, since it remains     *
*    resident after allocation.                             *
*                                                           *
*************************************************************/

void free_qtcodecdataExt(void) {
      if(qcdx) {
            if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
            MEM_freeN(qcdx);
            qcdx = NULL;
      }
}


/************************************************************
*                                                           *
*    check_renderbutton_framerate ( void )                  *
*                                                           *
*    To keep float framerates consistent between the codec  *
*    dialog and frs/sec button.                             *
*                                                           *
*************************************************************/

static void check_renderbutton_framerate(void) {
      OSErr err;  

      err = SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
      CheckError(err, "SCGetInfo fr error");

      if( (G.scene->r.frs_sec == 24 || G.scene->r.frs_sec == 30 || G.scene->r.frs_sec == 60) &&
            (qcdx->gTemporalSettings.frameRate == 1571553 ||
             qcdx->gTemporalSettings.frameRate == 1964113 ||
             qcdx->gTemporalSettings.frameRate == 3928227)) {;} else
      qcdx->gTemporalSettings.frameRate = G.scene->r.frs_sec << 16;

      err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
      CheckError( err, "SCSetInfo error" );

      if(qcdx->gTemporalSettings.frameRate == 1571553) {                // 23.98 fps
            qcdx->kVideoTimeScale = 2398;
            qcdx->duration = 100;
      } else if (qcdx->gTemporalSettings.frameRate == 1964113) {  // 29.97 fps
            qcdx->kVideoTimeScale = 2997;
            qcdx->duration = 100;
      } else if (qcdx->gTemporalSettings.frameRate == 3928227) {  // 59.94 fps
            qcdx->kVideoTimeScale = 5994;
            qcdx->duration = 100;
      } else {
            qcdx->kVideoTimeScale = (qcdx->gTemporalSettings.frameRate >> 16) * 100;
            qcdx->duration = 100;
      }
}

/********************************************************************
*                                                                   *
*    get_qtcodec_settings()                                         *
*                                                                   *
*    Displays Codec Dialog and retrieves Quicktime Codec settings.  *
*                                                                   *
********************************************************************/

int get_qtcodec_settings(void) 
{
      OSErr err = noErr;
      CodecInfo ci;
      char str[255];

      // erase any existing codecsetting
      if(qcdx) {
            if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
            free_qtcodecdataExt();
      }

      // allocate new
      qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");
      qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);

      // get previous selected codecsetting, if any 
      if(G.scene->r.qtcodecdata && G.scene->r.qtcodecdata->cdParms) {
//          printf("getting from MEM\n");
            GetExporterSettingsFromMem (G.scene->r.qtcodecdata);
            check_renderbutton_framerate();
      } else {

      // configure the standard image compression dialog box
      // set some default settings
//          qcdx->gSpatialSettings.codecType = nil;     
            qcdx->gSpatialSettings.codec = anyCodec;         
//          qcdx->gSpatialSettings.depth;         
            qcdx->gSpatialSettings.spatialQuality = codecMaxQuality;

            qcdx->gTemporalSettings.temporalQuality = codecMaxQuality;
//          qcdx->gTemporalSettings.frameRate;      
            qcdx->gTemporalSettings.keyFrameRate = 25;   

            qcdx->aDataRateSetting.dataRate = 90 * 1024;          
//          qcdx->aDataRateSetting.frameDuration;     
//          qcdx->aDataRateSetting.minSpatialQuality; 
//          qcdx->aDataRateSetting.minTemporalQuality;

            err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
            CheckError(err, "SCSetInfo1 error");
            err = SCSetInfo(qcdx->theComponent, scSpatialSettingsType,  &qcdx->gSpatialSettings);
            CheckError(err, "SCSetInfo2 error");
            err = SCSetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);
            CheckError(err, "SCSetInfo3 error");
      }

      check_renderbutton_framerate();

      // put up the dialog box
      err = SCRequestSequenceSettings(qcdx->theComponent);
 
      if (err == scUserCancelled) {
            G.afbreek = 1;
            return 0;
      }

      // get user selected data
      SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
      SCGetInfo(qcdx->theComponent, scSpatialSettingsType,  &qcdx->gSpatialSettings);
      SCGetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);

      GetCodecInfo (&ci, qcdx->gSpatialSettings.codecType, 0);
      CopyPascalStringToC(ci.typeName, str);
      sprintf(qtcdname,"Codec: %s", str);

      SaveExporterSettingsToMem(G.scene->r.qtcodecdata);

      // framerate jugglin'
      if(qcdx->gTemporalSettings.frameRate == 1571553) {                // 23.98 fps
            qcdx->kVideoTimeScale = 2398;
            qcdx->duration = 100;

            G.scene->r.frs_sec = 24;
      } else if (qcdx->gTemporalSettings.frameRate == 1964113) {  // 29.97 fps
            qcdx->kVideoTimeScale = 2997;
            qcdx->duration = 100;

            G.scene->r.frs_sec = 30;
      } else if (qcdx->gTemporalSettings.frameRate == 3928227) {  // 59.94 fps
            qcdx->kVideoTimeScale = 5994;
            qcdx->duration = 100;

            G.scene->r.frs_sec = 60;
      } else {
            qcdx->kVideoTimeScale = 600;
            qcdx->duration = qcdx->kVideoTimeScale / (qcdx->gTemporalSettings.frameRate / 65536);

            G.scene->r.frs_sec = (qcdx->gTemporalSettings.frameRate / 65536);
      }

      return 1;
}

#endif /* _WIN32 || __APPLE__ */

#endif /* WITH_QUICKTIME */


Generated by  Doxygen 1.6.0   Back to index