基于Pygame的视频播放器CPU占用率异常波动问题求助
Pygame视频播放器CPU占用波动问题调试求助
我用Pygame开发了一款视频播放器,通过缓冲区将视频文件的numpy帧数组流传输至Pygame窗口。当前遇到异常:CPU占用率随时间逐步升高(程序运行变慢),随后又骤降(程序运行提速),内存占用基本保持稳定,因此排除内存泄漏可能。这种波动导致视频播放变为幻灯片模式,幅度远超预期,恳请协助调试。
可通过文末代码复现问题,任意.mp4文件均可。程序会输出log.txt文件用于调试,我的调试发现如下:
初始几秒处理速度较快:
[12:13:31] (Variable: current_frame) 1 [12:13:31] (Variable: len(frame_buffer)) 3 [12:13:31] (Process time) 0.08 seconds
约30秒内持续变慢,处理时间峰值达约0.5秒:
[12:14:07] (Variable: current_frame) 154 [12:14:07] (Variable: len(frame_buffer)) 3 [12:14:07] (Process time) 0.53 seconds
随后处理时间回落至初始水平:
[12:14:11] (Variable: current_frame) 164 [12:14:11] (Variable: len(frame_buffer)) 3 [12:14:11] (Process time) 0.1 seconds
这是我用matplotlib绘制的约1000帧的趋势图:
import cv2 import time import pygame import gc from datetime import datetime #Debug code runtime_start = str(datetime.now().strftime("%H-%M-%S")) def log(prefix, message): string = "[" + str(datetime.now().strftime("%H:%M:%S")) + "] " + "(" + str(prefix) + ") " + str(message) print(string) with open(file="log" + runtime_start + ".txt", mode="a", encoding="utf-8") as file: file.write(string + "\n") ### ### ### #Globals buffer_size = 3 frame_buffer = [] ### ### ### #Functions def loadVideoFileToMemory(file): """ Load file to memory. """ global capture capture = cv2.VideoCapture(file) def getFrameFromVideo(file, frame_number): """ Captures a frame from the loaded file, returns a numpy image array. """ #capture = cv2.VideoCapture(file) capture.set(cv2.CAP_PROP_POS_FRAMES, frame_number) ret, frame = capture.read() #image = ImageTk.PhotoImage(image=Image.fromarray(frame)) image = cv2.resize(frame, (90*6, 160*6)) del frame gc.collect() return image def setBuffer(start_frame): """ Fills the buffer at a set starting frame before playing the video. """ frame_buffer.clear() for i in range(buffer_size): frame_buffer.append(getFrameFromVideo("test_video1.mp4", start_frame + i)) def updateBuffer(frame): """ Updates frame_buffer, deals with garabge collection. """ del frame_buffer[0] gc.collect() if len(frame_buffer) < buffer_size: #Limits to buffer size frame_array = getFrameFromVideo("test_video1.mp4", frame + buffer_size) frame_buffer.append(frame_array) del frame_array gc.collect() def displayImageToPygame(image, window): """ Converts a numpy image array to a pygame surface and blits to screen. """ window.blit(pygame.surfarray.make_surface(image), (0,0)) def createPygameWindow(): """ Creates a pygame window, sets the frame_buffer and starts the main thread. """ window = pygame.display.set_mode((160*6, 90*6)) pygame.display.flip() #Starting frame current_frame = 0 setBuffer(current_frame) #Set from this position displayImageToPygame(frame_buffer[0], window) #Show starting frame pygameThread(window, current_frame) def pygameThread(window, current_frame): """ Main thread. Plays the video. """ running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False timer_start = time.time() #DEBUG: PROCESSING TIME current_frame += 1 displayImageToPygame(frame_buffer[1], window) updateBuffer(current_frame) pygame.display.flip() #DEBUG: POST TO LOG.TXT log("Variable: current_frame", current_frame) log("Variable: len(frame_buffer)", len(frame_buffer)) timer_end = time.time() #DEBUG: PROCESSING TIME log("Process time", str(round(timer_end - timer_start, 2)) + " seconds") ### ### ### ### video_file = "test_video1.mp4" #Replace this with a path to an .mp4 file. loadVideoFileToMemory(video_file) createPygameWindow()
内容的提问来源于stack exchange,提问作者user9888447
相关产品推荐
相关产品推荐

