我正在尝试使用appsink建立管道,它会占用大量内存:

#!/usr/bin/env python

import sys

import gi


gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst


def main():
    GObject.threads_init()
    Gst.init(None)
    # pipeline = Gst.parse_launch('fakesrc ! fakesink')
    pipeline = Gst.parse_launch('fakesrc ! appsink')

    loop = GObject.MainLoop()

    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except:
        pass

    pipeline.set_state(Gst.State.NULL)


if __name__ == '__main__':
    sys.exit(main())


即使没有设置连接,内存也在不断增加。我尝试使用sink.connect("new-sample", handler, sink)连接功能-它也会泄漏内存。还尝试将处理程序添加到总线(读取gst可能会使未传递到python的消息排队并永久保存的地方)-两者均无济于事。

我需要在某个地方释放内存吗?我在C代码中找到了对gst_object_unref的调用,但是我不确定是否应该在python代码中使用unref。

同样,简单的管道'fakesrc ! fakesink'不会泄漏内存。

该脚本在Docker内部运行(不确定是否很重要,不幸的是,我无法在Docker外部进行测试):

FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /code
WORKDIR /code
ADD Pipfile Pipfile.lock /code/
RUN apt-get update && apt-get install -y software-properties-common cmake \
    gobject-introspection libgirepository1.0-dev libcairo2-dev \
    libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools \
    python-gst-1.0
RUN pip install pipenv && pipenv install --system
ADD . /code/
WORKDIR /code/src
EXPOSE 8181
CMD python main.py

最佳答案

Appsink有一个队列,用于存储传入的样本。默认情况下,此大小是无限的。您可以通过appsink的max-buffersdrop属性进行控制,以使其不会无限增长。

但是,您实际要做的是主动将这些样本从appsink中取出并进行处理-或至少将它们删除。

new-sample信号是一个好的开始。如果触发了该信号,则新样品已到达并准备进行处理。我在这里记不清Python,但是您想调用appsink对象的pull_sample方法以将样品所有权从appsink转移到您自己。一旦超出范围,该样本应正确发布-我想。

编辑:确保发出信号。有一个appsink属性emit-signals,默认情况下处于关闭状态。但是我通常会做C东西,所以我不确定Python确实会翻转某些开关,所以它开箱即用。

关于python - 使用gsteramer appsink的内存泄漏(Python绑定(bind)),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51177679/

10-12 21:24