- support for new Setup skin,
[enigma2-plugins.git] / autoresolution / src / plugin.py
1 from Screens.Screen import Screen
2 from Screens.Setup import SetupSummary
3 from Screens.MessageBox import MessageBox
4 from Components.ConfigList import ConfigList, ConfigListScreen
5 from Components.config import config, getConfigListEntry, ConfigSelection, ConfigSubsection, ConfigYesNo, ConfigSubDict
6 from Components.ServiceEventTracker import ServiceEventTracker
7 from Components.ActionMap import ActionMap
8 from Components.Label import Label
9 from Components.Sources.StaticText import StaticText
10 from enigma import iPlayableService, iServiceInformation, eTimer
11 from Plugins.Plugin import PluginDescriptor
12 from Plugins.SystemPlugins.Videomode.VideoHardware import video_hw # depends on Videomode Plugin
13
14 session = [ ]
15
16 default = (config.av.videomode[config.av.videoport.value].value, _("default"))
17 preferedmodes = [mode[0] for mode in video_hw.getModeList(config.av.videoport.value) if mode[0] != default[0]]
18 preferedmodes.append(default)
19 resolutions = (('sd_i_50', (_("SD 25/50HZ Interlace Mode"))), ('sd_i_60', (_("SD 30/60HZ Interlace Mode"))), \
20                         ('sd_p_50', (_("SD 25/50HZ Progressive Mode"))), ('sd_p_60', (_("SD 30/60HZ Progressive Mode"))), \
21                         ('hd_i', (_("HD Interlace Mode"))), ('hd_p', (_("HD Progressive Mode"))), \
22                         ('p720_24', (_("Enable 720p24 Mode"))), ('p1080_24', (_("Enable 1080p24 Mode"))), \
23                         ('p1080_25', (_("Enable 1080p25 Mode"))), ('p1080_30', (_("Enable 1080p30 Mode"))))
24
25 config.plugins.autoresolution = ConfigSubsection()
26 config.plugins.autoresolution.enable = ConfigYesNo(default = False)
27 config.plugins.autoresolution.videoresolution = ConfigSubDict()
28 videoresolution_dictionary = {}
29 for mode in resolutions:
30         if mode[0].startswith('p1080'):
31                 choices = ['1080p24', '1080p25', '1080p30'] + preferedmodes
32         elif mode[0] == 'p720_24':
33                 choices = ['720p24', '1080p24'] + preferedmodes
34         else:
35                 choices = preferedmodes
36         config.plugins.autoresolution.videoresolution[mode[0]] = ConfigSelection(default = default[0], choices = choices)
37         videoresolution_dictionary[mode[0]] = (config.plugins.autoresolution.videoresolution[mode[0]])
38 config.plugins.autoresolution.showinfo = ConfigYesNo(default = True)
39 config.plugins.autoresolution.testmode = ConfigYesNo(default = False)
40 config.plugins.autoresolution.deinterlacer = ConfigSelection(default = "auto", choices =
41                 [("off", _("off")), ("auto", _("auto")), ("on", _("on")), ("bob", _("bob"))])
42 config.plugins.autoresolution.deinterlacer_progressive = ConfigSelection(default = "auto", choices =
43                 [("off", _("off")), ("auto", _("auto")), ("on", _("on")), ("bob", _("bob"))])
44 config.plugins.autoresolution.delay_switch_mode = ConfigSelection(default = "1000", choices = [
45                 ("1000", "1 " + _("second")), ("2000", "2 " + _("seconds")), ("3000", "3 " + _("seconds")),
46                 ("4000", "4 " + _("seconds")), ("5000", "5 " + _("seconds")), ("6000", "6 " + _("seconds")), ("7000", "7 " + _("seconds")),
47                 ("8000", "8 " + _("seconds")), ("9000", "9 " + _("seconds")), ("10000", "10 " + _("seconds"))])
48
49 def setDeinterlacer(mode):
50         print "[AutoRes] switch deinterlacer mode to %s" % mode
51         f = open('/proc/stb/vmpeg/deinterlace' , "w")
52         f.write("%s\n" % mode)
53         f.close()
54
55 def setDeinterlacerInterlaced(configElement):
56         setDeinterlacer(config.plugins.autoresolution.deinterlacer.value)
57 config.plugins.autoresolution.deinterlacer.addNotifier(setDeinterlacerInterlaced)
58
59 def setDeinterlacerProgressive(configElement):
60         setDeinterlacer(config.plugins.autoresolution.deinterlacer_progressive.value)
61 config.plugins.autoresolution.deinterlacer_progressive.addNotifier(setDeinterlacerProgressive)
62
63 frqdic = { 23976: '24', \
64                 24000: '24', \
65                 25000: '25', \
66                 29970: '30', \
67                 30000: '30', \
68                 50000: '50', \
69                 59940: '60', \
70                 60000: '60'}
71
72 class AutoRes(Screen):
73         def __init__(self, session):
74                 Screen.__init__(self, session)
75                 self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
76                         {
77                                 iPlayableService.evVideoSizeChanged: self.__evVideoSizeChanged,
78                                 iPlayableService.evVideoProgressiveChanged: self.__evVideoProgressiveChanged,
79                                 iPlayableService.evVideoFramerateChanged: self.__evVideoFramerateChanged,
80                         })
81                 self.timer = eTimer()
82                 self.timer.callback.append(self.determineContent)
83                 self.lastmode = config.av.videomode[config.av.videoport.value].value
84         
85         def __evVideoFramerateChanged(self):
86                 print "[AutoRes] got event evFramerateChanged"
87                 if self.timer.isActive():
88                         self.timer.stop()
89                 if config.plugins.autoresolution.enable.value:
90                         self.timer.start(int(config.plugins.autoresolution.delay_switch_mode.value))
91
92         def __evVideoSizeChanged(self):
93                 print "[AutoRes] got event evVideoSizeChanged"
94                 if self.timer.isActive():
95                         self.timer.stop()
96                 if config.plugins.autoresolution.enable.value:
97                         self.timer.start(int(config.plugins.autoresolution.delay_switch_mode.value))
98
99         def __evVideoProgressiveChanged(self):
100                 print "[AutoRes] got event evVideoProgressiveChanged"
101                 if self.timer.isActive():
102                         self.timer.stop()
103                 if config.plugins.autoresolution.enable.value:
104                         self.timer.start(int(config.plugins.autoresolution.delay_switch_mode.value))
105
106         def determineContent(self):
107                 self.timer.stop()
108                 service = session.nav.getCurrentService()
109                 info = service and service.info()
110                 height = info and info.getInfo(iServiceInformation.sVideoHeight)
111                 width = info and info.getInfo(iServiceInformation.sVideoWidth)
112                 framerate = info and info.getInfo(iServiceInformation.sFrameRate)
113                 frate = str(framerate)[:2] #fallback?
114                 if frqdic.has_key(framerate):
115                         frate = frqdic[framerate]
116                 progressive = info and info.getInfo(iServiceInformation.sProgressive)
117                 if progressive == 1:
118                         prog = 'p'
119                 else:
120                         prog = 'i'
121                 print "[AutoRes] new content is %sx%s%s%s" %(width, height, prog, frate)
122                 self.determineVideoMode(width, height, prog, frate)
123
124         def determineVideoMode(self, width, height, prog, frate):
125                 if (height >= 900 or width >= 1600) and frate in ('24', '25', '30') and prog == 'p':    # 1080p content
126                         new_mode = 'p1080_%s' % frate
127                 elif (height >= 576 or width >= 720) and frate == '24' and prog == 'p':                 # 720p24 detection
128                         new_mode = 'p720_24'
129                 elif (height == 576 or height == 288) and frate in ('25', '50'):
130                         new_mode = 'sd_%s_50' % prog
131                 elif (height == 480 or height == 240) and frate in ('24', '30', '60'):
132                         new_mode = 'sd_%s_60' % prog
133                 else:
134                         new_mode = 'hd_%s' % prog
135                 if videoresolution_dictionary.has_key(new_mode):
136                         new_mode = videoresolution_dictionary[new_mode].value
137                         print '[AutoRes] determined videomode', new_mode
138                         self.contentlabeltxt = "Videocontent: %sx%s%s %sHZ" % (width, height, prog, frate)
139                         if new_mode != self.lastmode:
140                                 self.lastmode = new_mode
141                                 self.changeVideomode(new_mode)
142                         if config.plugins.autoresolution.showinfo.value:
143                                 resolutionlabel["content"].setText(self.contentlabeltxt)
144                                 resolutionlabel.show()
145                 if prog == 'p':
146                     setDeinterlacer(config.plugins.autoresolution.deinterlacer_progressive.value)
147                 else:
148                     setDeinterlacer(config.plugins.autoresolution.deinterlacer.value)
149
150         def changeVideomode(self, mode):
151                 if mode.find("1080p") != -1 or mode.find("720p24") != -1:
152                         print "[AutoRes] switching to", mode
153                         v = open('/proc/stb/video/videomode' , "w")
154                         v.write("%s\n" % mode)
155                         v.close()
156                         resolutionlabeltxt = "Videomode: %s" % mode
157                 else:
158                         port = config.av.videoport.value
159                         rate = config.av.videorate[mode].value
160                         print "[AutoRes] switching to %s %s %s" % (port, mode, rate)
161                         video_hw.setMode(port, mode, rate)
162                         resolutionlabeltxt = 'Videomode: %s %s %s' % (port, mode, rate)
163                 if config.plugins.autoresolution.showinfo.value:
164                         resolutionlabel["restxt"].setText(resolutionlabeltxt)
165                         resolutionlabel["content"].setText(self.contentlabeltxt)
166                         resolutionlabel.show()
167                 if config.plugins.autoresolution.testmode.value:
168                         self.session.openWithCallback(
169                                 self.confirm,
170                                 MessageBox,
171                                 _("Autoresolution Plugin Testmode:\nIs %s ok?") % (resolutionlabeltxt),
172                                 MessageBox.TYPE_YESNO,
173                                 timeout = 15,
174                                 default = False
175                         )
176
177         def confirm(self, confirmed):
178                 if not confirmed:
179                         port = config.av.videoport.value
180                         mode = config.av.videomode[port].value
181                         rate = config.av.videorate[mode].value
182                         if config.plugins.autoresolution.showinfo.value:
183                                 resolutionlabel["restxt"].setText("Videomode: %s %s %s" % (port, mode, rate))
184                                 resolutionlabel.show()
185                         video_hw.setMode(port, mode, rate)
186
187 class ResolutionLabel(Screen):
188         skin = """
189                 <screen position="50,40" size="250,36" flags="wfNoBorder" >
190                         <widget name="content" position="0,0" size="250,18" font="Regular;16" />
191                         <widget name="restxt" position="0,18" size="250,18" font="Regular;16" />
192                 </screen>"""
193         def __init__(self, session):
194                 Screen.__init__(self, session)
195
196                 self["content"] = Label()
197                 self["restxt"] = Label()
198
199                 self.hideTimer = eTimer()
200                 self.hideTimer.callback.append(self.hide)
201
202                 self.onShow.append(self.hide_me)
203                 self.onHide.append(self.clean_me)
204
205         def hide_me(self):
206                 self.hideTimer.start(config.usage.infobar_timeout.index * 1500, True)
207
208         def clean_me(self):
209 #               self["restxt"].setText("")
210                 self["content"].setText("")
211
212
213 class AutoResSetupMenu(Screen, ConfigListScreen):
214         def __init__(self, session):
215                 Screen.__init__(self, session)
216                 self.skinName = [ "AutoResSetupMenu", "Setup" ]
217                 self.setup_title = _("Autoresolution videomode setup")
218
219                 self.onChangedEntry = [ ]
220                 self.list = [ ]
221                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
222
223                 self["actions"] = ActionMap(["SetupActions"],
224                         {
225                                 "cancel": self.keyCancel,
226                                 "save": self.apply,
227                         }, -2)
228
229                 self["key_green"] = StaticText(_("OK"))
230                 self["key_red"] = StaticText(_("Cancel"))
231
232                 self.createSetup()
233                 self.onLayoutFinish.append(self.layoutFinished)
234
235         def layoutFinished(self):
236                 self.setTitle(_("Autoresolution settings"))
237
238         def createSetup(self):
239                 self.list = [
240                         getConfigListEntry(_("Enable Autoresolution"), config.plugins.autoresolution.enable)
241                 ]
242                 if config.plugins.autoresolution.enable.value:
243                         for mode, label in resolutions:
244                                 self.list.append(getConfigListEntry(label, videoresolution_dictionary[mode]))
245                         self.list.extend((
246                                 getConfigListEntry(_("Show info screen"), config.plugins.autoresolution.showinfo),
247                                 getConfigListEntry(_("Delay x seconds after service started"), config.plugins.autoresolution.delay_switch_mode),
248                                 getConfigListEntry(_("Running in testmode"), config.plugins.autoresolution.testmode),
249                                 getConfigListEntry(_("Deinterlacer mode"), config.plugins.autoresolution.deinterlacer),
250                                 getConfigListEntry(_("Deinterlacer mode for progressive content"), config.plugins.autoresolution.deinterlacer_progressive)
251                         ))
252                 self["config"].list = self.list
253                 self["config"].setList(self.list)
254
255         def apply(self):
256                 for x in self["config"].list:
257                         x[1].save()
258                 self.close()
259
260         def keyLeft(self):
261                 ConfigListScreen.keyLeft(self)
262                 self.createSetup()
263
264         def keyRight(self):
265                 ConfigListScreen.keyRight(self)
266                 self.createSetup()
267
268         # for summary:
269         def changedEntry(self):
270                 for x in self.onChangedEntry:
271                         x()
272
273         def getCurrentEntry(self):
274                 return self["config"].getCurrent()[0]
275
276         def getCurrentValue(self):
277                 return str(self["config"].getCurrent()[1].getText())
278
279         def createSummary(self):
280                 return SetupSummary
281
282
283 def autostart(reason, **kwargs):
284         global session, resolutionlabel
285         if "session" in kwargs:
286                 session = kwargs["session"]
287                 resolutionlabel = session.instantiateDialog(ResolutionLabel)
288                 AutoRes(session)
289
290 def startSetup(menuid):
291         if menuid != "system":
292                 return [ ]
293         return [("Autoresolution...", autoresSetup, "autores_setup", 45)]
294
295 def autoresSetup(session, **kwargs):
296         session.open(AutoResSetupMenu)
297
298 def Plugins(path, **kwargs):
299         return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART], fnc = autostart), \
300                 PluginDescriptor(name="Autoresolution", description=_("Autoresolution Switch"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup) ]