Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2007-10-21 19:42:08 +0400
committerPeter Schlaile <peter@schlaile.de>2007-10-21 19:42:08 +0400
commita0390e5cc340febece6e2a7e61085033d79742e2 (patch)
tree5d0e89c54603641f394b95b0e76ee917d15a727d /source/blender/python
parentbacfc9eb91f10871a2ba9c3b35e48c3895dffac3 (diff)
== Core ==
This adds fractional FPS support to blender and should finally make NTSC work correctly. NTSC has an FPS of 30.0/1.001 which is approximately 29.97 FPS. Therefore, it is not enough to simply make frs_sec a float, since you can't represent this accurately enough. I added a seperate variable frs_sec_base and FPS is now frs_sec / frs_sec_base. I changed all the places, where frs_sec was used to my best knowledge. For convenience sake, I added several macros, that should make life easier in the future: FRA2TIME(a) : convert frame number to a double precision time in seconds TIME2FRA(a) : the same in the opposite direction FPS : return current FPS as a double precision number (last resort) This closes bug #6715 Standard framerates not supported / breaks sync -- 23.967 29.967 etc. https://projects.blender.org/tracker/?func=detail&aid=6715&group_id=9&atid=125 Please give this heavy testing with NTSC files, quicktime in/export and the python interface. Errors are most probably only spotted on longer timelines, so that is also important. The patch was tested by Troy Sobotka and me, so it most probably should work out of the box, but wider testing is important, since errors are very subtle. Enjoy!
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/api2_2x/sceneRender.c64
-rw-r--r--source/blender/python/api2_2x/sceneSequence.c2
2 files changed, 52 insertions, 14 deletions
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index ba39e5e0f73..05d9b005b5f 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -75,6 +75,7 @@ enum rend_constants {
EXPP_RENDER_ATTR_SFRAME,
EXPP_RENDER_ATTR_EFRAME,
EXPP_RENDER_ATTR_FPS,
+ EXPP_RENDER_ATTR_FPS_BASE,
EXPP_RENDER_ATTR_SIZEX,
EXPP_RENDER_ATTR_SIZEY,
EXPP_RENDER_ATTR_GAUSSFILTER,
@@ -285,7 +286,8 @@ static PyObject *M_Render_GetSetAttributeInt( PyObject * args, int *structure,
static void M_Render_DoSizePreset( BPy_RenderData * self, short xsch,
short ysch, short xasp, short yasp,
short size, short xparts, short yparts,
- short frames, float a, float b, float c,
+ short fps, float fps_base,
+ float a, float b, float c,
float d )
{
self->renderContext->xsch = xsch;
@@ -293,7 +295,8 @@ static void M_Render_DoSizePreset( BPy_RenderData * self, short xsch,
self->renderContext->xasp = xasp;
self->renderContext->yasp = yasp;
self->renderContext->size = size;
- self->renderContext->frs_sec = frames;
+ self->renderContext->frs_sec = fps;
+ self->renderContext->frs_sec_base = fps_base;
self->renderContext->xparts = xparts;
self->renderContext->yparts = yparts;
@@ -1022,6 +1025,12 @@ PyObject *RenderData_FramesPerSec( BPy_RenderData * self, PyObject * args )
120 );
}
+PyObject *RenderData_FramesPerSecBase( BPy_RenderData * self, PyObject * args )
+{
+ return M_Render_GetSetAttributeFloat(
+ args, &self->renderContext->frs_sec_base, 1.0f, 120.0f );
+}
+
PyObject *RenderData_EnableGrayscale( BPy_RenderData * self )
{
self->renderContext->planes = R_PLANESBW;
@@ -1057,20 +1066,24 @@ PyObject *RenderData_SizePreset( BPy_RenderData * self, PyObject * args )
if( type == B_PR_PAL ) {
M_Render_DoSizePreset( self, 720, 576, 54, 51, 100,
self->renderContext->xparts,
- self->renderContext->yparts, 25, 0.1f,
+ self->renderContext->yparts, 25, 1.0f,
+ 0.1f,
0.9f, 0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_NTSC ) {
M_Render_DoSizePreset( self, 720, 480, 10, 11, 100, 1, 1,
- 30, 0.1f, 0.9f, 0.1f, 0.9f );
+ 30, 1.001f,
+ 0.1f, 0.9f, 0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_PRESET ) {
M_Render_DoSizePreset( self, 720, 576, 54, 51, 100, 1, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode = R_OSA + R_SHADOW + R_FIELDS;
self->renderContext->imtype = R_TARGA;
@@ -1078,34 +1091,42 @@ PyObject *RenderData_SizePreset( BPy_RenderData * self, PyObject * args )
0.9f );
} else if( type == B_PR_PRV ) {
M_Render_DoSizePreset( self, 640, 512, 1, 1, 50, 1, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_PC ) {
M_Render_DoSizePreset( self, 640, 480, 100, 100, 100, 1, 1,
- self->renderContext->frs_sec, 0.0f, 1.0f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.0f, 1.0f,
0.0f, 1.0f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.0f, 1.0f, 0.0f,
1.0f );
} else if( type == B_PR_PAL169 ) {
M_Render_DoSizePreset( self, 720, 576, 64, 45, 100, 1, 1,
- 25, 0.1f, 0.9f, 0.1f, 0.9f );
+ 25, 1.0f, 0.1f, 0.9f, 0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_PANO ) {
M_Render_DoSizePreset( self, 36, 176, 115, 100, 100, 16, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode |= R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_FULL ) {
M_Render_DoSizePreset( self, 1280, 1024, 1, 1, 100, 1, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
@@ -1729,9 +1750,11 @@ PyObject *RenderData_NewMapValue( BPy_RenderData * self, PyObject * args )
static PyObject *RenderData_getTimeCode( BPy_RenderData * self) {
char tc[12];
- int h, m, s, fps, cfa;
+ int h, m, s, cfa;
+ double fps;
- fps = self->renderContext->frs_sec;
+ fps = (double) self->renderContext->frs_sec /
+ self->renderContext->frs_sec_base;
cfa = self->renderContext->cfra-1;
s = cfa / fps;
m = s / 60;
@@ -1739,7 +1762,8 @@ static PyObject *RenderData_getTimeCode( BPy_RenderData * self) {
if( h > 99 )
return PyString_FromString("Time Greater than 99 Hours!");
- sprintf( tc, "%02d:%02d:%02d:%02d", h%60, m%60, s%60, cfa%fps);
+ sprintf( tc, "%02d:%02d:%02d:%02d", h%60, m%60, s%60,
+ (int) (cfa - ((int) (cfa / fps) * fps)));
return PyString_FromString(tc);
}
@@ -1762,6 +1786,9 @@ static PyObject *RenderData_getFloatAttr( BPy_RenderData *self, void *type )
case EXPP_RENDER_ATTR_MBLURFACTOR:
param = self->renderContext->blurfac;
break;
+ case EXPP_RENDER_ATTR_FPS_BASE:
+ param = self->renderContext->frs_sec_base;
+ break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"undefined type constant in RenderData_getFloatAttr" );
@@ -1790,6 +1817,11 @@ static int RenderData_setFloatAttrClamp( BPy_RenderData *self, PyObject *value,
max = 5.0f;
param = &self->renderContext->blurfac;
break;
+ case EXPP_RENDER_ATTR_FPS_BASE:
+ min = 1.0f;
+ max = 120.0f;
+ param = &self->renderContext->frs_sec_base;
+ break;
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type constant in RenderData_setFloatAttrClamp" );
@@ -2540,6 +2572,10 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"Frames per second",
(void *)EXPP_RENDER_ATTR_FPS},
+ {"fps_base",
+ (getter)RenderData_getFloatAttr, (setter)RenderData_setFloatAttrClamp,
+ "Frames per second base",
+ (void *)EXPP_RENDER_ATTR_FPS_BASE},
{"sizeX",
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"Image width (in pixels)",
@@ -2782,6 +2818,8 @@ static PyMethodDef BPy_RenderData_methods[] = {
"(int) - get/set quality get/setting for JPEG images, AVI Jpeg and SGI movies"},
{"framesPerSec", ( PyCFunction ) RenderData_FramesPerSec, METH_VARARGS,
"(int) - get/set frames per second"},
+ {"framesPerSecBase", ( PyCFunction ) RenderData_FramesPerSecBase, METH_VARARGS,
+ "(float) - get/set frames per second base"},
{"enableGrayscale", ( PyCFunction ) RenderData_EnableGrayscale,
METH_NOARGS,
"() - images are saved with BW (grayscale) data"},
diff --git a/source/blender/python/api2_2x/sceneSequence.c b/source/blender/python/api2_2x/sceneSequence.c
index 9d3d4eb5508..6ddaaf345c3 100644
--- a/source/blender/python/api2_2x/sceneSequence.c
+++ b/source/blender/python/api2_2x/sceneSequence.c
@@ -169,7 +169,7 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
seq->type= SEQ_RAM_SOUND;
seq->sound = sound;
- totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec);
+ totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec / sce->r.frs_sec_base);
sound->flags |= SOUND_FLAGS_SEQUENCE;