【发布时间】:2022-03-08 05:25:12
【问题描述】:
我正在使用在 Nvidia Jetson nano 上播放的 PyGST 和 Gst.parse_launch 编写 Gstreamer 管道。管道播放 4k 视频并在运行时淡入淡出视频。
我的问题是管道不会连续播放相同的视频。它会一个接一个地播放不同的视频。淡入淡出功能也运行良好。
这是问题的描述:
该管道第一次使用示例视频,例如 video_1.mp4。当我再次播放相同的视频时,它会卡在第一帧,停留在该帧并在几秒钟后退出该过程。
如果我播放 video_1.mp4,然后播放不同的视频,例如 video_2.mp4,那么管道将毫无问题地工作。如果在此之后我播放 video_1.mp4 那么它也会一直播放。
video_1.mp4 的持续时间为 10 秒。如果我在 5 秒处停止 video_1.mp4 并再次播放视频,将显示 video_1.mp4 的第一帧,它将在该帧等待 5 秒,然后在前一个管道停止的同一点继续解码视频.
我怀疑播放同一视频时缓冲区运行时间尚未重置为 0。我不确定为什么会发生这种情况,我将管道设置为 NULL,并尝试在视频完成后进行搜索位置 0 并刷新管道中的元素以将时钟时间重置回 0。也许是语法或我的方式我实施它是不正确的。
下面的这个线程创建管道
import gi
import time
gi.require_version(\'Gst\', \'1.0\')
gi.require_version(\'GstPbutils\', \'1.0\')
gi.require_version(\'GstController\', \'1.0\')
from gi.repository import GObject, Gst, GstPbutils, GstController
from player_thread import PlayerThread
from threading import Timer
import logging
import time
class VideoPlayer():
def __init__(self):
Gst.init(None)
GObject.threads_init()
self.pipeline = Gst.parse_launch (\"\"\"
nvcompositor name=comp sink_0::alpha=1 ! video/x-raw(memory:NVMM),format=RGBA !
nvvidconv ! video/x-raw(memory:NVMM), format=NV12 ! autovideosink name=sinky uridecodebin name=vidsrc !
nvvidconv name=pipeconv ! video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1 ! queue ! comp.sink_0
\"\"\")
self.loop = GObject.MainLoop()
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect(\"message::eos\", self.bus_call, self.loop)
self.bus.connect(\"message::error\", self.bus_call, self.loop)
self.sink = self.pipeline.get_by_name(\'sinky\')
self.convert = self.pipeline.get_by_name(\'pipeconv\')
self.source = self.pipeline.get_by_name(\'vidsrc\')
self.compositor = self.pipeline.get_by_name(\'comp\')
self.source.connect(\"pad-added\", self.on_pad_added)
self.running = False
self.pipeline.set_state(Gst.State.NULL)
self.loop.run()
def get_alpha_controller(self, incoming_pad):
self.pad = incoming_pad
self.control_source = GstController.InterpolationControlSource()
self.control_source.set_property(\'mode\', GstController.InterpolationMode.LINEAR)
self.control_bind = GstController.DirectControlBinding.new(self.pad, \'alpha\', self.control_source)
self.pad.add_control_binding(self.control_bind)
return self.control_source
def fade_video_in(self):
self.compositor_sink_pad = self.compositor.get_static_pad(\'sink_0\')
self.control_source = self.get_alpha_controller(self.compositor_sink_pad)
self.control_source.set(0*Gst.SECOND, 0)
self.control_source.set(2*Gst.SECOND, 1)
def fade_video_out(self):
self.pos = self.pipeline.query_position(Gst.Format.TIME).cur
self.control_source.set(self.pos, 1)
self.control_source.set(self.pos + 1*Gst.SECOND, 0)
def on_pad_added(self, src, new_pad):
print(
\"Received new pad \'{0:s}\' from \'{1:s}\'\".format(
new_pad.get_name(),
src.get_name()))
new_pad_caps = new_pad.get_current_caps()
new_pad_struct = new_pad_caps.get_structure(0)
new_pad_type = new_pad_struct.get_name()
if new_pad_type.startswith(\"video/x-raw\"):
sink_pad = self.convert.get_static_pad(\"sink\")
else:
print(
\"It has type \'{0:s}\' which is not raw audio/video. Ignoring.\".format(new_pad_type))
return
# if our converter is already linked, we have nothing to do here
# if(sink_pad.is_linked()):
# print(\"We are already linked. Ignoring.\")
# return
# attempt the link
ret = new_pad.link(sink_pad)
if not ret == Gst.PadLinkReturn.OK:
print(\"Type is \'{0:s}}\' but link failed\".format(new_pad_type))
else:
print(\"Link succeeded (type \'{0:s}\')\".format(new_pad_type))
return
def play_video(self, video_url, scene_name):
self.compositor.props.background = 1
self.running = True
self.scene_name = scene_name
self.video_url = video_url
print(self.video_url)
self.source.props.uri = self.video_url
self.sink.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0 * Gst.SECOND)
self.pipeline.set_state(Gst.State.READY)
self.pipeline.get_state(Gst.CLOCK_TIME_NONE)
self.pipeline.set_state(Gst.State.PAUSED)
self.pipeline.set_state(Gst.State.PLAYING)
def stop_video(self):
self.running = False
self.pipeline.set_state(Gst.State.NULL)
self.pipeline.set_state(Gst.State.READY)
self.pipeline.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0.0 * Gst.SECOND )
self.source.props.uri = \"\"
def bus_call(self, bus, message, loop):
t = message.type
if t == Gst.MessageType.EOS:
self.stop_video()
elif t == Gst.MessageType.ERROR:
print(message.parse_error())
elif message.type == Gst.MessageType.SEGMENT_DONE:
# self.fade_video_out()
pass
else:
# should not get here
print(\"ERROR: Unexpected message received\")
return True
def exit(self):
self.loop.quit()
这些是发生错误时的 Gstreamer 调试日志
0:05:51.707439047 1756 0x7f7800e540 WARN aggregator gstaggregator.c:1717:gst_aggregator_query_latency_unlocked:<comp> Latency query failed
0:05:51.709119977 1756 0x7f70007460 WARN basesrc gstbasesrc.c:3583:gst_base_src_start_complete:<source> pad not activated yet
0:05:51.709991980 1756 0x7f70007460 WARN basesrc gstbasesrc.c:3583:gst_base_src_start_complete:<source> pad not activated yet
sending message {\"action\": \"STATE_CHANGE\", \"body\": {\"videoActiveVideo\": \"test\"}}
0:05:51.714088392 1756 0x106e9630 WARN qtdemux qtdemux_types.c:233:qtdemux_type_get: unknown QuickTime node type pasp
0:05:51.714195686 1756 0x106e9630 WARN qtdemux qtdemux.c:3031:qtdemux_parse_trex:<qtdemux11> failed to find fragment defaults for stream 1
Opening in BLOCKING MODE
0:05:51.759452369 1756 0x106fae80 WARN v4l2 gstv4l2object.c:4447:gst_v4l2_object_probe_caps:<nvv4l2decoder11:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Unknown error -1
0:05:51.759527839 1756 0x106fae80 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f64022090 Failed to determine interlace mode
0:05:51.759581956 1756 0x106fae80 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f64022090 Failed to determine interlace mode
0:05:51.759638728 1756 0x106fae80 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f64022090 Failed to determine interlace mode
NvMMLiteOpen : Block : BlockType = 261
NVMEDIA: Reading vendor.tegra.display-size : status: 6
NvMMLiteBlockCreate : Block : BlockType = 261
0:05:51.865431565 1756 0x106fae80 WARN v4l2 gstv4l2object.c:4447:gst_v4l2_object_probe_caps:<nvv4l2decoder11:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Unknown error -1
0:05:51.865703395 1756 0x106fae80 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f64022090 Failed to determine interlace mode
0:05:51.865971579 1756 0x106fae80 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f64022090 Failed to determine interlace mode
0:05:51.866240232 1756 0x106fae80 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f64022090 Failed to determine interlace mode
Received new pad \'src_16\' from \'vidsrc\'
Link succeeded (type \'video/x-raw\')
0:05:51.876923175 1756 0x106fae80 WARN v4l2videodec gstv4l2videodec.c:1673:gst_v4l2_video_dec_decide_allocation:<nvv4l2decoder11> Duration invalid, not setting latency
0:05:51.877534077 1756 0x106fae80 WARN v4l2bufferpool gstv4l2bufferpool.c:1065:gst_v4l2_buffer_pool_start:<nvv4l2decoder11:pool:src> Uncertain or not enough buffers, enabling copy threshold
0:05:51.883864038 1756 0x7f5c007850 WARN v4l2bufferpool gstv4l2bufferpool.c:1512:gst_v4l2_buffer_pool_dqbuf:<nvv4l2decoder11:pool:src> Driver should never set v4l2_buffer.field to ANY
0:05:51.891684769 1756 0x7f7800e540 FIXME basesink gstbasesink.c:3145:gst_base_sink_default_event:<sinky-actual-sink-nvoverlay> stream-start event without group-id. Consider implementing group-id handling in the upstream elements
0:05:51.893670863 1756 0x7f7800e540 WARN nvcompositor gstnvcompositor.c:980:gst_nvcompositor_negotiated_caps:<comp> Release old pool
这些是您播放不同视频并且管道重置后的日志(管道正常工作)
0:06:21.907924995 1756 0x7f580cc320 WARN aggregator gstaggregator.c:1717:gst_aggregator_query_latency_unlocked:<comp> Latency query failed
0:06:21.909268156 1756 0x7f70007460 WARN basesrc gstbasesrc.c:3583:gst_base_src_start_complete:<source> pad not activated yet
0:06:21.910099324 1756 0x7f70007460 WARN basesrc gstbasesrc.c:3583:gst_base_src_start_complete:<source> pad not activated yet
sending message {\"action\": \"STATE_CHANGE\", \"body\": {\"videoActiveVideo\": \"test1\"}}
0:06:21.913367433 1756 0x7f7800e720 WARN qtdemux qtdemux_types.c:233:qtdemux_type_get: unknown QuickTime node type gsst
0:06:21.914455326 1756 0x7f7800e720 WARN qtdemux qtdemux_types.c:233:qtdemux_type_get: unknown QuickTime node type gstd
0:06:21.914529130 1756 0x7f7800e720 WARN qtdemux qtdemux.c:3031:qtdemux_parse_trex:<qtdemux12> failed to find fragment defaults for stream 1
0:06:21.914677884 1756 0x7f7800e720 WARN qtdemux qtdemux.c:3031:qtdemux_parse_trex:<qtdemux12> failed to find fragment defaults for stream 2
Opening in BLOCKING MODE
0:06:21.964505314 1756 0x106ee320 WARN v4l2 gstv4l2object.c:4447:gst_v4l2_object_probe_caps:<nvv4l2decoder12:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Unknown error -1
0:06:21.964574795 1756 0x106ee320 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f5802e8e0 Failed to determine interlace mode
0:06:21.964636619 1756 0x106ee320 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f5802e8e0 Failed to determine interlace mode
0:06:21.964687871 1756 0x106ee320 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f5802e8e0 Failed to determine interlace mode
NvMMLiteOpen : Block : BlockType = 261
NVMEDIA: Reading vendor.tegra.display-size : status: 6
NvMMLiteBlockCreate : Block : BlockType = 261
0:06:22.070629669 1756 0x106ee320 WARN v4l2 gstv4l2object.c:4447:gst_v4l2_object_probe_caps:<nvv4l2decoder12:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Unknown error -1
0:06:22.070809622 1756 0x106ee320 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f5802e8e0 Failed to determine interlace mode
0:06:22.071008898 1756 0x106ee320 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f5802e8e0 Failed to determine interlace mode
0:06:22.071295416 1756 0x106ee320 WARN v4l2 gstv4l2object.c:2388:gst_v4l2_object_add_interlace_mode:0x7f5802e8e0 Failed to determine interlace mode
Received new pad \'src_17\' from \'vidsrc\'
Link succeeded (type \'video/x-raw\')
Received new pad \'src_18\' from \'vidsrc\'
It has type \'audio/x-raw\' which is not raw audio/video. Ignoring.
0:06:22.080439932 1756 0x106ee320 WARN v4l2videodec gstv4l2videodec.c:1673:gst_v4l2_video_dec_decide_allocation:<nvv4l2decoder12> Duration invalid, not setting latency
0:06:22.080866610 1756 0x106ee320 WARN v4l2bufferpool gstv4l2bufferpool.c:1065:gst_v4l2_buffer_pool_start:<nvv4l2decoder12:pool:src> Uncertain or not enough buffers, enabling copy threshold
0:06:22.085282770 1756 0x7f5c0078f0 WARN v4l2bufferpool gstv4l2bufferpool.c:1512:gst_v4l2_buffer_pool_dqbuf:<nvv4l2decoder12:pool:src> Driver should never set v4l2_buffer.field to ANY
0:06:22.091041154 1756 0x7f580cc320 FIXME basesink gstbasesink.c:3145:gst_base_sink_default_event:<sinky-actual-sink-nvoverlay> stream-start event without group-id. Consider implementing group-id handling in the upstream elements
0:06:22.098388747 1756 0x7f580cc320 WARN nvcompositor gstnvcompositor.c:980:gst_nvcompositor_negotiated_caps:<comp> Release old pool
0:06:22.108516102 1756 0x7f580cc320 ERROR omx gstomx.c:256:gst_omx_component_handle_messages:<sinky-actual-sink-nvoverlay> yuv420 port 0 was not flushing
-
请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。
标签: python gstreamer nvidia-jetson-nano pygst