cfcb530f6d0c0e24c1921e47844f24dd1166e904
[vuplus_dvbapp-plugin] / ac3lipsync / src / AC3delay.py
1 from AC3utils import AC3, PCM, AC3GLOB, PCMGLOB, AC3PCM
2 from Components.config import config
3 from enigma import eTimer
4 from Tools.ISO639 import LanguageCodes
5 from Tools.HardwareInfo import HardwareInfo
6 import os
7 import NavigationInstance
8
9 class AC3delay:
10     def __init__(self):
11         self.iService = None
12         self.iServiceReference = None
13         self.iAudioDelay = None
14         self.channelAudio = AC3
15         self.whichAudio = AC3
16         self.bIsRecording = False
17
18         # Current audio- delay
19         self.systemDelay = {}
20
21         self.getAudioInformation()
22
23         self.activateTimer = eTimer()
24         self.activateTimer.callback.append(self.activateDelay)
25         self.activateWait = config.plugins.AC3LipSync.activationDelay.getValue()
26         
27         # Current value for movie start behaviour
28         self.movieStart = config.usage.on_movie_start.getValue()
29
30         # find out box type
31         self.oHWInfo = HardwareInfo()
32         if self.oHWInfo.get_device_name() in ("dm800","dm8000","dm500hd"):
33             self.bHasToRestartService = False
34         else:
35             self.bHasToRestartService = True
36         
37     def initAudio(self):
38         self.iService = NavigationInstance.instance.getCurrentService()
39         self.iServiceReference = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
40         self.iAudioDelay = self.iService and self.iService.audioDelay()
41         self.iSeek = self.iService and self.iService.seek()
42
43     def deleteAudio(self):
44         self.iService = None
45         self.iAudioDelay = None
46         self.iSeek = None
47
48     def setChannelAudio(self, sAudio):
49         self.channelAudio = sAudio
50
51     def delayedActivateDelay(self):
52         if self.activateTimer.isActive:
53             self.activateTimer.stop()
54         self.activateTimer.start(self.activateWait, False)
55
56     def activateDelay(self):
57         # This activation code is only neccessary for DM7025. 
58         # DM800, DM8000 and DM500HD directly activate the delay after using "setAC3Delay" and "setPCMDelay", they don't need the service restart
59         if self.activateTimer.isActive:
60             self.activateTimer.stop()
61         if self.bHasToRestartService == True:
62             bInitialized = False
63             if self.iService == None:
64                 self.initAudio()
65                 bInitialized = True
66             if self.iServiceReference is not None:
67                 lCurPosition = self.cueGetCurrentPosition()
68                 self.deleteAudio()
69                 if self.whichAudio == self.channelAudio:
70                     config.usage.on_movie_start.setValue("beginning")
71                     NavigationInstance.instance.stopService()
72                     NavigationInstance.instance.playService(self.iServiceReference)
73                     config.usage.on_movie_start.setValue(self.movieStart)
74                     if lCurPosition is not None:
75                         self.lCurPosition = lCurPosition
76                         self.timer = eTimer()
77                         self.timer.callback.append(self.seekAfterWait)
78                         self.timer.start(200, False)
79             else:
80                 self.deleteAudio()
81         
82     def seekAfterWait(self):
83         self.timer.stop()
84         self.initAudio()
85         if self.iSeek is not None:
86             self.iSeek.seekTo(self.lCurPosition)
87         self.deleteAudio()
88
89     def cueGetCurrentPosition(self):
90         if self.iSeek is None:
91             return None
92         r = self.iSeek.getPlayPosition()
93         if r[0]:
94             return None
95         return long(r[1])
96
97     def getSystemDelay(self, sAudio):
98         bInitialized = False
99         if self.iService == None:
100             self.initAudio()
101             bInitialized = True
102         iDelay = 0
103         if self.iAudioDelay is not None:
104             if sAudio == AC3:
105                 iDelay = self.iAudioDelay.getAC3Delay()
106             elif sAudio == PCM:
107                 iDelay = self.iAudioDelay.getPCMDelay()
108             elif sAudio == AC3GLOB:
109                 iDelay = config.av.generalAC3delay.getValue()
110             else:
111                 iDelay = config.av.generalPCMdelay.getValue()
112         if bInitialized == True:
113             self.deleteAudio()
114         if iDelay == -1:
115             iDelay = 0
116         return iDelay
117
118     def setSystemDelay(self, sAudio, iDelay, bDelayStart):
119         bInitialized = False
120         if self.iService == None:
121             self.initAudio()
122             bInitialized = True
123         if self.iAudioDelay is not None:
124             iDelayLameDb = iDelay
125             if iDelayLameDb == 0:
126                 iDelayLameDb = -1
127             if sAudio == AC3:
128                 self.iAudioDelay.setAC3Delay(iDelayLameDb)
129             elif sAudio == PCM:
130                 self.iAudioDelay.setPCMDelay(iDelayLameDb)
131             elif sAudio == AC3GLOB:
132                 config.av.generalAC3delay.setValue(iDelay)
133                 config.av.generalAC3delay.save()
134                 #Setting the global delay does not activate it, so now we call setAC3Delay to activate the new delay..
135                 self.iAudioDelay.setAC3Delay(self.systemDelay[AC3])
136             else:
137                 config.av.generalPCMdelay.setValue(iDelay)
138                 config.av.generalPCMdelay.save()
139                 #Setting the global delay does not activate it, so now we call setPCMDelay to activate the new delay..
140                 self.iAudioDelay.setPCMDelay(self.systemDelay[PCM])
141         if bInitialized == True:
142             self.deleteAudio()
143         if bDelayStart == True:
144             self.delayedActivateDelay()
145         else:
146             self.activateDelay()
147
148     def getAudioInformation(self):
149         bInitialized = False
150         if self.iService == None:
151             self.initAudio()
152             bInitialized = True
153
154         # check if we are in a recording
155         lCurPosition = self.cueGetCurrentPosition()
156         if lCurPosition is not None:
157             self.bIsRecording = True
158             
159         # check if downmix is enabled
160         try:
161             bDownmixEnabled = config.av.downmix_ac3.value
162         except:
163             bDownmixEnabled = False
164
165         oAudioTracks = self.iService and self.iService.audioTracks()
166         n = oAudioTracks and oAudioTracks.getNumberOfTracks() or 0
167         tlist = []
168         self.selectedAudioIndex = oAudioTracks.getCurrentTrack()
169         if n >= 0:
170             for x in range(n):
171                 i = oAudioTracks.getTrackInfo(x)
172                 language = i.getLanguage()
173                 description = i.getDescription()
174                 if LanguageCodes.has_key(language):
175                     language = LanguageCodes[language][0]
176                 if len(description):
177                     description += " (" + language + ")"
178                 else:
179                     description = language
180
181                 tlist.append((description, x))
182                 if x == self.selectedAudioIndex:
183                     if ((description.find("AC3") != -1 or description.find("AC-3") != -1) and not bDownmixEnabled) or description.find("DTS") != -1:
184                         self.whichAudio = AC3
185                         self.channelAudio = AC3
186                     else:
187                         self.whichAudio = PCM
188                         self.channelAudio = PCM
189                     self.selectedAudioInfo = (description, x)
190             tlist.sort(key=lambda x: x[0])
191
192             self.audioTrackList = tlist
193         for sAudio in AC3PCM:
194             self.systemDelay[sAudio]=self.getSystemDelay(sAudio)
195         del oAudioTracks
196         if bInitialized == True:
197             self.deleteAudio()