使用 appsink 时,gstreamer 管道 运行 速度 reading/decoding
Have gstreamer pipeline run at reading/decoding speed when using appsink
如果我创建一个简单的管道来将 mkv 文件读取到 fakesink 中,它将 运行 与机器读取和处理文件的速度一样快:
$ time gst-launch-1.0 filesrc location=bar.mkv ! matroskademux ! fakesink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Got EOS from element "pipeline0".
Execution ended after 0:00:00.000402211
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
real 0m0.020s
user 0m0.016s
sys 0m0.004s
有问题的文件有 5 秒长,但这个 运行 是几分之一秒。现在,如果我想在程序中使用相同的内容,并使用 appsink
而不是 fakesink
,这个 运行s 的播放速度。考虑这个简单的 Python 程序:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from gi.repository import GObject
def on_message(bus, msg, loop):
if msg.type == Gst.MessageType.EOS:
print("End of stream")
loop.quit()
return True
def new_sample(sink, data):
sample = sink.emit('pull-sample')
return Gst.FlowReturn.OK
def main():
Gst.init(None)
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
src = Gst.ElementFactory.make('filesrc')
demux = Gst.ElementFactory.make('matroskademux')
sink = Gst.ElementFactory.make(sys.argv[1])
src.set_property('location', 'bar.mkv')
if sys.argv[1] == 'appsink':
sink.set_property('emit-signals', True)
sink.connect('new-sample', new_sample, None)
pipeline.add(src)
pipeline.add(demux)
pipeline.add(sink)
src.link(demux)
def pad_added(element, pad):
stream = pad.query_caps(None).to_string()
pad.link(sink.get_static_pad('sink'))
demux.connect('pad-added', pad_added)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', on_message, loop)
pipeline.set_state(Gst.State.PLAYING)
loop.run()
pipeline.set_state(Gst.State.NULL)
if __name__ == '__main__':
main()
如果我运行它有一个fakesink,它仍然非常快:
$ time python ./foo.py fakesink
End of stream
real 0m0.095s
user 0m0.078s
sys 0m0.018s
但是如果我使用 appsink,只需要 5 秒多一点:
$ time python ./foo.py appsink
End of stream
real 0m5.068s
user 0m0.099s
sys 0m0.014s
这表明 gstreamer 正在同步帧,因此它们 运行 以文件中指定的帧速率。我们可以通过 appsink
获得 fakesink
行为吗?
此行为通过接收器的 sync
属性 控制。默认情况下,fakesink
将此设置为 false
。将此 属性 设置为 true
以获得与 appsink
.
相同的行为
$ time gst-launch-1.0 filesrc location=bar.mkv ! matroskademux ! fakesink sync=true
如果我创建一个简单的管道来将 mkv 文件读取到 fakesink 中,它将 运行 与机器读取和处理文件的速度一样快:
$ time gst-launch-1.0 filesrc location=bar.mkv ! matroskademux ! fakesink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Got EOS from element "pipeline0".
Execution ended after 0:00:00.000402211
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
real 0m0.020s
user 0m0.016s
sys 0m0.004s
有问题的文件有 5 秒长,但这个 运行 是几分之一秒。现在,如果我想在程序中使用相同的内容,并使用 appsink
而不是 fakesink
,这个 运行s 的播放速度。考虑这个简单的 Python 程序:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from gi.repository import GObject
def on_message(bus, msg, loop):
if msg.type == Gst.MessageType.EOS:
print("End of stream")
loop.quit()
return True
def new_sample(sink, data):
sample = sink.emit('pull-sample')
return Gst.FlowReturn.OK
def main():
Gst.init(None)
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
src = Gst.ElementFactory.make('filesrc')
demux = Gst.ElementFactory.make('matroskademux')
sink = Gst.ElementFactory.make(sys.argv[1])
src.set_property('location', 'bar.mkv')
if sys.argv[1] == 'appsink':
sink.set_property('emit-signals', True)
sink.connect('new-sample', new_sample, None)
pipeline.add(src)
pipeline.add(demux)
pipeline.add(sink)
src.link(demux)
def pad_added(element, pad):
stream = pad.query_caps(None).to_string()
pad.link(sink.get_static_pad('sink'))
demux.connect('pad-added', pad_added)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', on_message, loop)
pipeline.set_state(Gst.State.PLAYING)
loop.run()
pipeline.set_state(Gst.State.NULL)
if __name__ == '__main__':
main()
如果我运行它有一个fakesink,它仍然非常快:
$ time python ./foo.py fakesink
End of stream
real 0m0.095s
user 0m0.078s
sys 0m0.018s
但是如果我使用 appsink,只需要 5 秒多一点:
$ time python ./foo.py appsink
End of stream
real 0m5.068s
user 0m0.099s
sys 0m0.014s
这表明 gstreamer 正在同步帧,因此它们 运行 以文件中指定的帧速率。我们可以通过 appsink
获得 fakesink
行为吗?
此行为通过接收器的 sync
属性 控制。默认情况下,fakesink
将此设置为 false
。将此 属性 设置为 true
以获得与 appsink
.
$ time gst-launch-1.0 filesrc location=bar.mkv ! matroskademux ! fakesink sync=true