Updated Quicktime code so settings can be stored in the blendfile.

This enables Blender to;
- have scenes with different codec settings. (same as avicodec)
- render directly without dialog.
- batch/background render to Quicktime movies.

Only tested on windows. ;)
This commit is contained in:
Rob Haarsma 2003-05-21 01:21:07 +00:00
parent 0bebdabad2
commit 9662763ee0
10 changed files with 211 additions and 163 deletions

@ -40,6 +40,7 @@ struct Base;
struct AviCodecData;
void free_avicodecdata(struct AviCodecData *acd);
void free_qtcodecdata(struct QuicktimeCodecData *acd);
void free_scene(struct Scene *me);
struct Scene *add_scene(char *name);
int object_in_scene(struct Object *ob, struct Scene *sce);

@ -1,4 +1,3 @@
/* scene.c
*
*
@ -101,6 +100,17 @@ void free_avicodecdata(AviCodecData *acd)
}
}
void free_qtcodecdata(QuicktimeCodecData *qcd)
{
if (qcd) {
if (qcd->cdParms){
MEM_freeN(qcd->cdParms);
qcd->cdParms = NULL;
qcd->cdSize = 0;
}
}
}
/* do not free scene itself */
void free_scene(Scene *sce)
{
@ -125,6 +135,11 @@ void free_scene(Scene *sce)
MEM_freeN(sce->r.avicodecdata);
sce->r.avicodecdata = NULL;
}
if (sce->r.qtcodecdata) {
free_qtcodecdata(sce->r.qtcodecdata);
MEM_freeN(sce->r.qtcodecdata);
sce->r.qtcodecdata = NULL;
}
}
Scene *add_scene(char *name)

@ -2291,6 +2291,11 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->r.avicodecdata->lpParms = newdataadr(fd, sce->r.avicodecdata->lpParms);
}
sce->r.qtcodecdata = newdataadr(fd, sce->r.qtcodecdata);
if (sce->r.qtcodecdata) {
sce->r.qtcodecdata->cdParms = newdataadr(fd, sce->r.qtcodecdata->cdParms);
}
if(sce->ed) {
ed= sce->ed= newdataadr(fd, sce->ed);

@ -1164,6 +1164,11 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
if (sce->r.avicodecdata->lpParms) writedata(wd, DATA, sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms);
}
if (sce->r.qtcodecdata) {
writestruct(wd, DATA, "QuicktimeCodecData", 1, sce->r.qtcodecdata);
if (sce->r.qtcodecdata->cdParms) writedata(wd, DATA, sce->r.qtcodecdata->cdSize, sce->r.qtcodecdata->cdParms);
}
sce= sce->id.next;
}
}

