【问题标题】:Python-Gstreamer for dynamic control of element propertiesPython-Gstreamer 用于动态控制元素属性
【发布时间】:2018-08-10 19:08:51
【问题描述】:

我正在使用带有 Python 绑定的 Gstreamer 1.0。 以下是考虑到 Opengl plugins 我正在尝试构建的管道:

gltestsrc -> gltransformation -> glimagesink

我正在尝试根据从外部硬件设备接收到的值动态修改元素“gltransformation”的属性。这是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 的sn-p:

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 获取输入并更改'gltransformation' 的rotation-x/y/z。 我不知道,为什么在我的情况下这是一个问题。

  #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

其余代码与之前在帖子中描述的相同(稍作修改以使用线程)。但是,省略了以下代码:

#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)

【问题讨论】:

  • 我的猜测是控件绑定对象,您的 cb,期望为您的 cs 对象的“模式”属性和/或旋转-x/y/z 属性的 GParamSpecs 找到 GParamSpec你的 gltrnsfrm 对象。最有可能是 cs 模式,因为错误消息指的是绑定对象 pspec。希望这会有所帮助。
  • @HughFisher :添加了更多显示绑定对象信息的调试信息。你能建议我在这里做什么吗?

标签: opengl gstreamer python-gstreamer


【解决方案1】:

这里的问题是 gltransformation 属性是不可控的。即他们在属性创建时没有GST_PARAM_CONTROLLABLE 标志in the code

您可以通过向上游提出补丁或不依赖可控属性来为 gltransformation 添加可控性。

【讨论】:

  • 是否可以在 python 脚本中使用 'g_object_class_install_property' 并修改属性?还是有另一种方法可以动态设置rotation-x/y/z?
  • 不,g_object_class_install_property 用于子类。您不必使用控件绑定来动态设置属性。您可以随时拨打set_property 多次。
  • @ysteet00 在我的情况下,只要视频正在播放,我想获得更新的值(至少每 100 毫秒)。下一步是使用实时视频,而不是“gltestsrc”
  • 然后你可以用你喜欢的任何方法来做。无论是 async/await、glib mainloop、运行额外的 python 线程等
  • 我按照您的建议继续拨打set_property,并且成功了。然而,视频的渲染是不连贯的——除了当前帧之外,还可以看到之前的帧。关于如何过滤掉它并获得平滑的黑色背景的任何建议,除了当前帧?这是图片rotation-yrotation-yrotation-z
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 2019-08-21
  • 2023-03-19
  • 2017-02-06
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
相关资源
最近更新 更多