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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-06-09 00:08:19 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-06-09 00:08:19 +0400
commitc8b4cf92067ffeb625aa39003baf5d8f7c3f0025 (patch)
treec6c50dbc3d90a65fca6c1ca56a93e4a57cf7e154 /source/gameengine/VideoTexture
parente93db433a086a3e739c0f4026cd500f0b595b0f1 (diff)
parentd76a6f5231c015c35123d22e1f5c3ffcdfbf9bbd (diff)
2.50:
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19820:HEAD Notes: * Game and sequencer RNA, and sequencer header are now out of date a bit after changes in trunk. * I didn't know how to port these bugfixes, most likely they are not needed anymore. * Fix "duplicate strip" always increase the user count for ipo. * IPO pinning on sequencer strips was lost during Undo.
Diffstat (limited to 'source/gameengine/VideoTexture')
-rw-r--r--source/gameengine/VideoTexture/BlendType.h6
-rw-r--r--source/gameengine/VideoTexture/FilterBlueScreen.cpp7
-rw-r--r--source/gameengine/VideoTexture/FilterColor.cpp21
-rw-r--r--source/gameengine/VideoTexture/FilterNormal.cpp7
-rw-r--r--source/gameengine/VideoTexture/FilterSource.cpp21
-rw-r--r--source/gameengine/VideoTexture/ImageBase.cpp8
-rw-r--r--source/gameengine/VideoTexture/ImageBuff.cpp10
-rw-r--r--source/gameengine/VideoTexture/ImageMix.cpp15
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp71
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.cpp7
-rw-r--r--source/gameengine/VideoTexture/PyTypeList.cpp1
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp16
-rw-r--r--source/gameengine/VideoTexture/VideoBase.cpp7
-rw-r--r--source/gameengine/VideoTexture/VideoBase.h13
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp86
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h5
-rw-r--r--source/gameengine/VideoTexture/blendVideoTex.cpp46
17 files changed, 263 insertions, 84 deletions
diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h
index ac3ed8812a6..8b243c43912 100644
--- a/source/gameengine/VideoTexture/BlendType.h
+++ b/source/gameengine/VideoTexture/BlendType.h
@@ -25,6 +25,7 @@ http://www.gnu.org/copyleft/lesser.txt.
/// class allows check type of blender python object and access its contained object
+/// MUST ONLY BE USED FOR KX classes that are descendent of PyObjectPlus
template <class PyObj> class BlendType
{
public:
@@ -48,8 +49,9 @@ public:
// if pointer to type is set and don't match to type of provided object, return NULL
else if (obj->ob_type != m_objType)
return NULL;
- // return pointer to object
- return (PyObj*)obj;
+ // return pointer to object, this class can only be used for KX object =>
+ // the Py object is actually a proxy
+ return (PyObj*)BGE_PROXY_REF(obj);
}
/// parse arguments to get object
diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp
index 43d7566102a..6b23105a278 100644
--- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp
+++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp
@@ -135,8 +135,13 @@ static PyGetSetDef filterBSGetSets[] =
// define python type
PyTypeObject FilterBlueScreenType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterBlueScreen", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp
index 22ee729b200..5ff1f7f11ce 100644
--- a/source/gameengine/VideoTexture/FilterColor.cpp
+++ b/source/gameengine/VideoTexture/FilterColor.cpp
@@ -41,8 +41,13 @@ static PyGetSetDef filterGrayGetSets[] =
// define python type
PyTypeObject FilterGrayType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterGray", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -173,8 +178,13 @@ static PyGetSetDef filterColorGetSets[] =
// define python type
PyTypeObject FilterColorType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterColor", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -307,8 +317,13 @@ static PyGetSetDef filterLevelGetSets[] =
// define python type
PyTypeObject FilterLevelType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterLevel", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp
index a7266967efb..9a2b1e90d5a 100644
--- a/source/gameengine/VideoTexture/FilterNormal.cpp
+++ b/source/gameengine/VideoTexture/FilterNormal.cpp
@@ -124,8 +124,13 @@ static PyGetSetDef filterNormalGetSets[] =
// define python type
PyTypeObject FilterNormalType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterNormal", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/FilterSource.cpp b/source/gameengine/VideoTexture/FilterSource.cpp
index f3676e93a6d..4c75e14bbac 100644
--- a/source/gameengine/VideoTexture/FilterSource.cpp
+++ b/source/gameengine/VideoTexture/FilterSource.cpp
@@ -36,8 +36,13 @@ http://www.gnu.org/copyleft/lesser.txt.
// define python type
PyTypeObject FilterRGB24Type =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterRGB24", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -82,8 +87,13 @@ PyTypeObject FilterRGB24Type =
// define python type
PyTypeObject FilterRGBA32Type =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterRGBA32", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -128,8 +138,13 @@ PyTypeObject FilterRGBA32Type =
// define python type
PyTypeObject FilterBGR24Type =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.FilterBGR24", /*tp_name*/
sizeof(PyFilter), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
index dcca20de24a..5e2841271a6 100644
--- a/source/gameengine/VideoTexture/ImageBase.cpp
+++ b/source/gameengine/VideoTexture/ImageBase.cpp
@@ -437,7 +437,9 @@ PyObject * Image_getSource (PyImage * self, PyObject * args)
{
// get arguments
char * id;
- if (self->m_image != NULL && PyArg_ParseTuple(args, "s", &id))
+ if (!PyArg_ParseTuple(args, "s:getSource", &id))
+ return NULL;
+ if (self->m_image != NULL)
{
// get source object
PyObject * src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
@@ -460,7 +462,9 @@ PyObject * Image_setSource (PyImage * self, PyObject * args)
// get arguments
char * id;
PyObject * obj;
- if (self->m_image != NULL && PyArg_ParseTuple(args, "sO", &id, &obj))
+ if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj))
+ return NULL;
+ if (self->m_image != NULL)
{
// check type of object
if (pyImageTypes.in(obj->ob_type))
diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp
index 19ad17ac643..c7185660e83 100644
--- a/source/gameengine/VideoTexture/ImageBuff.cpp
+++ b/source/gameengine/VideoTexture/ImageBuff.cpp
@@ -71,10 +71,9 @@ static PyObject * load (PyImage * self, PyObject * args)
short width;
short height;
// parse parameters
- if (!PyArg_ParseTuple(args, "s#hh", &buff, &buffSize, &width, &height))
+ if (!PyArg_ParseTuple(args, "s#hh:load", &buff, &buffSize, &width, &height))
{
// report error
- PyErr_SetString(PyExc_TypeError, "Parameters are not correct");
return NULL;
}
// else check buffer size
@@ -123,8 +122,13 @@ static PyGetSetDef imageBuffGetSets[] =
// define python type
PyTypeObject ImageBuffType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.ImageBuff", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp
index b07b362818c..067143e57bb 100644
--- a/source/gameengine/VideoTexture/ImageMix.cpp
+++ b/source/gameengine/VideoTexture/ImageMix.cpp
@@ -109,7 +109,9 @@ PyObject * getWeight (PyImage * self, PyObject * args)
short weight = 0;
// get arguments
char * id;
- if (self->m_image != NULL && PyArg_ParseTuple(args, "s", &id))
+ if (!PyArg_ParseTuple(args, "s:getWeight", &id))
+ return NULL;
+ if (self->m_image != NULL)
// get weight
weight = getImageMix(self)->getWeight(id);
// return weight
@@ -123,7 +125,9 @@ PyObject * setWeight (PyImage * self, PyObject * args)
// get arguments
char * id;
short weight = 0;
- if (self->m_image != NULL && PyArg_ParseTuple(args, "sh", &id, &weight))
+ if (!PyArg_ParseTuple(args, "sh:setWeight", &id, &weight))
+ return NULL;
+ if (self->m_image != NULL)
// set weight
if (!getImageMix(self)->setWeight(id, weight))
{
@@ -162,8 +166,13 @@ static PyGetSetDef imageMixGetSets[] =
// define python type
PyTypeObject ImageMixType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.ImageMix", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 09c3c22f258..c4fb1fefd9c 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -181,7 +181,6 @@ void ImageRender::Render()
frustrum.camnear = -mirrorOffset[2];
frustrum.camfar = -mirrorOffset[2]+m_clip;
}
- const float ortho = 100.0;
const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
// The screen area that ImageViewport will copy is also the rendering zone
@@ -214,44 +213,48 @@ void ImageRender::Render()
float farfrust = m_camera->GetCameraFar();
float aspect_ratio = 1.0f;
Scene *blenderScene = m_scene->GetBlenderScene();
+ MT_Matrix4x4 projmat;
- if (orthographic) {
- lens *= ortho;
- nearfrust = (nearfrust + 1.0)*ortho;
- farfrust *= ortho;
- }
// compute the aspect ratio from frame blender scene settings so that render to texture
// works the same in Blender and in Blender player
if (blenderScene->r.ysch != 0)
- aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch);
-
- RAS_FramingManager::ComputeDefaultFrustum(
- nearfrust,
- farfrust,
- lens,
- aspect_ratio,
- frustrum);
-
- MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
- frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
-
+ aspect_ratio = float(blenderScene->r.xsch*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp);
+
+ if (orthographic) {
+
+ RAS_FramingManager::ComputeDefaultOrtho(
+ nearfrust,
+ farfrust,
+ m_camera->GetScale(),
+ aspect_ratio,
+ frustrum
+ );
+
+ projmat = m_rasterizer->GetOrthoMatrix(
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
+ } else
+ {
+ RAS_FramingManager::ComputeDefaultFrustum(
+ nearfrust,
+ farfrust,
+ lens,
+ aspect_ratio,
+ frustrum);
+
+ projmat = m_rasterizer->GetFrustumMatrix(
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
+ }
m_camera->SetProjectionMatrix(projmat);
}
MT_Transform camtrans(m_camera->GetWorldToCamera());
- if (!m_camera->GetCameraData()->m_perspective)
- camtrans.getOrigin()[2] *= ortho;
MT_Matrix4x4 viewmat(camtrans);
- m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(),
- m_camera->GetCameraLocation(), m_camera->GetCameraOrientation());
+ m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldOrientation(), m_camera->NodeGetWorldPosition(), m_camera->GetCameraData()->m_perspective);
m_camera->SetModelviewMatrix(viewmat);
// restore the stereo mode now that the matrix is computed
m_rasterizer->SetStereoMode(stereomode);
- // do not update the mesh transform, we don't want to do it more than once per frame
- //m_scene->UpdateMeshTransformations();
-
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
@@ -373,8 +376,13 @@ static PyGetSetDef imageRenderGetSets[] =
// define python type
PyTypeObject ImageRenderType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.ImageRender", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -553,8 +561,8 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
float yaxis[3] = {0.f, 1.f, 0.f};
float mirrorMat[3][3];
float left, right, top, bottom, back;
-
- m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata);
+ // make sure this camera will delete its node
+ m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata, true, true);
m_camera->SetName("__mirror__cam__");
// don't add the camera to the scene object list, it doesn't need to be accessible
m_owncamera = true;
@@ -707,8 +715,13 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
// define python type
PyTypeObject ImageMirrorType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.ImageMirror", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp
index a4e36b5948c..d2c23e758f6 100644
--- a/source/gameengine/VideoTexture/ImageViewport.cpp
+++ b/source/gameengine/VideoTexture/ImageViewport.cpp
@@ -289,8 +289,13 @@ static PyGetSetDef imageViewportGetSets[] =
// define python type
PyTypeObject ImageViewportType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.ImageViewport", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp
index 6d2676dce09..2d571675dbd 100644
--- a/source/gameengine/VideoTexture/PyTypeList.cpp
+++ b/source/gameengine/VideoTexture/PyTypeList.cpp
@@ -45,7 +45,6 @@ bool PyTypeList::in (PyTypeObject * type)
/// add type to list
void PyTypeList::add (PyTypeObject * type, const char * name)
{
- PyTypeListItem * typeItem;
// if list doesn't exist, create it
if (m_list.get() == NULL)
m_list.reset(new PyTypeListType());
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index 3533cee0f7f..f4105652f80 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -50,7 +50,7 @@ http://www.gnu.org/copyleft/lesser.txt.
// macro for exception handling and logging
#define CATCH_EXCP catch (Exception & exp) \
-{ exp.report(); }
+{ exp.report(); return NULL; }
// Blender GameObject type
@@ -162,11 +162,12 @@ void Texture_dealloc (Texture * self)
// release renderer
Py_XDECREF(self->m_source);
// close texture
- Texture_close(self);
+ PyObject* ret = Texture_close(self);
+ Py_DECREF(ret);
// release scaled image buffer
delete [] self->m_scaledImg;
// release object
- self->ob_type->tp_free((PyObject*)self);
+ ((PyObject *)self)->ob_type->tp_free((PyObject*)self);
}
@@ -278,7 +279,7 @@ PyObject * Texture_refresh (Texture * self, PyObject * args)
{
// get parameter - refresh source
PyObject * param;
- if (!PyArg_ParseTuple(args, "O", &param) || !PyBool_Check(param))
+ if (!PyArg_ParseTuple(args, "O:refresh", &param) || !PyBool_Check(param))
{
// report error
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
@@ -433,8 +434,13 @@ static PyGetSetDef textureGetSets[] =
// class Texture declaration
PyTypeObject TextureType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.Texture", /*tp_name*/
sizeof(Texture), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp
index 3c703d75cda..5d449a158d8 100644
--- a/source/gameengine/VideoTexture/VideoBase.cpp
+++ b/source/gameengine/VideoTexture/VideoBase.cpp
@@ -113,7 +113,10 @@ void Video_open (VideoBase * self, char * file, short captureID)
PyObject * Video_play (PyImage * self)
{ if (getVideo(self)->play()) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
-// stop video
+// pause video
+PyObject * Video_pause (PyImage * self)
+{ if (getVideo(self)->pause()) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
+
PyObject * Video_stop (PyImage * self)
{ if (getVideo(self)->stop()) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
@@ -146,7 +149,7 @@ int Video_setRange (PyImage * self, PyObject * value, void * closure)
|| !PyFloat_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyFloat_Check(PySequence_Fast_GET_ITEM(value, 1)))
{
- PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 longs");
+ PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 float");
return -1;
}
// set range
diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h
index 15ecb7a78f4..0c8668ee0bc 100644
--- a/source/gameengine/VideoTexture/VideoBase.h
+++ b/source/gameengine/VideoTexture/VideoBase.h
@@ -80,7 +80,17 @@ public:
}
return false;
}
- /// stop/pause video
+ /// pause video
+ virtual bool pause (void)
+ {
+ if (m_status == SourcePlaying)
+ {
+ m_status = SourceStopped;
+ return true;
+ }
+ return false;
+ }
+ /// stop video
virtual bool stop (void)
{
if (m_status == SourcePlaying)
@@ -170,6 +180,7 @@ template <class T> void Video_init (PyImage * self)
// video functions
void Video_open (VideoBase * self, char * file, short captureID);
PyObject * Video_play (PyImage * self);
+PyObject * Video_pause (PyImage * self);
PyObject * Video_stop (PyImage * self);
PyObject * Video_refresh (PyImage * self);
PyObject * Video_getStatus (PyImage * self, void * closure);
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 5265b0ecb93..1a5481488c0 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -117,6 +117,7 @@ bool VideoFFmpeg::release()
}
m_codec = NULL;
m_status = SourceStopped;
+ m_lastFrame = -1;
return true;
}
@@ -669,12 +670,12 @@ bool VideoFFmpeg::play (void)
}
-// stop video
-bool VideoFFmpeg::stop (void)
+// pause video
+bool VideoFFmpeg::pause (void)
{
try
{
- if (VideoBase::stop())
+ if (VideoBase::pause())
{
return true;
}
@@ -683,6 +684,20 @@ bool VideoFFmpeg::stop (void)
return false;
}
+// stop video
+bool VideoFFmpeg::stop (void)
+{
+ try
+ {
+ VideoBase::stop();
+ // force restart when play
+ m_lastFrame = -1;
+ return true;
+ }
+ CATCH_EXCP;
+ return false;
+}
+
// set video range
void VideoFFmpeg::setRange (double start, double stop)
@@ -721,6 +736,8 @@ void VideoFFmpeg::loadFrame (void)
{
// get actual time
double startTime = PIL_check_seconds_timer();
+ if (m_lastFrame == -1 && !m_isFile)
+ m_startTime = startTime;
double actTime = startTime - m_startTime;
// if video has ended
if (m_isFile && actTime * m_frameRate >= m_range[1])
@@ -886,28 +903,47 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
if (position != m_curPosition + 1)
{
double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
- long long pos = (long long)
- ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate);
- long long startTs = m_formatCtx->streams[m_videoStream]->start_time;
+ int64_t pos = (int64_t)((position - m_preseek) / (m_baseFrameRate*timeBase));
+ int64_t startTs = m_formatCtx->streams[m_videoStream]->start_time;
+ int seekres;
if (pos < 0)
pos = 0;
if (startTs != AV_NOPTS_VALUE)
- pos += (long long)(startTs * AV_TIME_BASE * timeBase);
+ pos += startTs;
if (position <= m_curPosition || !m_eof)
{
- // no need to seek past the end of the file
- if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0)
+#if 0
+ // Tried to make this work but couldn't: seeking on byte is ignored by the
+ // format plugin and it will generally continue to read from last timestamp.
+ // Too bad because frame seek is not always able to get the first frame
+ // of the file.
+ if (position <= m_preseek)
+ {
+ // we can safely go the begining of the file
+ if (av_seek_frame(m_formatCtx, m_videoStream, 0, AVSEEK_FLAG_BYTE) >= 0)
+ {
+ // binary seek does not reset the timestamp, must do it now
+ av_update_cur_dts(m_formatCtx, m_formatCtx->streams[m_videoStream], startTs);
+ m_curPosition = 0;
+ }
+ }
+ else
+#endif
{
// current position is now lost, guess a value.
- // It's not important because it will be set at this end of this function
- m_curPosition = position - m_preseek - 1;
+ if (av_seek_frame(m_formatCtx, m_videoStream, pos, AVSEEK_FLAG_BACKWARD) >= 0)
+ {
+ // current position is now lost, guess a value.
+ // It's not important because it will be set at this end of this function
+ m_curPosition = position - m_preseek - 1;
+ }
}
}
// this is the timestamp of the frame we're looking for
- targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase);
+ targetTs = (int64_t)(position / (m_baseFrameRate * timeBase));
if (startTs != AV_NOPTS_VALUE)
targetTs += startTs;
@@ -1097,8 +1133,9 @@ int VideoFFmpeg_setDeinterlace (PyImage * self, PyObject * value, void * closure
// methods structure
static PyMethodDef videoMethods[] =
{ // methods from VideoBase class
- {"play", (PyCFunction)Video_play, METH_NOARGS, "Play video"},
- {"stop", (PyCFunction)Video_stop, METH_NOARGS, "Stop (pause) video"},
+ {"play", (PyCFunction)Video_play, METH_NOARGS, "Play (restart) video"},
+ {"pause", (PyCFunction)Video_pause, METH_NOARGS, "pause video"},
+ {"stop", (PyCFunction)Video_stop, METH_NOARGS, "stop video (play will replay it from start)"},
{"refresh", (PyCFunction)Video_refresh, METH_NOARGS, "Refresh video - get its status"},
{NULL}
};
@@ -1123,8 +1160,13 @@ static PyGetSetDef videoGetSets[] =
// python type declaration
PyTypeObject VideoFFmpegType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.VideoFFmpeg", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
@@ -1173,7 +1215,7 @@ static int ImageFFmpeg_init (PyObject * pySelf, PyObject * args, PyObject * kwds
char * file = NULL;
// get parameters
- if (!PyArg_ParseTuple(args, "s", &file))
+ if (!PyArg_ParseTuple(args, "s:ImageFFmpeg", &file))
return -1;
try
@@ -1198,8 +1240,9 @@ static int ImageFFmpeg_init (PyObject * pySelf, PyObject * args, PyObject * kwds
PyObject * Image_reload (PyImage * self, PyObject *args)
{
char * newname = NULL;
-
- if (self->m_image != NULL && PyArg_ParseTuple(args, "|s", &newname))
+ if (!PyArg_ParseTuple(args, "|s:reload", &newname))
+ return NULL;
+ if (self->m_image != NULL)
{
VideoFFmpeg* video = getFFmpeg(self);
// check type of object
@@ -1241,8 +1284,13 @@ static PyGetSetDef imageGetSets[] =
// python type declaration
PyTypeObject ImageFFmpegType =
{
- PyObject_HEAD_INIT(NULL)
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /*ob_size*/
+#endif
"VideoTexture.ImageFFmpeg", /*tp_name*/
sizeof(PyImage), /*tp_basicsize*/
0, /*tp_itemsize*/
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h
index 51f1067c466..fbd04e7e1fc 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.h
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.h
@@ -83,9 +83,10 @@ public:
/// play video
virtual bool play (void);
- /// stop/pause video
+ /// pause video
+ virtual bool pause (void);
+ /// stop video
virtual bool stop (void);
-
/// set play range
virtual void setRange (double start, double stop);
/// set frame rate
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
index c11e7fffecd..1dcc72c8f7d 100644
--- a/source/gameengine/VideoTexture/blendVideoTex.cpp
+++ b/source/gameengine/VideoTexture/blendVideoTex.cpp
@@ -74,7 +74,7 @@ static PyObject * getLastError (PyObject *self, PyObject *args)
static PyObject * setLogFile (PyObject *self, PyObject *args)
{
// get parameters
- if (!PyArg_ParseTuple(args, "s", &Exception::m_logFile))
+ if (!PyArg_ParseTuple(args, "s:setLogFile", &Exception::m_logFile))
return Py_BuildValue("i", -1);
// log file was loaded
return Py_BuildValue("i", 0);
@@ -86,7 +86,7 @@ static PyObject * imageToArray (PyObject * self, PyObject *args)
{
// parameter is Image object
PyObject * pyImg;
- if (!PyArg_ParseTuple(args, "O", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
+ if (!PyArg_ParseTuple(args, "O:imageToArray", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
{
// if object is incorect, report error
PyErr_SetString(PyExc_TypeError, "VideoTexture.imageToArray(image): The value must be a image source object");
@@ -159,8 +159,25 @@ static void registerAllTypes(void)
pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24");
}
+
+#if (PY_VERSION_HEX >= 0x03000000)
+static struct PyModuleDef VideoTexture_module_def = {
+ {}, /* m_base */
+ "VideoTexture", /* m_name */
+ "Module that allows to play video files on textures in GameBlender.", /* m_doc */
+ 0, /* m_size */
+ moduleMethods, /* m_methods */
+ 0, /* m_reload */
+ 0, /* m_traverse */
+ 0, /* m_clear */
+ 0, /* m_free */
+};
+#endif
+
PyObject* initVideoTexture(void)
{
+ PyObject * m;
+
// initialize GL extensions
//bgl::InitExtensions(0);
@@ -175,9 +192,25 @@ PyObject* initVideoTexture(void)
if (PyType_Ready(&TextureType) < 0)
return NULL;
- PyObject * m = Py_InitModule4("VideoTexture", moduleMethods,
- "Module that allows to play video files on textures in GameBlender.",
- (PyObject*)NULL,PYTHON_API_VERSION);
+ /* Use existing module where possible
+ * be careful not to init any runtime vars after this */
+ m = PyImport_ImportModule( "VideoTexture" );
+ if(m) {
+ Py_DECREF(m);
+ return m;
+ }
+ else {
+ PyErr_Clear();
+
+#if (PY_VERSION_HEX >= 0x03000000)
+ m = PyModule_Create(&VideoTexture_module_def);
+#else
+ m = Py_InitModule4("VideoTexture", moduleMethods,
+ "Module that allows to play video files on textures in GameBlender.",
+ (PyObject*)NULL,PYTHON_API_VERSION);
+#endif
+ }
+
if (m == NULL)
return NULL;
@@ -187,9 +220,10 @@ PyObject* initVideoTexture(void)
Py_INCREF(&TextureType);
PyModule_AddObject(m, (char*)"Texture", (PyObject*)&TextureType);
-
+
// init last error description
Exception::m_lastError[0] = '\0';
+
return m;
}