diff options
Diffstat (limited to 'source/blender/quicktime/apple/quicktime_export.c')
-rw-r--r-- | source/blender/quicktime/apple/quicktime_export.c | 927 |
1 files changed, 0 insertions, 927 deletions
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c deleted file mode 100644 index 67be8b169c6..00000000000 --- a/source/blender/quicktime/apple/quicktime_export.c +++ /dev/null @@ -1,927 +0,0 @@ -/* - * ***** BEGIN GPL 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. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - * The Original Code is written by Rob Haarsma (phase) - * - * Contributor(s): Stefan Gartner (sgefant) - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/quicktime/apple/quicktime_export.c - * \ingroup quicktime - * - * Code to create QuickTime Movies with Blender - */ - - -#ifdef WITH_QUICKTIME -#if defined(_WIN32) || defined(__APPLE__) -#ifndef USE_QTKIT - -#include "DNA_scene_types.h" -#include "DNA_windowmanager_types.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "BKE_context.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_report.h" -#include "BKE_scene.h" - -#include "BLI_blenlib.h" - -#include "BLI_sys_types.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "MEM_guardedalloc.h" - -#include "quicktime_import.h" -#include "quicktime_export.h" - -#ifdef _WIN32 -#include <QTML.h> -#include <Movies.h> -#include <QuickTimeComponents.h> -#include <TextUtils.h> -#include <string.h> -#include <memory.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__ */ - -#define kMyCreatorType FOUR_CHAR_CODE('TVOD') -#define kTrackStart 0 -#define kMediaStart 0 - -static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, int recty, struct ReportList *reports); -static void QT_DoAddVideoSamplesToMedia(int frame, int *pixels, int rectx, int recty, struct ReportList *reports); -static void QT_EndAddVideoSamplesToMedia(void); -static void QT_CreateMyVideoTrack(int rectx, int recty, struct ReportList *reports); -static void QT_EndCreateMyVideoTrack(struct ReportList *reports); -static void check_renderbutton_framerate(struct RenderData *rd, struct ReportList *reports); -static int get_qtcodec_settings(struct RenderData *rd, struct ReportList *reports); - -typedef struct QuicktimeExport { - - FSSpec theSpec; - short resRefNum; - Str255 qtfilename; - - Media theMedia; - Movie theMovie; - Track theTrack; - - GWorldPtr theGWorld; - PixMapHandle thePixMap; - ImageDescription **anImageDescription; - - ImBuf *ibuf; /* imagedata for Quicktime's Gworld */ - ImBuf *ibuf2; /* copy of renderdata, to be Y-flipped */ - -} QuicktimeExport; - -typedef struct QuicktimeComponentData { - - ComponentInstance theComponent; - SCTemporalSettings gTemporalSettings; - SCSpatialSettings gSpatialSettings; - SCDataRateSettings aDataRateSetting; - TimeValue duration; - long kVideoTimeScale; - -} QuicktimeComponentData; - -static struct QuicktimeExport *qtexport; -static struct QuicktimeComponentData *qtdata; - -static int sframe; - -/* RNA functions */ - -static QuicktimeCodecTypeDesc qtVideoCodecList[] = { - {kRawCodecType, 1, "Uncompressed"}, - {kJPEGCodecType, 2, "JPEG"}, - {kMotionJPEGACodecType, 3, "M-JPEG A"}, - {kMotionJPEGBCodecType, 4, "M-JPEG B"}, - {kDVCPALCodecType, 5, "DV PAL"}, - {kDVCNTSCCodecType, 6, "DV/DVCPRO NTSC"}, - {kDVCPROHD720pCodecType, 7, "DVCPRO HD 720p"}, - {kDVCPROHD1080i50CodecType, 8, "DVCPRO HD 1080i50"}, - {kDVCPROHD1080i60CodecType, 9, "DVCPRO HD 1080i60"}, - {kMPEG4VisualCodecType, 10, "MPEG4"}, - {kH263CodecType, 11, "H.263"}, - {kH264CodecType, 12, "H.264"}, - {0, 0, NULL} -}; - -static int qtVideoCodecCount = 12; - -int quicktime_get_num_videocodecs() -{ - return qtVideoCodecCount; -} - -QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue) -{ - if ((indexValue >= 0) && (indexValue < qtVideoCodecCount)) - return &qtVideoCodecList[indexValue]; - else - return NULL; -} - -int quicktime_rnatmpvalue_from_videocodectype(int codecType) -{ - int i; - for (i = 0; i < qtVideoCodecCount; i++) { - if (qtVideoCodecList[i].codecType == codecType) - return qtVideoCodecList[i].rnatmpvalue; - } - - return 0; -} - -int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue) -{ - int i; - for (i = 0; i < qtVideoCodecCount; i++) { - if (qtVideoCodecList[i].rnatmpvalue == rnatmpvalue) - return qtVideoCodecList[i].codecType; - } - - return 0; -} - - - -static void CheckError(OSErr err, char *msg, ReportList *reports) -{ - if (err != noErr) { - BKE_reportf(reports, RPT_ERROR, "%s: %d", msg, err); - } -} - - -static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) -{ - QTAtomContainer myContainer = NULL; - ComponentResult myErr = noErr; - Ptr myPtr; - long mySize = 0; - - CodecInfo ci; - - QuicktimeCodecData *qcd = rd->qtcodecdata; - - /* check if current scene already has qtcodec settings, and clear them */ - if (qcd) { - free_qtcodecdata(qcd); - } - else { - qcd = rd->qtcodecdata = MEM_callocN(sizeof(QuicktimeCodecData), "QuicktimeCodecData"); - } - - /* obtain all current codec settings */ - SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - - /* retreive codecdata from quicktime in a atomcontainer */ - myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent, &myContainer); - if (myErr != noErr) { - BKE_report(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed"); - 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; - - GetCodecInfo(&ci, qtdata->gSpatialSettings.codecType, 0); - } - else { - BKE_report(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed"); - } - - QTUnlockContainer(myContainer); - -bail: - if (myContainer != NULL) - QTDisposeAtomContainer(myContainer); - - return((OSErr)myErr); -} - - -static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) -{ - Handle myHandle = NULL; - ComponentResult myErr = noErr; - - QuicktimeCodecData *qcd = rd->qtcodecdata; - - /* 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)qtdata->theComponent, (QTAtomContainer)myHandle); - if (myErr != noErr) { - BKE_report(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed"); - goto bail; - } - - /* update runtime codecsettings for use with the codec dialog */ - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - - /* Fill the render QuicktimeCodecSettigns struct */ - rd->qtcodecsettings.codecTemporalQuality = (qtdata->gTemporalSettings.temporalQuality * 100) / codecLosslessQuality; - /* Do not override scene frame rate (qtdata->gTemporalSettings.framerate) */ - rd->qtcodecsettings.keyFrameRate = qtdata->gTemporalSettings.keyFrameRate; - - rd->qtcodecsettings.codecType = qtdata->gSpatialSettings.codecType; - rd->qtcodecsettings.codec = (int)qtdata->gSpatialSettings.codec; - rd->qtcodecsettings.colorDepth = qtdata->gSpatialSettings.depth; - rd->qtcodecsettings.codecSpatialQuality = (qtdata->gSpatialSettings.spatialQuality * 100) / codecLosslessQuality; - - rd->qtcodecsettings.bitRate = qtdata->aDataRateSetting.dataRate; - rd->qtcodecsettings.minSpatialQuality = (qtdata->aDataRateSetting.minSpatialQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.minTemporalQuality = (qtdata->aDataRateSetting.minTemporalQuality * 100) / codecLosslessQuality; - /* Frame duration is already known (qtdata->aDataRateSetting.frameDuration) */ - - } - else { - BKE_report(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed"); - } -bail: - if (myHandle != NULL) - DisposeHandle(myHandle); - - return((OSErr)myErr); -} - - -static OSErr QT_AddUserDataTextToMovie(Movie theMovie, char *theText, OSType theType) -{ - UserData myUserData = NULL; - Handle myHandle = NULL; - long myLength = strlen(theText); - OSErr myErr = noErr; - - /* get the movie's user data list */ - myUserData = GetMovieUserData(theMovie); - if (myUserData == NULL) - return(paramErr); - - /* copy the specified text into a new handle */ - myHandle = NewHandleClear(myLength); - if (myHandle == NULL) - return(MemError()); - - BlockMoveData(theText, *myHandle, myLength); - - /* add the data to the movie's user data */ - myErr = AddUserDataText(myUserData, myHandle, theType, 1, (short)GetScriptManagerVariable(smRegionCode)); - - /* clean up */ - DisposeHandle(myHandle); - return(myErr); -} - - -static void QT_CreateMyVideoTrack(int rectx, int recty, ReportList *reports) -{ - OSErr err = noErr; - Rect trackFrame; -// MatrixRecord myMatrix; - - trackFrame.top = 0; - trackFrame.left = 0; - trackFrame.bottom = recty; - trackFrame.right = rectx; - - qtexport->theTrack = NewMovieTrack(qtexport->theMovie, - FixRatio(trackFrame.right, 1), - FixRatio(trackFrame.bottom, 1), - 0); - CheckError(GetMoviesError(), "NewMovieTrack error", reports); - - // SetIdentityMatrix(&myMatrix); - // ScaleMatrix(&myMatrix, fixed1, Long2Fix(-1), 0, 0); - // TranslateMatrix(&myMatrix, 0, Long2Fix(trackFrame.bottom)); - // SetMovieMatrix(qtexport->theMovie, &myMatrix); - - qtexport->theMedia = NewTrackMedia(qtexport->theTrack, - VideoMediaType, - qtdata->kVideoTimeScale, - nil, - 0); - CheckError(GetMoviesError(), "NewTrackMedia error", reports); - - err = BeginMediaEdits(qtexport->theMedia); - CheckError(err, "BeginMediaEdits error", reports); - - QT_StartAddVideoSamplesToMedia(&trackFrame, rectx, recty, reports); -} - - -static void QT_EndCreateMyVideoTrack(ReportList *reports) -{ - OSErr err = noErr; - - QT_EndAddVideoSamplesToMedia(); - - err = EndMediaEdits(qtexport->theMedia); - CheckError(err, "EndMediaEdits error", reports); - - err = InsertMediaIntoTrack(qtexport->theTrack, - kTrackStart, /* track start time */ - kMediaStart, /* media start time */ - GetMediaDuration(qtexport->theMedia), - fixed1); - CheckError(err, "InsertMediaIntoTrack error", reports); -} - - -static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, int recty, ReportList *reports) -{ - SCTemporalSettings gTemporalSettings; - OSErr err = noErr; - - qtexport->ibuf = IMB_allocImBuf(rectx, recty, 32, IB_rect); - qtexport->ibuf2 = IMB_allocImBuf(rectx, recty, 32, IB_rect); - - err = NewGWorldFromPtr(&qtexport->theGWorld, - k32ARGBPixelFormat, - trackFrame, - NULL, NULL, 0, - (Ptr)qtexport->ibuf->rect, - rectx * 4); - CheckError(err, "NewGWorldFromPtr error", reports); - - qtexport->thePixMap = GetGWorldPixMap(qtexport->theGWorld); - LockPixels(qtexport->thePixMap); - - SCDefaultPixMapSettings(qtdata->theComponent, qtexport->thePixMap, true); - - /* workaround for crash with H.264, which requires an upgrade to - * the new callback based api for proper encoding, but that's not - * really compatible with rendering out frames sequentially */ - gTemporalSettings = qtdata->gTemporalSettings; - if (qtdata->gSpatialSettings.codecType == kH264CodecType) { - if (gTemporalSettings.temporalQuality != codecMinQuality) { - BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for Quicktime H.264"); - gTemporalSettings.temporalQuality = codecMinQuality; - } - } - - SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &gTemporalSettings); - SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - - err = SCCompressSequenceBegin(qtdata->theComponent, qtexport->thePixMap, NULL, &qtexport->anImageDescription); - CheckError(err, "SCCompressSequenceBegin error", reports); -} - - -static void QT_DoAddVideoSamplesToMedia(int frame, int *pixels, int rectx, int recty, ReportList *reports) -{ - OSErr err = noErr; - Rect imageRect; - - int index; - int boxsize; - unsigned char *from, *to; - - short syncFlag; - long dataSize; - Handle compressedData; - Ptr myPtr; - - - /* copy and flip renderdata */ - memcpy(qtexport->ibuf2->rect, pixels, 4 * rectx * recty); - IMB_flipy(qtexport->ibuf2); - - /* get pointers to parse bitmapdata */ - myPtr = GetPixBaseAddr(qtexport->thePixMap); - imageRect = (**qtexport->thePixMap).bounds; - - from = (unsigned char *) qtexport->ibuf2->rect; - to = (unsigned char *) myPtr; - - /* parse RGBA bitmap into Quicktime's ARGB GWorld */ - boxsize = rectx * recty; - for (index = 0; index < boxsize; index++) { - to[0] = from[3]; - to[1] = from[0]; - to[2] = from[1]; - to[3] = from[2]; - to += 4, from += 4; - } - - err = SCCompressSequenceFrame(qtdata->theComponent, - qtexport->thePixMap, - &imageRect, - &compressedData, - &dataSize, - &syncFlag); - CheckError(err, "SCCompressSequenceFrame error", reports); - - err = AddMediaSample(qtexport->theMedia, - compressedData, - 0, - dataSize, - qtdata->duration, - (SampleDescriptionHandle)qtexport->anImageDescription, - 1, - syncFlag, - NULL); - CheckError(err, "AddMediaSample error", reports); -} - - -static void QT_EndAddVideoSamplesToMedia(void) -{ - SCCompressSequenceEnd(qtdata->theComponent); - - UnlockPixels(qtexport->thePixMap); - if (qtexport->theGWorld) - DisposeGWorld(qtexport->theGWorld); - - if (qtexport->ibuf) - IMB_freeImBuf(qtexport->ibuf); - - if (qtexport->ibuf2) - IMB_freeImBuf(qtexport->ibuf2); -} - - -void filepath_qt(char *string, RenderData *rd) -{ - char txt[64]; - - if (string == 0) return; - - strcpy(string, rd->pic); - BLI_path_abs(string, G.main->name); - - BLI_make_existing_file(string); - - if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) { - sprintf(txt, "%04d-%04d.mov", (rd->sfra), (rd->efra)); - strcat(string, txt); - } -} - - -int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, ReportList *reports) -{ - OSErr err = noErr; - - char name[2048]; - char theFullPath[255]; - -#ifdef __APPLE__ - int myFile; - FSRef myRef; -#else - char *qtname; -#endif - int success = 1; - - if (qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport"); - - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - free_qtcomponentdata(); - } - - qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeCodecDataExt"); - - if (rd->qtcodecdata == NULL || rd->qtcodecdata->cdParms == NULL) { - get_qtcodec_settings(rd, reports); - } - else { - qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); - - QT_GetCodecSettingsFromScene(rd, reports); - check_renderbutton_framerate(rd, reports); - } - - sframe = (rd->sfra); - - filepath_qt(name, rd); - -#ifdef __APPLE__ - EnterMoviesOnThread(0); - strcpy(theFullPath, 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) { - BKE_report(reports, RPT_ERROR, "Error while creating movie file!"); - /* do something? */ - } - close(myFile); - err = FSPathMakeRef((const UInt8 *)theFullPath, &myRef, 0); - CheckError(err, "FsPathMakeRef error", reports); - err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &qtexport->theSpec, NULL); - CheckError(err, "FsGetCatalogInfoRef error", reports); -#endif -#ifdef _WIN32 - qtname = get_valid_qtname(name); - strcpy(theFullPath, qtname); - strcpy(name, qtname); - MEM_freeN(qtname); - - CopyCStringToPascal(theFullPath, qtexport->qtfilename); - err = FSMakeFSSpec(0, 0L, qtexport->qtfilename, &qtexport->theSpec); -#endif - - err = CreateMovieFile(&qtexport->theSpec, - kMyCreatorType, - smCurrentScript, - createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, - &qtexport->resRefNum, - &qtexport->theMovie); - CheckError(err, "CreateMovieFile error", reports); - - if (err != noErr) { - BKE_reportf(reports, RPT_ERROR, "Unable to create Quicktime movie: %s", name); - success = 0; -#ifdef __APPLE__ - ExitMoviesOnThread(); -#endif - } - else { - /* printf("Created QuickTime movie: %s\n", name); */ - - QT_CreateMyVideoTrack(rectx, recty, reports); - } - - return success; -} - - -int append_qt(struct RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports) -{ - QT_DoAddVideoSamplesToMedia(frame, pixels, rectx, recty, reports); - return 1; -} - - -void end_qt(void) -{ - OSErr err = noErr; - short resId = movieInDataForkResID; - - if (qtexport->theMovie) { - QT_EndCreateMyVideoTrack(NULL); - - err = AddMovieResource(qtexport->theMovie, qtexport->resRefNum, &resId, qtexport->qtfilename); - CheckError(err, "AddMovieResource error", NULL); - - err = QT_AddUserDataTextToMovie(qtexport->theMovie, "Made with Blender", kUserDataTextInformation); - CheckError(err, "AddUserDataTextToMovie error", NULL); - - err = UpdateMovieResource(qtexport->theMovie, qtexport->resRefNum, resId, qtexport->qtfilename); - CheckError(err, "UpdateMovieResource error", NULL); - - if (qtexport->resRefNum) CloseMovieFile(qtexport->resRefNum); - - DisposeMovie(qtexport->theMovie); - - /* printf("Finished QuickTime movie.\n"); */ - } - -#ifdef __APPLE__ - ExitMoviesOnThread(); -#endif - - if (qtexport) { - MEM_freeN(qtexport); - qtexport = NULL; - } -} - - -void free_qtcomponentdata(void) -{ - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - MEM_freeN(qtdata); - qtdata = NULL; - } -} - - -static void check_renderbutton_framerate(RenderData *rd, ReportList *reports) -{ - /* to keep float framerates consistent between the codec dialog and frs/sec button. */ - OSErr err; - - err = SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCGetInfo fr error", reports); - - if ( (rd->frs_sec == 24 || rd->frs_sec == 30 || rd->frs_sec == 60) && - (qtdata->gTemporalSettings.frameRate == 1571553 || - qtdata->gTemporalSettings.frameRate == 1964113 || - qtdata->gTemporalSettings.frameRate == 3928227)) - { - /* do nothing */ - } - else { - if (rd->frs_sec_base > 0) - qtdata->gTemporalSettings.frameRate = - ((float)(rd->frs_sec << 16) / rd->frs_sec_base); - } - - err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCSetInfo error", reports); - - if (qtdata->gTemporalSettings.frameRate == 1571553) { /* 23.98 fps */ - qtdata->kVideoTimeScale = 24000; - qtdata->duration = 1001; - } - else if (qtdata->gTemporalSettings.frameRate == 1964113) { /* 29.97 fps */ - qtdata->kVideoTimeScale = 30000; - qtdata->duration = 1001; - } - else if (qtdata->gTemporalSettings.frameRate == 3928227) { /* 59.94 fps */ - qtdata->kVideoTimeScale = 60000; - qtdata->duration = 1001; - } - else { - qtdata->kVideoTimeScale = (qtdata->gTemporalSettings.frameRate >> 16) * 100; - qtdata->duration = 100; - } -} - -void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf) -{ - if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) { - if ((rd->qtcodecsettings.codecType == 0) || - (rd->qtcodecsettings.codecSpatialQuality < 0) || - (rd->qtcodecsettings.codecSpatialQuality > 100)) - { - rd->qtcodecsettings.codecType = kJPEGCodecType; - rd->qtcodecsettings.codec = (int)anyCodec; - rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.codecTemporalQuality = (codecHighQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.keyFrameRate = 25; - rd->qtcodecsettings.bitRate = 5000000; /* 5 Mbps */ - } - } -} - -int get_qtcodec_settings(RenderData *rd, ReportList *reports) -{ - OSErr err = noErr; - /* erase any existing codecsetting */ - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - free_qtcomponentdata(); - } - - /* allocate new */ - qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData"); - qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); - - /* get previous selected codecsetting, from qtatom or detailed settings */ - if (rd->qtcodecdata && rd->qtcodecdata->cdParms) { - QT_GetCodecSettingsFromScene(rd, reports); - } - else { - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - qtdata->gSpatialSettings.codecType = rd->qtcodecsettings.codecType; - qtdata->gSpatialSettings.codec = (CodecComponent)rd->qtcodecsettings.codec; - qtdata->gSpatialSettings.spatialQuality = (rd->qtcodecsettings.codecSpatialQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.temporalQuality = (rd->qtcodecsettings.codecTemporalQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.keyFrameRate = rd->qtcodecsettings.keyFrameRate; - qtdata->aDataRateSetting.dataRate = rd->qtcodecsettings.bitRate; - qtdata->gSpatialSettings.depth = rd->qtcodecsettings.colorDepth; - qtdata->aDataRateSetting.minSpatialQuality = (rd->qtcodecsettings.minSpatialQuality * codecLosslessQuality) / 100; - qtdata->aDataRateSetting.minTemporalQuality = (rd->qtcodecsettings.minTemporalQuality * codecLosslessQuality) / 100; - - qtdata->aDataRateSetting.frameDuration = rd->frs_sec; - SetMovieTimeScale(qtexport->theMovie, rd->frs_sec_base * 1000); - - - err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCSetInfo1 error", reports); - err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - CheckError(err, "SCSetInfo2 error", reports); - err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - CheckError(err, "SCSetInfo3 error", reports); - } - - check_renderbutton_framerate(rd, reports); - - return err; -} - -static int request_qtcodec_settings_exec(bContext *C, wmOperator *op) -{ - OSErr err = noErr; - Scene *scene = CTX_data_scene(C); - RenderData *rd = &scene->r; - - /* erase any existing codecsetting */ - if (qtdata) { - if (qtdata->theComponent) CloseComponent(qtdata->theComponent); - free_qtcomponentdata(); - } - - /* allocate new */ - qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeComponentData"); - qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); - - /* get previous selected codecsetting, from qtatom or detailed settings */ - if (rd->qtcodecdata && rd->qtcodecdata->cdParms) { - QT_GetCodecSettingsFromScene(rd, op->reports); - } - else { - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - qtdata->gSpatialSettings.codecType = rd->qtcodecsettings.codecType; - qtdata->gSpatialSettings.codec = (CodecComponent)rd->qtcodecsettings.codec; - qtdata->gSpatialSettings.spatialQuality = (rd->qtcodecsettings.codecSpatialQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.temporalQuality = (rd->qtcodecsettings.codecTemporalQuality * codecLosslessQuality) / 100; - qtdata->gTemporalSettings.keyFrameRate = rd->qtcodecsettings.keyFrameRate; - qtdata->gTemporalSettings.frameRate = ((float)(rd->frs_sec << 16) / rd->frs_sec_base); - qtdata->aDataRateSetting.dataRate = rd->qtcodecsettings.bitRate; - qtdata->gSpatialSettings.depth = rd->qtcodecsettings.colorDepth; - qtdata->aDataRateSetting.minSpatialQuality = (rd->qtcodecsettings.minSpatialQuality * codecLosslessQuality) / 100; - qtdata->aDataRateSetting.minTemporalQuality = (rd->qtcodecsettings.minTemporalQuality * codecLosslessQuality) / 100; - - qtdata->aDataRateSetting.frameDuration = rd->frs_sec; - - err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - CheckError(err, "SCSetInfo1 error", op->reports); - err = SCSetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - CheckError(err, "SCSetInfo2 error", op->reports); - err = SCSetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - CheckError(err, "SCSetInfo3 error", op->reports); - } - /* put up the dialog box - it needs to be called from the main thread */ - err = SCRequestSequenceSettings(qtdata->theComponent); - - if (err == scUserCancelled) { - return OPERATOR_FINISHED; - } - - /* update runtime codecsettings for use with the codec dialog */ - SCGetInfo(qtdata->theComponent, scDataRateSettingsType, &qtdata->aDataRateSetting); - SCGetInfo(qtdata->theComponent, scSpatialSettingsType, &qtdata->gSpatialSettings); - SCGetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings); - - - /* Fill the render QuicktimeCodecSettings struct */ - rd->qtcodecsettings.codecTemporalQuality = (qtdata->gTemporalSettings.temporalQuality * 100) / codecLosslessQuality; - /* Do not override scene frame rate (qtdata->gTemporalSettings.framerate) */ - rd->qtcodecsettings.keyFrameRate = qtdata->gTemporalSettings.keyFrameRate; - - rd->qtcodecsettings.codecType = qtdata->gSpatialSettings.codecType; - rd->qtcodecsettings.codec = (int)qtdata->gSpatialSettings.codec; - rd->qtcodecsettings.colorDepth = qtdata->gSpatialSettings.depth; - rd->qtcodecsettings.codecSpatialQuality = (qtdata->gSpatialSettings.spatialQuality * 100) / codecLosslessQuality; - - rd->qtcodecsettings.bitRate = qtdata->aDataRateSetting.dataRate; - rd->qtcodecsettings.minSpatialQuality = (qtdata->aDataRateSetting.minSpatialQuality * 100) / codecLosslessQuality; - rd->qtcodecsettings.minTemporalQuality = (qtdata->aDataRateSetting.minTemporalQuality * 100) / codecLosslessQuality; - /* Frame duration is already known (qtdata->aDataRateSetting.frameDuration) */ - - QT_SaveCodecSettingsToScene(rd, op->reports); - - /* framerate jugglin' */ - if (qtdata->gTemporalSettings.frameRate == 1571553) { /* 23.98 fps */ - qtdata->kVideoTimeScale = 24000; - qtdata->duration = 1001; - - rd->frs_sec = 24; - rd->frs_sec_base = 1.001; - } - else if (qtdata->gTemporalSettings.frameRate == 1964113) { /* 29.97 fps */ - qtdata->kVideoTimeScale = 30000; - qtdata->duration = 1001; - - rd->frs_sec = 30; - rd->frs_sec_base = 1.001; - } - else if (qtdata->gTemporalSettings.frameRate == 3928227) { /* 59.94 fps */ - qtdata->kVideoTimeScale = 60000; - qtdata->duration = 1001; - - rd->frs_sec = 60; - rd->frs_sec_base = 1.001; - } - else { - double fps = qtdata->gTemporalSettings.frameRate; - - qtdata->kVideoTimeScale = 60000; - qtdata->duration = qtdata->kVideoTimeScale / (qtdata->gTemporalSettings.frameRate / 65536); - - if ((qtdata->gTemporalSettings.frameRate & 0xffff) == 0) { - rd->frs_sec = fps / 65536; - rd->frs_sec_base = 1.0; - } - else { - /* we do our very best... */ - rd->frs_sec = fps / 65536; - rd->frs_sec_base = 1.0; - } - } - - return OPERATOR_FINISHED; -} - -static int ED_operator_setqtcodec(bContext *C) -{ - return G.have_quicktime != FALSE; -} - -#if defined(__APPLE__) -/* Need to set up a Cocoa NSAutoReleasePool to avoid memory leak - * And it must be done in an objC file, so use a GHOST_SystemCocoa.mm function for that */ -extern int cocoa_request_qtcodec_settings_exec(bContext *C, wmOperator *op); - -int fromcocoa_request_qtcodec_settings(bContext *C, wmOperator *op) -{ - return request_qtcodec_settings_exec(C, op); -} -#endif - - -void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Change Codec"; - ot->description = "Change Quicktime codec Settings"; - ot->idname = "SCENE_OT_render_data_set_quicktime_codec"; - - /* api callbacks */ -#if defined(__APPLE__) - ot->exec = cocoa_request_qtcodec_settings_exec; -#else - ot->exec = request_qtcodec_settings_exec; -#endif - ot->poll = ED_operator_setqtcodec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -#endif /* USE_QTKIT */ -#endif /* _WIN32 || __APPLE__ */ -#endif /* WITH_QUICKTIME */ - |