@ -81,8 +81,21 @@ typedef struct AviCodecData {
char avicodecname[128];
} AviCodecData;
typedef struct QuicktimeCodecData {
void *cdParms; /* codec/compressor options */
void *pad; /* padding */
unsigned int cdSize; /* size of cdParms buffer */
unsigned int pad2; /* padding */
char qtcodecname[128];
} QuicktimeCodecData;
typedef struct RenderData {
struct AviCodecData *avicodecdata;
struct QuicktimeCodecData *qtcodecdata;
short cfra, sfra, efra; /* fames as in 'images' */
short images, framapto, flag;

@ -31,22 +31,6 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
/*
TODO:
- fix saving of compressionsettings
This should be fixed because:
- currently only one quicktime codec is used for all scenes
- this single codecsetting gets only initialised from the codec dialog
- the codecsettings have to get stored in the blendfile for background
rendering. blender -b crashes when it wants to popup the qt codec dialog
to retrieve a valid codec.
(quicktime isnt initialised yet when blender -b requests a rendering codec)
Some references to store the codec settings are placed at the end of this file.
DONE:
* structurize file & compression data
@ -58,6 +42,7 @@ DONE:
* 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
*/
@ -153,7 +138,8 @@ typedef struct _QuicktimeCodecDataExt {
TimeValue duration;
long kVideoTimeScale;
} QuicktimeCodecDataExt;
} QuicktimeCodecDataExt; //qtopts
struct _QuicktimeExport *qte;
struct _QuicktimeCodecDataExt *qcdx;
@ -169,10 +155,118 @@ struct _QuicktimeCodecDataExt *qcdx;
#define kTrackStart 0
#define kMediaStart 0
static int sframe;
static int sframe;
static char qtcdname[128];
/************************************************************
* *
* SaveExporterSettingsToMem *
* *
*************************************************************/
OSErr SaveExporterSettingsToMem (QuicktimeCodecData *qcd)
{
QTAtomContainer myContainer = NULL;
ComponentResult myErr = noErr;
Ptr myPtr;
Handle myHandle;
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);
myHandle = (Handle) myContainer;
HLockHi(myHandle);
myPtr = *myHandle;
// 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 (myHandle != NULL)
DisposeHandle(myHandle);
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);
}
int have_qtcodec;
char qtcdname[64];
/************************************************************
* *
@ -356,10 +450,8 @@ static void QT_EndAddVideoSamplesToMedia (void)
UnlockPixels(qte->thePixMap);
if (qte->theGWorld) DisposeGWorld (qte->theGWorld);
if (qte->ibuf) IMB_freeImBuf(qte->ibuf);
if (qte->ibuf2) {
IMB_freeImBuf(qte->ibuf2);
}
if (qte->ibuf) IMB_freeImBuf(qte->ibuf);
if (qte->ibuf2) IMB_freeImBuf(qte->ibuf2);
}
@ -410,7 +502,23 @@ void start_qt(void) {
#endif
if(qte == NULL) qte = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
if(qcdx == NULL || have_qtcodec == FALSE) get_qtcodec_settings();
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);
@ -445,8 +553,6 @@ void start_qt(void) {
printf("Created QuickTime movie: %s\n", name);
check_renderbutton_framerate();
QT_CreateMyVideoTrack();
}
}
@ -489,6 +595,7 @@ void end_qt(void) {
void free_qtcodecdataExt(void) {
if(qcdx) {
if(qcdx->theComponent) CloseComponent(qcdx->theComponent);
MEM_freeN(qcdx);
qcdx = NULL;
}
@ -508,7 +615,7 @@ static void check_renderbutton_framerate(void) {
OSErr err;
err = SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
CheckError(err, "SCGetInfo error");
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 ||
@ -533,6 +640,7 @@ static void check_renderbutton_framerate(void) {
qcdx->duration = 100;
}
}
/********************************************************************
* *
* get_qtcodec_settings() *
@ -544,29 +652,28 @@ static void check_renderbutton_framerate(void) {
int get_qtcodec_settings(void)
{
OSErr err = noErr;
// Component c = 0;
// ComponentDescription cd;
CodecInfo ci;
char str[255];
// cd.componentType = StandardCompressionType;
// cd.componentSubType = StandardCompressionSubType;
// cd.componentManufacturer = 0;
// cd.componentFlags = 0;
// cd.componentFlagsMask = 0;
if(qcdx == NULL) {
qcdx = MEM_callocN(sizeof(QuicktimeCodecDataExt), "QuicktimeCodecDataExt");
have_qtcodec = FALSE;
// 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
if (qcdx->theComponent == NULL) {
qcdx->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType);
// c = FindNextComponent(c, &cd);
// qcdx->theComponent = OpenComponent(c);
// set some default settings
// qcdx->gSpatialSettings.codecType = nil;
qcdx->gSpatialSettings.codec = anyCodec;
// qcdx->gSpatialSettings.depth;
@ -581,7 +688,6 @@ int get_qtcodec_settings(void)
// qcdx->aDataRateSetting.minSpatialQuality;
// qcdx->aDataRateSetting.minTemporalQuality;
err = SCSetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
CheckError(err, "SCSetInfo1 error");
err = SCSetInfo(qcdx->theComponent, scSpatialSettingsType, &qcdx->gSpatialSettings);
@ -589,11 +695,7 @@ int get_qtcodec_settings(void)
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) {
@ -601,10 +703,7 @@ int get_qtcodec_settings(void)
return 0;
}
have_qtcodec = TRUE;
// get user selected data
SCGetInfo(qcdx->theComponent, scTemporalSettingsType, &qcdx->gTemporalSettings);
SCGetInfo(qcdx->theComponent, scSpatialSettingsType, &qcdx->gSpatialSettings);
SCGetInfo(qcdx->theComponent, scDataRateSettingsType, &qcdx->aDataRateSetting);
@ -613,8 +712,9 @@ int get_qtcodec_settings(void)
CopyPascalStringToC(ci.typeName, str);
sprintf(qtcdname,"Codec: %s", str);
// framerate jugglin'
SaveExporterSettingsToMem(G.scene->r.qtcodecdata);
// framerate jugglin'
if(qcdx->gTemporalSettings.frameRate == 1571553) { // 23.98 fps
qcdx->kVideoTimeScale = 2398;
qcdx->duration = 100;
@ -644,102 +744,3 @@ int get_qtcodec_settings(void)
#endif /* WITH_QUICKTIME */
#if 0
/************************************************************
* *
* References for future codec handling *
* *
*************************************************************/
these are from mplayer sourcecode:
struct ComponentRecord {
long data[1];
};
typedef struct ComponentRecord ComponentRecord;
typedef ComponentRecord * Component;
typedef long OSErr;
typedef int OSType;
typedef long ComponentResult;
typedef long Fixed;
these are from quicktime:
typedef Component CodecComponent;
typedef OSType CodecType;
typedef unsigned short CodecFlags;
typedef unsigned long CodecQ;
typedef struct {
CodecType codecType; /* compressor type */
CodecComponent codec; /* compressor */
short depth; /* pixel depth */
CodecQ spatialQuality; /* desired quality */
} SCSpatialSettings;
/* temporal options structure with the temporal settings request */
typedef struct {
CodecQ temporalQuality; /* desired quality */
Fixed frameRate; /* frame rate */
long keyFrameRate; /* key frame rate */
} SCTemporalSettings;
/* data rate options with the data rate settings request */
typedef struct {
long dataRate; /* desired data rate */
long frameDuration; /* frame duration */
CodecQ minSpatialQuality; /* minimum value */
CodecQ minTemporalQuality; /* minimum value */
} SCDataRateSettings;
would look like this ???
typedef struct {
int codecType; /* compressor type */
//here is the prob
long *codec; /* compressor */
short depth; /* pixel depth */
unsigned long spatialQuality; /* desired quality */
} SCSpatialSettings;
/* temporal options structure with the temporal settings request */
typedef struct {
unsigned long temporalQuality; /* desired quality */
long frameRate; /* frame rate */
long keyFrameRate; /* key frame rate */
} SCTemporalSettings;
/* data rate options with the data rate settings request */
typedef struct {
long dataRate; /* desired data rate */
long frameDuration; /* frame duration */
unsigned long minSpatialQuality; /* minimum value */
unsigned long minTemporalQuality; /* minimum value */
} SCDataRateSettings;
stuff to use quicktime Atoms (doesnt work) heh
long size;
Ptr thePtr;
QTAtomContainer myContainer = NULL;
QTAtom myAtom;
QTAtomContainer SettingsAtom;
atom -> component
SCSetSettingsFromAtomContainer(qcdx->theComponent, SettingsAtom);
component -> atom
SCGetSettingsAsAtomContainer(qcdx->theComponent, SettingsAtom);
QTCopyAtomDataToPtr(container, atom, 0, size, &targetPtr, &actualsize);
QTGetAtomDataPtr(container, atom, &size, &ptr);
kParentAtomIsContainer
#endif /* 0 */

