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