Page 1 of 1

Gstreamer spielt dasselbe Video nicht nacheinander ab

Posted: 25 Jan 2025, 12:55
by Guest
Ich schreibe eine Gstreamer-Pipeline mit PyGST und Gst.parse_launch, die auf einem Nvidia Jetson Nano läuft. Die Pipeline spielt 4K-Videos ab und blendet die Videos zur Laufzeit ein und aus.
Mein Problem ist, dass die Pipeline nicht dasselbe Video nacheinander abspielt. Es werden problemlos verschiedene Videos nacheinander abgespielt. Die Fade-Funktion funktioniert auch gut.
Hier ist eine Beschreibung des Problems:
Die Pipeline funktioniert beim ersten Mal mit einem Beispielvideo wie video_1.mp4. Wenn ich dasselbe Video noch einmal abspiele, bleibt es beim ersten Bild hängen. Bleiben Sie bei diesem Bild und beenden Sie den Vorgang nach ein paar Sekunden.
Wenn ich video_1.mp4 abspiele und dann a Wenn Sie ein anderes Video wie video_2.mp4 herunterladen, funktioniert die Pipeline ohne Probleme. Wenn ich danach video_1.mp4 abspiele, wird es auch vollständig abgespielt.
video_1.mp4 hat eine Dauer von 10 Sekunden. Wenn ich video_1.mp4 nach 5 Sekunden stoppe und das Video erneut abspiele, wird der erste Frame von video_1.mp4 angezeigt, bei diesem Frame wird 5 Sekunden gewartet und das Video dann an der gleichen Stelle dekodiert, an der die vorherige Pipeline aufgehört hat .
Mein Verdacht ist, dass die Pufferlaufzeit beim Abspielen desselben Videos nicht auf 0 zurückgesetzt wurde. Ich bin mir nicht sicher, warum das passiert. Ich habe die Pipeline auf NULL gesetzt und versucht, eine Suchposition 0 durchzuführen und die Elemente in der Pipeline zu leeren, nachdem das Video beendet ist, um die Uhrzeit wieder auf 0 zurückzusetzen. Vielleicht liegt es an der Syntax oder an der Art und Weise, wie ich Die Implementierung ist falsch.
Dieser Thread unten erstellt die Pipeline

Code: Select all

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()
Dies sind die Gstreamer-Debug-Protokolle, wenn der Fehler auftritt

Code: Select all

0:05:51.707439047  1756   0x7f7800e540 WARN              aggregator gstaggregator.c:1717:gst_aggregator_query_latency_unlocked: Latency query failed
0:05:51.709119977  1756   0x7f70007460 WARN                 basesrc gstbasesrc.c:3583:gst_base_src_start_complete: pad not activated yet
0:05:51.709991980  1756   0x7f70007460 WARN                 basesrc gstbasesrc.c:3583:gst_base_src_start_complete: 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: 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: 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: 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:  Duration invalid, not setting latency
0:05:51.877534077  1756     0x106fae80 WARN          v4l2bufferpool gstv4l2bufferpool.c:1065:gst_v4l2_buffer_pool_start: Uncertain or not enough buffers, enabling copy threshold
0:05:51.883864038  1756   0x7f5c007850 WARN          v4l2bufferpool gstv4l2bufferpool.c:1512:gst_v4l2_buffer_pool_dqbuf: 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: 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: Release old pool
Dies sind Protokolle, sobald Sie ein anderes Video abspielen und die Pipeline zurückgesetzt wird (Pipeline funktioniert ordnungsgemäß)

Code: Select all

0:06:21.907924995  1756   0x7f580cc320 WARN              aggregator gstaggregator.c:1717:gst_aggregator_query_latency_unlocked: Latency query failed
0:06:21.909268156  1756   0x7f70007460 WARN                 basesrc gstbasesrc.c:3583:gst_base_src_start_complete: pad not activated yet
0:06:21.910099324  1756   0x7f70007460 WARN                 basesrc gstbasesrc.c:3583:gst_base_src_start_complete: 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: failed to find fragment defaults for stream 1
0:06:21.914677884  1756   0x7f7800e720 WARN                 qtdemux qtdemux.c:3031:qtdemux_parse_trex: 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: 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: 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: Duration invalid, not setting latency
0:06:22.080866610  1756     0x106ee320 WARN          v4l2bufferpool gstv4l2bufferpool.c:1065:gst_v4l2_buffer_pool_start: Uncertain or not enough buffers, enabling copy threshold
0:06:22.085282770  1756   0x7f5c0078f0 WARN          v4l2bufferpool gstv4l2bufferpool.c:1512:gst_v4l2_buffer_pool_dqbuf: 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: 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: Release old pool
0:06:22.108516102  1756   0x7f580cc320 ERROR                    omx gstomx.c:256:gst_omx_component_handle_messages: yuv420 port 0 was not flushing