@ -45,9 +45,6 @@ void free_qtcodecdataExt(void); //usiblender.c
void makeqtstring (char *string); //for playanim.c
extern int have_qtcodec;
extern char qtcdname[64];
#endif //(_WIN32) || (__APPLE__)
#endif // __QUICKTIME_IMP_H__

@ -96,4 +96,4 @@ ImBuf *qtime_fetchibuf (struct anim *anim, int position);
int imb_is_a_quicktime (char *name);
ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags);
#endif // __QUICKTIME_IMP_H__
#endif // __QUICKTIME_IMP_H__

@ -6027,7 +6027,7 @@ void do_renderbuts(unsigned short event)
if (((G.scene->r.imtype == R_AVICODEC)
&& (G.scene->r.avicodecdata == NULL)) ||
((G.scene->r.imtype == R_QUICKTIME)
&& (have_qtcodec == FALSE))) {
&& (G.scene->r.qtcodecdata == NULL))) {
} else {
break;
}
@ -6589,10 +6589,10 @@ void renderbuts(void)
#if defined (_WIN32) || defined (__APPLE__)
glColor3f(0.65, 0.65, 0.7);
glRecti(892,yofs+46,892+225,yofs+45+20);
if(!have_qtcodec)
if(G.scene->r.qtcodecdata == NULL)
uiDefBut(block, LABEL, 0, "Codec: not set", 892,yofs+44,225,20, 0, 0, 0, 0, 0, "");
else
uiDefBut(block, LABEL, 0, qtcdname, 892,yofs+44,225,20, 0, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, G.scene->r.qtcodecdata->qtcodecname, 892,yofs+44,225,20, 0, 0, 0, 0, 0, "");
uiDefBut(block, BUT,B_SELECTCODEC, "Set codec", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for Quicktime");
#else /* libquicktime */
if (!G.scene->r.qtcodecdata) G.scene->r.qtcodecdata = MEM_callocN(sizeof(QtCodecData), "QtCodecData");

@ -2107,12 +2107,17 @@ Scene *copy_scene(Scene *sce, int level)
if (sce->r.avicodecdata) {
scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
}
// make a private copy of the qtcodecdata
if (sce->r.qtcodecdata) {
scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
}
return scen;
}
@ -2209,6 +2214,12 @@ void do_info_buttons(unsigned short event)
sce->r.avicodecdata->lpFormat = MEM_dupallocN(G.scene->r.avicodecdata->lpFormat);
sce->r.avicodecdata->lpParms = MEM_dupallocN(G.scene->r.avicodecdata->lpParms);
}
#endif
#ifdef WITH_QUICKTIME
if (sce->r.qtcodecdata) {
sce->r.qtcodecdata = MEM_dupallocN(G.scene->r.qtcodecdata);
sce->r.qtcodecdata->cdParms = MEM_dupallocN(G.scene->r.qtcodecdata->cdParms);
}
#endif
}
else sce= copy_scene(G.scene, nr-2);