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