Python-动态控制元素属性的Gstreamer
Python-Gstreamer for dynamic control of element properties
我正在使用带有 Python 绑定的 Gstreamer 1.0。
下面是我尝试构建的考虑 Opengl plugins 的管道:
gltestsrc -> gltransformation -> glimagesink
我正在尝试修改元素 'gltransformation' dynamically based on the values received from external hardware device. Here is the link 的属性以解决类似的问题,但它对我的用例没有太大帮助。
下面是 python 脚本的片段:
import gi
gi.require_version('Gst','1.0')
from gi.repository import Gst,GstController
#global variables
#the values of a,b,c get updated for certain events dynamically based on external hardware
a = 0
b= 0
c = 0
source = Gst.ElementFactory.make("gltestsrc", "source")
gltrnsfrm = Gst.ElementFactory.make("gltransformation","gltrnsfrm")
sink = Gst.ElementFactory.make("glimagesink", "sink")
# create the empty pipeline
pipeline = Gst.Pipeline.new("test-pipeline")
if not pipeline or not source or not gltrnsfrm or not sink:
print("ERROR: Not all elements could be created")
sys.exit(1)
# build the pipeline
pipeline.add(source,gltrnsfrm,sink)
if not source.link(gltrnsfrm):
print("ERROR: Could not link source to gltrsnfrm")
sys.exit(1)
if not gltrnsfrm.link(sink):
print("ERROR: Could not link gltrsnfrm to sink")
sys.exit(1)
# modify the gltransformation's properties
gltrnsfrm.set_property("rotation-z",a)
gltrnsfrm.set_property("rotation-x",b)
gltrnsfrm.set_property("rotation-y",c)
#dynamic controller
cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
cb= Gstcontorller.DirectControlBinding.new(gltrnsfrm,"rotation-x",cs)
gltrnsfrm.add_control_binding(cb)
#modify the values
cs.set(0*Gst.SECOND,b) #use updated values of b
cs.set(1*Gst.SECOND,b)
上面的例子只显示了1个元素属性的修改,但是我还有其他属性需要根据a,b & c
的值进行修改。
执行上面的脚本会出现以下错误:
GStreamer-CRITICAL : gst_object_add_control_binding: assertion 'binding->pspec' failed.
我想我必须在 python 中设置更多属性才能使其正常工作。
有人能解决这个问题吗?
编辑:
根据 Hugh Fisher 的建议,我试图追溯文件的来源。这是 original code 的片段:
GST_INFO_OBJECT (object, "trying to put property '%s' under control",
binding->name);
/* check if the object has a property of that name */
if ((pspec =
g_object_class_find_property (G_OBJECT_GET_CLASS (object),
binding->name))) {
GST_DEBUG_OBJECT (object, " psec->flags : 0x%08x", pspec->flags);
/* check if this param is witable && controlable && !construct-only */
if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE |
G_PARAM_CONSTRUCT_ONLY)) ==
(G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) {
binding->pspec = pspec;
} else {
GST_WARNING_OBJECT (object,
"property '%s' on class '%s' needs to "
"be writeable, controlable and not construct_only", binding->name,
G_OBJECT_TYPE_NAME (object));
}
} else {
GST_WARNING_OBJECT (object, "class '%s' has no property '%s'",
G_OBJECT_TYPE_NAME (object), binding->name);
}
gst_object_unref (object);
这是我的脚本的日志文件:
0:00:00.174410648 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:207:gst_object_init:<GstObject@0x10b0020>[00m 0x10b0020 new
0:00:00.174697421 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:207:gst_object_init:<GstObject@0x10b20f0>[00m 0x10b20f0 new
0:00:00.174716708 [336m 8309[00m 0xd1b750 [36mINFO [00m [00m gstcontrolbinding gstcontrolbinding.c:144:gst_control_binding_constructor:<gltrnsfrm>[00m trying to put property 'rotation-x' under control
0:00:00.174723927 [336m 8309[00m 0xd1b750 [37mDEBUG [00m [00m gstcontrolbinding gstcontrolbinding.c:150:gst_control_binding_constructor:<gltrnsfrm>[00m psec->flags : 0x000000e3
0:00:00.174729088 [336m 8309[00m 0xd1b750 [33;01mWARN [00m [00m gstcontrolbinding gstcontrolbinding.c:161:gst_control_binding_constructor:<gltrnsfrm>[00m property 'rotation-x' on class 'GstGLTransformation' needs to be writeable, controlable and not construct_only
0:00:00.174733951 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:264:gst_object_unref:<gltrnsfrm>[00m 0x10a60e0 unref 4->3
(python3:8309): GStreamer-CRITICAL **: 10:37:00.609: gst_object_add_control_binding: assertion 'binding->pspec' failed
根据 'gltransformation' 的手册页,属性 rotation-x/y/z 是可写和可读的。这里还有一个应用程序 link,它从 GUI 获取输入并将 rotation-x/y/z 更改为 'gltransformation'。
我不知道,为什么在我的情况下这是一个问题。
#gst-inspect-1.0 gltransformation
translation-x : Translates the video at the X-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
translation-y : Translates the video at the Y-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
translation-z : Translates the video at the Z-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-x : Rotates the video around the X-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-y : Rotates the video around the Y-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-z : Rotates the video around the Z-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
编辑 2:更新了代码,解决了以下问题:
class Thread(object):
def __init__(self):
thread = threading.Thread(target=self.get)
self.gltrnsfrm = Gst.ElementFactory.make("gltransformation","gltrnsfrm")
thread.start()
def get(self):
try:
global a,b,c
while True:
self.gltrnsfrm.set_property("rotation-z",a)
self.gltrnsfrm.set_property("rotation-x",b)
self.gltrnsfrm.set_property("rotation-y",c)
#time.sleep(0.01)
except KeyboardInterrupt:
pass
其余代码与之前在 post 中描述的相同(稍作调整以使用线程)。但是,省略了以下代码:
#dynamic controller
cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
cb= Gstcontorller.DirectControlBinding.new(gltrnsfrm,"rotation-x",cs)
gltrnsfrm.add_control_binding(cb)
#modify the values
cs.set(0*Gst.SECOND,b) #use updated values of b
cs.set(1*Gst.SECOND,b)
这里的问题是gltransformation属性不可控。即他们在 属性 创建 in the code.
时没有 GST_PARAM_CONTROLLABLE
标志
您可以通过在上游提出补丁或不依赖可控属性来增加 gltransformation 的可控性。
我正在使用带有 Python 绑定的 Gstreamer 1.0。 下面是我尝试构建的考虑 Opengl plugins 的管道:
gltestsrc -> gltransformation -> glimagesink
我正在尝试修改元素 'gltransformation' dynamically based on the values received from external hardware device. Here is the link 的属性以解决类似的问题,但它对我的用例没有太大帮助。 下面是 python 脚本的片段:
import gi
gi.require_version('Gst','1.0')
from gi.repository import Gst,GstController
#global variables
#the values of a,b,c get updated for certain events dynamically based on external hardware
a = 0
b= 0
c = 0
source = Gst.ElementFactory.make("gltestsrc", "source")
gltrnsfrm = Gst.ElementFactory.make("gltransformation","gltrnsfrm")
sink = Gst.ElementFactory.make("glimagesink", "sink")
# create the empty pipeline
pipeline = Gst.Pipeline.new("test-pipeline")
if not pipeline or not source or not gltrnsfrm or not sink:
print("ERROR: Not all elements could be created")
sys.exit(1)
# build the pipeline
pipeline.add(source,gltrnsfrm,sink)
if not source.link(gltrnsfrm):
print("ERROR: Could not link source to gltrsnfrm")
sys.exit(1)
if not gltrnsfrm.link(sink):
print("ERROR: Could not link gltrsnfrm to sink")
sys.exit(1)
# modify the gltransformation's properties
gltrnsfrm.set_property("rotation-z",a)
gltrnsfrm.set_property("rotation-x",b)
gltrnsfrm.set_property("rotation-y",c)
#dynamic controller
cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
cb= Gstcontorller.DirectControlBinding.new(gltrnsfrm,"rotation-x",cs)
gltrnsfrm.add_control_binding(cb)
#modify the values
cs.set(0*Gst.SECOND,b) #use updated values of b
cs.set(1*Gst.SECOND,b)
上面的例子只显示了1个元素属性的修改,但是我还有其他属性需要根据a,b & c
的值进行修改。
执行上面的脚本会出现以下错误:
GStreamer-CRITICAL : gst_object_add_control_binding: assertion 'binding->pspec' failed.
我想我必须在 python 中设置更多属性才能使其正常工作。 有人能解决这个问题吗?
编辑: 根据 Hugh Fisher 的建议,我试图追溯文件的来源。这是 original code 的片段:
GST_INFO_OBJECT (object, "trying to put property '%s' under control",
binding->name);
/* check if the object has a property of that name */
if ((pspec =
g_object_class_find_property (G_OBJECT_GET_CLASS (object),
binding->name))) {
GST_DEBUG_OBJECT (object, " psec->flags : 0x%08x", pspec->flags);
/* check if this param is witable && controlable && !construct-only */
if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE |
G_PARAM_CONSTRUCT_ONLY)) ==
(G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) {
binding->pspec = pspec;
} else {
GST_WARNING_OBJECT (object,
"property '%s' on class '%s' needs to "
"be writeable, controlable and not construct_only", binding->name,
G_OBJECT_TYPE_NAME (object));
}
} else {
GST_WARNING_OBJECT (object, "class '%s' has no property '%s'",
G_OBJECT_TYPE_NAME (object), binding->name);
}
gst_object_unref (object);
这是我的脚本的日志文件:
0:00:00.174410648 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:207:gst_object_init:<GstObject@0x10b0020>[00m 0x10b0020 new
0:00:00.174697421 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:207:gst_object_init:<GstObject@0x10b20f0>[00m 0x10b20f0 new
0:00:00.174716708 [336m 8309[00m 0xd1b750 [36mINFO [00m [00m gstcontrolbinding gstcontrolbinding.c:144:gst_control_binding_constructor:<gltrnsfrm>[00m trying to put property 'rotation-x' under control
0:00:00.174723927 [336m 8309[00m 0xd1b750 [37mDEBUG [00m [00m gstcontrolbinding gstcontrolbinding.c:150:gst_control_binding_constructor:<gltrnsfrm>[00m psec->flags : 0x000000e3
0:00:00.174729088 [336m 8309[00m 0xd1b750 [33;01mWARN [00m [00m gstcontrolbinding gstcontrolbinding.c:161:gst_control_binding_constructor:<gltrnsfrm>[00m property 'rotation-x' on class 'GstGLTransformation' needs to be writeable, controlable and not construct_only
0:00:00.174733951 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:264:gst_object_unref:<gltrnsfrm>[00m 0x10a60e0 unref 4->3
(python3:8309): GStreamer-CRITICAL **: 10:37:00.609: gst_object_add_control_binding: assertion 'binding->pspec' failed
根据 'gltransformation' 的手册页,属性 rotation-x/y/z 是可写和可读的。这里还有一个应用程序 link,它从 GUI 获取输入并将 rotation-x/y/z 更改为 'gltransformation'。 我不知道,为什么在我的情况下这是一个问题。
#gst-inspect-1.0 gltransformation
translation-x : Translates the video at the X-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
translation-y : Translates the video at the Y-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
translation-z : Translates the video at the Z-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-x : Rotates the video around the X-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-y : Rotates the video around the Y-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-z : Rotates the video around the Z-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
编辑 2:更新了代码,解决了以下问题:
class Thread(object):
def __init__(self):
thread = threading.Thread(target=self.get)
self.gltrnsfrm = Gst.ElementFactory.make("gltransformation","gltrnsfrm")
thread.start()
def get(self):
try:
global a,b,c
while True:
self.gltrnsfrm.set_property("rotation-z",a)
self.gltrnsfrm.set_property("rotation-x",b)
self.gltrnsfrm.set_property("rotation-y",c)
#time.sleep(0.01)
except KeyboardInterrupt:
pass
其余代码与之前在 post 中描述的相同(稍作调整以使用线程)。但是,省略了以下代码:
#dynamic controller
cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
cb= Gstcontorller.DirectControlBinding.new(gltrnsfrm,"rotation-x",cs)
gltrnsfrm.add_control_binding(cb)
#modify the values
cs.set(0*Gst.SECOND,b) #use updated values of b
cs.set(1*Gst.SECOND,b)
这里的问题是gltransformation属性不可控。即他们在 属性 创建 in the code.
时没有GST_PARAM_CONTROLLABLE
标志
您可以通过在上游提出补丁或不依赖可控属性来增加 gltransformation 的可控性。