使用PySide6与GStreamer接收视频流:图像无色彩且重复问题
问题:GStreamer推流在PySide6中显示色彩异常且图像重复
推流端命令
我在另一台电脑上用以下GStreamer命令推送网络摄像头视频:
gst-launch-1.0 -v v4l2src device=/dev/<video4> ! image/jpeg,width=640,height=480,framerate=30/1 ! jpegdec ! videoconvert ! x264enc bitrate=2000 speed-preset=ultrafast tune=zerolatency ref=4 qp-min=5 qp-max=10 ! rtph264pay config-interval=1 ! udpsink host=<ip_destination> port=<port_dest>
接收端GStreamer管道
在Python代码中用Gst接收流的管道如下:
self.pipeline = Gst.parse_launch("udpsrc address={ip_address} port={port} ! application/x-rtp, encoding-name=H264 ! rtph264depay ! decodebin ! videoconvert ! jpegenc ! appsink name={name}")
问题现象
将视频流处理后在PySide6中显示时,出现无色彩且重复的图像;但不使用PySide6,仅用Flask测试时显示完全正常。
完整接收端代码
import cv2 import gi from PySide6.QtWidgets import QVBoxLayout, QWidget from PySide6.QtCore import QTimer from PySide6.QtGui import QImage, QPixmap from PySide6.QtWidgets import QLabel gi.require_version("Gst", "1.0") from gi.repository import Gst class VideoStreamWidget(QWidget): def __init__(self, port, node, parent=None): super(VideoStreamWidget, self).__init__(parent) self.node = node Gst.init(None) # 设置显示视频帧的标签 self.video_label = QLabel(self) layout = QVBoxLayout() layout.addWidget(self.video_label) self.setLayout(layout) self.create_pipeline_gs(port) self.bus = self.pipeline.get_bus() self.bus.add_signal_watch() self.bus.connect("message::eos", self.on_eos) self.bus.connect("message::error", self.on_error) self.pipeline.set_state(Gst.State.PLAYING) def create_pipeline_gs(self, port): name = f"appsink{port}" self.pipeline = Gst.parse_launch( f"udpsrc address=127.0.0.1 port={port} ! application/x-rtp, encoding-name=H264 ! rtph264depay ! decodebin ! videoconvert ! jpegenc ! appsink name={name}" ) self.appsink = self.pipeline.get_by_name(name) self.appsink.set_property('emit-signals', True) self.appsink.set_property('sync', False) self.appsink.connect("new-sample", self.on_new_sample) def on_new_sample(self, sink): sample = sink.emit("pull-sample") if sample: caps = sample.get_caps() buffer = sample.get_buffer() structure = caps.get_structure(0) width = structure.get_value("width") height = structure.get_value("height") success, map_info = buffer.map(Gst.MapFlags.READ) if success: image = QImage( map_info.data, width, height, width * 3, QImage.Format_RGB888 ) pixmap = QPixmap.fromImage(image) self.video_label.setPixmap(pixmap) buffer.unmap(map_info) return 0 def on_eos(self, bus, msg): print("流已结束") self.pipeline.set_state(Gst.State.NULL) def on_error(self, bus, msg): err, debug = msg.parse_error() print(f"错误:{err}") self.pipeline.set_state(Gst.State.NULL) def closeEvent(self, event): self.pipeline.set_state(Gst.State.NULL) event.accept() super(VideoStreamWidget, self).closeEvent(event)
求助
我认为问题出在将GStreamer的图像数据转换为QImage和QPixmap的过程中,但找不到具体解决方法,希望得到帮助。
内容的提问来源于stack exchange,提问作者user26714515
相关产品推荐
相关产品推荐

