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