from . import _
from Screens.Screen import Screen
from Screens.ChoiceBox import ChoiceBox
from Screens.Setup import SetupSummary
from Screens.MessageBox import MessageBox
from Components.ConfigList import ConfigList, ConfigListScreen
from Components.config import config, configfile, getConfigListEntry, ConfigSelection, ConfigSubsection, ConfigYesNo, ConfigSubDict, ConfigNothing
from Components.ServiceEventTracker import ServiceEventTracker
from Components.ActionMap import ActionMap
from Components.Label import Label
from Components.SystemInfo import SystemInfo
from Components.Sources.StaticText import StaticText
from enigma import iPlayableService, iServiceInformation, eTimer, getDesktop
from Plugins.Plugin import PluginDescriptor
from Tools import Notifications
from Plugins.SystemPlugins.Videomode.VideoHardware import video_hw # depends on Videomode Plugin
def readAvailableModes():
try:
f = open("/proc/stb/video/videomode_choices")
modes = f.read()[:-1]
f.close()
return modes.split(' ')
except:
return []
modes_available = readAvailableModes()
usable = False
preferedmodes = None
default = None
port = None
videoresolution_dictionary = {}
resolutionlabel = None
manualResolution = None
resolutions = (
('sd_i_50', _("SD 25/50HZ Interlace Mode")),
('sd_i_60', _("SD 30/60HZ Interlace Mode")),
('sd_p_24', _("SD 24HZ Progressive mode")),
('sd_p_50', _("SD 25/50HZ Progressive Mode")),
('sd_p_60', _("SD 30/60HZ Progressive Mode")),
('hd_i', _("HD Interlace Mode")),
('hd_p', _("HD Progressive Mode")),
('p720_24', _("Enable 720p24 Mode")),
('p720_50', _("Enable 720p50 Mode")),
('p1080_24', _("Enable 1080p24 Mode")),
('p1080_25', _("Enable 1080p25 Mode")),
('p1080_30', _("Enable 1080p30 Mode")),
)
have_1080p = config.av.videorate.get("1080p", False)
if have_1080p:
resolutions += (
('fhd_p', _("FHD 50/60HZ Progressive Mode")),
)
have_2160p = config.av.videorate.get("2160p", False)
if have_2160p:
resolutions += (
('uhd_i', _("UHD Interlace Mode")),
('uhd_p', _("UHD Progressive Mode")),
('p2160_24', _("Enable 2160p24 Mode")),
('p2160_25', _("Enable 2160p25 Mode")),
('p2160_30', _("Enable 2160p30 Mode")),
)
config.plugins.autoresolution = ConfigSubsection()
config.plugins.autoresolution.enable = ConfigYesNo(default=False)
config.plugins.autoresolution.showinfo = ConfigYesNo(default=True)
config.plugins.autoresolution.testmode = ConfigYesNo(default=False)
config.plugins.autoresolution.hdmihdrtype = ConfigYesNo(default=False)
config.plugins.autoresolution.hdmicolorimetry = ConfigSelection(default="no", choices=[("no", _("no")), ("bt2020ncl", "BT 2020 NCL"), ("bt2020cl", "BT 2020 CL")])
config.plugins.autoresolution.deinterlacer = ConfigSelection(default="auto", choices=[("off", _("off")), ("auto", _("auto")), ("on", _("on"))])
config.plugins.autoresolution.deinterlacer_progressive = ConfigSelection(default="auto", choices=[("off", _("off")), ("auto", _("auto")), ("on", _("on"))])
config.plugins.autoresolution.delay_switch_mode = ConfigSelection(default="1000", choices=[
("0", "0 " + _("seconds")), ("50", "0.05 " + _("seconds")), ("500", "0.5 " + _("seconds")),
("1000", "1 " + _("second")), ("2000", "2 " + _("seconds")), ("3000", "3 " + _("seconds")),
("4000", "4 " + _("seconds")), ("5000", "5 " + _("seconds")), ("6000", "6 " + _("seconds")), ("7000", "7 " + _("seconds")),
("8000", "8 " + _("seconds")), ("9000", "9 " + _("seconds")), ("10000", "10 " + _("seconds")), ("60000", "60 " + _("seconds"))])
config.plugins.autoresolution.mode = ConfigSelection(default="manual", choices=[("manual", _("Manual")), ("auto", _("Auto frame rate (refresh need 'multi/auto')"))])
config.plugins.autoresolution.lock_timeout = ConfigSelection(default="60", choices=[("30", "30 " + _("seconds")), ("60", "60 " + _("seconds"))])
config.plugins.autoresolution.ask_apply_mode = ConfigYesNo(default=False)
config.plugins.autoresolution.auto_30_60 = ConfigYesNo(default=True)
config.plugins.autoresolution.auto_24_30_alternative = ConfigYesNo(default=True)
config.plugins.autoresolution.ask_timeout = ConfigSelection(default="20", choices=[("5", "5 " + _("seconds")), ("10", "10 " + _("seconds")), ("15", "15 " + _("seconds")), ("20", "20 " + _("seconds"))])
config.plugins.autoresolution.manual_resolution_ext_menu = ConfigYesNo(default=False)
config.plugins.autoresolution.manual_resolution_ask = ConfigYesNo(default=True)
config.plugins.autoresolution.force_progressive_mode = ConfigYesNo(default=False)
def setDeinterlacer(mode):
try:
f = open('/proc/stb/vmpeg/deinterlace', "w")
f.write("%s\n" % mode)
f.close()
print "[AutoRes] switch deinterlacer mode to %s" % mode
except:
print "[AutoRes] failed switch deinterlacer mode to %s" % mode
def setHdmiHdrType(mode):
try:
f = open("/proc/stb/video/hdmi_hdrtype", "r")
old_mode = f.read()
f.close()
except:
old_mode = ""
if old_mode and old_mode != mode:
try:
f = open("/proc/stb/video/hdmi_hdrtype", "w")
f.write("%s" % mode)
f.close()
print "[AutoRes] switch hdmi_hdrtype mode to %s" % mode
except:
print "[AutoRes] failed switch hdmi_hdrtype mode to %s" % mode
def setColorimetry(mode):
try:
f = open("/proc/stb/video/hdmi_colorimetry", "r")
old_mode = f.read()
f.close()
except:
old_mode = ""
if old_mode and old_mode != mode:
try:
f = open("/proc/stb/video/hdmi_colorimetry", "w")
f.write("%s" % mode)
f.close()
print "[AutoRes] switch hdmi_colorimetry mode to %s" % mode
except:
print "[AutoRes] failed switch hdmi_colorimetry mode to %s" % mode
frqdic = {23000: '24',
23976: '24',
24000: '24',
25000: '25',
29970: '30',
30000: '30',
50000: '50',
59940: '60',
60000: '60'}
codec_data = {
-1: "N/A",
0: "MPEG2",
1: "AVC",
2: "H263",
3: "VC1",
4: "MPEG4-VC",
5: "VC1-SM",
6: "MPEG1",
7: "HEVC",
8: "VP8",
9: "VP9",
10: "XVID",
11: "N/A 11",
12: "N/A 12",
13: "DIVX 3.11",
14: "DIVX 4",
15: "DIVX 5",
16: "AVS",
17: "N/A 17",
18: "VP6",
19: "N/A 19",
20: "N/A 20",
21: "SPARK",
}
class AutoRes(Screen):
def __init__(self, session):
global port, modes_available
Screen.__init__(self, session)
self.__event_tracker = ServiceEventTracker(screen=self, eventmap={
iPlayableService.evVideoSizeChanged: self.__evVideoSizeChanged,
iPlayableService.evVideoProgressiveChanged: self.__evVideoProgressiveChanged,
iPlayableService.evVideoFramerateChanged: self.__evVideoFramerateChanged,
iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
iPlayableService.evVideoGammaChanged: self.__evVideoGammaChanged,
iPlayableService.evStart: self.__evStart,
iPlayableService.evEnd: self.__evEnd
})
self.timer = eTimer()
self.timer.callback.append(self.determineContent)
self.extra_mode720p60 = '720p60' in modes_available
self.extra_mode1080p50 = '1080p50' in modes_available
self.extra_mode1080p60 = '1080p60' in modes_available
self.extra_mode2160p50 = '2160p50' in modes_available
if config.av.videoport.value in config.av.videomode:
self.lastmode = config.av.videomode[config.av.videoport.value].value
config.av.videoport.addNotifier(self.defaultModeChanged)
config.plugins.autoresolution.enable.addNotifier(self.enableChanged, initial_call=False)
config.plugins.autoresolution.deinterlacer.addNotifier(self.enableChanged, initial_call=False)
config.plugins.autoresolution.deinterlacer_progressive.addNotifier(self.enableChanged, initial_call=False)
if default:
self.setMode(default[0], False)
self.after_switch_delay = False
self.newService = False
self.video_stream_service = False
if "720p" in config.av.videorate:
config.av.videorate["720p"].addNotifier(self.__videorate_720p_changed, initial_call=False, immediate_feedback=False)
if "1080i" in config.av.videorate:
config.av.videorate["1080i"].addNotifier(self.__videorate_1080i_changed, initial_call=False, immediate_feedback=False)
if "1080p" in config.av.videorate:
config.av.videorate["1080p"].addNotifier(self.__videorate_1080p_changed, initial_call=False, immediate_feedback=False)
if "2160p" in config.av.videorate:
config.av.videorate["2160p"].addNotifier(self.__videorate_2160p_changed, initial_call=False, immediate_feedback=False)
def __videorate_720p_changed(self, configEntry):
if self.lastmode == "720p":
self.changeVideomode()
def __videorate_1080i_changed(self, configEntry):
if self.lastmode == "1080i":
self.changeVideomode()
def __videorate_1080p_changed(self, configEntry):
if self.lastmode == "1080p":
self.changeVideomode()
def __videorate_2160p_changed(self, configEntry):
if self.lastmode == "2160p":
self.changeVideomode()
def __evStart(self):
self.newService = True
def __evEnd(self):
self.newService = False
self.video_stream_service = False
def __evUpdatedInfo(self):
if self.newService and config.plugins.autoresolution.mode.value == "manual":
print "[AutoRes] service changed"
self.after_switch_delay = False
if int(config.plugins.autoresolution.delay_switch_mode.value) > 0:
resolutionlabel.hide()
self.timer.start(int(config.plugins.autoresolution.delay_switch_mode.value), True)
else:
self.determineContent()
self.newService = False
def defaultModeChanged(self, configEntry):
global preferedmodes
global port
global default
global usable
port_changed = configEntry == config.av.videoport
if port_changed:
print "[AutoRes] port changed to", configEntry.value
if port:
config.av.videomode[port].notifiers.remove(self.defaultModeChanged)
port = config.av.videoport.value
if port in config.av.videomode:
config.av.videomode[port].addNotifier(self.defaultModeChanged)
usable = config.plugins.autoresolution.enable.value and not port in ('DVI-PC', 'Scart')
else: # videomode changed in normal av setup
global videoresolution_dictionary
print "[AutoRes] mode changed to", configEntry.value
default = (configEntry.value, _("default") + " (%s)" % configEntry.value)
preferedmodes = [mode[0] for mode in video_hw.getModeList(port) if mode[0] != default[0]]
preferedmodes.append(default)
print "[AutoRes] default", default
print "[AutoRes] preferedmodes", preferedmodes
videoresolution_dictionary = {}
config.plugins.autoresolution.videoresolution = ConfigSubDict()
if self.extra_mode720p60 and '720p60' not in preferedmodes:
preferedmodes.append('720p60')
if self.extra_mode1080p50 and '1080p50' not in preferedmodes:
preferedmodes.append('1080p50')
if self.extra_mode1080p60 and '1080p60' not in preferedmodes:
preferedmodes.append('1080p60')
if self.extra_mode2160p50 and '2160p50' not in preferedmodes:
preferedmodes.append('2160p50')
for mode in resolutions:
if have_2160p:
if mode[0].startswith('p2160'):
choices = ['2160p24', '2160p25', '2160p30', '1080p24', '1080p25', '1080p30'] + preferedmodes
elif mode[0].startswith('p1080_24'):
choices = ['1080p24', '2160p24'] + preferedmodes
elif mode[0].startswith('p1080'):
choices = ['1080p24', '1080p25', '1080p30'] + preferedmodes
elif mode[0] == 'p720_24':
choices = ['720p24', '1080p24', '2160p24'] + preferedmodes
elif mode[0] == 'p720_50':
choices = ['720p50', '1080p25', '2160p25'] + preferedmodes
else:
choices = preferedmodes
else:
if mode[0].startswith('p1080'):
choices = ['1080p24', '1080p25', '1080p30'] + preferedmodes
elif mode[0] == 'p720_24':
choices = ['720p24', '1080p24'] + preferedmodes
elif mode[0] == 'p720_50':
choices = ['720p50', '1080p25'] + preferedmodes
else:
choices = preferedmodes
config.plugins.autoresolution.videoresolution[mode[0]] = ConfigSelection(default=default[0], choices=choices)
config.plugins.autoresolution.videoresolution[mode[0]].addNotifier(self.modeConfigChanged, initial_call=False, immediate_feedback=False)
videoresolution_dictionary[mode[0]] = (config.plugins.autoresolution.videoresolution[mode[0]])
def modeConfigChanged(self, configElement):
self.determineContent()
def enableChanged(self, configElement):
global usable
if configElement.value:
usable = not port in ('DVI-PC', 'Scart')
self.determineContent()
else:
usable = False
self.changeVideomode()
def __evVideoGammaChanged(self):
if SystemInfo["HasHdrType"] and config.plugins.autoresolution.hdmihdrtype.value and config.av.hdmihdrtype.value == "auto":
if not self.timer.isActive() or self.after_switch_delay:
print "[AutoRes] got event evVideoGammaChanged"
self.timer.start(200, True)
def __evVideoFramerateChanged(self):
if not self.timer.isActive() or self.after_switch_delay:
print "[AutoRes] got event evFramerateChanged"
self.timer.start(200, True)
def __evVideoSizeChanged(self):
if not self.timer.isActive() or self.after_switch_delay:
print "[AutoRes] got event evVideoSizeChanged"
self.timer.start(200, True)
def __evVideoProgressiveChanged(self):
if not self.timer.isActive() or self.after_switch_delay:
print "[AutoRes] got event evVideoProgressiveChanged"
self.timer.start(200, True)
def determineContent(self):
if config.plugins.autoresolution.mode.value != "manual":
return
self.timer.stop()
resolutionlabel.hide()
self.after_switch_delay = True
if usable:
print "[AutoRes] determineContent"
service = self.session.nav.getCurrentService()
info = service and service.info()
if not info:
return
ref = self.session.nav.getCurrentlyPlayingServiceReference()
refstr = ref and ref.toString() or ""
self.video_stream_service = refstr and ("%3a//" in refstr or refstr.rsplit(":", 1)[1].startswith("/"))
height = info.getInfo(iServiceInformation.sVideoHeight)
if self.video_stream_service and (not height or height == -1):
try:
f = open("/proc/stb/vmpeg/0/yres", "r")
height = int(f.read(), 16)
f.close()
except:
pass
width = info.getInfo(iServiceInformation.sVideoWidth)
if self.video_stream_service and (not width or width == -1):
try:
f = open("/proc/stb/vmpeg/0/xres", "r")
width = int(f.read(), 16)
f.close()
except:
pass
framerate = info.getInfo(iServiceInformation.sFrameRate)
if self.video_stream_service and (not framerate or framerate == -1):
try:
framerate = int(open("/proc/stb/vmpeg/0/framerate", "r").read())
except:
pass
if height != -1 and width != -1 and framerate != -1:
videocodec = codec_data.get(info.getInfo(iServiceInformation.sVideoType), "N/A")
frate = str(framerate)[:2] #fallback?
if framerate in frqdic:
frate = frqdic[framerate]
prog = ("i", "p", "")[info.getInfo(iServiceInformation.sProgressive)]
if config.plugins.autoresolution.force_progressive_mode.value and self.video_stream_service and prog != "p":
prog = "p"
if have_2160p and (height >= 2100 or width >= 3200): # 2160 content
if frate in ('24', '25', '30') and prog == 'p':
new_mode = 'p2160_%s' % frate
elif frate in ('50', '60') and prog == 'p':
new_mode = 'uhd_p'
else:
new_mode = 'uhd_i' # 2160i content
elif (height >= 900 or width >= 1600) and frate in ('24', '25', '30') and prog == 'p': # 1080p content
new_mode = 'p1080_%s' % frate
elif (576 < height < 900 or 720 < width < 1600) and frate == '24' and prog == 'p': # 720p24 content
new_mode = 'p720_24'
elif frate in ('24'): # always 1080p24 content
new_mode = 'p1080_24'
elif (576 < height < 900 or 720 < width < 1600) and frate == '50' and prog == 'p': # 720p50 content
new_mode = 'p720_50'
elif (height <= 576) and (width <= 720) and frate in ('25', '50'):
new_mode = 'sd_%s_50' % prog
elif (height <= 480) and (width <= 720) and frate in ('24', '30', '60'):
new_mode = 'sd_%s_60' % prog
elif have_1080p and (height >= 900 or width >= 1600) and frate in ('50', '60') and prog == 'p': # 1080p50/60 content
new_mode = 'fhd_p'
else:
new_mode = 'hd_%s' % prog
if prog == 'p':
setDeinterlacer(config.plugins.autoresolution.deinterlacer_progressive.value)
elif prog == 'i':
setDeinterlacer(config.plugins.autoresolution.deinterlacer.value)
else:
setDeinterlacer("auto")
gamma_num = info.getInfo(iServiceInformation.sGamma)
if SystemInfo["HasHdrType"] and config.plugins.autoresolution.hdmihdrtype.value and config.av.hdmihdrtype.value == "auto":
gammas = ("auto", "hdr10", "hdr10", "hlg", "auto")
if gamma_num < len(gammas):
# Possible gamma values
# 0: Traditional gamma - SDR luminance range
# 1: Traditional gamma - HDR luminance range
# 2: SMPTE ST2084 (aka HDR10)
# 3: Hybrid Log-gamma
hdrtype = gammas[gamma_num]
setHdmiHdrType(hdrtype)
if SystemInfo["HasColorimetry"] and config.plugins.autoresolution.hdmicolorimetry.value != "no" and config.av.hdmicolorimetry.value == "auto":
colorimetry = hdrtype in ("hdr10", "hlg") and config.plugins.autoresolution.hdmicolorimetry.value or "auto"
setColorimetry(colorimetry)
print "[AutoRes] new content is %sx%s%s%s" % (width, height, prog, frate)
if new_mode in videoresolution_dictionary:
new_mode = videoresolution_dictionary[new_mode].value
print '[AutoRes] determined videomode', new_mode
old = resolutionlabel["content"].getText()
codec_info = "%s %s" % (videocodec, width)
gamma = (" SDR", " HDR", " HDR10", " HLG", "")[gamma_num]
resolutionlabel["content"].setText(_("Videocontent: %sx%s%s %sHZ") % (codec_info, height, prog, frate) + gamma)
if self.lastmode != new_mode:
self.lastmode = new_mode
self.changeVideomode()
elif old != resolutionlabel["content"].getText() and config.plugins.autoresolution.showinfo.value:
resolutionlabel.show()
def changeVideomode(self):
if config.plugins.autoresolution.mode.value != "manual":
return
if usable:
mode = self.lastmode
if "p24" in mode or "p25" in mode or "p30" in mode or (self.extra_mode1080p50 and "1080p50" in mode) or (self.extra_mode1080p60 and "1080p60" in mode) or (self.extra_mode720p60 and "720p60" in mode) or (self.extra_mode2160p50 and "2160p50" in mode) or "720p50" in mode:
try:
v = open('/proc/stb/video/videomode', "w")
v.write("%s\n" % mode)
v.close()
print "[AutoRes] switching to", mode
if self.video_stream_service:
self.doSeekRelative(2 * 9000)
except:
print "[AutoRes] failed switching to", mode
resolutionlabel["restxt"].setText(_("Videomode: %s") % mode)
if config.plugins.autoresolution.showinfo.value:
resolutionlabel.show()
else:
self.setMode(mode)
if config.plugins.autoresolution.testmode.value and default[0] != mode:
resolutionlabeltxt = _("Videomode: %s") % mode
self.session.openWithCallback(
self.confirm,
MessageBox,
_("Autoresolution Plugin Testmode:\nIs %s OK?") % (resolutionlabeltxt),
MessageBox.TYPE_YESNO,
timeout=15,
default=False
)
else:
setDeinterlacer("auto")
if self.lastmode != default[0]:
self.setMode(default[0])
def confirm(self, confirmed):
if not confirmed:
self.setMode(default[0])
def setMode(self, mode, set=True):
if config.plugins.autoresolution.mode.value != "manual":
return
rate = config.av.videorate[mode].value
port_txt = "HDMI" if port == "DVI" else port
resolutionlabel["restxt"].setText(_("Videomode: %s %s %s") % (port_txt, mode, rate))
if set:
print "[AutoRes] switching to %s %s %s" % (port_txt, mode, rate)
if config.plugins.autoresolution.showinfo.value:
resolutionlabel.show()
try:
video_hw.setMode(port, mode, rate)
if self.video_stream_service:
self.doSeekRelative(2 * 9000)
except:
print "[AutoRes] Videomode: failed switching to", mode
return
self.lastmode = mode
def getSeek(self):
service = self.session.nav.getCurrentService()
if service is None:
return None
seek = service.seek()
if seek is None or not seek.isCurrentlySeekable():
return None
return seek
def doSeekRelative(self, pts):
seekable = self.getSeek()
if seekable is None:
return
seekable.seekRelative(pts < 0 and -1 or 1, abs(pts))
class ResolutionLabel(Screen):
height = getDesktop(0).size().height()
if height >= 2100:
skin = """
"""
elif height == 1080:
skin = """
"""
else:
skin = """
"""
def __init__(self, session):
Screen.__init__(self, session)
self["content"] = Label()
self["restxt"] = Label()
self.hideTimer = eTimer()
self.hideTimer.callback.append(self.hide)
self.onShow.append(self.hide_me)
def hide_me(self):
self.hideTimer.start(config.usage.infobar_timeout.index * 2000, True)
class AutoResSetupMenu(Screen, ConfigListScreen):
def __init__(self, session):
Screen.__init__(self, session)
self.skinName = ["AutoResSetupMenu", "Setup"]
self.setup_title = _("Autoresolution videomode setup")
self.setTitle(self.setup_title)
self.onChangedEntry = []
self.list = []
ConfigListScreen.__init__(self, self.list, session=session, on_change=self.changedEntry)
self.prev_manual_resolution_ext_menu = config.plugins.autoresolution.manual_resolution_ext_menu.value
self["actions"] = ActionMap(["SetupActions"],
{
"cancel": self.keyCancel,
"save": self.apply,
}, -2)
self["key_green"] = StaticText(_("OK"))
self["key_red"] = StaticText(_("Cancel"))
self.createSetup()
def createSetup(self):
self.list = [getConfigListEntry(_("Enable Autoresolution"), config.plugins.autoresolution.enable)]
if config.plugins.autoresolution.enable.value:
if usable:
self.list.append(getConfigListEntry(_("Mode"), config.plugins.autoresolution.mode))
if config.plugins.autoresolution.mode.value == "manual":
for mode, label in resolutions:
self.list.append(getConfigListEntry(label, videoresolution_dictionary[mode]))
if "720p" in config.av.videorate:
self.list.append(getConfigListEntry(_("Refresh Rate") + " 720p", config.av.videorate["720p"]))
if "1080i" in config.av.videorate:
self.list.append(getConfigListEntry(_("Refresh Rate") + " 1080i", config.av.videorate["1080i"]))
if "1080p" in config.av.videorate:
self.list.append(getConfigListEntry(_("Refresh Rate") + " 1080p", config.av.videorate["1080p"]))
if "2160p" in config.av.videorate:
self.list.append(getConfigListEntry(_("Refresh Rate") + " 2160p", config.av.videorate["2160p"]))
self.list.extend((
getConfigListEntry(_("Show info screen"), config.plugins.autoresolution.showinfo),
getConfigListEntry(_("Delay x seconds after service started"), config.plugins.autoresolution.delay_switch_mode),
getConfigListEntry(_("Running in testmode"), config.plugins.autoresolution.testmode),
getConfigListEntry(_("Deinterlacer mode for interlaced content"), config.plugins.autoresolution.deinterlacer),
getConfigListEntry(_("Deinterlacer mode for progressive content"), config.plugins.autoresolution.deinterlacer_progressive),
getConfigListEntry(_("Force set progressive for stream/video content"), config.plugins.autoresolution.force_progressive_mode)
))
if SystemInfo["HasHdrType"]:
self.list.append(getConfigListEntry(_("Smart HDR type (set 'auto' HDMI HDR type)"), config.plugins.autoresolution.hdmihdrtype))
if SystemInfo["HasColorimetry"] and config.plugins.autoresolution.hdmihdrtype.value:
self.list.append(getConfigListEntry(_("Separate colorimetry for HDR (set 'auto' HDMI Colorimetry)"), config.plugins.autoresolution.hdmicolorimetry))
else:
self.list.append(getConfigListEntry(_("Lock timeout"), config.plugins.autoresolution.lock_timeout))
self.list.append(getConfigListEntry(_("Ask before changing videomode"), config.plugins.autoresolution.ask_apply_mode))
if config.plugins.autoresolution.ask_apply_mode.value:
self.list.append(getConfigListEntry(_("Message timeout"), config.plugins.autoresolution.ask_timeout))
self.list.append(getConfigListEntry(_("Use 60HZ instead 30HZ"), config.plugins.autoresolution.auto_30_60))
self.list.append(getConfigListEntry(_("Alternative resolution when native not supported"), config.plugins.autoresolution.auto_24_30_alternative))
else:
self.list.append(getConfigListEntry(_("Autoresolution is not working in Scart/DVI-PC Mode"), ConfigNothing()))
elif config.av.videoport.value not in ('DVI-PC', 'Scart'):
self.list.append(getConfigListEntry(_("Show 'Manual resolution' in extensions menu"), config.plugins.autoresolution.manual_resolution_ext_menu))
if config.plugins.autoresolution.manual_resolution_ext_menu.value:
self.list.append(getConfigListEntry(_("Return back without confirmation after 10 sec."), config.plugins.autoresolution.ask_apply_mode))
self["config"].list = self.list
self["config"].setList(self.list)
def apply(self):
for x in self["config"].list:
x[1].save()
configfile.save()
if self.prev_manual_resolution_ext_menu != config.plugins.autoresolution.manual_resolution_ext_menu.value:
self.refreshPlugins()
self.close()
def keyLeft(self):
ConfigListScreen.keyLeft(self)
if self["config"].getCurrent() and len(self["config"].getCurrent()) > 0:
if self["config"].getCurrent()[1] in (config.plugins.autoresolution.enable, config.plugins.autoresolution.mode, config.plugins.autoresolution.ask_apply_mode, config.plugins.autoresolution.manual_resolution_ext_menu, config.plugins.autoresolution.hdmihdrtype):
self.createSetup()
def keyRight(self):
ConfigListScreen.keyRight(self)
if self["config"].getCurrent() and len(self["config"].getCurrent()) > 0:
if self["config"].getCurrent()[1] in (config.plugins.autoresolution.enable, config.plugins.autoresolution.mode, config.plugins.autoresolution.ask_apply_mode, config.plugins.autoresolution.manual_resolution_ext_menu, config.plugins.autoresolution.hdmihdrtype):
self.createSetup()
def changedEntry(self):
for x in self.onChangedEntry:
x()
def getCurrentEntry(self):
return self["config"].getCurrent() and self["config"].getCurrent()[0] or ""
def getCurrentValue(self):
if self["config"].getCurrent() and len(self["config"].getCurrent()) > 0:
return str(self["config"].getCurrent()[1].getText())
return ""
def createSummary(self):
return SetupSummary
def refreshPlugins(self):
from Components.PluginComponent import plugins
from Tools.Directories import SCOPE_PLUGINS, resolveFilename
plugins.clearPluginList()
plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
class AutoFrameRate(Screen):
def __init__(self, session):
Screen.__init__(self, session)
self.lockTimer = eTimer()
self.lockTimer.callback.append(self.unlockFramerateChange)
self.framerate_change_is_locked = False
self.lastService = None
self.__event_tracker = ServiceEventTracker(screen=self, eventmap={iPlayableService.evVideoFramerateChanged: self.AutoVideoFramerateChanged})
self.init = False
def AutoVideoFramerateChanged(self):
print "[AutoFrameRate] got event evFramerateChanged"
if usable and config.plugins.autoresolution.mode.value == "auto":
if config.av.videoport.value in config.av.videomode:
if config.av.videomode[config.av.videoport.value].value in config.av.videorate:
service = self.session.nav.getCurrentService()
ref = self.session.nav.getCurrentlyPlayingServiceReference()
if not ref or not service:
return
cur_service_str = ref.toString()
if not (cur_service_str and self.lastService):
self.lastService = cur_service_str
if cur_service_str != self.lastService:
self.lockTimer.stop()
self.lastService = cur_service_str
self.framerate_change_is_locked = False
info = service and service.info()
framerate = info and info.getInfo(iServiceInformation.sFrameRate)
if not framerate or framerate == -1:
try:
framerate = int(open("/proc/stb/vmpeg/0/framerate", "r").read())
except:
pass
if config.av.videorate[config.av.videomode[config.av.videoport.value].value].value in ("multi", "auto"):
replace_mode = '30'
if config.plugins.autoresolution.auto_30_60.value:
replace_mode = '60'
if framerate in (59940, 60000):
self.setVideoFrameRate('60')
elif framerate in (23000, 23976, 24000):
self.setVideoFrameRate('24')
elif framerate in (29970, 30000):
self.setVideoFrameRate(replace_mode)
else:
self.setVideoFrameRate('50')
def setVideoFrameRate(self, rate):
if self.framerate_change_is_locked:
return
try:
f = open("/proc/stb/video/videomode", "r")
videomode = f.read()
f.close()
if rate in ('24', '30'):
multi_videomode = videomode
if not videomode.endswith(rate):
resolutions = ('1080', '2160', '720')
for resolution in resolutions:
if videomode.startswith(resolution):
new_mode = resolution + 'p' + rate
if new_mode in modes_available:
multi_videomode = new_mode
break
elif config.plugins.autoresolution.auto_24_30_alternative.value:
for alternative_resolution in resolutions:
if alternative_resolution != resolution:
new_mode = alternative_resolution + 'p' + rate
if new_mode in modes_available:
multi_videomode = new_mode
break
else:
f = open("/proc/stb/video/videomode_%shz" % rate, "r")
multi_videomode = f.read()
f.close()
if videomode != multi_videomode:
self.new_mode = multi_videomode
self.cur_mode = videomode
self.framerate_change_is_locked = True
self.lockTimer.startLongTimer(int(config.plugins.autoresolution.lock_timeout.value))
if config.plugins.autoresolution.ask_apply_mode.value and self.init:
Notifications.AddNotificationWithCallback(self.changeFramerateCallback, MessageBox, _("Changing framerate for current service?\nCurrent framerate: %s\nNew framerate: %s\n") % (videomode, multi_videomode), MessageBox.TYPE_YESNO, timeout=int(config.plugins.autoresolution.ask_timeout.value))
else:
self.changeFramerateCallback(True)
if not self.init:
self.init = True
except IOError:
print "[AutoFrameRate] error at reading/writing /proc/stb/video.. files"
def changeFramerateCallback(self, ret=True):
if ret:
f = open("/proc/stb/video/videomode", "w")
f.write(self.new_mode)
f.close()
print "[AutoFramerate] set resolution/framerate: %s" % self.new_mode
service = self.session.nav.getCurrentlyPlayingServiceReference()
if service:
path = service.getPath()
if path.find("://") == -1:
self.doSeekRelative(2 * 9000)
def unlockFramerateChange(self):
self.lockTimer.stop()
self.framerate_change_is_locked = False
def getSeek(self):
service = self.session.nav.getCurrentService()
if service is None:
return None
seek = service.seek()
if seek is None or not seek.isCurrentlySeekable():
return None
return seek
def doSeekRelative(self, pts):
seekable = self.getSeek()
if seekable is None:
return
seekable.seekRelative(pts < 0 and -1 or 1, abs(pts))
class ManualResolution(Screen):
def __init__(self, session):
Screen.__init__(self, session)
self.choices = []
self.init = False
try:
f = open("/proc/stb/video/videomode_choices")
values = f.readline().replace("\n", "").replace("pal ", "").replace("ntsc ", "").replace("auto", "").replace("480i", "").replace("480p", "").replace("576i", "").replace("576p", "").replace("3d1080p24", "").replace("3d720p50", "").replace("3d720p", "").split(" ", -1)
for x in values:
if x:
entry = x.replace('i50', 'i@50hz').replace('i60', 'i@60hz').replace('p23', 'p@23.976hz').replace('p24', 'p@24hz').replace('p25', 'p@25hz').replace('p29', 'p@29.970hz').replace('p30', 'p@30hz').replace('p50', 'p@50hz').replace('p60', 'p@60hz'), x
self.choices.append(entry)
f.close()
except:
print"[ManualResolution] Error open /proc/stb/video/videomode_choices"
else:
self.choices and self.choices.sort()
def resolutionSelection(self):
if not self.choices:
return
try:
f = open("/proc/stb/vmpeg/0/xres", "r")
xresString = f.read()
f.close()
f = open("/proc/stb/vmpeg/0/yres", "r")
yresString = f.read()
f.close()
try:
f = open("/proc/stb/vmpeg/0/framerate", "r")
fpsString = f.read()
f.close()
except:
print "[ManualResolution] Error open /proc/stb/vmpeg/0/framerate"
fpsString = '50000'
xres = int(xresString, 16)
yres = int(yresString, 16)
fps = int(fpsString)
fpsFloat = float(fps)
fpsFloat = fpsFloat / 1000
except:
print "[ManualResolution] Error reading current mode!Stop!"
return
selection = 0
tlist = []
tlist.append((_("Exit"), "exit"))
tlist.append((_("Video: ") + str(xres) + "x" + str(yres) + "@" + str(fpsFloat) + "hz", ""))
tlist.append(("--", ""))
for x in self.choices:
tlist.append(x)
keys = ["green", "yellow", "blue", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
self.old_mode = ""
if self.init:
try:
self.old_mode = open("/proc/stb/video/videomode").read()[:-1]
except:
print "[ManualResolution] Error open /proc/stb/video/videomode"
if self.old_mode:
for x in range(len(tlist)):
if tlist[x][1] == self.old_mode:
selection = x
self.session.openWithCallback(self.resolutionSelected, ChoiceBox, title=_("Please select a resolution..."), list=tlist, selection=selection, keys=keys, windowTitle=_("Manual resolution"))
def resolutionSelected(self, res):
res = res and res[1]
if res and isinstance(res, str) and res != "exit":
self.setResolution(res)
if config.plugins.autoresolution.ask_apply_mode.value and self.init and self.old_mode != res:
self.session.openWithCallback(self.confirmMode, MessageBox, _("This resolution is OK?"), MessageBox.TYPE_YESNO, timeout=10, default=False)
if not self.init:
self.init = True
def confirmMode(self, answer):
if not answer and self.old_mode:
self.setResolution(self.old_mode)
def setResolution(self, mode):
try:
f = open("/proc/stb/video/videomode", "w")
f.write(mode)
f.close()
except:
print "[ManualResolution] Error write /proc/stb/video/videomode"
def openManualResolution(session, **kwargs):
if config.av.videoport.value not in ('DVI-PC', 'Scart'):
global manualResolution
if manualResolution is None:
manualResolution = session.instantiateDialog(ManualResolution)
manualResolution and manualResolution.resolutionSelection()
else:
config.plugins.autoresolution.manual_resolution_ext_menu.value = False
config.plugins.autoresolution.manual_resolution_ext_menu.save()
session.open(MessageBox, _("Manual resolution is not working in Scart/DVI-PC mode!"), MessageBox.TYPE_INFO, timeout=6)
def autostart(reason, **kwargs):
global resolutionlabel
if reason == 0 and "session" in kwargs and resolutionlabel is None:
session = kwargs["session"]
if session:
resolutionlabel = session.instantiateDialog(ResolutionLabel)
AutoFrameRate(session)
AutoRes(session)
def startSetup(menuid):
if menuid != "video":
return []
return [(_("Autoresolution"), autoresSetup, "autores_setup", None)]
def autoresSetup(session, **kwargs):
autostart(reason=0, session=session)
session.open(AutoResSetupMenu)
def Plugins(path, **kwargs):
lst = [PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART], fnc=autostart),
PluginDescriptor(name="Autoresolution", description=_("Autoresolution Switch"), where=PluginDescriptor.WHERE_MENU, fnc=startSetup)]
if not config.plugins.autoresolution.enable.value and config.plugins.autoresolution.manual_resolution_ext_menu.value:
lst.append(PluginDescriptor(name=_("Manual resolution"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=False, fnc=openManualResolution))
return lst