Skip to content

Commit

Permalink
fix: fix hardware decoding in MacOS
Browse files Browse the repository at this point in the history
  • Loading branch information
vzhd1701 committed Nov 7, 2021
1 parent f2bcfb5 commit 899ca3b
Show file tree
Hide file tree
Showing 8 changed files with 377 additions and 21 deletions.
17 changes: 12 additions & 5 deletions gridplayer/dialogs/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,18 @@ def fill_playlistGridMode(self):
def fill_playerVideoDriver(self):
video_drivers_disabled = []

video_drivers = {
VideoDriver.VLC_HW: f"Hardware <VLC {params_env.VLC_VERSION}>",
VideoDriver.VLC_SW: f"Software <VLC {params_env.VLC_VERSION}>",
VideoDriver.DUMMY: "Dummy",
}
if platform.system() == "Darwin":
video_drivers = {
VideoDriver.VLC_HW_SP: f"Hardware SP <VLC {params_env.VLC_VERSION}>",
VideoDriver.VLC_SW: f"Software <VLC {params_env.VLC_VERSION}>",
VideoDriver.DUMMY: "Dummy",
}
else:
video_drivers = {
VideoDriver.VLC_HW: f"Hardware <VLC {params_env.VLC_VERSION}>",
VideoDriver.VLC_SW: f"Software <VLC {params_env.VLC_VERSION}>",
VideoDriver.DUMMY: "Dummy",
}

_fill_combo_box(self.playerVideoDriver, video_drivers)

Expand Down
1 change: 1 addition & 0 deletions gridplayer/params_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class VideoAspect(AutoName):
class VideoDriver(AutoName):
VLC_SW = auto()
VLC_HW = auto()
VLC_HW_SP = auto()
DUMMY = auto()


Expand Down
21 changes: 16 additions & 5 deletions gridplayer/player/managers/video_driver.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import platform
from functools import partial

from gridplayer.exceptions import PlayerException
Expand All @@ -7,6 +8,7 @@
from gridplayer.widgets.video_frame_dummy import VideoFrameDummy
from gridplayer.widgets.video_frame_vlc_base import ProcessManagerVLC
from gridplayer.widgets.video_frame_vlc_hw import InstanceProcessVLCHW, VideoFrameVLCHW
from gridplayer.widgets.video_frame_vlc_hw_sp import VideoFrameVLCHWSP
from gridplayer.widgets.video_frame_vlc_sw import InstanceProcessVLCSW, VideoFrameVLCSW


Expand All @@ -15,6 +17,7 @@ class VideoDriverManager(ManagerBase):
VideoDriver.DUMMY: VideoFrameDummy,
VideoDriver.VLC_SW: VideoFrameVLCSW,
VideoDriver.VLC_HW: VideoFrameVLCHW,
VideoDriver.VLC_HW_SP: VideoFrameVLCHWSP,
}

_process_instances = {
Expand All @@ -35,22 +38,27 @@ def __init__(self, **kwargs):
self._process_manager = None

def video_driver(self):
video_driver_cfg = Settings().get("player/video_driver")
is_multiprocess = video_driver_cfg in self._multiprocess_drivers
video_driver = Settings().get("player/video_driver")

if video_driver == VideoDriver.VLC_HW and platform.system() == "Darwin":
video_driver = VideoDriver.VLC_HW_SP
Settings().set("player/video_driver", video_driver)

is_multiprocess = video_driver in self._multiprocess_drivers

if is_multiprocess:
if self._process_manager is None:
self._process_manager = ProcessManagerVLC(
self._process_instances[video_driver_cfg]
self._process_instances[video_driver]
)
self._process_manager.crash.connect(self.crash)

return partial(
self._video_drivers[video_driver_cfg],
self._video_drivers[video_driver],
process_manager=self._process_manager,
)

return self._video_drivers[video_driver_cfg]
return self._video_drivers[video_driver]

def cleanup(self):
if self._process_manager:
Expand All @@ -60,6 +68,9 @@ def cleanup(self):
def set_log_level_vlc(self, log_level):
if self._process_manager:
self._process_manager.set_log_level_vlc(log_level)
elif Settings().get("player/video_driver") == VideoDriver.VLC_HW_SP:
for vb in self._ctx.video_blocks:
vb.video_driver.video_driver.set_log_level_vlc(log_level)

def set_log_level(self, log_level):
if self._process_manager:
Expand Down
4 changes: 4 additions & 0 deletions gridplayer/settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import os
import platform
from enum import Enum

from PyQt5.QtCore import QSettings
Expand Down Expand Up @@ -33,6 +34,9 @@
"internal/opaque_hw_overlay": False,
}

if platform.system() == "Darwin":
_default_settings["player/video_driver"] = VideoDriver.VLC_HW_SP


class _Settings(object):
def __init__(self):
Expand Down
29 changes: 25 additions & 4 deletions gridplayer/widgets/video_frame_vlc_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,31 @@ def error_state(self):


class InstanceProcessVLC(InstanceProcess):
def __init__(self, vlc_log_level, **kwargs):
super().__init__(**kwargs)

self._vlc = InstanceVLC(vlc_log_level)

@property
def _vlc_instance(self):
return self._vlc._vlc_instance

def init_instance(self):
self._vlc.init_instance()

def cleanup_instance(self):
self._vlc.cleanup_instance()

# outside
def request_set_log_level_vlc(self, log_level):
self.cmd_send_self("set_log_level_vlc", log_level)

# process
def set_log_level_vlc(self, log_level):
self._vlc.set_log_level_vlc(log_level)


class InstanceVLC(object):
log_level_map = {
vlc.LogLevel.DEBUG: logging.DEBUG,
vlc.LogLevel.ERROR: logging.ERROR,
Expand Down Expand Up @@ -426,10 +451,6 @@ def _cb(ptr_data, level, ctx, fmt, args): # noqa: WPS430

return _cb

# outside
def request_set_log_level_vlc(self, log_level):
self.cmd_send_self("set_log_level_vlc", log_level)

# process
def set_log_level_vlc(self, log_level):
self._vlc_log_level = log_level
Expand Down
11 changes: 5 additions & 6 deletions gridplayer/widgets/video_frame_vlc_hw.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,14 @@ def ui_setup(self):
self.layout().setContentsMargins(0, 0, 0, 0)

def ui_video_widget(self):
if platform.system() == "Darwin": # for MacOS
self.video_surface = QMacCocoaViewContainer(0, self)
self.palette = self.video_surface.palette()
self.palette.setColor(QPalette.Window, QColor(0, 0, 0))
self.video_surface.setPalette(self.palette)
self.video_surface.setAutoFillBackground(True)
if platform.system() == "Darwin":
# Drawing using window id from another process is not possible on MacOS
# https://stackoverflow.com/questions/583202/mac-os-x-can-one-process-render-to-another-processs-window
raise NotImplementedError()
else:
self.video_surface = QWidget(self)

self.video_surface.setMouseTracking(True)
self.video_surface.setWindowFlags(Qt.WindowTransparentForInput)
self.video_surface.setAttribute(Qt.WA_TransparentForMouseEvents)

Expand Down
Loading

0 comments on commit 899ca3b

Please sign in to comment.