Я работаю над программным обеспечением, которое может воспроизводить несколько видео одновременно и собирать их в одном интерфейсе. В результате существования GIL, который мешает эффективности потоков, я решил использовать один процесс для каждого воспроизводимого видео. Вот мои упрощенные коды.
import multiprocessing as mp
import threading
import cv2
from PyQt5.Qt import *
from PyQt5 import QtWidgets, QtCore
import threading
class Main_UI(QtWidgets.QMainWindow)
def __init__(self):
super().__init__()
self.label_screen1 = QtWidgets.QLabel(self) # used for display
self.label_screen2 = QtWidgets.QLabel(self) # used for display
self.img_q1=mp.Queue(maxsize=2) # a queue used as frame channel
self.img_q2=mp.Queue(maxsize=2) # a queue used as frame channel
#create a process to read videos, it sends frames to the queue1
self.img_fetcher1= mp.Process(target=play,args = (self.img_q1,"xxx/xxx.mp4"))
self.img_fetcher1.start()
#create a process to read videos, it sends frames to the queue2
self.img_fetcher2= mp.Process(target=play,args = (self.img_q2,"yyy/yyy.mp4"))
self.img_fetcher2.start()
#create a thread to keep displaying the images received from the queue1 onto the label1
self.video_thread1 = threading.Thread(target=self.display)
self.video_thread1.start()
#create a thread to keep displaying the images received from the queue2 onto the label2
self.video_thread2 = threading.Thread(target=self.display)
self.video_thread2.start()
def display(self):
while True:
if not self.result_img_q.empty():
show=self.result_img_q.get()
showImage = QImage(show.data, show.shape[1], show.shape[0],
QImage.Format_RGB888)
self.label_screen.setScaledContents(True)
self.label_screen.setPixmap(QPixmap.fromImage(showImage)) #display on the label
def play(img_q,video_path): # this method run as a process
videocap = cv2.VideoCapture(video_path)
while True:
flag, frame = videocap.read()
if flag:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
time.sleep(0.02)
img_q.put(frame) #send the frame to the queue
Код работает нормально ,, но я обнаружил, что скорость не настолько удовлетворительная. Я думаю, это отчасти из-за GIL, 2 потока не могут отображать изображения на ярлыках по отдельности и одновременно, так как один должен ждать другого. Интересно, можно ли отобразить изображение на этикетке напрямую с помощью процесса img_fetcher? Точно так же, как передача общего значения процессу из основного процесса и изменение значения в этом процессе.
Может кто-нибудь сказать, как решить эту проблему? Спасибо!