使用 Cython 将 python 对象传递给 C Gstreamer 函数

问题描述 投票:0回答:0

我将 Python3.6 与 GStreamer-1.0PyGObject(用于 python 访问)一起使用,以从相机 (tiscamera) 读取视频帧。

帧是通过 python 代码获取的,最终我得到了一个 GstBuffer:

import gi
gi.require_version("Gst", "1.0")
from gi.repository import 

# Set up
Gst.init([])
pipeline = Gst.parse_launch("tcambin serial=12345678 name=source ! video/x-raw,format=GRAY8,width=1920,height=1080,framerate=18/1 ! appsink name=sink")
sink = pipeline.get_by_name("sink")
sink.set_property("max-buffers", 10)
sink.set_property("drop", 1)
sink.set_property("emit-signals", 1)
pipeline.set_state(Gst.State.PLAYING)

# Get sample
sample = sink.emit("pull-sample")
buffer = sample.get_buffer()
meta = buffer.get_meta("TcamStatisticsMetaApi")

meta的类型是gi.repository.Gst.Meta,但在C中它实际上是TcamStatisticsMeta*,看tiscamera的c代码示例10-metadata.c就可以理解。那里的C代码是:

GstBuffer* buffer = gst_sample_get_buffer(sample);
GstMeta* meta = gst_buffer_get_meta(buffer, g_type_from_name("TcamStatisticsMetaApi"));
GstStructure* struc = ((TcamStatisticsMeta*)meta)->structure;

我的问题是,在 Python 中,我无法访问

TcamStatisticsMeta
中定义的结构属性。我只是缺少从 GstMeta* 到 TcamStatisticsMeta* 的转换位以及 TcamStatisticsMeta* 到 PyObject 的转换。

有人知道如何在不需要修改/重新编译 gstreamer-1.0 C 代码的情况下完成这项工作吗?也许使用 Cython?

我已经开始使用 Cython 尝试使用从 Python 获得的数据调用 C 函数。 python对象是

gi.repository.Gst.Buffer
类型,函数应该得到一个
GstBuffer*
,但我找不到从Python对象获取struct指针的方法。

这是我的 .pxd 文件:

cdef extern from "gstreamer-1.0/gstmetatcamstatistics.h":
    ctypedef unsigned long GType
    ctypedef struct GstBuffer:
        pass
    ctypedef struct GstMeta:
        pass

    GstMeta* gst_buffer_get_meta(GstBuffer* buffer, GType api)
    GType g_type_from_name(const char* name)

我的 .pyx 文件:

from my_pxd_file cimport GType, g_type_from_name, GstMeta, gst_buffer_get_meta

cdef void c_a(buffer):
    cdef char* tcam_statistics_meta_api = "TcamStatisticsMetaApi"
    cdef GType gt = g_type_from_name(tcam_statistics_meta_api)
    cdef GstMeta* meta = gst_buffer_get_meta(buffer, gt)


def a(buffer):
    c_a(buffer)

还有我的 python 文件:

# No need to use pyximport as I've cythonized the code in setup.py
from . import my_pyx_file
...
buffer = sample.get_buffer()
my_pyx_file.a(buffer)

这会导致 SIGSEGV 错误:

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

问题是我无法将缓冲区转换为 GstBuffer*。有谁知道怎么做?

在Pycharm中调试,居然可以看到GstBuffer*地址:

<Gst.Buffer object at 0x7f3a0b4fc348 (GstBuffer at 0x7f39ec007060)>

但是我如何获得这个地址,以便我可以将它传递给

gst_buffer_get_meta
? 有没有一种规范的 Cython 方法可以做到这一点?

python-3.x cython gstreamer-1.0
© www.soinside.com 2019 - 2024. All rights reserved.