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