У нас есть приложение на основе Python Media Player, которое проходит через медиа-файлы и отображает их на экране. Когда это произойдет, DMESG показывает следующие сообщения (эти конкретные сообщения, от того, когда мы все еще использовали DRM для вывода видео. Теперь мы используем xcb_xv, но у нас такая же проблема): < /p>
...
...
[ 3.028998] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device
[ 9139.538040] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9139.545459] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9139.552522] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9139.583064] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9151.090537] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9151.096344] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9191.649563] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
[ 9191.675813] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28
...
...
< /code>
Это указывает на то, что память графического процессора просочилась, и уже недостаточно доступно для продолжения воспроизведения видео. Устройство (Raspberry Pi) продолжает функционировать иначе. < /P>
Для видеофайлов VLC используется для воспроизведения. В конце каждого видео мы пытаемся очистить все ресурсы, используемые VLC, используемые для отображения видео. Мы также попытались сохранить счетчик видео воспроизведения, который мы использовали, чтобы полностью разрушить и восстановить экземпляр игрока VLC после каждых 50 видео воспроизведения. Это не решило проблему. < /P>
Вот код: < /p>
import os
import time
import json
import vlc
import subprocess
from pathlib import Path
import pygame
from pygame import display, image, time as pygame_time
from jplayer.utils import scene_update_flag_utils as sufu
from jplayer.utils import logging_utils as lu
from jplayer.utils import system_utils as su
from jplayer.clients.japi_client import JApiClient
logger = lu.get_logger("jplayer_app")
VIDEO_REINIT_THRESHOLD = 50
class MediaPlayer:
def __init__(self, media_directory, scenes_directory):
logger.info("Initializing MediaPlayer ...")
self.media_directory = Path(media_directory)
self.scenes_directory = Path(scenes_directory)
self.default_image_path = Path('/home/static_images/ready_for_content.jpeg')
self.supported_images = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.heic'}
self.supported_videos = {'.mp4', '.avi', '.mov'}
self.current_scenes = []
self.video_count = 0
# Get orientation
self.jclient = JApiClient(logger)
orientation = self.jclient.jplayer_info.get("orientation", "LANDSCAPE")
logger.info(f" Detected Orientation: {orientation}")
self.screen_config = su.get_screen_config(orientation)
# Initialize Pygame for image display
pygame.init()
display.init()
# Set up fullscreen display with proper orientation
display_dims = self.screen_config.get_display_dimensions()
self.screen = display.set_mode(display_dims, pygame.FULLSCREEN)
self.screen_width, self.screen_height = display_dims
# Initialize VLC
self.initialize_vlc()
logger.info("Done initializing MediaPlayer.")
def initialize_vlc(self):
"""Initialize the VLC instance and player."""
vlc_args = [
'--vout=xcb_xv',
'--no-video-title-show',
'--file-caching=2000'
]
self.vlc_instance = vlc.Instance(vlc_args)
self.vlc_player = self.vlc_instance.media_player_new()
# Tell VLC to render to the pygame window
if os.name == 'nt': # Windows
self.vlc_player.set_hwnd(pygame.display.get_wm_info()['window'])
else: # Linux/Raspberry Pi
self.vlc_player.set_xwindow(pygame.display.get_wm_info()['window'])
def reinitialize_vlc(self):
"""Reinitialize VLC after releasing resources to free up GPU memory."""
logger.info("Reinitializing VLC to reclaim GPU resources...")
self.vlc_player.release()
self.vlc_instance.release()
self.initialize_vlc()
self.video_count = 0 # Reset the counter after reinitialization
logger.info("VLC reinitialized successfully.")
def load_scenes(self):
"""Load and parse scene configuration files."""
scenes = []
for file in self.scenes_directory.glob('*.json'):
try:
with open(file, 'r') as f:
scene = json.load(f)
required_fields = {'id', 'media_file', 'order'}
if not all(field in scene for field in required_fields):
logger.info(f"Scene file {file} missing required fields")
continue
media_path = self.media_directory / scene['media_file']
if not media_path.exists():
logger.info(f"Media file not found: {media_path}")
continue
scene['media_path'] = media_path
scenes.append(scene)
except Exception as e:
logger.error(f"Error loading scene file {file}: {e}")
continue
return sorted(scenes, key=lambda x: x['order'])
def display_image(self, scene):
"""Display an image for the specified duration."""
try:
img = image.load(str(scene['media_path']))
img = pygame.transform.scale(img, (self.screen_width, self.screen_height))
if self.screen_config.get_pygame_rotation() != 0:
img = pygame.transform.rotate(img, self.screen_config.get_pygame_rotation())
self.screen.blit(img, (0, 0))
display.flip()
duration = int(scene.get('time_to_display', 7))
pygame_time.wait(duration * 1000)
return True
except Exception as e:
logger.info(f"Error displaying image {scene['media_path']}: {e}")
return False
def display_video(self, scene):
"""Play a video file using VLC."""
media = None
try:
# Stop any existing playback and force cleanup
if self.vlc_player.is_playing():
self.vlc_player.stop()
# Create new media instance
media = self.vlc_instance.media_new(str(scene['media_path']))
media.add_option(":no-audio") # Disable audio processing if not needed
media.add_option(":no-metadata-network-access") # Prevent network access
media.add_option(":no-video-title-show") # Disable title display
# Set media and immediately check if it was successful
self.vlc_player.set_media(media)
if not self.vlc_player.get_media():
logger.info(" Failed to set media")
return False
# Attempt playback
play_result = self.vlc_player.play()
if play_result == -1:
logger.info(f" Failed to start playback for scene {scene.get('id')}")
return False
time.sleep(1)
while self.vlc_player.is_playing():
logger.info(" video is playing")
pygame.event.pump()
time.sleep(0.25)
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.vlc_player.stop()
if media:
media.release()
return False
# Explicitly stop playback
self.vlc_player.stop()
# Small delay to ensure cleanup
time.sleep(0.1)
# If we got here, the video played successfully
self.video_count += 1
if self.video_count >= VIDEO_REINIT_THRESHOLD:
self.reinitialize_vlc()
return True
except Exception as e:
logger.error(f"Error playing video {scene.get('id')}: {e}")
return False
finally:
# Aggressive cleanup
if self.vlc_player.is_playing():
self.vlc_player.stop()
# Force VLC to release GPU resources
self.vlc_player.set_media(None)
if media:
media.release()
media = None
def display_default_scene(self):
"""Display the default 'ready for content' scene."""
try:
if not self.default_image_path.exists():
logger.error(f"Default image not found at {self.default_image_path}")
return False
img = image.load(str(self.default_image_path))
img = pygame.transform.scale(img, (self.screen_width, self.screen_height))
if self.screen_config.get_pygame_rotation() != 0:
img = pygame.transform.rotate(img, self.screen_config.get_pygame_rotation())
self.screen.blit(img, (0, 0))
display.flip()
pygame_time.wait(7000)
return True
except Exception as e:
logger.error(f"Error displaying default image: {e}")
return False
def run(self):
"""Main loop to display media files."""
try:
while True:
if sufu.should_reload_scenes():
self.current_scenes = self.load_scenes()
logger.info("Reloaded scenes due to update flag")
sufu.reset_update_flag_to_zero()
elif not self.current_scenes:
self.current_scenes = self.load_scenes()
logger.info("Initial scene load")
if not self.current_scenes:
logger.info("No valid scenes found, displaying default scene")
self.display_default_scene()
time.sleep(15)
continue
logger.info("Iterating through scenes ...")
for scene in self.current_scenes:
logger.info(f" Displaying scene {scene.get('id')} at media path {scene.get('media_path')}")
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
suffix = scene['media_path'].suffix.lower()
if suffix in self.supported_images:
if not self.display_image(scene):
continue
elif suffix in self.supported_videos:
if not self.display_video(scene):
continue
finally:
self.vlc_player.release()
pygame.quit()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Display images and videos in a loop based on scene configurations')
parser.add_argument('media_directory', help='Directory containing media files (images and videos)')
parser.add_argument('scenes_directory', help='Directory containing scene configuration JSON files')
args = parser.parse_args()
player = MediaPlayer(args.media_directory, args.scenes_directory)
player.run()
Мы пытались очистить ресурсы так же агрессивно, как мы знаем, как/способны. К сожалению, мы все еще испытываем утечку. Мы также попытались увеличить память графического процессора, которая не решила проблему.
У нас есть приложение на основе Python Media Player, которое проходит через медиа-файлы и отображает их на экране. Когда это произойдет, DMESG показывает следующие сообщения (эти конкретные сообщения, от того, когда мы все еще использовали DRM для вывода видео. Теперь мы используем xcb_xv, но у нас такая же проблема): < /p> [code]... ... [ 3.028998] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device [ 9139.538040] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9139.545459] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9139.552522] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9139.583064] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9151.090537] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9151.096344] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9191.649563] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 [ 9191.675813] vc4-drm gpu: [drm] *ERROR* Failed to allocate DLIST entry. Requested size=9. ret=-28 ... ... < /code> Это указывает на то, что память графического процессора просочилась, и уже недостаточно доступно для продолжения воспроизведения видео. Устройство (Raspberry Pi) продолжает функционировать иначе. < /P> Для видеофайлов VLC используется для воспроизведения. В конце каждого видео мы пытаемся очистить все ресурсы, используемые VLC, используемые для отображения видео. Мы также попытались сохранить счетчик видео воспроизведения, который мы использовали, чтобы полностью разрушить и восстановить экземпляр игрока VLC после каждых 50 видео воспроизведения. Это не решило проблему. < /P> Вот код: < /p> import os import time import json import vlc import subprocess from pathlib import Path import pygame from pygame import display, image, time as pygame_time from jplayer.utils import scene_update_flag_utils as sufu from jplayer.utils import logging_utils as lu from jplayer.utils import system_utils as su from jplayer.clients.japi_client import JApiClient
# Tell VLC to render to the pygame window if os.name == 'nt': # Windows self.vlc_player.set_hwnd(pygame.display.get_wm_info()['window']) else: # Linux/Raspberry Pi self.vlc_player.set_xwindow(pygame.display.get_wm_info()['window'])
def reinitialize_vlc(self): """Reinitialize VLC after releasing resources to free up GPU memory.""" logger.info("Reinitializing VLC to reclaim GPU resources...") self.vlc_player.release() self.vlc_instance.release() self.initialize_vlc() self.video_count = 0 # Reset the counter after reinitialization logger.info("VLC reinitialized successfully.")
def load_scenes(self): """Load and parse scene configuration files.""" scenes = [] for file in self.scenes_directory.glob('*.json'): try: with open(file, 'r') as f: scene = json.load(f) required_fields = {'id', 'media_file', 'order'} if not all(field in scene for field in required_fields): logger.info(f"Scene file {file} missing required fields") continue
media_path = self.media_directory / scene['media_file'] if not media_path.exists(): logger.info(f"Media file not found: {media_path}") continue
scene['media_path'] = media_path scenes.append(scene) except Exception as e: logger.error(f"Error loading scene file {file}: {e}") continue
return sorted(scenes, key=lambda x: x['order'])
def display_image(self, scene): """Display an image for the specified duration.""" try: img = image.load(str(scene['media_path'])) img = pygame.transform.scale(img, (self.screen_width, self.screen_height))
if self.screen_config.get_pygame_rotation() != 0: img = pygame.transform.rotate(img, self.screen_config.get_pygame_rotation())
def display_video(self, scene): """Play a video file using VLC.""" media = None try: # Stop any existing playback and force cleanup if self.vlc_player.is_playing(): self.vlc_player.stop()
# Create new media instance media = self.vlc_instance.media_new(str(scene['media_path'])) media.add_option(":no-audio") # Disable audio processing if not needed media.add_option(":no-metadata-network-access") # Prevent network access media.add_option(":no-video-title-show") # Disable title display
# Set media and immediately check if it was successful self.vlc_player.set_media(media) if not self.vlc_player.get_media(): logger.info(" Failed to set media") return False
# Attempt playback play_result = self.vlc_player.play() if play_result == -1: logger.info(f" Failed to start playback for scene {scene.get('id')}") return False
time.sleep(1)
while self.vlc_player.is_playing(): logger.info(" video is playing") pygame.event.pump() time.sleep(0.25)
for event in pygame.event.get(): if event.type == pygame.QUIT: self.vlc_player.stop() if media: media.release() return False
# Explicitly stop playback self.vlc_player.stop()
# Small delay to ensure cleanup time.sleep(0.1)
# If we got here, the video played successfully self.video_count += 1 if self.video_count >= VIDEO_REINIT_THRESHOLD: self.reinitialize_vlc()
return True
except Exception as e: logger.error(f"Error playing video {scene.get('id')}: {e}") return False
finally: # Aggressive cleanup if self.vlc_player.is_playing(): self.vlc_player.stop() # Force VLC to release GPU resources self.vlc_player.set_media(None) if media: media.release() media = None
def display_default_scene(self): """Display the default 'ready for content' scene.""" try: if not self.default_image_path.exists(): logger.error(f"Default image not found at {self.default_image_path}") return False
def run(self): """Main loop to display media files.""" try: while True: if sufu.should_reload_scenes(): self.current_scenes = self.load_scenes() logger.info("Reloaded scenes due to update flag") sufu.reset_update_flag_to_zero() elif not self.current_scenes: self.current_scenes = self.load_scenes() logger.info("Initial scene load")
if not self.current_scenes: logger.info("No valid scenes found, displaying default scene") self.display_default_scene() time.sleep(15) continue
logger.info("Iterating through scenes ...") for scene in self.current_scenes: logger.info(f" Displaying scene {scene.get('id')} at media path {scene.get('media_path')}") for event in pygame.event.get(): if event.type == pygame.QUIT: return
suffix = scene['media_path'].suffix.lower() if suffix in self.supported_images: if not self.display_image(scene): continue elif suffix in self.supported_videos: if not self.display_video(scene): continue
finally: self.vlc_player.release() pygame.quit()
if __name__ == "__main__": import argparse
parser = argparse.ArgumentParser(description='Display images and videos in a loop based on scene configurations') parser.add_argument('media_directory', help='Directory containing media files (images and videos)') parser.add_argument('scenes_directory', help='Directory containing scene configuration JSON files')
args = parser.parse_args()
player = MediaPlayer(args.media_directory, args.scenes_directory) player.run() [/code] Мы пытались очистить ресурсы так же агрессивно, как мы знаем, как/способны. К сожалению, мы все еще испытываем утечку. Мы также попытались увеличить память графического процессора, которая не решила проблему.
У нас есть приложение медиаплеера на основе Python, которое просматривает медиафайлы и отображает их на экране.
После примерно 3–24 часов работы дисплей иногда зависает. во время воспроизведения видео. Когда это происходит, dmesg отображает...
Мне сложно отличить разные графические процессоры. Это мой код, и, насколько я понимаю, он должен возвращать разные номера шин/устройств/функций, однако я получаю одинаковые номера для всех графических процессоров. Любая помощь будет оценена по...
Я следую этому сценарию и пытаюсь адаптироваться, установив device_map = auto для использования нескольких графических процессоров в контейнере Docker. Ниже приведены настройки сервера:
DITRIB_ID=Ubuntu
DISPRIB_RELEASE=22.04
ubuntu@ubuntu:~$...
Я создал приложение RAG, которое в основном отвечает на вопросы пользователей на основе предоставленных данных. Оно отлично работает как на графическом процессоре, так и на одном графическом процессоре. Я хочу развернуть его на нескольких...
У меня есть RTX 4080 Super и Quadro RTX 6000, но я хочу использовать 2 графических процессора в одном процессе одновременно, но независимо от того, как я пытаюсь оптимизировать код, использую только один из 2 графических процессоров в создании...