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