updated on Thu Jan 19 16:10:29 UTC 2012
[aur-mirror.git] / enigma2 / enigma21_11_11.patch
blob67d68849c6f0383420f6085b3a60d8ea1c8e6efa
1 diff -crB Enigma2PC/data/keymap.xml Enigma2PC_orig/data/keymap.xml
2 *** Enigma2PC/data/keymap.xml 2011-11-20 21:56:11.100830925 +0400
3 --- Enigma2PC_orig/data/keymap.xml 2011-11-20 03:22:00.000000000 +0400
4 ***************
5 *** 1,680 ****
6 ! <keymap>
7 ! <map context="ListboxActions">
8 ! <device name="keyboard">
9 ! <key id="a" mapto="up" flags="mr" />
10 ! <key id="b" mapto="down" flags="mr" />
11 ! </device>
12 ! <key id="KEY_UP" mapto="moveUp" flags="mr" />
13 ! <key id="KEY_DOWN" mapto="moveDown" flags="mr" />
14 ! <key id="KEY_HOME" mapto="moveTop" flags="mr" />
15 ! <key id="KEY_END" mapto="moveEnd" flags="mr" />
16 ! <key id="KEY_PAGEUP" mapto="pageUp" flags="mr" />
17 ! <key id="KEY_PAGEDOWN" mapto="pageDown" flags="mr" />
18 ! <key id="KEY_LEFT" mapto="pageUp" flags="mr" />
19 ! <key id="KEY_RIGHT" mapto="pageDown" flags="mr" />
21 ! <key id="1" mapto="moveUp" flags="mr" />
22 ! <key id="2" mapto="moveDown" flags="mr" />
23 ! </map>
25 ! <map context="KeyboardInputActions">
26 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
27 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
28 ! <key id="KEY_HOME" mapto="home" flags="mr" />
29 ! <key id="KEY_END" mapto="end" flags="mr" />
30 ! <key id="KEY_BACK" mapto="home" flags="mr" />
31 ! <key id="KEY_FORWARD" mapto="end" flags="mr" />
32 ! <key id="KEY_DELETE" mapto="deleteForward" flags="mr" />
33 ! <key id="KEY_BACKSPACE" mapto="deleteBackward" flags="mr" />
34 ! <key id="KEY_TAB" mapto="tab" flags="mr" />
35 ! <key id="KEY_INSERT" mapto="toggleOverwrite" flags="m" />
36 ! </map>
38 ! <map context="SetupActions">
39 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
40 ! <key id="KEY_OK" mapto="ok" flags="m" />
41 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
42 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
43 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
44 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
45 ! <key id="KEY_RED" mapto="cancel" flags="m" />
46 ! <key id="KEY_GREEN" mapto="save" flags="m" />
47 ! <device name="dreambox remote control (native)">
48 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
49 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
50 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
51 ! </device>
52 ! <device name="dreambox advanced remote control (native)">
53 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
54 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
55 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
56 ! </device>
57 ! <key id="KEY_1" mapto="1" flags="m" />
58 ! <key id="KEY_2" mapto="2" flags="m" />
59 ! <key id="KEY_3" mapto="3" flags="m" />
60 ! <key id="KEY_4" mapto="4" flags="m" />
61 ! <key id="KEY_5" mapto="5" flags="m" />
62 ! <key id="KEY_6" mapto="6" flags="m" />
63 ! <key id="KEY_7" mapto="7" flags="m" />
64 ! <key id="KEY_8" mapto="8" flags="m" />
65 ! <key id="KEY_9" mapto="9" flags="m" />
66 ! <key id="KEY_0" mapto="0" flags="m" />
67 ! </map>
69 ! <map context="InputActions">
70 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
71 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
72 ! <key id="KEY_1" mapto="1" flags="m" />
73 ! <key id="KEY_2" mapto="2" flags="m" />
74 ! <key id="KEY_3" mapto="3" flags="m" />
75 ! <key id="KEY_4" mapto="4" flags="m" />
76 ! <key id="KEY_5" mapto="5" flags="m" />
77 ! <key id="KEY_6" mapto="6" flags="m" />
78 ! <key id="KEY_7" mapto="7" flags="m" />
79 ! <key id="KEY_8" mapto="8" flags="m" />
80 ! <key id="KEY_9" mapto="9" flags="m" />
81 ! <key id="KEY_0" mapto="0" flags="m" />
82 ! </map>
84 ! <map context="InfobarEPGActions">
85 ! <key id="KEY_INFO" mapto="showEventInfo" flags="b" />
86 ! <key id="KEY_INFO" mapto="showEventInfoPlugin" flags="l" />
87 ! </map>
89 ! <map context="InfobarInstantRecord">
90 ! <device name="dreambox advanced remote control (native)">
91 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
92 ! <!-- this breaks timeshift end!!! key id="KEY_STOP" mapto="instantRecord" flags="m" /-->
93 ! </device>
94 ! <device name="dreambox ir keyboard">
95 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
96 ! </device>
97 ! <device name="dreambox remote control (native)">
98 ! <key id="KEY_RED" mapto="instantRecord" flags="b" />
99 ! </device>
100 ! <device name="Xlib">
101 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
102 ! </device>
103 ! </map>
105 ! <map context="InfobarExtensions">
106 ! <key id="KEY_BLUE" mapto="extensions" flags="b" />
107 ! </map>
109 ! <map context="SatlistShortcutAction">
110 ! <key id="KEY_BLUE" mapto="nothingconnected" flags="b" />
111 ! </map>
113 ! <map context="InfobarChannelSelection">
114 ! <key id="KEY_LEFT" mapto="zapUp" flags="mr" />
115 ! <key id="KEY_RIGHT" mapto="zapDown" flags="mr" />
116 ! <key id="KEY_UP" mapto="switchChannelUp" flags="mr" />
117 ! <key id="KEY_DOWN" mapto="switchChannelDown" flags="mr" />
118 ! <key id="KEY_PREVIOUS" mapto="historyBack" flags="mr" />
119 ! <key id="KEY_NEXT" mapto="historyNext" flags="mr" />
120 ! <key id="KEY_BACK" mapto="historyBack" flags="mr" />
121 ! <key id="KEY_FORWARD" mapto="historyNext" flags="mr" />
122 ! <key id="KEY_CHANNELUP" mapto="openServiceList" flags="m" />
123 ! <key id="KEY_CHANNELDOWN" mapto="openServiceList" flags="m" />
124 ! <key id="BTN_0" mapto="zapUp" flags="mr" />
125 ! <key id="BTN_1" mapto="zapDown" flags="mr" />
126 ! </map>
128 ! <map context="MinuteInputActions">
129 ! <key id="KEY_UP" mapto="up" flags="mr" />
130 ! <key id="KEY_DOWN" mapto="down" flags="mr" />
131 ! <key id="KEY_OK" mapto="ok" flags="m" />
132 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
133 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
134 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
135 ! </map>
137 ! <map context="InputAsciiActions">
138 ! <device name="Console">
139 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
140 ! </device>
141 ! <device name="SDL">
142 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
143 ! </device>
144 ! </map>
146 ! <map context="InputBoxActions">
147 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
148 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
149 ! <key id="KEY_OK" mapto="ok" flags="m" />
150 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
151 ! <key id="KEY_EXIT" mapto="back" flags="m" />
152 ! <key id="KEY_ESC" mapto="back" flags="m" />
153 ! <device name="dreambox remote control (native)">
154 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
155 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
156 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
157 ! </device>
158 ! <device name="dreambox advanced remote control (native)">
159 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
160 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
161 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
162 ! </device>
163 ! <key id="KEY_1" mapto="1" flags="m" />
164 ! <key id="KEY_2" mapto="2" flags="m" />
165 ! <key id="KEY_3" mapto="3" flags="m" />
166 ! <key id="KEY_4" mapto="4" flags="m" />
167 ! <key id="KEY_5" mapto="5" flags="m" />
168 ! <key id="KEY_6" mapto="6" flags="m" />
169 ! <key id="KEY_7" mapto="7" flags="m" />
170 ! <key id="KEY_8" mapto="8" flags="m" />
171 ! <key id="KEY_9" mapto="9" flags="m" />
172 ! <key id="KEY_0" mapto="0" flags="m" />
173 ! </map>
175 ! <map context="WizardActions">
176 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
177 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
178 ! <key id="KEY_UP" mapto="up" flags="mr" />
179 ! <key id="KEY_DOWN" mapto="down" flags="mr" />
180 ! <key id="KEY_OK" mapto="ok" flags="m" />
181 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
182 ! <key id="KEY_EXIT" mapto="back" flags="m" />
183 ! <key id="KEY_ESC" mapto="back" flags="m" />
184 ! </map>
186 ! <map context="InfobarMenuActions">
187 ! <key id="KEY_MENU" mapto="mainMenu" flags="mr" />
188 ! <key id="KEY_SPACE" mapto="mainMenu" flags="mr" />
189 ! </map>
191 ! <map context="MenuActions">
192 ! <key id="KEY_MENU" mapto="menu" flags="mr" />
193 ! <key id="KEY_SPACE" mapto="menu" flags="mr" />
194 ! </map>
196 ! <map context="InfobarShowHideActions">
197 ! <key id="KEY_OK" mapto="toggleShow" flags="m" />
198 ! <key id="KEY_ENTER" mapto="toggleShow" flags="m" />
199 ! <key id="KEY_EXIT" mapto="hide" flags="m" />
200 ! <key id="KEY_ESC" mapto="hide" flags="m" />
201 ! </map>
203 ! <map context="InfobarActions">
204 ! <key id="KEY_VIDEO" mapto="showMovies" flags="m" />
205 ! <key id="KEY_RADIO" mapto="showRadio" flags="m" />
206 ! <key id="KEY_TV" mapto="showTv" flags="m" />
207 ! </map>
209 ! <map context="InfobarAudioSelectionActions">
210 ! <device name="dreambox remote control (native)">
211 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
212 ! </device>
213 ! <device name="dreambox ir keyboard">
214 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
215 ! </device>
216 ! <device name="dreambox advanced remote control (native)">
217 ! <key id="KEY_YELLOW" mapto="audioSelection" flags="b" />
218 ! </device>
219 ! <device name="Xlib">
220 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
221 ! </device>
222 ! </map>
224 ! <map context="InfobarSubserviceSelectionActions">
225 ! <key id="KEY_GREEN" mapto="subserviceSelection" flags="b" />
226 ! </map>
228 ! <map context="InfobarSubserviceQuickzapActions">
229 ! <key id="KEY_PREVIOUS" mapto="prevSubservice" flags="m" />
230 ! <key id="KEY_NEXT" mapto="nextSubservice" flags="m" />
231 ! <key id="KEY_BACK" mapto="prevSubservice" flags="m" />
232 ! <key id="KEY_FORWARD" mapto="nextSubservice" flags="m" />
233 ! <key id="KEY_EXIT" mapto="exit" flags="m" />
234 ! <key id="KEY_ESC" mapto="exit" flags="m" />
235 ! <device name="dreambox remote control (native)">
236 ! <key id="KEY_TV" mapto="exit" flags="m" />
237 ! </device>
238 ! <device name="dreambox advanced remote control (native)">
239 ! <key id="KEY_TV" mapto="exit" flags="m" />
240 ! </device>
241 ! </map>
243 ! <map context="GlobalActions">
244 ! <key id="KEY_VOLUMEUP" mapto="volumeUp" flags="mr" />
245 ! <key id="KEY_VOLUMEDOWN" mapto="volumeDown" flags="mr" />
246 ! <key id="KEY_MUTE" mapto="volumeMute" flags="mr" />
247 ! <key id="KEY_POWER" mapto="power_long" flags="l" />
248 ! <key id="KEY_POWER" mapto="power_down" flags="m" />
249 ! <key id="KEY_POWER" mapto="power_up" flags="b" />
250 ! <device name="dreambox front panel">
251 ! <key id="KEY_POWER" mapto="deepstandby" flags="l" />
252 ! </device>
253 ! </map>
255 ! <map context="PowerKeyActions">
256 ! <key id="KEY_POWER" mapto="powerdown" flags="m" />
257 ! <key id="KEY_POWER" mapto="powerup" flags="b" />
258 ! </map>
260 ! <map context="NumberActions">
261 ! <key id="KEY_1" mapto="1" flags="m" />
262 ! <key id="KEY_2" mapto="2" flags="m" />
263 ! <key id="KEY_3" mapto="3" flags="m" />
264 ! <key id="KEY_4" mapto="4" flags="m" />
265 ! <key id="KEY_5" mapto="5" flags="m" />
266 ! <key id="KEY_6" mapto="6" flags="m" />
267 ! <key id="KEY_7" mapto="7" flags="m" />
268 ! <key id="KEY_8" mapto="8" flags="m" />
269 ! <key id="KEY_9" mapto="9" flags="m" />
270 ! <key id="KEY_0" mapto="0" flags="m" />
271 ! </map>
273 ! <map context="TextEntryActions">
274 ! <device name="dreambox remote control (native)">
275 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
276 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
277 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
278 ! </device>
279 ! <device name="dreambox advanced remote control (native)">
280 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
281 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
282 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
283 ! </device>
284 ! </map>
286 ! <map context="InfobarSeekActions">
287 ! <device name="dreambox remote control (native)">
288 ! <key id="KEY_YELLOW" mapto="pauseService" flags="b" />
289 ! <key id="KEY_GREEN" mapto="unPauseService" flags="b" />
290 ! <key id="KEY_RED" mapto="seekBack" flags="b" />
291 ! <key id="KEY_BLUE" mapto="seekFwd" flags="b" />
292 ! <key id="KEY_RED" mapto="seekBackManual" flags="l" />
293 ! <key id="KEY_BLUE" mapto="seekFwdManual" flags="l" />
294 ! </device>
295 ! <device name="dreambox advanced remote control (native)">
296 ! <key id="KEY_PLAY" mapto="playpauseService" flags="m" />
297 ! <key id="KEY_PLAYPAUSE" mapto="playpauseService" flags="m" />
298 ! <key id="KEY_PREVIOUSSONG" mapto="seekBack" flags="b" />
299 ! <key id="KEY_NEXTSONG" mapto="seekFwd" flags="b" />
300 ! <key id="KEY_PREVIOUSSONG" mapto="seekBackManual" flags="l" />
301 ! <key id="KEY_NEXTSONG" mapto="seekFwdManual" flags="l" />
302 ! </device>
303 ! <device name="dreambox ir keyboard">
304 ! <key id="KEY_PAUSE" mapto="pauseService" flags="m" />
305 ! <key id="KEY_PLAY" mapto="playpauseService" flags="m" />
306 ! <key id="KEY_REWIND" mapto="seekBack" flags="b" />
307 ! <key id="KEY_FASTFORWARD" mapto="seekFwd" flags="b" />
308 ! <key id="KEY_REWIND" mapto="seekBackManual" flags="l" />
309 ! <key id="KEY_FASTFORWARD" mapto="seekFwdManual" flags="l" />
310 ! </device>
312 ! <key id="KEY_LEFT" mapto="seekBack" flags="m" />
313 ! <key id="KEY_RIGHT" mapto="seekFwd" flags="m" />
315 ! <key id="KEY_OK" mapto="unPauseService" flags="m" />
317 ! <key id="KEY_1" mapto="seekdef:1" flags="m" />
318 ! <key id="KEY_3" mapto="seekdef:3" flags="m" />
319 ! <key id="KEY_4" mapto="seekdef:4" flags="m" />
320 ! <key id="KEY_6" mapto="seekdef:6" flags="m" />
321 ! <key id="KEY_7" mapto="seekdef:7" flags="m" />
322 ! <key id="KEY_9" mapto="seekdef:9" flags="m" />
323 ! </map>
325 ! <map context="MediaPlayerSeekActions">
326 ! <device name="dreambox remote control (native)">
327 ! <key id="KEY_RED" mapto="seekBack" flags="b" />
328 ! <key id="KEY_BLUE" mapto="seekFwd" flags="b" />
329 ! <key id="KEY_RED" mapto="seekBackManual" flags="l" />
330 ! <key id="KEY_BLUE" mapto="seekFwdManual" flags="l" />
331 ! </device>
332 ! <device name="dreambox advanced remote control (native)">
333 ! <key id="KEY_PREVIOUSSONG" mapto="seekBack" flags="b" />
334 ! <key id="KEY_NEXTSONG" mapto="seekFwd" flags="b" />
335 ! <key id="KEY_PREVIOUSSONG" mapto="seekBackManual" flags="l" />
336 ! <key id="KEY_NEXTSONG" mapto="seekFwdManual" flags="l" />
337 ! </device>
338 ! <device name="dreambox ir keyboard">
339 ! <key id="KEY_REWIND" mapto="seekBack" flags="b" />
340 ! <key id="KEY_FASTFORWARD" mapto="seekFwd" flags="b" />
341 ! <key id="KEY_REWIND" mapto="seekBackManual" flags="l" />
342 ! <key id="KEY_FASTFORWARD" mapto="seekFwdManual" flags="l" />
343 ! </device>
345 ! <key id="KEY_1" mapto="seekdef:1" flags="m" />
346 ! <key id="KEY_3" mapto="seekdef:3" flags="m" />
347 ! <key id="KEY_4" mapto="seekdef:4" flags="m" />
348 ! <key id="KEY_6" mapto="seekdef:6" flags="m" />
349 ! <key id="KEY_7" mapto="seekdef:7" flags="m" />
350 ! <key id="KEY_9" mapto="seekdef:9" flags="m" />
351 ! </map>
353 ! <map context="InfobarTimeshiftActions">
354 ! <device name="dreambox remote control (native)">
355 ! <key id="KEY_YELLOW" mapto="timeshiftStart" flags="b" />
356 ! <key id="KEY_TV" mapto="timeshiftStop" flags="m" />
357 ! </device>
358 ! <device name="dreambox advanced remote control (native)">
359 ! <key id="KEY_PLAY" mapto="timeshiftStart" flags="m" />
360 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftStart" flags="m" />
361 ! <key id="KEY_TV" mapto="timeshiftStop" flags="m" />
362 ! <key id="KEY_STOP" mapto="timeshiftStop" flags="m" />
363 ! </device>
364 ! <device name="dreambox ir keyboard">
365 ! <key id="KEY_YELLOW" mapto="timeshiftStart" flags="m" />
366 ! <key id="KEY_PAUSE" mapto="timeshiftStart" flags="m" />
367 ! <key id="KEY_STOP" mapto="timeshiftStop" flags="m" />
368 ! </device>
369 ! <device name="Xlib">
370 ! <key id="KEY_YELLOW" mapto="timeshiftStart" flags="b" />
371 ! <key id="KEY_TV" mapto="timeshiftStop" flags="m" />
372 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftStart" flags="m" />
373 ! </device>
374 ! </map>
376 ! <map context="InfobarTimeshiftActivateActions">
377 ! <device name="dreambox remote control (native)">
378 ! <key id="KEY_RED" mapto="timeshiftActivateEnd" flags="b" />
379 ! <key id="KEY_YELLOW" mapto="timeshiftActivateEndAndPause" flags="b" />
380 ! </device>
381 ! <device name="dreambox advanced remote control (native)">
382 ! <key id="KEY_PREVIOUSSONG" mapto="timeshiftActivateEnd" flags="m" />
383 ! <key id="KEY_PLAY" mapto="timeshiftActivateEndAndPause" flags="m" />
384 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
385 ! </device>
386 ! <device name="dreambox ir keyboard">
387 ! <key id="KEY_REWIND" mapto="timeshiftActivateEnd" flags="m" />
388 ! <key id="KEY_PAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
389 ! </device>
390 ! <device name="Xlib">
391 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
392 ! </device>
393 ! </map>
395 ! <map context="MovieSelectionActions">
396 ! <key id="KEY_MENU" mapto="contextMenu" flags="m" />
397 ! <key id="KEY_SPACE" mapto="contextMenu" flags="m" />
398 ! <key id="KEY_INFO" mapto="showEventInfo" flags="m" />
399 ! </map>
401 ! <map context="InfobarMovieListActions">
402 ! <key id="KEY_UP" mapto="up" flags="m" />
403 ! <key id="KEY_DOWN" mapto="down" flags="m" />
404 ! <key id="KEY_VIDEO" mapto="movieList" flags="m" />
405 ! </map>
407 ! <map context="MoviePlayerActions">
408 ! <device name="dreambox remote control (native)">
409 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
410 ! </device>
411 ! <device name="dreambox advanced remote control (native)">
412 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
413 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
414 ! </device>
415 ! <device name="dreambox ir keyboard">
416 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
417 ! </device>
418 ! <device name="Xlib">
419 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
420 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
421 ! </device>
422 ! </map>
424 ! <map context="InfobarCueSheetActions">
425 ! <device name="dreambox remote control (native)">
426 ! <key id="KEY_PREVIOUS" mapto="jumpPreviousMark" flags="m" />
427 ! <key id="KEY_NEXT" mapto="jumpNextMark" flags="m" />
428 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
429 ! </device>
430 ! <device name="dreambox advanced remote control (native)">
431 ! <key id="KEY_PREVIOUS" mapto="jumpPreviousMark" flags="m" />
432 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
433 ! <key id="KEY_NEXT" mapto="jumpNextMark" flags="m" />
434 ! </device>
435 ! <device name="dreambox ir keyboard">
436 ! <key id="KEY_PREVIOUSSONG" mapto="jumpPreviousMark" flags="m" />
437 ! <key id="KEY_TAB" mapto="toggleMark" flags="m" />
438 ! <key id="KEY_NEXTSONG" mapto="jumpNextMark" flags="m" />
439 ! </device>
440 ! </map>
442 ! <map context="MediaPlayerCueSheetActions">
443 ! <device name="dreambox remote control (native)">
444 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
445 ! </device>
446 ! <device name="dreambox advanced remote control (native)">
447 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
448 ! <key id="KEY_YELLOW" mapto="toggleMark" flags="b" />
449 ! </device>
450 ! <device name="dreambox ir keyboard">
451 ! <key id="KEY_TAB" mapto="toggleMark" flags="m" />
452 ! </device>
453 ! </map>
455 ! <map context="VirtualKeyboardActions">
456 ! <key id="KEY_TEXT" mapto="showVirtualKeyboard" flags="m" />
457 ! </map>
459 ! <map context="InfobarTeletextActions">
460 ! <key id="KEY_TEXT" mapto="startTeletext" flags="m" />
461 ! </map>
463 ! <map context="InfobarRdsActions">
464 ! <key id="KEY_TEXT" mapto="startRassInteractive" flags="m" />
465 ! </map>
467 ! <map context="RassInteractiveActions">
468 ! <key id="KEY_LEFT" mapto="prevSubPage" flags="mr" />
469 ! <key id="KEY_RIGHT" mapto="nextSubPage" flags="mr" />
470 ! <key id="KEY_UP" mapto="prevPage" flags="mr" />
471 ! <key id="KEY_DOWN" mapto="nextPage" flags="mr" />
472 ! <key id="KEY_EXIT" mapto="exit" flags="m" />
473 ! <key id="KEY_ESC" mapto="exit" flags="m" />
474 ! </map>
476 ! <map context="ChannelSelectBaseActions">
477 ! <key id="KEY_RED" mapto="showAllServices" flags="m" />
478 ! <key id="KEY_GREEN" mapto="showSatellites" flags="m" />
479 ! <key id="KEY_YELLOW" mapto="showProviders" flags="m" />
480 ! <key id="KEY_BLUE" mapto="showFavourites" flags="m" />
481 ! <key id="KEY_CHANNELUP" mapto="nextBouquet" flags="m" />
482 ! <key id="KEY_CHANNELDOWN" mapto="prevBouquet" flags="m" />
483 ! <key id="KEY_PREVIOUS" mapto="prevMarker" flags="m" />
484 ! <key id="KEY_NEXT" mapto="nextMarker" flags="m" />
485 ! <key id="KEY_BACK" mapto="prevMarker" flags="m" />
486 ! <key id="KEY_FORWARD" mapto="nextMarker" flags="m" />
487 ! </map>
489 ! <map context="ChannelSelectEPGActions">
490 ! <key id="KEY_INFO" mapto="showEPGList" flags="m" />
491 ! </map>
493 ! <map context="ChannelSelectEditActions">
494 ! <key id="KEY_MENU" mapto="contextMenu" flags="m" />
495 ! <key id="KEY_SPACE" mapto="contextMenu" flags="m" />
496 ! </map>
498 ! <map context="TvRadioActions">
499 ! <key id="KEY_TV" mapto="keyTV" flags="m" />
500 ! <key id="KEY_RADIO" mapto="keyRadio" flags="m" />
501 ! </map>
503 ! <map context="TimerEditActions">
504 ! <key id="KEY_INFO" mapto="log" flags="m" />
505 ! </map>
507 ! <map context="EPGSelectActions">
508 ! <key id="KEY_GREEN" mapto="timerAdd" flags="m" />
509 ! <key id="KEY_YELLOW" mapto="yellow" flags="mr" />
510 ! <key id="KEY_BLUE" mapto="blue" flags="mr" />
511 ! <key id="KEY_RED" mapto="red" flags="m" />
512 ! <key id="KEY_INFO" mapto="info" flags="m" />
513 ! <key id="KEY_MENU" mapto="input_date_time" flags="m" />
514 ! <key id="KEY_CHANNELUP" mapto="nextBouquet" flags="m" />
515 ! <key id="KEY_CHANNELDOWN" mapto="prevBouquet" flags="m" />
516 ! <key id="KEY_NEXT" mapto="nextService" flags="m" />
517 ! <key id="KEY_PREVIOUS" mapto="prevService" flags="m" />
518 ! </map>
520 ! <map context="EventViewActions">
521 ! <key id="KEY_UP" mapto="pageUp" flags="mr" />
522 ! <key id="KEY_DOWN" mapto="pageDown" flags="mr" />
523 ! <key id="KEY_LEFT" mapto="prevEvent" flags="mr" />
524 ! <key id="KEY_RIGHT" mapto="nextEvent" flags="mr" />
525 ! <key id="KEY_RED" mapto="openSimilarList" flags="m" />
526 ! <key id="KEY_GREEN" mapto="timerAdd" flags="m" />
527 ! <key id="KEY_INFO" mapto="cancel" flags="m" />
528 ! </map>
530 ! <map context="EventViewEPGActions">
531 ! <key id="KEY_YELLOW" mapto="openSingleServiceEPG" flags="m" />
532 ! <key id="KEY_BLUE" mapto="openMultiServiceEPG" flags="m" />
533 ! </map>
535 ! <map context="OkCancelActions">
536 ! <key id="\x0a" mapto="ok" flags="m" />
537 ! <key id="\x1b" mapto="cancel" flags="m" />
539 ! <!-- use this on rcu, ok? -->
540 ! <key id="KEY_OK" mapto="ok" flags="m" />
541 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
543 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
544 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
545 ! </map>
547 ! <map context="DirectionActions">
548 ! <key id="KEY_UP" mapto="up" flags="m" />
549 ! <key id="KEY_DOWN" mapto="down" flags="m" />
550 ! <key id="KEY_LEFT" mapto="left" flags="m" />
551 ! <key id="KEY_RIGHT" mapto="right" flags="m" />
553 ! <key id="KEY_UP" mapto="upRepeated" flags="r" />
554 ! <key id="KEY_DOWN" mapto="downRepeated" flags="r" />
555 ! <key id="KEY_LEFT" mapto="leftRepeated" flags="r" />
556 ! <key id="KEY_RIGHT" mapto="rightRepeated" flags="r" />
558 ! <key id="KEY_LEFT" mapto="leftUp" flags="b" />
559 ! <key id="KEY_RIGHT" mapto="rightUp" flags="b" />
560 ! <key id="KEY_UP" mapto="upUp" flags="b" />
561 ! <key id="KEY_DOWN" mapto="downUp" flags="b" />
562 ! </map>
564 ! <map context="ColorActions">
565 ! <key id="KEY_RED" mapto="red" flags="m" />
566 ! <key id="KEY_GREEN" mapto="green" flags="m" />
567 ! <key id="KEY_YELLOW" mapto="yellow" flags="m" />
568 ! <key id="KEY_BLUE" mapto="blue" flags="m" />
569 ! </map>
571 ! <map context="MsgBoxActions">
572 ! <key id="KEY_GREEN" mapto="alwaysOK" flags="m" />
573 ! <key id="KEY_OK" mapto="ok" flags="m" />
574 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
575 ! <key id="KEY_RED" mapto="cancel" flags="m" />
576 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
577 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
578 ! </map>
580 ! <map context="WindowActions">
582 ! </map>
584 ! <map context="HelpActions">
585 ! <key id="KEY_HELP" mapto="displayHelp" flags="m" />
586 ! </map>
588 ! <map context="ShortcutActions">
589 ! <key id="KEY_F1" mapto="red" flags="mr" />
590 ! <key id="KEY_F2" mapto="yellow" flags="mr" />
591 ! <key id="KEY_F3" mapto="green" flags="mr" />
592 ! <key id="KEY_F4" mapto="blue" flags="mr" />
594 ! <key id="KEY_RED" mapto="red" flags="mr" />
595 ! <key id="KEY_YELLOW" mapto="yellow" flags="mr" />
596 ! <key id="KEY_GREEN" mapto="green" flags="mr" />
597 ! <key id="KEY_BLUE" mapto="blue" flags="mr" />
598 ! </map>
599 ! <map context="StandbyActions">
600 ! <key id="KEY_POWER" mapto="power" flags="m" />
601 ! </map>
603 ! <map context="SleepTimerEditorActions">
604 ! <key id="KEY_OK" mapto="select" flags="m" />
605 ! <key id="KEY_ENTER" mapto="select" flags="m" />
606 ! <key id="KEY_EXIT" mapto="exit" flags="m" />
607 ! <key id="KEY_ESC" mapto="exit" flags="m" />
608 ! <key id="KEY_1" mapto="1" flags="m" />
609 ! <key id="KEY_2" mapto="2" flags="m" />
610 ! <key id="KEY_3" mapto="3" flags="m" />
611 ! <key id="KEY_4" mapto="4" flags="m" />
612 ! <key id="KEY_5" mapto="5" flags="m" />
613 ! <key id="KEY_6" mapto="6" flags="m" />
614 ! <key id="KEY_7" mapto="7" flags="m" />
615 ! <key id="KEY_8" mapto="8" flags="m" />
616 ! <key id="KEY_9" mapto="9" flags="m" />
617 ! <key id="KEY_0" mapto="0" flags="m" />
618 ! <key id="KEY_LEFT" mapto="selectLeft" flags="mr" />
619 ! <key id="KEY_RIGHT" mapto="selectRight" flags="mr" />
620 ! <key id="KEY_RED" mapto="disableTimer" flags="mr" />
621 ! <key id="KEY_YELLOW" mapto="toggleAsk" flags="mr" />
622 ! <key id="KEY_GREEN" mapto="toggleAction" flags="mr" />
623 ! <key id="KEY_BLUE" mapto="useServiceTime" flags="mr" />
624 ! </map>
626 ! <map context="CiSelectionActions">
627 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
628 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
629 ! </map>
631 ! <map context="PiPSetupActions">
632 ! <key id="KEY_UP" mapto="up" flags="mr" />
633 ! <key id="KEY_DOWN" mapto="down" flags="mr" />
634 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
635 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
636 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
637 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
638 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
639 ! <key id="KEY_OK" mapto="ok" flags="m" />
640 ! <key id="KEY_CHANNELUP" mapto="size+" flags="mr" />
641 ! <key id="KEY_CHANNELDOWN" mapto="size-" flags="mr" />
642 ! </map>
644 ! <map context="MediaPlayerActions">
645 ! <device name="dreambox remote control (native)">
646 ! <key id="KEY_YELLOW" mapto="pause" flags="m" />
647 ! <key id="KEY_GREEN" mapto="play" flags="m" />
648 ! <key id="KEY_TV" mapto="stop" flags="b" />
649 ! <key id="KEY_TV" mapto="shift_stop" flags="l" />
650 ! <key id="KEY_RADIO" mapto="shift_record" flags="l" />
651 ! <key id="KEY_PREVIOUS" mapto="previous" flags="m" />
652 ! <key id="KEY_NEXT" mapto="next" flags="m" />
653 ! </device>
654 ! <device name="dreambox advanced remote control (native)">
655 ! <key id="KEY_PLAYPAUSE" mapto="pause" flags="m" />
656 ! <key id="KEY_PLAY" mapto="pause" flags="m" />
657 ! <key id="KEY_STOP" mapto="stop" flags="b" />
658 ! <key id="KEY_STOP" mapto="shift_stop" flags="l" />
659 ! <key id="KEY_RECORD" mapto="shift_record" flags="l" />
660 ! <key id="KEY_PREVIOUS" mapto="previous" flags="m" />
661 ! <key id="KEY_NEXT" mapto="next" flags="m" />
662 ! <key id="KEY_RED" mapto="previous" flags="m" />
663 ! <key id="KEY_BLUE" mapto="next" flags="m" />
664 ! </device>
665 ! <device name="dreambox ir keyboard">
666 ! <key id="KEY_PAUSE" mapto="pause" flags="m" />
667 ! <key id="KEY_PLAY" mapto="play" flags="m" />
668 ! <key id="KEY_STOP" mapto="stop" flags="b" />
669 ! <key id="KEY_STOP" mapto="shift_stop" flags="l" />
670 ! <key id="KEY_RECORD" mapto="shift_record" flags="l" />
671 ! <key id="KEY_PREVIOUSSONG" mapto="previous" flags="m" />
672 ! <key id="KEY_NEXTSONG" mapto="next" flags="m" />
673 ! </device>
675 ! <key id="KEY_MENU" mapto="menu" flags="m" />
676 ! <key id="KEY_SPACE" mapto="menu" flags="m" />
678 ! <key id="KEY_2" mapto="skipListbegin" flags="m" />
679 ! <key id="KEY_8" mapto="skipListend" flags="m" />
680 ! <key id="KEY_CHANNELUP" mapto="nextBouquet" flags="m" />
681 ! <key id="KEY_CHANNELDOWN" mapto="prevBouquet" flags="m" />
682 ! <key id="KEY_VIDEO" mapto="delete" flags="m" />
683 ! <key id="KEY_TEXT" mapto="subtitles" flags="m" />
684 ! </map>
685 ! </keymap>
686 --- 1,687 ----
687 ! <keymap>
688 ! <map context="ListboxActions">
689 ! <device name="keyboard">
690 ! <key id="a" mapto="up" flags="mr" />
691 ! <key id="b" mapto="down" flags="mr" />
692 ! </device>
693 ! <key id="KEY_UP" mapto="moveUp" flags="mr" />
694 ! <key id="KEY_DOWN" mapto="moveDown" flags="mr" />
695 ! <key id="KEY_HOME" mapto="moveTop" flags="mr" />
696 ! <key id="KEY_END" mapto="moveEnd" flags="mr" />
697 ! <key id="KEY_PAGEUP" mapto="pageUp" flags="mr" />
698 ! <key id="KEY_PAGEDOWN" mapto="pageDown" flags="mr" />
699 ! <key id="KEY_LEFT" mapto="pageUp" flags="mr" />
700 ! <key id="KEY_RIGHT" mapto="pageDown" flags="mr" />
701 ! <key id="1" mapto="moveUp" flags="mr" />
702 ! <key id="2" mapto="moveDown" flags="mr" />
703 ! </map>
705 ! <map context="KeyboardInputActions">
706 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
707 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
708 ! <key id="KEY_HOME" mapto="home" flags="mr" />
709 ! <key id="KEY_END" mapto="end" flags="mr" />
710 ! <key id="KEY_BACK" mapto="home" flags="mr" />
711 ! <key id="KEY_FORWARD" mapto="end" flags="mr" />
712 ! <key id="KEY_DELETE" mapto="deleteForward" flags="mr" />
713 ! <key id="KEY_BACKSPACE" mapto="deleteBackward" flags="mr" />
714 ! <key id="KEY_TAB" mapto="tab" flags="mr" />
715 ! <key id="KEY_INSERT" mapto="toggleOverwrite" flags="m" />
716 ! </map>
718 ! <map context="SetupActions">
719 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
720 ! <key id="KEY_OK" mapto="ok" flags="m" />
721 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
722 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
723 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
724 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
725 ! <key id="KEY_RED" mapto="cancel" flags="m" />
726 ! <key id="KEY_GREEN" mapto="save" flags="m" />
727 ! <device name="dreambox remote control (native)">
728 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
729 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
730 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
731 ! </device>
732 ! <device name="dreambox advanced remote control (native)">
733 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
734 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
735 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
736 ! </device>
737 ! <key id="KEY_1" mapto="1" flags="m" />
738 ! <key id="KEY_2" mapto="2" flags="m" />
739 ! <key id="KEY_3" mapto="3" flags="m" />
740 ! <key id="KEY_4" mapto="4" flags="m" />
741 ! <key id="KEY_5" mapto="5" flags="m" />
742 ! <key id="KEY_6" mapto="6" flags="m" />
743 ! <key id="KEY_7" mapto="7" flags="m" />
744 ! <key id="KEY_8" mapto="8" flags="m" />
745 ! <key id="KEY_9" mapto="9" flags="m" />
746 ! <key id="KEY_0" mapto="0" flags="m" />
747 ! </map>
749 ! <map context="InputActions">
750 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
751 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
752 ! <key id="KEY_1" mapto="1" flags="m" />
753 ! <key id="KEY_2" mapto="2" flags="m" />
754 ! <key id="KEY_3" mapto="3" flags="m" />
755 ! <key id="KEY_4" mapto="4" flags="m" />
756 ! <key id="KEY_5" mapto="5" flags="m" />
757 ! <key id="KEY_6" mapto="6" flags="m" />
758 ! <key id="KEY_7" mapto="7" flags="m" />
759 ! <key id="KEY_8" mapto="8" flags="m" />
760 ! <key id="KEY_9" mapto="9" flags="m" />
761 ! <key id="KEY_0" mapto="0" flags="m" />
762 ! </map>
764 ! <map context="InfobarEPGActions">
765 ! <key id="KEY_INFO" mapto="showEventInfo" flags="b" />
766 ! <key id="KEY_INFO" mapto="showEventInfoPlugin" flags="l" />
767 ! </map>
769 ! <map context="InfobarInstantRecord">
770 ! <device name="dreambox advanced remote control (native)">
771 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
772 ! <!-- this breaks timeshift end!!! key id="KEY_STOP" mapto="instantRecord" flags="m" /-->
773 ! </device>
774 ! <device name="dreambox ir keyboard">
775 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
776 ! </device>
777 ! <device name="dreambox remote control (native)">
778 ! <key id="KEY_RED" mapto="instantRecord" flags="b" />
779 ! </device>
780 ! <device name="Xlib">
781 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
782 ! </device>
783 ! </map>
785 ! <map context="InfobarExtensions">
786 ! <key id="KEY_BLUE" mapto="extensions" flags="b" />
787 ! </map>
789 ! <map context="SatlistShortcutAction">
790 ! <key id="KEY_BLUE" mapto="nothingconnected" flags="b" />
791 ! </map>
793 ! <map context="InfobarChannelSelection">
794 ! <key id="KEY_LEFT" mapto="zapUp" flags="mr" />
795 ! <key id="KEY_RIGHT" mapto="zapDown" flags="mr" />
796 ! <key id="KEY_UP" mapto="switchChannelUp" flags="mr" />
797 ! <key id="KEY_DOWN" mapto="switchChannelDown" flags="mr" />
798 ! <key id="KEY_PREVIOUS" mapto="historyBack" flags="mr" />
799 ! <key id="KEY_NEXT" mapto="historyNext" flags="mr" />
800 ! <key id="KEY_BACK" mapto="historyBack" flags="mr" />
801 ! <key id="KEY_FORWARD" mapto="historyNext" flags="mr" />
802 ! <key id="KEY_CHANNELUP" mapto="openServiceList" flags="m" />
803 ! <key id="KEY_CHANNELDOWN" mapto="openServiceList" flags="m" />
804 ! <key id="BTN_0" mapto="zapUp" flags="mr" />
805 ! <key id="BTN_1" mapto="zapDown" flags="mr" />
806 ! </map>
808 ! <map context="MinuteInputActions">
809 ! <key id="KEY_UP" mapto="up" flags="mr" />
810 ! <key id="KEY_DOWN" mapto="down" flags="mr" />
811 ! <key id="KEY_OK" mapto="ok" flags="m" />
812 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
813 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
814 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
815 ! </map>
817 ! <map context="InputAsciiActions">
818 ! <device name="Console">
819 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
820 ! </device>
821 ! <device name="SDL">
822 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
823 ! </device>
824 ! </map>
826 ! <map context="InputBoxActions">
827 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
828 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
829 ! <key id="KEY_OK" mapto="ok" flags="m" />
830 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
831 ! <key id="KEY_EXIT" mapto="back" flags="m" />
832 ! <key id="KEY_ESC" mapto="back" flags="m" />
833 ! <device name="dreambox remote control (native)">
834 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
835 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
836 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
837 ! </device>
838 ! <device name="dreambox advanced remote control (native)">
839 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
840 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
841 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
842 ! </device>
843 ! <key id="KEY_1" mapto="1" flags="m" />
844 ! <key id="KEY_2" mapto="2" flags="m" />
845 ! <key id="KEY_3" mapto="3" flags="m" />
846 ! <key id="KEY_4" mapto="4" flags="m" />
847 ! <key id="KEY_5" mapto="5" flags="m" />
848 ! <key id="KEY_6" mapto="6" flags="m" />
849 ! <key id="KEY_7" mapto="7" flags="m" />
850 ! <key id="KEY_8" mapto="8" flags="m" />
851 ! <key id="KEY_9" mapto="9" flags="m" />
852 ! <key id="KEY_0" mapto="0" flags="m" />
853 ! </map>
855 ! <map context="WizardActions">
856 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
857 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
858 ! <key id="KEY_UP" mapto="up" flags="mr" />
859 ! <key id="KEY_DOWN" mapto="down" flags="mr" />
860 ! <key id="KEY_OK" mapto="ok" flags="m" />
861 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
862 ! <key id="KEY_EXIT" mapto="back" flags="m" />
863 ! <key id="KEY_ESC" mapto="back" flags="m" />
864 ! </map>
866 ! <map context="InfobarMenuActions">
867 ! <key id="KEY_MENU" mapto="mainMenu" flags="mr" />
868 ! <key id="KEY_SPACE" mapto="mainMenu" flags="mr" />
869 ! </map>
871 ! <map context="MenuActions">
872 ! <key id="KEY_MENU" mapto="menu" flags="mr" />
873 ! <key id="KEY_SPACE" mapto="menu" flags="mr" />
874 ! </map>
876 ! <map context="InfobarShowHideActions">
877 ! <key id="KEY_OK" mapto="toggleShow" flags="m" />
878 ! <key id="KEY_ENTER" mapto="toggleShow" flags="m" />
879 ! <key id="KEY_EXIT" mapto="hide" flags="m" />
880 ! <key id="KEY_ESC" mapto="hide" flags="m" />
881 ! </map>
883 ! <map context="InfobarActions">
884 ! <key id="KEY_VIDEO" mapto="showMovies" flags="m" />
885 ! <key id="KEY_RADIO" mapto="showRadio" flags="m" />
886 ! <key id="KEY_TV" mapto="showTv" flags="m" />
887 ! </map>
889 ! <map context="InfobarAudioSelectionActions">
890 ! <device name="dreambox remote control (native)">
891 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
892 ! </device>
893 ! <device name="dreambox ir keyboard">
894 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
895 ! </device>
896 ! <device name="dreambox advanced remote control (native)">
897 ! <key id="KEY_YELLOW" mapto="audioSelection" flags="b" />
898 ! </device>
899 ! <device name="Xlib">
900 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
901 ! </device>
902 ! </map>
904 ! <map context="InfobarSubserviceSelectionActions">
905 ! <key id="KEY_GREEN" mapto="subserviceSelection" flags="b" />
906 ! </map>
908 ! <map context="InfobarSubserviceQuickzapActions">
909 ! <key id="KEY_PREVIOUS" mapto="prevSubservice" flags="m" />
910 ! <key id="KEY_NEXT" mapto="nextSubservice" flags="m" />
911 ! <key id="KEY_BACK" mapto="prevSubservice" flags="m" />
912 ! <key id="KEY_FORWARD" mapto="nextSubservice" flags="m" />
913 ! <key id="KEY_EXIT" mapto="exit" flags="m" />
914 ! <key id="KEY_ESC" mapto="exit" flags="m" />
915 ! <device name="dreambox remote control (native)">
916 ! <key id="KEY_TV" mapto="exit" flags="m" />
917 ! </device>
918 ! <device name="dreambox advanced remote control (native)">
919 ! <key id="KEY_TV" mapto="exit" flags="m" />
920 ! </device>
921 ! </map>
923 ! <map context="GlobalActions">
924 ! <key id="KEY_VOLUMEUP" mapto="volumeUp" flags="mr" />
925 ! <key id="KEY_VOLUMEDOWN" mapto="volumeDown" flags="mr" />
926 ! <key id="KEY_MUTE" mapto="volumeMute" flags="mr" />
927 ! <key id="KEY_POWER" mapto="power_long" flags="l" />
928 ! <key id="KEY_POWER" mapto="power_down" flags="m" />
929 ! <key id="KEY_POWER" mapto="power_up" flags="b" />
930 ! <device name="dreambox front panel">
931 ! <key id="KEY_POWER" mapto="deepstandby" flags="l" />
932 ! </device>
933 ! </map>
935 ! <map context="PowerKeyActions">
936 ! <key id="KEY_POWER" mapto="powerdown" flags="m" />
937 ! <key id="KEY_POWER" mapto="powerup" flags="b" />
938 ! </map>
940 ! <map context="NumberActions">
941 ! <key id="KEY_1" mapto="1" flags="m" />
942 ! <key id="KEY_2" mapto="2" flags="m" />
943 ! <key id="KEY_3" mapto="3" flags="m" />
944 ! <key id="KEY_4" mapto="4" flags="m" />
945 ! <key id="KEY_5" mapto="5" flags="m" />
946 ! <key id="KEY_6" mapto="6" flags="m" />
947 ! <key id="KEY_7" mapto="7" flags="m" />
948 ! <key id="KEY_8" mapto="8" flags="m" />
949 ! <key id="KEY_9" mapto="9" flags="m" />
950 ! <key id="KEY_0" mapto="0" flags="m" />
951 ! </map>
953 ! <map context="TextEntryActions">
954 ! <device name="dreambox remote control (native)">
955 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
956 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
957 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
958 ! </device>
959 ! <device name="dreambox advanced remote control (native)">
960 ! <key id="KEY_MUTE" mapto="deleteForward" flags="mr" />
961 ! <key id="KEY_NEXT" mapto="deleteForward" flags="mr" />
962 ! <key id="KEY_PREVIOUS" mapto="deleteBackward" flags="mr" />
963 ! </device>
964 ! </map>
966 ! <map context="InfobarSeekActions">
967 ! <device name="dreambox remote control (native)">
968 ! <key id="KEY_YELLOW" mapto="pauseService" flags="b" />
969 ! <key id="KEY_GREEN" mapto="unPauseService" flags="b" />
970 ! <key id="KEY_RED" mapto="seekBack" flags="b" />
971 ! <key id="KEY_BLUE" mapto="seekFwd" flags="b" />
972 ! <key id="KEY_RED" mapto="seekBackManual" flags="l" />
973 ! <key id="KEY_BLUE" mapto="seekFwdManual" flags="l" />
974 ! </device>
975 ! <device name="dreambox advanced remote control (native)">
976 ! <key id="KEY_PLAY" mapto="playpauseService" flags="m" />
977 ! <key id="KEY_PLAYPAUSE" mapto="playpauseService" flags="m" />
978 ! <key id="KEY_PREVIOUSSONG" mapto="seekBack" flags="b" />
979 ! <key id="KEY_NEXTSONG" mapto="seekFwd" flags="b" />
980 ! <key id="KEY_PREVIOUSSONG" mapto="seekBackManual" flags="l" />
981 ! <key id="KEY_NEXTSONG" mapto="seekFwdManual" flags="l" />
982 ! </device>
983 ! <device name="dreambox ir keyboard">
984 ! <key id="KEY_PAUSE" mapto="pauseService" flags="m" />
985 ! <key id="KEY_PLAY" mapto="playpauseService" flags="m" />
986 ! <key id="KEY_REWIND" mapto="seekBack" flags="b" />
987 ! <key id="KEY_FASTFORWARD" mapto="seekFwd" flags="b" />
988 ! <key id="KEY_REWIND" mapto="seekBackManual" flags="l" />
989 ! <key id="KEY_FASTFORWARD" mapto="seekFwdManual" flags="l" />
990 ! </device>
991 ! <device name="Xlib">
992 ! <key id="KEY_PAUSE" mapto="pauseService" flags="m" />
993 ! <key id="KEY_PLAYPAUSE" mapto="playpauseService" flags="m" />
994 ! <key id="KEY_REWIND" mapto="seekBack" flags="b" />
995 ! <key id="KEY_FASTFORWARD" mapto="seekFwd" flags="b" />
996 ! <key id="KEY_REWIND" mapto="seekBackManual" flags="l" />
997 ! <key id="KEY_FASTFORWARD" mapto="seekFwdManual" flags="l" />
998 ! </device>
999 ! <key id="KEY_LEFT" mapto="seekBack" flags="m" />
1000 ! <key id="KEY_RIGHT" mapto="seekFwd" flags="m" />
1001 ! <key id="KEY_OK" mapto="unPauseService" flags="m" />
1002 ! <key id="KEY_1" mapto="seekdef:1" flags="m" />
1003 ! <key id="KEY_3" mapto="seekdef:3" flags="m" />
1004 ! <key id="KEY_4" mapto="seekdef:4" flags="m" />
1005 ! <key id="KEY_6" mapto="seekdef:6" flags="m" />
1006 ! <key id="KEY_7" mapto="seekdef:7" flags="m" />
1007 ! <key id="KEY_9" mapto="seekdef:9" flags="m" />
1008 ! </map>
1010 ! <map context="MediaPlayerSeekActions">
1011 ! <device name="dreambox remote control (native)">
1012 ! <key id="KEY_RED" mapto="seekBack" flags="b" />
1013 ! <key id="KEY_BLUE" mapto="seekFwd" flags="b" />
1014 ! <key id="KEY_RED" mapto="seekBackManual" flags="l" />
1015 ! <key id="KEY_BLUE" mapto="seekFwdManual" flags="l" />
1016 ! </device>
1017 ! <device name="dreambox advanced remote control (native)">
1018 ! <key id="KEY_PREVIOUSSONG" mapto="seekBack" flags="b" />
1019 ! <key id="KEY_NEXTSONG" mapto="seekFwd" flags="b" />
1020 ! <key id="KEY_PREVIOUSSONG" mapto="seekBackManual" flags="l" />
1021 ! <key id="KEY_NEXTSONG" mapto="seekFwdManual" flags="l" />
1022 ! </device>
1023 ! <device name="dreambox ir keyboard">
1024 ! <key id="KEY_REWIND" mapto="seekBack" flags="b" />
1025 ! <key id="KEY_FASTFORWARD" mapto="seekFwd" flags="b" />
1026 ! <key id="KEY_REWIND" mapto="seekBackManual" flags="l" />
1027 ! <key id="KEY_FASTFORWARD" mapto="seekFwdManual" flags="l" />
1028 ! </device>
1029 ! <key id="KEY_1" mapto="seekdef:1" flags="m" />
1030 ! <key id="KEY_3" mapto="seekdef:3" flags="m" />
1031 ! <key id="KEY_4" mapto="seekdef:4" flags="m" />
1032 ! <key id="KEY_6" mapto="seekdef:6" flags="m" />
1033 ! <key id="KEY_7" mapto="seekdef:7" flags="m" />
1034 ! <key id="KEY_8" mapto="seekFwd" flags="b" />
1035 ! <key id="KEY_0" mapto="seekBack" flags="b" />
1036 ! <key id="KEY_9" mapto="seekdef:9" flags="m" />
1037 ! </map>
1039 ! <map context="InfobarTimeshiftActions">
1040 ! <device name="dreambox remote control (native)">
1041 ! <key id="KEY_YELLOW" mapto="timeshiftStart" flags="b" />
1042 ! <key id="KEY_TV" mapto="timeshiftStop" flags="m" />
1043 ! </device>
1044 ! <device name="dreambox advanced remote control (native)">
1045 ! <key id="KEY_PLAY" mapto="timeshiftStart" flags="m" />
1046 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftStart" flags="m" />
1047 ! <key id="KEY_TV" mapto="timeshiftStop" flags="m" />
1048 ! <key id="KEY_STOP" mapto="timeshiftStop" flags="m" />
1049 ! </device>
1050 ! <device name="dreambox ir keyboard">
1051 ! <key id="KEY_YELLOW" mapto="timeshiftStart" flags="m" />
1052 ! <key id="KEY_PAUSE" mapto="timeshiftStart" flags="m" />
1053 ! <key id="KEY_STOP" mapto="timeshiftStop" flags="m" />
1054 ! </device>
1055 ! <device name="Xlib">
1056 ! <key id="KEY_YELLOW" mapto="timeshiftStart" flags="b" />
1057 ! <key id="KEY_TV" mapto="timeshiftStop" flags="m" />
1058 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftStart" flags="m" />
1059 ! </device>
1060 ! </map>
1062 ! <map context="InfobarTimeshiftActivateActions">
1063 ! <device name="dreambox remote control (native)">
1064 ! <key id="KEY_RED" mapto="timeshiftActivateEnd" flags="b" />
1065 ! <key id="KEY_YELLOW" mapto="timeshiftActivateEndAndPause" flags="b" />
1066 ! </device>
1067 ! <device name="dreambox advanced remote control (native)">
1068 ! <key id="KEY_PREVIOUSSONG" mapto="timeshiftActivateEnd" flags="m" />
1069 ! <key id="KEY_PLAY" mapto="timeshiftActivateEndAndPause" flags="m" />
1070 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
1071 ! </device>
1072 ! <device name="dreambox ir keyboard">
1073 ! <key id="KEY_REWIND" mapto="timeshiftActivateEnd" flags="m" />
1074 ! <key id="KEY_PAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
1075 ! </device>
1076 ! <device name="Xlib">
1077 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
1078 ! </device>
1079 ! </map>
1081 ! <map context="MovieSelectionActions">
1082 ! <key id="KEY_MENU" mapto="contextMenu" flags="m" />
1083 ! <key id="KEY_SPACE" mapto="contextMenu" flags="m" />
1084 ! <key id="KEY_INFO" mapto="showEventInfo" flags="m" />
1085 ! </map>
1087 ! <map context="InfobarMovieListActions">
1088 ! <key id="KEY_UP" mapto="up" flags="m" />
1089 ! <key id="KEY_DOWN" mapto="down" flags="m" />
1090 ! <key id="KEY_VIDEO" mapto="movieList" flags="m" />
1091 ! </map>
1093 ! <map context="MoviePlayerActions">
1094 ! <device name="dreambox remote control (native)">
1095 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
1096 ! </device>
1097 ! <device name="dreambox advanced remote control (native)">
1098 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
1099 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
1100 ! </device>
1101 ! <device name="dreambox ir keyboard">
1102 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
1103 ! </device>
1104 ! <device name="Xlib">
1105 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
1106 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
1107 ! </device>
1108 ! </map>
1110 ! <map context="InfobarCueSheetActions">
1111 ! <device name="dreambox remote control (native)">
1112 ! <key id="KEY_PREVIOUS" mapto="jumpPreviousMark" flags="m" />
1113 ! <key id="KEY_NEXT" mapto="jumpNextMark" flags="m" />
1114 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
1115 ! </device>
1116 ! <device name="dreambox advanced remote control (native)">
1117 ! <key id="KEY_PREVIOUS" mapto="jumpPreviousMark" flags="m" />
1118 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
1119 ! <key id="KEY_NEXT" mapto="jumpNextMark" flags="m" />
1120 ! </device>
1121 ! <device name="dreambox ir keyboard">
1122 ! <key id="KEY_PREVIOUSSONG" mapto="jumpPreviousMark" flags="m" />
1123 ! <key id="KEY_TAB" mapto="toggleMark" flags="m" />
1124 ! <key id="KEY_NEXTSONG" mapto="jumpNextMark" flags="m" />
1125 ! </device>
1126 ! </map>
1128 ! <map context="MediaPlayerCueSheetActions">
1129 ! <device name="dreambox remote control (native)">
1130 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
1131 ! </device>
1132 ! <device name="dreambox advanced remote control (native)">
1133 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
1134 ! <key id="KEY_YELLOW" mapto="toggleMark" flags="b" />
1135 ! </device>
1136 ! <device name="dreambox ir keyboard">
1137 ! <key id="KEY_TAB" mapto="toggleMark" flags="m" />
1138 ! </device>
1139 ! </map>
1141 ! <map context="VirtualKeyboardActions">
1142 ! <key id="KEY_TEXT" mapto="showVirtualKeyboard" flags="m" />
1143 ! </map>
1145 ! <map context="InfobarTeletextActions">
1146 ! <key id="KEY_TEXT" mapto="startTeletext" flags="m" />
1147 ! </map>
1149 ! <map context="InfobarRdsActions">
1150 ! <key id="KEY_TEXT" mapto="startRassInteractive" flags="m" />
1151 ! </map>
1153 ! <map context="RassInteractiveActions">
1154 ! <key id="KEY_LEFT" mapto="prevSubPage" flags="mr" />
1155 ! <key id="KEY_RIGHT" mapto="nextSubPage" flags="mr" />
1156 ! <key id="KEY_UP" mapto="prevPage" flags="mr" />
1157 ! <key id="KEY_DOWN" mapto="nextPage" flags="mr" />
1158 ! <key id="KEY_EXIT" mapto="exit" flags="m" />
1159 ! <key id="KEY_ESC" mapto="exit" flags="m" />
1160 ! </map>
1162 ! <map context="ChannelSelectBaseActions">
1163 ! <key id="KEY_RED" mapto="showAllServices" flags="m" />
1164 ! <key id="KEY_GREEN" mapto="showSatellites" flags="m" />
1165 ! <key id="KEY_YELLOW" mapto="showProviders" flags="m" />
1166 ! <key id="KEY_BLUE" mapto="showFavourites" flags="m" />
1167 ! <key id="KEY_CHANNELUP" mapto="nextBouquet" flags="m" />
1168 ! <key id="KEY_CHANNELDOWN" mapto="prevBouquet" flags="m" />
1169 ! <key id="KEY_PREVIOUS" mapto="prevMarker" flags="m" />
1170 ! <key id="KEY_NEXT" mapto="nextMarker" flags="m" />
1171 ! <key id="KEY_BACK" mapto="prevMarker" flags="m" />
1172 ! <key id="KEY_FORWARD" mapto="nextMarker" flags="m" />
1173 ! </map>
1175 ! <map context="ChannelSelectEPGActions">
1176 ! <key id="KEY_INFO" mapto="showEPGList" flags="m" />
1177 ! <key id="KEY_EPG" mapto="showEPGList" flags="m" />
1178 ! </map>
1180 ! <map context="ChannelSelectEditActions">
1181 ! <key id="KEY_MENU" mapto="contextMenu" flags="m" />
1182 ! <key id="KEY_SPACE" mapto="contextMenu" flags="m" />
1183 ! </map>
1185 ! <map context="TvRadioActions">
1186 ! <key id="KEY_TV" mapto="keyTV" flags="m" />
1187 ! <key id="KEY_RADIO" mapto="keyRadio" flags="m" />
1188 ! </map>
1190 ! <map context="TimerEditActions">
1191 ! <key id="KEY_INFO" mapto="log" flags="m" />
1192 ! </map>
1194 ! <map context="EPGSelectActions">
1195 ! <key id="KEY_GREEN" mapto="timerAdd" flags="m" />
1196 ! <key id="KEY_YELLOW" mapto="yellow" flags="mr" />
1197 ! <key id="KEY_BLUE" mapto="blue" flags="mr" />
1198 ! <key id="KEY_RED" mapto="red" flags="m" />
1199 ! <key id="KEY_INFO" mapto="info" flags="m" />
1200 ! <key id="KEY_MENU" mapto="input_date_time" flags="m" />
1201 ! <key id="KEY_CHANNELUP" mapto="nextBouquet" flags="m" />
1202 ! <key id="KEY_CHANNELDOWN" mapto="prevBouquet" flags="m" />
1203 ! <key id="KEY_NEXT" mapto="nextService" flags="m" />
1204 ! <key id="KEY_PREVIOUS" mapto="prevService" flags="m" />
1205 ! </map>
1207 ! <map context="EventViewActions">
1208 ! <key id="KEY_UP" mapto="pageUp" flags="mr" />
1209 ! <key id="KEY_DOWN" mapto="pageDown" flags="mr" />
1210 ! <key id="KEY_LEFT" mapto="prevEvent" flags="mr" />
1211 ! <key id="KEY_RIGHT" mapto="nextEvent" flags="mr" />
1212 ! <key id="KEY_RED" mapto="openSimilarList" flags="m" />
1213 ! <key id="KEY_GREEN" mapto="timerAdd" flags="m" />
1214 ! <key id="KEY_INFO" mapto="cancel" flags="m" />
1215 ! </map>
1217 ! <map context="EventViewEPGActions">
1218 ! <key id="KEY_YELLOW" mapto="openSingleServiceEPG" flags="m" />
1219 ! <key id="KEY_BLUE" mapto="openMultiServiceEPG" flags="m" />
1220 ! </map>
1222 ! <map context="OkCancelActions">
1223 ! <key id="\x0a" mapto="ok" flags="m" />
1224 ! <key id="\x1b" mapto="cancel" flags="m" />
1225 ! <!-- use this on rcu, ok? -->
1226 ! <key id="KEY_OK" mapto="ok" flags="m" />
1227 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
1228 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
1229 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
1230 ! </map>
1232 ! <map context="DirectionActions">
1233 ! <key id="KEY_UP" mapto="up" flags="m" />
1234 ! <key id="KEY_DOWN" mapto="down" flags="m" />
1235 ! <key id="KEY_LEFT" mapto="left" flags="m" />
1236 ! <key id="KEY_RIGHT" mapto="right" flags="m" />
1237 ! <key id="KEY_UP" mapto="upRepeated" flags="r" />
1238 ! <key id="KEY_DOWN" mapto="downRepeated" flags="r" />
1239 ! <key id="KEY_LEFT" mapto="leftRepeated" flags="r" />
1240 ! <key id="KEY_RIGHT" mapto="rightRepeated" flags="r" />
1241 ! <key id="KEY_LEFT" mapto="leftUp" flags="b" />
1242 ! <key id="KEY_RIGHT" mapto="rightUp" flags="b" />
1243 ! <key id="KEY_UP" mapto="upUp" flags="b" />
1244 ! <key id="KEY_DOWN" mapto="downUp" flags="b" />
1245 ! </map>
1247 ! <map context="ColorActions">
1248 ! <key id="KEY_RED" mapto="red" flags="m" />
1249 ! <key id="KEY_GREEN" mapto="green" flags="m" />
1250 ! <key id="KEY_YELLOW" mapto="yellow" flags="m" />
1251 ! <key id="KEY_BLUE" mapto="blue" flags="m" />
1252 ! </map>
1254 ! <map context="MsgBoxActions">
1255 ! <key id="KEY_GREEN" mapto="alwaysOK" flags="m" />
1256 ! <key id="KEY_OK" mapto="ok" flags="m" />
1257 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
1258 ! <key id="KEY_RED" mapto="cancel" flags="m" />
1259 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
1260 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
1261 ! </map>
1263 ! <map context="WindowActions">
1264 ! </map>
1266 ! <map context="HelpActions">
1267 ! <key id="KEY_HELP" mapto="displayHelp" flags="m" />
1268 ! </map>
1270 ! <map context="ShortcutActions">
1271 ! <key id="KEY_F1" mapto="red" flags="mr" />
1272 ! <key id="KEY_F2" mapto="yellow" flags="mr" />
1273 ! <key id="KEY_F3" mapto="green" flags="mr" />
1274 ! <key id="KEY_F4" mapto="blue" flags="mr" />
1275 ! <key id="KEY_RED" mapto="red" flags="mr" />
1276 ! <key id="KEY_YELLOW" mapto="yellow" flags="mr" />
1277 ! <key id="KEY_GREEN" mapto="green" flags="mr" />
1278 ! <key id="KEY_BLUE" mapto="blue" flags="mr" />
1279 ! </map>
1281 ! <map context="StandbyActions">
1282 ! <key id="KEY_POWER" mapto="power" flags="m" />
1283 ! </map>
1285 ! <map context="SleepTimerEditorActions">
1286 ! <key id="KEY_OK" mapto="select" flags="m" />
1287 ! <key id="KEY_ENTER" mapto="select" flags="m" />
1288 ! <key id="KEY_EXIT" mapto="exit" flags="m" />
1289 ! <key id="KEY_ESC" mapto="exit" flags="m" />
1290 ! <key id="KEY_1" mapto="1" flags="m" />
1291 ! <key id="KEY_2" mapto="2" flags="m" />
1292 ! <key id="KEY_3" mapto="3" flags="m" />
1293 ! <key id="KEY_4" mapto="4" flags="m" />
1294 ! <key id="KEY_5" mapto="5" flags="m" />
1295 ! <key id="KEY_6" mapto="6" flags="m" />
1296 ! <key id="KEY_7" mapto="7" flags="m" />
1297 ! <key id="KEY_8" mapto="8" flags="m" />
1298 ! <key id="KEY_9" mapto="9" flags="m" />
1299 ! <key id="KEY_0" mapto="0" flags="m" />
1300 ! <key id="KEY_LEFT" mapto="selectLeft" flags="mr" />
1301 ! <key id="KEY_RIGHT" mapto="selectRight" flags="mr" />
1302 ! <key id="KEY_RED" mapto="disableTimer" flags="mr" />
1303 ! <key id="KEY_YELLOW" mapto="toggleAsk" flags="mr" />
1304 ! <key id="KEY_GREEN" mapto="toggleAction" flags="mr" />
1305 ! <key id="KEY_BLUE" mapto="useServiceTime" flags="mr" />
1306 ! </map>
1308 ! <map context="CiSelectionActions">
1309 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
1310 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
1311 ! </map>
1313 ! <map context="PiPSetupActions">
1314 ! <key id="KEY_UP" mapto="up" flags="mr" />
1315 ! <key id="KEY_DOWN" mapto="down" flags="mr" />
1316 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
1317 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
1318 ! <key id="KEY_EXIT" mapto="cancel" flags="m" />
1319 ! <key id="KEY_ESC" mapto="cancel" flags="m" />
1320 ! <key id="KEY_ENTER" mapto="ok" flags="m" />
1321 ! <key id="KEY_OK" mapto="ok" flags="m" />
1322 ! <key id="KEY_CHANNELUP" mapto="size+" flags="mr" />
1323 ! <key id="KEY_CHANNELDOWN" mapto="size-" flags="mr" />
1324 ! </map>
1326 ! <map context="MediaPlayerActions">
1327 ! <device name="dreambox remote control (native)">
1328 ! <key id="KEY_YELLOW" mapto="pause" flags="m" />
1329 ! <key id="KEY_GREEN" mapto="play" flags="m" />
1330 ! <key id="KEY_TV" mapto="stop" flags="b" />
1331 ! <key id="KEY_TV" mapto="shift_stop" flags="l" />
1332 ! <key id="KEY_RADIO" mapto="shift_record" flags="l" />
1333 ! <key id="KEY_PREVIOUS" mapto="previous" flags="m" />
1334 ! <key id="KEY_NEXT" mapto="next" flags="m" />
1335 ! </device>
1336 ! <device name="dreambox advanced remote control (native)">
1337 ! <key id="KEY_PLAYPAUSE" mapto="pause" flags="m" />
1338 ! <key id="KEY_PLAY" mapto="pause" flags="m" />
1339 ! <key id="KEY_STOP" mapto="stop" flags="b" />
1340 ! <key id="KEY_STOP" mapto="shift_stop" flags="l" />
1341 ! <key id="KEY_RECORD" mapto="shift_record" flags="l" />
1342 ! <key id="KEY_PREVIOUS" mapto="previous" flags="m" />
1343 ! <key id="KEY_NEXT" mapto="next" flags="m" />
1344 ! <key id="KEY_RED" mapto="previous" flags="m" />
1345 ! <key id="KEY_BLUE" mapto="next" flags="m" />
1346 ! </device>
1347 ! <device name="dreambox ir keyboard">
1348 ! <key id="KEY_PAUSE" mapto="pause" flags="m" />
1349 ! <key id="KEY_PLAY" mapto="play" flags="m" />
1350 ! <key id="KEY_STOP" mapto="stop" flags="b" />
1351 ! <key id="KEY_STOP" mapto="shift_stop" flags="l" />
1352 ! <key id="KEY_RECORD" mapto="shift_record" flags="l" />
1353 ! <key id="KEY_PREVIOUSSONG" mapto="previous" flags="m" />
1354 ! <key id="KEY_NEXTSONG" mapto="next" flags="m" />
1355 ! </device>
1356 ! <device name="Xlib">
1357 ! <key id="KEY_YELLOW" mapto="pause" flags="b" />
1358 ! <key id="KEY_GREEN" mapto="play" flags="m" />
1359 ! <key id="KEY_RED" mapto="previous" flags="m" />
1360 ! <key id="KEY_BLUE" mapto="next" flags="m" />
1361 ! <key id="KEY_2" mapto="pause" flags="b" />
1362 ! <key id="KEY_5" mapto="play" flags="b" />
1363 ! </device>
1364 ! <key id="KEY_MENU" mapto="menu" flags="m" />
1365 ! <key id="KEY_SPACE" mapto="menu" flags="m" />
1366 ! <key id="KEY_2" mapto="skipListbegin" flags="m" />
1367 ! <key id="KEY_8" mapto="skipListend" flags="m" />
1368 ! <key id="KEY_CHANNELUP" mapto="nextBouquet" flags="m" />
1369 ! <key id="KEY_CHANNELDOWN" mapto="prevBouquet" flags="m" />
1370 ! <key id="KEY_VIDEO" mapto="delete" flags="m" />
1371 ! <key id="KEY_TEXT" mapto="subtitles" flags="m" />
1372 ! </map>
1373 ! </keymap>
1374 diff -crB Enigma2PC/lib/base/condVar.cpp Enigma2PC_orig/lib/base/condVar.cpp
1375 *** Enigma2PC/lib/base/condVar.cpp 2011-11-20 21:56:11.124164167 +0400
1376 --- Enigma2PC_orig/lib/base/condVar.cpp 2011-11-21 02:05:11.705895672 +0400
1377 ***************
1378 *** 187,247 ****
1379 return false;
1383 - // --- cTimeMs ---------------------------------------------------------------
1385 - cTimeMs::cTimeMs(int Ms)
1387 - Set(Ms);
1390 - uint64_t cTimeMs::Now(void)
1392 - #if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
1393 - #define MIN_RESOLUTION 5 // ms
1394 - static bool initialized = false;
1395 - static bool monotonic = false;
1396 - struct timespec tp;
1397 - if (!initialized) {
1398 - // check if monotonic timer is available and provides enough accurate resolution:
1399 - if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
1400 - long Resolution = tp.tv_nsec;
1401 - // require a minimum resolution:
1402 - if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
1403 - if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
1404 - monotonic = true;
1408 - initialized = true;
1410 - if (monotonic) {
1411 - if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
1412 - return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
1413 - monotonic = false;
1414 - // fall back to gettimeofday()
1416 - #else
1417 - # warning Posix monotonic clock not available
1418 - #endif
1419 - struct timeval t;
1420 - if (gettimeofday(&t, NULL) == 0)
1421 - return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
1422 - return 0;
1425 - void cTimeMs::Set(int Ms)
1427 - begin = Now() + Ms;
1430 - bool cTimeMs::TimedOut(void)
1432 - return Now() >= begin;
1435 - uint64_t cTimeMs::Elapsed(void)
1437 - return Now() - begin;
1440 --- 187,189 ----
1441 diff -crB Enigma2PC/lib/base/condVar.h Enigma2PC_orig/lib/base/condVar.h
1442 *** Enigma2PC/lib/base/condVar.h 2011-11-20 21:56:11.124164167 +0400
1443 --- Enigma2PC_orig/lib/base/condVar.h 2011-11-21 02:05:11.705895672 +0400
1444 ***************
1445 *** 49,64 ****
1446 bool Lock(cMutex *Mutex);
1449 - class cTimeMs {
1450 - private:
1451 - uint64_t begin;
1452 - public:
1453 - cTimeMs(int Ms = 0);
1454 - ///< Creates a timer with ms resolution and an initial timeout of Ms.
1455 - static uint64_t Now(void);
1456 - void Set(int Ms = 0);
1457 - bool TimedOut(void);
1458 - uint64_t Elapsed(void);
1459 - };
1461 #endif
1462 --- 49,52 ----
1463 diff -crB Enigma2PC/lib/driver/Makefile.am Enigma2PC_orig/lib/driver/Makefile.am
1464 *** Enigma2PC/lib/driver/Makefile.am 2011-11-20 21:56:11.130830808 +0400
1465 --- Enigma2PC_orig/lib/driver/Makefile.am 2011-11-21 02:05:11.705895672 +0400
1466 ***************
1467 *** 40,46 ****
1468 if HAVE_XLIB
1469 libenigma_driver_a_SOURCES += \
1470 rcxlib.cpp \
1471 ! rcxlib.h \
1472 ! rclirc.cpp \
1473 ! rclirc.h
1474 endif
1475 --- 40,44 ----
1476 if HAVE_XLIB
1477 libenigma_driver_a_SOURCES += \
1478 rcxlib.cpp \
1479 ! rcxlib.h
1480 endif
1481 Only in Enigma2PC/lib/driver: rclirc.cpp
1482 Only in Enigma2PC/lib/driver: rclirc.h
1483 diff -crB Enigma2PC/lib/dvb/decoder.cpp Enigma2PC_orig/lib/dvb/decoder.cpp
1484 *** Enigma2PC/lib/dvb/decoder.cpp 2011-11-20 21:56:11.134164129 +0400
1485 --- Enigma2PC_orig/lib/dvb/decoder.cpp 2011-11-20 02:56:00.000000000 +0400
1486 ***************
1487 *** 1,722 ****
1488 ! #include <lib/base/ebase.h>
1489 ! #include <lib/base/eerror.h>
1490 ! #include <lib/dvb/decoder.h>
1491 ! #include <lib/gdi/xineLib.h>
1493 ! #include <unistd.h>
1494 ! #include <fcntl.h>
1495 ! #include <sys/ioctl.h>
1496 ! #include <sys/types.h>
1497 ! #include <sys/stat.h>
1498 ! #include <errno.h>
1501 ! DEFINE_REF(eDVBAudio);
1503 ! eDVBAudio::eDVBAudio(int dev) : m_dev(dev) {}
1505 ! #define ISO_13818_AUDIO 0x04
1506 ! #define HDMV_AUDIO_80_PCM 0x80
1507 ! #define STREAM_AUDIO_AC3 0x81
1508 ! #define HDMV_AUDIO_82_DTS 0x82
1509 ! #define HDMV_AUDIO_86_DTS_HD_MA 0x86
1511 ! int eDVBAudio::startPid(int pid, int type)
1513 ! cXineLib *xineLib = cXineLib::getInstance();
1515 ! int bypass = 0;
1517 ! switch (type)
1519 ! case aMPEG:
1520 ! bypass = ISO_13818_AUDIO;
1521 ! break;
1522 ! case aAC3:
1523 ! bypass = STREAM_AUDIO_AC3;
1524 ! break;
1525 ! case aDTS:
1526 ! bypass = HDMV_AUDIO_82_DTS;
1527 ! break;
1528 ! case aAAC:
1529 ! bypass = 8;
1530 ! break;
1531 ! case aAACHE:
1532 ! bypass = 9;
1533 ! break;
1534 ! case aLPCM:
1535 ! bypass = HDMV_AUDIO_80_PCM;
1536 ! break;
1537 ! case aDTSHD:
1538 ! bypass = HDMV_AUDIO_86_DTS_HD_MA;
1539 ! break;
1542 ! xineLib->setAudioType(pid, bypass);
1544 ! return 0;
1547 ! void eDVBAudio::stop()
1549 ! eDebug("AUDIO_STOP");
1552 ! void eDVBAudio::flush()
1554 ! eDebug("AUDIO_CLEAR_BUFFER");
1557 ! void eDVBAudio::freeze()
1559 ! eDebug("AUDIO_PAUSE");
1562 ! void eDVBAudio::unfreeze()
1564 ! eDebug("AUDIO_CONTINUE");
1567 ! void eDVBAudio::setChannel(int channel)
1569 ! int val = 0;//AUDIO_STEREO;
1571 ! /*switch (channel)
1573 ! case aMonoLeft:
1574 ! val = AUDIO_MONO_LEFT;
1575 ! break;
1576 ! case aMonoRight:
1577 ! val = AUDIO_MONO_RIGHT;
1578 ! break;
1579 ! default:
1580 ! break;
1581 ! }*/
1583 ! eDebug("AUDIO_CHANNEL_SELECT(%d)", val);
1586 ! int eDVBAudio::getPTS(pts_t &now)
1588 ! cXineLib *xineLib = cXineLib::getInstance();
1589 ! //if (xineLib->getPTS(now) < 0)
1590 ! // eDebug("AUDIO_GET_PTS failed (%m)");
1591 ! return 0;
1594 ! eDVBAudio::~eDVBAudio()
1596 ! unfreeze(); // why unfreeze here... but not unfreeze video in ~eDVBVideo ?!?
1599 ! DEFINE_REF(eDVBVideo);
1601 ! eDVBVideo::eDVBVideo(int dev) : m_dev(dev), m_progressive(-1) {}
1603 ! // not finally values i think.. !!
1604 ! #define VIDEO_STREAMTYPE_MPEG2 0x02
1605 ! #define VIDEO_STREAMTYPE_MPEG4_H264 0x1B
1606 ! #define VIDEO_STREAMTYPE_VC1 0xEA
1607 ! #define VIDEO_STREAMTYPE_MPEG4_Part2 0x10
1608 ! #define VIDEO_STREAMTYPE_VC1_SM 0xEA
1609 ! #define VIDEO_STREAMTYPE_MPEG1 0x01
1611 ! int eDVBVideo::startPid(int pid, int type)
1613 ! cXineLib *xineLib = cXineLib::getInstance();
1614 ! int streamtype = VIDEO_STREAMTYPE_MPEG2;
1616 ! switch(type)
1618 ! default:
1619 ! case MPEG2:
1620 ! break;
1621 ! case MPEG4_H264:
1622 ! streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
1623 ! break;
1624 ! case MPEG1:
1625 ! streamtype = VIDEO_STREAMTYPE_MPEG1;
1626 ! break;
1627 ! case MPEG4_Part2:
1628 ! streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
1629 ! break;
1630 ! case VC1:
1631 ! streamtype = VIDEO_STREAMTYPE_VC1;
1632 ! break;
1633 ! case VC1_SM:
1634 ! streamtype = VIDEO_STREAMTYPE_VC1_SM;
1635 ! break;
1638 ! eDebug("VIDEO_SET_STREAMTYPE %d", streamtype);
1640 ! xineLib->setVideoType(pid, streamtype);
1642 ! freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in
1643 ! eDebug("VIDEO_PLAY\n");
1645 ! xineLib->playVideo();
1647 ! return 0;
1650 ! void eDVBVideo::stop()
1652 ! cXineLib *xineLib = cXineLib::getInstance();
1653 ! xineLib->stopVideo();
1656 ! void eDVBVideo::flush()
1658 ! eDebug("VIDEO_CLEAR_BUFFER");
1661 ! void eDVBVideo::freeze()
1663 ! eDebug("VIDEO_FREEZE");
1666 ! void eDVBVideo::unfreeze()
1668 ! eDebug("VIDEO_CONTINUE");
1671 ! int eDVBVideo::setSlowMotion(int repeat)
1673 ! eDebug("VIDEO_SLOWMOTION(%d)", repeat);
1674 ! int ret = 0;
1676 ! return ret;
1679 ! int eDVBVideo::setFastForward(int skip)
1681 ! eDebug("VIDEO_FAST_FORWARD(%d)", skip);
1682 ! int ret = 0;
1684 ! return ret;
1687 ! int eDVBVideo::getPTS(pts_t &now)
1689 ! cXineLib *xineLib = cXineLib::getInstance();
1691 ! int ret = 0;//xineLib->getPTS(now);
1692 ! now = 0;
1694 ! if (ret < 0)
1695 ! eDebug("VIDEO_GET_PTS failed(%m)");
1696 ! return ret;
1699 ! eDVBVideo::~eDVBVideo() {}
1701 ! void eDVBVideo::video_event(int)
1703 ! struct video_event evt;
1704 ! eDebug("VIDEO_GET_EVENT");
1705 ! #if 0
1706 ! if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
1707 ! eDebug("failed (%m)");
1708 ! else
1710 ! else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
1712 ! struct iTSMPEGDecoder::videoEvent event;
1713 ! event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
1714 ! m_framerate = event.framerate = evt.u.frame_rate;
1715 ! /* emit */ m_event(event);
1717 ! else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
1719 ! struct iTSMPEGDecoder::videoEvent event;
1720 ! event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged;
1721 ! m_progressive = event.progressive = evt.u.frame_rate;
1722 ! /* emit */ m_event(event);
1724 ! else
1725 ! eDebug("unhandled DVBAPI Video Event %d", evt.type);
1727 ! #endif
1730 ! DEFINE_REF(eDVBPCR);
1732 ! eDVBPCR::eDVBPCR(int dev) : m_dev(dev) {}
1734 ! int eDVBPCR::startPid(int pid)
1736 ! eDebug("DEMUX_START - pcr");
1737 ! return 0;
1740 ! void eDVBPCR::stop()
1742 ! eDebug("DEMUX_STOP - pcr");
1745 ! eDVBPCR::~eDVBPCR() {}
1747 ! DEFINE_REF(eDVBTText);
1749 ! eDVBTText::eDVBTText(int dev) : m_dev(dev) {}
1751 ! int eDVBTText::startPid(int pid)
1753 ! eDebug("DEMUX_START - ttx");
1755 ! return 0;
1758 ! void eDVBTText::stop()
1760 ! eDebug("DEMUX_STOP - ttx");
1763 ! eDVBTText::~eDVBTText() {}
1765 ! DEFINE_REF(eTSMPEGDecoder);
1767 ! int eTSMPEGDecoder::setState()
1769 ! int res = 0;
1771 ! int noaudio = (m_state != statePlay) && (m_state != statePause);
1772 ! int nott = noaudio; /* actually same conditions */
1774 ! if ((noaudio && m_audio) || (!m_audio && !noaudio))
1775 ! m_changed |= changeAudio | changeState;
1777 ! if ((nott && m_text) || (!m_text && !nott))
1778 ! m_changed |= changeText | changeState;
1780 ! const char *decoder_states[] = {"stop", "pause", "play", "decoderfastforward", "trickmode", "slowmotion"};
1781 ! eDebug("decoder state: %s, vpid=%d, apid=%d", decoder_states[m_state], m_vpid, m_apid);
1783 ! int changed = m_changed;
1785 ! if (m_changed & changePCR)
1787 ! if (m_pcr)
1788 ! m_pcr->stop();
1789 ! m_pcr = 0;
1791 ! if (m_changed & changeVideo)
1793 ! if (m_video)
1795 ! m_video->stop();
1796 ! m_video = 0;
1799 ! if (m_changed & changeAudio)
1801 ! if (m_audio)
1802 ! m_audio->stop();
1803 ! m_audio = 0;
1805 ! if (m_changed & changeText)
1807 ! if (m_text)
1808 ! m_text->stop();
1809 ! m_text = 0;
1811 ! if (m_changed & changePCR)
1813 ! if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
1815 ! m_pcr = new eDVBPCR(m_decoder);
1816 ! if (m_pcr->startPid(m_pcrpid))
1817 ! res = -1;
1819 ! m_changed &= ~changePCR;
1821 ! if (m_changed & changeAudio)
1823 ! if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
1825 ! m_audio = new eDVBAudio(m_decoder);
1826 ! if (m_audio->startPid(m_apid, m_atype))
1827 ! res = -1;
1829 ! m_changed &= ~changeAudio;
1831 ! if (m_changed & changeVideo)
1833 ! if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
1835 ! m_video = new eDVBVideo(m_decoder);
1836 ! if (m_video->startPid(m_vpid, m_vtype))
1837 ! res = -1;
1839 ! m_changed &= ~changeVideo;
1841 ! if (m_changed & changeText)
1843 ! if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
1845 ! m_text = new eDVBTText(m_decoder);
1846 ! if (m_text->startPid(m_textpid))
1847 ! res = -1;
1849 ! m_changed &= ~changeText;
1852 ! if (changed & (changeState|changeVideo|changeAudio))
1854 ! /* play, slowmotion, fast-forward */
1855 ! int state_table[6][4] =
1857 ! /* [stateStop] = */ {0, 0, 0},
1858 ! /* [statePause] = */ {0, 0, 0},
1859 ! /* [statePlay] = */ {1, 0, 0},
1860 ! /* [stateDecoderFastForward] = */ {1, 0, m_ff_sm_ratio},
1861 ! /* [stateHighspeedFastForward] = */ {1, 0, 1},
1862 ! /* [stateSlowMotion] = */ {1, m_ff_sm_ratio, 0}
1863 ! };
1864 ! int *s = state_table[m_state];
1865 ! if (changed & (changeState|changeVideo) && m_video)
1867 ! m_video->setSlowMotion(s[1]);
1868 ! m_video->setFastForward(s[2]);
1869 ! if (s[0])
1870 ! m_video->unfreeze();
1871 ! else
1872 ! m_video->freeze();
1874 ! if (changed & (changeState|changeAudio) && m_audio)
1876 ! if (s[0])
1877 ! m_audio->unfreeze();
1878 ! else
1879 ! m_audio->freeze();
1881 ! m_changed &= ~changeState;
1884 ! if (changed && !m_video && m_audio && m_radio_pic.length())
1885 ! showSinglePic(m_radio_pic.c_str());
1887 ! return res;
1890 ! int eTSMPEGDecoder::m_pcm_delay=-1,
1891 ! eTSMPEGDecoder::m_ac3_delay=-1;
1893 ! RESULT eTSMPEGDecoder::setHwPCMDelay(int delay)
1895 ! if (delay != m_pcm_delay )
1897 ! FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
1898 ! if (fp)
1900 ! fprintf(fp, "%x", delay*90);
1901 ! fclose(fp);
1902 ! m_pcm_delay = delay;
1903 ! return 0;
1906 ! return -1;
1909 ! RESULT eTSMPEGDecoder::setHwAC3Delay(int delay)
1911 ! if ( delay != m_ac3_delay )
1913 ! FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
1914 ! if (fp)
1916 ! fprintf(fp, "%x", delay*90);
1917 ! fclose(fp);
1918 ! m_ac3_delay = delay;
1919 ! return 0;
1922 ! return -1;
1926 ! RESULT eTSMPEGDecoder::setPCMDelay(int delay)
1928 ! return m_decoder == 0 ? setHwPCMDelay(delay) : -1;
1931 ! RESULT eTSMPEGDecoder::setAC3Delay(int delay)
1933 ! return m_decoder == 0 ? setHwAC3Delay(delay) : -1;
1936 ! eTSMPEGDecoder::eTSMPEGDecoder(int decoder)
1937 ! : m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1),
1938 ! m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp))
1940 ! CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
1941 ! m_state = stateStop;
1944 ! eTSMPEGDecoder::~eTSMPEGDecoder()
1946 ! finishShowSinglePic();
1947 ! m_vpid = m_apid = m_pcrpid = m_textpid = pidNone;
1948 ! m_changed = -1;
1949 ! setState();
1952 ! RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
1954 ! printf("eTSMPEGDecoder setVideoPID %d\n", vpid);
1955 ! if ((m_vpid != vpid) || (m_vtype != type))
1957 ! m_changed |= changeVideo;
1958 ! m_vpid = vpid;
1959 ! m_vtype = type;
1961 ! return 0;
1964 ! RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
1966 ! printf("eTSMPEGDecoder setAudioPID %d\n", apid);
1967 ! if ((m_apid != apid) || (m_atype != type))
1969 ! m_changed |= changeAudio;
1970 ! m_atype = type;
1971 ! m_apid = apid;
1974 ! return 0;
1977 ! int eTSMPEGDecoder::m_audio_channel = -1;
1979 ! RESULT eTSMPEGDecoder::setAudioChannel(int channel)
1981 ! if (channel == -1)
1982 ! channel = ac_stereo;
1983 ! if (m_decoder == 0 && m_audio_channel != channel)
1985 ! if (m_audio)
1987 ! m_audio->setChannel(channel);
1988 ! m_audio_channel=channel;
1990 ! else
1991 ! eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
1993 ! return 0;
1996 ! int eTSMPEGDecoder::getAudioChannel()
1998 ! return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
2001 ! RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
2003 ! if (m_pcrpid != pcrpid)
2005 ! m_changed |= changePCR;
2006 ! m_pcrpid = pcrpid;
2008 ! return 0;
2011 ! RESULT eTSMPEGDecoder::setTextPID(int textpid)
2013 ! if (m_textpid != textpid)
2015 ! m_changed |= changeText;
2016 ! m_textpid = textpid;
2018 ! return 0;
2021 ! RESULT eTSMPEGDecoder::setSyncMaster(int who)
2023 ! return -1;
2026 ! RESULT eTSMPEGDecoder::set()
2028 ! return setState();
2031 ! RESULT eTSMPEGDecoder::play()
2033 ! printf("eTSMPEGDecoder play\n");
2034 ! if (m_state == statePlay)
2036 ! if (!m_changed)
2037 ! return 0;
2038 ! } else
2040 ! m_state = statePlay;
2041 ! m_changed |= changeState;
2043 ! return setState();
2046 ! RESULT eTSMPEGDecoder::pause()
2048 ! printf("eTSMPEGDecoder pause\n");
2049 ! if (m_state == statePause)
2050 ! return 0;
2051 ! m_state = statePause;
2052 ! m_changed |= changeState;
2053 ! return setState();
2056 ! RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
2058 ! if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip))
2059 ! return 0;
2061 ! m_state = stateDecoderFastForward;
2062 ! m_ff_sm_ratio = frames_to_skip;
2063 ! m_changed |= changeState;
2064 ! return setState();
2066 ! // return m_video->setFastForward(frames_to_skip);
2069 ! RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
2071 ! if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat))
2072 ! return 0;
2074 ! m_state = stateSlowMotion;
2075 ! m_ff_sm_ratio = repeat;
2076 ! m_changed |= changeState;
2077 ! return setState();
2080 ! RESULT eTSMPEGDecoder::setTrickmode()
2082 ! if (m_state == stateTrickmode)
2083 ! return 0;
2085 ! m_state = stateTrickmode;
2086 ! m_changed |= changeState;
2087 ! return setState();
2090 ! RESULT eTSMPEGDecoder::flush()
2092 ! if (m_audio)
2093 ! m_audio->flush();
2094 ! if (m_video)
2095 ! m_video->flush();
2096 ! return 0;
2099 ! RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
2101 ! if (what == 0) /* auto */
2102 ! what = m_video ? 1 : 2;
2104 ! if (what == 1) /* video */
2106 ! if (m_video)
2107 ! return m_video->getPTS(pts);
2108 ! else
2109 ! return -1;
2112 ! if (what == 2) /* audio */
2114 ! if (m_audio)
2115 ! return m_audio->getPTS(pts);
2116 ! else
2117 ! return -1;
2120 ! return -1;
2123 ! RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
2125 ! m_radio_pic = filename;
2126 ! return 0;
2129 ! RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
2131 ! if (m_decoder == 0)
2133 ! eDebug("showSinglePic %s", filename);
2134 ! int f = open(filename, O_RDONLY);
2135 ! if (f >= 0)
2137 ! struct stat s;
2138 ! size_t written=0;
2139 ! fstat(f, &s);
2140 ! if (m_video_clip_fd == -1)
2141 ! m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY);
2142 ! if (m_video_clip_fd >= 0)
2144 ! bool seq_end_avail = false;
2145 ! size_t pos=0;
2146 ! unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
2147 ! unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 };
2148 ! unsigned char iframe[s.st_size];
2149 ! unsigned char stuffing[8192];
2150 ! int streamtype = VIDEO_STREAMTYPE_MPEG2;
2151 ! memset(stuffing, 0, 8192);
2152 ! read(f, iframe, s.st_size);
2153 ! if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
2154 ! eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
2155 ! if (ioctl(m_video_clip_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
2156 ! eDebug("VIDEO_SET_STREAMTYPE failed(%m)");
2157 ! if (ioctl(m_video_clip_fd, VIDEO_PLAY) < 0)
2158 ! eDebug("VIDEO_PLAY failed (%m)");
2159 ! if (ioctl(m_video_clip_fd, VIDEO_CONTINUE) < 0)
2160 ! eDebug("video: VIDEO_CONTINUE: %m");
2161 ! if (ioctl(m_video_clip_fd, VIDEO_CLEAR_BUFFER) < 0)
2162 ! eDebug("video: VIDEO_CLEAR_BUFFER: %m");
2163 ! while(pos <= (s.st_size-4) && !(seq_end_avail = (!iframe[pos] && !iframe[pos+1] && iframe[pos+2] == 1 && iframe[pos+3] == 0xB7)))
2164 ! ++pos;
2165 ! if ((iframe[3] >> 4) != 0xE) // no pes header
2166 ! write(m_video_clip_fd, pes_header, sizeof(pes_header));
2167 ! else
2168 ! iframe[4] = iframe[5] = 0x00;
2169 ! write(m_video_clip_fd, iframe, s.st_size);
2170 ! if (!seq_end_avail)
2171 ! write(m_video_clip_fd, seq_end, sizeof(seq_end));
2172 ! write(m_video_clip_fd, stuffing, 8192);
2173 ! m_showSinglePicTimer->start(150, true);
2175 ! close(f);
2177 ! else
2179 ! eDebug("couldnt open %s", filename);
2180 ! return -1;
2183 ! else
2185 ! eDebug("only show single pics on first decoder");
2186 ! return -1;
2188 ! return 0;
2191 ! void eTSMPEGDecoder::finishShowSinglePic()
2193 ! if (m_video_clip_fd >= 0)
2195 ! if (ioctl(m_video_clip_fd, VIDEO_STOP, 0) < 0)
2196 ! eDebug("VIDEO_STOP failed (%m)");
2197 ! if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
2198 ! eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
2199 ! close(m_video_clip_fd);
2200 ! m_video_clip_fd = -1;
2204 ! RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
2206 ! conn = new eConnection(this, m_video_event.connect(event));
2207 ! return 0;
2210 --- 1,731 ----
2211 ! #include <lib/base/ebase.h>
2212 ! #include <lib/base/eerror.h>
2213 ! #include <lib/dvb/decoder.h>
2214 ! #include <lib/gdi/xineLib.h>
2216 ! #include <unistd.h>
2217 ! #include <fcntl.h>
2218 ! #include <sys/ioctl.h>
2219 ! #include <sys/types.h>
2220 ! #include <sys/stat.h>
2221 ! #include <errno.h>
2224 ! DEFINE_REF(eDVBAudio);
2226 ! eDVBAudio::eDVBAudio(int dev) : m_dev(dev) {}
2228 ! #define STREAM_SPU_BITMAP_HDMV 0x90
2229 ! #define ISO_13818_AUDIO 0x04
2230 ! #define STREAM_VIDEO_VC1 0xea /* VC-1 Video */
2231 ! #define HDMV_AUDIO_80_PCM 0x80 /* BluRay PCM */
2232 ! #define STREAM_AUDIO_AC3 0x81
2233 ! #define HDMV_AUDIO_82_DTS 0x82 /* DTS */
2234 ! #define HDMV_AUDIO_83_TRUEHD 0x83 /* Dolby TrueHD, primary audio */
2235 ! #define HDMV_AUDIO_84_EAC3 0x84 /* Dolby Digital plus, primary audio */
2236 ! #define HDMV_AUDIO_85_DTS_HRA 0x85 /* DTS-HRA */
2237 ! #define HDMV_AUDIO_86_DTS_HD_MA 0x86 /* DTS-HD Master audio */
2240 ! int eDVBAudio::startPid(int pid, int type)
2242 ! cXineLib *xineLib = cXineLib::getInstance();
2244 ! int bypass = 0;
2246 ! switch (type)
2248 ! case aMPEG:
2249 ! bypass = ISO_13818_AUDIO;
2250 ! break;
2251 ! case aAC3:
2252 ! bypass = STREAM_AUDIO_AC3;
2253 ! break;
2254 ! case aDTS:
2255 ! bypass = HDMV_AUDIO_82_DTS;
2256 ! break;
2257 ! case aAAC:
2258 ! bypass = 8;
2259 ! break;
2260 ! case aAACHE:
2261 ! bypass = 9;
2262 ! break;
2263 ! case aLPCM:
2264 ! bypass = HDMV_AUDIO_80_PCM;
2265 ! break;
2266 ! case aDTSHD:
2267 ! bypass = HDMV_AUDIO_86_DTS_HD_MA;
2268 ! break;
2270 ! xineLib->setAudioType(pid, bypass);
2271 ! xineLib->playVideo();
2272 ! return 0;
2275 ! void eDVBAudio::stop()
2277 ! eDebug("AUDIO_STOP");
2280 ! void eDVBAudio::flush()
2282 ! eDebug("AUDIO_CLEAR_BUFFER");
2285 ! void eDVBAudio::freeze()
2287 ! eDebug("AUDIO_PAUSE");
2290 ! void eDVBAudio::unfreeze()
2292 ! eDebug("AUDIO_CONTINUE");
2295 ! void eDVBAudio::setChannel(int channel)
2297 ! int val = 0;//AUDIO_STEREO;
2299 ! /*switch (channel)
2301 ! case aMonoLeft:
2302 ! val = AUDIO_MONO_LEFT;
2303 ! break;
2304 ! case aMonoRight:
2305 ! val = AUDIO_MONO_RIGHT;
2306 ! break;
2307 ! default:
2308 ! break;
2309 ! }*/
2311 ! eDebug("AUDIO_CHANNEL_SELECT(%d)", val);
2314 ! int eDVBAudio::getPTS(pts_t &now)
2316 ! cXineLib *xineLib = cXineLib::getInstance();
2317 ! //if (xineLib->getPTS(now) < 0)
2318 ! // eDebug("AUDIO_GET_PTS failed (%m)");
2319 ! return 0;
2322 ! eDVBAudio::~eDVBAudio()
2324 ! unfreeze(); // why unfreeze here... but not unfreeze video in ~eDVBVideo ?!?
2327 ! DEFINE_REF(eDVBVideo);
2329 ! eDVBVideo::eDVBVideo(int dev) : m_dev(dev), m_progressive(-1) {}
2331 ! // not finally values i think.. !!
2332 ! #define VIDEO_STREAMTYPE_MPEG2 0x02
2333 ! #define VIDEO_STREAMTYPE_MPEG4_H264 0x1B
2334 ! #define VIDEO_STREAMTYPE_VC1 0xEA
2335 ! #define VIDEO_STREAMTYPE_MPEG4_Part2 0x10
2336 ! #define VIDEO_STREAMTYPE_VC1_SM 0xEA
2337 ! #define VIDEO_STREAMTYPE_MPEG1 0x01
2339 ! int eDVBVideo::startPid(int pid, int type)
2341 ! cXineLib *xineLib = cXineLib::getInstance();
2342 ! int streamtype = VIDEO_STREAMTYPE_MPEG2;
2344 ! switch(type)
2346 ! default:
2347 ! case MPEG2:
2348 ! break;
2349 ! case MPEG4_H264:
2350 ! streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
2351 ! break;
2352 ! case MPEG1:
2353 ! streamtype = VIDEO_STREAMTYPE_MPEG1;
2354 ! break;
2355 ! case MPEG4_Part2:
2356 ! streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
2357 ! break;
2358 ! case VC1:
2359 ! streamtype = VIDEO_STREAMTYPE_VC1;
2360 ! break;
2361 ! case VC1_SM:
2362 ! streamtype = VIDEO_STREAMTYPE_VC1_SM;
2363 ! break;
2366 ! eDebug("VIDEO_SET_STREAMTYPE %d", streamtype);
2368 ! xineLib->setVideoType(pid, streamtype);
2370 ! freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in
2371 ! eDebug("VIDEO_PLAY\n");
2373 ! xineLib->playVideo();
2375 ! return 0;
2378 ! void eDVBVideo::stop()
2380 ! cXineLib *xineLib = cXineLib::getInstance();
2381 ! xineLib->stopVideo();
2384 ! void eDVBVideo::flush()
2386 ! eDebug("VIDEO_CLEAR_BUFFER");
2389 ! void eDVBVideo::freeze()
2391 ! cXineLib *xineLib = cXineLib::getInstance();
2392 ! xineLib->VideoPause();
2393 ! eDebug("VIDEO_FREEZE");
2396 ! void eDVBVideo::unfreeze()
2398 ! cXineLib *xineLib = cXineLib::getInstance();
2399 ! xineLib->VideoResume();
2400 ! eDebug("VIDEO_CONTINUE");
2403 ! int eDVBVideo::setSlowMotion(int repeat)
2405 ! eDebug("VIDEO_SLOWMOTION(%d)", repeat);
2406 ! int ret = 0;
2408 ! return ret;
2411 ! int eDVBVideo::setFastForward(int skip)
2413 ! eDebug("VIDEO_FAST_FORWARD(%d)", skip);
2414 ! int ret = 0;
2416 ! return ret;
2419 ! int eDVBVideo::getPTS(pts_t &now)
2421 ! cXineLib *xineLib = cXineLib::getInstance();
2423 ! int ret = 0;//xineLib->getPTS(now);
2424 ! now = 0;
2426 ! if (ret < 0)
2427 ! eDebug("VIDEO_GET_PTS failed(%m)");
2428 ! return ret;
2431 ! eDVBVideo::~eDVBVideo() {}
2433 ! void eDVBVideo::video_event(int)
2435 ! struct video_event evt;
2436 ! eDebug("VIDEO_GET_EVENT");
2437 ! #if 0
2438 ! if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
2439 ! eDebug("failed (%m)");
2440 ! else
2442 ! else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
2444 ! struct iTSMPEGDecoder::videoEvent event;
2445 ! event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
2446 ! m_framerate = event.framerate = evt.u.frame_rate;
2447 ! /* emit */ m_event(event);
2449 ! else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
2451 ! struct iTSMPEGDecoder::videoEvent event;
2452 ! event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged;
2453 ! m_progressive = event.progressive = evt.u.frame_rate;
2454 ! /* emit */ m_event(event);
2456 ! else
2457 ! eDebug("unhandled DVBAPI Video Event %d", evt.type);
2459 ! #endif
2462 ! DEFINE_REF(eDVBPCR);
2464 ! eDVBPCR::eDVBPCR(int dev) : m_dev(dev) {}
2466 ! int eDVBPCR::startPid(int pid)
2468 ! eDebug("DEMUX_START - pcr");
2469 ! return 0;
2472 ! void eDVBPCR::stop()
2474 ! eDebug("DEMUX_STOP - pcr");
2477 ! eDVBPCR::~eDVBPCR() {}
2479 ! DEFINE_REF(eDVBTText);
2481 ! eDVBTText::eDVBTText(int dev) : m_dev(dev) {}
2483 ! int eDVBTText::startPid(int pid)
2485 ! eDebug("DEMUX_START - ttx");
2487 ! return 0;
2490 ! void eDVBTText::stop()
2492 ! eDebug("DEMUX_STOP - ttx");
2495 ! eDVBTText::~eDVBTText() {}
2497 ! DEFINE_REF(eTSMPEGDecoder);
2499 ! int eTSMPEGDecoder::setState()
2501 ! int res = 0;
2503 ! int noaudio = (m_state != statePlay) && (m_state != statePause);
2504 ! int nott = noaudio; /* actually same conditions */
2506 ! if ((noaudio && m_audio) || (!m_audio && !noaudio))
2507 ! m_changed |= changeAudio | changeState;
2509 ! if ((nott && m_text) || (!m_text && !nott))
2510 ! m_changed |= changeText | changeState;
2512 ! const char *decoder_states[] = {"stop", "pause", "play", "decoderfastforward", "trickmode", "slowmotion"};
2513 ! eDebug("decoder state: %s, vpid=%d, apid=%d", decoder_states[m_state], m_vpid, m_apid);
2515 ! int changed = m_changed;
2517 ! if (m_changed & changePCR)
2519 ! if (m_pcr)
2520 ! m_pcr->stop();
2521 ! m_pcr = 0;
2523 ! if (m_changed & changeVideo)
2525 ! if (m_video)
2527 ! m_video->stop();
2528 ! m_video = 0;
2531 ! if (m_changed & changeAudio)
2533 ! if (m_audio)
2534 ! m_audio->stop();
2535 ! m_audio = 0;
2537 ! if (m_changed & changeText)
2539 ! if (m_text)
2540 ! m_text->stop();
2541 ! m_text = 0;
2543 ! if (m_changed & changePCR)
2545 ! if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
2547 ! m_pcr = new eDVBPCR(m_decoder);
2548 ! if (m_pcr->startPid(m_pcrpid))
2549 ! res = -1;
2551 ! m_changed &= ~changePCR;
2553 ! if (m_changed & changeAudio)
2555 ! if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
2557 ! m_audio = new eDVBAudio(m_decoder);
2558 ! if (m_audio->startPid(m_apid, m_atype))
2559 ! res = -1;
2561 ! m_changed &= ~changeAudio;
2563 ! if (m_changed & changeVideo)
2565 ! if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
2567 ! m_video = new eDVBVideo(m_decoder);
2568 ! if (m_video->startPid(m_vpid, m_vtype))
2569 ! res = -1;
2571 ! m_changed &= ~changeVideo;
2573 ! if (m_changed & changeText)
2575 ! if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
2577 ! m_text = new eDVBTText(m_decoder);
2578 ! if (m_text->startPid(m_textpid))
2579 ! res = -1;
2581 ! m_changed &= ~changeText;
2584 ! if (changed & (changeState|changeVideo|changeAudio))
2586 ! /* play, slowmotion, fast-forward */
2587 ! int state_table[6][4] =
2589 ! /* [stateStop] = */ {0, 0, 0},
2590 ! /* [statePause] = */ {0, 0, 0},
2591 ! /* [statePlay] = */ {1, 0, 0},
2592 ! /* [stateDecoderFastForward] = */ {1, 0, m_ff_sm_ratio},
2593 ! /* [stateHighspeedFastForward] = */ {1, 0, 1},
2594 ! /* [stateSlowMotion] = */ {1, m_ff_sm_ratio, 0}
2595 ! };
2596 ! int *s = state_table[m_state];
2597 ! if (changed & (changeState|changeVideo) && m_video)
2599 ! m_video->setSlowMotion(s[1]);
2600 ! m_video->setFastForward(s[2]);
2601 ! if (s[0])
2602 ! m_video->unfreeze();
2603 ! else
2604 ! m_video->freeze();
2606 ! if (changed & (changeState|changeAudio) && m_audio)
2608 ! if (s[0])
2609 ! m_audio->unfreeze();
2610 ! else
2611 ! m_audio->freeze();
2613 ! m_changed &= ~changeState;
2616 ! if (changed && !m_video && m_audio && m_radio_pic.length())
2617 ! showSinglePic(m_radio_pic.c_str());
2619 ! return res;
2622 ! int eTSMPEGDecoder::m_pcm_delay=-1,
2623 ! eTSMPEGDecoder::m_ac3_delay=-1;
2625 ! RESULT eTSMPEGDecoder::setHwPCMDelay(int delay)
2627 ! if (delay != m_pcm_delay )
2629 ! FILE *fp = fopen("/usr/local/etc/stb/audio/audio_delay_pcm", "w");
2630 ! if (fp)
2632 ! fprintf(fp, "%x", delay*90);
2633 ! fclose(fp);
2634 ! m_pcm_delay = delay;
2635 ! return 0;
2638 ! return -1;
2641 ! RESULT eTSMPEGDecoder::setHwAC3Delay(int delay)
2643 ! if ( delay != m_ac3_delay )
2645 ! FILE *fp = fopen("/usr/local/etc/stb/audio/audio_delay_bitstream", "w");
2646 ! if (fp)
2648 ! fprintf(fp, "%x", delay*90);
2649 ! fclose(fp);
2650 ! m_ac3_delay = delay;
2651 ! return 0;
2654 ! return -1;
2658 ! RESULT eTSMPEGDecoder::setPCMDelay(int delay)
2660 ! return m_decoder == 0 ? setHwPCMDelay(delay) : -1;
2663 ! RESULT eTSMPEGDecoder::setAC3Delay(int delay)
2665 ! return m_decoder == 0 ? setHwAC3Delay(delay) : -1;
2668 ! eTSMPEGDecoder::eTSMPEGDecoder(int decoder)
2669 ! : m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1),
2670 ! m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp))
2672 ! CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
2673 ! m_state = stateStop;
2676 ! eTSMPEGDecoder::~eTSMPEGDecoder()
2678 ! finishShowSinglePic();
2679 ! m_vpid = m_apid = m_pcrpid = m_textpid = pidNone;
2680 ! m_changed = -1;
2681 ! setState();
2684 ! RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
2686 ! printf("eTSMPEGDecoder setVideoPID %d\n", vpid);
2687 ! if ((m_vpid != vpid) || (m_vtype != type))
2689 ! m_changed |= changeVideo;
2690 ! m_vpid = vpid;
2691 ! m_vtype = type;
2693 ! return 0;
2696 ! RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
2698 ! printf("eTSMPEGDecoder setAudioPID %d\n", apid);
2699 ! if ((m_apid != apid) || (m_atype != type))
2701 ! m_changed |= changeAudio;
2702 ! m_atype = type;
2703 ! m_apid = apid;
2706 ! return 0;
2709 ! int eTSMPEGDecoder::m_audio_channel = -1;
2711 ! RESULT eTSMPEGDecoder::setAudioChannel(int channel)
2713 ! if (channel == -1)
2714 ! channel = ac_stereo;
2715 ! if (m_decoder == 0 && m_audio_channel != channel)
2717 ! if (m_audio)
2719 ! m_audio->setChannel(channel);
2720 ! m_audio_channel=channel;
2722 ! else
2723 ! eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
2725 ! return 0;
2728 ! int eTSMPEGDecoder::getAudioChannel()
2730 ! return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
2733 ! RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
2735 ! if (m_pcrpid != pcrpid)
2737 ! m_changed |= changePCR;
2738 ! m_pcrpid = pcrpid;
2740 ! return 0;
2743 ! RESULT eTSMPEGDecoder::setTextPID(int textpid)
2745 ! if (m_textpid != textpid)
2747 ! m_changed |= changeText;
2748 ! m_textpid = textpid;
2750 ! return 0;
2753 ! RESULT eTSMPEGDecoder::setSyncMaster(int who)
2755 ! return -1;
2758 ! RESULT eTSMPEGDecoder::set()
2760 ! return setState();
2763 ! RESULT eTSMPEGDecoder::play()
2765 ! printf("eTSMPEGDecoder play\n");
2766 ! if (m_state == statePlay)
2768 ! if (!m_changed)
2769 ! return 0;
2770 ! } else
2772 ! m_state = statePlay;
2773 ! m_changed |= changeState;
2775 ! return setState();
2778 ! RESULT eTSMPEGDecoder::pause()
2780 ! printf("eTSMPEGDecoder pause\n");
2781 ! if (m_state == statePause)
2782 ! return 0;
2783 ! m_state = statePause;
2784 ! m_changed |= changeState;
2785 ! return setState();
2788 ! RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
2790 ! if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip))
2791 ! return 0;
2793 ! m_state = stateDecoderFastForward;
2794 ! m_ff_sm_ratio = frames_to_skip;
2795 ! m_changed |= changeState;
2796 ! return setState();
2798 ! // return m_video->setFastForward(frames_to_skip);
2801 ! RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
2803 ! if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat))
2804 ! return 0;
2806 ! m_state = stateSlowMotion;
2807 ! m_ff_sm_ratio = repeat;
2808 ! m_changed |= changeState;
2809 ! return setState();
2812 ! RESULT eTSMPEGDecoder::setTrickmode()
2814 ! if (m_state == stateTrickmode)
2815 ! return 0;
2817 ! m_state = stateTrickmode;
2818 ! m_changed |= changeState;
2819 ! return setState();
2822 ! RESULT eTSMPEGDecoder::flush()
2824 ! if (m_audio)
2825 ! m_audio->flush();
2826 ! if (m_video)
2827 ! m_video->flush();
2828 ! return 0;
2831 ! RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
2833 ! if (what == 0) /* auto */
2834 ! what = m_video ? 1 : 2;
2836 ! if (what == 1) /* video */
2838 ! if (m_video)
2839 ! return m_video->getPTS(pts);
2840 ! else
2841 ! return -1;
2844 ! if (what == 2) /* audio */
2846 ! if (m_audio)
2847 ! return m_audio->getPTS(pts);
2848 ! else
2849 ! return -1;
2852 ! return -1;
2855 ! RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
2857 ! m_radio_pic = filename;
2858 ! return 0;
2861 ! RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
2863 ! if (m_decoder == 0)
2865 ! eDebug("showSinglePic %s", filename);
2866 ! int f = open(filename, O_RDONLY);
2867 ! if (f >= 0)
2869 ! struct stat s;
2870 ! size_t written=0;
2871 ! fstat(f, &s);
2872 ! if (m_video_clip_fd == -1)
2873 ! m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY);
2874 ! if (m_video_clip_fd >= 0)
2876 ! bool seq_end_avail = false;
2877 ! size_t pos=0;
2878 ! unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
2879 ! unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 };
2880 ! unsigned char iframe[s.st_size];
2881 ! unsigned char stuffing[8192];
2882 ! int streamtype = VIDEO_STREAMTYPE_MPEG2;
2883 ! memset(stuffing, 0, 8192);
2884 ! read(f, iframe, s.st_size);
2885 ! if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
2886 ! eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
2887 ! if (ioctl(m_video_clip_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
2888 ! eDebug("VIDEO_SET_STREAMTYPE failed(%m)");
2889 ! if (ioctl(m_video_clip_fd, VIDEO_PLAY) < 0)
2890 ! eDebug("VIDEO_PLAY failed (%m)");
2891 ! if (ioctl(m_video_clip_fd, VIDEO_CONTINUE) < 0)
2892 ! eDebug("video: VIDEO_CONTINUE: %m");
2893 ! if (ioctl(m_video_clip_fd, VIDEO_CLEAR_BUFFER) < 0)
2894 ! eDebug("video: VIDEO_CLEAR_BUFFER: %m");
2895 ! while(pos <= (s.st_size-4) && !(seq_end_avail = (!iframe[pos] && !iframe[pos+1] && iframe[pos+2] == 1 && iframe[pos+3] == 0xB7)))
2896 ! ++pos;
2897 ! if ((iframe[3] >> 4) != 0xE) // no pes header
2898 ! write(m_video_clip_fd, pes_header, sizeof(pes_header));
2899 ! else
2900 ! iframe[4] = iframe[5] = 0x00;
2901 ! write(m_video_clip_fd, iframe, s.st_size);
2902 ! if (!seq_end_avail)
2903 ! write(m_video_clip_fd, seq_end, sizeof(seq_end));
2904 ! write(m_video_clip_fd, stuffing, 8192);
2905 ! m_showSinglePicTimer->start(150, true);
2907 ! close(f);
2909 ! else
2911 ! eDebug("couldnt open %s", filename);
2912 ! return -1;
2915 ! else
2917 ! eDebug("only show single pics on first decoder");
2918 ! return -1;
2920 ! return 0;
2923 ! void eTSMPEGDecoder::finishShowSinglePic()
2925 ! if (m_video_clip_fd >= 0)
2927 ! if (ioctl(m_video_clip_fd, VIDEO_STOP, 0) < 0)
2928 ! eDebug("VIDEO_STOP failed (%m)");
2929 ! if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
2930 ! eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
2931 ! close(m_video_clip_fd);
2932 ! m_video_clip_fd = -1;
2936 ! RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
2938 ! conn = new eConnection(this, m_video_event.connect(event));
2939 ! return 0;
2942 diff -crB Enigma2PC/lib/dvb/decoder.h Enigma2PC_orig/lib/dvb/decoder.h
2943 *** Enigma2PC/lib/dvb/decoder.h 2011-11-20 21:56:11.134164129 +0400
2944 --- Enigma2PC_orig/lib/dvb/decoder.h 2011-11-17 00:36:00.000000000 +0400
2945 ***************
2946 *** 1,168 ****
2947 ! #ifndef __decoder_h
2948 ! #define __decoder_h
2950 ! #include <lib/base/object.h>
2951 ! #include <lib/dvb/demux.h>
2952 ! #include <lib/gdi/gxlibdc.h>
2954 ! class eSocketNotifier;
2956 ! class eDVBAudio: public iObject
2958 ! DECLARE_REF(eDVBAudio);
2959 ! private:
2960 ! int m_dev, m_is_freezed;
2961 ! public:
2962 ! enum { aMPEG, aAC3, aDTS, aAAC, aAACHE, aLPCM, aDTSHD };
2963 ! eDVBAudio(int dev);
2964 ! enum { aMonoLeft, aStereo, aMonoRight };
2965 ! void setChannel(int channel);
2966 ! void stop();
2967 ! int startPid(int pid, int type);
2969 ! void flush();
2970 ! void freeze();
2971 ! void unfreeze();
2972 ! int getPTS(pts_t &now);
2973 ! virtual ~eDVBAudio();
2974 ! };
2976 ! class eDVBVideo: public iObject, public Object
2978 ! DECLARE_REF(eDVBVideo);
2979 ! private:
2980 ! int m_dev;
2982 ! int m_is_slow_motion, m_is_fast_forward, m_is_freezed;
2983 ! ePtr<eSocketNotifier> m_sn;
2984 ! void video_event(int what);
2985 ! Signal1<void, struct iTSMPEGDecoder::videoEvent> m_event;
2986 ! int m_progressive;
2987 ! public:
2988 ! enum { MPEG2, MPEG4_H264, MPEG1, MPEG4_Part2, VC1, VC1_SM };
2989 ! eDVBVideo(int dev);
2990 ! void stop();
2991 ! int startPid(int pid, int type=MPEG2);
2993 ! void flush();
2994 ! void freeze();
2995 ! int setSlowMotion(int repeat);
2996 ! int setFastForward(int skip);
2997 ! void unfreeze();
2998 ! int getPTS(pts_t &now);
2999 ! virtual ~eDVBVideo();
3000 ! };
3002 ! class eDVBPCR: public iObject
3004 ! DECLARE_REF(eDVBPCR);
3005 ! private:
3006 ! int m_dev;
3007 ! public:
3008 ! eDVBPCR(int dev);
3009 ! int startPid(int pid);
3010 ! void stop();
3011 ! virtual ~eDVBPCR();
3012 ! };
3014 ! class eDVBTText: public iObject
3016 ! DECLARE_REF(eDVBTText);
3017 ! private:
3018 ! int m_dev;
3019 ! public:
3020 ! eDVBTText(int dev);
3021 ! int startPid(int pid);
3022 ! void stop();
3023 ! virtual ~eDVBTText();
3024 ! };
3026 ! class eTSMPEGDecoder: public Object, public iTSMPEGDecoder
3028 ! DECLARE_REF(eTSMPEGDecoder);
3029 ! private:
3030 ! static int m_pcm_delay;
3031 ! static int m_ac3_delay;
3032 ! static int m_audio_channel;
3033 ! std::string m_radio_pic;
3034 ! ePtr<eDVBAudio> m_audio;
3035 ! ePtr<eDVBVideo> m_video;
3036 ! ePtr<eDVBPCR> m_pcr;
3037 ! ePtr<eDVBTText> m_text;
3038 ! int m_vpid, m_vtype, m_apid, m_atype, m_pcrpid, m_textpid;
3039 ! enum
3041 ! changeVideo = 1,
3042 ! changeAudio = 2,
3043 ! changePCR = 4,
3044 ! changeText = 8,
3045 ! changeState = 16,
3046 ! };
3047 ! int m_changed, m_decoder;
3048 ! int m_state;
3049 ! int m_ff_sm_ratio;
3050 ! int setState();
3052 ! Signal1<void, struct videoEvent> m_video_event;
3053 ! int m_video_clip_fd;
3054 ! ePtr<eTimer> m_showSinglePicTimer;
3055 ! void finishShowSinglePic(); // called by timer
3057 ! public:
3059 ! enum { pidNone = -1 };
3060 ! eTSMPEGDecoder(int decoder);
3061 ! virtual ~eTSMPEGDecoder();
3062 ! RESULT setVideoPID(int vpid, int type);
3063 ! RESULT setAudioPID(int apid, int type);
3064 ! RESULT setAudioChannel(int channel);
3065 ! int getAudioChannel();
3066 ! RESULT setPCMDelay(int delay);
3067 ! int getPCMDelay() { return m_pcm_delay; }
3068 ! RESULT setAC3Delay(int delay);
3069 ! int getAC3Delay() { return m_ac3_delay; }
3070 ! RESULT setSyncPCR(int pcrpid);
3071 ! RESULT setTextPID(int textpid);
3072 ! RESULT setSyncMaster(int who);
3074 ! /*
3075 ! The following states exist:
3077 ! - stop: data source closed, no playback
3078 ! - pause: data source active, decoder paused
3079 ! - play: data source active, decoder consuming
3080 ! - decoder fast forward: data source linear, decoder drops frames
3081 ! - trickmode, highspeed reverse: data source fast forwards / reverses, decoder just displays frames as fast as it can
3082 ! - slow motion: decoder displays frames multiple times
3083 ! */
3084 ! enum {
3085 ! stateStop,
3086 ! statePause,
3087 ! statePlay,
3088 ! stateDecoderFastForward,
3089 ! stateTrickmode,
3090 ! stateSlowMotion
3091 ! };
3092 ! RESULT set(); /* just apply settings, keep state */
3093 ! RESULT play(); /* -> play */
3094 ! RESULT pause(); /* -> pause */
3095 ! RESULT setFastForward(int frames_to_skip); /* -> decoder fast forward */
3096 ! RESULT setSlowMotion(int repeat); /* -> slow motion **/
3097 ! RESULT setTrickmode(); /* -> highspeed fast forward */
3099 ! RESULT flush();
3100 ! RESULT showSinglePic(const char *filename);
3101 ! RESULT setRadioPic(const std::string &filename);
3102 ! /* what 0=auto, 1=video, 2=audio. */
3103 ! RESULT getPTS(int what, pts_t &pts);
3104 ! RESULT connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &connection);
3105 ! int getVideoWidth() { return -1; };
3106 ! int getVideoHeight() { return -1; };
3107 ! int getVideoProgressive() { return -1; };
3108 ! int getVideoFrameRate() { return -1; };
3109 ! int getVideoAspect() { return -1; };
3110 ! static RESULT setHwPCMDelay(int delay);
3111 ! static RESULT setHwAC3Delay(int delay);
3112 ! };
3114 ! #endif
3115 --- 1,168 ----
3116 ! #ifndef __decoder_h
3117 ! #define __decoder_h
3119 ! #include <lib/base/object.h>
3120 ! #include <lib/dvb/demux.h>
3121 ! #include <lib/gdi/gxlibdc.h>
3123 ! class eSocketNotifier;
3125 ! class eDVBAudio: public iObject
3127 ! DECLARE_REF(eDVBAudio);
3128 ! private:
3129 ! int m_dev, m_is_freezed;
3130 ! public:
3131 ! enum { aMPEG, aAC3, aDTS, aAAC, aAACHE, aLPCM, aDTSHD };
3132 ! eDVBAudio(int dev);
3133 ! enum { aMonoLeft, aStereo, aMonoRight };
3134 ! void setChannel(int channel);
3135 ! void stop();
3136 ! int startPid(int pid, int type);
3138 ! void flush();
3139 ! void freeze();
3140 ! void unfreeze();
3141 ! int getPTS(pts_t &now);
3142 ! virtual ~eDVBAudio();
3143 ! };
3145 ! class eDVBVideo: public iObject, public Object
3147 ! DECLARE_REF(eDVBVideo);
3148 ! private:
3149 ! int m_dev;
3151 ! int m_is_slow_motion, m_is_fast_forward, m_is_freezed;
3152 ! ePtr<eSocketNotifier> m_sn;
3153 ! void video_event(int what);
3154 ! Signal1<void, struct iTSMPEGDecoder::videoEvent> m_event;
3155 ! int m_progressive;
3156 ! public:
3157 ! enum { MPEG2, MPEG4_H264, MPEG1, MPEG4_Part2, VC1, VC1_SM };
3158 ! eDVBVideo(int dev);
3159 ! void stop();
3160 ! int startPid(int pid, int type=MPEG2);
3162 ! void flush();
3163 ! void freeze();
3164 ! int setSlowMotion(int repeat);
3165 ! int setFastForward(int skip);
3166 ! void unfreeze();
3167 ! int getPTS(pts_t &now);
3168 ! virtual ~eDVBVideo();
3169 ! };
3171 ! class eDVBPCR: public iObject
3173 ! DECLARE_REF(eDVBPCR);
3174 ! private:
3175 ! int m_dev;
3176 ! public:
3177 ! eDVBPCR(int dev);
3178 ! int startPid(int pid);
3179 ! void stop();
3180 ! virtual ~eDVBPCR();
3181 ! };
3183 ! class eDVBTText: public iObject
3185 ! DECLARE_REF(eDVBTText);
3186 ! private:
3187 ! int m_dev;
3188 ! public:
3189 ! eDVBTText(int dev);
3190 ! int startPid(int pid);
3191 ! void stop();
3192 ! virtual ~eDVBTText();
3193 ! };
3195 ! class eTSMPEGDecoder: public Object, public iTSMPEGDecoder
3197 ! DECLARE_REF(eTSMPEGDecoder);
3198 ! private:
3199 ! static int m_pcm_delay;
3200 ! static int m_ac3_delay;
3201 ! static int m_audio_channel;
3202 ! std::string m_radio_pic;
3203 ! ePtr<eDVBAudio> m_audio;
3204 ! ePtr<eDVBVideo> m_video;
3205 ! ePtr<eDVBPCR> m_pcr;
3206 ! ePtr<eDVBTText> m_text;
3207 ! int m_vpid, m_vtype, m_apid, m_atype, m_pcrpid, m_textpid;
3208 ! enum
3210 ! changeVideo = 1,
3211 ! changeAudio = 2,
3212 ! changePCR = 4,
3213 ! changeText = 8,
3214 ! changeState = 16,
3215 ! };
3216 ! int m_changed, m_decoder;
3217 ! int m_state;
3218 ! int m_ff_sm_ratio;
3219 ! int setState();
3221 ! Signal1<void, struct videoEvent> m_video_event;
3222 ! int m_video_clip_fd;
3223 ! ePtr<eTimer> m_showSinglePicTimer;
3224 ! void finishShowSinglePic(); // called by timer
3226 ! public:
3228 ! enum { pidNone = -1 };
3229 ! eTSMPEGDecoder(int decoder);
3230 ! virtual ~eTSMPEGDecoder();
3231 ! RESULT setVideoPID(int vpid, int type);
3232 ! RESULT setAudioPID(int apid, int type);
3233 ! RESULT setAudioChannel(int channel);
3234 ! int getAudioChannel();
3235 ! RESULT setPCMDelay(int delay);
3236 ! int getPCMDelay() { return m_pcm_delay; }
3237 ! RESULT setAC3Delay(int delay);
3238 ! int getAC3Delay() { return m_ac3_delay; }
3239 ! RESULT setSyncPCR(int pcrpid);
3240 ! RESULT setTextPID(int textpid);
3241 ! RESULT setSyncMaster(int who);
3243 ! /*
3244 ! The following states exist:
3246 ! - stop: data source closed, no playback
3247 ! - pause: data source active, decoder paused
3248 ! - play: data source active, decoder consuming
3249 ! - decoder fast forward: data source linear, decoder drops frames
3250 ! - trickmode, highspeed reverse: data source fast forwards / reverses, decoder just displays frames as fast as it can
3251 ! - slow motion: decoder displays frames multiple times
3252 ! */
3253 ! enum {
3254 ! stateStop,
3255 ! statePause,
3256 ! statePlay,
3257 ! stateDecoderFastForward,
3258 ! stateTrickmode,
3259 ! stateSlowMotion
3260 ! };
3261 ! RESULT set(); /* just apply settings, keep state */
3262 ! RESULT play(); /* -> play */
3263 ! RESULT pause(); /* -> pause */
3264 ! RESULT setFastForward(int frames_to_skip); /* -> decoder fast forward */
3265 ! RESULT setSlowMotion(int repeat); /* -> slow motion **/
3266 ! RESULT setTrickmode(); /* -> highspeed fast forward */
3268 ! RESULT flush();
3269 ! RESULT showSinglePic(const char *filename);
3270 ! RESULT setRadioPic(const std::string &filename);
3271 ! /* what 0=auto, 1=video, 2=audio. */
3272 ! RESULT getPTS(int what, pts_t &pts);
3273 ! RESULT connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &connection);
3274 ! int getVideoWidth() { return -1; };
3275 ! int getVideoHeight() { return -1; };
3276 ! int getVideoProgressive() { return -1; };
3277 ! int getVideoFrameRate() { return -1; };
3278 ! int getVideoAspect() { return -1; };
3279 ! static RESULT setHwPCMDelay(int delay);
3280 ! static RESULT setHwAC3Delay(int delay);
3281 ! };
3283 ! #endif
3284 diff -crB Enigma2PC/lib/gdi/gxlibdc.cpp Enigma2PC_orig/lib/gdi/gxlibdc.cpp
3285 *** Enigma2PC/lib/gdi/gxlibdc.cpp 2011-11-20 21:56:11.150830730 +0400
3286 --- Enigma2PC_orig/lib/gdi/gxlibdc.cpp 2011-11-20 02:53:00.000000000 +0400
3287 ***************
3288 *** 1,356 ****
3289 ! #include <fstream>
3290 ! #include <lib/gdi/gxlibdc.h>
3291 ! #include <lib/actions/action.h>
3292 ! #include <lib/base/init.h>
3293 ! #include <lib/base/init_num.h>
3294 ! #include <lib/base/eenv.h>
3295 ! #include <lib/driver/input_fake.h>
3296 ! #include <lib/driver/rcxlib.h>
3298 ! gXlibDC *gXlibDC::instance;
3299 ! Display *gXlibDC::display;
3300 ! Window gXlibDC::window;
3301 ! int gXlibDC::width, gXlibDC::height;
3302 ! double gXlibDC::pixel_aspect;
3304 ! static const std::string getConfigString(const std::string &key, const std::string &defaultValue)
3306 ! std::string value = defaultValue;
3308 ! // get value from enigma2 settings file
3309 ! std::ifstream in(eEnv::resolve("${sysconfdir}/enigma2/settings").c_str());
3310 ! if (in.good()) {
3311 ! do {
3312 ! std::string line;
3313 ! std::getline(in, line);
3314 ! size_t size = key.size();
3315 ! if (!line.compare(0, size, key) && line[size] == '=') {
3316 ! value = line.substr(size + 1);
3317 ! break;
3319 ! } while (in.good());
3320 ! in.close();
3323 ! return value;
3326 ! static bool getConfigBool(const std::string &key, bool defaultValue)
3328 ! std::string value = getConfigString(key, defaultValue ? "true" : "false");
3329 ! const char *cvalue = value.c_str();
3331 ! if (!strcasecmp(cvalue, "true"))
3332 ! return true;
3333 ! if (!strcasecmp(cvalue, "false"))
3334 ! return false;
3336 ! return defaultValue;
3339 ! gXlibDC::gXlibDC() : m_pump(eApp, 1)
3341 ! double res_h, res_v;
3343 ! umask(0);
3344 ! mknod("/tmp/ENIGMA_FIFO", S_IFIFO|0666, 0);
3346 ! CONNECT(m_pump.recv_msg, gXlibDC::pumpEvent);
3348 ! argb_buffer = NULL;
3349 ! fullscreen = getConfigBool("config.pc.default_fullscreen", false);
3350 ! windowWidth = 720;
3351 ! windowHeight = 576;
3353 ! ASSERT(instance == 0);
3354 ! instance = this;
3356 ! if(!XInitThreads())
3358 ! eFatal("XInitThreads() failed\n");
3359 ! return;
3362 ! if((display = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
3363 ! eFatal("XOpenDisplay() failed.\n");
3364 ! return;
3367 ! screen = XDefaultScreen(display);
3369 ! if (fullscreen) {
3370 ! width = DisplayWidth( display, screen );
3371 ! height = DisplayHeight( display, screen );
3372 ! } else {
3373 ! width = windowWidth;
3374 ! height = windowHeight;
3377 ! XLockDisplay(display);
3378 ! window = XCreateSimpleWindow(display, XDefaultRootWindow(display), 0, 0, windowWidth, windowHeight, 0, 0, 0);
3379 ! XSelectInput (display, window, INPUT_MOTION);
3380 ! XMapRaised(display, window);
3381 ! res_h = (DisplayWidth(display, screen) * 1000 / DisplayWidthMM(display, screen));
3382 ! res_v = (DisplayHeight(display, screen) * 1000 / DisplayHeightMM(display, screen));
3383 ! XSync(display, False);
3384 ! XUnlockDisplay(display);
3386 ! wmDelete=XInternAtom(display, "WM_DELETE_WINDOW", True);
3387 ! XSetWMProtocols(display, window, &wmDelete, 1);
3389 ! printf("Display resolution %d %d\n", DisplayWidth(display, screen), DisplayHeight(display, screen));
3391 ! vis.display = display;
3392 ! vis.screen = screen;
3393 ! vis.d = window;
3394 ! vis.dest_size_cb = dest_size_cb;
3395 ! vis.frame_output_cb = frame_output_cb;
3396 ! vis.user_data = NULL;
3397 ! pixel_aspect = res_v / res_h;
3399 ! if(fabs(pixel_aspect - 1.0) < 0.01)
3400 ! pixel_aspect = 1.0;
3402 ! xineLib = new cXineLib(&vis);
3404 ! setResolution(width, height); // default res
3406 ! run();
3408 ! /*m_surface.type = 0;
3409 ! m_surface.clut.colors = 256;
3410 ! m_surface.clut.data = new gRGB[m_surface.clut.colors];
3412 ! m_pixmap = new gPixmap(&m_surface);
3414 ! memset(m_surface.clut.data, 0, sizeof(*m_surface.clut.data)*m_surface.clut.colors);*/
3417 ! gXlibDC::~gXlibDC()
3419 ! instance = 0;
3421 ! thread_stop = true;
3422 ! kill();
3424 ! if (xineLib) {
3425 ! delete xineLib;
3426 ! xineLib = NULL;
3429 ! XLockDisplay(display);
3430 ! XUnmapWindow(display, window);
3431 ! XDestroyWindow(display, window);
3432 ! XUnlockDisplay(display);
3434 ! XCloseDisplay (display);
3437 ! void gXlibDC::keyEvent(const XKeyEvent &event)
3439 ! eXlibInputDriver *driver = eXlibInputDriver::getInstance();
3441 ! eDebug("SDL Key %s: key=%d", (event.type == KeyPress) ? "Down" : "Up", event.keycode);
3443 ! if (driver)
3444 ! driver->keyPressed(event);
3447 ! void gXlibDC::pumpEvent(const XKeyEvent &event)
3449 ! switch (event.type) {
3450 ! case KeyPress:
3451 ! case KeyRelease:
3452 ! switch (event.keycode) {
3453 ! case 95: // F11
3454 ! if (event.type==KeyPress) {
3455 ! fullscreen_switch();
3457 ! break;
3458 ! case 53: // X
3459 ! if (event.type==KeyPress) {
3460 ! eDebug("Enigma2 Quit");
3461 ! extern void quitMainloop(int exit_code);
3462 ! quitMainloop(0);
3464 ! break;
3465 ! default:
3466 ! keyEvent(event);
3467 ! break;
3469 ! break;
3473 ! /*void gSDLDC::pushEvent(enum event code, void *data1, void *data2)
3475 ! SDL_Event event;
3477 ! event.type = SDL_USEREVENT;
3478 ! event.user.code = code;
3479 ! event.user.data1 = data1;
3480 ! event.user.data2 = data2;
3482 ! SDL_PushEvent(&event);
3483 ! }*/
3485 ! void gXlibDC::exec(const gOpcode *o)
3487 ! switch (o->opcode)
3489 ! case gOpcode::flush:
3490 ! eDebug("FLUSH");
3491 ! xineLib->showOsd();
3492 ! break;
3493 ! default:
3494 ! gDC::exec(o);
3495 ! break;
3499 ! void gXlibDC::setResolution(int xres, int yres)
3501 ! printf("setResolution %d %d\n", xres, yres);
3502 ! windowWidth = xres;
3503 ! windowHeight = yres;
3505 ! if (!fullscreen) {
3506 ! width = xres;
3507 ! height = yres;
3510 ! if (argb_buffer)
3511 ! delete [] argb_buffer;
3512 ! argb_buffer = new uint32_t[windowWidth*windowHeight];
3514 ! xineLib->newOsd(windowWidth, windowHeight, argb_buffer);
3516 ! m_surface.type = 0;
3517 ! m_surface.x = windowWidth;
3518 ! m_surface.y = windowHeight;
3519 ! m_surface.bpp = 32;
3520 ! m_surface.bypp = 4;
3521 ! m_surface.stride = windowWidth*4;
3522 ! m_surface.data = argb_buffer;
3523 ! m_surface.offset = 0;
3525 ! m_pixmap = new gPixmap(&m_surface);
3527 ! updateWindowState();
3530 ! void gXlibDC::updateWindowState() {
3531 ! if (fullscreen) {
3532 ! width = DisplayWidth( display, screen );
3533 ! height = DisplayHeight( display, screen );
3534 ! } else {
3535 ! width = windowWidth;
3536 ! height = windowHeight;
3539 ! XEvent xev;
3540 ! Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
3541 ! Atom fullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
3543 ! memset(&xev, 0, sizeof(xev));
3544 ! xev.type = ClientMessage;
3545 ! xev.xclient.window = window;
3546 ! xev.xclient.message_type = wm_state;
3547 ! xev.xclient.format = 32;
3548 ! xev.xclient.data.l[0] = fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
3549 ! xev.xclient.data.l[1] = fullscreenAtom;
3550 ! xev.xclient.data.l[2] = 0;
3551 ! XSendEvent(display, XDefaultRootWindow(display), False, SubstructureNotifyMask, &xev);
3553 ! if (!fullscreen)
3554 ! XResizeWindow(display, window, windowWidth, windowHeight);
3556 ! XFlush(display);
3558 ! xineLib->updateWindowSize(width, height);
3559 ! xineLib->showOsd();
3562 ! void gXlibDC::fullscreen_switch() {
3563 ! printf("FULLSCREEN EVENT\n");
3564 ! fullscreen ^= 1;
3565 ! updateWindowState();
3568 ! void gXlibDC::evFlip()
3570 ! //SDL_Flip(m_screen);
3573 ! void gXlibDC::thread()
3575 ! hasStarted();
3577 ! int x11_fd = ConnectionNumber(display);
3578 ! thread_stop = false;
3579 ! fd_set in_fds;
3580 ! struct timeval tv;
3581 ! XEvent event;
3583 ! while (!thread_stop) {
3584 ! FD_ZERO(&in_fds);
3585 ! FD_SET(x11_fd, &in_fds);
3587 ! tv.tv_usec = 100000;
3588 ! tv.tv_sec = 0;
3590 ! if (select(x11_fd+1, &in_fds, 0, 0, &tv))
3591 ! printf("Event Received!\n");
3593 ! while(XPending(display))
3595 ! XNextEvent(display, &event);
3596 ! printf("XNextEvent %d\n", event.type);
3597 ! switch(event.type)
3599 ! case KeyPress:
3600 ! case KeyRelease:
3602 ! XKeyEvent& xKeyEvent = (XKeyEvent&)event;
3603 ! m_pump.send(xKeyEvent);
3605 ! break;
3606 ! case ClientMessage:
3607 ! if (event.xclient.data.l[0] == wmDelete) {
3608 ! thread_stop = true;
3609 ! XKeyEvent xKeyEvent;
3610 ! xKeyEvent.type = KeyPress;
3611 ! xKeyEvent.keycode = 53; // X
3612 ! m_pump.send(xKeyEvent);
3614 ! break;
3615 ! case Expose:
3616 ! xineLib->showOsd();
3617 ! break;
3623 ! void gXlibDC::frame_output_cb(void *data, int video_width, int video_height, double video_pixel_aspect,
3624 ! int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect,
3625 ! int *win_x, int *win_y)
3627 ! *dest_x = 0;
3628 ! *dest_y = 0;
3629 ! *win_x = 0;
3630 ! *win_y = 0;
3631 ! *dest_width = gXlibDC::width;
3632 ! *dest_height = gXlibDC::height;
3633 ! *dest_pixel_aspect = gXlibDC::pixel_aspect;
3636 ! void gXlibDC::dest_size_cb(void *data, int video_width, int video_height, double video_pixel_aspect,
3637 ! int *dest_width, int *dest_height, double *dest_pixel_aspect)
3639 ! *dest_width = gXlibDC::width;
3640 ! *dest_height = gXlibDC::height;
3641 ! *dest_pixel_aspect = gXlibDC::pixel_aspect;
3644 ! eAutoInitPtr<gXlibDC> init_gXlibDC(eAutoInitNumbers::graphic-1, "gXlibDC");
3645 --- 1,356 ----
3646 ! #include <fstream>
3647 ! #include <lib/gdi/gxlibdc.h>
3648 ! #include <lib/actions/action.h>
3649 ! #include <lib/base/init.h>
3650 ! #include <lib/base/init_num.h>
3651 ! #include <lib/base/eenv.h>
3652 ! #include <lib/driver/input_fake.h>
3653 ! #include <lib/driver/rcxlib.h>
3655 ! gXlibDC *gXlibDC::instance;
3656 ! Display *gXlibDC::display;
3657 ! Window gXlibDC::window;
3658 ! int gXlibDC::width, gXlibDC::height;
3659 ! double gXlibDC::pixel_aspect;
3660 ! static const std::string getConfigString(const std::string &key, const std::string &defaultValue)
3662 ! std::string value = defaultValue;
3664 ! // get value from enigma2 settings file
3665 ! std::ifstream in(eEnv::resolve("${sysconfdir}/enigma2/settings").c_str());
3666 ! if (in.good()) {
3667 ! do {
3668 ! std::string line;
3669 ! std::getline(in, line);
3670 ! size_t size = key.size();
3671 ! if (!line.compare(0, size, key) && line[size] == '=') {
3672 ! value = line.substr(size + 1);
3673 ! break;
3675 ! } while (in.good());
3676 ! in.close();
3679 ! return value;
3682 ! static bool getConfigBool(const std::string &key, bool defaultValue)
3684 ! std::string value = getConfigString(key, defaultValue ? "true" : "false");
3685 ! const char *cvalue = value.c_str();
3687 ! if (!strcasecmp(cvalue, "true"))
3688 ! return true;
3689 ! if (!strcasecmp(cvalue, "false"))
3690 ! return false;
3692 ! return defaultValue;
3695 ! gXlibDC::gXlibDC() : m_pump(eApp, 1)
3697 ! double res_h, res_v;
3699 ! umask(0);
3700 ! mknod("/tmp/ENIGMA_FIFO", S_IFIFO|0666, 0);
3702 ! CONNECT(m_pump.recv_msg, gXlibDC::pumpEvent);
3704 ! argb_buffer = NULL;
3705 ! fullscreen = getConfigBool("config.pc.default_fullscreen", false);
3706 ! windowWidth = 720;
3707 ! windowHeight = 576;
3709 ! ASSERT(instance == 0);
3710 ! instance = this;
3712 ! if(!XInitThreads())
3714 ! eFatal("XInitThreads() failed\n");
3715 ! return;
3718 ! if((display = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
3719 ! eFatal("XOpenDisplay() failed.\n");
3720 ! return;
3723 ! screen = XDefaultScreen(display);
3725 ! if (fullscreen) {
3726 ! width = DisplayWidth( display, screen );
3727 ! height = DisplayHeight( display, screen );
3728 ! } else {
3729 ! width = windowWidth;
3730 ! height = windowHeight;
3733 ! XLockDisplay(display);
3734 ! window = XCreateSimpleWindow(display, XDefaultRootWindow(display), 0, 0, windowWidth, windowHeight, 0, 0, 0);
3735 ! XSelectInput (display, window, INPUT_MOTION);
3736 ! XMapRaised(display, window);
3737 ! res_h = (DisplayWidth(display, screen) * 1000 / DisplayWidthMM(display, screen));
3738 ! res_v = (DisplayHeight(display, screen) * 1000 / DisplayHeightMM(display, screen));
3739 ! XSync(display, False);
3740 ! XUnlockDisplay(display);
3742 ! wmDelete=XInternAtom(display, "WM_DELETE_WINDOW", True);
3743 ! XSetWMProtocols(display, window, &wmDelete, 1);
3745 ! printf("Display resolution %d %d\n", DisplayWidth(display, screen), DisplayHeight(display, screen));
3747 ! vis.display = display;
3748 ! vis.screen = screen;
3749 ! vis.d = window;
3750 ! vis.dest_size_cb = dest_size_cb;
3751 ! vis.frame_output_cb = frame_output_cb;
3752 ! vis.user_data = NULL;
3753 ! pixel_aspect = res_v / res_h;
3755 ! if(fabs(pixel_aspect - 1.0) < 0.01)
3756 ! pixel_aspect = 1.0;
3758 ! xineLib = new cXineLib(&vis);
3760 ! setResolution(width, height); // default res
3762 ! run();
3764 ! /*m_surface.type = 0;
3765 ! m_surface.clut.colors = 256;
3766 ! m_surface.clut.data = new gRGB[m_surface.clut.colors];
3768 ! m_pixmap = new gPixmap(&m_surface);
3770 ! memset(m_surface.clut.data, 0, sizeof(*m_surface.clut.data)*m_surface.clut.colors);*/
3773 ! gXlibDC::~gXlibDC()
3775 ! instance = 0;
3777 ! thread_stop = true;
3778 ! kill();
3780 ! if (xineLib) {
3781 ! delete xineLib;
3782 ! xineLib = NULL;
3785 ! XLockDisplay(display);
3786 ! XUnmapWindow(display, window);
3787 ! XDestroyWindow(display, window);
3788 ! XUnlockDisplay(display);
3790 ! XCloseDisplay (display);
3793 ! void gXlibDC::keyEvent(const XKeyEvent &event)
3795 ! eXlibInputDriver *driver = eXlibInputDriver::getInstance();
3796 ! xineLib->getVideoFrameRate();
3797 ! eDebug("SDL Key %s: key=%d", (event.type == KeyPress) ? "Down" : "Up", event.keycode);
3799 ! if (driver)
3800 ! driver->keyPressed(event);
3803 ! void gXlibDC::pumpEvent(const XKeyEvent &event)
3805 ! switch (event.type) {
3806 ! case KeyPress:
3807 ! case KeyRelease:
3808 ! switch (event.keycode) {
3809 ! case 95: // F11
3810 ! if (event.type==KeyPress) {
3811 ! fullscreen_switch();
3813 ! break;
3814 ! case 53: // X
3815 ! if (event.type==KeyPress) {
3816 ! eDebug("Enigma2 Quit");
3817 ! extern void quitMainloop(int exit_code);
3818 ! quitMainloop(0);
3820 ! break;
3821 ! default:
3822 ! keyEvent(event);
3823 ! break;
3825 ! break;
3830 ! /*void gSDLDC::pushEvent(enum event code, void *data1, void *data2)
3832 ! SDL_Event event;
3834 ! event.type = SDL_USEREVENT;
3835 ! event.user.code = code;
3836 ! event.user.data1 = data1;
3837 ! event.user.data2 = data2;
3839 ! SDL_PushEvent(&event);
3840 ! }*/
3842 ! void gXlibDC::exec(const gOpcode *o)
3844 ! switch (o->opcode)
3846 ! case gOpcode::flush:
3847 ! eDebug("FLUSH");
3848 ! xineLib->showOsd();
3849 ! break;
3850 ! default:
3851 ! gDC::exec(o);
3852 ! break;
3856 ! void gXlibDC::setResolution(int xres, int yres)
3858 ! printf("setResolution %d %d\n", xres, yres);
3859 ! windowWidth = xres;
3860 ! windowHeight = yres;
3862 ! if (!fullscreen) {
3863 ! width = xres;
3864 ! height = yres;
3867 ! if (argb_buffer)
3868 ! delete [] argb_buffer;
3869 ! argb_buffer = new uint32_t[windowWidth*windowHeight];
3871 ! xineLib->newOsd(windowWidth, windowHeight, argb_buffer);
3873 ! m_surface.type = 0;
3874 ! m_surface.x = windowWidth;
3875 ! m_surface.y = windowHeight;
3876 ! m_surface.bpp = 32;
3877 ! m_surface.bypp = 4;
3878 ! m_surface.stride = windowWidth*4;
3879 ! m_surface.data = argb_buffer;
3880 ! m_surface.offset = 0;
3882 ! m_pixmap = new gPixmap(&m_surface);
3884 ! updateWindowState();
3887 ! void gXlibDC::updateWindowState() {
3888 ! if (fullscreen) {
3889 ! width = DisplayWidth( display, screen );
3890 ! height = DisplayHeight( display, screen );
3891 ! } else {
3892 ! width = windowWidth;
3893 ! height = windowHeight;
3896 ! XEvent xev;
3897 ! Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
3898 ! Atom fullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
3900 ! memset(&xev, 0, sizeof(xev));
3901 ! xev.type = ClientMessage;
3902 ! xev.xclient.window = window;
3903 ! xev.xclient.message_type = wm_state;
3904 ! xev.xclient.format = 32;
3905 ! xev.xclient.data.l[0] = fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
3906 ! xev.xclient.data.l[1] = fullscreenAtom;
3907 ! xev.xclient.data.l[2] = 0;
3908 ! XSendEvent(display, XDefaultRootWindow(display), False, SubstructureNotifyMask, &xev);
3910 ! if (!fullscreen)
3911 ! XResizeWindow(display, window, windowWidth, windowHeight);
3913 ! XFlush(display);
3915 ! xineLib->updateWindowSize(width, height);
3916 ! xineLib->showOsd();
3919 ! void gXlibDC::fullscreen_switch() {
3920 ! printf("FULLSCREEN EVENT\n");
3921 ! fullscreen ^= 1;
3922 ! updateWindowState();
3925 ! void gXlibDC::evFlip()
3927 ! //SDL_Flip(m_screen);
3930 ! void gXlibDC::thread()
3932 ! hasStarted();
3934 ! int x11_fd = ConnectionNumber(display);
3935 ! thread_stop = false;
3936 ! fd_set in_fds;
3937 ! struct timeval tv;
3938 ! XEvent event;
3940 ! while (!thread_stop) {
3941 ! FD_ZERO(&in_fds);
3942 ! FD_SET(x11_fd, &in_fds);
3944 ! tv.tv_usec = 100000;
3945 ! tv.tv_sec = 0;
3947 ! if (select(x11_fd+1, &in_fds, 0, 0, &tv))
3948 ! printf("Event Received!\n");
3950 ! while(XPending(display))
3952 ! XNextEvent(display, &event);
3953 ! printf("XNextEvent %d\n", event.type);
3954 ! switch(event.type)
3956 ! case KeyPress:
3957 ! case KeyRelease:
3959 ! XKeyEvent& xKeyEvent = (XKeyEvent&)event;
3960 ! m_pump.send(xKeyEvent);
3962 ! break;
3963 ! case ClientMessage:
3964 ! if (event.xclient.data.l[0] == wmDelete) {
3965 ! thread_stop = true;
3966 ! XKeyEvent xKeyEvent;
3967 ! xKeyEvent.type = KeyPress;
3968 ! xKeyEvent.keycode = 53; // X
3969 ! m_pump.send(xKeyEvent);
3971 ! break;
3972 ! case Expose:
3973 ! xineLib->showOsd();
3974 ! break;
3980 ! void gXlibDC::frame_output_cb(void *data, int video_width, int video_height, double video_pixel_aspect,
3981 ! int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect,
3982 ! int *win_x, int *win_y)
3984 ! *dest_x = 0;
3985 ! *dest_y = 0;
3986 ! *win_x = 0;
3987 ! *win_y = 0;
3988 ! *dest_width = gXlibDC::width;
3989 ! *dest_height = gXlibDC::height;
3990 ! *dest_pixel_aspect = gXlibDC::pixel_aspect;
3993 ! void gXlibDC::dest_size_cb(void *data, int video_width, int video_height, double video_pixel_aspect,
3994 ! int *dest_width, int *dest_height, double *dest_pixel_aspect)
3996 ! *dest_width = gXlibDC::width;
3997 ! *dest_height = gXlibDC::height;
3998 ! *dest_pixel_aspect = gXlibDC::pixel_aspect;
4001 ! eAutoInitPtr<gXlibDC> init_gXlibDC(eAutoInitNumbers::graphic-1, "gXlibDC");
4002 diff -crB Enigma2PC/lib/gdi/xineLib.cpp Enigma2PC_orig/lib/gdi/xineLib.cpp
4003 *** Enigma2PC/lib/gdi/xineLib.cpp 2011-11-20 21:56:11.150830730 +0400
4004 --- Enigma2PC_orig/lib/gdi/xineLib.cpp 2011-11-20 03:00:00.000000000 +0400
4005 ***************
4006 *** 1,463 ****
4007 ! #include <fstream>
4008 ! #include <lib/gdi/xineLib.h>
4009 ! #include <lib/base/eenv.h>
4011 ! cXineLib *cXineLib::instance;
4013 ! DEFINE_REF(cXineLib);
4015 ! cXineLib::cXineLib(x11_visual_t *vis) : m_pump(eApp, 1) {
4016 ! char configfile[150];
4017 ! char vo_driver[] = "vdpau";
4018 ! char ao_driver[] = "alsa";
4020 ! instance = this;
4021 ! osd = NULL;
4022 ! stream = NULL;
4023 ! end_of_stream = false;
4024 ! videoPlayed = false;
4026 ! printf("XINE-LIB version: %s\n", xine_get_version_string() );
4028 ! xine = xine_new();
4029 ! strcpy(configfile, eEnv::resolve("${datadir}/enigma2/xine.conf").c_str());
4030 ! printf("configfile %s\n", configfile);
4031 ! xine_config_load(xine, configfile);
4032 ! xine_init(xine);
4034 ! if((vo_port = xine_open_video_driver(xine, vo_driver, XINE_VISUAL_TYPE_X11, (void *) vis)) == NULL)
4036 ! printf("I'm unable to initialize '%s' video driver. Giving up.\n", vo_driver);
4037 ! return;
4040 ! ao_port = xine_open_audio_driver(xine , ao_driver, NULL);
4041 ! stream = xine_stream_new(xine, ao_port, vo_port);
4043 ! if ( (!xine_open(stream, eEnv::resolve("${sysconfdir}/tuxbox/logo.mvi").c_str()))
4044 ! || (!xine_play(stream, 0, 0)) ) {
4045 ! return;
4048 ! //setPrebuffer(150000);
4049 ! xine_engine_set_param(xine, XINE_ENGINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG);
4051 ! xine_queue = xine_event_new_queue (stream);
4052 ! xine_event_create_listener_thread(xine_queue, xine_event_handler, this);
4054 ! CONNECT(m_pump.recv_msg, cXineLib::pumpEvent);
4056 ! m_width = 0;
4057 ! m_height = 0;
4058 ! m_framerate = 0;
4059 ! m_aspect = -1;
4060 ! m_windowAspectRatio = 0;
4061 ! m_policy43 = 0;
4062 ! m_policy169 = 0;
4064 ! m_sharpness = 0;
4065 ! m_noise = 0;
4068 ! cXineLib::~cXineLib() {
4069 ! instance = 0;
4071 ! if (stream)
4073 ! xine_stop(stream);
4074 ! xine_close(stream);
4076 ! if (xine_queue)
4078 ! xine_event_dispose_queue(xine_queue);
4079 ! xine_queue = 0;
4082 ! _x_demux_flush_engine(stream);
4084 ! xine_dispose(stream);
4085 ! stream = NULL;
4088 ! if (ao_port)
4089 ! xine_close_audio_driver(xine, ao_port);
4090 ! if (vo_port)
4091 ! xine_close_video_driver(xine, vo_port);
4094 ! void cXineLib::setVolume(int value) {
4095 ! xine_set_param (stream, XINE_PARAM_AUDIO_VOLUME, value);
4098 ! void cXineLib::setVolumeMute(int value) {
4099 ! xine_set_param (stream, XINE_PARAM_AUDIO_MUTE, value==0?0:1);
4102 ! void cXineLib::showOsd() {
4103 ! xine_osd_show_scaled(osd, 0);
4104 ! //stream->osd_renderer->draw_bitmap(osd, (uint8_t*)m_surface.data, 0, 0, 720, 576, temp_bitmap_mapping);
4107 ! void cXineLib::newOsd(int width, int height, uint32_t *argb_buffer) {
4108 ! osdWidth = width;
4109 ! osdHeight = height;
4111 ! if (osd)
4112 ! xine_osd_free(osd);
4114 ! osd = xine_osd_new(stream, 0, 0, osdWidth, osdHeight);
4115 ! xine_osd_set_extent(osd, osdWidth, osdHeight);
4116 ! xine_osd_set_argb_buffer(osd, argb_buffer, 0, 0, osdWidth, osdHeight);
4119 ! void cXineLib::playVideo(void) {
4120 ! //xine_stop(stream);
4121 ! end_of_stream = false;
4122 ! videoPlayed = false;
4124 ! printf("XINE try START !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4125 ! if ( !xine_open(stream, "enigma:/") ) {
4126 ! printf("Unable to open stream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4129 ! setStreamType(1);
4130 ! setStreamType(0);
4132 ! //_x_demux_control_start(stream);
4133 ! //_x_demux_seek(stream, 0, 0, 0);
4135 ! if( !xine_play(stream, 0, 0) ) {
4136 ! printf("Unable to play stream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4138 ! printf("XINE STARTED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4140 ! videoPlayed = true;
4143 ! void cXineLib::stopVideo(void) {
4144 ! xine_stop(stream);
4145 ! end_of_stream = false;
4146 ! videoPlayed = false;
4149 ! void cXineLib::setStreamType(int video) {
4150 ! xine_event_t event;
4152 ! if (video) {
4153 ! event.type = XINE_EVENT_SET_VIDEO_STREAMTYPE;
4154 ! event.data = &videoData;
4155 ! } else {
4156 ! event.type = XINE_EVENT_SET_AUDIO_STREAMTYPE;
4157 ! event.data = &audioData;
4160 ! event.data_length = sizeof (xine_streamtype_data_t);
4162 ! xine_event_send (stream, &event);
4165 ! void cXineLib::setVideoType(int pid, int type) {
4166 ! videoData.pid = pid;
4167 ! videoData.streamtype = type;
4170 ! void cXineLib::setAudioType(int pid, int type) {
4171 ! audioData.pid = pid;
4172 ! audioData.streamtype = type;
4175 ! void cXineLib::setPrebuffer(int prebuffer) {
4176 ! xine_set_param(stream, XINE_PARAM_METRONOM_PREBUFFER, prebuffer);
4179 ! void cXineLib::xine_event_handler(void *user_data, const xine_event_t *event)
4181 ! cXineLib *xineLib = (cXineLib*)user_data;
4182 ! //if (event->type!=15)
4183 ! // printf("I have event %d\n", event->type);
4185 ! switch (event->type)
4187 ! case XINE_EVENT_UI_PLAYBACK_FINISHED:
4188 ! printf("XINE_EVENT_UI_PLAYBACK_FINISHED\n");
4189 ! break;
4190 ! case XINE_EVENT_NBC_STATS:
4191 ! return;
4192 ! case XINE_EVENT_FRAME_FORMAT_CHANGE:
4193 ! printf("XINE_EVENT_FRAME_FORMAT_CHANGE\n");
4195 ! xine_format_change_data_t* data = (xine_format_change_data_t*)event->data;
4196 ! printf("width %d height %d aspect %d\n", data->width, data->height, data->aspect);
4198 ! struct iTSMPEGDecoder::videoEvent evt;
4199 ! evt.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
4200 ! xineLib->m_aspect = evt.aspect = data->aspect;
4201 ! xineLib->m_height = evt.height = data->height;
4202 ! xineLib->m_width = evt.width = data->width;
4203 ! xineLib->m_pump.send(evt);
4205 ! xineLib->adjust_policy();
4207 ! return;
4208 ! case XINE_EVENT_FRAMERATE_CHANGE:
4209 ! printf("XINE_EVENT_FRAMERATE_CHANGE\n");
4211 ! xine_framerate_data_t* data = (xine_framerate_data_t*)event->data;
4212 ! printf("framerate %d \n", data->framerate);
4214 ! struct iTSMPEGDecoder::videoEvent evt;
4215 ! evt.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
4216 ! xineLib->m_framerate = evt.framerate = data->framerate;
4217 ! xineLib->m_pump.send(evt);
4219 ! return;
4220 ! case XINE_EVENT_PROGRESS:
4222 ! xine_progress_data_t* data = (xine_progress_data_t*) event->data;
4223 ! printf("XINE_EVENT_PROGRESS %s %d\n", data->description, data->percent);
4224 ! if (xineLib->videoPlayed && data->percent==0)
4225 ! xineLib->end_of_stream = true;
4227 ! break;
4229 ! default:
4230 ! printf("xine_event_handler(): event->type: %d\n", event->type);
4231 ! return;
4235 ! void cXineLib::pumpEvent(const iTSMPEGDecoder::videoEvent &event)
4237 ! m_event(event);
4240 ! int cXineLib::getVideoWidth()
4242 ! return m_width;
4245 ! int cXineLib::getVideoHeight()
4247 ! return m_height;
4250 ! int cXineLib::getVideoFrameRate()
4252 ! return m_framerate;
4255 ! int cXineLib::getVideoAspect()
4257 ! return m_aspect;
4260 ! RESULT cXineLib::getPTS(pts_t &pts)
4262 ! pts_t* last_pts_l = (pts_t*)vo_port->get_property(vo_port, VO_PROP_LAST_PTS);
4264 ! pts = *last_pts_l;
4266 ! if (pts != 0)
4267 ! return 0;
4269 ! return -1;
4272 ! void cXineLib::setVideoWindow(int window_x, int window_y, int window_width, int window_height)
4274 ! int left = window_x * windowWidth / osdWidth;
4275 ! int top = window_y * windowHeight / osdHeight;
4276 ! int width = window_width * windowWidth / osdWidth;
4277 ! int height = window_height * windowHeight / osdHeight;
4279 ! xine_osd_set_video_window(osd, left, top, width, height);
4280 ! showOsd();
4283 ! void cXineLib::updateWindowSize(int width, int height)
4285 ! windowWidth = width;
4286 ! windowHeight = height;
4289 ! void cXineLib::setDeinterlace(int global, int sd, int hd)
4291 ! vo_port->set_property(vo_port, VO_PROP_DEINTERLACE_SD, sd);
4292 ! vo_port->set_property(vo_port, VO_PROP_DEINTERLACE_HD, hd);
4293 ! vo_port->set_property(vo_port, VO_PROP_INTERLACED, global);
4296 ! void cXineLib::setSDfeatures(int sharpness, int noise)
4298 ! m_sharpness = sharpness;
4299 ! m_noise = noise;
4302 ! void cXineLib::setAspectRatio(int ratio)
4304 ! m_windowAspectRatio = ratio;
4307 ! void cXineLib::setPolicy43(int mode)
4309 ! m_policy43 = mode;
4312 ! void cXineLib::setPolicy169(int mode)
4314 ! m_policy169 = mode;
4317 ! void cXineLib::setZoom(int zoom43_x, int zoom43_y, int zoom169_x, int zoom169_y)
4319 ! m_zoom43_x = zoom43_x;
4320 ! m_zoom43_y = zoom43_y;
4321 ! m_zoom169_x = zoom169_x;
4322 ! m_zoom169_y = zoom169_y;
4325 ! void cXineLib::set_zoom_settings(int x, int y)
4327 ! xine_set_param(stream, XINE_PARAM_VO_ZOOM_X, x);
4328 ! xine_set_param(stream, XINE_PARAM_VO_ZOOM_Y, y);
4331 ! void cXineLib::set_crop_settings(int left, int right, int top, int bottom)
4333 ! xine_set_param(stream, XINE_PARAM_VO_CROP_LEFT, left);
4334 ! xine_set_param(stream, XINE_PARAM_VO_CROP_RIGHT, right);
4335 ! xine_set_param(stream, XINE_PARAM_VO_CROP_TOP, top);
4336 ! xine_set_param(stream, XINE_PARAM_VO_CROP_BOTTOM, bottom);
4339 ! void cXineLib::adjust_policy()
4341 ! switch (m_windowAspectRatio) {
4342 ! case XINE_VO_ASPECT_AUTO:
4343 ! printf("XINE_VO_ASPECT_AUTO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4344 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, 0);
4345 ! set_zoom_settings(100, 100);
4346 ! set_crop_settings(0, 0, 0, 0);
4347 ! break;
4348 ! case XINE_VO_ASPECT_4_3:
4349 ! printf("XINE_VO_ASPECT_4_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4350 ! switch (m_aspect) {
4351 ! case 2: // 4:3
4352 ! printf("m_policy43 %d\n", m_policy43);
4353 ! switch (m_policy43) {
4354 ! case 0: // scale
4355 ! case 1: // nonlinear
4356 ! case 2: // panscan
4357 ! case 3: // pillarbox
4358 ! printf("4:3 SCALE/NONLINEAR/PANSCAN/PILLARBOX\n");
4359 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4360 ! set_zoom_settings(100, 100);
4361 ! set_crop_settings(0, 0, 0, 0);
4362 ! break;
4363 ! case 4: // zoom
4364 ! printf("4:3 ZOOM\n");
4365 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4366 ! set_zoom_settings(m_zoom43_x, m_zoom43_y);
4367 ! set_crop_settings(0, 0, 0, 0);
4368 ! break;
4370 ! break;
4371 ! case 3: // 16:9
4372 ! printf("m_policy169 %d\n", m_policy169);
4373 ! switch (m_policy169) {
4374 ! case 0: // scale
4375 ! printf("16:9 SCALE\n");
4376 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4377 ! set_zoom_settings(100, 100);
4378 ! set_crop_settings(0, 0, 0, 0);
4379 ! break;
4380 ! case 1: // panscan
4381 ! printf("16:9 PANSCAN\n");
4382 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4383 ! set_zoom_settings(100, 100);
4384 ! set_crop_settings(m_width/8, m_width/8, 0, 0);
4385 ! break;
4386 ! case 2: // letterbox
4387 ! printf("16:9 LETTERBOX\n");
4388 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4389 ! set_zoom_settings(100, 100);
4390 ! set_crop_settings(0, 0, 0, 0);
4391 ! break;
4392 ! case 3: // zoom
4393 ! printf("16:9 ZOOM\n");
4394 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4395 ! set_zoom_settings(m_zoom169_x, m_zoom169_y);
4396 ! set_crop_settings(0, 0, 0, 0);
4397 ! break;
4399 ! break;
4401 ! break;
4402 ! case XINE_VO_ASPECT_ANAMORPHIC: //16:9
4403 ! printf("XINE_VO_ASPECT_ANAMORPHIC (16:9) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4404 ! switch (m_aspect) {
4405 ! case 2: // 4:3
4406 ! switch (m_policy43) {
4407 ! case 0: // scale
4408 ! printf("4:3 SCALE\n");
4409 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4410 ! set_zoom_settings(100, 100);
4411 ! set_crop_settings(0, 0, 0, 0);
4412 ! break;
4413 ! case 1: // nonlinear
4414 ! printf("4:3 NONLINEAR\n");
4415 ! break;
4416 ! case 2: // panscan
4417 ! printf("4:3 PANSCAN\n");
4418 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4419 ! set_zoom_settings(100, 100);
4420 ! set_crop_settings(0, 0, m_height/8, m_height/8);
4421 ! break;
4422 ! case 3: // pillarbox
4423 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4424 ! set_zoom_settings(100, 100);
4425 ! printf("4:3 PILLARBOX\n");
4426 ! break;
4427 ! case 4: // zoom
4428 ! printf("4:3 ZOOM\n");
4429 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4430 ! set_zoom_settings(m_zoom43_x, m_zoom43_y);
4431 ! set_crop_settings(0, 0, 0, 0);
4432 ! break;
4434 ! break;
4435 ! case 3: // 16:9
4436 ! printf("m_policy169 %d\n", m_policy169);
4437 ! switch (m_policy169) {
4438 ! case 0: // scale
4439 ! case 1: // panscan
4440 ! case 2: // letterbox
4441 ! printf("16:9 SCALE/PANSCAN/LETTERBOX\n");
4442 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4443 ! set_zoom_settings(100, 100);
4444 ! set_crop_settings(0, 0, 0, 0);
4445 ! break;
4446 ! case 3: // zoom
4447 ! printf("16:9 ZOOM\n");
4448 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4449 ! set_zoom_settings(m_zoom169_x, m_zoom169_y);
4450 ! set_crop_settings(0, 0, 0, 0);
4451 ! break;
4453 ! break;
4455 ! break;
4458 ! if (m_width<=720) // SD channels
4460 ! vo_port->set_property(vo_port, VO_PROP_SHARPNESS, m_sharpness);
4461 ! vo_port->set_property(vo_port, VO_PROP_NOISE_REDUCTION, m_noise);
4463 ! else // HD channels
4465 ! vo_port->set_property(vo_port, VO_PROP_SHARPNESS, 0);
4466 ! vo_port->set_property(vo_port, VO_PROP_NOISE_REDUCTION, 0);
4470 --- 1,558 ----
4471 ! #include <fstream>
4472 ! #include <lib/gdi/xineLib.h>
4473 ! #include <lib/base/eenv.h>
4475 ! cXineLib *cXineLib::instance;
4477 ! DEFINE_REF(cXineLib);
4479 ! cXineLib::cXineLib(x11_visual_t *vis) : m_pump(eApp, 1) {
4480 ! char configfile[150];
4481 ! char vo_driver[] = "vdpau";
4482 ! char ao_driver[] = "alsa";
4484 ! instance = this;
4485 ! osd = NULL;
4486 ! stream = NULL;
4487 ! end_of_stream = false;
4488 ! videoPlayed = false;
4490 ! printf("XINE-LIB version: %s\n", xine_get_version_string() );
4492 ! xine = xine_new();
4493 ! strcpy(configfile, eEnv::resolve("${datadir}/enigma2/xine.conf").c_str());
4494 ! printf("configfile %s\n", configfile);
4495 ! xine_config_load(xine, configfile);
4496 ! xine_init(xine);
4498 ! if((vo_port = xine_open_video_driver(xine, vo_driver, XINE_VISUAL_TYPE_X11, (void *) vis)) == NULL)
4500 ! printf("I'm unable to initialize '%s' video driver. Giving up.\n", vo_driver);
4501 ! return;
4504 ! ao_port = xine_open_audio_driver(xine , ao_driver, NULL);
4505 ! stream = xine_stream_new(xine, ao_port, vo_port);
4507 ! if ( (!xine_open(stream, eEnv::resolve("${sysconfdir}/tuxbox/logo.mvi").c_str()))
4508 ! || (!xine_play(stream, 0, 0)) ) {
4509 ! return;
4512 ! //setPrebuffer(150000);
4513 ! xine_engine_set_param(xine, XINE_ENGINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG);
4515 ! xine_queue = xine_event_new_queue (stream);
4516 ! xine_event_create_listener_thread(xine_queue, xine_event_handler, this);
4518 ! CONNECT(m_pump.recv_msg, cXineLib::pumpEvent);
4520 ! m_width = 0;
4521 ! m_height = 0;
4522 ! m_framerate = 0;
4523 ! m_aspect = -1;
4524 ! m_windowAspectRatio = 0;
4525 ! m_policy43 = 0;
4526 ! m_policy169 = 0;
4528 ! m_sharpness = 0;
4529 ! m_noise = 0;
4532 ! cXineLib::~cXineLib() {
4533 ! instance = 0;
4535 ! if (stream)
4537 ! xine_stop(stream);
4538 ! xine_close(stream);
4540 ! if (xine_queue)
4542 ! xine_event_dispose_queue(xine_queue);
4543 ! xine_queue = 0;
4546 ! _x_demux_flush_engine(stream);
4548 ! xine_dispose(stream);
4549 ! stream = NULL;
4552 ! if (ao_port)
4553 ! xine_close_audio_driver(xine, ao_port);
4554 ! if (vo_port)
4555 ! xine_close_video_driver(xine, vo_port);
4558 ! void cXineLib::setVolume(int value) {
4559 ! // xine_set_param (stream, XINE_PARAM_AUDIO_VOLUME, value);
4560 ! xine_set_param (stream, XINE_PARAM_AUDIO_AMP_LEVEL , value);
4563 ! void cXineLib::setVolumeMute(int value) {
4564 ! // xine_set_param (stream, XINE_PARAM_AUDIO_MUTE, value==0?0:1);
4565 ! xine_set_param(stream, XINE_PARAM_AUDIO_AMP_MUTE, value==0?0:1);
4568 ! void cXineLib::showOsd() {
4569 ! xine_osd_show_scaled(osd, 0);
4570 ! //stream->osd_renderer->draw_bitmap(osd, (uint8_t*)m_surface.data, 0, 0, 720, 576, temp_bitmap_mapping);
4573 ! void cXineLib::newOsd(int width, int height, uint32_t *argb_buffer) {
4574 ! osdWidth = width;
4575 ! osdHeight = height;
4577 ! if (osd)
4578 ! xine_osd_free(osd);
4580 ! osd = xine_osd_new(stream, 0, 0, osdWidth, osdHeight);
4581 ! xine_osd_set_extent(osd, osdWidth, osdHeight);
4582 ! xine_osd_set_argb_buffer(osd, argb_buffer, 0, 0, osdWidth, osdHeight);
4585 ! void cXineLib::playVideo(void) {
4586 ! xine_stop(stream);
4587 ! end_of_stream = false;
4588 ! videoPlayed = false;
4590 ! printf("XINE try START !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4591 ! if ( !xine_open(stream, "enigma:/") ) {
4592 ! printf("Unable to open stream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4595 ! // setStreamType(1);
4596 ! // setStreamType(0);
4597 ! xine_pids_data_t data;
4598 ! xine_event_t event;
4599 ! event.type = XINE_EVENT_PIDS_CHANGE;
4600 ! data.vpid = videoData.pid;
4601 ! data.apid = audioData.pid;
4602 ! event.data = &data;
4603 ! event.data_length = sizeof (xine_pids_data_t);
4605 ! printf ("input_dvb: sending event\n");
4607 ! xine_event_send (stream, &event);
4608 ! setStreamType(1);
4609 ! setStreamType(0);
4610 ! //_x_demux_control_start(stream);
4611 ! //_x_demux_seek(stream, 0, 0, 0);
4613 ! if( !xine_play(stream, 0, 0) ) {
4614 ! printf("Unable to play stream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4616 ! printf("XINE STARTED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4618 ! videoPlayed = true;
4621 ! void cXineLib::stopVideo(void) {
4622 ! xine_stop(stream);
4623 ! xine_close (stream);
4624 ! end_of_stream = false;
4625 ! videoPlayed = false;
4628 ! void cXineLib::setStreamType(int video) {
4629 ! xine_event_t event;
4631 ! if (video==1) {
4632 ! event.type = XINE_EVENT_SET_VIDEO_STREAMTYPE;
4633 ! event.data = &videoData;
4634 ! } else {
4635 ! event.type = XINE_EVENT_SET_AUDIO_STREAMTYPE;
4636 ! event.data = &audioData;
4639 ! event.data_length = sizeof (xine_streamtype_data_t);
4641 ! xine_event_send (stream, &event);
4644 ! void cXineLib::setVideoType(int pid, int type) {
4645 ! videoData.pid = pid;
4646 ! videoData.streamtype = type;
4649 ! //////////////////////7
4650 ! void cXineLib::FilmVideo(char *mrl) {
4651 ! ASSERT(stream);
4653 ! if (!xine_open(stream, mrl))
4655 ! eWarning("xine_open failed!");
4656 ! return ;
4659 ! if (!xine_play(stream, 0, 0))
4661 ! eWarning("xine_play failed!");
4662 ! return ;
4664 ! videoPlayed = true;
4667 ! int
4668 ! cXineLib::VideoPause()
4670 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
4671 ! return 1;
4675 ! int
4676 ! cXineLib::VideoResume()
4678 ! int ret;
4679 ! /* Resume the playback. */
4680 ! ret = xine_get_param(stream, XINE_PARAM_SPEED);
4681 ! if( ret != XINE_SPEED_NORMAL ){
4682 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
4684 ! return 1;
4687 ! int
4688 ! cXineLib::VideoGeriT(pts_t Sar)
4689 ! {// 10 saniye Geri Sarma
4690 ! pts_t geriSar;
4691 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
4692 ! VideoPosisyon();
4693 ! geriSar=Vpos+Sar;
4694 ! printf("%d---Vpos=%d---Sar=%d",geriSar,Vpos,Sar);
4695 ! if (geriSar<0) geriSar=0;
4696 ! xine_play(stream, 0, geriSar);
4697 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
4698 ! return 1;
4701 ! int
4702 ! cXineLib::VideoIleriF()
4704 ! int ret;
4705 ! /* Slow the playback. */
4706 ! ret = xine_get_param(stream, XINE_PARAM_SPEED);
4707 ! if( ret != XINE_EVENT_INPUT_RIGHT){
4708 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_EVENT_INPUT_RIGHT);
4710 ! return 1;
4713 ! int
4714 ! cXineLib::VideoPosisyon()
4716 ! xine_get_pos_length (stream, &VposStream, &Vpos, &Vlength);
4717 ! return 1;
4719 ! /*
4720 ! XINE_SPEED_SLOW_4
4721 ! XINE_SPEED_SLOW_2
4722 ! XINE_SPEED_NORMAL
4723 ! XINE_SPEED_FAST_2
4724 ! XINE_SPEED_FAST_4
4725 ! XINE_FINE_SPEED_NORMAL
4726 ! */
4727 ! /////////////////////
4729 ! void cXineLib::setAudioType(int pid, int type) {
4730 ! audioData.pid = pid;
4731 ! audioData.streamtype = type;
4734 ! void cXineLib::setPrebuffer(int prebuffer) {
4735 ! xine_set_param(stream, XINE_PARAM_METRONOM_PREBUFFER, prebuffer);
4738 ! void cXineLib::xine_event_handler(void *user_data, const xine_event_t *event)
4740 ! cXineLib *xineLib = (cXineLib*)user_data;
4741 ! //if (event->type!=15)
4742 ! // printf("I have event %d\n", event->type);
4744 ! switch (event->type)
4746 ! case XINE_EVENT_UI_PLAYBACK_FINISHED:
4747 ! printf("XINE_EVENT_UI_PLAYBACK_FINISHED\n");
4748 ! break;
4749 ! case XINE_EVENT_NBC_STATS:
4750 ! return;
4751 ! case XINE_EVENT_FRAME_FORMAT_CHANGE:
4752 ! printf("XINE_EVENT_FRAME_FORMAT_CHANGE\n");
4754 ! xine_format_change_data_t* data = (xine_format_change_data_t*)event->data;
4755 ! printf("width %d height %d aspect %d\n", data->width, data->height, data->aspect);
4757 ! struct iTSMPEGDecoder::videoEvent evt;
4758 ! evt.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
4759 ! xineLib->m_aspect = evt.aspect = data->aspect;
4760 ! xineLib->m_height = evt.height = data->height;
4761 ! xineLib->m_width = evt.width = data->width;
4762 ! xineLib->m_pump.send(evt);
4764 ! xineLib->adjust_policy();
4766 ! return;
4767 ! case XINE_EVENT_FRAMERATE_CHANGE:
4768 ! printf("XINE_EVENT_FRAMERATE_CHANGE\n");
4770 ! xine_framerate_data_t* data = (xine_framerate_data_t*)event->data;
4771 ! printf("framerate %d \n", data->framerate);
4773 ! struct iTSMPEGDecoder::videoEvent evt;
4774 ! evt.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
4775 ! xineLib->m_framerate = evt.framerate = data->framerate;
4776 ! xineLib->m_pump.send(evt);
4778 ! return;
4779 ! case XINE_EVENT_PROGRESS:
4781 ! xine_progress_data_t* data = (xine_progress_data_t*) event->data;
4782 ! printf("XINE_EVENT_PROGRESS %s %d\n", data->description, data->percent);
4783 ! if (xineLib->videoPlayed && data->percent==0)
4784 ! xineLib->end_of_stream = true;
4786 ! break;
4788 ! default:
4789 ! printf("xine_event_handler(): event->type: %d\n", event->type);
4790 ! return;
4794 ! void cXineLib::pumpEvent(const iTSMPEGDecoder::videoEvent &event)
4796 ! m_event(event);
4799 ! int cXineLib::getVideoWidth()
4801 ! return m_width;
4804 ! int cXineLib::getVideoHeight()
4806 ! return m_height;
4809 ! int cXineLib::getVideoFrameRate()
4811 ! return m_framerate;
4814 ! int cXineLib::getVideoAspect()
4816 ! return m_aspect;
4819 ! RESULT cXineLib::getPTS(pts_t &pts)
4821 ! pts_t* last_pts_l = (pts_t*)vo_port->get_property(vo_port, VO_PROP_LAST_PTS);
4823 ! pts = *last_pts_l;
4825 ! if (pts != 0)
4826 ! return 0;
4828 ! return -1;
4831 ! void cXineLib::setVideoWindow(int window_x, int window_y, int window_width, int window_height)
4833 ! int left = window_x * windowWidth / osdWidth;
4834 ! int top = window_y * windowHeight / osdHeight;
4835 ! int width = window_width * windowWidth / osdWidth;
4836 ! int height = window_height * windowHeight / osdHeight;
4838 ! xine_osd_set_video_window(osd, left, top, width, height);
4839 ! showOsd();
4842 ! void cXineLib::updateWindowSize(int width, int height)
4844 ! windowWidth = width;
4845 ! windowHeight = height;
4848 ! void cXineLib::setDeinterlace(int global, int sd, int hd)
4850 ! vo_port->set_property(vo_port, VO_PROP_DEINTERLACE_SD, sd);
4851 ! vo_port->set_property(vo_port, VO_PROP_DEINTERLACE_HD, hd);
4852 ! vo_port->set_property(vo_port, VO_PROP_INTERLACED, global);
4855 ! void cXineLib::setSDfeatures(int sharpness, int noise)
4857 ! m_sharpness = sharpness;
4858 ! m_noise = noise;
4861 ! void cXineLib::setAspectRatio(int ratio)
4863 ! m_windowAspectRatio = ratio;
4866 ! void cXineLib::setPolicy43(int mode)
4868 ! m_policy43 = mode;
4871 ! void cXineLib::setPolicy169(int mode)
4873 ! m_policy169 = mode;
4876 ! void cXineLib::setZoom(int zoom43_x, int zoom43_y, int zoom169_x, int zoom169_y)
4878 ! m_zoom43_x = zoom43_x;
4879 ! m_zoom43_y = zoom43_y;
4880 ! m_zoom169_x = zoom169_x;
4881 ! m_zoom169_y = zoom169_y;
4884 ! void cXineLib::set_zoom_settings(int x, int y)
4886 ! xine_set_param(stream, XINE_PARAM_VO_ZOOM_X, x);
4887 ! xine_set_param(stream, XINE_PARAM_VO_ZOOM_Y, y);
4890 ! void cXineLib::set_crop_settings(int left, int right, int top, int bottom)
4892 ! xine_set_param(stream, XINE_PARAM_VO_CROP_LEFT, left);
4893 ! xine_set_param(stream, XINE_PARAM_VO_CROP_RIGHT, right);
4894 ! xine_set_param(stream, XINE_PARAM_VO_CROP_TOP, top);
4895 ! xine_set_param(stream, XINE_PARAM_VO_CROP_BOTTOM, bottom);
4898 ! void cXineLib::adjust_policy()
4900 ! switch (m_windowAspectRatio) {
4901 ! case XINE_VO_ASPECT_AUTO:
4902 ! printf("XINE_VO_ASPECT_AUTO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4903 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, 0);
4904 ! set_zoom_settings(100, 100);
4905 ! set_crop_settings(0, 0, 0, 0);
4906 ! break;
4907 ! case XINE_VO_ASPECT_4_3:
4908 ! printf("XINE_VO_ASPECT_4_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4909 ! switch (m_aspect) {
4910 ! case 2: // 4:3
4911 ! printf("m_policy43 %d\n", m_policy43);
4912 ! switch (m_policy43) {
4913 ! case 0: // scale
4914 ! case 1: // nonlinear
4915 ! case 2: // panscan
4916 ! case 3: // pillarbox
4917 ! printf("4:3 SCALE/NONLINEAR/PANSCAN/PILLARBOX\n");
4918 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4919 ! set_zoom_settings(100, 100);
4920 ! set_crop_settings(0, 0, 0, 0);
4921 ! break;
4922 ! case 4: // zoom
4923 ! printf("4:3 ZOOM\n");
4924 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4925 ! set_zoom_settings(m_zoom43_x, m_zoom43_y);
4926 ! set_crop_settings(0, 0, 0, 0);
4927 ! break;
4929 ! break;
4930 ! case 3: // 16:9
4931 ! printf("m_policy169 %d\n", m_policy169);
4932 ! switch (m_policy169) {
4933 ! case 0: // scale
4934 ! printf("16:9 SCALE\n");
4935 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4936 ! set_zoom_settings(100, 100);
4937 ! set_crop_settings(0, 0, 0, 0);
4938 ! break;
4939 ! case 1: // panscan
4940 ! printf("16:9 PANSCAN\n");
4941 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4942 ! set_zoom_settings(100, 100);
4943 ! set_crop_settings(m_width/8, m_width/8, 0, 0);
4944 ! break;
4945 ! case 2: // letterbox
4946 ! printf("16:9 LETTERBOX\n");
4947 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4948 ! set_zoom_settings(100, 100);
4949 ! set_crop_settings(0, 0, 0, 0);
4950 ! break;
4951 ! case 3: // zoom
4952 ! printf("16:9 ZOOM\n");
4953 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4954 ! set_zoom_settings(m_zoom169_x, m_zoom169_y);
4955 ! set_crop_settings(0, 0, 0, 0);
4956 ! break;
4958 ! break;
4960 ! break;
4961 ! case XINE_VO_ASPECT_ANAMORPHIC: //16:9
4962 ! printf("XINE_VO_ASPECT_ANAMORPHIC (16:9) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4963 ! switch (m_aspect) {
4964 ! case 2: // 4:3
4965 ! switch (m_policy43) {
4966 ! case 0: // scale
4967 ! printf("4:3 SCALE\n");
4968 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4969 ! set_zoom_settings(100, 100);
4970 ! set_crop_settings(0, 0, 0, 0);
4971 ! break;
4972 ! case 1: // nonlinear
4973 ! printf("4:3 NONLINEAR\n");
4974 ! break;
4975 ! case 2: // panscan
4976 ! printf("4:3 PANSCAN\n");
4977 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
4978 ! set_zoom_settings(100, 100);
4979 ! set_crop_settings(0, 0, m_height/8, m_height/8);
4980 ! break;
4981 ! case 3: // pillarbox
4982 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_4_3);
4983 ! set_zoom_settings(100, 100);
4984 ! printf("4:3 PILLARBOX\n");
4985 ! break;
4986 ! case 4: // zoom
4987 ! printf("4:3 ZOOM\n");
4988 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
4989 ! set_zoom_settings(m_zoom43_x, m_zoom43_y);
4990 ! set_crop_settings(0, 0, 0, 0);
4991 ! break;
4993 ! break;
4994 ! case 3: // 16:9
4995 ! printf("m_policy169 %d\n", m_policy169);
4996 ! switch (m_policy169) {
4997 ! case 0: // scale
4998 ! case 1: // panscan
4999 ! case 2: // letterbox
5000 ! printf("16:9 SCALE/PANSCAN/LETTERBOX\n");
5001 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_ANAMORPHIC);
5002 ! set_zoom_settings(100, 100);
5003 ! set_crop_settings(0, 0, 0, 0);
5004 ! break;
5005 ! case 3: // zoom
5006 ! printf("16:9 ZOOM\n");
5007 ! xine_set_param(stream, XINE_PARAM_VO_ASPECT_RATIO, XINE_VO_ASPECT_AUTO);
5008 ! set_zoom_settings(m_zoom169_x, m_zoom169_y);
5009 ! set_crop_settings(0, 0, 0, 0);
5010 ! break;
5012 ! break;
5014 ! break;
5017 ! if (m_width<=720) // SD channels
5019 ! vo_port->set_property(vo_port, VO_PROP_SHARPNESS, m_sharpness);
5020 ! vo_port->set_property(vo_port, VO_PROP_NOISE_REDUCTION, m_noise);
5022 ! else // HD channels
5024 ! vo_port->set_property(vo_port, VO_PROP_SHARPNESS, 0);
5025 ! vo_port->set_property(vo_port, VO_PROP_NOISE_REDUCTION, 0);
5029 diff -crB Enigma2PC/lib/gdi/xineLib.h Enigma2PC_orig/lib/gdi/xineLib.h
5030 *** Enigma2PC/lib/gdi/xineLib.h 2011-11-20 21:56:11.154164050 +0400
5031 --- Enigma2PC_orig/lib/gdi/xineLib.h 2011-11-20 02:55:00.000000000 +0400
5032 ***************
5033 *** 1,80 ****
5034 ! #ifndef __lib_gdi_xineLib_h
5035 ! #define __lib_gdi_xineLib_h
5037 ! #include <lib/gdi/gpixmap.h>
5038 ! #include <xine.h>
5039 ! #include <xine/xineutils.h>
5040 ! #include <xine/xine_internal.h>
5041 ! #include <lib/dvb/idvb.h>
5042 ! #include <lib/base/message.h>
5044 ! class cXineLib : public Object {
5045 ! DECLARE_REF(cXineLib);
5046 ! private:
5047 ! static cXineLib *instance;
5049 ! xine_t *xine;
5050 ! xine_stream_t *stream;
5051 ! xine_video_port_t *vo_port;
5052 ! xine_audio_port_t *ao_port;
5053 ! xine_osd_t *osd;
5054 ! xine_event_queue_t *xine_queue;
5056 ! xine_streamtype_data_t videoData, audioData;
5058 ! bool videoPlayed;
5059 ! int osdWidth, osdHeight;
5060 ! int windowWidth, windowHeight;
5062 ! int m_width, m_height, m_framerate, m_aspect, m_progressive;
5063 ! int m_windowAspectRatio, m_policy43, m_policy169;
5064 ! int m_zoom43_x, m_zoom43_y, m_zoom169_x, m_zoom169_y;
5065 ! int m_sharpness, m_noise;
5067 ! void setStreamType(int video);
5069 ! static void xine_event_handler(void *user_data, const xine_event_t *event);
5071 ! eFixedMessagePump<iTSMPEGDecoder::videoEvent> m_pump;
5072 ! void pumpEvent(const iTSMPEGDecoder::videoEvent &event);
5074 ! void set_zoom_settings(int x, int y);
5075 ! void set_crop_settings(int left, int right, int top, int bottom);
5076 ! public:
5077 ! bool end_of_stream;
5079 ! cXineLib(x11_visual_t *vis);
5080 ! virtual ~cXineLib();
5082 ! static cXineLib *getInstance() { return instance; }
5084 ! void setPrebuffer(int prebuffer);
5085 ! void setVolume(int value);
5086 ! void setVolumeMute(int value);
5087 ! void showOsd();
5088 ! void newOsd(int width, int height, uint32_t *argb_buffer);
5089 ! void playVideo(void);
5090 ! void stopVideo(void);
5091 ! void setVideoType(int pid, int type);
5092 ! void setAudioType(int pid, int type);
5094 ! Signal1<void, struct iTSMPEGDecoder::videoEvent> m_event;
5096 ! int getVideoWidth();
5097 ! int getVideoHeight();
5098 ! int getVideoFrameRate();
5099 ! int getVideoAspect();
5100 ! void adjust_policy();
5101 ! RESULT getPTS(pts_t &pts);
5102 ! void setVideoWindow(int window_x, int window_y, int window_width, int window_height);
5103 ! void updateWindowSize(int width, int height);
5105 ! void setDeinterlace(int global, int sd, int hd);
5106 ! void setSDfeatures(int sharpness, int noise);
5107 ! void setAspectRatio(int ratio);
5108 ! void setPolicy43(int mode);
5109 ! void setPolicy169(int mode);
5110 ! void setZoom(int zoom43_x, int zoom43_y, int zoom169_x, int zoom169_y);
5111 ! };
5113 ! #endif
5114 --- 1,92 ----
5115 ! #ifndef __lib_gdi_xineLib_h
5116 ! #define __lib_gdi_xineLib_h
5118 ! #include <lib/gdi/gpixmap.h>
5119 ! #include <xine.h>
5120 ! #include <xine/xineutils.h>
5121 ! #include <xine/xine_internal.h>
5122 ! #include <lib/dvb/idvb.h>
5123 ! #include <lib/base/message.h>
5125 ! class cXineLib : public Object {
5126 ! DECLARE_REF(cXineLib);
5127 ! private:
5128 ! static cXineLib *instance;
5130 ! xine_t *xine;
5131 ! xine_stream_t *stream;
5132 ! xine_video_port_t *vo_port;
5133 ! xine_audio_port_t *ao_port;
5134 ! xine_osd_t *osd;
5135 ! xine_event_queue_t *xine_queue;
5137 ! xine_streamtype_data_t videoData, audioData;
5139 ! bool videoPlayed;
5140 ! int osdWidth, osdHeight;
5141 ! int windowWidth, windowHeight;
5143 ! int m_width, m_height, m_framerate, m_aspect, m_progressive;
5144 ! int m_windowAspectRatio, m_policy43, m_policy169;
5145 ! int m_zoom43_x, m_zoom43_y, m_zoom169_x, m_zoom169_y;
5146 ! int m_sharpness, m_noise;
5148 ! void setStreamType(int video);
5150 ! static void xine_event_handler(void *user_data, const xine_event_t *event);
5152 ! eFixedMessagePump<iTSMPEGDecoder::videoEvent> m_pump;
5153 ! void pumpEvent(const iTSMPEGDecoder::videoEvent &event);
5155 ! void set_zoom_settings(int x, int y);
5156 ! void set_crop_settings(int left, int right, int top, int bottom);
5157 ! public:
5158 ! bool end_of_stream;
5160 ! cXineLib(x11_visual_t *vis);
5161 ! virtual ~cXineLib();
5163 ! static cXineLib *getInstance() { return instance; }
5165 ! void setPrebuffer(int prebuffer);
5166 ! void setVolume(int value);
5167 ! void setVolumeMute(int value);
5168 ! void showOsd();
5169 ! void newOsd(int width, int height, uint32_t *argb_buffer);
5170 ! void playVideo(void);
5171 ! void stopVideo(void);
5172 ! void setVideoType(int pid, int type);
5173 ! void setAudioType(int pid, int type);
5175 ! //////////////////////////////
5176 ! void FilmVideo(char *mrl);
5177 ! int VideoPause();
5178 ! int VideoResume();
5179 ! int VideoPosisyon();
5180 ! int VideoIleriF();
5181 ! int VposStream;
5182 ! int Vpos;
5183 ! int Vlength;
5184 ! int VideoGeriT(pts_t Sar);
5185 ! ///////////////////////
5187 ! Signal1<void, struct iTSMPEGDecoder::videoEvent> m_event;
5189 ! int getVideoWidth();
5190 ! int getVideoHeight();
5191 ! int getVideoFrameRate();
5192 ! int getVideoAspect();
5193 ! void adjust_policy();
5194 ! RESULT getPTS(pts_t &pts);
5195 ! void setVideoWindow(int window_x, int window_y, int window_width, int window_height);
5196 ! void updateWindowSize(int width, int height);
5198 ! void setDeinterlace(int global, int sd, int hd);
5199 ! void setSDfeatures(int sharpness, int noise);
5200 ! void setAspectRatio(int ratio);
5201 ! void setPolicy43(int mode);
5202 ! void setPolicy169(int mode);
5203 ! void setZoom(int zoom43_x, int zoom43_y, int zoom169_x, int zoom169_y);
5204 ! };
5206 ! #endif
5207 diff -crB Enigma2PC/lib/service/servicedvb.cpp Enigma2PC_orig/lib/service/servicedvb.cpp
5208 *** Enigma2PC/lib/service/servicedvb.cpp 2011-11-20 21:56:11.260830302 +0400
5209 --- Enigma2PC_orig/lib/service/servicedvb.cpp 2011-11-20 04:14:00.000000000 +0400
5210 ***************
5211 *** 1,3187 ****
5212 ! #include <lib/base/eerror.h>
5213 ! #include <lib/base/object.h>
5214 ! #include <string>
5215 ! #include <lib/service/servicedvb.h>
5216 ! #include <lib/service/service.h>
5217 ! #include <lib/base/estring.h>
5218 ! #include <lib/base/init_num.h>
5219 ! #include <lib/base/init.h>
5220 ! #include <lib/dvb/dvb.h>
5221 ! #include <lib/dvb/db.h>
5222 ! #include <lib/dvb/decoder.h>
5224 ! #include <lib/components/file_eraser.h>
5225 ! #include <lib/service/servicedvbrecord.h>
5226 ! #include <lib/service/event.h>
5227 ! #include <lib/dvb/metaparser.h>
5228 ! #include <lib/dvb/tstools.h>
5229 ! #include <lib/python/python.h>
5230 ! #include <lib/base/nconfig.h> // access to python config
5232 ! /* for subtitles */
5233 ! #include <lib/gui/esubtitle.h>
5235 ! #include <sys/vfs.h>
5236 ! #include <sys/stat.h>
5238 ! #include <byteswap.h>
5239 ! #include <netinet/in.h>
5241 ! #ifndef BYTE_ORDER
5242 ! #error no byte order defined!
5243 ! #endif
5245 ! class eStaticServiceDVBInformation: public iStaticServiceInformation
5247 ! DECLARE_REF(eStaticServiceDVBInformation);
5248 ! public:
5249 ! RESULT getName(const eServiceReference &ref, std::string &name);
5250 ! int getLength(const eServiceReference &ref);
5251 ! int isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
5252 ! PyObject *getInfoObject(const eServiceReference &ref, int);
5253 ! };
5255 ! DEFINE_REF(eStaticServiceDVBInformation);
5257 ! RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
5259 ! eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
5260 ! if ( !ref.name.empty() )
5262 ! if (service.getParentTransportStreamID().get()) // linkage subservice
5264 ! ePtr<iServiceHandler> service_center;
5265 ! if (!eServiceCenter::getInstance(service_center))
5267 ! eServiceReferenceDVB parent = service;
5268 ! parent.setTransportStreamID( service.getParentTransportStreamID() );
5269 ! parent.setServiceID( service.getParentServiceID() );
5270 ! parent.setParentTransportStreamID(eTransportStreamID(0));
5271 ! parent.setParentServiceID(eServiceID(0));
5272 ! parent.name="";
5273 ! ePtr<iStaticServiceInformation> service_info;
5274 ! if (!service_center->info(parent, service_info))
5276 ! if (!service_info->getName(parent, name))
5277 ! name=buildShortName(name) + " - ";
5281 ! else
5282 ! name="";
5283 ! name += ref.name;
5284 ! return 0;
5286 ! else
5287 ! return -1;
5290 ! int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
5292 ! return -1;
5295 ! int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore)
5297 ! ePtr<eDVBResourceManager> res_mgr;
5298 ! if ( eDVBResourceManager::getInstance( res_mgr ) )
5299 ! eDebug("isPlayable... no res manager!!");
5300 ! else
5302 ! eDVBChannelID chid, chid_ignore;
5303 ! ((const eServiceReferenceDVB&)ref).getChannelID(chid);
5304 ! ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
5305 ! return res_mgr->canAllocateChannel(chid, chid_ignore);
5307 ! return false;
5310 ! extern void PutToDict(ePyObject &dict, const char*key, long value); // defined in dvb/frontend.cpp
5311 ! extern void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm); // defined in dvb/frontend.cpp
5312 ! extern void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm); // defined in dvb/frontend.cpp
5313 ! extern void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm); // defined in dvb/frontend.cpp
5315 ! PyObject *eStaticServiceDVBInformation::getInfoObject(const eServiceReference &r, int what)
5317 ! if (r.type == eServiceReference::idDVB)
5319 ! const eServiceReferenceDVB &ref = (const eServiceReferenceDVB&)r;
5320 ! switch(what)
5322 ! case iServiceInformation::sTransponderData:
5324 ! ePtr<eDVBResourceManager> res;
5325 ! if (!eDVBResourceManager::getInstance(res))
5327 ! ePtr<iDVBChannelList> db;
5328 ! if (!res->getChannelList(db))
5330 ! eDVBChannelID chid;
5331 ! ref.getChannelID(chid);
5332 ! ePtr<iDVBFrontendParameters> feparm;
5333 ! if (!db->getChannelFrontendData(chid, feparm))
5335 ! int system;
5336 ! if (!feparm->getSystem(system))
5338 ! ePyObject dict = PyDict_New();
5339 ! switch(system)
5341 ! case iDVBFrontend::feSatellite:
5343 ! eDVBFrontendParametersSatellite s;
5344 ! feparm->getDVBS(s);
5345 ! PutSatelliteDataToDict(dict, s);
5346 ! break;
5348 ! case iDVBFrontend::feTerrestrial:
5350 ! eDVBFrontendParametersTerrestrial t;
5351 ! feparm->getDVBT(t);
5352 ! PutTerrestrialDataToDict(dict, t);
5353 ! break;
5355 ! case iDVBFrontend::feCable:
5357 ! eDVBFrontendParametersCable c;
5358 ! feparm->getDVBC(c);
5359 ! PutCableDataToDict(dict, c);
5360 ! break;
5362 ! default:
5363 ! eDebug("unknown frontend type %d", system);
5364 ! Py_DECREF(dict);
5365 ! break;
5367 ! return dict;
5375 ! Py_RETURN_NONE;
5378 ! DEFINE_REF(eStaticServiceDVBBouquetInformation);
5380 ! RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
5382 ! ePtr<iDVBChannelList> db;
5383 ! ePtr<eDVBResourceManager> res;
5385 ! int err;
5386 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
5388 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
5389 ! return err;
5391 ! if ((err = res->getChannelList(db)) != 0)
5393 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
5394 ! return err;
5397 ! eBouquet *bouquet=0;
5398 ! if ((err = db->getBouquet(ref, bouquet)) != 0)
5400 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
5401 ! return -1;
5404 ! if ( bouquet && bouquet->m_bouquet_name.length() )
5406 ! name = bouquet->m_bouquet_name;
5407 ! return 0;
5409 ! else
5410 ! return -1;
5413 ! int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
5415 ! if (ref.flags & eServiceReference::isGroup)
5417 ! ePtr<iDVBChannelList> db;
5418 ! ePtr<eDVBResourceManager> res;
5420 ! if (eDVBResourceManager::getInstance(res))
5422 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no resource manager!");
5423 ! return 0;
5426 ! if (res->getChannelList(db))
5428 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no channel list!");
5429 ! return 0;
5432 ! eBouquet *bouquet=0;
5433 ! if (db->getBouquet(ref, bouquet))
5435 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. getBouquet failed!");
5436 ! return 0;
5439 ! int prio_order = eDVBFrontend::getTypePriorityOrder();
5440 ! int cur=0;
5441 ! eDVBChannelID chid, chid_ignore;
5442 ! ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
5443 ! for (std::list<eServiceReference>::iterator it(bouquet->m_services.begin()); it != bouquet->m_services.end(); ++it)
5445 ! static unsigned char prio_map[6][3] = {
5446 ! { 3, 2, 1 }, // -S -C -T
5447 ! { 3, 1, 2 }, // -S -T -C
5448 ! { 2, 3, 1 }, // -C -S -T
5449 ! { 1, 3, 2 }, // -C -T -S
5450 ! { 1, 2, 3 }, // -T -C -S
5451 ! { 2, 1, 3 } // -T -S -C
5452 ! };
5453 ! ((const eServiceReferenceDVB&)*it).getChannelID(chid);
5454 ! int tmp=res->canAllocateChannel(chid, chid_ignore, simulate);
5455 ! switch(tmp)
5457 ! case 0:
5458 ! break;
5459 ! case 30000: // cached DVB-T channel
5460 ! case 1: // DVB-T frontend
5461 ! tmp = prio_map[prio_order][2];
5462 ! break;
5463 ! case 40000: // cached DVB-C channel
5464 ! case 2:
5465 ! tmp = prio_map[prio_order][1];
5466 ! break;
5467 ! default: // DVB-S
5468 ! tmp = prio_map[prio_order][0];
5469 ! break;
5471 ! if (tmp > cur)
5473 ! m_playable_service = *it;
5474 ! cur = tmp;
5477 ! if (cur)
5478 ! return cur;
5480 ! m_playable_service = eServiceReference();
5481 ! return 0;
5484 ! int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
5486 ! return -1;
5489 ! #include <lib/dvb/epgcache.h>
5491 ! RESULT eStaticServiceDVBBouquetInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time)
5493 ! return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr);
5496 ! class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
5498 ! DECLARE_REF(eStaticServiceDVBPVRInformation);
5499 ! eServiceReference m_ref;
5500 ! eDVBMetaParser m_parser;
5501 ! public:
5502 ! eStaticServiceDVBPVRInformation(const eServiceReference &ref);
5503 ! RESULT getName(const eServiceReference &ref, std::string &name);
5504 ! int getLength(const eServiceReference &ref);
5505 ! RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time);
5506 ! int isPlayable(const eServiceReference &ref, const eServiceReference &ignore) { return 1; }
5507 ! int getInfo(const eServiceReference &ref, int w);
5508 ! std::string getInfoString(const eServiceReference &ref,int w);
5509 ! PyObject *getInfoObject(const eServiceReference &r, int what);
5510 ! };
5512 ! DEFINE_REF(eStaticServiceDVBPVRInformation);
5514 ! eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
5516 ! m_ref = ref;
5517 ! m_parser.parseFile(ref.path);
5520 ! RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
5522 ! ASSERT(ref == m_ref);
5523 ! if (!ref.name.empty())
5524 ! name = ref.name;
5525 ! else if (!m_parser.m_name.empty())
5526 ! name = m_parser.m_name;
5527 ! else
5529 ! name = ref.path;
5530 ! size_t n = name.rfind('/');
5531 ! if (n != std::string::npos)
5532 ! name = name.substr(n + 1);
5534 ! return 0;
5537 ! int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
5539 ! ASSERT(ref == m_ref);
5541 ! eDVBTSTools tstools;
5543 ! struct stat s;
5544 ! stat(ref.path.c_str(), &s);
5546 ! if (tstools.openFile(ref.path.c_str(), 1))
5547 ! return 0;
5549 ! /* check if cached data is still valid */
5550 ! if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length))
5551 ! return m_parser.m_length / 90000;
5553 ! /* open again, this time with stream info */
5554 ! if (tstools.openFile(ref.path.c_str()))
5555 ! return 0;
5557 ! /* otherwise, re-calc length and update meta file */
5558 ! pts_t len;
5559 ! if (tstools.calcLen(len))
5560 ! return 0;
5562 ! m_parser.m_length = len;
5563 ! m_parser.m_filesize = s.st_size;
5564 ! m_parser.updateMeta(ref.path);
5565 ! return m_parser.m_length / 90000;
5568 ! int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
5570 ! switch (w)
5572 ! case iServiceInformation::sDescription:
5573 ! return iServiceInformation::resIsString;
5574 ! case iServiceInformation::sServiceref:
5575 ! return iServiceInformation::resIsString;
5576 ! case iServiceInformation::sFileSize:
5577 ! return m_parser.m_filesize;
5578 ! case iServiceInformation::sTimeCreate:
5579 ! if (m_parser.m_time_create)
5580 ! return m_parser.m_time_create;
5581 ! else
5582 ! return iServiceInformation::resNA;
5583 ! default:
5584 ! return iServiceInformation::resNA;
5588 ! std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
5590 ! switch (w)
5592 ! case iServiceInformation::sDescription:
5593 ! return m_parser.m_description;
5594 ! case iServiceInformation::sServiceref:
5595 ! return m_parser.m_ref.toString();
5596 ! case iServiceInformation::sTags:
5597 ! return m_parser.m_tags;
5598 ! default:
5599 ! return "";
5603 ! PyObject *eStaticServiceDVBPVRInformation::getInfoObject(const eServiceReference &r, int what)
5605 ! switch (what)
5607 ! case iServiceInformation::sFileSize:
5608 ! return PyLong_FromLongLong(m_parser.m_filesize);
5609 ! default:
5610 ! Py_RETURN_NONE;
5614 ! RESULT eStaticServiceDVBPVRInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
5616 ! if (!ref.path.empty())
5618 ! ePtr<eServiceEvent> event = new eServiceEvent;
5619 ! std::string filename = ref.path;
5620 ! filename.erase(filename.length()-2, 2);
5621 ! filename+="eit";
5622 ! if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
5624 ! evt = event;
5625 ! return 0;
5628 ! evt = 0;
5629 ! return -1;
5632 ! class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
5634 ! DECLARE_REF(eDVBPVRServiceOfflineOperations);
5635 ! eServiceReferenceDVB m_ref;
5636 ! public:
5637 ! eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
5639 ! RESULT deleteFromDisk(int simulate);
5640 ! RESULT getListOfFilenames(std::list<std::string> &);
5641 ! RESULT reindex();
5642 ! };
5644 ! DEFINE_REF(eDVBPVRServiceOfflineOperations);
5646 ! eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
5650 ! RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
5652 ! if (simulate)
5653 ! return 0;
5654 ! else
5656 ! std::list<std::string> res;
5657 ! if (getListOfFilenames(res))
5658 ! return -1;
5660 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
5661 ! if (!eraser)
5662 ! eDebug("FATAL !! can't get background file eraser");
5664 ! for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
5666 ! eDebug("Removing %s...", i->c_str());
5667 ! if (eraser)
5668 ! eraser->erase(i->c_str());
5669 ! else
5670 ! ::unlink(i->c_str());
5673 ! return 0;
5677 ! RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
5679 ! res.clear();
5680 ! res.push_back(m_ref.path);
5682 ! // handling for old splitted recordings (enigma 1)
5683 ! char buf[255];
5684 ! int slice=1;
5685 ! while(true)
5687 ! snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
5688 ! struct stat s;
5689 ! if (stat(buf, &s) < 0)
5690 ! break;
5691 ! res.push_back(buf);
5692 ! }
5694 ! res.push_back(m_ref.path + ".meta");
5695 ! res.push_back(m_ref.path + ".ap");
5696 ! res.push_back(m_ref.path + ".sc");
5697 ! res.push_back(m_ref.path + ".cuts");
5698 ! std::string tmp = m_ref.path;
5699 ! tmp.erase(m_ref.path.length()-3);
5700 ! res.push_back(tmp + ".eit");
5701 ! return 0;
5704 ! RESULT eDVBPVRServiceOfflineOperations::reindex()
5706 ! const char *filename = m_ref.path.c_str();
5707 ! eDebug("reindexing %s...", filename);
5709 ! eMPEGStreamInformation info;
5710 ! eMPEGStreamParserTS parser(info);
5712 ! info.startSave(filename);
5714 ! eRawFile f;
5716 ! int err = f.open(m_ref.path.c_str(), 0);
5717 ! if (err < 0)
5718 ! return -1;
5720 ! off_t offset = 0;
5721 ! off_t length = f.length();
5722 ! unsigned char buffer[188*256*4];
5723 ! while (1)
5725 ! eDebug("at %08llx / %08llx (%d %%)", offset, length, (int)(offset * 100 / length));
5726 ! int r = f.read(offset, buffer, sizeof(buffer));
5727 ! if (!r)
5728 ! break;
5729 ! if (r < 0)
5730 ! return r;
5731 ! offset += r;
5732 ! parser.parseData(offset, buffer, r);
5735 ! info.stopSave();
5736 ! f.close();
5738 ! return 0;
5741 ! DEFINE_REF(eServiceFactoryDVB)
5743 ! eServiceFactoryDVB::eServiceFactoryDVB()
5745 ! ePtr<eServiceCenter> sc;
5747 ! eServiceCenter::getPrivInstance(sc);
5748 ! if (sc)
5750 ! std::list<std::string> extensions;
5751 ! extensions.push_back("ts");
5752 ! extensions.push_back("trp");
5753 ! sc->addServiceFactory(eServiceFactoryDVB::id, this, extensions);
5756 ! m_StaticServiceDVBInfo = new eStaticServiceDVBInformation;
5757 ! m_StaticServiceDVBBouquetInfo = new eStaticServiceDVBBouquetInformation;
5760 ! eServiceFactoryDVB::~eServiceFactoryDVB()
5762 ! ePtr<eServiceCenter> sc;
5764 ! eServiceCenter::getPrivInstance(sc);
5765 ! if (sc)
5766 ! sc->removeServiceFactory(eServiceFactoryDVB::id);
5769 ! DEFINE_REF(eDVBServiceList);
5771 ! eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
5775 ! eDVBServiceList::~eDVBServiceList()
5779 ! RESULT eDVBServiceList::startQuery()
5781 ! ePtr<iDVBChannelList> db;
5782 ! ePtr<eDVBResourceManager> res;
5784 ! int err;
5785 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
5787 ! eDebug("no resource manager");
5788 ! return err;
5790 ! if ((err = res->getChannelList(db)) != 0)
5792 ! eDebug("no channel list");
5793 ! return err;
5796 ! ePtr<eDVBChannelQuery> q;
5798 ! if (!m_parent.path.empty())
5800 ! eDVBChannelQuery::compile(q, m_parent.path);
5801 ! if (!q)
5803 ! eDebug("compile query failed");
5804 ! return err;
5808 ! if ((err = db->startQuery(m_query, q, m_parent)) != 0)
5810 ! eDebug("startQuery failed");
5811 ! return err;
5814 ! return 0;
5817 ! RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
5819 ! eServiceReferenceDVB ref;
5821 ! if (!m_query)
5822 ! return -1;
5824 ! while (!m_query->getNextResult(ref))
5825 ! list.push_back(ref);
5827 ! if (sorted)
5828 ! list.sort(iListableServiceCompare(this));
5830 ! return 0;
5833 ! // The first argument of this function is a format string to specify the order and
5834 ! // the content of the returned list
5835 ! // useable format options are
5836 ! // R = Service Reference (as swig object .. this is very slow)
5837 ! // S = Service Reference (as python string object .. same as ref.toString())
5838 ! // C = Service Reference (as python string object .. same as ref.toCompareString())
5839 ! // N = Service Name (as python string object)
5840 ! // n = Short Service Name (short name brakets used) (as python string object)
5841 ! // when exactly one return value per service is selected in the format string,
5842 ! // then each value is directly a list entry
5843 ! // when more than one value is returned per service, then the list is a list of
5844 ! // python tuples
5845 ! // unknown format string chars are returned as python None values !
5846 ! PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
5848 ! ePyObject ret;
5849 ! std::list<eServiceReference> tmplist;
5850 ! int retcount=1;
5852 ! if (!format || !(retcount=strlen(format)))
5853 ! format = "R"; // just return service reference swig object ...
5855 ! if (!getContent(tmplist, sorted))
5857 ! int services=tmplist.size();
5858 ! ePtr<iStaticServiceInformation> sptr;
5859 ! eServiceCenterPtr service_center;
5861 ! if (strchr(format, 'N') || strchr(format, 'n'))
5862 ! eServiceCenter::getPrivInstance(service_center);
5864 ! ret = PyList_New(services);
5865 ! std::list<eServiceReference>::iterator it(tmplist.begin());
5867 ! for (int cnt=0; cnt < services; ++cnt)
5869 ! eServiceReference &ref=*it++;
5870 ! ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject();
5871 ! for (int i=0; i < retcount; ++i)
5873 ! ePyObject tmp;
5874 ! switch(format[i])
5876 ! case 'R': // service reference (swig)object
5877 ! tmp = NEW_eServiceReference(ref);
5878 ! break;
5879 ! case 'C': // service reference compare string
5880 ! tmp = PyString_FromString(ref.toCompareString().c_str());
5881 ! break;
5882 ! case 'S': // service reference string
5883 ! tmp = PyString_FromString(ref.toString().c_str());
5884 ! break;
5885 ! case 'N': // service name
5886 ! if (service_center)
5888 ! service_center->info(ref, sptr);
5889 ! if (sptr)
5891 ! std::string name;
5892 ! sptr->getName(ref, name);
5894 ! // filter short name brakets
5895 ! size_t pos;
5896 ! while((pos = name.find("\xc2\x86")) != std::string::npos)
5897 ! name.erase(pos,2);
5898 ! while((pos = name.find("\xc2\x87")) != std::string::npos)
5899 ! name.erase(pos,2);
5901 ! if (name.length())
5902 ! tmp = PyString_FromString(name.c_str());
5905 ! if (!tmp)
5906 ! tmp = PyString_FromString("<n/a>");
5907 ! break;
5908 ! case 'n': // short service name
5909 ! if (service_center)
5911 ! service_center->info(ref, sptr);
5912 ! if (sptr)
5914 ! std::string name;
5915 ! sptr->getName(ref, name);
5916 ! name = buildShortName(name);
5917 ! if (name.length())
5918 ! tmp = PyString_FromString(name.c_str());
5921 ! if (!tmp)
5922 ! tmp = PyString_FromString("<n/a>");
5923 ! break;
5924 ! default:
5925 ! if (tuple)
5927 ! tmp = Py_None;
5928 ! Py_INCREF(Py_None);
5930 ! break;
5932 ! if (tmp)
5934 ! if (tuple)
5935 ! PyTuple_SET_ITEM(tuple, i, tmp);
5936 ! else
5937 ! PyList_SET_ITEM(ret, cnt, tmp);
5940 ! if (tuple)
5941 ! PyList_SET_ITEM(ret, cnt, tuple);
5944 ! return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
5947 ! RESULT eDVBServiceList::getNext(eServiceReference &ref)
5949 ! if (!m_query)
5950 ! return -1;
5952 ! return m_query->getNextResult((eServiceReferenceDVB&)ref);
5955 ! RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
5957 ! if (m_parent.flags & eServiceReference::canDescent) // bouquet
5959 ! ePtr<iDVBChannelList> db;
5960 ! ePtr<eDVBResourceManager> resm;
5962 ! if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
5963 ! return -1;
5965 ! if (db->getBouquet(m_parent, m_bouquet) != 0)
5966 ! return -1;
5968 ! res = this;
5970 ! return 0;
5972 ! res = 0;
5973 ! return -1;
5976 ! RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
5978 ! if (!m_bouquet)
5979 ! return -1;
5980 ! return m_bouquet->addService(ref, before);
5983 ! RESULT eDVBServiceList::removeService(eServiceReference &ref)
5985 ! if (!m_bouquet)
5986 ! return -1;
5987 ! return m_bouquet->removeService(ref);
5990 ! RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
5992 ! if (!m_bouquet)
5993 ! return -1;
5994 ! return m_bouquet->moveService(ref, pos);
5997 ! RESULT eDVBServiceList::flushChanges()
5999 ! if (!m_bouquet)
6000 ! return -1;
6001 ! return m_bouquet->flushChanges();
6004 ! RESULT eDVBServiceList::setListName(const std::string &name)
6006 ! if (!m_bouquet)
6007 ! return -1;
6008 ! return m_bouquet->setListName(name);
6011 ! RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
6013 ! ePtr<eDVBService> service;
6014 ! int r = lookupService(service, ref);
6015 ! if (r)
6016 ! service = 0;
6017 ! // check resources...
6018 ! ptr = new eDVBServicePlay(ref, service);
6019 ! return 0;
6022 ! RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
6024 ! if (ref.path.empty())
6026 ! ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
6027 ! return 0;
6028 ! } else
6030 ! ptr = 0;
6031 ! return -1;
6035 ! RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
6037 ! ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
6038 ! if (list->startQuery())
6040 ! ptr = 0;
6041 ! return -1;
6044 ! ptr = list;
6045 ! return 0;
6048 ! RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
6050 ! /* is a listable service? */
6051 ! if (ref.flags & eServiceReference::canDescent) // bouquet
6053 ! if ( !ref.name.empty() ) // satellites or providers list
6054 ! ptr = m_StaticServiceDVBInfo;
6055 ! else // a dvb bouquet
6056 ! ptr = m_StaticServiceDVBBouquetInfo;
6058 ! else if (!ref.path.empty()) /* do we have a PVR service? */
6059 ! ptr = new eStaticServiceDVBPVRInformation(ref);
6060 ! else // normal dvb service
6062 ! ePtr<eDVBService> service;
6063 ! if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
6064 ! ptr = m_StaticServiceDVBInfo;
6065 ! else
6066 ! /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
6067 ! ptr = service;
6069 ! return 0;
6072 ! RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
6074 ! if (ref.path.empty())
6076 ! ptr = 0;
6077 ! return -1;
6078 ! } else
6080 ! ptr = new eDVBPVRServiceOfflineOperations(ref);
6081 ! return 0;
6085 ! RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
6087 ! if (!ref.path.empty()) // playback
6089 ! eDVBMetaParser parser;
6090 ! int ret=parser.parseFile(ref.path);
6091 ! service = new eDVBService;
6092 ! if (!ret)
6093 ! eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
6095 ! else
6097 ! // TODO: handle the listing itself
6098 ! // if (ref.... == -1) .. return "... bouquets ...";
6099 ! // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
6100 ! // TODO: cache
6101 ! ePtr<iDVBChannelList> db;
6102 ! ePtr<eDVBResourceManager> res;
6104 ! int err;
6105 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
6107 ! eDebug("no resource manager");
6108 ! return err;
6110 ! if ((err = res->getChannelList(db)) != 0)
6112 ! eDebug("no channel list");
6113 ! return err;
6116 ! /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
6117 ! if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
6119 ! // eDebug("getService failed!");
6120 ! return err;
6124 ! return 0;
6127 ! eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
6128 ! m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
6130 ! m_is_primary = 1;
6131 ! m_is_pvr = !m_reference.path.empty();
6133 ! m_timeshift_enabled = m_timeshift_active = 0, m_timeshift_changed = 0;
6134 ! m_skipmode = m_fastforward = m_slowmotion = 0;
6136 ! CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
6137 ! CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
6138 ! CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
6140 ! m_cuesheet_changed = 0;
6141 ! m_cutlist_enabled = 1;
6143 ! m_subtitle_widget = 0;
6145 ! m_tune_state = -1;
6147 ! m_subtitle_sync_timer = eTimer::create(eApp);
6149 ! CONNECT(m_subtitle_sync_timer->timeout, eDVBServicePlay::checkSubtitleTiming);
6151 ! m_player = 0;
6153 ! xineLib = cXineLib::getInstance();
6154 ! xine_connection = CONNECT(xineLib->m_event, eDVBServicePlay::video_event);
6157 ! eDVBServicePlay::~eDVBServicePlay()
6159 ! if (m_is_pvr)
6161 ! eDVBMetaParser meta;
6162 ! int ret=meta.parseFile(m_reference.path);
6163 ! if (!ret)
6165 ! char tmp[255];
6166 ! meta.m_service_data="";
6167 ! sprintf(tmp, "f:%x", m_dvb_service->m_flags);
6168 ! meta.m_service_data += tmp;
6169 ! // cached pids
6170 ! for (int x=0; x < eDVBService::cacheMax; ++x)
6172 ! int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
6173 ! if (entry != -1)
6175 ! sprintf(tmp, ",c:%02d%04x", x, entry);
6176 ! meta.m_service_data += tmp;
6179 ! meta.updateMeta(m_reference.path);
6183 ! xine_connection.disconnect();
6185 ! delete m_subtitle_widget;
6188 ! void eDVBServicePlay::gotNewEvent()
6190 ! #if 0
6191 ! // debug only
6192 ! ePtr<eServiceEvent> m_event_now, m_event_next;
6193 ! getEvent(m_event_now, 0);
6194 ! getEvent(m_event_next, 1);
6196 ! if (m_event_now)
6197 ! eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
6198 ! if (m_event_next)
6199 ! eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
6200 ! #endif
6201 ! m_event((iPlayableService*)this, evUpdatedEventInfo);
6204 ! void eDVBServicePlay::serviceEvent(int event)
6206 ! m_tune_state = event;
6208 ! switch (event)
6210 ! case eDVBServicePMTHandler::eventTuned:
6212 ! ePtr<iDVBDemux> m_demux;
6213 ! if (!m_service_handler.getDataDemux(m_demux))
6215 ! eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
6216 ! int sid = ref.getParentServiceID().get();
6217 ! if (!sid)
6218 ! sid = ref.getServiceID().get();
6219 ! if ( ref.getParentTransportStreamID().get() &&
6220 ! ref.getParentTransportStreamID() != ref.getTransportStreamID() )
6221 ! m_event_handler.startOther(m_demux, sid);
6222 ! else
6223 ! m_event_handler.start(m_demux, sid);
6225 ! m_event((iPlayableService*)this, evTunedIn);
6226 ! break;
6228 ! case eDVBServicePMTHandler::eventNoResources:
6229 ! case eDVBServicePMTHandler::eventNoPAT:
6230 ! case eDVBServicePMTHandler::eventNoPATEntry:
6231 ! case eDVBServicePMTHandler::eventNoPMT:
6232 ! case eDVBServicePMTHandler::eventTuneFailed:
6233 ! case eDVBServicePMTHandler::eventMisconfiguration:
6235 ! eDebug("DVB service failed to tune - error %d", event);
6236 ! m_event((iPlayableService*)this, evTuneFailed);
6237 ! break;
6239 ! case eDVBServicePMTHandler::eventNewProgramInfo:
6241 ! eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
6242 ! if (m_timeshift_enabled)
6243 ! updateTimeshiftPids();
6244 ! if (!m_timeshift_active)
6245 ! updateDecoder();
6246 ! if (m_first_program_info & 1 && m_is_pvr)
6248 ! m_first_program_info &= ~1;
6249 ! seekTo(0);
6251 ! if (!m_timeshift_active)
6252 ! m_event((iPlayableService*)this, evUpdatedInfo);
6254 ! ePtr<iDVBDemux> m_demux;
6255 ! if (!m_service_handler.getDataDemux(m_demux))
6257 ! printf("Start live TV!\n");
6259 ! m_demux->createTSPlayer(m_player);
6260 ! if (!m_player)
6261 ! printf("ERROR: !m_player\n");
6263 ! m_player->setTargetFD(m_fd_dst);
6264 ! updateTimeshiftPids();
6265 ! m_player->start();
6267 ! printf("Start live TV END\n");
6270 ! break;
6272 ! case eDVBServicePMTHandler::eventPreStart:
6273 ! loadCuesheet();
6274 ! break;
6275 ! case eDVBServicePMTHandler::eventEOF:
6276 ! m_event((iPlayableService*)this, evEOF);
6277 ! break;
6278 ! case eDVBServicePMTHandler::eventSOF:
6279 ! m_event((iPlayableService*)this, evSOF);
6280 ! break;
6284 ! void eDVBServicePlay::serviceEventTimeshift(int event)
6286 ! switch (event)
6288 ! case eDVBServicePMTHandler::eventNewProgramInfo:
6289 ! eDebug("eventNewProgramInfo TS");
6290 ! if (m_timeshift_active)
6292 ! updateDecoder();
6293 ! if (m_first_program_info & 2)
6295 ! if (m_slowmotion)
6297 ! eDebug("re-apply slowmotion after timeshift file change");
6298 ! m_decoder->setSlowMotion(m_slowmotion);
6300 ! if (m_fastforward)
6302 ! eDebug("re-apply skip %d, ratio %d after timeshift file change", m_skipmode, m_fastforward);
6303 ! if (m_skipmode)
6304 ! m_cue->setSkipmode(m_skipmode * 90000); /* convert to 90000 per second */
6305 ! if (m_fastforward != 1)
6306 ! m_decoder->setFastForward(m_fastforward);
6307 ! else
6308 ! m_decoder->setTrickmode();
6310 ! else
6311 ! seekTo(0);
6312 ! m_first_program_info &= ~2;
6314 ! m_event((iPlayableService*)this, evUpdatedInfo);
6316 ! break;
6317 ! case eDVBServicePMTHandler::eventSOF:
6318 ! #if 0
6319 ! if (!m_timeshift_file_next.empty())
6321 ! eDebug("timeshift SOF, switch to next file");
6322 ! m_decoder->pause();
6324 ! m_first_program_info |= 2;
6326 ! eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
6327 ! r.path = m_timeshift_file_next;
6329 ! /* free the timeshift service handler, we need the resources */
6330 ! m_service_handler_timeshift.free();
6331 ! resetTimeshift(1);
6333 ! if (m_skipmode < 0)
6334 ! m_cue->seekTo(0, -1000);
6335 ! ePtr<iTsSource> source = createTsSource(r);
6336 ! m_service_handler_timeshift.tuneExt(r, 1, source, r.path.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
6338 ! m_event((iPlayableService*)this, evUser+1);
6340 ! else
6341 ! #endif
6342 ! m_event((iPlayableService*)this, evSOF);
6343 ! break;
6344 ! case eDVBServicePMTHandler::eventEOF:
6345 ! if ((!m_is_paused) && (m_skipmode >= 0))
6347 ! if (m_timeshift_file_next.empty())
6349 ! eDebug("timeshift EOF, so let's go live");
6350 ! switchToLive();
6352 ! else
6354 ! eDebug("timeshift EOF, switch to next file");
6356 ! m_first_program_info |= 2;
6358 ! eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
6359 ! r.path = m_timeshift_file_next;
6361 ! /* free the timeshift service handler, we need the resources */
6362 ! m_service_handler_timeshift.free();
6363 ! resetTimeshift(1);
6365 ! ePtr<iTsSource> source = createTsSource(r);
6366 ! m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file_next.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
6368 ! m_event((iPlayableService*)this, evUser+1);
6371 ! break;
6375 ! RESULT eDVBServicePlay::start()
6377 ! printf("eDVBServicePlay::start\n");
6378 ! eServiceReferenceDVB service = (eServiceReferenceDVB&)m_reference;
6380 ! m_fd_dst = ::open("/tmp/ENIGMA_FIFO", O_RDWR);
6381 ! if (m_fd_dst < 0)
6383 ! eDebug("can't open DVR device - FIFO file (%m)");
6386 ! /* in pvr mode, we only want to use one demux. in tv mode, we're using
6387 ! two (one for decoding, one for data source), as we must be prepared
6388 ! to start recording from the data demux. */
6389 ! if (m_is_pvr)
6391 ! eDVBMetaParser meta;
6392 ! if (!meta.parseFile(m_reference.path))
6394 ! service = meta.m_ref;
6395 ! service.path = m_reference.path;
6397 ! m_cue = new eCueSheet();
6399 ! else
6400 ! m_event(this, evStart);
6402 ! m_first_program_info = 1;
6403 ! ePtr<iTsSource> source = createTsSource(service);
6404 ! m_service_handler.tuneExt(service, m_is_pvr, source, service.path.c_str(), m_cue, false, m_dvb_service);
6406 ! if (m_is_pvr)
6408 ! /* inject EIT if there is a stored one */
6409 ! std::string filename = service.path;
6410 ! filename.erase(filename.length()-2, 2);
6411 ! filename+="eit";
6412 ! ePtr<eServiceEvent> event = new eServiceEvent;
6413 ! if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
6415 ! ePtr<eServiceEvent> empty;
6416 ! m_event_handler.inject(event, 0);
6417 ! m_event_handler.inject(empty, 1);
6419 ! m_event(this, evStart);
6421 ! return 0;
6424 ! RESULT eDVBServicePlay::stop()
6426 ! printf("eDVBServicePlay::stop\n");
6427 ! /* add bookmark for last play position */
6428 ! if (m_is_pvr)
6430 ! pts_t play_position, length;
6431 ! if (!getPlayPosition(play_position))
6433 ! /* remove last position */
6434 ! for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
6436 ! if (i->what == 3) /* current play position */
6438 ! m_cue_entries.erase(i);
6439 ! i = m_cue_entries.begin();
6440 ! continue;
6441 ! } else
6442 ! ++i;
6445 ! if (getLength(length))
6446 ! length = 0;
6448 ! if (length)
6450 ! m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
6452 ! m_cuesheet_changed = 1;
6456 ! stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
6458 ! // stop TSPlayer
6459 ! if (m_player) {
6460 ! m_player->stop();
6461 ! m_player = 0;
6463 ! if (m_fd_dst>0) {
6464 ! printf("close(m_fd_dst) %d\n", m_fd_dst);
6465 ! close(m_fd_dst);
6468 ! m_service_handler_timeshift.free();
6469 ! m_service_handler.free();
6471 ! if (m_is_pvr && m_cuesheet_changed)
6473 ! struct stat s;
6474 ! /* save cuesheet only when main file is accessible. */
6475 ! if (!::stat(m_reference.path.c_str(), &s))
6476 ! saveCuesheet();
6478 ! m_event((iPlayableService*)this, evStopped);
6479 ! return 0;
6482 ! RESULT eDVBServicePlay::setTarget(int target)
6484 ! m_is_primary = !target;
6485 ! return 0;
6488 ! RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
6490 ! connection = new eConnection((iPlayableService*)this, m_event.connect(event));
6491 ! return 0;
6494 ! RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
6496 ! /* note: we check for timeshift to be enabled,
6497 ! not neccessary active. if you pause when timeshift
6498 ! is not active, you should activate it when unpausing */
6499 ! if ((!m_is_pvr) && (!m_timeshift_enabled))
6501 ! ptr = 0;
6502 ! return -1;
6505 ! ptr = this;
6506 ! return 0;
6509 ! RESULT eDVBServicePlay::setSlowMotion(int ratio)
6511 ! ASSERT(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */
6512 ! eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
6513 ! setFastForward_internal(0);
6514 ! if (m_decoder)
6516 ! m_slowmotion = ratio;
6517 ! return m_decoder->setSlowMotion(ratio);
6519 ! else
6520 ! return -1;
6523 ! RESULT eDVBServicePlay::setFastForward(int ratio)
6525 ! eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
6526 ! ASSERT(ratio);
6527 ! return setFastForward_internal(ratio);
6530 ! RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
6532 ! int skipmode, ffratio, ret = 0;
6533 ! pts_t pos=0;
6535 ! if (ratio > 8)
6537 ! skipmode = ratio;
6538 ! ffratio = 1;
6539 ! } else if (ratio > 0)
6541 ! skipmode = 0;
6542 ! ffratio = ratio;
6543 ! } else if (!ratio)
6545 ! skipmode = 0;
6546 ! ffratio = 0;
6547 ! } else // if (ratio < 0)
6549 ! skipmode = ratio;
6550 ! ffratio = 1;
6553 ! if (m_skipmode != skipmode)
6555 ! eDebug("setting cue skipmode to %d", skipmode);
6556 ! if (m_cue)
6557 ! m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
6560 ! m_skipmode = skipmode;
6562 ! if (final_seek)
6563 ! eDebug("trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
6565 ! m_fastforward = ffratio;
6567 ! if (!m_decoder)
6568 ! return -1;
6570 ! if (ffratio == 0)
6571 ! ; /* return m_decoder->play(); is done in caller*/
6572 ! else if (ffratio != 1)
6573 ! ret = m_decoder->setFastForward(ffratio);
6574 ! else
6575 ! ret = m_decoder->setTrickmode();
6577 ! if (pos)
6578 ! eDebug("final seek after trickplay ret %d", seekTo(pos));
6580 ! return ret;
6583 ! RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
6585 ! if (m_is_pvr || m_timeshift_enabled)
6587 ! ptr = this;
6588 ! return 0;
6591 ! ptr = 0;
6592 ! return -1;
6595 ! /* TODO: when timeshift is enabled but not active, this doesn't work. */
6596 ! RESULT eDVBServicePlay::getLength(pts_t &len)
6598 ! ePtr<iDVBPVRChannel> pvr_channel;
6600 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
6601 ! return -1;
6603 ! return pvr_channel->getLength(len);
6606 ! RESULT eDVBServicePlay::pause()
6608 ! eDebug("eDVBServicePlay::pause");
6609 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
6610 ! if (m_decoder)
6612 ! m_slowmotion = 0;
6613 ! m_is_paused = 1;
6614 ! return m_decoder->pause();
6615 ! } else
6616 ! return -1;
6619 ! RESULT eDVBServicePlay::unpause()
6621 ! eDebug("eDVBServicePlay::unpause");
6622 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
6623 ! if (m_decoder)
6625 ! m_slowmotion = 0;
6626 ! m_is_paused = 0;
6627 ! return m_decoder->play();
6628 ! } else
6629 ! return -1;
6632 ! RESULT eDVBServicePlay::seekTo(pts_t to)
6634 ! eDebug("eDVBServicePlay::seekTo: jump %lld", to);
6636 ! if (!m_decode_demux)
6637 ! return -1;
6639 ! ePtr<iDVBPVRChannel> pvr_channel;
6641 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
6642 ! return -1;
6644 ! if (!m_cue)
6645 ! return -1;
6647 ! m_cue->seekTo(0, to);
6648 ! m_dvb_subtitle_pages.clear();
6649 ! m_subtitle_pages.clear();
6651 ! return 0;
6654 ! RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
6656 ! eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
6658 ! if (!m_decode_demux)
6659 ! return -1;
6661 ! ePtr<iDVBPVRChannel> pvr_channel;
6663 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
6664 ! return -1;
6666 ! int mode = 1;
6668 ! /* HACK until we have skip-AP api */
6669 ! if ((to > 0) && (to < 100))
6670 ! mode = 2;
6672 ! to *= direction;
6674 ! if (!m_cue)
6675 ! return 0;
6677 ! m_cue->seekTo(mode, to);
6678 ! m_dvb_subtitle_pages.clear();
6679 ! m_subtitle_pages.clear();
6680 ! return 0;
6683 ! RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
6685 ! ePtr<iDVBPVRChannel> pvr_channel;
6687 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
6688 ! return -1;
6690 ! int r = 0;
6692 ! r = xineLib->getPTS(pos);
6693 ! if (r)
6694 ! return r;
6696 ! /* fixup */
6697 ! return pvr_channel->getCurrentPosition(m_decode_demux, pos, 1);
6700 ! RESULT eDVBServicePlay::setTrickmode(int trick)
6702 ! /* currently unimplemented */
6703 ! return -1;
6706 ! RESULT eDVBServicePlay::isCurrentlySeekable()
6708 ! int ret = 0;
6709 ! if (m_decoder)
6711 ! ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
6712 ! if (m_decoder->getVideoProgressive() == -1)
6713 ! ret &= ~2;
6715 ! return ret;
6718 ! RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
6720 ! ptr = this;
6721 ! return 0;
6724 ! RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
6726 ! ptr = this;
6727 ! return 0;
6730 ! RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
6732 ! ptr = this;
6733 ! return 0;
6736 ! RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
6738 ! ptr = this;
6739 ! return 0;
6742 ! RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
6744 ! ptr = this;
6745 ! return 0;
6748 ! RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
6750 ! ptr = 0;
6751 ! if (m_have_video_pid && // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
6752 ! (m_timeshift_enabled || !m_is_pvr))
6754 ! if (!m_timeshift_enabled)
6756 ! /* query config path */
6757 ! std::string tspath;
6758 ! if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
6759 ! eDebug("could not query ts path from config");
6760 ! return -4;
6762 ! tspath.append("/");
6763 ! /* we need enough diskspace */
6764 ! struct statfs fs;
6765 ! if (statfs(tspath.c_str(), &fs) < 0)
6767 ! eDebug("statfs failed!");
6768 ! return -2;
6771 ! if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
6773 ! eDebug("not enough diskspace for timeshift! (less than 1GB)");
6774 ! return -3;
6777 ! ptr = this;
6778 ! return 0;
6780 ! return -1;
6783 ! RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
6785 ! if (m_is_pvr)
6787 ! ptr = this;
6788 ! return 0;
6790 ! ptr = 0;
6791 ! return -1;
6794 ! RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
6796 ! ptr = this;
6797 ! return 0;
6800 ! RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
6802 ! ptr = this;
6803 ! return 0;
6806 ! RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
6808 ! ptr = this;
6809 ! return 0;
6812 ! RESULT eDVBServicePlay::getName(std::string &name)
6814 ! if (m_is_pvr)
6816 ! ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
6817 ! return i->getName(m_reference, name);
6819 ! else if (m_dvb_service)
6821 ! m_dvb_service->getName(m_reference, name);
6822 ! if (name.empty())
6823 ! name = "(...)";
6825 ! else if (!m_reference.name.empty())
6826 ! eStaticServiceDVBInformation().getName(m_reference, name);
6827 ! else
6828 ! name = "DVB service";
6829 ! return 0;
6832 ! RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
6834 ! return m_event_handler.getEvent(evt, nownext);
6837 ! int eDVBServicePlay::getInfo(int w)
6839 ! eDVBServicePMTHandler::program program;
6841 ! if (w == sCAIDs || w == sCAIDPIDs)
6842 ! return resIsPyObject;
6844 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
6846 ! int no_program_info = 0;
6848 ! if (h.getProgramInfo(program))
6849 ! no_program_info = 1;
6851 ! switch (w)
6853 ! case sVideoHeight:
6854 ! //if (m_decoder)
6855 ! // return m_decoder->getVideoHeight();
6856 ! return xineLib->getVideoHeight();
6857 ! break;
6858 ! case sVideoWidth:
6859 ! //if (m_decoder)
6860 ! // return m_decoder->getVideoWidth();
6861 ! return xineLib->getVideoWidth();
6862 ! break;
6863 ! case sFrameRate:
6864 ! //if (m_decoder)
6865 ! // return m_decoder->getVideoFrameRate();
6866 ! return xineLib->getVideoFrameRate();
6867 ! break;
6868 ! case sProgressive:
6869 ! if (m_decoder)
6870 ! return m_decoder->getVideoProgressive();
6871 ! break;
6872 ! case sAspect:
6874 ! //if (m_decoder)
6875 ! // aspect = m_decoder->getVideoAspect();
6876 ! int aspect = xineLib->getVideoAspect();
6878 ! if (aspect == -1 && no_program_info)
6879 ! break;
6880 ! else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
6882 ! ePtr<eServiceEvent> evt;
6883 ! if (!m_event_handler.getEvent(evt, 0))
6885 ! ePtr<eComponentData> data;
6886 ! if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
6888 ! if ( data->getStreamContent() == 1 )
6890 ! switch(data->getComponentType())
6892 ! // SD
6893 ! case 1: // 4:3 SD PAL
6894 ! case 2:
6895 ! case 3: // 16:9 SD PAL
6896 ! case 4: // > 16:9 PAL
6897 ! case 5: // 4:3 SD NTSC
6898 ! case 6:
6899 ! case 7: // 16:9 SD NTSC
6900 ! case 8: // > 16:9 NTSC
6902 ! // HD
6903 ! case 9: // 4:3 HD PAL
6904 ! case 0xA:
6905 ! case 0xB: // 16:9 HD PAL
6906 ! case 0xC: // > 16:9 HD PAL
6907 ! case 0xD: // 4:3 HD NTSC
6908 ! case 0xE:
6909 ! case 0xF: // 16:9 HD NTSC
6910 ! case 0x10: // > 16:9 HD PAL
6911 ! return data->getComponentType();
6917 ! else
6918 ! return aspect;
6919 ! break;
6921 ! case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
6922 ! case sVideoPID:
6923 ! if (m_dvb_service)
6925 ! int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
6926 ! if (vpid != -1)
6927 ! return vpid;
6929 ! if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
6930 ! case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
6931 ! case sAudioPID:
6932 ! if (m_dvb_service)
6934 ! int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
6935 ! if (apid != -1)
6936 ! return apid;
6937 ! apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
6938 ! if (apid != -1)
6939 ! return apid;
6941 ! if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
6942 ! case sPCRPID:
6943 ! if (m_dvb_service)
6945 ! int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
6946 ! if (pcrpid != -1)
6947 ! return pcrpid;
6949 ! if (no_program_info) return -1; return program.pcrPid;
6950 ! case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
6951 ! case sTXTPID: if (no_program_info) return -1; return program.textPid;
6952 ! case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
6953 ! case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
6954 ! case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
6955 ! case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
6956 ! case sProvider: if (!m_dvb_service) return -1; return -2;
6957 ! case sServiceref: return resIsString;
6958 ! case sDVBState: return m_tune_state;
6959 ! default:
6960 ! break;
6962 ! return -1;
6965 ! std::string eDVBServicePlay::getInfoString(int w)
6967 ! switch (w)
6969 ! case sProvider:
6970 ! if (!m_dvb_service) return "";
6971 ! return m_dvb_service->m_provider_name;
6972 ! case sServiceref:
6973 ! return m_reference.toString();
6974 ! default:
6975 ! break;
6977 ! return iServiceInformation::getInfoString(w);
6980 ! PyObject *eDVBServicePlay::getInfoObject(int w)
6982 ! switch (w)
6984 ! case sCAIDs:
6985 ! return m_service_handler.getCaIds();
6986 ! case sCAIDPIDs:
6987 ! return m_service_handler.getCaIds(true);
6988 ! case sTransponderData:
6989 ! return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
6990 ! default:
6991 ! break;
6993 ! return iServiceInformation::getInfoObject(w);
6996 ! int eDVBServicePlay::getNumberOfTracks()
6998 ! eDVBServicePMTHandler::program program;
6999 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
7000 ! if (h.getProgramInfo(program))
7001 ! return 0;
7002 ! return program.audioStreams.size();
7005 ! int eDVBServicePlay::getCurrentTrack()
7007 ! eDVBServicePMTHandler::program program;
7008 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
7009 ! if (h.getProgramInfo(program))
7010 ! return 0;
7012 ! int max = program.audioStreams.size();
7013 ! int i;
7015 ! for (i = 0; i < max; ++i)
7016 ! if (program.audioStreams[i].pid == m_current_audio_pid)
7017 ! return i;
7019 ! return 0;
7022 ! RESULT eDVBServicePlay::selectTrack(unsigned int i)
7024 ! int ret = selectAudioStream(i);
7026 ! if (m_decoder->set())
7027 ! return -5;
7029 ! return ret;
7032 ! RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
7034 ! eDVBServicePMTHandler::program program;
7035 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
7037 ! if (h.getProgramInfo(program))
7038 ! return -1;
7040 ! if (i >= program.audioStreams.size())
7041 ! return -2;
7043 ! info.m_pid = program.audioStreams[i].pid;
7045 ! if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
7046 ! info.m_description = "MPEG";
7047 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
7048 ! info.m_description = "AC3";
7049 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
7050 ! info.m_description = "AAC";
7051 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
7052 ! info.m_description = "AAC-HE";
7053 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
7054 ! info.m_description = "DTS";
7055 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTSHD)
7056 ! info.m_description = "DTS-HD";
7057 ! else
7058 ! info.m_description = "???";
7060 ! if (program.audioStreams[i].component_tag != -1)
7062 ! ePtr<eServiceEvent> evt;
7063 ! if (!m_event_handler.getEvent(evt, 0))
7065 ! ePtr<eComponentData> data;
7066 ! if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
7067 ! info.m_language = data->getText();
7071 ! if (info.m_language.empty())
7072 ! info.m_language = program.audioStreams[i].language_code;
7074 ! return 0;
7077 ! int eDVBServicePlay::selectAudioStream(int i)
7079 ! eDVBServicePMTHandler::program program;
7080 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
7081 ! pts_t position = -1;
7083 ! if (h.getProgramInfo(program))
7084 ! return -1;
7086 ! if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
7087 ! return -2;
7089 ! if (!m_decoder)
7090 ! return -3;
7092 ! int stream = i;
7093 ! if (stream == -1)
7094 ! stream = program.defaultAudioStream;
7096 ! int apid = -1, apidtype = -1;
7098 ! if (((unsigned int)stream) < program.audioStreams.size())
7100 ! apid = program.audioStreams[stream].pid;
7101 ! apidtype = program.audioStreams[stream].type;
7104 ! if (i != -1 && apid != m_current_audio_pid && (m_is_pvr || m_timeshift_active))
7105 ! eDebug("getPlayPosition ret %d, pos %lld in selectAudioStream", getPlayPosition(position), position);
7107 ! m_current_audio_pid = apid;
7109 ! if (m_is_primary && m_decoder->setAudioPID(apid, apidtype))
7111 ! eDebug("set audio pid failed");
7112 ! return -4;
7115 ! if (position != -1)
7116 ! eDebug("seekTo ret %d", seekTo(position));
7118 ! int rdsPid = apid;
7120 ! /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
7121 ! if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
7123 ! int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
7124 ! if (different_pid)
7125 ! rdsPid = program.audioStreams[stream].rdsPid;
7126 ! if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
7128 ! m_rds_decoder = 0;
7129 ! ePtr<iDVBDemux> data_demux;
7130 ! if (!h.getDataDemux(data_demux))
7132 ! m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
7133 ! m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
7134 ! m_rds_decoder->start(rdsPid);
7139 ! /* store new pid as default only when:
7140 ! a.) we have an entry in the service db for the current service,
7141 ! b.) we are not playing back something,
7142 ! c.) we are not selecting the default entry. (we wouldn't change
7143 ! anything in the best case, or destroy the default setting in
7144 ! case the real default is not yet available.)
7145 ! */
7146 ! if (m_dvb_service && ((i != -1)
7147 ! || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
7149 ! if (apidtype == eDVBAudio::aMPEG)
7151 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
7152 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
7154 ! else if (apidtype == eDVBAudio::aAC3)
7156 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
7157 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
7159 ! else
7161 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
7162 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
7166 ! h.resetCachedProgram();
7168 ! return 0;
7171 ! int eDVBServicePlay::getCurrentChannel()
7173 ! return m_decoder ? m_decoder->getAudioChannel() : STEREO;
7176 ! RESULT eDVBServicePlay::selectChannel(int i)
7178 ! if (i < LEFT || i > RIGHT || i == STEREO)
7179 ! i = -1; // Stereo
7180 ! if (m_dvb_service)
7181 ! m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
7182 ! if (m_decoder)
7183 ! m_decoder->setAudioChannel(i);
7184 ! return 0;
7187 ! std::string eDVBServicePlay::getText(int x)
7189 ! if (m_rds_decoder)
7190 ! switch(x)
7192 ! case RadioText:
7193 ! return convertLatin1UTF8(m_rds_decoder->getRadioText());
7194 ! case RtpText:
7195 ! return convertLatin1UTF8(m_rds_decoder->getRtpText());
7197 ! return "";
7200 ! void eDVBServicePlay::rdsDecoderEvent(int what)
7202 ! switch(what)
7204 ! case eDVBRdsDecoder::RadioTextChanged:
7205 ! m_event((iPlayableService*)this, evUpdatedRadioText);
7206 ! break;
7207 ! case eDVBRdsDecoder::RtpTextChanged:
7208 ! m_event((iPlayableService*)this, evUpdatedRtpText);
7209 ! break;
7210 ! case eDVBRdsDecoder::RassInteractivePicMaskChanged:
7211 ! m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
7212 ! break;
7213 ! case eDVBRdsDecoder::RecvRassSlidePic:
7214 ! m_event((iPlayableService*)this, evUpdatedRassSlidePic);
7215 ! break;
7219 ! void eDVBServicePlay::showRassSlidePicture()
7221 ! if (m_rds_decoder)
7223 ! if (m_decoder)
7225 ! std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
7226 ! if (rass_slide_pic.length())
7227 ! m_decoder->showSinglePic(rass_slide_pic.c_str());
7228 ! else
7229 ! eDebug("empty filename for rass slide picture received!!");
7231 ! else
7232 ! eDebug("no MPEG Decoder to show iframes avail");
7234 ! else
7235 ! eDebug("showRassSlidePicture called.. but not decoder");
7238 ! void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
7240 ! if (m_rds_decoder)
7242 ! if (m_decoder)
7244 ! std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
7245 ! if (rass_interactive_pic.length())
7246 ! m_decoder->showSinglePic(rass_interactive_pic.c_str());
7247 ! else
7248 ! eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
7250 ! else
7251 ! eDebug("no MPEG Decoder to show iframes avail");
7253 ! else
7254 ! eDebug("showRassInteractivePic called.. but not decoder");
7257 ! ePyObject eDVBServicePlay::getRassInteractiveMask()
7259 ! if (m_rds_decoder)
7260 ! return m_rds_decoder->getRassPictureMask();
7261 ! Py_RETURN_NONE;
7264 ! int eDVBServiceBase::getFrontendInfo(int w)
7266 ! eUsePtr<iDVBChannel> channel;
7267 ! if(m_service_handler.getChannel(channel))
7268 ! return 0;
7269 ! ePtr<iDVBFrontend> fe;
7270 ! if(channel->getFrontend(fe))
7271 ! return 0;
7272 ! return fe->readFrontendData(w);
7275 ! PyObject *eDVBServiceBase::getFrontendData()
7277 ! ePyObject ret = PyDict_New();
7278 ! if (ret)
7280 ! eUsePtr<iDVBChannel> channel;
7281 ! if(!m_service_handler.getChannel(channel))
7283 ! ePtr<iDVBFrontend> fe;
7284 ! if(!channel->getFrontend(fe))
7285 ! fe->getFrontendData(ret);
7288 ! else
7289 ! Py_RETURN_NONE;
7290 ! return ret;
7293 ! PyObject *eDVBServiceBase::getFrontendStatus()
7295 ! ePyObject ret = PyDict_New();
7296 ! if (ret)
7298 ! eUsePtr<iDVBChannel> channel;
7299 ! if(!m_service_handler.getChannel(channel))
7301 ! ePtr<iDVBFrontend> fe;
7302 ! if(!channel->getFrontend(fe))
7303 ! fe->getFrontendStatus(ret);
7306 ! else
7307 ! Py_RETURN_NONE;
7308 ! return ret;
7311 ! PyObject *eDVBServiceBase::getTransponderData(bool original)
7313 ! ePyObject ret = PyDict_New();
7314 ! if (ret)
7316 ! eUsePtr<iDVBChannel> channel;
7317 ! if(!m_service_handler.getChannel(channel))
7319 ! ePtr<iDVBFrontend> fe;
7320 ! if(!channel->getFrontend(fe))
7321 ! fe->getTransponderData(ret, original);
7324 ! else
7325 ! Py_RETURN_NONE;
7326 ! return ret;
7329 ! PyObject *eDVBServiceBase::getAll(bool original)
7331 ! ePyObject ret = getTransponderData(original);
7332 ! if (ret != Py_None)
7334 ! eUsePtr<iDVBChannel> channel;
7335 ! if(!m_service_handler.getChannel(channel))
7337 ! ePtr<iDVBFrontend> fe;
7338 ! if(!channel->getFrontend(fe))
7340 ! fe->getFrontendData(ret);
7341 ! fe->getFrontendStatus(ret);
7345 ! return ret;
7348 ! int eDVBServicePlay::getNumberOfSubservices()
7350 ! ePtr<eServiceEvent> evt;
7351 ! if (!m_event_handler.getEvent(evt, 0))
7352 ! return evt->getNumOfLinkageServices();
7353 ! return 0;
7356 ! RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
7358 ! ePtr<eServiceEvent> evt;
7359 ! if (!m_event_handler.getEvent(evt, 0))
7361 ! if (!evt->getLinkageService(sub, m_reference, n))
7362 ! return 0;
7364 ! sub.type=eServiceReference::idInvalid;
7365 ! return -1;
7368 ! RESULT eDVBServicePlay::startTimeshift()
7370 ! ePtr<iDVBDemux> demux;
7372 ! eDebug("Start timeshift!");
7374 ! if (m_timeshift_enabled)
7375 ! return -1;
7377 ! /* start recording with the data demux. */
7378 ! if (m_service_handler.getDataDemux(demux))
7379 ! return -2;
7381 ! demux->createTSRecorder(m_record);
7382 ! if (!m_record)
7383 ! return -3;
7385 ! std::string tspath;
7386 ! if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
7387 ! eDebug("could not query ts path");
7388 ! return -5;
7390 ! tspath.append("/timeshift.XXXXXX");
7391 ! char* templ;
7392 ! templ = new char[tspath.length() + 1];
7393 ! strcpy(templ, tspath.c_str());
7395 ! m_timeshift_fd = mkstemp(templ);
7396 ! m_timeshift_file = std::string(templ);
7398 ! eDebug("recording to %s", templ);
7400 ! delete [] templ;
7402 ! if (m_timeshift_fd < 0)
7404 ! m_record = 0;
7405 ! return -4;
7408 ! m_record->setTargetFD(m_timeshift_fd);
7410 ! m_timeshift_enabled = 1;
7412 ! updateTimeshiftPids();
7413 ! m_record->start();
7415 ! return 0;
7418 ! RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
7420 ! if (!m_timeshift_enabled)
7421 ! return -1;
7423 ! if (swToLive)
7424 ! switchToLive();
7426 ! m_timeshift_enabled = 0;
7428 ! m_record->stop();
7429 ! m_record = 0;
7431 ! close(m_timeshift_fd);
7432 ! eDebug("remove timeshift file");
7433 ! eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
7435 ! return 0;
7438 ! int eDVBServicePlay::isTimeshiftActive()
7440 ! return m_timeshift_enabled && m_timeshift_active;
7443 ! RESULT eDVBServicePlay::activateTimeshift()
7445 ! if (!m_timeshift_enabled)
7446 ! return -1;
7448 ! if (!m_timeshift_active)
7450 ! switchToTimeshift();
7451 ! return 0;
7454 ! return -2;
7457 ! PyObject *eDVBServicePlay::getCutList()
7459 ! ePyObject list = PyList_New(0);
7461 ! for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
7463 ! ePyObject tuple = PyTuple_New(2);
7464 ! PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
7465 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
7466 ! PyList_Append(list, tuple);
7467 ! Py_DECREF(tuple);
7470 ! return list;
7473 ! void eDVBServicePlay::setCutList(ePyObject list)
7475 ! if (!PyList_Check(list))
7476 ! return;
7477 ! int size = PyList_Size(list);
7478 ! int i;
7480 ! m_cue_entries.clear();
7482 ! for (i=0; i<size; ++i)
7484 ! ePyObject tuple = PyList_GET_ITEM(list, i);
7485 ! if (!PyTuple_Check(tuple))
7487 ! eDebug("non-tuple in cutlist");
7488 ! continue;
7490 ! if (PyTuple_Size(tuple) != 2)
7492 ! eDebug("cutlist entries need to be a 2-tuple");
7493 ! continue;
7495 ! ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
7496 ! if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
7498 ! eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
7499 ! continue;
7501 ! pts_t pts = PyLong_AsLongLong(ppts);
7502 ! int type = PyInt_AsLong(ptype);
7503 ! m_cue_entries.insert(cueEntry(pts, type));
7504 ! eDebug("adding %08llx, %d", pts, type);
7506 ! m_cuesheet_changed = 1;
7508 ! cutlistToCuesheet();
7509 ! m_event((iPlayableService*)this, evCuesheetChanged);
7512 ! void eDVBServicePlay::setCutListEnable(int enable)
7514 ! m_cutlist_enabled = enable;
7515 ! cutlistToCuesheet();
7518 ! void eDVBServicePlay::updateTimeshiftPids()
7520 ! eDVBServicePMTHandler::program program;
7521 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
7523 ! if (h.getProgramInfo(program))
7524 ! return;
7525 ! else
7527 ! std::set<int> pids_to_record;
7528 ! pids_to_record.insert(0); // PAT
7529 ! if (program.pmtPid != -1)
7530 ! pids_to_record.insert(program.pmtPid); // PMT
7532 ! if (program.textPid != -1)
7533 ! pids_to_record.insert(program.textPid); // Videotext
7535 ! for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
7536 ! i(program.videoStreams.begin());
7537 ! i != program.videoStreams.end(); ++i)
7538 ! pids_to_record.insert(i->pid);
7540 ! for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
7541 ! i(program.audioStreams.begin());
7542 ! i != program.audioStreams.end(); ++i)
7543 ! pids_to_record.insert(i->pid);
7545 ! for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
7546 ! i(program.subtitleStreams.begin());
7547 ! i != program.subtitleStreams.end(); ++i)
7548 ! pids_to_record.insert(i->pid);
7550 ! std::set<int> new_pids, obsolete_pids;
7552 ! std::set_difference(pids_to_record.begin(), pids_to_record.end(),
7553 ! m_pids_active.begin(), m_pids_active.end(),
7554 ! std::inserter(new_pids, new_pids.begin()));
7556 ! std::set_difference(
7557 ! m_pids_active.begin(), m_pids_active.end(),
7558 ! pids_to_record.begin(), pids_to_record.end(),
7559 ! std::inserter(new_pids, new_pids.begin())
7560 ! );
7562 ! if (m_record) {
7563 ! for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
7564 ! m_record->addPID(*i);
7565 ! for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
7566 ! m_record->removePID(*i);
7569 ! for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
7570 ! m_player->addPID(*i);
7571 ! for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
7572 ! m_player->removePID(*i);
7576 ! RESULT eDVBServicePlay::setNextPlaybackFile(const char *f)
7578 ! m_timeshift_file_next = f;
7579 ! return 0;
7582 ! void eDVBServicePlay::switchToLive()
7584 ! if (!m_timeshift_active)
7585 ! return;
7587 ! eDebug("SwitchToLive");
7589 ! resetTimeshift(0);
7591 ! m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
7593 ! /* free the timeshift service handler, we need the resources */
7594 ! m_service_handler_timeshift.free();
7596 ! updateDecoder(true);
7599 ! void eDVBServicePlay::resetTimeshift(int start)
7601 ! m_cue = 0;
7602 ! m_decode_demux = 0;
7603 ! m_decoder = 0;
7604 ! m_teletext_parser = 0;
7605 ! m_rds_decoder = 0;
7606 ! m_subtitle_parser = 0;
7607 ! m_new_subtitle_page_connection = 0;
7608 ! m_new_dvb_subtitle_page_connection = 0;
7609 ! m_rds_decoder_event_connection = 0;
7610 ! m_timeshift_changed = 1;
7611 ! m_timeshift_file_next.clear();
7613 ! if (start)
7615 ! m_cue = new eCueSheet();
7616 ! m_timeshift_active = 1;
7618 ! else
7619 ! m_timeshift_active = 0;
7622 ! ePtr<iTsSource> eDVBServicePlay::createTsSource(eServiceReferenceDVB &ref)
7624 ! eRawFile *f = new eRawFile();
7625 ! f->open(ref.path.c_str());
7626 ! return ePtr<iTsSource>(f);
7629 ! void eDVBServicePlay::switchToTimeshift()
7631 ! if (m_timeshift_active)
7632 ! return;
7634 ! resetTimeshift(1);
7636 ! eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
7637 ! r.path = m_timeshift_file;
7639 ! m_cue->seekTo(0, -1000);
7641 ! ePtr<iTsSource> source = createTsSource(r);
7642 ! m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
7644 ! eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
7645 ! pause();
7646 ! updateDecoder(true); /* mainly to switch off PCR, and to set pause */
7649 ! void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
7651 ! int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
7652 ! bool mustPlay = false;
7654 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
7656 ! eDVBServicePMTHandler::program program;
7657 ! if (h.getProgramInfo(program))
7658 ! eDebug("getting program info failed.");
7659 ! else
7661 ! eDebugNoNewLine("have %zd video stream(s)", program.videoStreams.size());
7662 ! if (!program.videoStreams.empty())
7664 ! eDebugNoNewLine(" (");
7665 ! for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
7666 ! i(program.videoStreams.begin());
7667 ! i != program.videoStreams.end(); ++i)
7669 ! if (vpid == -1)
7671 ! vpid = i->pid;
7672 ! vpidtype = i->type;
7674 ! if (i != program.videoStreams.begin())
7675 ! eDebugNoNewLine(", ");
7676 ! eDebugNoNewLine("%04x", i->pid);
7678 ! eDebugNoNewLine(")");
7680 ! eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
7681 ! if (!program.audioStreams.empty())
7683 ! eDebugNoNewLine(" (");
7684 ! for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
7685 ! i(program.audioStreams.begin());
7686 ! i != program.audioStreams.end(); ++i)
7688 ! if (i != program.audioStreams.begin())
7689 ! eDebugNoNewLine(", ");
7690 ! eDebugNoNewLine("%04x", i->pid);
7692 ! eDebugNoNewLine(")");
7694 ! eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
7695 ! pcrpid = program.pcrPid;
7696 ! eDebug(", and the text pid is %04x", program.textPid);
7697 ! tpid = program.textPid;
7700 ! if (!m_decoder)
7702 ! m_decoder = new eTSMPEGDecoder(m_is_primary ? 0 : 1);
7704 ! if (!m_is_pvr) {
7705 ! h.getDecodeDemux(m_decode_demux);
7706 ! if (m_decode_demux)
7708 ! if (m_is_primary)
7710 ! m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
7711 ! m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
7712 ! m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
7713 ! m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
7714 ! if (m_timeshift_changed)
7716 ! ePyObject subs = getCachedSubtitle();
7717 ! if (subs != Py_None)
7719 ! int type = PyInt_AsLong(PyTuple_GET_ITEM(subs, 0)),
7720 ! pid = PyInt_AsLong(PyTuple_GET_ITEM(subs, 1)),
7721 ! comp_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 2)), // ttx page
7722 ! anc_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 3)); // ttx magazine
7723 ! if (type == 0) // dvb
7724 ! m_subtitle_parser->start(pid, comp_page, anc_page);
7725 ! else if (type == 1) // ttx
7726 ! m_teletext_parser->setPageAndMagazine(comp_page, anc_page);
7728 ! Py_DECREF(subs);
7733 ! if (m_cue)
7734 ! m_cue->setDecodingDemux(m_decode_demux, m_decoder);
7737 ! mustPlay = true;
7740 ! m_timeshift_changed = 0;
7742 ! if (m_decoder)
7744 ! bool wasSeekable = m_decoder->getVideoProgressive() != -1;
7745 ! if (m_dvb_service)
7747 ! achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
7748 ! ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
7749 ! pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
7751 ! else // subservice
7753 ! eServiceReferenceDVB ref;
7754 ! m_service_handler.getServiceReference(ref);
7755 ! eServiceReferenceDVB parent = ref.getParentServiceReference();
7756 ! if (!parent)
7757 ! parent = ref;
7758 ! if (parent)
7760 ! ePtr<eDVBResourceManager> res_mgr;
7761 ! if (!eDVBResourceManager::getInstance(res_mgr))
7763 ! ePtr<iDVBChannelList> db;
7764 ! if (!res_mgr->getChannelList(db))
7766 ! ePtr<eDVBService> origService;
7767 ! if (!db->getService(parent, origService))
7769 ! ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
7770 ! pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
7777 ! setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
7778 ! setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
7780 ! m_decoder->setVideoPID(vpid, vpidtype);
7781 ! selectAudioStream();
7783 ! if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
7784 ! m_decoder->setSyncPCR(pcrpid);
7785 ! else
7786 ! m_decoder->setSyncPCR(-1);
7788 ! if (m_is_primary && m_decode_demux && !m_is_pvr)
7790 ! m_decoder->setTextPID(tpid);
7791 ! m_teletext_parser->start(program.textPid);
7794 ! if (vpid > 0 && vpid < 0x2000)
7796 ! else
7798 ! std::string radio_pic;
7799 ! if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
7800 ! m_decoder->setRadioPic(radio_pic);
7803 ! printf("mustPlay %d\n", mustPlay);
7804 ! if (mustPlay)
7805 ! m_decoder->play();
7806 ! else
7807 ! m_decoder->set();
7809 ! m_decoder->setAudioChannel(achannel);
7811 ! /* don't worry about non-existing services, nor pvr services */
7812 ! if (m_dvb_service)
7814 ! /* (audio pid will be set in selectAudioTrack */
7815 ! m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
7816 ! m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
7817 ! m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
7818 ! m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
7820 ! if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
7821 ! sendSeekableStateChanged = true;
7823 ! m_have_video_pid = (vpid > 0 && vpid < 0x2000);
7825 ! if (sendSeekableStateChanged)
7826 ! m_event((iPlayableService*)this, evSeekableStatusChanged);
7829 ! void eDVBServicePlay::loadCuesheet()
7831 ! std::string filename = m_reference.path + ".cuts";
7833 ! m_cue_entries.clear();
7835 ! FILE *f = fopen(filename.c_str(), "rb");
7837 ! if (f)
7839 ! eDebug("loading cuts..");
7840 ! while (1)
7842 ! unsigned long long where;
7843 ! unsigned int what;
7845 ! if (!fread(&where, sizeof(where), 1, f))
7846 ! break;
7847 ! if (!fread(&what, sizeof(what), 1, f))
7848 ! break;
7850 ! #if BYTE_ORDER == LITTLE_ENDIAN
7851 ! where = bswap_64(where);
7852 ! #endif
7853 ! what = ntohl(what);
7855 ! if (what > 3)
7856 ! break;
7858 ! m_cue_entries.insert(cueEntry(where, what));
7860 ! fclose(f);
7861 ! eDebug("%zd entries", m_cue_entries.size());
7862 ! } else
7863 ! eDebug("cutfile not found!");
7865 ! m_cuesheet_changed = 0;
7866 ! cutlistToCuesheet();
7867 ! m_event((iPlayableService*)this, evCuesheetChanged);
7870 ! void eDVBServicePlay::saveCuesheet()
7872 ! std::string filename = m_reference.path + ".cuts";
7874 ! FILE *f = fopen(filename.c_str(), "wb");
7876 ! if (f)
7878 ! unsigned long long where;
7879 ! int what;
7881 ! for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
7883 ! #if BYTE_ORDER == BIG_ENDIAN
7884 ! where = i->where;
7885 ! #else
7886 ! where = bswap_64(i->where);
7887 ! #endif
7888 ! what = htonl(i->what);
7889 ! fwrite(&where, sizeof(where), 1, f);
7890 ! fwrite(&what, sizeof(what), 1, f);
7893 ! fclose(f);
7896 ! m_cuesheet_changed = 0;
7899 ! void eDVBServicePlay::cutlistToCuesheet()
7901 ! if (!m_cue)
7903 ! eDebug("no cue sheet");
7904 ! return;
7905 ! }
7906 ! m_cue->clear();
7908 ! if (!m_cutlist_enabled)
7910 ! m_cue->commitSpans();
7911 ! eDebug("cutlists were disabled");
7912 ! return;
7915 ! pts_t in = 0, out = 0, length = 0;
7917 ! getLength(length);
7919 ! std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
7921 ! int have_any_span = 0;
7923 ! while (1)
7925 ! if (i == m_cue_entries.end())
7927 ! if (!have_any_span && !in)
7928 ! break;
7929 ! out = length;
7930 ! } else {
7931 ! if (i->what == 0) /* in */
7933 ! in = i++->where;
7934 ! continue;
7935 ! } else if (i->what == 1) /* out */
7936 ! out = i++->where;
7937 ! else /* mark (2) or last play position (3) */
7939 ! i++;
7940 ! continue;
7944 ! if (in < 0)
7945 ! in = 0;
7946 ! if (out < 0)
7947 ! out = 0;
7948 ! if (in > length)
7949 ! in = length;
7950 ! if (out > length)
7951 ! out = length;
7953 ! if (in < out)
7955 ! have_any_span = 1;
7956 ! m_cue->addSourceSpan(in, out);
7957 ! in = out = 0;
7960 ! in = length;
7962 ! if (i == m_cue_entries.end())
7963 ! break;
7965 ! m_cue->commitSpans();
7968 ! RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
7970 ! if (m_subtitle_widget)
7971 ! disableSubtitles(parent);
7973 ! ePyObject entry;
7974 ! int tuplesize = PyTuple_Size(tuple);
7975 ! int type = 0;
7977 ! if (!PyTuple_Check(tuple))
7978 ! goto error_out;
7980 ! if (tuplesize < 1)
7981 ! goto error_out;
7983 ! entry = PyTuple_GET_ITEM(tuple, 0);
7985 ! if (!PyInt_Check(entry))
7986 ! goto error_out;
7988 ! type = PyInt_AsLong(entry);
7990 ! if (type == 1) // teletext subtitles
7992 ! int page, magazine, pid;
7993 ! if (tuplesize < 4)
7994 ! goto error_out;
7996 ! if (!m_teletext_parser)
7998 ! eDebug("enable teletext subtitles.. no parser !!!");
7999 ! return -1;
8002 ! entry = PyTuple_GET_ITEM(tuple, 1);
8003 ! if (!PyInt_Check(entry))
8004 ! goto error_out;
8005 ! pid = PyInt_AsLong(entry);
8007 ! entry = PyTuple_GET_ITEM(tuple, 2);
8008 ! if (!PyInt_Check(entry))
8009 ! goto error_out;
8010 ! page = PyInt_AsLong(entry);
8012 ! entry = PyTuple_GET_ITEM(tuple, 3);
8013 ! if (!PyInt_Check(entry))
8014 ! goto error_out;
8015 ! magazine = PyInt_AsLong(entry);
8017 ! m_subtitle_widget = new eSubtitleWidget(parent);
8018 ! m_subtitle_widget->resize(parent->size()); /* full size */
8019 ! m_teletext_parser->setPageAndMagazine(page, magazine);
8020 ! if (m_dvb_service)
8021 ! m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
8023 ! else if (type == 0)
8025 ! int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
8026 ! if (!m_subtitle_parser)
8028 ! eDebug("enable dvb subtitles.. no parser !!!");
8029 ! return -1;
8031 ! if (tuplesize < 4)
8032 ! goto error_out;
8034 ! entry = PyTuple_GET_ITEM(tuple, 1);
8035 ! if (!PyInt_Check(entry))
8036 ! goto error_out;
8037 ! pid = PyInt_AsLong(entry);
8039 ! entry = PyTuple_GET_ITEM(tuple, 2);
8040 ! if (!PyInt_Check(entry))
8041 ! goto error_out;
8042 ! composition_page_id = PyInt_AsLong(entry);
8044 ! entry = PyTuple_GET_ITEM(tuple, 3);
8045 ! if (!PyInt_Check(entry))
8046 ! goto error_out;
8047 ! ancillary_page_id = PyInt_AsLong(entry);
8049 ! m_subtitle_widget = new eSubtitleWidget(parent);
8050 ! m_subtitle_widget->resize(parent->size()); /* full size */
8051 ! m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
8052 ! if (m_dvb_service)
8053 ! m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
8055 ! else
8056 ! goto error_out;
8057 ! return 0;
8058 ! error_out:
8059 ! eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
8060 ! "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
8061 ! "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
8062 ! return -1;
8065 ! RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
8067 ! delete m_subtitle_widget;
8068 ! m_subtitle_widget = 0;
8069 ! if (m_subtitle_parser)
8071 ! m_subtitle_parser->stop();
8072 ! m_dvb_subtitle_pages.clear();
8074 ! if (m_teletext_parser)
8076 ! m_teletext_parser->setPageAndMagazine(-1, -1);
8077 ! m_subtitle_pages.clear();
8079 ! if (m_dvb_service)
8080 ! m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
8081 ! return 0;
8084 ! PyObject *eDVBServicePlay::getCachedSubtitle()
8086 ! if (m_dvb_service)
8088 ! int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
8089 ! if (tmp != -1)
8091 ! unsigned int data = (unsigned int)tmp;
8092 ! int pid = (data&0xFFFF0000)>>16;
8093 ! ePyObject tuple = PyTuple_New(4);
8094 ! eDVBServicePMTHandler::program program;
8095 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
8096 ! if (!h.getProgramInfo(program))
8098 ! if (program.textPid==pid) // teletext
8099 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
8100 ! else
8101 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
8102 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(pid)); // pid
8103 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
8104 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
8105 ! return tuple;
8109 ! Py_RETURN_NONE;
8112 ! PyObject *eDVBServicePlay::getSubtitleList()
8114 ! if (!m_teletext_parser)
8115 ! Py_RETURN_NONE;
8117 ! ePyObject l = PyList_New(0);
8118 ! std::set<int> added_ttx_pages;
8120 ! std::set<eDVBServicePMTHandler::subtitleStream> &subs =
8121 ! m_teletext_parser->m_found_subtitle_pages;
8123 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
8124 ! eDVBServicePMTHandler::program program;
8125 ! if (h.getProgramInfo(program))
8126 ! eDebug("getting program info failed.");
8127 ! else
8129 ! for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
8130 ! it != program.subtitleStreams.end(); ++it)
8132 ! switch(it->subtitling_type)
8134 ! case 0x01: // ebu teletext subtitles
8136 ! int page_number = it->teletext_page_number & 0xFF;
8137 ! int magazine_number = it->teletext_magazine_number & 7;
8138 ! int hash = magazine_number << 8 | page_number;
8139 ! if (added_ttx_pages.find(hash) == added_ttx_pages.end())
8141 ! ePyObject tuple = PyTuple_New(5);
8142 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
8143 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
8144 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
8145 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
8146 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
8147 ! PyList_Append(l, tuple);
8148 ! Py_DECREF(tuple);
8149 ! added_ttx_pages.insert(hash);
8151 ! break;
8153 ! case 0x10 ... 0x13:
8154 ! case 0x20 ... 0x23: // dvb subtitles
8156 ! ePyObject tuple = PyTuple_New(5);
8157 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
8158 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
8159 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
8160 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
8161 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
8162 ! PyList_Insert(l, 0, tuple);
8163 ! Py_DECREF(tuple);
8164 ! break;
8170 ! for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
8171 ! it != subs.end(); ++it)
8173 ! int page_number = it->teletext_page_number & 0xFF;
8174 ! int magazine_number = it->teletext_magazine_number & 7;
8175 ! int hash = magazine_number << 8 | page_number;
8176 ! if (added_ttx_pages.find(hash) == added_ttx_pages.end())
8178 ! ePyObject tuple = PyTuple_New(5);
8179 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
8180 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
8181 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
8182 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
8183 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
8184 ! PyList_Append(l, tuple);
8185 ! Py_DECREF(tuple);
8189 ! return l;
8192 ! void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
8194 ! if (m_subtitle_widget)
8196 ! pts_t pos = 0;
8197 ! //if (m_decoder)
8198 ! // m_decoder->getPTS(0, pos);
8199 ! xineLib->getPTS(pos);
8200 ! eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
8201 ! m_subtitle_pages.push_back(page);
8202 ! checkSubtitleTiming();
8206 ! void eDVBServicePlay::checkSubtitleTiming()
8208 ! eDebug("checkSubtitleTiming");
8209 ! if (!m_subtitle_widget)
8210 ! return;
8211 ! while (1)
8213 ! enum { TELETEXT, DVB } type;
8214 ! eDVBTeletextSubtitlePage page;
8215 ! eDVBSubtitlePage dvb_page;
8216 ! pts_t show_time;
8217 ! if (!m_subtitle_pages.empty())
8219 ! page = m_subtitle_pages.front();
8220 ! type = TELETEXT;
8221 ! show_time = page.m_pts;
8223 ! else if (!m_dvb_subtitle_pages.empty())
8225 ! dvb_page = m_dvb_subtitle_pages.front();
8226 ! type = DVB;
8227 ! show_time = dvb_page.m_show_time;
8229 ! else
8230 ! return;
8232 ! pts_t pos = 0;
8234 ! //if (m_decoder)
8235 ! // m_decoder->getPTS(0, pos);
8236 ! xineLib->getPTS(pos);
8238 ! eDebug("%lld %lld", pos, show_time);
8239 ! int diff = show_time - pos;
8240 ! if (type == TELETEXT && !page.m_have_pts)
8242 ! eDebug("ttx subtitle page without pts... immediate show");
8243 ! diff = 0;
8245 ! if (diff < 0)
8247 ! eDebug("[late (%d ms)]", -diff / 90);
8248 ! diff = 0;
8250 ! if (abs(diff) > 1800000)
8252 ! eDebug("[invalid]... immediate show!");
8253 ! diff = 0;
8255 ! if ((diff/90)<20)
8257 ! if (type == TELETEXT)
8259 ! eDebug("display teletext subtitle page %lld", show_time);
8260 ! m_subtitle_widget->setPage(page);
8261 ! m_subtitle_pages.pop_front();
8263 ! else
8265 ! eDebug("display dvb subtitle Page %lld", show_time);
8266 ! m_subtitle_widget->setPage(dvb_page);
8267 ! m_dvb_subtitle_pages.pop_front();
8269 ! } else
8271 ! eDebug("start subtitle delay %d", diff / 90);
8272 ! m_subtitle_sync_timer->start(diff / 90, 1);
8273 ! break;
8278 ! void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
8280 ! if (m_subtitle_widget)
8282 ! pts_t pos = 0;
8283 ! //if (m_decoder)
8284 ! // m_decoder->getPTS(0, pos);
8285 ! xineLib->getPTS(pos);
8286 ! eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
8287 ! m_dvb_subtitle_pages.push_back(p);
8288 ! checkSubtitleTiming();
8292 ! int eDVBServicePlay::getAC3Delay()
8294 ! if (m_dvb_service)
8295 ! return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
8296 ! else if (m_decoder)
8297 ! return m_decoder->getAC3Delay();
8298 ! else
8299 ! return 0;
8302 ! int eDVBServicePlay::getPCMDelay()
8304 ! if (m_dvb_service)
8305 ! return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
8306 ! else if (m_decoder)
8307 ! return m_decoder->getPCMDelay();
8308 ! else
8309 ! return 0;
8312 ! void eDVBServicePlay::setAC3Delay(int delay)
8314 ! if (m_dvb_service)
8315 ! m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
8316 ! if (m_decoder) {
8317 ! std::string config_delay;
8318 ! int config_delay_int = 0;
8319 ! if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
8320 ! config_delay_int = atoi(config_delay.c_str());
8321 ! m_decoder->setAC3Delay(delay + config_delay_int);
8325 ! void eDVBServicePlay::setPCMDelay(int delay)
8327 ! if (m_dvb_service)
8328 ! m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
8329 ! if (m_decoder) {
8330 ! std::string config_delay;
8331 ! int config_delay_int = 0;
8332 ! if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
8333 ! config_delay_int = atoi(config_delay.c_str());
8334 ! else
8335 ! config_delay_int = 0;
8336 ! m_decoder->setPCMDelay(delay + config_delay_int);
8340 ! void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
8342 ! switch(event.type) {
8343 ! case iTSMPEGDecoder::videoEvent::eventSizeChanged:
8344 ! m_event((iPlayableService*)this, evVideoSizeChanged);
8345 ! break;
8346 ! case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
8347 ! m_event((iPlayableService*)this, evVideoFramerateChanged);
8348 ! break;
8349 ! case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
8350 ! m_event((iPlayableService*)this, evVideoProgressiveChanged);
8351 ! break;
8352 ! default:
8353 ! break;
8357 ! RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
8359 ! ptr = this;
8360 ! return 0;
8363 ! PyObject *eDVBServicePlay::getStreamingData()
8365 ! eDVBServicePMTHandler::program program;
8366 ! if (m_service_handler.getProgramInfo(program))
8368 ! Py_RETURN_NONE;
8371 ! ePyObject r = program.createPythonObject();
8372 ! ePtr<iDVBDemux> demux;
8373 ! if (!m_service_handler.getDataDemux(demux))
8375 ! uint8_t demux_id;
8376 ! if (!demux->getCADemuxID(demux_id))
8377 ! PutToDict(r, "demux", demux_id);
8380 ! return r;
8384 ! DEFINE_REF(eDVBServicePlay)
8386 ! PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
8388 ! switch (w)
8390 ! case iServiceInformation::sTransponderData:
8391 ! return eStaticServiceDVBInformation().getInfoObject(ref, w);
8392 ! default:
8393 ! break;
8395 ! return iStaticServiceInformation::getInfoObject(ref, w);
8398 ! eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");
8399 --- 1,3187 ----
8400 ! #include <lib/base/eerror.h>
8401 ! #include <lib/base/object.h>
8402 ! #include <string>
8403 ! #include <lib/service/servicedvb.h>
8404 ! #include <lib/service/service.h>
8405 ! #include <lib/base/estring.h>
8406 ! #include <lib/base/init_num.h>
8407 ! #include <lib/base/init.h>
8408 ! #include <lib/dvb/dvb.h>
8409 ! #include <lib/dvb/db.h>
8410 ! #include <lib/dvb/decoder.h>
8412 ! #include <lib/components/file_eraser.h>
8413 ! #include <lib/service/servicedvbrecord.h>
8414 ! #include <lib/service/event.h>
8415 ! #include <lib/dvb/metaparser.h>
8416 ! #include <lib/dvb/tstools.h>
8417 ! #include <lib/python/python.h>
8418 ! #include <lib/base/nconfig.h> // access to python config
8420 ! /* for subtitles */
8421 ! #include <lib/gui/esubtitle.h>
8423 ! #include <sys/vfs.h>
8424 ! #include <sys/stat.h>
8426 ! #include <byteswap.h>
8427 ! #include <netinet/in.h>
8429 ! #ifndef BYTE_ORDER
8430 ! #error no byte order defined!
8431 ! #endif
8433 ! class eStaticServiceDVBInformation: public iStaticServiceInformation
8435 ! DECLARE_REF(eStaticServiceDVBInformation);
8436 ! public:
8437 ! RESULT getName(const eServiceReference &ref, std::string &name);
8438 ! int getLength(const eServiceReference &ref);
8439 ! int isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
8440 ! PyObject *getInfoObject(const eServiceReference &ref, int);
8441 ! };
8443 ! DEFINE_REF(eStaticServiceDVBInformation);
8445 ! RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
8447 ! eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
8448 ! if ( !ref.name.empty() )
8450 ! if (service.getParentTransportStreamID().get()) // linkage subservice
8452 ! ePtr<iServiceHandler> service_center;
8453 ! if (!eServiceCenter::getInstance(service_center))
8455 ! eServiceReferenceDVB parent = service;
8456 ! parent.setTransportStreamID( service.getParentTransportStreamID() );
8457 ! parent.setServiceID( service.getParentServiceID() );
8458 ! parent.setParentTransportStreamID(eTransportStreamID(0));
8459 ! parent.setParentServiceID(eServiceID(0));
8460 ! parent.name="";
8461 ! ePtr<iStaticServiceInformation> service_info;
8462 ! if (!service_center->info(parent, service_info))
8464 ! if (!service_info->getName(parent, name))
8465 ! name=buildShortName(name) + " - ";
8469 ! else
8470 ! name="";
8471 ! name += ref.name;
8472 ! return 0;
8474 ! else
8475 ! return -1;
8478 ! int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
8480 ! return -1;
8483 ! int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore)
8485 ! ePtr<eDVBResourceManager> res_mgr;
8486 ! if ( eDVBResourceManager::getInstance( res_mgr ) )
8487 ! eDebug("isPlayable... no res manager!!");
8488 ! else
8490 ! eDVBChannelID chid, chid_ignore;
8491 ! ((const eServiceReferenceDVB&)ref).getChannelID(chid);
8492 ! ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
8493 ! return res_mgr->canAllocateChannel(chid, chid_ignore);
8495 ! return false;
8498 ! extern void PutToDict(ePyObject &dict, const char*key, long value); // defined in dvb/frontend.cpp
8499 ! extern void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm); // defined in dvb/frontend.cpp
8500 ! extern void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm); // defined in dvb/frontend.cpp
8501 ! extern void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm); // defined in dvb/frontend.cpp
8503 ! PyObject *eStaticServiceDVBInformation::getInfoObject(const eServiceReference &r, int what)
8505 ! if (r.type == eServiceReference::idDVB)
8507 ! const eServiceReferenceDVB &ref = (const eServiceReferenceDVB&)r;
8508 ! switch(what)
8510 ! case iServiceInformation::sTransponderData:
8512 ! ePtr<eDVBResourceManager> res;
8513 ! if (!eDVBResourceManager::getInstance(res))
8515 ! ePtr<iDVBChannelList> db;
8516 ! if (!res->getChannelList(db))
8518 ! eDVBChannelID chid;
8519 ! ref.getChannelID(chid);
8520 ! ePtr<iDVBFrontendParameters> feparm;
8521 ! if (!db->getChannelFrontendData(chid, feparm))
8523 ! int system;
8524 ! if (!feparm->getSystem(system))
8526 ! ePyObject dict = PyDict_New();
8527 ! switch(system)
8529 ! case iDVBFrontend::feSatellite:
8531 ! eDVBFrontendParametersSatellite s;
8532 ! feparm->getDVBS(s);
8533 ! PutSatelliteDataToDict(dict, s);
8534 ! break;
8536 ! case iDVBFrontend::feTerrestrial:
8538 ! eDVBFrontendParametersTerrestrial t;
8539 ! feparm->getDVBT(t);
8540 ! PutTerrestrialDataToDict(dict, t);
8541 ! break;
8543 ! case iDVBFrontend::feCable:
8545 ! eDVBFrontendParametersCable c;
8546 ! feparm->getDVBC(c);
8547 ! PutCableDataToDict(dict, c);
8548 ! break;
8550 ! default:
8551 ! eDebug("unknown frontend type %d", system);
8552 ! Py_DECREF(dict);
8553 ! break;
8555 ! return dict;
8563 ! Py_RETURN_NONE;
8566 ! DEFINE_REF(eStaticServiceDVBBouquetInformation);
8568 ! RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
8570 ! ePtr<iDVBChannelList> db;
8571 ! ePtr<eDVBResourceManager> res;
8573 ! int err;
8574 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
8576 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
8577 ! return err;
8579 ! if ((err = res->getChannelList(db)) != 0)
8581 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
8582 ! return err;
8585 ! eBouquet *bouquet=0;
8586 ! if ((err = db->getBouquet(ref, bouquet)) != 0)
8588 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
8589 ! return -1;
8592 ! if ( bouquet && bouquet->m_bouquet_name.length() )
8594 ! name = bouquet->m_bouquet_name;
8595 ! return 0;
8597 ! else
8598 ! return -1;
8601 ! int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
8603 ! if (ref.flags & eServiceReference::isGroup)
8605 ! ePtr<iDVBChannelList> db;
8606 ! ePtr<eDVBResourceManager> res;
8608 ! if (eDVBResourceManager::getInstance(res))
8610 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no resource manager!");
8611 ! return 0;
8614 ! if (res->getChannelList(db))
8616 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no channel list!");
8617 ! return 0;
8620 ! eBouquet *bouquet=0;
8621 ! if (db->getBouquet(ref, bouquet))
8623 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. getBouquet failed!");
8624 ! return 0;
8627 ! int prio_order = eDVBFrontend::getTypePriorityOrder();
8628 ! int cur=0;
8629 ! eDVBChannelID chid, chid_ignore;
8630 ! ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
8631 ! for (std::list<eServiceReference>::iterator it(bouquet->m_services.begin()); it != bouquet->m_services.end(); ++it)
8633 ! static unsigned char prio_map[6][3] = {
8634 ! { 3, 2, 1 }, // -S -C -T
8635 ! { 3, 1, 2 }, // -S -T -C
8636 ! { 2, 3, 1 }, // -C -S -T
8637 ! { 1, 3, 2 }, // -C -T -S
8638 ! { 1, 2, 3 }, // -T -C -S
8639 ! { 2, 1, 3 } // -T -S -C
8640 ! };
8641 ! ((const eServiceReferenceDVB&)*it).getChannelID(chid);
8642 ! int tmp=res->canAllocateChannel(chid, chid_ignore, simulate);
8643 ! switch(tmp)
8645 ! case 0:
8646 ! break;
8647 ! case 30000: // cached DVB-T channel
8648 ! case 1: // DVB-T frontend
8649 ! tmp = prio_map[prio_order][2];
8650 ! break;
8651 ! case 40000: // cached DVB-C channel
8652 ! case 2:
8653 ! tmp = prio_map[prio_order][1];
8654 ! break;
8655 ! default: // DVB-S
8656 ! tmp = prio_map[prio_order][0];
8657 ! break;
8659 ! if (tmp > cur)
8661 ! m_playable_service = *it;
8662 ! cur = tmp;
8665 ! if (cur)
8666 ! return cur;
8668 ! m_playable_service = eServiceReference();
8669 ! return 0;
8672 ! int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
8674 ! return -1;
8677 ! #include <lib/dvb/epgcache.h>
8679 ! RESULT eStaticServiceDVBBouquetInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time)
8681 ! return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr);
8684 ! class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
8686 ! DECLARE_REF(eStaticServiceDVBPVRInformation);
8687 ! eServiceReference m_ref;
8688 ! eDVBMetaParser m_parser;
8689 ! public:
8690 ! eStaticServiceDVBPVRInformation(const eServiceReference &ref);
8691 ! RESULT getName(const eServiceReference &ref, std::string &name);
8692 ! int getLength(const eServiceReference &ref);
8693 ! RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time);
8694 ! int isPlayable(const eServiceReference &ref, const eServiceReference &ignore) { return 1; }
8695 ! int getInfo(const eServiceReference &ref, int w);
8696 ! std::string getInfoString(const eServiceReference &ref,int w);
8697 ! PyObject *getInfoObject(const eServiceReference &r, int what);
8698 ! };
8700 ! DEFINE_REF(eStaticServiceDVBPVRInformation);
8702 ! eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
8704 ! m_ref = ref;
8705 ! m_parser.parseFile(ref.path);
8708 ! RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
8710 ! ASSERT(ref == m_ref);
8711 ! if (!ref.name.empty())
8712 ! name = ref.name;
8713 ! else if (!m_parser.m_name.empty())
8714 ! name = m_parser.m_name;
8715 ! else
8717 ! name = ref.path;
8718 ! size_t n = name.rfind('/');
8719 ! if (n != std::string::npos)
8720 ! name = name.substr(n + 1);
8722 ! return 0;
8725 ! int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
8727 ! ASSERT(ref == m_ref);
8729 ! eDVBTSTools tstools;
8731 ! struct stat s;
8732 ! stat(ref.path.c_str(), &s);
8734 ! if (tstools.openFile(ref.path.c_str(), 1))
8735 ! return 0;
8737 ! /* check if cached data is still valid */
8738 ! if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length))
8739 ! return m_parser.m_length / 90000;
8741 ! /* open again, this time with stream info */
8742 ! if (tstools.openFile(ref.path.c_str()))
8743 ! return 0;
8745 ! /* otherwise, re-calc length and update meta file */
8746 ! pts_t len;
8747 ! if (tstools.calcLen(len))
8748 ! return 0;
8750 ! m_parser.m_length = len;
8751 ! m_parser.m_filesize = s.st_size;
8752 ! m_parser.updateMeta(ref.path);
8753 ! return m_parser.m_length / 90000;
8756 ! int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
8758 ! switch (w)
8760 ! case iServiceInformation::sDescription:
8761 ! return iServiceInformation::resIsString;
8762 ! case iServiceInformation::sServiceref:
8763 ! return iServiceInformation::resIsString;
8764 ! case iServiceInformation::sFileSize:
8765 ! return m_parser.m_filesize;
8766 ! case iServiceInformation::sTimeCreate:
8767 ! if (m_parser.m_time_create)
8768 ! return m_parser.m_time_create;
8769 ! else
8770 ! return iServiceInformation::resNA;
8771 ! default:
8772 ! return iServiceInformation::resNA;
8776 ! std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
8778 ! switch (w)
8780 ! case iServiceInformation::sDescription:
8781 ! return m_parser.m_description;
8782 ! case iServiceInformation::sServiceref:
8783 ! return m_parser.m_ref.toString();
8784 ! case iServiceInformation::sTags:
8785 ! return m_parser.m_tags;
8786 ! default:
8787 ! return "";
8791 ! PyObject *eStaticServiceDVBPVRInformation::getInfoObject(const eServiceReference &r, int what)
8793 ! switch (what)
8795 ! case iServiceInformation::sFileSize:
8796 ! return PyLong_FromLongLong(m_parser.m_filesize);
8797 ! default:
8798 ! Py_RETURN_NONE;
8802 ! RESULT eStaticServiceDVBPVRInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
8804 ! if (!ref.path.empty())
8806 ! ePtr<eServiceEvent> event = new eServiceEvent;
8807 ! std::string filename = ref.path;
8808 ! filename.erase(filename.length()-2, 2);
8809 ! filename+="eit";
8810 ! if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
8812 ! evt = event;
8813 ! return 0;
8816 ! evt = 0;
8817 ! return -1;
8820 ! class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
8822 ! DECLARE_REF(eDVBPVRServiceOfflineOperations);
8823 ! eServiceReferenceDVB m_ref;
8824 ! public:
8825 ! eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
8827 ! RESULT deleteFromDisk(int simulate);
8828 ! RESULT getListOfFilenames(std::list<std::string> &);
8829 ! RESULT reindex();
8830 ! };
8832 ! DEFINE_REF(eDVBPVRServiceOfflineOperations);
8834 ! eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
8838 ! RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
8840 ! if (simulate)
8841 ! return 0;
8842 ! else
8844 ! std::list<std::string> res;
8845 ! if (getListOfFilenames(res))
8846 ! return -1;
8848 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
8849 ! if (!eraser)
8850 ! eDebug("FATAL !! can't get background file eraser");
8852 ! for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
8854 ! eDebug("Removing %s...", i->c_str());
8855 ! if (eraser)
8856 ! eraser->erase(i->c_str());
8857 ! else
8858 ! ::unlink(i->c_str());
8861 ! return 0;
8865 ! RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
8867 ! res.clear();
8868 ! res.push_back(m_ref.path);
8870 ! // handling for old splitted recordings (enigma 1)
8871 ! char buf[255];
8872 ! int slice=1;
8873 ! while(true)
8875 ! snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
8876 ! struct stat s;
8877 ! if (stat(buf, &s) < 0)
8878 ! break;
8879 ! res.push_back(buf);
8880 ! }
8882 ! res.push_back(m_ref.path + ".meta");
8883 ! res.push_back(m_ref.path + ".ap");
8884 ! res.push_back(m_ref.path + ".sc");
8885 ! res.push_back(m_ref.path + ".cuts");
8886 ! std::string tmp = m_ref.path;
8887 ! tmp.erase(m_ref.path.length()-3);
8888 ! res.push_back(tmp + ".eit");
8889 ! return 0;
8892 ! RESULT eDVBPVRServiceOfflineOperations::reindex()
8894 ! const char *filename = m_ref.path.c_str();
8895 ! eDebug("reindexing %s...", filename);
8897 ! eMPEGStreamInformation info;
8898 ! eMPEGStreamParserTS parser(info);
8900 ! info.startSave(filename);
8902 ! eRawFile f;
8904 ! int err = f.open(m_ref.path.c_str(), 0);
8905 ! if (err < 0)
8906 ! return -1;
8908 ! off_t offset = 0;
8909 ! off_t length = f.length();
8910 ! unsigned char buffer[188*256*4];
8911 ! while (1)
8913 ! eDebug("at %08llx / %08llx (%d %%)", offset, length, (int)(offset * 100 / length));
8914 ! int r = f.read(offset, buffer, sizeof(buffer));
8915 ! if (!r)
8916 ! break;
8917 ! if (r < 0)
8918 ! return r;
8919 ! offset += r;
8920 ! parser.parseData(offset, buffer, r);
8923 ! info.stopSave();
8924 ! f.close();
8926 ! return 0;
8929 ! DEFINE_REF(eServiceFactoryDVB)
8931 ! eServiceFactoryDVB::eServiceFactoryDVB()
8933 ! ePtr<eServiceCenter> sc;
8935 ! eServiceCenter::getPrivInstance(sc);
8936 ! if (sc)
8938 ! std::list<std::string> extensions;
8939 ! extensions.push_back("ts");
8940 ! extensions.push_back("trp");
8941 ! sc->addServiceFactory(eServiceFactoryDVB::id, this, extensions);
8944 ! m_StaticServiceDVBInfo = new eStaticServiceDVBInformation;
8945 ! m_StaticServiceDVBBouquetInfo = new eStaticServiceDVBBouquetInformation;
8948 ! eServiceFactoryDVB::~eServiceFactoryDVB()
8950 ! ePtr<eServiceCenter> sc;
8952 ! eServiceCenter::getPrivInstance(sc);
8953 ! if (sc)
8954 ! sc->removeServiceFactory(eServiceFactoryDVB::id);
8957 ! DEFINE_REF(eDVBServiceList);
8959 ! eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
8963 ! eDVBServiceList::~eDVBServiceList()
8967 ! RESULT eDVBServiceList::startQuery()
8969 ! ePtr<iDVBChannelList> db;
8970 ! ePtr<eDVBResourceManager> res;
8972 ! int err;
8973 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
8975 ! eDebug("no resource manager");
8976 ! return err;
8978 ! if ((err = res->getChannelList(db)) != 0)
8980 ! eDebug("no channel list");
8981 ! return err;
8984 ! ePtr<eDVBChannelQuery> q;
8986 ! if (!m_parent.path.empty())
8988 ! eDVBChannelQuery::compile(q, m_parent.path);
8989 ! if (!q)
8991 ! eDebug("compile query failed");
8992 ! return err;
8996 ! if ((err = db->startQuery(m_query, q, m_parent)) != 0)
8998 ! eDebug("startQuery failed");
8999 ! return err;
9002 ! return 0;
9005 ! RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
9007 ! eServiceReferenceDVB ref;
9009 ! if (!m_query)
9010 ! return -1;
9012 ! while (!m_query->getNextResult(ref))
9013 ! list.push_back(ref);
9015 ! if (sorted)
9016 ! list.sort(iListableServiceCompare(this));
9018 ! return 0;
9021 ! // The first argument of this function is a format string to specify the order and
9022 ! // the content of the returned list
9023 ! // useable format options are
9024 ! // R = Service Reference (as swig object .. this is very slow)
9025 ! // S = Service Reference (as python string object .. same as ref.toString())
9026 ! // C = Service Reference (as python string object .. same as ref.toCompareString())
9027 ! // N = Service Name (as python string object)
9028 ! // n = Short Service Name (short name brakets used) (as python string object)
9029 ! // when exactly one return value per service is selected in the format string,
9030 ! // then each value is directly a list entry
9031 ! // when more than one value is returned per service, then the list is a list of
9032 ! // python tuples
9033 ! // unknown format string chars are returned as python None values !
9034 ! PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
9036 ! ePyObject ret;
9037 ! std::list<eServiceReference> tmplist;
9038 ! int retcount=1;
9040 ! if (!format || !(retcount=strlen(format)))
9041 ! format = "R"; // just return service reference swig object ...
9043 ! if (!getContent(tmplist, sorted))
9045 ! int services=tmplist.size();
9046 ! ePtr<iStaticServiceInformation> sptr;
9047 ! eServiceCenterPtr service_center;
9049 ! if (strchr(format, 'N') || strchr(format, 'n'))
9050 ! eServiceCenter::getPrivInstance(service_center);
9052 ! ret = PyList_New(services);
9053 ! std::list<eServiceReference>::iterator it(tmplist.begin());
9055 ! for (int cnt=0; cnt < services; ++cnt)
9057 ! eServiceReference &ref=*it++;
9058 ! ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject();
9059 ! for (int i=0; i < retcount; ++i)
9061 ! ePyObject tmp;
9062 ! switch(format[i])
9064 ! case 'R': // service reference (swig)object
9065 ! tmp = NEW_eServiceReference(ref);
9066 ! break;
9067 ! case 'C': // service reference compare string
9068 ! tmp = PyString_FromString(ref.toCompareString().c_str());
9069 ! break;
9070 ! case 'S': // service reference string
9071 ! tmp = PyString_FromString(ref.toString().c_str());
9072 ! break;
9073 ! case 'N': // service name
9074 ! if (service_center)
9076 ! service_center->info(ref, sptr);
9077 ! if (sptr)
9079 ! std::string name;
9080 ! sptr->getName(ref, name);
9082 ! // filter short name brakets
9083 ! size_t pos;
9084 ! while((pos = name.find("\xc2\x86")) != std::string::npos)
9085 ! name.erase(pos,2);
9086 ! while((pos = name.find("\xc2\x87")) != std::string::npos)
9087 ! name.erase(pos,2);
9089 ! if (name.length())
9090 ! tmp = PyString_FromString(name.c_str());
9093 ! if (!tmp)
9094 ! tmp = PyString_FromString("<n/a>");
9095 ! break;
9096 ! case 'n': // short service name
9097 ! if (service_center)
9099 ! service_center->info(ref, sptr);
9100 ! if (sptr)
9102 ! std::string name;
9103 ! sptr->getName(ref, name);
9104 ! name = buildShortName(name);
9105 ! if (name.length())
9106 ! tmp = PyString_FromString(name.c_str());
9109 ! if (!tmp)
9110 ! tmp = PyString_FromString("<n/a>");
9111 ! break;
9112 ! default:
9113 ! if (tuple)
9115 ! tmp = Py_None;
9116 ! Py_INCREF(Py_None);
9118 ! break;
9120 ! if (tmp)
9122 ! if (tuple)
9123 ! PyTuple_SET_ITEM(tuple, i, tmp);
9124 ! else
9125 ! PyList_SET_ITEM(ret, cnt, tmp);
9128 ! if (tuple)
9129 ! PyList_SET_ITEM(ret, cnt, tuple);
9132 ! return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
9135 ! RESULT eDVBServiceList::getNext(eServiceReference &ref)
9137 ! if (!m_query)
9138 ! return -1;
9140 ! return m_query->getNextResult((eServiceReferenceDVB&)ref);
9143 ! RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
9145 ! if (m_parent.flags & eServiceReference::canDescent) // bouquet
9147 ! ePtr<iDVBChannelList> db;
9148 ! ePtr<eDVBResourceManager> resm;
9150 ! if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
9151 ! return -1;
9153 ! if (db->getBouquet(m_parent, m_bouquet) != 0)
9154 ! return -1;
9156 ! res = this;
9158 ! return 0;
9160 ! res = 0;
9161 ! return -1;
9164 ! RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
9166 ! if (!m_bouquet)
9167 ! return -1;
9168 ! return m_bouquet->addService(ref, before);
9171 ! RESULT eDVBServiceList::removeService(eServiceReference &ref)
9173 ! if (!m_bouquet)
9174 ! return -1;
9175 ! return m_bouquet->removeService(ref);
9178 ! RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
9180 ! if (!m_bouquet)
9181 ! return -1;
9182 ! return m_bouquet->moveService(ref, pos);
9185 ! RESULT eDVBServiceList::flushChanges()
9187 ! if (!m_bouquet)
9188 ! return -1;
9189 ! return m_bouquet->flushChanges();
9192 ! RESULT eDVBServiceList::setListName(const std::string &name)
9194 ! if (!m_bouquet)
9195 ! return -1;
9196 ! return m_bouquet->setListName(name);
9199 ! RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
9201 ! ePtr<eDVBService> service;
9202 ! int r = lookupService(service, ref);
9203 ! if (r)
9204 ! service = 0;
9205 ! // check resources...
9206 ! ptr = new eDVBServicePlay(ref, service);
9207 ! return 0;
9210 ! RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
9212 ! if (ref.path.empty())
9214 ! ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
9215 ! return 0;
9216 ! } else
9218 ! ptr = 0;
9219 ! return -1;
9223 ! RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
9225 ! ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
9226 ! if (list->startQuery())
9228 ! ptr = 0;
9229 ! return -1;
9232 ! ptr = list;
9233 ! return 0;
9236 ! RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
9238 ! /* is a listable service? */
9239 ! if (ref.flags & eServiceReference::canDescent) // bouquet
9241 ! if ( !ref.name.empty() ) // satellites or providers list
9242 ! ptr = m_StaticServiceDVBInfo;
9243 ! else // a dvb bouquet
9244 ! ptr = m_StaticServiceDVBBouquetInfo;
9246 ! else if (!ref.path.empty()) /* do we have a PVR service? */
9247 ! ptr = new eStaticServiceDVBPVRInformation(ref);
9248 ! else // normal dvb service
9250 ! ePtr<eDVBService> service;
9251 ! if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
9252 ! ptr = m_StaticServiceDVBInfo;
9253 ! else
9254 ! /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
9255 ! ptr = service;
9257 ! return 0;
9260 ! RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
9262 ! if (ref.path.empty())
9264 ! ptr = 0;
9265 ! return -1;
9266 ! } else
9268 ! ptr = new eDVBPVRServiceOfflineOperations(ref);
9269 ! return 0;
9273 ! RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
9275 ! if (!ref.path.empty()) // playback
9277 ! eDVBMetaParser parser;
9278 ! int ret=parser.parseFile(ref.path);
9279 ! service = new eDVBService;
9280 ! if (!ret)
9281 ! eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
9283 ! else
9285 ! // TODO: handle the listing itself
9286 ! // if (ref.... == -1) .. return "... bouquets ...";
9287 ! // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
9288 ! // TODO: cache
9289 ! ePtr<iDVBChannelList> db;
9290 ! ePtr<eDVBResourceManager> res;
9292 ! int err;
9293 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
9295 ! eDebug("no resource manager");
9296 ! return err;
9298 ! if ((err = res->getChannelList(db)) != 0)
9300 ! eDebug("no channel list");
9301 ! return err;
9304 ! /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
9305 ! if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
9307 ! // eDebug("getService failed!");
9308 ! return err;
9312 ! return 0;
9315 ! eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
9316 ! m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
9318 ! m_is_primary = 1;
9319 ! m_is_pvr = !m_reference.path.empty();
9321 ! m_timeshift_enabled = m_timeshift_active = 0, m_timeshift_changed = 0;
9322 ! m_skipmode = m_fastforward = m_slowmotion = 0;
9324 ! CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
9325 ! CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
9326 ! CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
9328 ! m_cuesheet_changed = 0;
9329 ! m_cutlist_enabled = 1;
9331 ! m_subtitle_widget = 0;
9333 ! m_tune_state = -1;
9335 ! m_subtitle_sync_timer = eTimer::create(eApp);
9337 ! CONNECT(m_subtitle_sync_timer->timeout, eDVBServicePlay::checkSubtitleTiming);
9339 ! m_player = 0;
9341 ! xineLib = cXineLib::getInstance();
9342 ! xine_connection = CONNECT(xineLib->m_event, eDVBServicePlay::video_event);
9345 ! eDVBServicePlay::~eDVBServicePlay()
9347 ! if (m_is_pvr)
9349 ! eDVBMetaParser meta;
9350 ! int ret=meta.parseFile(m_reference.path);
9351 ! if (!ret)
9353 ! char tmp[255];
9354 ! meta.m_service_data="";
9355 ! sprintf(tmp, "f:%x", m_dvb_service->m_flags);
9356 ! meta.m_service_data += tmp;
9357 ! // cached pids
9358 ! for (int x=0; x < eDVBService::cacheMax; ++x)
9360 ! int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
9361 ! if (entry != -1)
9363 ! sprintf(tmp, ",c:%02d%04x", x, entry);
9364 ! meta.m_service_data += tmp;
9367 ! meta.updateMeta(m_reference.path);
9371 ! xine_connection.disconnect();
9373 ! delete m_subtitle_widget;
9376 ! void eDVBServicePlay::gotNewEvent()
9378 ! #if 0
9379 ! // debug only
9380 ! ePtr<eServiceEvent> m_event_now, m_event_next;
9381 ! getEvent(m_event_now, 0);
9382 ! getEvent(m_event_next, 1);
9384 ! if (m_event_now)
9385 ! eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
9386 ! if (m_event_next)
9387 ! eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
9388 ! #endif
9389 ! m_event((iPlayableService*)this, evUpdatedEventInfo);
9392 ! void eDVBServicePlay::serviceEvent(int event)
9394 ! m_tune_state = event;
9396 ! switch (event)
9398 ! case eDVBServicePMTHandler::eventTuned:
9400 ! ePtr<iDVBDemux> m_demux;
9401 ! if (!m_service_handler.getDataDemux(m_demux))
9403 ! eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
9404 ! int sid = ref.getParentServiceID().get();
9405 ! if (!sid)
9406 ! sid = ref.getServiceID().get();
9407 ! if ( ref.getParentTransportStreamID().get() &&
9408 ! ref.getParentTransportStreamID() != ref.getTransportStreamID() )
9409 ! m_event_handler.startOther(m_demux, sid);
9410 ! else
9411 ! m_event_handler.start(m_demux, sid);
9413 ! m_event((iPlayableService*)this, evTunedIn);
9414 ! break;
9416 ! case eDVBServicePMTHandler::eventNoResources:
9417 ! case eDVBServicePMTHandler::eventNoPAT:
9418 ! case eDVBServicePMTHandler::eventNoPATEntry:
9419 ! case eDVBServicePMTHandler::eventNoPMT:
9420 ! case eDVBServicePMTHandler::eventTuneFailed:
9421 ! case eDVBServicePMTHandler::eventMisconfiguration:
9423 ! eDebug("DVB service failed to tune - error %d", event);
9424 ! m_event((iPlayableService*)this, evTuneFailed);
9425 ! break;
9427 ! case eDVBServicePMTHandler::eventNewProgramInfo:
9429 ! eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
9430 ! if (m_timeshift_enabled)
9431 ! updateTimeshiftPids();
9432 ! if (!m_timeshift_active)
9433 ! updateDecoder();
9434 ! if (m_first_program_info & 1 && m_is_pvr)
9436 ! m_first_program_info &= ~1;
9437 ! seekTo(0);
9439 ! if (!m_timeshift_active)
9440 ! m_event((iPlayableService*)this, evUpdatedInfo);
9442 ! ePtr<iDVBDemux> m_demux;
9443 ! if (!m_service_handler.getDataDemux(m_demux))
9445 ! printf("Start live TV!\n");
9447 ! m_demux->createTSPlayer(m_player);
9448 ! if (!m_player)
9449 ! printf("ERROR: !m_player\n");
9451 ! m_player->setTargetFD(m_fd_dst);
9452 ! updateTimeshiftPids();
9453 ! m_player->start();
9455 ! printf("Start live TV END\n");
9458 ! break;
9460 ! case eDVBServicePMTHandler::eventPreStart:
9461 ! loadCuesheet();
9462 ! break;
9463 ! case eDVBServicePMTHandler::eventEOF:
9464 ! m_event((iPlayableService*)this, evEOF);
9465 ! break;
9466 ! case eDVBServicePMTHandler::eventSOF:
9467 ! m_event((iPlayableService*)this, evSOF);
9468 ! break;
9472 ! void eDVBServicePlay::serviceEventTimeshift(int event)
9474 ! switch (event)
9476 ! case eDVBServicePMTHandler::eventNewProgramInfo:
9477 ! eDebug("eventNewProgramInfo TS");
9478 ! if (m_timeshift_active)
9480 ! updateDecoder();
9481 ! if (m_first_program_info & 2)
9483 ! if (m_slowmotion)
9485 ! eDebug("re-apply slowmotion after timeshift file change");
9486 ! m_decoder->setSlowMotion(m_slowmotion);
9488 ! if (m_fastforward)
9490 ! eDebug("re-apply skip %d, ratio %d after timeshift file change", m_skipmode, m_fastforward);
9491 ! if (m_skipmode)
9492 ! m_cue->setSkipmode(m_skipmode * 90000); /* convert to 90000 per second */
9493 ! if (m_fastforward != 1)
9494 ! m_decoder->setFastForward(m_fastforward);
9495 ! else
9496 ! m_decoder->setTrickmode();
9498 ! else
9499 ! seekTo(0);
9500 ! m_first_program_info &= ~2;
9502 ! m_event((iPlayableService*)this, evUpdatedInfo);
9504 ! break;
9505 ! case eDVBServicePMTHandler::eventSOF:
9506 ! #if 0
9507 ! if (!m_timeshift_file_next.empty())
9509 ! eDebug("timeshift SOF, switch to next file");
9510 ! m_decoder->pause();
9512 ! m_first_program_info |= 2;
9514 ! eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
9515 ! r.path = m_timeshift_file_next;
9517 ! /* free the timeshift service handler, we need the resources */
9518 ! m_service_handler_timeshift.free();
9519 ! resetTimeshift(1);
9521 ! if (m_skipmode < 0)
9522 ! m_cue->seekTo(0, -1000);
9523 ! ePtr<iTsSource> source = createTsSource(r);
9524 ! m_service_handler_timeshift.tuneExt(r, 1, source, r.path.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
9526 ! m_event((iPlayableService*)this, evUser+1);
9528 ! else
9529 ! #endif
9530 ! m_event((iPlayableService*)this, evSOF);
9531 ! break;
9532 ! case eDVBServicePMTHandler::eventEOF:
9533 ! if ((!m_is_paused) && (m_skipmode >= 0))
9535 ! if (m_timeshift_file_next.empty())
9537 ! eDebug("timeshift EOF, so let's go live");
9538 ! switchToLive();
9540 ! else
9542 ! eDebug("timeshift EOF, switch to next file");
9544 ! m_first_program_info |= 2;
9546 ! eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
9547 ! r.path = m_timeshift_file_next;
9549 ! /* free the timeshift service handler, we need the resources */
9550 ! m_service_handler_timeshift.free();
9551 ! resetTimeshift(1);
9553 ! ePtr<iTsSource> source = createTsSource(r);
9554 ! m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file_next.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
9556 ! m_event((iPlayableService*)this, evUser+1);
9559 ! break;
9563 ! RESULT eDVBServicePlay::start()
9565 ! printf("eDVBServicePlay::start\n");
9566 ! eServiceReferenceDVB service = (eServiceReferenceDVB&)m_reference;
9568 ! m_fd_dst = ::open("/tmp/ENIGMA_FIFO", O_RDWR);
9569 ! if (m_fd_dst < 0)
9571 ! eDebug("can't open DVR device - FIFO file (%m)");
9574 ! /* in pvr mode, we only want to use one demux. in tv mode, we're using
9575 ! two (one for decoding, one for data source), as we must be prepared
9576 ! to start recording from the data demux. */
9577 ! if (m_is_pvr)
9579 ! eDVBMetaParser meta;
9580 ! if (!meta.parseFile(m_reference.path))
9582 ! service = meta.m_ref;
9583 ! service.path = m_reference.path;
9585 ! m_cue = new eCueSheet();
9587 ! else
9588 ! m_event(this, evStart);
9590 ! m_first_program_info = 1;
9591 ! ePtr<iTsSource> source = createTsSource(service);
9592 ! m_service_handler.tuneExt(service, m_is_pvr, source, service.path.c_str(), m_cue, false, m_dvb_service);
9594 ! if (m_is_pvr)
9596 ! /* inject EIT if there is a stored one */
9597 ! std::string filename = service.path;
9598 ! filename.erase(filename.length()-2, 2);
9599 ! filename+="eit";
9600 ! ePtr<eServiceEvent> event = new eServiceEvent;
9601 ! if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
9603 ! ePtr<eServiceEvent> empty;
9604 ! m_event_handler.inject(event, 0);
9605 ! m_event_handler.inject(empty, 1);
9607 ! m_event(this, evStart);
9609 ! return 0;
9612 ! RESULT eDVBServicePlay::stop()
9614 ! printf("eDVBServicePlay::stop\n");
9615 ! /* add bookmark for last play position */
9616 ! if (m_is_pvr)
9618 ! pts_t play_position, length;
9619 ! if (!getPlayPosition(play_position))
9621 ! /* remove last position */
9622 ! for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
9624 ! if (i->what == 3) /* current play position */
9626 ! m_cue_entries.erase(i);
9627 ! i = m_cue_entries.begin();
9628 ! continue;
9629 ! } else
9630 ! ++i;
9633 ! if (getLength(length))
9634 ! length = 0;
9636 ! if (length)
9638 ! m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
9640 ! m_cuesheet_changed = 1;
9644 ! stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
9646 ! // stop TSPlayer
9647 ! if (m_player) {
9648 ! m_player->stop();
9649 ! m_player = 0;
9651 ! if (m_fd_dst>0) {
9652 ! printf("close(m_fd_dst) %d\n", m_fd_dst);
9653 ! close(m_fd_dst);
9656 ! m_service_handler_timeshift.free();
9657 ! m_service_handler.free();
9659 ! if (m_is_pvr && m_cuesheet_changed)
9661 ! struct stat s;
9662 ! /* save cuesheet only when main file is accessible. */
9663 ! if (!::stat(m_reference.path.c_str(), &s))
9664 ! saveCuesheet();
9666 ! m_event((iPlayableService*)this, evStopped);
9667 ! return 0;
9670 ! RESULT eDVBServicePlay::setTarget(int target)
9672 ! m_is_primary = !target;
9673 ! return 0;
9676 ! RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
9678 ! connection = new eConnection((iPlayableService*)this, m_event.connect(event));
9679 ! return 0;
9682 ! RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
9684 ! /* note: we check for timeshift to be enabled,
9685 ! not neccessary active. if you pause when timeshift
9686 ! is not active, you should activate it when unpausing */
9687 ! if ((!m_is_pvr) && (!m_timeshift_enabled))
9689 ! ptr = 0;
9690 ! return -1;
9693 ! ptr = this;
9694 ! return 0;
9697 ! RESULT eDVBServicePlay::setSlowMotion(int ratio)
9699 ! ASSERT(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */
9700 ! eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
9701 ! setFastForward_internal(0);
9702 ! if (m_decoder)
9704 ! m_slowmotion = ratio;
9705 ! return m_decoder->setSlowMotion(ratio);
9707 ! else
9708 ! return -1;
9711 ! RESULT eDVBServicePlay::setFastForward(int ratio)
9713 ! eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
9714 ! ASSERT(ratio);
9715 ! return setFastForward_internal(ratio);
9718 ! RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
9720 ! int skipmode, ffratio, ret = 0;
9721 ! pts_t pos=0;
9723 ! if (ratio > 8)
9725 ! skipmode = ratio;
9726 ! ffratio = 1;
9727 ! } else if (ratio > 0)
9729 ! skipmode = 0;
9730 ! ffratio = ratio;
9731 ! } else if (!ratio)
9733 ! skipmode = 0;
9734 ! ffratio = 0;
9735 ! } else // if (ratio < 0)
9737 ! skipmode = ratio;
9738 ! ffratio = 1;
9741 ! if (m_skipmode != skipmode)
9743 ! eDebug("setting cue skipmode to %d", skipmode);
9744 ! if (m_cue)
9745 ! m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
9748 ! m_skipmode = skipmode;
9750 ! if (final_seek)
9751 ! eDebug("trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
9753 ! m_fastforward = ffratio;
9755 ! if (!m_decoder)
9756 ! return -1;
9758 ! if (ffratio == 0)
9759 ! ; /* return m_decoder->play(); is done in caller*/
9760 ! else if (ffratio != 1)
9761 ! ret = m_decoder->setFastForward(ffratio);
9762 ! else
9763 ! ret = m_decoder->setTrickmode();
9765 ! if (pos)
9766 ! eDebug("final seek after trickplay ret %d", seekTo(pos));
9768 ! return ret;
9771 ! RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
9773 ! if (m_is_pvr || m_timeshift_enabled)
9775 ! ptr = this;
9776 ! return 0;
9779 ! ptr = 0;
9780 ! return -1;
9783 ! /* TODO: when timeshift is enabled but not active, this doesn't work. */
9784 ! RESULT eDVBServicePlay::getLength(pts_t &len)
9786 ! ePtr<iDVBPVRChannel> pvr_channel;
9788 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
9789 ! return -1;
9791 ! return pvr_channel->getLength(len);
9794 ! RESULT eDVBServicePlay::pause()
9796 ! eDebug("eDVBServicePlay::pause");
9797 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
9798 ! if (m_decoder)
9800 ! m_slowmotion = 0;
9801 ! m_is_paused = 1;
9802 ! return m_decoder->pause();
9803 ! } else
9804 ! return -1;
9807 ! RESULT eDVBServicePlay::unpause()
9809 ! eDebug("eDVBServicePlay::unpause");
9810 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
9811 ! if (m_decoder)
9813 ! m_slowmotion = 0;
9814 ! m_is_paused = 0;
9815 ! return m_decoder->play();
9816 ! } else
9817 ! return -1;
9820 ! RESULT eDVBServicePlay::seekTo(pts_t to)
9822 ! eDebug("eDVBServicePlay::seekTo: jump %lld", to);
9824 ! if (!m_decode_demux)
9825 ! return -1;
9827 ! ePtr<iDVBPVRChannel> pvr_channel;
9829 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
9830 ! return -1;
9832 ! if (!m_cue)
9833 ! return -1;
9835 ! m_cue->seekTo(0, to);
9836 ! m_dvb_subtitle_pages.clear();
9837 ! m_subtitle_pages.clear();
9839 ! return 0;
9842 ! RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
9844 ! eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
9846 ! if (!m_decode_demux)
9847 ! return -1;
9849 ! ePtr<iDVBPVRChannel> pvr_channel;
9851 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
9852 ! return -1;
9854 ! int mode = 1;
9856 ! /* HACK until we have skip-AP api */
9857 ! if ((to > 0) && (to < 100))
9858 ! mode = 2;
9860 ! to *= direction;
9862 ! if (!m_cue)
9863 ! return 0;
9865 ! m_cue->seekTo(mode, to);
9866 ! m_dvb_subtitle_pages.clear();
9867 ! m_subtitle_pages.clear();
9868 ! return 0;
9871 ! RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
9873 ! ePtr<iDVBPVRChannel> pvr_channel;
9875 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
9876 ! return -1;
9878 ! int r = 0;
9880 ! r = xineLib->getPTS(pos);
9881 ! if (r)
9882 ! return r;
9884 ! /* fixup */
9885 ! return pvr_channel->getCurrentPosition(m_decode_demux, pos, 1);
9888 ! RESULT eDVBServicePlay::setTrickmode(int trick)
9890 ! /* currently unimplemented */
9891 ! return -1;
9894 ! RESULT eDVBServicePlay::isCurrentlySeekable()
9896 ! int ret = 0;
9897 ! if (m_decoder)
9899 ! ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
9900 ! if (m_decoder->getVideoProgressive() == -1)
9901 ! ret &= ~2;
9903 ! return ret;
9906 ! RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
9908 ! ptr = this;
9909 ! return 0;
9912 ! RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
9914 ! ptr = this;
9915 ! return 0;
9918 ! RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
9920 ! ptr = this;
9921 ! return 0;
9924 ! RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
9926 ! ptr = this;
9927 ! return 0;
9930 ! RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
9932 ! ptr = this;
9933 ! return 0;
9936 ! RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
9938 ! ptr = 0;
9939 ! if (m_have_video_pid && // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
9940 ! (m_timeshift_enabled || !m_is_pvr))
9942 ! if (!m_timeshift_enabled)
9944 ! /* query config path */
9945 ! std::string tspath;
9946 ! if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
9947 ! eDebug("could not query ts path from config");
9948 ! return -4;
9950 ! tspath.append("/");
9951 ! /* we need enough diskspace */
9952 ! struct statfs fs;
9953 ! if (statfs(tspath.c_str(), &fs) < 0)
9955 ! eDebug("statfs failed!");
9956 ! return -2;
9959 ! if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
9961 ! eDebug("not enough diskspace for timeshift! (less than 1GB)");
9962 ! return -3;
9965 ! ptr = this;
9966 ! return 0;
9968 ! return -1;
9971 ! RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
9973 ! if (m_is_pvr)
9975 ! ptr = this;
9976 ! return 0;
9978 ! ptr = 0;
9979 ! return -1;
9982 ! RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
9984 ! ptr = this;
9985 ! return 0;
9988 ! RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
9990 ! ptr = this;
9991 ! return 0;
9994 ! RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
9996 ! ptr = this;
9997 ! return 0;
10000 ! RESULT eDVBServicePlay::getName(std::string &name)
10002 ! if (m_is_pvr)
10004 ! ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
10005 ! return i->getName(m_reference, name);
10007 ! else if (m_dvb_service)
10009 ! m_dvb_service->getName(m_reference, name);
10010 ! if (name.empty())
10011 ! name = "(...)";
10013 ! else if (!m_reference.name.empty())
10014 ! eStaticServiceDVBInformation().getName(m_reference, name);
10015 ! else
10016 ! name = "DVB service";
10017 ! return 0;
10020 ! RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
10022 ! return m_event_handler.getEvent(evt, nownext);
10025 ! int eDVBServicePlay::getInfo(int w)
10027 ! eDVBServicePMTHandler::program program;
10029 ! if (w == sCAIDs || w == sCAIDPIDs)
10030 ! return resIsPyObject;
10032 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10034 ! int no_program_info = 0;
10036 ! if (h.getProgramInfo(program))
10037 ! no_program_info = 1;
10039 ! switch (w)
10041 ! case sVideoHeight:
10042 ! //if (m_decoder)
10043 ! // return m_decoder->getVideoHeight();
10044 ! return xineLib->getVideoHeight();
10045 ! break;
10046 ! case sVideoWidth:
10047 ! //if (m_decoder)
10048 ! // return m_decoder->getVideoWidth();
10049 ! return xineLib->getVideoWidth();
10050 ! break;
10051 ! case sFrameRate:
10052 ! //if (m_decoder)
10053 ! // return m_decoder->getVideoFrameRate();
10054 ! return xineLib->getVideoFrameRate();
10055 ! break;
10056 ! case sProgressive:
10057 ! if (m_decoder)
10058 ! return m_decoder->getVideoProgressive();
10059 ! break;
10060 ! case sAspect:
10062 ! //if (m_decoder)
10063 ! // aspect = m_decoder->getVideoAspect();
10064 ! int aspect = xineLib->getVideoAspect();
10066 ! if (aspect == -1 && no_program_info)
10067 ! break;
10068 ! else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
10070 ! ePtr<eServiceEvent> evt;
10071 ! if (!m_event_handler.getEvent(evt, 0))
10073 ! ePtr<eComponentData> data;
10074 ! if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
10076 ! if ( data->getStreamContent() == 1 )
10078 ! switch(data->getComponentType())
10080 ! // SD
10081 ! case 1: // 4:3 SD PAL
10082 ! case 2:
10083 ! case 3: // 16:9 SD PAL
10084 ! case 4: // > 16:9 PAL
10085 ! case 5: // 4:3 SD NTSC
10086 ! case 6:
10087 ! case 7: // 16:9 SD NTSC
10088 ! case 8: // > 16:9 NTSC
10090 ! // HD
10091 ! case 9: // 4:3 HD PAL
10092 ! case 0xA:
10093 ! case 0xB: // 16:9 HD PAL
10094 ! case 0xC: // > 16:9 HD PAL
10095 ! case 0xD: // 4:3 HD NTSC
10096 ! case 0xE:
10097 ! case 0xF: // 16:9 HD NTSC
10098 ! case 0x10: // > 16:9 HD PAL
10099 ! return data->getComponentType();
10105 ! else
10106 ! return aspect;
10107 ! break;
10109 ! case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
10110 ! case sVideoPID:
10111 ! if (m_dvb_service)
10113 ! int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
10114 ! if (vpid != -1)
10115 ! return vpid;
10117 ! if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
10118 ! case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
10119 ! case sAudioPID:
10120 ! if (m_dvb_service)
10122 ! int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
10123 ! if (apid != -1)
10124 ! return apid;
10125 ! apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
10126 ! if (apid != -1)
10127 ! return apid;
10129 ! if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
10130 ! case sPCRPID:
10131 ! if (m_dvb_service)
10133 ! int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
10134 ! if (pcrpid != -1)
10135 ! return pcrpid;
10137 ! if (no_program_info) return -1; return program.pcrPid;
10138 ! case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
10139 ! case sTXTPID: if (no_program_info) return -1; return program.textPid;
10140 ! case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
10141 ! case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
10142 ! case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
10143 ! case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
10144 ! case sProvider: if (!m_dvb_service) return -1; return -2;
10145 ! case sServiceref: return resIsString;
10146 ! case sDVBState: return m_tune_state;
10147 ! default:
10148 ! break;
10150 ! return -1;
10153 ! std::string eDVBServicePlay::getInfoString(int w)
10155 ! switch (w)
10157 ! case sProvider:
10158 ! if (!m_dvb_service) return "";
10159 ! return m_dvb_service->m_provider_name;
10160 ! case sServiceref:
10161 ! return m_reference.toString();
10162 ! default:
10163 ! break;
10165 ! return iServiceInformation::getInfoString(w);
10168 ! PyObject *eDVBServicePlay::getInfoObject(int w)
10170 ! switch (w)
10172 ! case sCAIDs:
10173 ! return m_service_handler.getCaIds();
10174 ! case sCAIDPIDs:
10175 ! return m_service_handler.getCaIds(true);
10176 ! case sTransponderData:
10177 ! return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
10178 ! default:
10179 ! break;
10181 ! return iServiceInformation::getInfoObject(w);
10184 ! int eDVBServicePlay::getNumberOfTracks()
10186 ! eDVBServicePMTHandler::program program;
10187 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10188 ! if (h.getProgramInfo(program))
10189 ! return 0;
10190 ! return program.audioStreams.size();
10193 ! int eDVBServicePlay::getCurrentTrack()
10195 ! eDVBServicePMTHandler::program program;
10196 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10197 ! if (h.getProgramInfo(program))
10198 ! return 0;
10200 ! int max = program.audioStreams.size();
10201 ! int i;
10203 ! for (i = 0; i < max; ++i)
10204 ! if (program.audioStreams[i].pid == m_current_audio_pid)
10205 ! return i;
10207 ! return 0;
10210 ! RESULT eDVBServicePlay::selectTrack(unsigned int i)
10212 ! int ret = selectAudioStream(i);
10214 ! if (m_decoder->set())
10215 ! return -5;
10217 ! return ret;
10220 ! RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
10222 ! eDVBServicePMTHandler::program program;
10223 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10225 ! if (h.getProgramInfo(program))
10226 ! return -1;
10228 ! if (i >= program.audioStreams.size())
10229 ! return -2;
10231 ! info.m_pid = program.audioStreams[i].pid;
10233 ! if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
10234 ! info.m_description = "MPEG";
10235 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
10236 ! info.m_description = "AC3";
10237 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
10238 ! info.m_description = "AAC";
10239 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
10240 ! info.m_description = "AAC-HE";
10241 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
10242 ! info.m_description = "DTS";
10243 ! else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTSHD)
10244 ! info.m_description = "DTS-HD";
10245 ! else
10246 ! info.m_description = "???";
10248 ! if (program.audioStreams[i].component_tag != -1)
10250 ! ePtr<eServiceEvent> evt;
10251 ! if (!m_event_handler.getEvent(evt, 0))
10253 ! ePtr<eComponentData> data;
10254 ! if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
10255 ! info.m_language = data->getText();
10259 ! if (info.m_language.empty())
10260 ! info.m_language = program.audioStreams[i].language_code;
10262 ! return 0;
10265 ! int eDVBServicePlay::selectAudioStream(int i)
10267 ! eDVBServicePMTHandler::program program;
10268 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10269 ! pts_t position = -1;
10271 ! if (h.getProgramInfo(program))
10272 ! return -1;
10274 ! if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
10275 ! return -2;
10277 ! if (!m_decoder)
10278 ! return -3;
10280 ! int stream = i;
10281 ! if (stream == -1)
10282 ! stream = program.defaultAudioStream;
10284 ! int apid = -1, apidtype = -1;
10286 ! if (((unsigned int)stream) < program.audioStreams.size())
10288 ! apid = program.audioStreams[stream].pid;
10289 ! apidtype = program.audioStreams[stream].type;
10292 ! if (i != -1 && apid != m_current_audio_pid && (m_is_pvr || m_timeshift_active))
10293 ! eDebug("getPlayPosition ret %d, pos %lld in selectAudioStream", getPlayPosition(position), position);
10295 ! m_current_audio_pid = apid;
10297 ! if (m_is_primary && m_decoder->setAudioPID(apid, apidtype))
10299 ! eDebug("set audio pid failed");
10300 ! return -4;
10303 ! if (position != -1)
10304 ! eDebug("seekTo ret %d", seekTo(position));
10306 ! int rdsPid = apid;
10308 ! /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
10309 ! if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
10311 ! int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
10312 ! if (different_pid)
10313 ! rdsPid = program.audioStreams[stream].rdsPid;
10314 ! if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
10316 ! m_rds_decoder = 0;
10317 ! ePtr<iDVBDemux> data_demux;
10318 ! if (!h.getDataDemux(data_demux))
10320 ! m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
10321 ! m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
10322 ! m_rds_decoder->start(rdsPid);
10327 ! /* store new pid as default only when:
10328 ! a.) we have an entry in the service db for the current service,
10329 ! b.) we are not playing back something,
10330 ! c.) we are not selecting the default entry. (we wouldn't change
10331 ! anything in the best case, or destroy the default setting in
10332 ! case the real default is not yet available.)
10333 ! */
10334 ! if (m_dvb_service && ((i != -1)
10335 ! || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
10337 ! if (apidtype == eDVBAudio::aMPEG)
10339 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
10340 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
10342 ! else if (apidtype == eDVBAudio::aAC3)
10344 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
10345 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
10347 ! else
10349 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
10350 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
10354 ! h.resetCachedProgram();
10356 ! return 0;
10359 ! int eDVBServicePlay::getCurrentChannel()
10361 ! return m_decoder ? m_decoder->getAudioChannel() : STEREO;
10364 ! RESULT eDVBServicePlay::selectChannel(int i)
10366 ! if (i < LEFT || i > RIGHT || i == STEREO)
10367 ! i = -1; // Stereo
10368 ! if (m_dvb_service)
10369 ! m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
10370 ! if (m_decoder)
10371 ! m_decoder->setAudioChannel(i);
10372 ! return 0;
10375 ! std::string eDVBServicePlay::getText(int x)
10377 ! if (m_rds_decoder)
10378 ! switch(x)
10380 ! case RadioText:
10381 ! return convertLatin1UTF8(m_rds_decoder->getRadioText());
10382 ! case RtpText:
10383 ! return convertLatin1UTF8(m_rds_decoder->getRtpText());
10385 ! return "";
10388 ! void eDVBServicePlay::rdsDecoderEvent(int what)
10390 ! switch(what)
10392 ! case eDVBRdsDecoder::RadioTextChanged:
10393 ! m_event((iPlayableService*)this, evUpdatedRadioText);
10394 ! break;
10395 ! case eDVBRdsDecoder::RtpTextChanged:
10396 ! m_event((iPlayableService*)this, evUpdatedRtpText);
10397 ! break;
10398 ! case eDVBRdsDecoder::RassInteractivePicMaskChanged:
10399 ! m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
10400 ! break;
10401 ! case eDVBRdsDecoder::RecvRassSlidePic:
10402 ! m_event((iPlayableService*)this, evUpdatedRassSlidePic);
10403 ! break;
10407 ! void eDVBServicePlay::showRassSlidePicture()
10409 ! if (m_rds_decoder)
10411 ! if (m_decoder)
10413 ! std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
10414 ! if (rass_slide_pic.length())
10415 ! m_decoder->showSinglePic(rass_slide_pic.c_str());
10416 ! else
10417 ! eDebug("empty filename for rass slide picture received!!");
10419 ! else
10420 ! eDebug("no MPEG Decoder to show iframes avail");
10422 ! else
10423 ! eDebug("showRassSlidePicture called.. but not decoder");
10426 ! void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
10428 ! if (m_rds_decoder)
10430 ! if (m_decoder)
10432 ! std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
10433 ! if (rass_interactive_pic.length())
10434 ! m_decoder->showSinglePic(rass_interactive_pic.c_str());
10435 ! else
10436 ! eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
10438 ! else
10439 ! eDebug("no MPEG Decoder to show iframes avail");
10441 ! else
10442 ! eDebug("showRassInteractivePic called.. but not decoder");
10445 ! ePyObject eDVBServicePlay::getRassInteractiveMask()
10447 ! if (m_rds_decoder)
10448 ! return m_rds_decoder->getRassPictureMask();
10449 ! Py_RETURN_NONE;
10452 ! int eDVBServiceBase::getFrontendInfo(int w)
10454 ! eUsePtr<iDVBChannel> channel;
10455 ! if(m_service_handler.getChannel(channel))
10456 ! return 0;
10457 ! ePtr<iDVBFrontend> fe;
10458 ! if(channel->getFrontend(fe))
10459 ! return 0;
10460 ! return fe->readFrontendData(w);
10463 ! PyObject *eDVBServiceBase::getFrontendData()
10465 ! ePyObject ret = PyDict_New();
10466 ! if (ret)
10468 ! eUsePtr<iDVBChannel> channel;
10469 ! if(!m_service_handler.getChannel(channel))
10471 ! ePtr<iDVBFrontend> fe;
10472 ! if(!channel->getFrontend(fe))
10473 ! fe->getFrontendData(ret);
10476 ! else
10477 ! Py_RETURN_NONE;
10478 ! return ret;
10481 ! PyObject *eDVBServiceBase::getFrontendStatus()
10483 ! ePyObject ret = PyDict_New();
10484 ! if (ret)
10486 ! eUsePtr<iDVBChannel> channel;
10487 ! if(!m_service_handler.getChannel(channel))
10489 ! ePtr<iDVBFrontend> fe;
10490 ! if(!channel->getFrontend(fe))
10491 ! fe->getFrontendStatus(ret);
10494 ! else
10495 ! Py_RETURN_NONE;
10496 ! return ret;
10499 ! PyObject *eDVBServiceBase::getTransponderData(bool original)
10501 ! ePyObject ret = PyDict_New();
10502 ! if (ret)
10504 ! eUsePtr<iDVBChannel> channel;
10505 ! if(!m_service_handler.getChannel(channel))
10507 ! ePtr<iDVBFrontend> fe;
10508 ! if(!channel->getFrontend(fe))
10509 ! fe->getTransponderData(ret, original);
10512 ! else
10513 ! Py_RETURN_NONE;
10514 ! return ret;
10517 ! PyObject *eDVBServiceBase::getAll(bool original)
10519 ! ePyObject ret = getTransponderData(original);
10520 ! if (ret != Py_None)
10522 ! eUsePtr<iDVBChannel> channel;
10523 ! if(!m_service_handler.getChannel(channel))
10525 ! ePtr<iDVBFrontend> fe;
10526 ! if(!channel->getFrontend(fe))
10528 ! fe->getFrontendData(ret);
10529 ! fe->getFrontendStatus(ret);
10533 ! return ret;
10536 ! int eDVBServicePlay::getNumberOfSubservices()
10538 ! ePtr<eServiceEvent> evt;
10539 ! if (!m_event_handler.getEvent(evt, 0))
10540 ! return evt->getNumOfLinkageServices();
10541 ! return 0;
10544 ! RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
10546 ! ePtr<eServiceEvent> evt;
10547 ! if (!m_event_handler.getEvent(evt, 0))
10549 ! if (!evt->getLinkageService(sub, m_reference, n))
10550 ! return 0;
10552 ! sub.type=eServiceReference::idInvalid;
10553 ! return -1;
10556 ! RESULT eDVBServicePlay::startTimeshift()
10558 ! ePtr<iDVBDemux> demux;
10560 ! eDebug("Start timeshift!");
10562 ! if (m_timeshift_enabled)
10563 ! return -1;
10565 ! /* start recording with the data demux. */
10566 ! if (m_service_handler.getDataDemux(demux))
10567 ! return -2;
10569 ! demux->createTSRecorder(m_record);
10570 ! if (!m_record)
10571 ! return -3;
10573 ! std::string tspath;
10574 ! if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
10575 ! eDebug("could not query ts path");
10576 ! return -5;
10578 ! tspath.append("/timeshift.XXXXXX");
10579 ! char* templ;
10580 ! templ = new char[tspath.length() + 1];
10581 ! strcpy(templ, tspath.c_str());
10583 ! m_timeshift_fd = mkstemp(templ);
10584 ! m_timeshift_file = std::string(templ);
10586 ! eDebug("recording to %s", templ);
10588 ! delete [] templ;
10590 ! if (m_timeshift_fd < 0)
10592 ! m_record = 0;
10593 ! return -4;
10596 ! m_record->setTargetFD(m_timeshift_fd);
10598 ! m_timeshift_enabled = 1;
10600 ! updateTimeshiftPids();
10601 ! m_record->start();
10603 ! return 0;
10606 ! RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
10608 ! if (!m_timeshift_enabled)
10609 ! return -1;
10611 ! if (swToLive)
10612 ! switchToLive();
10614 ! m_timeshift_enabled = 0;
10616 ! m_record->stop();
10617 ! m_record = 0;
10619 ! close(m_timeshift_fd);
10620 ! eDebug("remove timeshift file");
10621 ! eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
10623 ! return 0;
10626 ! int eDVBServicePlay::isTimeshiftActive()
10628 ! return m_timeshift_enabled && m_timeshift_active;
10631 ! RESULT eDVBServicePlay::activateTimeshift()
10633 ! if (!m_timeshift_enabled)
10634 ! return -1;
10636 ! if (!m_timeshift_active)
10638 ! switchToTimeshift();
10639 ! return 0;
10642 ! return -2;
10645 ! PyObject *eDVBServicePlay::getCutList()
10647 ! ePyObject list = PyList_New(0);
10649 ! for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
10651 ! ePyObject tuple = PyTuple_New(2);
10652 ! PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
10653 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
10654 ! PyList_Append(list, tuple);
10655 ! Py_DECREF(tuple);
10658 ! return list;
10661 ! void eDVBServicePlay::setCutList(ePyObject list)
10663 ! if (!PyList_Check(list))
10664 ! return;
10665 ! int size = PyList_Size(list);
10666 ! int i;
10668 ! m_cue_entries.clear();
10670 ! for (i=0; i<size; ++i)
10672 ! ePyObject tuple = PyList_GET_ITEM(list, i);
10673 ! if (!PyTuple_Check(tuple))
10675 ! eDebug("non-tuple in cutlist");
10676 ! continue;
10678 ! if (PyTuple_Size(tuple) != 2)
10680 ! eDebug("cutlist entries need to be a 2-tuple");
10681 ! continue;
10683 ! ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
10684 ! if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
10686 ! eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
10687 ! continue;
10689 ! pts_t pts = PyLong_AsLongLong(ppts);
10690 ! int type = PyInt_AsLong(ptype);
10691 ! m_cue_entries.insert(cueEntry(pts, type));
10692 ! eDebug("adding %08llx, %d", pts, type);
10694 ! m_cuesheet_changed = 1;
10696 ! cutlistToCuesheet();
10697 ! m_event((iPlayableService*)this, evCuesheetChanged);
10700 ! void eDVBServicePlay::setCutListEnable(int enable)
10702 ! m_cutlist_enabled = enable;
10703 ! cutlistToCuesheet();
10706 ! void eDVBServicePlay::updateTimeshiftPids()
10708 ! eDVBServicePMTHandler::program program;
10709 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10711 ! if (h.getProgramInfo(program))
10712 ! return;
10713 ! else
10715 ! std::set<int> pids_to_record;
10716 ! pids_to_record.insert(0); // PAT
10717 ! if (program.pmtPid != -1)
10718 ! pids_to_record.insert(program.pmtPid); // PMT
10720 ! if (program.textPid != -1)
10721 ! pids_to_record.insert(program.textPid); // Videotext
10723 ! for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
10724 ! i(program.videoStreams.begin());
10725 ! i != program.videoStreams.end(); ++i)
10726 ! pids_to_record.insert(i->pid);
10728 ! for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
10729 ! i(program.audioStreams.begin());
10730 ! i != program.audioStreams.end(); ++i)
10731 ! pids_to_record.insert(i->pid);
10733 ! for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
10734 ! i(program.subtitleStreams.begin());
10735 ! i != program.subtitleStreams.end(); ++i)
10736 ! pids_to_record.insert(i->pid);
10738 ! std::set<int> new_pids, obsolete_pids;
10740 ! std::set_difference(pids_to_record.begin(), pids_to_record.end(),
10741 ! m_pids_active.begin(), m_pids_active.end(),
10742 ! std::inserter(new_pids, new_pids.begin()));
10744 ! std::set_difference(
10745 ! m_pids_active.begin(), m_pids_active.end(),
10746 ! pids_to_record.begin(), pids_to_record.end(),
10747 ! std::inserter(new_pids, new_pids.begin())
10748 ! );
10750 ! if (m_record) {
10751 ! for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
10752 ! m_record->addPID(*i);
10753 ! for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
10754 ! m_record->removePID(*i);
10757 ! for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
10758 ! m_player->addPID(*i);
10759 ! for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
10760 ! m_player->removePID(*i);
10764 ! RESULT eDVBServicePlay::setNextPlaybackFile(const char *f)
10766 ! m_timeshift_file_next = f;
10767 ! return 0;
10770 ! void eDVBServicePlay::switchToLive()
10772 ! if (!m_timeshift_active)
10773 ! return;
10775 ! eDebug("SwitchToLive");
10777 ! resetTimeshift(0);
10779 ! m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
10781 ! /* free the timeshift service handler, we need the resources */
10782 ! m_service_handler_timeshift.free();
10784 ! updateDecoder(true);
10787 ! void eDVBServicePlay::resetTimeshift(int start)
10789 ! m_cue = 0;
10790 ! m_decode_demux = 0;
10791 ! m_decoder = 0;
10792 ! m_teletext_parser = 0;
10793 ! m_rds_decoder = 0;
10794 ! m_subtitle_parser = 0;
10795 ! m_new_subtitle_page_connection = 0;
10796 ! m_new_dvb_subtitle_page_connection = 0;
10797 ! m_rds_decoder_event_connection = 0;
10798 ! m_timeshift_changed = 1;
10799 ! m_timeshift_file_next.clear();
10801 ! if (start)
10803 ! m_cue = new eCueSheet();
10804 ! m_timeshift_active = 1;
10806 ! else
10807 ! m_timeshift_active = 0;
10810 ! ePtr<iTsSource> eDVBServicePlay::createTsSource(eServiceReferenceDVB &ref)
10812 ! eRawFile *f = new eRawFile();
10813 ! f->open(ref.path.c_str());
10814 ! return ePtr<iTsSource>(f);
10817 ! void eDVBServicePlay::switchToTimeshift()
10819 ! if (m_timeshift_active)
10820 ! return;
10822 ! resetTimeshift(1);
10824 ! eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
10825 ! r.path = m_timeshift_file;
10827 ! m_cue->seekTo(0, -1000);
10829 ! ePtr<iTsSource> source = createTsSource(r);
10830 ! m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
10832 ! eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
10833 ! pause();
10834 ! updateDecoder(true); /* mainly to switch off PCR, and to set pause */
10837 ! void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
10839 ! int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
10840 ! bool mustPlay = false;
10842 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
10844 ! eDVBServicePMTHandler::program program;
10845 ! if (h.getProgramInfo(program))
10846 ! eDebug("getting program info failed.");
10847 ! else
10849 ! eDebugNoNewLine("have %zd video stream(s)", program.videoStreams.size());
10850 ! if (!program.videoStreams.empty())
10852 ! eDebugNoNewLine(" (");
10853 ! for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
10854 ! i(program.videoStreams.begin());
10855 ! i != program.videoStreams.end(); ++i)
10857 ! if (vpid == -1)
10859 ! vpid = i->pid;
10860 ! vpidtype = i->type;
10862 ! if (i != program.videoStreams.begin())
10863 ! eDebugNoNewLine(", ");
10864 ! eDebugNoNewLine("%04x", i->pid);
10866 ! eDebugNoNewLine(")");
10868 ! eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
10869 ! if (!program.audioStreams.empty())
10871 ! eDebugNoNewLine(" (");
10872 ! for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
10873 ! i(program.audioStreams.begin());
10874 ! i != program.audioStreams.end(); ++i)
10876 ! if (i != program.audioStreams.begin())
10877 ! eDebugNoNewLine(", ");
10878 ! eDebugNoNewLine("%04x", i->pid);
10880 ! eDebugNoNewLine(")");
10882 ! eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
10883 ! pcrpid = program.pcrPid;
10884 ! eDebug(", and the text pid is %04x", program.textPid);
10885 ! tpid = program.textPid;
10888 ! if (!m_decoder)
10890 ! m_decoder = new eTSMPEGDecoder(m_is_primary ? 0 : 1);
10892 ! if (!m_is_pvr) {
10893 ! h.getDecodeDemux(m_decode_demux);
10894 ! if (m_decode_demux)
10896 ! if (m_is_primary)
10898 ! m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
10899 ! m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
10900 ! m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
10901 ! m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
10902 ! if (m_timeshift_changed)
10904 ! ePyObject subs = getCachedSubtitle();
10905 ! if (subs != Py_None)
10907 ! int type = PyInt_AsLong(PyTuple_GET_ITEM(subs, 0)),
10908 ! pid = PyInt_AsLong(PyTuple_GET_ITEM(subs, 1)),
10909 ! comp_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 2)), // ttx page
10910 ! anc_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 3)); // ttx magazine
10911 ! if (type == 0) // dvb
10912 ! m_subtitle_parser->start(pid, comp_page, anc_page);
10913 ! else if (type == 1) // ttx
10914 ! m_teletext_parser->setPageAndMagazine(comp_page, anc_page);
10916 ! Py_DECREF(subs);
10921 ! if (m_cue)
10922 ! m_cue->setDecodingDemux(m_decode_demux, m_decoder);
10925 ! mustPlay = true;
10928 ! m_timeshift_changed = 0;
10930 ! if (m_decoder)
10932 ! bool wasSeekable = m_decoder->getVideoProgressive() != -1;
10933 ! if (m_dvb_service)
10935 ! achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
10936 ! ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
10937 ! pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
10939 ! else // subservice
10941 ! eServiceReferenceDVB ref;
10942 ! m_service_handler.getServiceReference(ref);
10943 ! eServiceReferenceDVB parent = ref.getParentServiceReference();
10944 ! if (!parent)
10945 ! parent = ref;
10946 ! if (parent)
10948 ! ePtr<eDVBResourceManager> res_mgr;
10949 ! if (!eDVBResourceManager::getInstance(res_mgr))
10951 ! ePtr<iDVBChannelList> db;
10952 ! if (!res_mgr->getChannelList(db))
10954 ! ePtr<eDVBService> origService;
10955 ! if (!db->getService(parent, origService))
10957 ! ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
10958 ! pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
10965 ! setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
10966 ! setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
10968 ! m_decoder->setVideoPID(vpid, vpidtype);
10969 ! selectAudioStream();
10971 ! if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
10972 ! m_decoder->setSyncPCR(pcrpid);
10973 ! else
10974 ! m_decoder->setSyncPCR(-1);
10976 ! if (m_is_primary && m_decode_demux && !m_is_pvr)
10978 ! m_decoder->setTextPID(tpid);
10979 ! m_teletext_parser->start(program.textPid);
10982 ! if (vpid > 0 && vpid < 0x2000)
10984 ! else
10986 ! std::string radio_pic;
10987 ! if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
10988 ! m_decoder->setRadioPic(radio_pic);
10991 ! printf("mustPlay %d\n", mustPlay);
10992 ! if (mustPlay)
10993 ! m_decoder->play();
10994 ! else
10995 ! m_decoder->set();
10997 ! m_decoder->setAudioChannel(achannel);
10999 ! /* don't worry about non-existing services, nor pvr services */
11000 ! if (m_dvb_service)
11002 ! /* (audio pid will be set in selectAudioTrack */
11003 ! m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
11004 ! m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
11005 ! m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
11006 ! m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
11008 ! if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
11009 ! sendSeekableStateChanged = true;
11011 ! m_have_video_pid = (vpid > 0 && vpid < 0x2000);
11013 ! if (sendSeekableStateChanged)
11014 ! m_event((iPlayableService*)this, evSeekableStatusChanged);
11017 ! void eDVBServicePlay::loadCuesheet()
11019 ! std::string filename = m_reference.path + ".cuts";
11021 ! m_cue_entries.clear();
11023 ! FILE *f = fopen(filename.c_str(), "rb");
11025 ! if (f)
11027 ! eDebug("loading cuts..");
11028 ! while (1)
11030 ! unsigned long long where;
11031 ! unsigned int what;
11033 ! if (!fread(&where, sizeof(where), 1, f))
11034 ! break;
11035 ! if (!fread(&what, sizeof(what), 1, f))
11036 ! break;
11038 ! #if BYTE_ORDER == LITTLE_ENDIAN
11039 ! where = bswap_64(where);
11040 ! #endif
11041 ! what = ntohl(what);
11043 ! if (what > 3)
11044 ! break;
11046 ! m_cue_entries.insert(cueEntry(where, what));
11048 ! fclose(f);
11049 ! eDebug("%zd entries", m_cue_entries.size());
11050 ! } else
11051 ! eDebug("cutfile not found!");
11053 ! m_cuesheet_changed = 0;
11054 ! cutlistToCuesheet();
11055 ! m_event((iPlayableService*)this, evCuesheetChanged);
11058 ! void eDVBServicePlay::saveCuesheet()
11060 ! std::string filename = m_reference.path + ".cuts";
11062 ! FILE *f = fopen(filename.c_str(), "wb");
11064 ! if (f)
11066 ! unsigned long long where;
11067 ! int what;
11069 ! for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
11071 ! #if BYTE_ORDER == BIG_ENDIAN
11072 ! where = i->where;
11073 ! #else
11074 ! where = bswap_64(i->where);
11075 ! #endif
11076 ! what = htonl(i->what);
11077 ! fwrite(&where, sizeof(where), 1, f);
11078 ! fwrite(&what, sizeof(what), 1, f);
11081 ! fclose(f);
11084 ! m_cuesheet_changed = 0;
11087 ! void eDVBServicePlay::cutlistToCuesheet()
11089 ! if (!m_cue)
11091 ! eDebug("no cue sheet");
11092 ! return;
11093 ! }
11094 ! m_cue->clear();
11096 ! if (!m_cutlist_enabled)
11098 ! m_cue->commitSpans();
11099 ! eDebug("cutlists were disabled");
11100 ! return;
11103 ! pts_t in = 0, out = 0, length = 0;
11105 ! getLength(length);
11107 ! std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
11109 ! int have_any_span = 0;
11111 ! while (1)
11113 ! if (i == m_cue_entries.end())
11115 ! if (!have_any_span && !in)
11116 ! break;
11117 ! out = length;
11118 ! } else {
11119 ! if (i->what == 0) /* in */
11121 ! in = i++->where;
11122 ! continue;
11123 ! } else if (i->what == 1) /* out */
11124 ! out = i++->where;
11125 ! else /* mark (2) or last play position (3) */
11127 ! i++;
11128 ! continue;
11132 ! if (in < 0)
11133 ! in = 0;
11134 ! if (out < 0)
11135 ! out = 0;
11136 ! if (in > length)
11137 ! in = length;
11138 ! if (out > length)
11139 ! out = length;
11141 ! if (in < out)
11143 ! have_any_span = 1;
11144 ! m_cue->addSourceSpan(in, out);
11145 ! in = out = 0;
11148 ! in = length;
11150 ! if (i == m_cue_entries.end())
11151 ! break;
11153 ! m_cue->commitSpans();
11156 ! RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
11158 ! if (m_subtitle_widget)
11159 ! disableSubtitles(parent);
11161 ! ePyObject entry;
11162 ! int tuplesize = PyTuple_Size(tuple);
11163 ! int type = 0;
11165 ! if (!PyTuple_Check(tuple))
11166 ! goto error_out;
11168 ! if (tuplesize < 1)
11169 ! goto error_out;
11171 ! entry = PyTuple_GET_ITEM(tuple, 0);
11173 ! if (!PyInt_Check(entry))
11174 ! goto error_out;
11176 ! type = PyInt_AsLong(entry);
11178 ! if (type == 1) // teletext subtitles
11180 ! int page, magazine, pid;
11181 ! if (tuplesize < 4)
11182 ! goto error_out;
11184 ! if (!m_teletext_parser)
11186 ! eDebug("enable teletext subtitles.. no parser !!!");
11187 ! return -1;
11190 ! entry = PyTuple_GET_ITEM(tuple, 1);
11191 ! if (!PyInt_Check(entry))
11192 ! goto error_out;
11193 ! pid = PyInt_AsLong(entry);
11195 ! entry = PyTuple_GET_ITEM(tuple, 2);
11196 ! if (!PyInt_Check(entry))
11197 ! goto error_out;
11198 ! page = PyInt_AsLong(entry);
11200 ! entry = PyTuple_GET_ITEM(tuple, 3);
11201 ! if (!PyInt_Check(entry))
11202 ! goto error_out;
11203 ! magazine = PyInt_AsLong(entry);
11205 ! m_subtitle_widget = new eSubtitleWidget(parent);
11206 ! m_subtitle_widget->resize(parent->size()); /* full size */
11207 ! m_teletext_parser->setPageAndMagazine(page, magazine);
11208 ! if (m_dvb_service)
11209 ! m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
11211 ! else if (type == 0)
11213 ! int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
11214 ! if (!m_subtitle_parser)
11216 ! eDebug("enable dvb subtitles.. no parser !!!");
11217 ! return -1;
11219 ! if (tuplesize < 4)
11220 ! goto error_out;
11222 ! entry = PyTuple_GET_ITEM(tuple, 1);
11223 ! if (!PyInt_Check(entry))
11224 ! goto error_out;
11225 ! pid = PyInt_AsLong(entry);
11227 ! entry = PyTuple_GET_ITEM(tuple, 2);
11228 ! if (!PyInt_Check(entry))
11229 ! goto error_out;
11230 ! composition_page_id = PyInt_AsLong(entry);
11232 ! entry = PyTuple_GET_ITEM(tuple, 3);
11233 ! if (!PyInt_Check(entry))
11234 ! goto error_out;
11235 ! ancillary_page_id = PyInt_AsLong(entry);
11237 ! m_subtitle_widget = new eSubtitleWidget(parent);
11238 ! m_subtitle_widget->resize(parent->size()); /* full size */
11239 ! m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
11240 ! if (m_dvb_service)
11241 ! m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
11243 ! else
11244 ! goto error_out;
11245 ! return 0;
11246 ! error_out:
11247 ! eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
11248 ! "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
11249 ! "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
11250 ! return -1;
11253 ! RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
11255 ! delete m_subtitle_widget;
11256 ! m_subtitle_widget = 0;
11257 ! if (m_subtitle_parser)
11259 ! m_subtitle_parser->stop();
11260 ! m_dvb_subtitle_pages.clear();
11262 ! if (m_teletext_parser)
11264 ! m_teletext_parser->setPageAndMagazine(-1, -1);
11265 ! m_subtitle_pages.clear();
11267 ! if (m_dvb_service)
11268 ! m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
11269 ! return 0;
11272 ! PyObject *eDVBServicePlay::getCachedSubtitle()
11274 ! if (m_dvb_service)
11276 ! int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
11277 ! if (tmp != -1)
11279 ! unsigned int data = (unsigned int)tmp;
11280 ! int pid = (data&0xFFFF0000)>>16;
11281 ! ePyObject tuple = PyTuple_New(4);
11282 ! eDVBServicePMTHandler::program program;
11283 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
11284 ! if (!h.getProgramInfo(program))
11286 ! if (program.textPid==pid) // teletext
11287 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
11288 ! else
11289 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
11290 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(pid)); // pid
11291 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
11292 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
11293 ! return tuple;
11297 ! Py_RETURN_NONE;
11300 ! PyObject *eDVBServicePlay::getSubtitleList()
11302 ! if (!m_teletext_parser)
11303 ! Py_RETURN_NONE;
11305 ! ePyObject l = PyList_New(0);
11306 ! std::set<int> added_ttx_pages;
11308 ! std::set<eDVBServicePMTHandler::subtitleStream> &subs =
11309 ! m_teletext_parser->m_found_subtitle_pages;
11311 ! eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
11312 ! eDVBServicePMTHandler::program program;
11313 ! if (h.getProgramInfo(program))
11314 ! eDebug("getting program info failed.");
11315 ! else
11317 ! for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
11318 ! it != program.subtitleStreams.end(); ++it)
11320 ! switch(it->subtitling_type)
11322 ! case 0x01: // ebu teletext subtitles
11324 ! int page_number = it->teletext_page_number & 0xFF;
11325 ! int magazine_number = it->teletext_magazine_number & 7;
11326 ! int hash = magazine_number << 8 | page_number;
11327 ! if (added_ttx_pages.find(hash) == added_ttx_pages.end())
11329 ! ePyObject tuple = PyTuple_New(5);
11330 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
11331 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
11332 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
11333 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
11334 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
11335 ! PyList_Append(l, tuple);
11336 ! Py_DECREF(tuple);
11337 ! added_ttx_pages.insert(hash);
11339 ! break;
11341 ! case 0x10 ... 0x13:
11342 ! case 0x20 ... 0x23: // dvb subtitles
11344 ! ePyObject tuple = PyTuple_New(5);
11345 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
11346 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
11347 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
11348 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
11349 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
11350 ! PyList_Insert(l, 0, tuple);
11351 ! Py_DECREF(tuple);
11352 ! break;
11358 ! for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
11359 ! it != subs.end(); ++it)
11361 ! int page_number = it->teletext_page_number & 0xFF;
11362 ! int magazine_number = it->teletext_magazine_number & 7;
11363 ! int hash = magazine_number << 8 | page_number;
11364 ! if (added_ttx_pages.find(hash) == added_ttx_pages.end())
11366 ! ePyObject tuple = PyTuple_New(5);
11367 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
11368 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
11369 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
11370 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
11371 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
11372 ! PyList_Append(l, tuple);
11373 ! Py_DECREF(tuple);
11377 ! return l;
11380 ! void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
11382 ! if (m_subtitle_widget)
11384 ! pts_t pos = 0;
11385 ! //if (m_decoder)
11386 ! // m_decoder->getPTS(0, pos);
11387 ! xineLib->getPTS(pos);
11388 ! eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
11389 ! m_subtitle_pages.push_back(page);
11390 ! checkSubtitleTiming();
11394 ! void eDVBServicePlay::checkSubtitleTiming()
11396 ! eDebug("checkSubtitleTiming");
11397 ! if (!m_subtitle_widget)
11398 ! return;
11399 ! while (1)
11401 ! enum { TELETEXT, DVB } type;
11402 ! eDVBTeletextSubtitlePage page;
11403 ! eDVBSubtitlePage dvb_page;
11404 ! pts_t show_time;
11405 ! if (!m_subtitle_pages.empty())
11407 ! page = m_subtitle_pages.front();
11408 ! type = TELETEXT;
11409 ! show_time = page.m_pts;
11411 ! else if (!m_dvb_subtitle_pages.empty())
11413 ! dvb_page = m_dvb_subtitle_pages.front();
11414 ! type = DVB;
11415 ! show_time = dvb_page.m_show_time;
11417 ! else
11418 ! return;
11420 ! pts_t pos = 0;
11422 ! //if (m_decoder)
11423 ! // m_decoder->getPTS(0, pos);
11424 ! xineLib->getPTS(pos);
11426 ! eDebug("%lld %lld", pos, show_time);
11427 ! int diff = show_time - pos;
11428 ! if (type == TELETEXT && !page.m_have_pts)
11430 ! eDebug("ttx subtitle page without pts... immediate show");
11431 ! diff = 0;
11433 ! if (diff < 0)
11435 ! eDebug("[late (%d ms)]", -diff / 90);
11436 ! diff = 0;
11438 ! if (abs(diff) > 1800000)
11440 ! eDebug("[invalid]... immediate show!");
11441 ! diff = 0;
11443 ! if ((diff/90)<20)
11445 ! if (type == TELETEXT)
11447 ! eDebug("display teletext subtitle page %lld", show_time);
11448 ! m_subtitle_widget->setPage(page);
11449 ! m_subtitle_pages.pop_front();
11451 ! else
11453 ! eDebug("display dvb subtitle Page %lld", show_time);
11454 ! m_subtitle_widget->setPage(dvb_page);
11455 ! m_dvb_subtitle_pages.pop_front();
11457 ! } else
11459 ! eDebug("start subtitle delay %d", diff / 90);
11460 ! m_subtitle_sync_timer->start(diff / 90, 1);
11461 ! break;
11466 ! void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
11468 ! if (m_subtitle_widget)
11470 ! pts_t pos = 0;
11471 ! //if (m_decoder)
11472 ! // m_decoder->getPTS(0, pos);
11473 ! xineLib->getPTS(pos);
11474 ! eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
11475 ! m_dvb_subtitle_pages.push_back(p);
11476 ! checkSubtitleTiming();
11480 ! int eDVBServicePlay::getAC3Delay()
11482 ! if (m_dvb_service)
11483 ! return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
11484 ! else if (m_decoder)
11485 ! return m_decoder->getAC3Delay();
11486 ! else
11487 ! return 0;
11490 ! int eDVBServicePlay::getPCMDelay()
11492 ! if (m_dvb_service)
11493 ! return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
11494 ! else if (m_decoder)
11495 ! return m_decoder->getPCMDelay();
11496 ! else
11497 ! return 0;
11500 ! void eDVBServicePlay::setAC3Delay(int delay)
11502 ! if (m_dvb_service)
11503 ! m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
11504 ! if (m_decoder) {
11505 ! std::string config_delay;
11506 ! int config_delay_int = 0;
11507 ! if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
11508 ! config_delay_int = atoi(config_delay.c_str());
11509 ! m_decoder->setAC3Delay(delay + config_delay_int);
11513 ! void eDVBServicePlay::setPCMDelay(int delay)
11515 ! if (m_dvb_service)
11516 ! m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
11517 ! if (m_decoder) {
11518 ! std::string config_delay;
11519 ! int config_delay_int = 0;
11520 ! if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
11521 ! config_delay_int = atoi(config_delay.c_str());
11522 ! else
11523 ! config_delay_int = 0;
11524 ! m_decoder->setPCMDelay(delay + config_delay_int);
11528 ! void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
11530 ! switch(event.type) {
11531 ! case iTSMPEGDecoder::videoEvent::eventSizeChanged:
11532 ! m_event((iPlayableService*)this, evVideoSizeChanged);
11533 ! break;
11534 ! case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
11535 ! m_event((iPlayableService*)this, evVideoFramerateChanged);
11536 ! break;
11537 ! case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
11538 ! m_event((iPlayableService*)this, evVideoProgressiveChanged);
11539 ! break;
11540 ! default:
11541 ! break;
11545 ! RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
11547 ! ptr = this;
11548 ! return 0;
11551 ! PyObject *eDVBServicePlay::getStreamingData()
11553 ! eDVBServicePMTHandler::program program;
11554 ! if (m_service_handler.getProgramInfo(program))
11556 ! Py_RETURN_NONE;
11559 ! ePyObject r = program.createPythonObject();
11560 ! ePtr<iDVBDemux> demux;
11561 ! if (!m_service_handler.getDataDemux(demux))
11563 ! uint8_t demux_id;
11564 ! if (!demux->getCADemuxID(demux_id))
11565 ! PutToDict(r, "demux", demux_id);
11568 ! return r;
11572 ! DEFINE_REF(eDVBServicePlay)
11574 ! PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
11576 ! switch (w)
11578 ! case iServiceInformation::sTransponderData:
11579 ! return eStaticServiceDVBInformation().getInfoObject(ref, w);
11580 ! default:
11581 ! break;
11583 ! return iStaticServiceInformation::getInfoObject(ref, w);
11586 ! eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");
11587 diff -crB Enigma2PC/lib/service/servicemp3.cpp Enigma2PC_orig/lib/service/servicemp3.cpp
11588 *** Enigma2PC/lib/service/servicemp3.cpp 2011-11-20 21:56:11.260830302 +0400
11589 --- Enigma2PC_orig/lib/service/servicemp3.cpp 2011-11-20 03:56:00.000000000 +0400
11590 ***************
11591 *** 1,1964 ****
11592 ! /* note: this requires gstreamer 0.10.x and a big list of plugins. */
11593 ! /* it's currently hardcoded to use a big-endian alsasink as sink. */
11594 ! #include <lib/base/ebase.h>
11595 ! #include <lib/base/eerror.h>
11596 ! #include <lib/base/init_num.h>
11597 ! #include <lib/base/init.h>
11598 ! #include <lib/base/nconfig.h>
11599 ! #include <lib/base/object.h>
11600 ! #include <lib/dvb/decoder.h>
11601 ! #include <lib/components/file_eraser.h>
11602 ! #include <lib/gui/esubtitle.h>
11603 ! #include <lib/service/servicemp3.h>
11604 ! #include <lib/service/service.h>
11605 ! #include <lib/gdi/gpixmap.h>
11607 ! #include <string>
11609 ! #include <gst/gst.h>
11610 ! #include <gst/pbutils/missing-plugins.h>
11611 ! #include <sys/stat.h>
11613 ! #define HTTP_TIMEOUT 10
11615 ! // eServiceFactoryMP3
11617 ! eServiceFactoryMP3::eServiceFactoryMP3()
11619 ! ePtr<eServiceCenter> sc;
11621 ! eServiceCenter::getPrivInstance(sc);
11622 ! if (sc)
11624 ! std::list<std::string> extensions;
11625 ! extensions.push_back("mp2");
11626 ! extensions.push_back("mp3");
11627 ! extensions.push_back("ogg");
11628 ! extensions.push_back("mpg");
11629 ! extensions.push_back("vob");
11630 ! extensions.push_back("wav");
11631 ! extensions.push_back("wave");
11632 ! extensions.push_back("m4v");
11633 ! extensions.push_back("mkv");
11634 ! extensions.push_back("avi");
11635 ! extensions.push_back("divx");
11636 ! extensions.push_back("dat");
11637 ! extensions.push_back("flac");
11638 ! extensions.push_back("mp4");
11639 ! extensions.push_back("mov");
11640 ! extensions.push_back("m4a");
11641 ! sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
11644 ! m_service_info = new eStaticServiceMP3Info();
11647 ! eServiceFactoryMP3::~eServiceFactoryMP3()
11649 ! ePtr<eServiceCenter> sc;
11651 ! eServiceCenter::getPrivInstance(sc);
11652 ! if (sc)
11653 ! sc->removeServiceFactory(eServiceFactoryMP3::id);
11656 ! DEFINE_REF(eServiceFactoryMP3)
11658 ! // iServiceHandler
11659 ! RESULT eServiceFactoryMP3::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
11661 ! // check resources...
11662 ! ptr = new eServiceMP3(ref);
11663 ! return 0;
11666 ! RESULT eServiceFactoryMP3::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
11668 ! ptr=0;
11669 ! return -1;
11672 ! RESULT eServiceFactoryMP3::list(const eServiceReference &, ePtr<iListableService> &ptr)
11674 ! ptr=0;
11675 ! return -1;
11678 ! RESULT eServiceFactoryMP3::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
11680 ! ptr = m_service_info;
11681 ! return 0;
11684 ! class eMP3ServiceOfflineOperations: public iServiceOfflineOperations
11686 ! DECLARE_REF(eMP3ServiceOfflineOperations);
11687 ! eServiceReference m_ref;
11688 ! public:
11689 ! eMP3ServiceOfflineOperations(const eServiceReference &ref);
11691 ! RESULT deleteFromDisk(int simulate);
11692 ! RESULT getListOfFilenames(std::list<std::string> &);
11693 ! RESULT reindex();
11694 ! };
11696 ! DEFINE_REF(eMP3ServiceOfflineOperations);
11698 ! eMP3ServiceOfflineOperations::eMP3ServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReference&)ref)
11702 ! RESULT eMP3ServiceOfflineOperations::deleteFromDisk(int simulate)
11704 ! if (simulate)
11705 ! return 0;
11706 ! else
11708 ! std::list<std::string> res;
11709 ! if (getListOfFilenames(res))
11710 ! return -1;
11712 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
11713 ! if (!eraser)
11714 ! eDebug("FATAL !! can't get background file eraser");
11716 ! for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
11718 ! eDebug("Removing %s...", i->c_str());
11719 ! if (eraser)
11720 ! eraser->erase(i->c_str());
11721 ! else
11722 ! ::unlink(i->c_str());
11725 ! return 0;
11729 ! RESULT eMP3ServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
11731 ! res.clear();
11732 ! res.push_back(m_ref.path);
11733 ! return 0;
11736 ! RESULT eMP3ServiceOfflineOperations::reindex()
11738 ! return -1;
11742 ! RESULT eServiceFactoryMP3::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
11744 ! ptr = new eMP3ServiceOfflineOperations(ref);
11745 ! return 0;
11748 ! // eStaticServiceMP3Info
11751 ! // eStaticServiceMP3Info is seperated from eServiceMP3 to give information
11752 ! // about unopened files.
11754 ! // probably eServiceMP3 should use this class as well, and eStaticServiceMP3Info
11755 ! // should have a database backend where ID3-files etc. are cached.
11756 ! // this would allow listing the mp3 database based on certain filters.
11758 ! DEFINE_REF(eStaticServiceMP3Info)
11760 ! eStaticServiceMP3Info::eStaticServiceMP3Info()
11764 ! RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string &name)
11766 ! if ( ref.name.length() )
11767 ! name = ref.name;
11768 ! else
11770 ! size_t last = ref.path.rfind('/');
11771 ! if (last != std::string::npos)
11772 ! name = ref.path.substr(last+1);
11773 ! else
11774 ! name = ref.path;
11776 ! return 0;
11779 ! int eStaticServiceMP3Info::getLength(const eServiceReference &ref)
11781 ! return -1;
11784 ! int eStaticServiceMP3Info::getInfo(const eServiceReference &ref, int w)
11786 ! switch (w)
11788 ! case iServiceInformation::sTimeCreate:
11790 ! struct stat s;
11791 ! if(stat(ref.path.c_str(), &s) == 0)
11793 ! return s.st_mtime;
11795 ! return iServiceInformation::resNA;
11797 ! default: break;
11799 ! return iServiceInformation::resNA;
11803 ! // eServiceMP3
11804 ! int eServiceMP3::ac3_delay,
11805 ! eServiceMP3::pcm_delay;
11807 ! eServiceMP3::eServiceMP3(eServiceReference ref)
11808 ! :m_ref(ref), m_pump(eApp, 1)
11810 ! m_seekTimeout = eTimer::create(eApp);
11811 ! m_subtitle_sync_timer = eTimer::create(eApp);
11812 ! m_streamingsrc_timeout = 0;
11813 ! m_stream_tags = 0;
11814 ! m_currentAudioStream = -1;
11815 ! m_currentSubtitleStream = 0;
11816 ! m_subtitle_widget = 0;
11817 ! m_currentTrickRatio = 0;
11818 ! m_subs_to_pull = 0;
11819 ! m_buffer_size = 1*1024*1024;
11820 ! m_prev_decoder_time = -1;
11821 ! m_decoder_time_valid_state = 0;
11822 ! m_errorInfo.missing_codec = "";
11824 ! CONNECT(m_seekTimeout->timeout, eServiceMP3::seekTimeoutCB);
11825 ! CONNECT(m_subtitle_sync_timer->timeout, eServiceMP3::pushSubtitles);
11826 ! CONNECT(m_pump.recv_msg, eServiceMP3::gstPoll);
11827 ! m_aspect = m_width = m_height = m_framerate = m_progressive = -1;
11829 ! m_state = stIdle;
11830 ! eDebug("eServiceMP3::construct!");
11832 ! const char *filename = m_ref.path.c_str();
11833 ! const char *ext = strrchr(filename, '.');
11834 ! if (!ext)
11835 ! ext = filename;
11837 ! m_sourceinfo.is_video = FALSE;
11838 ! m_sourceinfo.audiotype = atUnknown;
11839 ! if ( (strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin") && strcasecmp(ext, ".dat") ) == 0 )
11841 ! m_sourceinfo.containertype = ctMPEGPS;
11842 ! m_sourceinfo.is_video = TRUE;
11844 ! else if ( strcasecmp(ext, ".ts") == 0 )
11846 ! m_sourceinfo.containertype = ctMPEGTS;
11847 ! m_sourceinfo.is_video = TRUE;
11849 ! else if ( strcasecmp(ext, ".mkv") == 0 )
11851 ! m_sourceinfo.containertype = ctMKV;
11852 ! m_sourceinfo.is_video = TRUE;
11854 ! else if ( strcasecmp(ext, ".avi") == 0 || strcasecmp(ext, ".divx") == 0)
11856 ! m_sourceinfo.containertype = ctAVI;
11857 ! m_sourceinfo.is_video = TRUE;
11859 ! else if ( strcasecmp(ext, ".mp4") == 0 || strcasecmp(ext, ".mov") == 0 || strcasecmp(ext, ".m4v") == 0)
11861 ! m_sourceinfo.containertype = ctMP4;
11862 ! m_sourceinfo.is_video = TRUE;
11864 ! else if ( strcasecmp(ext, ".m4a") == 0 )
11866 ! m_sourceinfo.containertype = ctMP4;
11867 ! m_sourceinfo.audiotype = atAAC;
11869 ! else if ( strcasecmp(ext, ".mp3") == 0 )
11870 ! m_sourceinfo.audiotype = atMP3;
11871 ! else if ( (strncmp(filename, "/autofs/", 8) || strncmp(filename+strlen(filename)-13, "/track-", 7) || strcasecmp(ext, ".wav")) == 0 )
11872 ! m_sourceinfo.containertype = ctCDA;
11873 ! if ( strcasecmp(ext, ".dat") == 0 )
11875 ! m_sourceinfo.containertype = ctVCD;
11876 ! m_sourceinfo.is_video = TRUE;
11878 ! if ( strstr(filename, "://") )
11879 ! m_sourceinfo.is_streaming = TRUE;
11881 ! gchar *uri;
11883 ! if ( m_sourceinfo.is_streaming )
11885 ! uri = g_strdup_printf ("%s", filename);
11886 ! m_streamingsrc_timeout = eTimer::create(eApp);;
11887 ! CONNECT(m_streamingsrc_timeout->timeout, eServiceMP3::sourceTimeout);
11889 ! std::string config_str;
11890 ! if( ePythonConfigQuery::getConfigValue("config.mediaplayer.useAlternateUserAgent", config_str) == 0 )
11892 ! if ( config_str == "True" )
11893 ! ePythonConfigQuery::getConfigValue("config.mediaplayer.alternateUserAgent", m_useragent);
11895 ! if ( m_useragent.length() == 0 )
11896 ! m_useragent = "Dream Multimedia Dreambox Enigma2 Mediaplayer";
11898 ! else if ( m_sourceinfo.containertype == ctCDA )
11900 ! int i_track = atoi(filename+18);
11901 ! uri = g_strdup_printf ("cdda://%i", i_track);
11903 ! else if ( m_sourceinfo.containertype == ctVCD )
11905 ! int fd = open(filename,O_RDONLY);
11906 ! char tmp[128*1024];
11907 ! int ret = read(fd, tmp, 128*1024);
11908 ! close(fd);
11909 ! if ( ret == -1 ) // this is a "REAL" VCD
11910 ! uri = g_strdup_printf ("vcd://");
11911 ! else
11912 ! uri = g_filename_to_uri(filename, NULL, NULL);
11914 ! else
11916 ! uri = g_filename_to_uri(filename, NULL, NULL);
11918 ! eDebug("eServiceMP3::playbin2 uri=%s", uri);
11920 ! m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
11921 ! if (!m_gst_playbin)
11922 ! m_errorInfo.error_message = "failed to create GStreamer pipeline!\n";
11924 ! g_object_set (G_OBJECT (m_gst_playbin), "uri", uri, NULL);
11926 ! int flags = 0x47; // ( GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_TEXT );
11927 ! g_object_set (G_OBJECT (m_gst_playbin), "flags", flags, NULL);
11929 ! g_free(uri);
11931 ! GstElement *subsink = gst_element_factory_make("appsink", "subtitle_sink");
11932 ! if (!subsink)
11933 ! eDebug("eServiceMP3::sorry, can't play: missing gst-plugin-appsink");
11934 ! else
11936 ! m_subs_to_pull_handler_id = g_signal_connect (subsink, "new-buffer", G_CALLBACK (gstCBsubtitleAvail), this);
11937 ! g_object_set (G_OBJECT (subsink), "caps", gst_caps_from_string("text/plain; text/x-plain; text/x-pango-markup; video/x-dvd-subpicture; subpicture/x-pgs"), NULL);
11938 ! g_object_set (G_OBJECT (m_gst_playbin), "text-sink", subsink, NULL);
11942 ! if ( m_gst_playbin )
11944 ! gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_playbin)), gstBusSyncHandler, this);
11945 ! char srt_filename[strlen(filename)+1];
11946 ! strncpy(srt_filename,filename,strlen(filename)-3);
11947 ! srt_filename[strlen(filename)-3]='\0';
11948 ! strcat(srt_filename, "srt");
11949 ! struct stat buffer;
11950 ! if (stat(srt_filename, &buffer) == 0)
11952 ! eDebug("eServiceMP3::subtitle uri: %s", g_filename_to_uri(srt_filename, NULL, NULL));
11953 ! g_object_set (G_OBJECT (m_gst_playbin), "suburi", g_filename_to_uri(srt_filename, NULL, NULL), NULL);
11955 ! if ( m_sourceinfo.is_streaming )
11957 ! g_signal_connect (G_OBJECT (m_gst_playbin), "notify::source", G_CALLBACK (gstHTTPSourceSetAgent), this);
11959 ! } else
11961 ! m_event((iPlayableService*)this, evUser+12);
11963 ! if (m_gst_playbin)
11964 ! gst_object_unref(GST_OBJECT(m_gst_playbin));
11966 ! eDebug("eServiceMP3::sorry, can't play: %s",m_errorInfo.error_message.c_str());
11967 ! m_gst_playbin = 0;
11970 ! setBufferSize(m_buffer_size);
11973 ! eServiceMP3::~eServiceMP3()
11975 ! // disconnect subtitle callback
11976 ! GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
11978 ! if (appsink)
11980 ! g_signal_handler_disconnect (appsink, m_subs_to_pull_handler_id);
11981 ! gst_object_unref(appsink);
11984 ! delete m_subtitle_widget;
11986 ! // disconnect sync handler callback
11987 ! gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_playbin)), NULL, NULL);
11989 ! if (m_state == stRunning)
11990 ! stop();
11992 ! if (m_stream_tags)
11993 ! gst_tag_list_free(m_stream_tags);
11995 ! if (m_gst_playbin)
11997 ! gst_object_unref (GST_OBJECT (m_gst_playbin));
11998 ! eDebug("eServiceMP3::destruct!");
12002 ! DEFINE_REF(eServiceMP3);
12004 ! RESULT eServiceMP3::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
12006 ! connection = new eConnection((iPlayableService*)this, m_event.connect(event));
12007 ! return 0;
12010 ! RESULT eServiceMP3::start()
12012 ! ASSERT(m_state == stIdle);
12014 ! m_state = stRunning;
12015 ! if (m_gst_playbin)
12017 ! eDebug("eServiceMP3::starting pipeline");
12018 ! gst_element_set_state (m_gst_playbin, GST_STATE_PLAYING);
12021 ! m_event(this, evStart);
12023 ! return 0;
12026 ! void eServiceMP3::sourceTimeout()
12028 ! eDebug("eServiceMP3::http source timeout! issuing eof...");
12029 ! m_event((iPlayableService*)this, evEOF);
12032 ! RESULT eServiceMP3::stop()
12034 ! ASSERT(m_state != stIdle);
12036 ! if (m_state == stStopped)
12037 ! return -1;
12039 ! //GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(m_gst_playbin),GST_DEBUG_GRAPH_SHOW_ALL,"e2-playbin");
12041 ! eDebug("eServiceMP3::stop %s", m_ref.path.c_str());
12042 ! gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
12043 ! m_state = stStopped;
12045 ! return 0;
12048 ! RESULT eServiceMP3::setTarget(int target)
12050 ! return -1;
12053 ! RESULT eServiceMP3::pause(ePtr<iPauseableService> &ptr)
12055 ! ptr=this;
12056 ! return 0;
12059 ! RESULT eServiceMP3::setSlowMotion(int ratio)
12061 ! if (!ratio)
12062 ! return 0;
12063 ! eDebug("eServiceMP3::setSlowMotion ratio=%f",1/(float)ratio);
12064 ! return trickSeek(1/(float)ratio);
12067 ! RESULT eServiceMP3::setFastForward(int ratio)
12069 ! eDebug("eServiceMP3::setFastForward ratio=%i",ratio);
12070 ! return trickSeek(ratio);
12073 ! void eServiceMP3::seekTimeoutCB()
12075 ! pts_t ppos, len;
12076 ! getPlayPosition(ppos);
12077 ! getLength(len);
12078 ! ppos += 90000*m_currentTrickRatio;
12080 ! if (ppos < 0)
12082 ! ppos = 0;
12083 ! m_seekTimeout->stop();
12085 ! if (ppos > len)
12087 ! ppos = 0;
12088 ! stop();
12089 ! m_seekTimeout->stop();
12090 ! return;
12092 ! seekTo(ppos);
12095 ! // iPausableService
12096 ! RESULT eServiceMP3::pause()
12098 ! if (!m_gst_playbin || m_state != stRunning)
12099 ! return -1;
12101 ! gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
12103 ! return 0;
12106 ! RESULT eServiceMP3::unpause()
12108 ! if (!m_gst_playbin || m_state != stRunning)
12109 ! return -1;
12111 ! gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
12113 ! return 0;
12116 ! /* iSeekableService */
12117 ! RESULT eServiceMP3::seek(ePtr<iSeekableService> &ptr)
12119 ! ptr = this;
12120 ! return 0;
12123 ! RESULT eServiceMP3::getLength(pts_t &pts)
12125 ! if (!m_gst_playbin)
12126 ! return -1;
12128 ! if (m_state != stRunning)
12129 ! return -1;
12131 ! GstFormat fmt = GST_FORMAT_TIME;
12132 ! gint64 len;
12134 ! if (!gst_element_query_duration(m_gst_playbin, &fmt, &len))
12135 ! return -1;
12136 ! /* len is in nanoseconds. we have 90 000 pts per second. */
12138 ! pts = len / 11111;
12139 ! return 0;
12142 ! RESULT eServiceMP3::seekToImpl(pts_t to)
12144 ! /* convert pts to nanoseconds */
12145 ! gint64 time_nanoseconds = to * 11111LL;
12146 ! if (!gst_element_seek (m_gst_playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
12147 ! GST_SEEK_TYPE_SET, time_nanoseconds,
12148 ! GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
12150 ! eDebug("eServiceMP3::seekTo failed");
12151 ! return -1;
12154 ! return 0;
12157 ! RESULT eServiceMP3::seekTo(pts_t to)
12159 ! RESULT ret = -1;
12161 ! if (m_gst_playbin) {
12162 ! eSingleLocker l(m_subs_to_pull_lock); // this is needed to dont handle incomming subtitles during seek!
12163 ! if (!(ret = seekToImpl(to)))
12165 ! m_subtitle_pages.clear();
12166 ! m_prev_decoder_time = -1;
12167 ! m_decoder_time_valid_state = 0;
12168 ! m_subs_to_pull = 0;
12172 ! return ret;
12176 ! RESULT eServiceMP3::trickSeek(gdouble ratio)
12178 ! if (!m_gst_playbin)
12179 ! return -1;
12180 ! if (!ratio)
12181 ! return seekRelative(0, 0);
12183 ! GstEvent *s_event;
12184 ! int flags;
12185 ! flags = GST_SEEK_FLAG_NONE;
12186 ! flags |= GST_SEEK_FLAG_FLUSH;
12187 ! // flags |= GstSeekFlags (GST_SEEK_FLAG_ACCURATE);
12188 ! flags |= GST_SEEK_FLAG_KEY_UNIT;
12189 ! // flags |= GstSeekFlags (GST_SEEK_FLAG_SEGMENT);
12190 ! // flags |= GstSeekFlags (GST_SEEK_FLAG_SKIP);
12192 ! GstFormat fmt = GST_FORMAT_TIME;
12193 ! gint64 pos, len;
12194 ! gst_element_query_duration(m_gst_playbin, &fmt, &len);
12195 ! gst_element_query_position(m_gst_playbin, &fmt, &pos);
12197 ! if ( ratio >= 0 )
12199 ! s_event = gst_event_new_seek (ratio, GST_FORMAT_TIME, (GstSeekFlags)flags, GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_SET, len);
12201 ! eDebug("eServiceMP3::trickSeek with rate %lf to %" GST_TIME_FORMAT " ", ratio, GST_TIME_ARGS (pos));
12203 ! else
12205 ! s_event = gst_event_new_seek (ratio, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_SKIP|GST_SEEK_FLAG_FLUSH), GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
12208 ! if (!gst_element_send_event ( GST_ELEMENT (m_gst_playbin), s_event))
12210 ! eDebug("eServiceMP3::trickSeek failed");
12211 ! return -1;
12214 ! return 0;
12218 ! RESULT eServiceMP3::seekRelative(int direction, pts_t to)
12220 ! if (!m_gst_playbin)
12221 ! return -1;
12223 ! pts_t ppos;
12224 ! getPlayPosition(ppos);
12225 ! ppos += to * direction;
12226 ! if (ppos < 0)
12227 ! ppos = 0;
12228 ! seekTo(ppos);
12230 ! return 0;
12233 ! RESULT eServiceMP3::getPlayPosition(pts_t &pts)
12235 ! GstFormat fmt = GST_FORMAT_TIME;
12236 ! gint64 pos;
12237 ! GstElement *sink;
12238 ! pts = 0;
12240 ! if (!m_gst_playbin)
12241 ! return -1;
12242 ! if (m_state != stRunning)
12243 ! return -1;
12245 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
12247 ! if (!sink)
12248 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
12250 ! if (!sink)
12251 ! return -1;
12253 ! gchar *name = gst_element_get_name(sink);
12254 ! gboolean use_get_decoder_time = strstr(name, "dvbaudiosink") || strstr(name, "dvbvideosink");
12255 ! g_free(name);
12257 ! if (use_get_decoder_time)
12258 ! g_signal_emit_by_name(sink, "get-decoder-time", &pos);
12260 ! gst_object_unref(sink);
12262 ! if (!use_get_decoder_time && !gst_element_query_position(m_gst_playbin, &fmt, &pos)) {
12263 ! eDebug("gst_element_query_position failed in getPlayPosition");
12264 ! return -1;
12267 ! /* pos is in nanoseconds. we have 90 000 pts per second. */
12268 ! pts = pos / 11111;
12269 ! // eDebug("gst_element_query_position %lld pts (%lld ms)", pts, pos/1000000);
12270 ! return 0;
12273 ! RESULT eServiceMP3::setTrickmode(int trick)
12275 ! /* trickmode is not yet supported by our dvbmediasinks. */
12276 ! return -1;
12279 ! RESULT eServiceMP3::isCurrentlySeekable()
12281 ! int ret = 3; // seeking and fast/slow winding possible
12282 ! GstElement *sink;
12284 ! if (!m_gst_playbin)
12285 ! return 0;
12286 ! if (m_state != stRunning)
12287 ! return 0;
12289 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
12291 ! // disable fast winding yet when a dvbvideosink or dvbaudiosink is used
12292 ! // for this we must do some changes on different places.. (gstreamer.. our sinks.. enigma2)
12293 ! if (sink) {
12294 ! ret &= ~2; // only seeking possible
12295 ! gst_object_unref(sink);
12297 ! else {
12298 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
12299 ! if (sink) {
12300 ! ret &= ~2; // only seeking possible
12301 ! gst_object_unref(sink);
12305 ! return ret;
12308 ! RESULT eServiceMP3::info(ePtr<iServiceInformation>&i)
12310 ! i = this;
12311 ! return 0;
12314 ! RESULT eServiceMP3::getName(std::string &name)
12316 ! std::string title = m_ref.getName();
12317 ! if (title.empty())
12319 ! name = m_ref.path;
12320 ! size_t n = name.rfind('/');
12321 ! if (n != std::string::npos)
12322 ! name = name.substr(n + 1);
12324 ! else
12325 ! name = title;
12326 ! return 0;
12329 ! int eServiceMP3::getInfo(int w)
12331 ! const gchar *tag = 0;
12333 ! switch (w)
12335 ! case sServiceref: return m_ref;
12336 ! case sVideoHeight: return m_height;
12337 ! case sVideoWidth: return m_width;
12338 ! case sFrameRate: return m_framerate;
12339 ! case sProgressive: return m_progressive;
12340 ! case sAspect: return m_aspect;
12341 ! case sTagTitle:
12342 ! case sTagArtist:
12343 ! case sTagAlbum:
12344 ! case sTagTitleSortname:
12345 ! case sTagArtistSortname:
12346 ! case sTagAlbumSortname:
12347 ! case sTagDate:
12348 ! case sTagComposer:
12349 ! case sTagGenre:
12350 ! case sTagComment:
12351 ! case sTagExtendedComment:
12352 ! case sTagLocation:
12353 ! case sTagHomepage:
12354 ! case sTagDescription:
12355 ! case sTagVersion:
12356 ! case sTagISRC:
12357 ! case sTagOrganization:
12358 ! case sTagCopyright:
12359 ! case sTagCopyrightURI:
12360 ! case sTagContact:
12361 ! case sTagLicense:
12362 ! case sTagLicenseURI:
12363 ! case sTagCodec:
12364 ! case sTagAudioCodec:
12365 ! case sTagVideoCodec:
12366 ! case sTagEncoder:
12367 ! case sTagLanguageCode:
12368 ! case sTagKeywords:
12369 ! case sTagChannelMode:
12370 ! case sUser+12:
12371 ! return resIsString;
12372 ! case sTagTrackGain:
12373 ! case sTagTrackPeak:
12374 ! case sTagAlbumGain:
12375 ! case sTagAlbumPeak:
12376 ! case sTagReferenceLevel:
12377 ! case sTagBeatsPerMinute:
12378 ! case sTagImage:
12379 ! case sTagPreviewImage:
12380 ! case sTagAttachment:
12381 ! return resIsPyObject;
12382 ! case sTagTrackNumber:
12383 ! tag = GST_TAG_TRACK_NUMBER;
12384 ! break;
12385 ! case sTagTrackCount:
12386 ! tag = GST_TAG_TRACK_COUNT;
12387 ! break;
12388 ! case sTagAlbumVolumeNumber:
12389 ! tag = GST_TAG_ALBUM_VOLUME_NUMBER;
12390 ! break;
12391 ! case sTagAlbumVolumeCount:
12392 ! tag = GST_TAG_ALBUM_VOLUME_COUNT;
12393 ! break;
12394 ! case sTagBitrate:
12395 ! tag = GST_TAG_BITRATE;
12396 ! break;
12397 ! case sTagNominalBitrate:
12398 ! tag = GST_TAG_NOMINAL_BITRATE;
12399 ! break;
12400 ! case sTagMinimumBitrate:
12401 ! tag = GST_TAG_MINIMUM_BITRATE;
12402 ! break;
12403 ! case sTagMaximumBitrate:
12404 ! tag = GST_TAG_MAXIMUM_BITRATE;
12405 ! break;
12406 ! case sTagSerial:
12407 ! tag = GST_TAG_SERIAL;
12408 ! break;
12409 ! case sTagEncoderVersion:
12410 ! tag = GST_TAG_ENCODER_VERSION;
12411 ! break;
12412 ! case sTagCRC:
12413 ! tag = "has-crc";
12414 ! break;
12415 ! default:
12416 ! return resNA;
12419 ! if (!m_stream_tags || !tag)
12420 ! return 0;
12422 ! guint value;
12423 ! if (gst_tag_list_get_uint(m_stream_tags, tag, &value))
12424 ! return (int) value;
12426 ! return 0;
12429 ! std::string eServiceMP3::getInfoString(int w)
12431 ! if ( !m_stream_tags && w < sUser && w > 26 )
12432 ! return "";
12433 ! const gchar *tag = 0;
12434 ! switch (w)
12436 ! case sTagTitle:
12437 ! tag = GST_TAG_TITLE;
12438 ! break;
12439 ! case sTagArtist:
12440 ! tag = GST_TAG_ARTIST;
12441 ! break;
12442 ! case sTagAlbum:
12443 ! tag = GST_TAG_ALBUM;
12444 ! break;
12445 ! case sTagTitleSortname:
12446 ! tag = GST_TAG_TITLE_SORTNAME;
12447 ! break;
12448 ! case sTagArtistSortname:
12449 ! tag = GST_TAG_ARTIST_SORTNAME;
12450 ! break;
12451 ! case sTagAlbumSortname:
12452 ! tag = GST_TAG_ALBUM_SORTNAME;
12453 ! break;
12454 ! case sTagDate:
12455 ! GDate *date;
12456 ! if (gst_tag_list_get_date(m_stream_tags, GST_TAG_DATE, &date))
12458 ! gchar res[5];
12459 ! g_date_strftime (res, sizeof(res), "%Y-%M-%D", date);
12460 ! return (std::string)res;
12462 ! break;
12463 ! case sTagComposer:
12464 ! tag = GST_TAG_COMPOSER;
12465 ! break;
12466 ! case sTagGenre:
12467 ! tag = GST_TAG_GENRE;
12468 ! break;
12469 ! case sTagComment:
12470 ! tag = GST_TAG_COMMENT;
12471 ! break;
12472 ! case sTagExtendedComment:
12473 ! tag = GST_TAG_EXTENDED_COMMENT;
12474 ! break;
12475 ! case sTagLocation:
12476 ! tag = GST_TAG_LOCATION;
12477 ! break;
12478 ! case sTagHomepage:
12479 ! tag = GST_TAG_HOMEPAGE;
12480 ! break;
12481 ! case sTagDescription:
12482 ! tag = GST_TAG_DESCRIPTION;
12483 ! break;
12484 ! case sTagVersion:
12485 ! tag = GST_TAG_VERSION;
12486 ! break;
12487 ! case sTagISRC:
12488 ! tag = GST_TAG_ISRC;
12489 ! break;
12490 ! case sTagOrganization:
12491 ! tag = GST_TAG_ORGANIZATION;
12492 ! break;
12493 ! case sTagCopyright:
12494 ! tag = GST_TAG_COPYRIGHT;
12495 ! break;
12496 ! case sTagCopyrightURI:
12497 ! tag = GST_TAG_COPYRIGHT_URI;
12498 ! break;
12499 ! case sTagContact:
12500 ! tag = GST_TAG_CONTACT;
12501 ! break;
12502 ! case sTagLicense:
12503 ! tag = GST_TAG_LICENSE;
12504 ! break;
12505 ! case sTagLicenseURI:
12506 ! tag = GST_TAG_LICENSE_URI;
12507 ! break;
12508 ! case sTagCodec:
12509 ! tag = GST_TAG_CODEC;
12510 ! break;
12511 ! case sTagAudioCodec:
12512 ! tag = GST_TAG_AUDIO_CODEC;
12513 ! break;
12514 ! case sTagVideoCodec:
12515 ! tag = GST_TAG_VIDEO_CODEC;
12516 ! break;
12517 ! case sTagEncoder:
12518 ! tag = GST_TAG_ENCODER;
12519 ! break;
12520 ! case sTagLanguageCode:
12521 ! tag = GST_TAG_LANGUAGE_CODE;
12522 ! break;
12523 ! case sTagKeywords:
12524 ! tag = GST_TAG_KEYWORDS;
12525 ! break;
12526 ! case sTagChannelMode:
12527 ! tag = "channel-mode";
12528 ! break;
12529 ! case sUser+12:
12530 ! return m_errorInfo.error_message;
12531 ! default:
12532 ! return "";
12534 ! if ( !tag )
12535 ! return "";
12536 ! gchar *value;
12537 ! if (gst_tag_list_get_string(m_stream_tags, tag, &value))
12539 ! std::string res = value;
12540 ! g_free(value);
12541 ! return res;
12543 ! return "";
12546 ! PyObject *eServiceMP3::getInfoObject(int w)
12548 ! const gchar *tag = 0;
12549 ! bool isBuffer = false;
12550 ! switch (w)
12552 ! case sTagTrackGain:
12553 ! tag = GST_TAG_TRACK_GAIN;
12554 ! break;
12555 ! case sTagTrackPeak:
12556 ! tag = GST_TAG_TRACK_PEAK;
12557 ! break;
12558 ! case sTagAlbumGain:
12559 ! tag = GST_TAG_ALBUM_GAIN;
12560 ! break;
12561 ! case sTagAlbumPeak:
12562 ! tag = GST_TAG_ALBUM_PEAK;
12563 ! break;
12564 ! case sTagReferenceLevel:
12565 ! tag = GST_TAG_REFERENCE_LEVEL;
12566 ! break;
12567 ! case sTagBeatsPerMinute:
12568 ! tag = GST_TAG_BEATS_PER_MINUTE;
12569 ! break;
12570 ! case sTagImage:
12571 ! tag = GST_TAG_IMAGE;
12572 ! isBuffer = true;
12573 ! break;
12574 ! case sTagPreviewImage:
12575 ! tag = GST_TAG_PREVIEW_IMAGE;
12576 ! isBuffer = true;
12577 ! break;
12578 ! case sTagAttachment:
12579 ! tag = GST_TAG_ATTACHMENT;
12580 ! isBuffer = true;
12581 ! break;
12582 ! default:
12583 ! break;
12586 ! if ( isBuffer )
12588 ! const GValue *gv_buffer = gst_tag_list_get_value_index(m_stream_tags, tag, 0);
12589 ! if ( gv_buffer )
12591 ! GstBuffer *buffer;
12592 ! buffer = gst_value_get_buffer (gv_buffer);
12593 ! return PyBuffer_FromMemory(GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
12596 ! else
12598 ! gdouble value = 0.0;
12599 ! gst_tag_list_get_double(m_stream_tags, tag, &value);
12600 ! return PyFloat_FromDouble(value);
12603 ! return 0;
12606 ! RESULT eServiceMP3::audioChannel(ePtr<iAudioChannelSelection> &ptr)
12608 ! ptr = this;
12609 ! return 0;
12612 ! RESULT eServiceMP3::audioTracks(ePtr<iAudioTrackSelection> &ptr)
12614 ! ptr = this;
12615 ! return 0;
12618 ! RESULT eServiceMP3::subtitle(ePtr<iSubtitleOutput> &ptr)
12620 ! ptr = this;
12621 ! return 0;
12624 ! RESULT eServiceMP3::audioDelay(ePtr<iAudioDelay> &ptr)
12626 ! ptr = this;
12627 ! return 0;
12630 ! int eServiceMP3::getNumberOfTracks()
12632 ! return m_audioStreams.size();
12635 ! int eServiceMP3::getCurrentTrack()
12637 ! if (m_currentAudioStream == -1)
12638 ! g_object_get (G_OBJECT (m_gst_playbin), "current-audio", &m_currentAudioStream, NULL);
12639 ! return m_currentAudioStream;
12642 ! RESULT eServiceMP3::selectTrack(unsigned int i)
12644 ! pts_t ppos;
12645 ! getPlayPosition(ppos);
12646 ! ppos -= 90000;
12647 ! if (ppos < 0)
12648 ! ppos = 0;
12650 ! int ret = selectAudioStream(i);
12651 ! if (!ret) {
12652 ! /* flush */
12653 ! seekTo(ppos);
12656 ! return ret;
12659 ! int eServiceMP3::selectAudioStream(int i)
12661 ! int current_audio;
12662 ! g_object_set (G_OBJECT (m_gst_playbin), "current-audio", i, NULL);
12663 ! g_object_get (G_OBJECT (m_gst_playbin), "current-audio", &current_audio, NULL);
12664 ! if ( current_audio == i )
12666 ! eDebug ("eServiceMP3::switched to audio stream %i", current_audio);
12667 ! m_currentAudioStream = i;
12668 ! return 0;
12670 ! return -1;
12673 ! int eServiceMP3::getCurrentChannel()
12675 ! return STEREO;
12678 ! RESULT eServiceMP3::selectChannel(int i)
12680 ! eDebug("eServiceMP3::selectChannel(%i)",i);
12681 ! return 0;
12684 ! RESULT eServiceMP3::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
12686 ! if (i >= m_audioStreams.size())
12687 ! return -2;
12688 ! info.m_description = m_audioStreams[i].codec;
12689 ! /* if (m_audioStreams[i].type == atMPEG)
12690 ! info.m_description = "MPEG";
12691 ! else if (m_audioStreams[i].type == atMP3)
12692 ! info.m_description = "MP3";
12693 ! else if (m_audioStreams[i].type == atAC3)
12694 ! info.m_description = "AC3";
12695 ! else if (m_audioStreams[i].type == atAAC)
12696 ! info.m_description = "AAC";
12697 ! else if (m_audioStreams[i].type == atDTS)
12698 ! info.m_description = "DTS";
12699 ! else if (m_audioStreams[i].type == atPCM)
12700 ! info.m_description = "PCM";
12701 ! else if (m_audioStreams[i].type == atOGG)
12702 ! info.m_description = "OGG";
12703 ! else if (m_audioStreams[i].type == atFLAC)
12704 ! info.m_description = "FLAC";
12705 ! else
12706 ! info.m_description = "???";*/
12707 ! if (info.m_language.empty())
12708 ! info.m_language = m_audioStreams[i].language_code;
12709 ! return 0;
12712 ! subtype_t getSubtitleType(GstPad* pad, gchar *g_codec=NULL)
12714 ! subtype_t type = stUnknown;
12715 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
12717 ! if ( caps )
12719 ! GstStructure* str = gst_caps_get_structure(caps, 0);
12720 ! const gchar *g_type = gst_structure_get_name(str);
12721 ! eDebug("getSubtitleType::subtitle probe caps type=%s", g_type);
12723 ! if ( !strcmp(g_type, "video/x-dvd-subpicture") )
12724 ! type = stVOB;
12725 ! else if ( !strcmp(g_type, "text/x-pango-markup") )
12726 ! type = stSSA;
12727 ! else if ( !strcmp(g_type, "text/plain") )
12728 ! type = stPlainText;
12729 ! else if ( !strcmp(g_type, "subpicture/x-pgs") )
12730 ! type = stPGS;
12731 ! else
12732 ! eDebug("getSubtitleType::unsupported subtitle caps %s (%s)", g_type, g_codec);
12734 ! else if ( g_codec )
12736 ! eDebug("getSubtitleType::subtitle probe codec tag=%s", g_codec);
12737 ! if ( !strcmp(g_codec, "VOB") )
12738 ! type = stVOB;
12739 ! else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
12740 ! type = stSSA;
12741 ! else if ( !strcmp(g_codec, "ASS") )
12742 ! type = stASS;
12743 ! else if ( !strcmp(g_codec, "UTF-8 plain text") )
12744 ! type = stPlainText;
12745 ! else
12746 ! eDebug("getSubtitleType::unsupported subtitle codec %s", g_codec);
12748 ! else
12749 ! eDebug("getSubtitleType::unidentifiable subtitle stream!");
12751 ! return type;
12754 ! void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
12756 ! if (!msg)
12757 ! return;
12758 ! gchar *sourceName;
12759 ! GstObject *source;
12760 ! source = GST_MESSAGE_SRC(msg);
12761 ! if (!GST_IS_OBJECT(source))
12762 ! return;
12763 ! sourceName = gst_object_get_name(source);
12764 ! #if 0
12765 ! gchar *string;
12766 ! if (gst_message_get_structure(msg))
12767 ! string = gst_structure_to_string(gst_message_get_structure(msg));
12768 ! else
12769 ! string = g_strdup(GST_MESSAGE_TYPE_NAME(msg));
12770 ! eDebug("eTsRemoteSource::gst_message from %s: %s", sourceName, string);
12771 ! g_free(string);
12772 ! #endif
12773 ! switch (GST_MESSAGE_TYPE (msg))
12775 ! case GST_MESSAGE_EOS:
12776 ! m_event((iPlayableService*)this, evEOF);
12777 ! break;
12778 ! case GST_MESSAGE_STATE_CHANGED:
12780 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
12781 ! break;
12783 ! GstState old_state, new_state;
12784 ! gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
12786 ! if(old_state == new_state)
12787 ! break;
12789 ! eDebug("eServiceMP3::state transition %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
12791 ! GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
12793 ! switch(transition)
12795 ! case GST_STATE_CHANGE_NULL_TO_READY:
12797 ! } break;
12798 ! case GST_STATE_CHANGE_READY_TO_PAUSED:
12800 ! GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
12801 ! if (appsink)
12803 ! g_object_set (G_OBJECT (appsink), "max-buffers", 2, NULL);
12804 ! g_object_set (G_OBJECT (appsink), "sync", FALSE, NULL);
12805 ! g_object_set (G_OBJECT (appsink), "emit-signals", TRUE, NULL);
12806 ! eDebug("eServiceMP3::appsink properties set!");
12807 ! gst_object_unref(appsink);
12809 ! setAC3Delay(ac3_delay);
12810 ! setPCMDelay(pcm_delay);
12811 ! } break;
12812 ! case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
12814 ! if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout )
12815 ! m_streamingsrc_timeout->stop();
12816 ! } break;
12817 ! case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
12819 ! } break;
12820 ! case GST_STATE_CHANGE_PAUSED_TO_READY:
12822 ! } break;
12823 ! case GST_STATE_CHANGE_READY_TO_NULL:
12825 ! } break;
12827 ! break;
12829 ! case GST_MESSAGE_ERROR:
12831 ! gchar *debug;
12832 ! GError *err;
12833 ! gst_message_parse_error (msg, &err, &debug);
12834 ! g_free (debug);
12835 ! eWarning("Gstreamer error: %s (%i) from %s", err->message, err->code, sourceName );
12836 ! if ( err->domain == GST_STREAM_ERROR )
12838 ! if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
12840 ! if ( g_strrstr(sourceName, "videosink") )
12841 ! m_event((iPlayableService*)this, evUser+11);
12842 ! else if ( g_strrstr(sourceName, "audiosink") )
12843 ! m_event((iPlayableService*)this, evUser+10);
12846 ! g_error_free(err);
12847 ! break;
12849 ! case GST_MESSAGE_INFO:
12851 ! gchar *debug;
12852 ! GError *inf;
12854 ! gst_message_parse_info (msg, &inf, &debug);
12855 ! g_free (debug);
12856 ! if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
12858 ! if ( g_strrstr(sourceName, "videosink") )
12859 ! m_event((iPlayableService*)this, evUser+14);
12861 ! g_error_free(inf);
12862 ! break;
12864 ! case GST_MESSAGE_TAG:
12866 ! GstTagList *tags, *result;
12867 ! gst_message_parse_tag(msg, &tags);
12869 ! result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_REPLACE);
12870 ! if (result)
12872 ! if (m_stream_tags)
12873 ! gst_tag_list_free(m_stream_tags);
12874 ! m_stream_tags = result;
12877 ! const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0);
12878 ! if ( gv_image )
12880 ! GstBuffer *buf_image;
12881 ! buf_image = gst_value_get_buffer (gv_image);
12882 ! int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644);
12883 ! int ret = write(fd, GST_BUFFER_DATA(buf_image), GST_BUFFER_SIZE(buf_image));
12884 ! close(fd);
12885 ! eDebug("eServiceMP3::/tmp/.id3coverart %d bytes written ", ret);
12886 ! m_event((iPlayableService*)this, evUser+13);
12888 ! gst_tag_list_free(tags);
12889 ! m_event((iPlayableService*)this, evUpdatedInfo);
12890 ! break;
12892 ! case GST_MESSAGE_ASYNC_DONE:
12894 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
12895 ! break;
12897 ! GstTagList *tags;
12898 ! gint i, active_idx, n_video = 0, n_audio = 0, n_text = 0;
12900 ! g_object_get (m_gst_playbin, "n-video", &n_video, NULL);
12901 ! g_object_get (m_gst_playbin, "n-audio", &n_audio, NULL);
12902 ! g_object_get (m_gst_playbin, "n-text", &n_text, NULL);
12904 ! eDebug("eServiceMP3::async-done - %d video, %d audio, %d subtitle", n_video, n_audio, n_text);
12906 ! if ( n_video + n_audio <= 0 )
12907 ! stop();
12909 ! active_idx = 0;
12911 ! m_audioStreams.clear();
12912 ! m_subtitleStreams.clear();
12914 ! for (i = 0; i < n_audio; i++)
12916 ! audioStream audio;
12917 ! gchar *g_codec, *g_lang;
12918 ! GstPad* pad = 0;
12919 ! g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad);
12920 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
12921 ! if (!caps)
12922 ! continue;
12923 ! GstStructure* str = gst_caps_get_structure(caps, 0);
12924 ! const gchar *g_type = gst_structure_get_name(str);
12925 ! audio.type = gstCheckAudioPad(str);
12926 ! g_codec = g_strdup(g_type);
12927 ! g_lang = g_strdup_printf ("und");
12928 ! g_signal_emit_by_name (m_gst_playbin, "get-audio-tags", i, &tags);
12929 ! if ( tags && gst_is_tag_list(tags) )
12931 ! gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec);
12932 ! gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
12933 ! gst_tag_list_free(tags);
12935 ! audio.language_code = std::string(g_lang);
12936 ! audio.codec = std::string(g_codec);
12937 ! eDebug("eServiceMP3::audio stream=%i codec=%s language=%s", i, g_codec, g_lang);
12938 ! m_audioStreams.push_back(audio);
12939 ! g_free (g_lang);
12940 ! g_free (g_codec);
12941 ! gst_caps_unref(caps);
12944 ! for (i = 0; i < n_text; i++)
12946 ! gchar *g_codec = NULL, *g_lang = NULL;
12947 ! g_signal_emit_by_name (m_gst_playbin, "get-text-tags", i, &tags);
12948 ! subtitleStream subs;
12949 ! // int ret;
12951 ! g_lang = g_strdup_printf ("und");
12952 ! if ( tags && gst_is_tag_list(tags) )
12954 ! gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
12955 ! gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec);
12956 ! gst_tag_list_free(tags);
12959 ! subs.language_code = std::string(g_lang);
12960 ! eDebug("eServiceMP3::subtitle stream=%i language=%s codec=%s", i, g_lang, g_codec);
12962 ! GstPad* pad = 0;
12963 ! g_signal_emit_by_name (m_gst_playbin, "get-text-pad", i, &pad);
12964 ! if ( pad )
12965 ! g_signal_connect (G_OBJECT (pad), "notify::caps", G_CALLBACK (gstTextpadHasCAPS), this);
12966 ! subs.type = getSubtitleType(pad, g_codec);
12968 ! m_subtitleStreams.push_back(subs);
12969 ! g_free (g_lang);
12971 ! m_event((iPlayableService*)this, evUpdatedEventInfo);
12973 ! if ( m_errorInfo.missing_codec != "" )
12975 ! if ( m_errorInfo.missing_codec.find("video/") == 0 || ( m_errorInfo.missing_codec.find("audio/") == 0 && getNumberOfTracks() == 0 ) )
12976 ! m_event((iPlayableService*)this, evUser+12);
12978 ! break;
12980 ! case GST_MESSAGE_ELEMENT:
12982 ! if (const GstStructure *msgstruct = gst_message_get_structure(msg))
12984 ! if ( gst_is_missing_plugin_message(msg) )
12986 ! GstCaps *caps;
12987 ! gst_structure_get ((GstStructure*)msgstruct, "detail", GST_TYPE_CAPS, &caps, NULL);
12988 ! std::string codec = (const char*) gst_caps_to_string(caps);
12989 ! gchar *description = gst_missing_plugin_message_get_description(msg);
12990 ! if ( description )
12992 ! eDebug("eServiceMP3::m_errorInfo.missing_codec = %s", codec.c_str());
12993 ! m_errorInfo.error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
12994 ! m_errorInfo.missing_codec = codec.substr(0,(codec.find_first_of(',')));
12995 ! g_free(description);
12997 ! gst_caps_unref(caps);
12999 ! else
13001 ! const gchar *eventname = gst_structure_get_name(msgstruct);
13002 ! if ( eventname )
13004 ! if (!strcmp(eventname, "eventSizeChanged") || !strcmp(eventname, "eventSizeAvail"))
13006 ! gst_structure_get_int (msgstruct, "aspect_ratio", &m_aspect);
13007 ! gst_structure_get_int (msgstruct, "width", &m_width);
13008 ! gst_structure_get_int (msgstruct, "height", &m_height);
13009 ! if (strstr(eventname, "Changed"))
13010 ! m_event((iPlayableService*)this, evVideoSizeChanged);
13012 ! else if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
13014 ! gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
13015 ! if (strstr(eventname, "Changed"))
13016 ! m_event((iPlayableService*)this, evVideoFramerateChanged);
13018 ! else if (!strcmp(eventname, "eventProgressiveChanged") || !strcmp(eventname, "eventProgressiveAvail"))
13020 ! gst_structure_get_int (msgstruct, "progressive", &m_progressive);
13021 ! if (strstr(eventname, "Changed"))
13022 ! m_event((iPlayableService*)this, evVideoProgressiveChanged);
13027 ! break;
13029 ! case GST_MESSAGE_BUFFERING:
13031 ! GstBufferingMode mode;
13032 ! gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
13033 ! gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
13034 ! m_event((iPlayableService*)this, evBuffering);
13035 ! break;
13037 ! case GST_MESSAGE_STREAM_STATUS:
13039 ! GstStreamStatusType type;
13040 ! GstElement *owner;
13041 ! gst_message_parse_stream_status (msg, &type, &owner);
13042 ! if ( type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming )
13044 ! if ( GST_IS_PAD(source) )
13045 ! owner = gst_pad_get_parent_element(GST_PAD(source));
13046 ! else if ( GST_IS_ELEMENT(source) )
13047 ! owner = GST_ELEMENT(source);
13048 ! else
13049 ! owner = 0;
13050 ! if ( owner )
13052 ! GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
13053 ! const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
13054 ! if (!strcmp(name, "souphttpsrc"))
13056 ! m_streamingsrc_timeout->start(HTTP_TIMEOUT*1000, true);
13057 ! g_object_set (G_OBJECT (owner), "timeout", HTTP_TIMEOUT, NULL);
13058 ! eDebug("eServiceMP3::GST_STREAM_STATUS_TYPE_CREATE -> setting timeout on %s to %is", name, HTTP_TIMEOUT);
13062 ! if ( GST_IS_PAD(source) )
13063 ! gst_object_unref(owner);
13065 ! break;
13067 ! default:
13068 ! break;
13070 ! g_free (sourceName);
13073 ! GstBusSyncReply eServiceMP3::gstBusSyncHandler(GstBus *bus, GstMessage *message, gpointer user_data)
13075 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
13076 ! _this->m_pump.send(Message(1));
13077 ! /* wake */
13078 ! return GST_BUS_PASS;
13081 ! void eServiceMP3::gstHTTPSourceSetAgent(GObject *object, GParamSpec *unused, gpointer user_data)
13083 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
13084 ! GstElement *source;
13085 ! g_object_get(_this->m_gst_playbin, "source", &source, NULL);
13086 ! g_object_set (G_OBJECT (source), "user-agent", _this->m_useragent.c_str(), NULL);
13087 ! gst_object_unref(source);
13090 ! audiotype_t eServiceMP3::gstCheckAudioPad(GstStructure* structure)
13092 ! if (!structure)
13093 ! return atUnknown;
13095 ! if ( gst_structure_has_name (structure, "audio/mpeg"))
13097 ! gint mpegversion, layer = -1;
13098 ! if (!gst_structure_get_int (structure, "mpegversion", &mpegversion))
13099 ! return atUnknown;
13101 ! switch (mpegversion) {
13102 ! case 1:
13104 ! gst_structure_get_int (structure, "layer", &layer);
13105 ! if ( layer == 3 )
13106 ! return atMP3;
13107 ! else
13108 ! return atMPEG;
13109 ! break;
13111 ! case 2:
13112 ! return atAAC;
13113 ! case 4:
13114 ! return atAAC;
13115 ! default:
13116 ! return atUnknown;
13120 ! else if ( gst_structure_has_name (structure, "audio/x-ac3") || gst_structure_has_name (structure, "audio/ac3") )
13121 ! return atAC3;
13122 ! else if ( gst_structure_has_name (structure, "audio/x-dts") || gst_structure_has_name (structure, "audio/dts") )
13123 ! return atDTS;
13124 ! else if ( gst_structure_has_name (structure, "audio/x-raw-int") )
13125 ! return atPCM;
13127 ! return atUnknown;
13130 ! void eServiceMP3::gstPoll(const Message &msg)
13132 ! if (msg.type == 1)
13134 ! GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_gst_playbin));
13135 ! GstMessage *message;
13136 ! while ((message = gst_bus_pop(bus)))
13138 ! gstBusCall(bus, message);
13139 ! gst_message_unref (message);
13142 ! else if (msg.type == 2)
13143 ! pullSubtitle();
13144 ! else if (msg.type == 3)
13145 ! gstTextpadHasCAPS_synced(msg.d.pad);
13146 ! else
13147 ! eDebug("gstPoll unhandled Message %d\n", msg.type);
13150 ! eAutoInitPtr<eServiceFactoryMP3> init_eServiceFactoryMP3(eAutoInitNumbers::service+1, "eServiceFactoryMP3");
13152 ! void eServiceMP3::gstCBsubtitleAvail(GstElement *appsink, gpointer user_data)
13154 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
13155 ! eSingleLocker l(_this->m_subs_to_pull_lock);
13156 ! ++_this->m_subs_to_pull;
13157 ! _this->m_pump.send(Message(2));
13160 ! void eServiceMP3::gstTextpadHasCAPS(GstPad *pad, GParamSpec * unused, gpointer user_data)
13162 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
13164 ! gst_object_ref (pad);
13166 ! _this->m_pump.send(Message(3, pad));
13169 ! // after messagepump
13170 ! void eServiceMP3::gstTextpadHasCAPS_synced(GstPad *pad)
13172 ! GstCaps *caps;
13174 ! g_object_get (G_OBJECT (pad), "caps", &caps, NULL);
13176 ! eDebug("gstTextpadHasCAPS:: signal::caps = %s", gst_caps_to_string(caps));
13178 ! if (caps)
13180 ! subtitleStream subs;
13182 ! // eDebug("gstGhostpadHasCAPS_synced %p %d", pad, m_subtitleStreams.size());
13184 ! if (!m_subtitleStreams.empty())
13185 ! subs = m_subtitleStreams[m_currentSubtitleStream];
13186 ! else {
13187 ! subs.type = stUnknown;
13188 ! subs.pad = pad;
13191 ! if ( subs.type == stUnknown )
13193 ! GstTagList *tags;
13194 ! // eDebug("gstGhostpadHasCAPS::m_subtitleStreams[%i].type == stUnknown...", m_currentSubtitleStream);
13196 ! gchar *g_lang;
13197 ! g_signal_emit_by_name (m_gst_playbin, "get-text-tags", m_currentSubtitleStream, &tags);
13199 ! g_lang = g_strdup_printf ("und");
13200 ! if ( tags && gst_is_tag_list(tags) )
13201 ! gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
13203 ! subs.language_code = std::string(g_lang);
13204 ! subs.type = getSubtitleType(pad);
13206 ! if (!m_subtitleStreams.empty())
13207 ! m_subtitleStreams[m_currentSubtitleStream] = subs;
13208 ! else
13209 ! m_subtitleStreams.push_back(subs);
13211 ! g_free (g_lang);
13214 ! // eDebug("gstGhostpadHasCAPS:: m_gst_prev_subtitle_caps=%s equal=%i",gst_caps_to_string(m_gst_prev_subtitle_caps),gst_caps_is_equal(m_gst_prev_subtitle_caps, caps));
13216 ! gst_caps_unref (caps);
13219 ! gst_object_unref (pad);
13222 ! void eServiceMP3::pullSubtitle()
13224 ! GstElement *sink;
13225 ! g_object_get (G_OBJECT (m_gst_playbin), "text-sink", &sink, NULL);
13227 ! if (sink)
13229 ! while (m_subs_to_pull && m_subtitle_pages.size() < 2)
13231 ! GstBuffer *buffer;
13233 ! eSingleLocker l(m_subs_to_pull_lock);
13234 ! --m_subs_to_pull;
13235 ! g_signal_emit_by_name (sink, "pull-buffer", &buffer);
13237 ! if (buffer)
13239 ! gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
13240 ! gint64 duration_ns = GST_BUFFER_DURATION(buffer);
13241 ! size_t len = GST_BUFFER_SIZE(buffer);
13242 ! eDebug("pullSubtitle m_subtitleStreams[m_currentSubtitleStream].type=%i",m_subtitleStreams[m_currentSubtitleStream].type);
13244 ! if ( m_subtitleStreams[m_currentSubtitleStream].type )
13246 ! if ( m_subtitleStreams[m_currentSubtitleStream].type < stVOB )
13248 ! unsigned char line[len+1];
13249 ! SubtitlePage page;
13250 ! memcpy(line, GST_BUFFER_DATA(buffer), len);
13251 ! line[len] = 0;
13252 ! eDebug("got new text subtitle @ buf_pos = %lld ns (in pts=%lld): '%s' ", buf_pos, buf_pos/11111, line);
13253 ! gRGB rgbcol(0xD0,0xD0,0xD0);
13254 ! page.type = SubtitlePage::Pango;
13255 ! page.pango_page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)line));
13256 ! page.pango_page.m_show_pts = buf_pos / 11111L;
13257 ! page.pango_page.m_timeout = duration_ns / 1000000;
13258 ! m_subtitle_pages.push_back(page);
13259 ! if (m_subtitle_pages.size()==1)
13260 ! pushSubtitles();
13262 ! else
13264 ! eDebug("unsupported subpicture... ignoring");
13267 ! gst_buffer_unref(buffer);
13270 ! gst_object_unref(sink);
13272 ! else
13273 ! eDebug("no subtitle sink!");
13276 ! void eServiceMP3::pushSubtitles()
13278 ! while ( !m_subtitle_pages.empty() )
13280 ! SubtitlePage &frontpage = m_subtitle_pages.front();
13281 ! pts_t running_pts;
13282 ! gint64 diff_ms = 0;
13283 ! gint64 show_pts = 0;
13285 ! getPlayPosition(running_pts);
13287 ! if (m_decoder_time_valid_state < 4) {
13288 ! ++m_decoder_time_valid_state;
13289 ! if (m_prev_decoder_time == running_pts)
13290 ! m_decoder_time_valid_state = 0;
13291 ! if (m_decoder_time_valid_state < 4) {
13292 ! // if (m_decoder_time_valid_state)
13293 ! // eDebug("%d: decoder time not valid! prev %lld, now %lld\n", m_decoder_time_valid_state, m_prev_decoder_time/90, running_pts/90);
13294 ! // else
13295 ! // eDebug("%d: decoder time not valid! now %lld\n", m_decoder_time_valid_state, running_pts/90);
13296 ! m_subtitle_sync_timer->start(25, true);
13297 ! m_prev_decoder_time = running_pts;
13298 ! break;
13302 ! if (frontpage.type == SubtitlePage::Pango)
13303 ! show_pts = frontpage.pango_page.m_show_pts;
13305 ! diff_ms = ( show_pts - running_pts ) / 90;
13306 ! eDebug("check subtitle: decoder: %lld, show_pts: %lld, diff: %lld ms", running_pts/90, show_pts/90, diff_ms);
13308 ! if ( diff_ms < -100 )
13310 ! eDebug("subtitle too late... drop");
13311 ! m_subtitle_pages.pop_front();
13313 ! else if ( diff_ms > 20 )
13315 ! eDebug("start timer");
13316 ! m_subtitle_sync_timer->start(diff_ms, true);
13317 ! break;
13319 ! else // immediate show
13321 ! if ( m_subtitle_widget )
13323 ! eDebug("show!\n");
13324 ! if ( frontpage.type == SubtitlePage::Pango)
13325 ! m_subtitle_widget->setPage(frontpage.pango_page);
13326 ! m_subtitle_widget->show();
13328 ! m_subtitle_pages.pop_front();
13331 ! if (m_subtitle_pages.empty())
13332 ! pullSubtitle();
13336 ! RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
13338 ! eDebug ("eServiceMP3::enableSubtitles m_currentSubtitleStream=%i this=%p",m_currentSubtitleStream, this);
13339 ! ePyObject entry;
13340 ! int tuplesize = PyTuple_Size(tuple);
13341 ! int pid, type;
13342 ! gint text_pid = 0;
13343 ! eSingleLocker l(m_subs_to_pull_lock);
13345 ! // GstPad *pad = 0;
13346 ! // g_signal_emit_by_name (m_gst_playbin, "get-text-pad", m_currentSubtitleStream, &pad);
13347 ! // gst_element_get_static_pad(m_gst_subtitlebin, "sink");
13348 ! // gulong subprobe_handler_id = gst_pad_add_buffer_probe (pad, G_CALLBACK (gstCBsubtitleDrop), NULL);
13350 ! if (!PyTuple_Check(tuple))
13351 ! goto error_out;
13352 ! if (tuplesize < 1)
13353 ! goto error_out;
13354 ! entry = PyTuple_GET_ITEM(tuple, 1);
13355 ! if (!PyInt_Check(entry))
13356 ! goto error_out;
13357 ! pid = PyInt_AsLong(entry);
13358 ! entry = PyTuple_GET_ITEM(tuple, 2);
13359 ! if (!PyInt_Check(entry))
13360 ! goto error_out;
13361 ! type = PyInt_AsLong(entry);
13363 ! if (m_currentSubtitleStream != pid)
13365 ! g_object_set (G_OBJECT (m_gst_playbin), "current-text", pid, NULL);
13366 ! eDebug ("eServiceMP3::enableSubtitles g_object_set current-text = %i", pid);
13367 ! m_currentSubtitleStream = pid;
13368 ! m_subs_to_pull = 0;
13369 ! m_prev_decoder_time = -1;
13370 ! m_subtitle_pages.clear();
13373 ! m_subtitle_widget = 0;
13374 ! m_subtitle_widget = new eSubtitleWidget(parent);
13375 ! m_subtitle_widget->resize(parent->size()); /* full size */
13377 ! g_object_get (G_OBJECT (m_gst_playbin), "current-text", &text_pid, NULL);
13379 ! eDebug ("eServiceMP3::switched to subtitle stream %i", text_pid);
13380 ! // gst_pad_remove_buffer_probe (pad, subprobe_handler_id);
13382 ! m_event((iPlayableService*)this, evUpdatedInfo);
13384 ! return 0;
13386 ! error_out:
13387 ! eDebug("eServiceMP3::enableSubtitles needs a tuple as 2nd argument!\n"
13388 ! "for gst subtitles (2, subtitle_stream_count, subtitle_type)");
13389 ! return -1;
13392 ! RESULT eServiceMP3::disableSubtitles(eWidget *parent)
13394 ! eDebug("eServiceMP3::disableSubtitles");
13395 ! m_subtitle_pages.clear();
13396 ! delete m_subtitle_widget;
13397 ! m_subtitle_widget = 0;
13398 ! return 0;
13401 ! PyObject *eServiceMP3::getCachedSubtitle()
13403 ! // eDebug("eServiceMP3::getCachedSubtitle");
13404 ! Py_RETURN_NONE;
13407 ! PyObject *eServiceMP3::getSubtitleList()
13409 ! // eDebug("eServiceMP3::getSubtitleList");
13410 ! ePyObject l = PyList_New(0);
13411 ! int stream_idx = 0;
13413 ! for (std::vector<subtitleStream>::iterator IterSubtitleStream(m_subtitleStreams.begin()); IterSubtitleStream != m_subtitleStreams.end(); ++IterSubtitleStream)
13415 ! subtype_t type = IterSubtitleStream->type;
13416 ! switch(type)
13418 ! case stUnknown:
13419 ! case stVOB:
13420 ! case stPGS:
13421 ! break;
13422 ! default:
13424 ! ePyObject tuple = PyTuple_New(5);
13425 ! // eDebug("eServiceMP3::getSubtitleList idx=%i type=%i, code=%s", stream_idx, int(type), (IterSubtitleStream->language_code).c_str());
13426 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
13427 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(stream_idx));
13428 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(int(type)));
13429 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(0));
13430 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString((IterSubtitleStream->language_code).c_str()));
13431 ! PyList_Append(l, tuple);
13432 ! Py_DECREF(tuple);
13435 ! stream_idx++;
13437 ! eDebug("eServiceMP3::getSubtitleList finished");
13438 ! return l;
13441 ! RESULT eServiceMP3::streamed(ePtr<iStreamedService> &ptr)
13443 ! ptr = this;
13444 ! return 0;
13447 ! PyObject *eServiceMP3::getBufferCharge()
13449 ! ePyObject tuple = PyTuple_New(5);
13450 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(m_bufferInfo.bufferPercent));
13451 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(m_bufferInfo.avgInRate));
13452 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(m_bufferInfo.avgOutRate));
13453 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(m_bufferInfo.bufferingLeft));
13454 ! PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(m_buffer_size));
13455 ! return tuple;
13458 ! int eServiceMP3::setBufferSize(int size)
13460 ! m_buffer_size = size;
13461 ! g_object_set (G_OBJECT (m_gst_playbin), "buffer-size", m_buffer_size, NULL);
13462 ! return 0;
13465 ! int eServiceMP3::getAC3Delay()
13467 ! return ac3_delay;
13470 ! int eServiceMP3::getPCMDelay()
13472 ! return pcm_delay;
13475 ! void eServiceMP3::setAC3Delay(int delay)
13477 ! ac3_delay = delay;
13478 ! if (!m_gst_playbin || m_state != stRunning)
13479 ! return;
13480 ! else
13482 ! GstElement *sink;
13483 ! int config_delay_int = delay;
13484 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
13486 ! if (sink)
13488 ! std::string config_delay;
13489 ! if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
13490 ! config_delay_int += atoi(config_delay.c_str());
13491 ! gst_object_unref(sink);
13493 ! else
13495 ! eDebug("dont apply ac3 delay when no video is running!");
13496 ! config_delay_int = 0;
13499 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
13501 ! if (sink)
13503 ! gchar *name = gst_element_get_name(sink);
13504 ! if (strstr(name, "dvbaudiosink"))
13505 ! eTSMPEGDecoder::setHwAC3Delay(config_delay_int);
13506 ! g_free(name);
13507 ! gst_object_unref(sink);
13512 ! void eServiceMP3::setPCMDelay(int delay)
13514 ! pcm_delay = delay;
13515 ! if (!m_gst_playbin || m_state != stRunning)
13516 ! return;
13517 ! else
13519 ! GstElement *sink;
13520 ! int config_delay_int = delay;
13521 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
13523 ! if (sink)
13525 ! std::string config_delay;
13526 ! if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
13527 ! config_delay_int += atoi(config_delay.c_str());
13528 ! gst_object_unref(sink);
13530 ! else
13532 ! eDebug("dont apply pcm delay when no video is running!");
13533 ! config_delay_int = 0;
13536 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
13538 ! if (sink)
13540 ! gchar *name = gst_element_get_name(sink);
13541 ! if (strstr(name, "dvbaudiosink"))
13542 ! eTSMPEGDecoder::setHwPCMDelay(config_delay_int);
13543 ! else
13545 ! // this is realy untested..and not used yet
13546 ! gint64 offset = config_delay_int;
13547 ! offset *= 1000000; // milli to nano
13548 ! g_object_set (G_OBJECT (m_gst_playbin), "ts-offset", offset, NULL);
13550 ! g_free(name);
13551 ! gst_object_unref(sink);
13556 --- 1,1520 ----
13557 ! /* note: this requires gstreamer 0.10.x and a big list of plugins. */
13558 ! /* it's currently hardcoded to use a big-endian alsasink as sink. */
13559 ! #include <lib/base/ebase.h>
13560 ! #include <lib/base/eerror.h>
13561 ! #include <lib/base/init_num.h>
13562 ! #include <lib/base/init.h>
13563 ! #include <lib/base/nconfig.h>
13564 ! #include <lib/base/object.h>
13565 ! #include <lib/dvb/decoder.h>
13566 ! #include <lib/components/file_eraser.h>
13567 ! #include <lib/gui/esubtitle.h>
13568 ! #include <lib/service/servicemp3.h>
13569 ! #include <lib/service/service.h>
13570 ! #include <lib/gdi/gpixmap.h>
13572 ! #include <string>
13574 ! //#include <gst/gst.h>
13575 ! //#include <gst/pbutils/missing-plugins.h>
13576 ! //#include <sys/stat.h>
13578 ! #define HTTP_TIMEOUT 10
13580 ! // eServiceFactoryMP3
13582 ! eServiceFactoryMP3::eServiceFactoryMP3()
13584 ! ePtr<eServiceCenter> sc;
13586 ! eServiceCenter::getPrivInstance(sc);
13587 ! if (sc)
13589 ! std::list<std::string> extensions;
13590 ! extensions.push_back("mp2");
13591 ! extensions.push_back("mp3");
13592 ! extensions.push_back("ogg");
13593 ! extensions.push_back("mpg");
13594 ! extensions.push_back("vob");
13595 ! extensions.push_back("wav");
13596 ! extensions.push_back("wave");
13597 ! extensions.push_back("m4v");
13598 ! extensions.push_back("mkv");
13599 ! extensions.push_back("avi");
13600 ! extensions.push_back("divx");
13601 ! extensions.push_back("dat");
13602 ! extensions.push_back("flac");
13603 ! extensions.push_back("mp4");
13604 ! extensions.push_back("mov");
13605 ! extensions.push_back("m4a");
13606 ! sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
13609 ! m_service_info = new eStaticServiceMP3Info();
13612 ! eServiceFactoryMP3::~eServiceFactoryMP3()
13614 ! ePtr<eServiceCenter> sc;
13616 ! eServiceCenter::getPrivInstance(sc);
13617 ! if (sc)
13618 ! sc->removeServiceFactory(eServiceFactoryMP3::id);
13621 ! DEFINE_REF(eServiceFactoryMP3)
13623 ! // iServiceHandler
13624 ! RESULT eServiceFactoryMP3::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
13626 ! // check resources...
13627 ! ptr = new eServiceMP3(ref);
13628 ! return 0;
13631 ! RESULT eServiceFactoryMP3::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
13633 ! ptr=0;
13634 ! return -1;
13637 ! RESULT eServiceFactoryMP3::list(const eServiceReference &, ePtr<iListableService> &ptr)
13639 ! ptr=0;
13640 ! return -1;
13643 ! RESULT eServiceFactoryMP3::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
13645 ! ptr = m_service_info;
13646 ! return 0;
13649 ! class eMP3ServiceOfflineOperations: public iServiceOfflineOperations
13651 ! DECLARE_REF(eMP3ServiceOfflineOperations);
13652 ! eServiceReference m_ref;
13653 ! public:
13654 ! eMP3ServiceOfflineOperations(const eServiceReference &ref);
13656 ! RESULT deleteFromDisk(int simulate);
13657 ! RESULT getListOfFilenames(std::list<std::string> &);
13658 ! RESULT reindex();
13659 ! };
13661 ! DEFINE_REF(eMP3ServiceOfflineOperations);
13663 ! eMP3ServiceOfflineOperations::eMP3ServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReference&)ref)
13667 ! RESULT eMP3ServiceOfflineOperations::deleteFromDisk(int simulate)
13669 ! if (simulate)
13670 ! return 0;
13671 ! else
13673 ! std::list<std::string> res;
13674 ! if (getListOfFilenames(res))
13675 ! return -1;
13677 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
13678 ! if (!eraser)
13679 ! eDebug("FATAL !! can't get background file eraser");
13681 ! for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
13683 ! eDebug("Removing %s...", i->c_str());
13684 ! if (eraser)
13685 ! eraser->erase(i->c_str());
13686 ! else
13687 ! ::unlink(i->c_str());
13690 ! return 0;
13694 ! RESULT eMP3ServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
13696 ! res.clear();
13697 ! res.push_back(m_ref.path);
13698 ! return 0;
13701 ! RESULT eMP3ServiceOfflineOperations::reindex()
13703 ! return -1;
13707 ! RESULT eServiceFactoryMP3::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
13709 ! ptr = new eMP3ServiceOfflineOperations(ref);
13710 ! return 0;
13713 ! // eStaticServiceMP3Info
13716 ! // eStaticServiceMP3Info is seperated from eServiceMP3 to give information
13717 ! // about unopened files.
13719 ! // probably eServiceMP3 should use this class as well, and eStaticServiceMP3Info
13720 ! // should have a database backend where ID3-files etc. are cached.
13721 ! // this would allow listing the mp3 database based on certain filters.
13723 ! DEFINE_REF(eStaticServiceMP3Info)
13725 ! eStaticServiceMP3Info::eStaticServiceMP3Info()
13729 ! RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string &name)
13731 ! if ( ref.name.length() )
13732 ! name = ref.name;
13733 ! else
13735 ! size_t last = ref.path.rfind('/');
13736 ! if (last != std::string::npos)
13737 ! name = ref.path.substr(last+1);
13738 ! else
13739 ! name = ref.path;
13741 ! return 0;
13744 ! int eStaticServiceMP3Info::getLength(const eServiceReference &ref)
13746 ! return -1;
13749 ! int eStaticServiceMP3Info::getInfo(const eServiceReference &ref, int w)
13751 ! switch (w)
13753 ! case iServiceInformation::sTimeCreate:
13755 ! struct stat s;
13756 ! if(stat(ref.path.c_str(), &s) == 0)
13758 ! return s.st_mtime;
13760 ! return iServiceInformation::resNA;
13762 ! default: break;
13764 ! return iServiceInformation::resNA;
13768 ! // eServiceMP3
13769 ! int eServiceMP3::ac3_delay,
13770 ! eServiceMP3::pcm_delay;
13772 ! eServiceMP3::eServiceMP3(eServiceReference ref)
13773 ! :m_ref(ref), m_pump(eApp, 1)
13775 ! printf("Sira=1\n");
13776 ! cXineLib *xineLib = cXineLib::getInstance();
13777 ! //xineLib->stopVideo();
13778 ! m_state = stIdle;
13779 ! eDebug("eServiceMP3::construct!");
13781 ! const char *filename = m_ref.path.c_str();
13782 ! //const char *ext = strrchr(filename, '.');
13783 ! char myfile[255];
13784 ! sprintf(myfile,"%s",filename);
13786 ! ASSERT(m_state == stIdle);
13787 ! xineLib->FilmVideo(myfile);
13789 ! m_state = stRunning;
13791 ! m_event(this, evStart);
13792 ! return ;
13795 ! eServiceMP3::~eServiceMP3()
13796 ! {printf("Sira=2\n");
13797 ! if (m_state == stRunning)
13798 ! stop();
13801 ! DEFINE_REF(eServiceMP3);
13803 ! RESULT eServiceMP3::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
13805 ! connection = new eConnection((iPlayableService*)this, m_event.connect(event));
13806 ! return 0;
13809 ! RESULT eServiceMP3::start()
13811 ! printf("Sira=3\n");
13813 ! //ASSERT(m_state == stIdle);
13815 ! m_state = stRunning;
13816 ! m_event(this, evStart);
13818 ! return 0;
13821 ! void eServiceMP3::sourceTimeout()
13823 ! eDebug("eServiceMP3::http source timeout! issuing eof...");
13824 ! m_event((iPlayableService*)this, evEOF);
13827 ! RESULT eServiceMP3::stop()
13828 ! {printf("Sira=4\n");
13829 ! ASSERT(m_state != stIdle);
13831 ! if (m_state == stStopped)
13832 ! return -1;
13834 ! m_state = stStopped;
13835 ! cXineLib *xineLib = cXineLib::getInstance();
13836 ! xineLib->stopVideo();
13837 ! return 0;
13840 ! RESULT eServiceMP3::setTarget(int target)
13842 ! return -1;
13845 ! RESULT eServiceMP3::pause(ePtr<iPauseableService> &ptr)
13846 ! {printf("Sira=104\n");
13847 ! ptr=this;
13848 ! return 0;
13851 ! RESULT eServiceMP3::setSlowMotion(int ratio)
13852 ! {printf("Sira=102\n");
13853 ! if (!ratio)
13854 ! return 0;
13855 ! eDebug("eServiceMP3::setSlowMotion ratio=%f",1/(float)ratio);
13856 ! return trickSeek(1/(float)ratio);
13859 ! RESULT eServiceMP3::setFastForward(int ratio)
13860 ! {printf("Sira=101\n");
13861 ! eDebug("eServiceMP3::setFastForward ratio=%i",ratio);
13862 ! return trickSeek(ratio);
13865 ! void eServiceMP3::seekTimeoutCB()
13866 ! {printf("Sira=100\n");
13867 ! pts_t ppos, len;
13868 ! getPlayPosition(ppos);
13869 ! getLength(len);
13870 ! ppos += 90000*m_currentTrickRatio;
13872 ! if (ppos < 0)
13874 ! ppos = 0;
13875 ! m_seekTimeout->stop();
13877 ! if (ppos > len)
13879 ! ppos = 0;
13880 ! stop();
13881 ! m_seekTimeout->stop();
13882 ! return;
13884 ! seekTo(ppos);
13887 ! // iPausableService
13888 ! RESULT eServiceMP3::pause()
13890 ! if (m_state != stRunning)
13891 ! return -1;
13893 ! cXineLib *xineLib = cXineLib::getInstance();
13894 ! xineLib->VideoPause();
13896 ! return 0;
13899 ! RESULT eServiceMP3::unpause()
13900 ! {printf("Sira=91\n");
13902 ! if (m_state != stRunning)
13903 ! return -1;
13905 ! cXineLib *xineLib = cXineLib::getInstance();
13906 ! xineLib->VideoResume();
13908 ! return 0;
13911 ! /* iSeekableService */
13912 ! RESULT eServiceMP3::seek(ePtr<iSeekableService> &ptr)
13914 ! ptr = this;
13915 ! return 0;
13918 ! RESULT eServiceMP3::getLength(pts_t &pts)
13920 ! if (m_state != stRunning)
13921 ! return -1;
13923 ! cXineLib *xineLib = cXineLib::getInstance();
13924 ! xineLib->VideoPosisyon();
13925 ! pts=xineLib->Vlength*90;
13926 ! return 0;
13929 ! RESULT eServiceMP3::seekToImpl(pts_t to)
13930 ! {printf("Sira=8\n");
13931 ! return 0;
13934 ! RESULT eServiceMP3::seekTo(pts_t to)
13936 ! printf("Sira=9\n");
13937 ! RESULT ret = 0;
13939 ! return ret;
13943 ! RESULT eServiceMP3::trickSeek(int ratio)
13945 ! printf("Sira=11----Ratio=%d\n",ratio);
13947 ! cXineLib *xineLib = cXineLib::getInstance();
13948 ! xineLib->VideoIleriF();
13950 ! //if (!ratio) return seekRelative(0, 0);
13953 ! return 0;
13957 ! RESULT eServiceMP3::seekRelative(int direction, pts_t to)
13959 ! eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
13961 ! cXineLib *xineLib = cXineLib::getInstance();
13962 ! xineLib->VideoGeriT(to/90*direction);
13964 ! return 0;
13967 ! RESULT eServiceMP3::getPlayPosition(pts_t &pts)
13970 ! if (m_state != stRunning)
13971 ! return -1;
13973 ! cXineLib *xineLib = cXineLib::getInstance();
13974 ! xineLib->VideoPosisyon();
13975 ! pts=xineLib->Vpos*90;
13976 ! return 0;
13979 ! RESULT eServiceMP3::setTrickmode(int trick)
13980 ! {printf("Sira=11-1\n");
13981 ! /* trickmode is not yet supported by our dvbmediasinks. */
13982 ! return -1;
13985 ! RESULT eServiceMP3::isCurrentlySeekable()
13987 ! printf("Sira=13\n");
13988 ! if (m_state != stRunning)
13989 ! return 0;
13991 ! int ret = 3; // seeking and fast/slow winding possible
13992 ! return ret;
13995 ! RESULT eServiceMP3::info(ePtr<iServiceInformation>&i)
13997 ! i = this;
13998 ! return 0;
14001 ! RESULT eServiceMP3::getName(std::string &name)
14003 ! std::string title = m_ref.getName();
14004 ! if (title.empty())
14006 ! name = m_ref.path;
14007 ! size_t n = name.rfind('/');
14008 ! if (n != std::string::npos)
14009 ! name = name.substr(n + 1);
14011 ! else
14012 ! name = title;
14013 ! return 0;
14016 ! int eServiceMP3::getInfo(int w)
14018 ! printf("Sira=15\n");
14020 ! const gchar *tag = 0;
14022 ! switch (w)
14024 ! case sServiceref: return m_ref;
14025 ! case sVideoHeight: return m_height;
14026 ! case sVideoWidth: return m_width;
14027 ! case sFrameRate: return m_framerate;
14028 ! case sProgressive: return m_progressive;
14029 ! case sAspect: return m_aspect;
14030 ! case sTagTitle:
14031 ! case sTagArtist:
14032 ! case sTagAlbum:
14033 ! case sTagTitleSortname:
14034 ! case sTagArtistSortname:
14035 ! case sTagAlbumSortname:
14036 ! case sTagDate:
14037 ! case sTagComposer:
14038 ! case sTagGenre:
14039 ! case sTagComment:
14040 ! case sTagExtendedComment:
14041 ! case sTagLocation:
14042 ! case sTagHomepage:
14043 ! case sTagDescription:
14044 ! case sTagVersion:
14045 ! case sTagISRC:
14046 ! case sTagOrganization:
14047 ! case sTagCopyright:
14048 ! case sTagCopyrightURI:
14049 ! case sTagContact:
14050 ! case sTagLicense:
14051 ! case sTagLicenseURI:
14052 ! case sTagCodec:
14053 ! case sTagAudioCodec:
14054 ! case sTagVideoCodec:
14055 ! case sTagEncoder:
14056 ! case sTagLanguageCode:
14057 ! case sTagKeywords:
14058 ! case sTagChannelMode:
14059 ! case sUser+12:
14060 ! return resIsString;
14061 ! case sTagTrackGain:
14062 ! case sTagTrackPeak:
14063 ! case sTagAlbumGain:
14064 ! case sTagAlbumPeak:
14065 ! case sTagReferenceLevel:
14066 ! case sTagBeatsPerMinute:
14067 ! case sTagImage:
14068 ! case sTagPreviewImage:
14069 ! case sTagAttachment:
14070 ! return resIsPyObject;
14071 ! case sTagCRC:
14072 ! tag = "has-crc";
14073 ! break;
14074 ! default:
14075 ! return resNA;
14078 ! if (!m_stream_tags || !tag)
14079 ! return 0;
14081 ! return 0;
14084 ! std::string eServiceMP3::getInfoString(int w)
14086 ! printf("Sira=16\n");
14088 ! return "";
14091 ! PyObject *eServiceMP3::getInfoObject(int w)
14093 ! printf("Sira=17\n");
14094 ! return 0;
14097 ! RESULT eServiceMP3::audioChannel(ePtr<iAudioChannelSelection> &ptr)
14099 ! ptr = this;
14100 ! return 0;
14103 ! RESULT eServiceMP3::audioTracks(ePtr<iAudioTrackSelection> &ptr)
14105 ! ptr = this;
14106 ! return 0;
14109 ! RESULT eServiceMP3::subtitle(ePtr<iSubtitleOutput> &ptr)
14111 ! ptr = this;
14112 ! return 0;
14115 ! RESULT eServiceMP3::audioDelay(ePtr<iAudioDelay> &ptr)
14117 ! ptr = this;
14118 ! return 0;
14121 ! int eServiceMP3::getNumberOfTracks()
14123 ! return m_audioStreams.size();
14126 ! int eServiceMP3::getCurrentTrack()
14127 ! {/*
14128 ! if (m_currentAudioStream == -1)
14129 ! g_object_get (G_OBJECT (m_gst_playbin), "current-audio", &m_currentAudioStream, NULL);
14130 ! return m_currentAudioStream;*/
14133 ! RESULT eServiceMP3::selectTrack(unsigned int i)
14135 ! pts_t ppos;
14136 ! getPlayPosition(ppos);
14137 ! ppos -= 90000;
14138 ! if (ppos < 0)
14139 ! ppos = 0;
14141 ! int ret = selectAudioStream(i);
14142 ! if (!ret) {
14143 ! /* flush */
14144 ! seekTo(ppos);
14147 ! return ret;
14150 ! int eServiceMP3::selectAudioStream(int i)
14152 ! printf("Sira=18\n");
14153 ! /*
14154 ! int current_audio;
14155 ! g_object_set (G_OBJECT (m_gst_playbin), "current-audio", i, NULL);
14156 ! g_object_get (G_OBJECT (m_gst_playbin), "current-audio", &current_audio, NULL);
14157 ! if ( current_audio == i )
14159 ! eDebug ("eServiceMP3::switched to audio stream %i", current_audio);
14160 ! m_currentAudioStream = i;
14161 ! return 0;
14163 ! return -1;*/
14166 ! int eServiceMP3::getCurrentChannel()
14168 ! return STEREO;
14171 ! RESULT eServiceMP3::selectChannel(int i)
14173 ! eDebug("eServiceMP3::selectChannel(%i)",i);
14174 ! return 0;
14177 ! RESULT eServiceMP3::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
14178 ! {printf("Sira=19\n");
14179 ! if (i >= m_audioStreams.size())
14180 ! return -2;
14181 ! info.m_description = m_audioStreams[i].codec;
14182 ! /* if (m_audioStreams[i].type == atMPEG)
14183 ! info.m_description = "MPEG";
14184 ! else if (m_audioStreams[i].type == atMP3)
14185 ! info.m_description = "MP3";
14186 ! else if (m_audioStreams[i].type == atAC3)
14187 ! info.m_description = "AC3";
14188 ! else if (m_audioStreams[i].type == atAAC)
14189 ! info.m_description = "AAC";
14190 ! else if (m_audioStreams[i].type == atDTS)
14191 ! info.m_description = "DTS";
14192 ! else if (m_audioStreams[i].type == atPCM)
14193 ! info.m_description = "PCM";
14194 ! else if (m_audioStreams[i].type == atOGG)
14195 ! info.m_description = "OGG";
14196 ! else if (m_audioStreams[i].type == atFLAC)
14197 ! info.m_description = "FLAC";
14198 ! else
14199 ! info.m_description = "???";*/
14200 ! if (info.m_language.empty())
14201 ! info.m_language = m_audioStreams[i].language_code;
14202 ! return 0;
14205 ! subtype_t getSubtitleType(GstPad* pad, gchar *g_codec=NULL)
14207 ! printf("Sira=20\n");
14208 ! /*
14209 ! subtype_t type = stUnknown;
14210 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
14212 ! if ( caps )
14214 ! GstStructure* str = gst_caps_get_structure(caps, 0);
14215 ! const gchar *g_type = gst_structure_get_name(str);
14216 ! eDebug("getSubtitleType::subtitle probe caps type=%s", g_type);
14218 ! if ( !strcmp(g_type, "video/x-dvd-subpicture") )
14219 ! type = stVOB;
14220 ! else if ( !strcmp(g_type, "text/x-pango-markup") )
14221 ! type = stSSA;
14222 ! else if ( !strcmp(g_type, "text/plain") )
14223 ! type = stPlainText;
14224 ! else if ( !strcmp(g_type, "subpicture/x-pgs") )
14225 ! type = stPGS;
14226 ! else
14227 ! eDebug("getSubtitleType::unsupported subtitle caps %s (%s)", g_type, g_codec);
14229 ! else if ( g_codec )
14231 ! eDebug("getSubtitleType::subtitle probe codec tag=%s", g_codec);
14232 ! if ( !strcmp(g_codec, "VOB") )
14233 ! type = stVOB;
14234 ! else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
14235 ! type = stSSA;
14236 ! else if ( !strcmp(g_codec, "ASS") )
14237 ! type = stASS;
14238 ! else if ( !strcmp(g_codec, "UTF-8 plain text") )
14239 ! type = stPlainText;
14240 ! else
14241 ! eDebug("getSubtitleType::unsupported subtitle codec %s", g_codec);
14243 ! else
14244 ! eDebug("getSubtitleType::unidentifiable subtitle stream!");
14246 ! return type;*/
14249 ! void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
14251 ! printf("Sira=21\n");
14252 ! /*
14253 ! if (!msg)
14254 ! return;
14255 ! gchar *sourceName;
14256 ! GstObject *source;
14257 ! source = GST_MESSAGE_SRC(msg);
14258 ! if (!GST_IS_OBJECT(source))
14259 ! return;
14260 ! sourceName = gst_object_get_name(source);
14261 ! #if 0
14262 ! gchar *string;
14263 ! if (gst_message_get_structure(msg))
14264 ! string = gst_structure_to_string(gst_message_get_structure(msg));
14265 ! else
14266 ! string = g_strdup(GST_MESSAGE_TYPE_NAME(msg));
14267 ! eDebug("eTsRemoteSource::gst_message from %s: %s", sourceName, string);
14268 ! g_free(string);
14269 ! #endif
14270 ! switch (GST_MESSAGE_TYPE (msg))
14272 ! case GST_MESSAGE_EOS:
14273 ! m_event((iPlayableService*)this, evEOF);
14274 ! break;
14275 ! case GST_MESSAGE_STATE_CHANGED:
14277 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
14278 ! break;
14280 ! GstState old_state, new_state;
14281 ! gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
14283 ! if(old_state == new_state)
14284 ! break;
14286 ! eDebug("eServiceMP3::state transition %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
14288 ! GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
14290 ! switch(transition)
14292 ! case GST_STATE_CHANGE_NULL_TO_READY:
14294 ! } break;
14295 ! case GST_STATE_CHANGE_READY_TO_PAUSED:
14297 ! GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
14298 ! if (appsink)
14300 ! g_object_set (G_OBJECT (appsink), "max-buffers", 2, NULL);
14301 ! g_object_set (G_OBJECT (appsink), "sync", FALSE, NULL);
14302 ! g_object_set (G_OBJECT (appsink), "emit-signals", TRUE, NULL);
14303 ! eDebug("eServiceMP3::appsink properties set!");
14304 ! gst_object_unref(appsink);
14306 ! setAC3Delay(ac3_delay);
14307 ! setPCMDelay(pcm_delay);
14308 ! } break;
14309 ! case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
14311 ! if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout )
14312 ! m_streamingsrc_timeout->stop();
14313 ! } break;
14314 ! case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
14316 ! } break;
14317 ! case GST_STATE_CHANGE_PAUSED_TO_READY:
14319 ! } break;
14320 ! case GST_STATE_CHANGE_READY_TO_NULL:
14322 ! } break;
14324 ! break;
14326 ! case GST_MESSAGE_ERROR:
14328 ! gchar *debug;
14329 ! GError *err;
14330 ! gst_message_parse_error (msg, &err, &debug);
14331 ! g_free (debug);
14332 ! eWarning("Gstreamer error: %s (%i) from %s", err->message, err->code, sourceName );
14333 ! if ( err->domain == GST_STREAM_ERROR )
14335 ! if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
14337 ! if ( g_strrstr(sourceName, "videosink") )
14338 ! m_event((iPlayableService*)this, evUser+11);
14339 ! else if ( g_strrstr(sourceName, "audiosink") )
14340 ! m_event((iPlayableService*)this, evUser+10);
14343 ! g_error_free(err);
14344 ! break;
14346 ! case GST_MESSAGE_INFO:
14348 ! gchar *debug;
14349 ! GError *inf;
14351 ! gst_message_parse_info (msg, &inf, &debug);
14352 ! g_free (debug);
14353 ! if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
14355 ! if ( g_strrstr(sourceName, "videosink") )
14356 ! m_event((iPlayableService*)this, evUser+14);
14358 ! g_error_free(inf);
14359 ! break;
14361 ! case GST_MESSAGE_TAG:
14363 ! GstTagList *tags, *result;
14364 ! gst_message_parse_tag(msg, &tags);
14366 ! result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_REPLACE);
14367 ! if (result)
14369 ! if (m_stream_tags)
14370 ! gst_tag_list_free(m_stream_tags);
14371 ! m_stream_tags = result;
14374 ! const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0);
14375 ! if ( gv_image )
14377 ! GstBuffer *buf_image;
14378 ! buf_image = gst_value_get_buffer (gv_image);
14379 ! int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644);
14380 ! int ret = write(fd, GST_BUFFER_DATA(buf_image), GST_BUFFER_SIZE(buf_image));
14381 ! close(fd);
14382 ! eDebug("eServiceMP3::/tmp/.id3coverart %d bytes written ", ret);
14383 ! m_event((iPlayableService*)this, evUser+13);
14385 ! gst_tag_list_free(tags);
14386 ! m_event((iPlayableService*)this, evUpdatedInfo);
14387 ! break;
14389 ! case GST_MESSAGE_ASYNC_DONE:
14391 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
14392 ! break;
14394 ! GstTagList *tags;
14395 ! gint i, active_idx, n_video = 0, n_audio = 0, n_text = 0;
14397 ! g_object_get (m_gst_playbin, "n-video", &n_video, NULL);
14398 ! g_object_get (m_gst_playbin, "n-audio", &n_audio, NULL);
14399 ! g_object_get (m_gst_playbin, "n-text", &n_text, NULL);
14401 ! eDebug("eServiceMP3::async-done - %d video, %d audio, %d subtitle", n_video, n_audio, n_text);
14403 ! if ( n_video + n_audio <= 0 )
14404 ! stop();
14406 ! active_idx = 0;
14408 ! m_audioStreams.clear();
14409 ! m_subtitleStreams.clear();
14411 ! for (i = 0; i < n_audio; i++)
14413 ! audioStream audio;
14414 ! gchar *g_codec, *g_lang;
14415 ! GstPad* pad = 0;
14416 ! g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad);
14417 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
14418 ! if (!caps)
14419 ! continue;
14420 ! GstStructure* str = gst_caps_get_structure(caps, 0);
14421 ! const gchar *g_type = gst_structure_get_name(str);
14422 ! audio.type = gstCheckAudioPad(str);
14423 ! g_codec = g_strdup(g_type);
14424 ! g_lang = g_strdup_printf ("und");
14425 ! g_signal_emit_by_name (m_gst_playbin, "get-audio-tags", i, &tags);
14426 ! if ( tags && gst_is_tag_list(tags) )
14428 ! gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec);
14429 ! gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
14430 ! gst_tag_list_free(tags);
14432 ! audio.language_code = std::string(g_lang);
14433 ! audio.codec = std::string(g_codec);
14434 ! eDebug("eServiceMP3::audio stream=%i codec=%s language=%s", i, g_codec, g_lang);
14435 ! m_audioStreams.push_back(audio);
14436 ! g_free (g_lang);
14437 ! g_free (g_codec);
14438 ! gst_caps_unref(caps);
14441 ! for (i = 0; i < n_text; i++)
14443 ! gchar *g_codec = NULL, *g_lang = NULL;
14444 ! g_signal_emit_by_name (m_gst_playbin, "get-text-tags", i, &tags);
14445 ! subtitleStream subs;
14446 ! // int ret;
14448 ! g_lang = g_strdup_printf ("und");
14449 ! if ( tags && gst_is_tag_list(tags) )
14451 ! gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
14452 ! gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec);
14453 ! gst_tag_list_free(tags);
14456 ! subs.language_code = std::string(g_lang);
14457 ! eDebug("eServiceMP3::subtitle stream=%i language=%s codec=%s", i, g_lang, g_codec);
14459 ! GstPad* pad = 0;
14460 ! g_signal_emit_by_name (m_gst_playbin, "get-text-pad", i, &pad);
14461 ! if ( pad )
14462 ! g_signal_connect (G_OBJECT (pad), "notify::caps", G_CALLBACK (gstTextpadHasCAPS), this);
14463 ! subs.type = getSubtitleType(pad, g_codec);
14465 ! m_subtitleStreams.push_back(subs);
14466 ! g_free (g_lang);
14468 ! m_event((iPlayableService*)this, evUpdatedEventInfo);
14470 ! if ( m_errorInfo.missing_codec != "" )
14472 ! if ( m_errorInfo.missing_codec.find("video/") == 0 || ( m_errorInfo.missing_codec.find("audio/") == 0 && getNumberOfTracks() == 0 ) )
14473 ! m_event((iPlayableService*)this, evUser+12);
14475 ! break;
14477 ! case GST_MESSAGE_ELEMENT:
14479 ! if (const GstStructure *msgstruct = gst_message_get_structure(msg))
14481 ! if ( gst_is_missing_plugin_message(msg) )
14483 ! GstCaps *caps;
14484 ! gst_structure_get ((GstStructure*)msgstruct, "detail", GST_TYPE_CAPS, &caps, NULL);
14485 ! std::string codec = (const char*) gst_caps_to_string(caps);
14486 ! gchar *description = gst_missing_plugin_message_get_description(msg);
14487 ! if ( description )
14489 ! eDebug("eServiceMP3::m_errorInfo.missing_codec = %s", codec.c_str());
14490 ! m_errorInfo.error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
14491 ! m_errorInfo.missing_codec = codec.substr(0,(codec.find_first_of(',')));
14492 ! g_free(description);
14494 ! gst_caps_unref(caps);
14496 ! else
14498 ! const gchar *eventname = gst_structure_get_name(msgstruct);
14499 ! if ( eventname )
14501 ! if (!strcmp(eventname, "eventSizeChanged") || !strcmp(eventname, "eventSizeAvail"))
14503 ! gst_structure_get_int (msgstruct, "aspect_ratio", &m_aspect);
14504 ! gst_structure_get_int (msgstruct, "width", &m_width);
14505 ! gst_structure_get_int (msgstruct, "height", &m_height);
14506 ! if (strstr(eventname, "Changed"))
14507 ! m_event((iPlayableService*)this, evVideoSizeChanged);
14509 ! else if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
14511 ! gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
14512 ! if (strstr(eventname, "Changed"))
14513 ! m_event((iPlayableService*)this, evVideoFramerateChanged);
14515 ! else if (!strcmp(eventname, "eventProgressiveChanged") || !strcmp(eventname, "eventProgressiveAvail"))
14517 ! gst_structure_get_int (msgstruct, "progressive", &m_progressive);
14518 ! if (strstr(eventname, "Changed"))
14519 ! m_event((iPlayableService*)this, evVideoProgressiveChanged);
14524 ! break;
14526 ! case GST_MESSAGE_BUFFERING:
14528 ! GstBufferingMode mode;
14529 ! gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
14530 ! gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
14531 ! m_event((iPlayableService*)this, evBuffering);
14532 ! break;
14534 ! case GST_MESSAGE_STREAM_STATUS:
14536 ! GstStreamStatusType type;
14537 ! GstElement *owner;
14538 ! gst_message_parse_stream_status (msg, &type, &owner);
14539 ! if ( type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming )
14541 ! if ( GST_IS_PAD(source) )
14542 ! owner = gst_pad_get_parent_element(GST_PAD(source));
14543 ! else if ( GST_IS_ELEMENT(source) )
14544 ! owner = GST_ELEMENT(source);
14545 ! else
14546 ! owner = 0;
14547 ! if ( owner )
14549 ! GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
14550 ! const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
14551 ! if (!strcmp(name, "souphttpsrc"))
14553 ! m_streamingsrc_timeout->start(HTTP_TIMEOUT*1000, true);
14554 ! g_object_set (G_OBJECT (owner), "timeout", HTTP_TIMEOUT, NULL);
14555 ! eDebug("eServiceMP3::GST_STREAM_STATUS_TYPE_CREATE -> setting timeout on %s to %is", name, HTTP_TIMEOUT);
14559 ! if ( GST_IS_PAD(source) )
14560 ! gst_object_unref(owner);
14562 ! break;
14564 ! default:
14565 ! break;
14567 ! g_free (sourceName);*/
14570 ! GstBusSyncReply eServiceMP3::gstBusSyncHandler(GstBus *bus, GstMessage *message, gpointer user_data)
14572 ! printf("Sira=22\n");
14573 ! /*
14574 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
14575 ! _this->m_pump.send(Message(1));
14576 ! /* wake
14577 ! return GST_BUS_PASS;*/
14580 ! void eServiceMP3::gstHTTPSourceSetAgent(GObject *object, GParamSpec *unused, gpointer user_data)
14582 ! printf("Sira=23\n");
14583 ! /*
14584 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
14585 ! GstElement *source;
14586 ! g_object_get(_this->m_gst_playbin, "source", &source, NULL);
14587 ! g_object_set (G_OBJECT (source), "user-agent", _this->m_useragent.c_str(), NULL);
14588 ! gst_object_unref(source);*/
14591 ! audiotype_t eServiceMP3::gstCheckAudioPad(GstStructure* structure)
14593 ! printf("Sira=24\n");
14594 ! /*
14595 ! if (!structure)
14596 ! return atUnknown;
14598 ! if ( gst_structure_has_name (structure, "audio/mpeg"))
14600 ! gint mpegversion, layer = -1;
14601 ! if (!gst_structure_get_int (structure, "mpegversion", &mpegversion))
14602 ! return atUnknown;
14604 ! switch (mpegversion) {
14605 ! case 1:
14607 ! gst_structure_get_int (structure, "layer", &layer);
14608 ! if ( layer == 3 )
14609 ! return atMP3;
14610 ! else
14611 ! return atMPEG;
14612 ! break;
14614 ! case 2:
14615 ! return atAAC;
14616 ! case 4:
14617 ! return atAAC;
14618 ! default:
14619 ! return atUnknown;
14623 ! else if ( gst_structure_has_name (structure, "audio/x-ac3") || gst_structure_has_name (structure, "audio/ac3") )
14624 ! return atAC3;
14625 ! else if ( gst_structure_has_name (structure, "audio/x-dts") || gst_structure_has_name (structure, "audio/dts") )
14626 ! return atDTS;
14627 ! else if ( gst_structure_has_name (structure, "audio/x-raw-int") )
14628 ! return atPCM;
14630 ! return atUnknown;*/
14633 ! void eServiceMP3::gstPoll(const Message &msg)
14636 ! printf("Sira=25\n");
14637 ! /*
14638 ! if (msg.type == 1)
14640 ! GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_gst_playbin));
14641 ! GstMessage *message;
14642 ! while ((message = gst_bus_pop(bus)))
14644 ! gstBusCall(bus, message);
14645 ! gst_message_unref (message);
14648 ! else if (msg.type == 2)
14649 ! pullSubtitle();
14650 ! else if (msg.type == 3)
14651 ! gstTextpadHasCAPS_synced(msg.d.pad);
14652 ! else
14653 ! eDebug("gstPoll unhandled Message %d\n", msg.type);*/
14656 ! eAutoInitPtr<eServiceFactoryMP3> init_eServiceFactoryMP3(eAutoInitNumbers::service+1, "eServiceFactoryMP3");
14658 ! void eServiceMP3::gstCBsubtitleAvail(GstElement *appsink, gpointer user_data)
14660 ! printf("Sira=26\n");
14661 ! /*
14662 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
14663 ! eSingleLocker l(_this->m_subs_to_pull_lock);
14664 ! ++_this->m_subs_to_pull;
14665 ! _this->m_pump.send(Message(2));*/
14668 ! void eServiceMP3::gstTextpadHasCAPS(GstPad *pad, GParamSpec * unused, gpointer user_data)
14670 ! printf("Sira=27\n");
14671 ! /*
14672 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
14674 ! gst_object_ref (pad);
14676 ! _this->m_pump.send(Message(3, pad));*/
14679 ! // after messagepump
14680 ! void eServiceMP3::gstTextpadHasCAPS_synced(GstPad *pad)
14682 ! printf("Sira=28\n");
14683 ! /*
14684 ! GstCaps *caps;
14686 ! g_object_get (G_OBJECT (pad), "caps", &caps, NULL);
14688 ! eDebug("gstTextpadHasCAPS:: signal::caps = %s", gst_caps_to_string(caps));
14690 ! if (caps)
14692 ! subtitleStream subs;
14694 ! // eDebug("gstGhostpadHasCAPS_synced %p %d", pad, m_subtitleStreams.size());
14696 ! if (!m_subtitleStreams.empty())
14697 ! subs = m_subtitleStreams[m_currentSubtitleStream];
14698 ! else {
14699 ! subs.type = stUnknown;
14700 ! subs.pad = pad;
14703 ! if ( subs.type == stUnknown )
14705 ! GstTagList *tags;
14706 ! // eDebug("gstGhostpadHasCAPS::m_subtitleStreams[%i].type == stUnknown...", m_currentSubtitleStream);
14708 ! gchar *g_lang;
14709 ! g_signal_emit_by_name (m_gst_playbin, "get-text-tags", m_currentSubtitleStream, &tags);
14711 ! g_lang = g_strdup_printf ("und");
14712 ! if ( tags && gst_is_tag_list(tags) )
14713 ! gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
14715 ! subs.language_code = std::string(g_lang);
14716 ! subs.type = getSubtitleType(pad);
14718 ! if (!m_subtitleStreams.empty())
14719 ! m_subtitleStreams[m_currentSubtitleStream] = subs;
14720 ! else
14721 ! m_subtitleStreams.push_back(subs);
14723 ! g_free (g_lang);
14726 ! // eDebug("gstGhostpadHasCAPS:: m_gst_prev_subtitle_caps=%s equal=%i",gst_caps_to_string(m_gst_prev_subtitle_caps),gst_caps_is_equal(m_gst_prev_subtitle_caps, caps));
14728 ! gst_caps_unref (caps);
14731 ! gst_object_unref (pad);*/
14734 ! void eServiceMP3::pullSubtitle()
14736 ! printf("Sira=29\n");
14737 ! /*
14738 ! GstElement *sink;
14739 ! g_object_get (G_OBJECT (m_gst_playbin), "text-sink", &sink, NULL);
14741 ! if (sink)
14743 ! while (m_subs_to_pull && m_subtitle_pages.size() < 2)
14745 ! GstBuffer *buffer;
14747 ! eSingleLocker l(m_subs_to_pull_lock);
14748 ! --m_subs_to_pull;
14749 ! g_signal_emit_by_name (sink, "pull-buffer", &buffer);
14751 ! if (buffer)
14753 ! gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
14754 ! gint64 duration_ns = GST_BUFFER_DURATION(buffer);
14755 ! size_t len = GST_BUFFER_SIZE(buffer);
14756 ! eDebug("pullSubtitle m_subtitleStreams[m_currentSubtitleStream].type=%i",m_subtitleStreams[m_currentSubtitleStream].type);
14758 ! if ( m_subtitleStreams[m_currentSubtitleStream].type )
14760 ! if ( m_subtitleStreams[m_currentSubtitleStream].type < stVOB )
14762 ! unsigned char line[len+1];
14763 ! SubtitlePage page;
14764 ! memcpy(line, GST_BUFFER_DATA(buffer), len);
14765 ! line[len] = 0;
14766 ! eDebug("got new text subtitle @ buf_pos = %lld ns (in pts=%lld): '%s' ", buf_pos, buf_pos/11111, line);
14767 ! gRGB rgbcol(0xD0,0xD0,0xD0);
14768 ! page.type = SubtitlePage::Pango;
14769 ! page.pango_page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)line));
14770 ! page.pango_page.m_show_pts = buf_pos / 11111L;
14771 ! page.pango_page.m_timeout = duration_ns / 1000000;
14772 ! m_subtitle_pages.push_back(page);
14773 ! if (m_subtitle_pages.size()==1)
14774 ! pushSubtitles();
14776 ! else
14778 ! eDebug("unsupported subpicture... ignoring");
14781 ! gst_buffer_unref(buffer);
14784 ! gst_object_unref(sink);
14786 ! else
14787 ! eDebug("no subtitle sink!");
14790 ! void eServiceMP3::pushSubtitles()
14792 ! while ( !m_subtitle_pages.empty() )
14794 ! SubtitlePage &frontpage = m_subtitle_pages.front();
14795 ! pts_t running_pts;
14796 ! gint64 diff_ms = 0;
14797 ! gint64 show_pts = 0;
14799 ! getPlayPosition(running_pts);
14801 ! if (m_decoder_time_valid_state < 4) {
14802 ! ++m_decoder_time_valid_state;
14803 ! if (m_prev_decoder_time == running_pts)
14804 ! m_decoder_time_valid_state = 0;
14805 ! if (m_decoder_time_valid_state < 4) {
14806 ! // if (m_decoder_time_valid_state)
14807 ! // eDebug("%d: decoder time not valid! prev %lld, now %lld\n", m_decoder_time_valid_state, m_prev_decoder_time/90, running_pts/90);
14808 ! // else
14809 ! // eDebug("%d: decoder time not valid! now %lld\n", m_decoder_time_valid_state, running_pts/90);
14810 ! m_subtitle_sync_timer->start(25, true);
14811 ! m_prev_decoder_time = running_pts;
14812 ! break;
14816 ! if (frontpage.type == SubtitlePage::Pango)
14817 ! show_pts = frontpage.pango_page.m_show_pts;
14819 ! diff_ms = ( show_pts - running_pts ) / 90;
14820 ! eDebug("check subtitle: decoder: %lld, show_pts: %lld, diff: %lld ms", running_pts/90, show_pts/90, diff_ms);
14822 ! if ( diff_ms < -100 )
14824 ! eDebug("subtitle too late... drop");
14825 ! m_subtitle_pages.pop_front();
14827 ! else if ( diff_ms > 20 )
14829 ! eDebug("start timer");
14830 ! m_subtitle_sync_timer->start(diff_ms, true);
14831 ! break;
14833 ! else // immediate show
14835 ! if ( m_subtitle_widget )
14837 ! eDebug("show!\n");
14838 ! if ( frontpage.type == SubtitlePage::Pango)
14839 ! m_subtitle_widget->setPage(frontpage.pango_page);
14840 ! m_subtitle_widget->show();
14842 ! m_subtitle_pages.pop_front();
14845 ! if (m_subtitle_pages.empty())
14846 ! pullSubtitle();*/
14850 ! RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
14852 ! printf("Sira=30\n");
14853 ! /*
14854 ! eDebug ("eServiceMP3::enableSubtitles m_currentSubtitleStream=%i this=%p",m_currentSubtitleStream, this);
14855 ! ePyObject entry;
14856 ! int tuplesize = PyTuple_Size(tuple);
14857 ! int pid, type;
14858 ! gint text_pid = 0;
14859 ! eSingleLocker l(m_subs_to_pull_lock);
14861 ! // GstPad *pad = 0;
14862 ! // g_signal_emit_by_name (m_gst_playbin, "get-text-pad", m_currentSubtitleStream, &pad);
14863 ! // gst_element_get_static_pad(m_gst_subtitlebin, "sink");
14864 ! // gulong subprobe_handler_id = gst_pad_add_buffer_probe (pad, G_CALLBACK (gstCBsubtitleDrop), NULL);
14866 ! if (!PyTuple_Check(tuple))
14867 ! goto error_out;
14868 ! if (tuplesize < 1)
14869 ! goto error_out;
14870 ! entry = PyTuple_GET_ITEM(tuple, 1);
14871 ! if (!PyInt_Check(entry))
14872 ! goto error_out;
14873 ! pid = PyInt_AsLong(entry);
14874 ! entry = PyTuple_GET_ITEM(tuple, 2);
14875 ! if (!PyInt_Check(entry))
14876 ! goto error_out;
14877 ! type = PyInt_AsLong(entry);
14879 ! if (m_currentSubtitleStream != pid)
14881 ! g_object_set (G_OBJECT (m_gst_playbin), "current-text", pid, NULL);
14882 ! eDebug ("eServiceMP3::enableSubtitles g_object_set current-text = %i", pid);
14883 ! m_currentSubtitleStream = pid;
14884 ! m_subs_to_pull = 0;
14885 ! m_prev_decoder_time = -1;
14886 ! m_subtitle_pages.clear();
14889 ! m_subtitle_widget = 0;
14890 ! m_subtitle_widget = new eSubtitleWidget(parent);
14891 ! m_subtitle_widget->resize(parent->size()); /* full size
14893 ! g_object_get (G_OBJECT (m_gst_playbin), "current-text", &text_pid, NULL);
14895 ! eDebug ("eServiceMP3::switched to subtitle stream %i", text_pid);
14896 ! // gst_pad_remove_buffer_probe (pad, subprobe_handler_id);
14898 ! m_event((iPlayableService*)this, evUpdatedInfo);
14900 ! return 0;
14902 ! error_out:
14903 ! eDebug("eServiceMP3::enableSubtitles needs a tuple as 2nd argument!\n"
14904 ! "for gst subtitles (2, subtitle_stream_count, subtitle_type)");
14905 ! return -1;*/
14908 ! RESULT eServiceMP3::disableSubtitles(eWidget *parent)
14910 ! eDebug("eServiceMP3::disableSubtitles");
14911 ! m_subtitle_pages.clear();
14912 ! delete m_subtitle_widget;
14913 ! m_subtitle_widget = 0;
14914 ! return 0;
14917 ! PyObject *eServiceMP3::getCachedSubtitle()
14919 ! // eDebug("eServiceMP3::getCachedSubtitle");
14920 ! Py_RETURN_NONE;
14923 ! PyObject *eServiceMP3::getSubtitleList()
14924 ! {printf("Sira=31\n");
14925 ! // eDebug("eServiceMP3::getSubtitleList");
14926 ! ePyObject l = PyList_New(0);
14927 ! int stream_idx = 0;
14929 ! for (std::vector<subtitleStream>::iterator IterSubtitleStream(m_subtitleStreams.begin()); IterSubtitleStream != m_subtitleStreams.end(); ++IterSubtitleStream)
14931 ! subtype_t type = IterSubtitleStream->type;
14932 ! switch(type)
14934 ! case stUnknown:
14935 ! case stVOB:
14936 ! case stPGS:
14937 ! break;
14938 ! default:
14940 ! ePyObject tuple = PyTuple_New(5);
14941 ! // eDebug("eServiceMP3::getSubtitleList idx=%i type=%i, code=%s", stream_idx, int(type), (IterSubtitleStream->language_code).c_str());
14942 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
14943 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(stream_idx));
14944 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(int(type)));
14945 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(0));
14946 ! PyTuple_SET_ITEM(tuple, 4, PyString_FromString((IterSubtitleStream->language_code).c_str()));
14947 ! PyList_Append(l, tuple);
14948 ! Py_DECREF(tuple);
14951 ! stream_idx++;
14953 ! eDebug("eServiceMP3::getSubtitleList finished");
14954 ! return l;
14957 ! RESULT eServiceMP3::streamed(ePtr<iStreamedService> &ptr)
14959 ! ptr = this;
14960 ! return 0;
14963 ! PyObject *eServiceMP3::getBufferCharge()
14965 ! ePyObject tuple = PyTuple_New(5);
14966 ! PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(m_bufferInfo.bufferPercent));
14967 ! PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(m_bufferInfo.avgInRate));
14968 ! PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(m_bufferInfo.avgOutRate));
14969 ! PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(m_bufferInfo.bufferingLeft));
14970 ! PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(m_buffer_size));
14971 ! return tuple;
14974 ! int eServiceMP3::setBufferSize(int size)
14976 ! m_buffer_size = size;
14977 ! g_object_set (G_OBJECT (m_gst_playbin), "buffer-size", m_buffer_size, NULL);
14978 ! return 0;
14981 ! int eServiceMP3::getAC3Delay()
14983 ! return ac3_delay;
14986 ! int eServiceMP3::getPCMDelay()
14988 ! return pcm_delay;
14991 ! void eServiceMP3::setAC3Delay(int delay)
14994 ! printf("Sira=32\n");
14995 ! /*
14996 ! ac3_delay = delay;
14997 ! if (!m_gst_playbin || m_state != stRunning)
14998 ! return;
14999 ! else
15001 ! GstElement *sink;
15002 ! int config_delay_int = delay;
15003 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
15005 ! if (sink)
15007 ! std::string config_delay;
15008 ! if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
15009 ! config_delay_int += atoi(config_delay.c_str());
15010 ! gst_object_unref(sink);
15012 ! else
15014 ! eDebug("dont apply ac3 delay when no video is running!");
15015 ! config_delay_int = 0;
15018 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
15020 ! if (sink)
15022 ! gchar *name = gst_element_get_name(sink);
15023 ! if (strstr(name, "dvbaudiosink"))
15024 ! eTSMPEGDecoder::setHwAC3Delay(config_delay_int);
15025 ! g_free(name);
15026 ! gst_object_unref(sink);
15028 ! }*/
15031 ! void eServiceMP3::setPCMDelay(int delay)
15033 ! printf("Sira=33\n");
15034 ! /*
15035 ! pcm_delay = delay;
15036 ! if (!m_gst_playbin || m_state != stRunning)
15037 ! return;
15038 ! else
15040 ! GstElement *sink;
15041 ! int config_delay_int = delay;
15042 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
15044 ! if (sink)
15046 ! std::string config_delay;
15047 ! if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
15048 ! config_delay_int += atoi(config_delay.c_str());
15049 ! gst_object_unref(sink);
15051 ! else
15053 ! eDebug("dont apply pcm delay when no video is running!");
15054 ! config_delay_int = 0;
15057 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
15059 ! if (sink)
15061 ! gchar *name = gst_element_get_name(sink);
15062 ! if (strstr(name, "dvbaudiosink"))
15063 ! eTSMPEGDecoder::setHwPCMDelay(config_delay_int);
15064 ! else
15066 ! // this is realy untested..and not used yet
15067 ! gint64 offset = config_delay_int;
15068 ! offset *= 1000000; // milli to nano
15069 ! g_object_set (G_OBJECT (m_gst_playbin), "ts-offset", offset, NULL);
15071 ! g_free(name);
15072 ! gst_object_unref(sink);
15074 ! }*/
15077 diff -crB Enigma2PC/lib/service/servicemp3.h Enigma2PC_orig/lib/service/servicemp3.h
15078 *** Enigma2PC/lib/service/servicemp3.h 2011-11-20 21:56:11.260830302 +0400
15079 --- Enigma2PC_orig/lib/service/servicemp3.h 2011-11-20 03:13:00.000000000 +0400
15080 ***************
15081 *** 1,270 ****
15082 ! #ifndef __servicemp3_h
15083 ! #define __servicemp3_h
15085 ! #include <lib/base/message.h>
15086 ! #include <lib/service/iservice.h>
15087 ! #include <lib/dvb/pmt.h>
15088 ! #include <lib/dvb/subtitle.h>
15089 ! #include <lib/dvb/teletext.h>
15090 ! #include <gst/gst.h>
15091 ! /* for subtitles */
15092 ! #include <lib/gui/esubtitle.h>
15094 ! class eStaticServiceMP3Info;
15096 ! class eSubtitleWidget;
15098 ! class eServiceFactoryMP3: public iServiceHandler
15100 ! DECLARE_REF(eServiceFactoryMP3);
15101 ! public:
15102 ! eServiceFactoryMP3();
15103 ! virtual ~eServiceFactoryMP3();
15104 ! enum { id = 0x1001 };
15106 ! // iServiceHandler
15107 ! RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
15108 ! RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
15109 ! RESULT list(const eServiceReference &, ePtr<iListableService> &ptr);
15110 ! RESULT info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr);
15111 ! RESULT offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr);
15112 ! private:
15113 ! ePtr<eStaticServiceMP3Info> m_service_info;
15114 ! };
15116 ! class eStaticServiceMP3Info: public iStaticServiceInformation
15118 ! DECLARE_REF(eStaticServiceMP3Info);
15119 ! friend class eServiceFactoryMP3;
15120 ! eStaticServiceMP3Info();
15121 ! public:
15122 ! RESULT getName(const eServiceReference &ref, std::string &name);
15123 ! int getLength(const eServiceReference &ref);
15124 ! int getInfo(const eServiceReference &ref, int w);
15125 ! };
15127 ! typedef struct _GstElement GstElement;
15129 ! typedef enum { atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC } audiotype_t;
15130 ! typedef enum { stUnknown, stPlainText, stSSA, stASS, stSRT, stVOB, stPGS } subtype_t;
15131 ! typedef enum { ctNone, ctMPEGTS, ctMPEGPS, ctMKV, ctAVI, ctMP4, ctVCD, ctCDA } containertype_t;
15133 ! class eServiceMP3: public iPlayableService, public iPauseableService,
15134 ! public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection,
15135 ! public iSubtitleOutput, public iStreamedService, public iAudioDelay, public Object
15137 ! DECLARE_REF(eServiceMP3);
15138 ! public:
15139 ! virtual ~eServiceMP3();
15141 ! // iPlayableService
15142 ! RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
15143 ! RESULT start();
15144 ! RESULT stop();
15145 ! RESULT setTarget(int target);
15147 ! RESULT pause(ePtr<iPauseableService> &ptr);
15148 ! RESULT setSlowMotion(int ratio);
15149 ! RESULT setFastForward(int ratio);
15151 ! RESULT seek(ePtr<iSeekableService> &ptr);
15152 ! RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
15153 ! RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr);
15154 ! RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
15155 ! RESULT audioDelay(ePtr<iAudioDelay> &ptr);
15157 ! // not implemented (yet)
15158 ! RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
15159 ! RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
15160 ! RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
15161 ! RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
15163 ! RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
15164 ! RESULT keys(ePtr<iServiceKeys> &ptr) { ptr = 0; return -1; }
15165 ! RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
15167 ! // iPausableService
15168 ! RESULT pause();
15169 ! RESULT unpause();
15171 ! RESULT info(ePtr<iServiceInformation>&);
15173 ! // iSeekableService
15174 ! RESULT getLength(pts_t &SWIG_OUTPUT);
15175 ! RESULT seekTo(pts_t to);
15176 ! RESULT seekRelative(int direction, pts_t to);
15177 ! RESULT getPlayPosition(pts_t &SWIG_OUTPUT);
15178 ! RESULT setTrickmode(int trick);
15179 ! RESULT isCurrentlySeekable();
15181 ! // iServiceInformation
15182 ! RESULT getName(std::string &name);
15183 ! int getInfo(int w);
15184 ! std::string getInfoString(int w);
15185 ! PyObject *getInfoObject(int w);
15187 ! // iAudioTrackSelection
15188 ! int getNumberOfTracks();
15189 ! RESULT selectTrack(unsigned int i);
15190 ! RESULT getTrackInfo(struct iAudioTrackInfo &, unsigned int n);
15191 ! int getCurrentTrack();
15193 ! // iAudioChannelSelection
15194 ! int getCurrentChannel();
15195 ! RESULT selectChannel(int i);
15197 ! // iSubtitleOutput
15198 ! RESULT enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry);
15199 ! RESULT disableSubtitles(eWidget *parent);
15200 ! PyObject *getSubtitleList();
15201 ! PyObject *getCachedSubtitle();
15203 ! // iStreamedService
15204 ! RESULT streamed(ePtr<iStreamedService> &ptr);
15205 ! PyObject *getBufferCharge();
15206 ! int setBufferSize(int size);
15208 ! // iAudioDelay
15209 ! int getAC3Delay();
15210 ! int getPCMDelay();
15211 ! void setAC3Delay(int);
15212 ! void setPCMDelay(int);
15214 ! struct audioStream
15216 ! GstPad* pad;
15217 ! audiotype_t type;
15218 ! std::string language_code; /* iso-639, if available. */
15219 ! std::string codec; /* clear text codec description */
15220 ! audioStream()
15221 ! :pad(0), type(atUnknown)
15224 ! };
15225 ! struct subtitleStream
15227 ! GstPad* pad;
15228 ! subtype_t type;
15229 ! std::string language_code; /* iso-639, if available. */
15230 ! subtitleStream()
15231 ! :pad(0)
15234 ! };
15235 ! struct sourceStream
15237 ! audiotype_t audiotype;
15238 ! containertype_t containertype;
15239 ! bool is_video;
15240 ! bool is_streaming;
15241 ! sourceStream()
15242 ! :audiotype(atUnknown), containertype(ctNone), is_video(FALSE), is_streaming(FALSE)
15245 ! };
15246 ! struct bufferInfo
15248 ! int bufferPercent;
15249 ! int avgInRate;
15250 ! int avgOutRate;
15251 ! int64_t bufferingLeft;
15252 ! bufferInfo()
15253 ! :bufferPercent(0), avgInRate(0), avgOutRate(0), bufferingLeft(-1)
15256 ! };
15257 ! struct errorInfo
15259 ! std::string error_message;
15260 ! std::string missing_codec;
15261 ! };
15263 ! private:
15264 ! static int pcm_delay;
15265 ! static int ac3_delay;
15266 ! int m_currentAudioStream;
15267 ! int m_currentSubtitleStream;
15268 ! int selectAudioStream(int i);
15269 ! std::vector<audioStream> m_audioStreams;
15270 ! std::vector<subtitleStream> m_subtitleStreams;
15271 ! eSubtitleWidget *m_subtitle_widget;
15272 ! int m_currentTrickRatio;
15273 ! ePtr<eTimer> m_seekTimeout;
15274 ! void seekTimeoutCB();
15275 ! friend class eServiceFactoryMP3;
15276 ! eServiceReference m_ref;
15277 ! int m_buffer_size;
15278 ! bufferInfo m_bufferInfo;
15279 ! errorInfo m_errorInfo;
15280 ! eServiceMP3(eServiceReference ref);
15281 ! Signal2<void,iPlayableService*,int> m_event;
15282 ! enum
15284 ! stIdle, stRunning, stStopped,
15285 ! };
15286 ! int m_state;
15287 ! GstElement *m_gst_playbin;
15288 ! GstTagList *m_stream_tags;
15290 ! struct Message
15292 ! Message()
15293 ! :type(-1)
15294 ! {}
15295 ! Message(int type)
15296 ! :type(type)
15297 ! {}
15298 ! Message(int type, GstPad *pad)
15299 ! :type(type)
15301 ! d.pad=pad;
15304 ! int type;
15305 ! union {
15306 ! GstPad *pad; // for msg type 3
15307 ! } d;
15308 ! };
15310 ! eFixedMessagePump<Message> m_pump;
15312 ! audiotype_t gstCheckAudioPad(GstStructure* structure);
15313 ! void gstBusCall(GstBus *bus, GstMessage *msg);
15314 ! static GstBusSyncReply gstBusSyncHandler(GstBus *bus, GstMessage *message, gpointer user_data);
15315 ! static void gstTextpadHasCAPS(GstPad *pad, GParamSpec * unused, gpointer user_data);
15316 ! void gstTextpadHasCAPS_synced(GstPad *pad);
15317 ! static void gstCBsubtitleAvail(GstElement *element, gpointer user_data);
15318 ! GstPad* gstCreateSubtitleSink(eServiceMP3* _this, subtype_t type);
15319 ! void gstPoll(const Message&);
15320 ! static void gstHTTPSourceSetAgent(GObject *source, GParamSpec *unused, gpointer user_data);
15322 ! struct SubtitlePage
15324 ! enum { Unknown, Pango, Vob } type;
15325 ! ePangoSubtitlePage pango_page;
15326 ! eVobSubtitlePage vob_page;
15327 ! };
15329 ! std::list<SubtitlePage> m_subtitle_pages;
15330 ! ePtr<eTimer> m_subtitle_sync_timer;
15332 ! ePtr<eTimer> m_streamingsrc_timeout;
15333 ! pts_t m_prev_decoder_time;
15334 ! int m_decoder_time_valid_state;
15336 ! void pushSubtitles();
15337 ! void pullSubtitle();
15338 ! void sourceTimeout();
15339 ! int m_subs_to_pull;
15340 ! sourceStream m_sourceinfo;
15341 ! eSingleLock m_subs_to_pull_lock;
15342 ! gulong m_subs_to_pull_handler_id;
15344 ! RESULT seekToImpl(pts_t to);
15346 ! gint m_aspect, m_width, m_height, m_framerate, m_progressive;
15347 ! std::string m_useragent;
15348 ! RESULT trickSeek(gdouble ratio);
15349 ! };
15351 ! #endif
15352 --- 1,270 ----
15353 ! #ifndef __servicemp3_h
15354 ! #define __servicemp3_h
15356 ! #include <lib/base/message.h>
15357 ! #include <lib/service/iservice.h>
15358 ! #include <lib/dvb/pmt.h>
15359 ! #include <lib/dvb/subtitle.h>
15360 ! #include <lib/dvb/teletext.h>
15361 ! #include <gst/gst.h>
15362 ! /* for subtitles */
15363 ! #include <lib/gui/esubtitle.h>
15365 ! class eStaticServiceMP3Info;
15367 ! class eSubtitleWidget;
15369 ! class eServiceFactoryMP3: public iServiceHandler
15371 ! DECLARE_REF(eServiceFactoryMP3);
15372 ! public:
15373 ! eServiceFactoryMP3();
15374 ! virtual ~eServiceFactoryMP3();
15375 ! enum { id = 0x1001 };
15377 ! // iServiceHandler
15378 ! RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
15379 ! RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
15380 ! RESULT list(const eServiceReference &, ePtr<iListableService> &ptr);
15381 ! RESULT info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr);
15382 ! RESULT offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr);
15383 ! private:
15384 ! ePtr<eStaticServiceMP3Info> m_service_info;
15385 ! };
15387 ! class eStaticServiceMP3Info: public iStaticServiceInformation
15389 ! DECLARE_REF(eStaticServiceMP3Info);
15390 ! friend class eServiceFactoryMP3;
15391 ! eStaticServiceMP3Info();
15392 ! public:
15393 ! RESULT getName(const eServiceReference &ref, std::string &name);
15394 ! int getLength(const eServiceReference &ref);
15395 ! int getInfo(const eServiceReference &ref, int w);
15396 ! };
15398 ! typedef struct _GstElement GstElement;
15400 ! typedef enum { atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC } audiotype_t;
15401 ! typedef enum { stUnknown, stPlainText, stSSA, stASS, stSRT, stVOB, stPGS } subtype_t;
15402 ! typedef enum { ctNone, ctMPEGTS, ctMPEGPS, ctMKV, ctAVI, ctMP4, ctVCD, ctCDA } containertype_t;
15404 ! class eServiceMP3: public iPlayableService, public iPauseableService,
15405 ! public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection,
15406 ! public iSubtitleOutput, public iStreamedService, public iAudioDelay, public Object
15408 ! DECLARE_REF(eServiceMP3);
15409 ! public:
15410 ! virtual ~eServiceMP3();
15412 ! // iPlayableService
15413 ! RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
15414 ! RESULT start();
15415 ! RESULT stop();
15416 ! RESULT setTarget(int target);
15418 ! RESULT pause(ePtr<iPauseableService> &ptr);
15419 ! RESULT setSlowMotion(int ratio);
15420 ! RESULT setFastForward(int ratio);
15422 ! RESULT seek(ePtr<iSeekableService> &ptr);
15423 ! RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
15424 ! RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr);
15425 ! RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
15426 ! RESULT audioDelay(ePtr<iAudioDelay> &ptr);
15428 ! // not implemented (yet)
15429 ! RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
15430 ! RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
15431 ! RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
15432 ! RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
15434 ! RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
15435 ! RESULT keys(ePtr<iServiceKeys> &ptr) { ptr = 0; return -1; }
15436 ! RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
15438 ! // iPausableService
15439 ! RESULT pause();
15440 ! RESULT unpause();
15442 ! RESULT info(ePtr<iServiceInformation>&);
15444 ! // iSeekableService
15445 ! RESULT getLength(pts_t &SWIG_OUTPUT);
15446 ! RESULT seekTo(pts_t to);
15447 ! RESULT seekRelative(int direction, pts_t to);
15448 ! RESULT getPlayPosition(pts_t &SWIG_OUTPUT);
15449 ! RESULT setTrickmode(int trick);
15450 ! RESULT isCurrentlySeekable();
15452 ! // iServiceInformation
15453 ! RESULT getName(std::string &name);
15454 ! int getInfo(int w);
15455 ! std::string getInfoString(int w);
15456 ! PyObject *getInfoObject(int w);
15458 ! // iAudioTrackSelection
15459 ! int getNumberOfTracks();
15460 ! RESULT selectTrack(unsigned int i);
15461 ! RESULT getTrackInfo(struct iAudioTrackInfo &, unsigned int n);
15462 ! int getCurrentTrack();
15464 ! // iAudioChannelSelection
15465 ! int getCurrentChannel();
15466 ! RESULT selectChannel(int i);
15468 ! // iSubtitleOutput
15469 ! RESULT enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry);
15470 ! RESULT disableSubtitles(eWidget *parent);
15471 ! PyObject *getSubtitleList();
15472 ! PyObject *getCachedSubtitle();
15474 ! // iStreamedService
15475 ! RESULT streamed(ePtr<iStreamedService> &ptr);
15476 ! PyObject *getBufferCharge();
15477 ! int setBufferSize(int size);
15479 ! // iAudioDelay
15480 ! int getAC3Delay();
15481 ! int getPCMDelay();
15482 ! void setAC3Delay(int);
15483 ! void setPCMDelay(int);
15485 ! struct audioStream
15487 ! GstPad* pad;
15488 ! audiotype_t type;
15489 ! std::string language_code; /* iso-639, if available. */
15490 ! std::string codec; /* clear text codec description */
15491 ! audioStream()
15492 ! :pad(0), type(atUnknown)
15495 ! };
15496 ! struct subtitleStream
15498 ! GstPad* pad;
15499 ! subtype_t type;
15500 ! std::string language_code; /* iso-639, if available. */
15501 ! subtitleStream()
15502 ! :pad(0)
15505 ! };
15506 ! struct sourceStream
15508 ! audiotype_t audiotype;
15509 ! containertype_t containertype;
15510 ! bool is_video;
15511 ! bool is_streaming;
15512 ! sourceStream()
15513 ! :audiotype(atUnknown), containertype(ctNone), is_video(FALSE), is_streaming(FALSE)
15516 ! };
15517 ! struct bufferInfo
15519 ! int bufferPercent;
15520 ! int avgInRate;
15521 ! int avgOutRate;
15522 ! int64_t bufferingLeft;
15523 ! bufferInfo()
15524 ! :bufferPercent(0), avgInRate(0), avgOutRate(0), bufferingLeft(-1)
15527 ! };
15528 ! struct errorInfo
15530 ! std::string error_message;
15531 ! std::string missing_codec;
15532 ! };
15534 ! private:
15535 ! static int pcm_delay;
15536 ! static int ac3_delay;
15537 ! int m_currentAudioStream;
15538 ! int m_currentSubtitleStream;
15539 ! int selectAudioStream(int i);
15540 ! std::vector<audioStream> m_audioStreams;
15541 ! std::vector<subtitleStream> m_subtitleStreams;
15542 ! eSubtitleWidget *m_subtitle_widget;
15543 ! int m_currentTrickRatio;
15544 ! ePtr<eTimer> m_seekTimeout;
15545 ! void seekTimeoutCB();
15546 ! friend class eServiceFactoryMP3;
15547 ! eServiceReference m_ref;
15548 ! int m_buffer_size;
15549 ! bufferInfo m_bufferInfo;
15550 ! errorInfo m_errorInfo;
15551 ! eServiceMP3(eServiceReference ref);
15552 ! Signal2<void,iPlayableService*,int> m_event;
15553 ! enum
15555 ! stIdle, stRunning, stStopped,
15556 ! };
15557 ! int m_state;
15558 ! GstElement *m_gst_playbin;
15559 ! GstTagList *m_stream_tags;
15561 ! struct Message
15563 ! Message()
15564 ! :type(-1)
15565 ! {}
15566 ! Message(int type)
15567 ! :type(type)
15568 ! {}
15569 ! Message(int type, GstPad *pad)
15570 ! :type(type)
15572 ! d.pad=pad;
15575 ! int type;
15576 ! union {
15577 ! GstPad *pad; // for msg type 3
15578 ! } d;
15579 ! };
15581 ! eFixedMessagePump<Message> m_pump;
15583 ! audiotype_t gstCheckAudioPad(GstStructure* structure);
15584 ! void gstBusCall(GstBus *bus, GstMessage *msg);
15585 ! static GstBusSyncReply gstBusSyncHandler(GstBus *bus, GstMessage *message, gpointer user_data);
15586 ! static void gstTextpadHasCAPS(GstPad *pad, GParamSpec * unused, gpointer user_data);
15587 ! void gstTextpadHasCAPS_synced(GstPad *pad);
15588 ! static void gstCBsubtitleAvail(GstElement *element, gpointer user_data);
15589 ! GstPad* gstCreateSubtitleSink(eServiceMP3* _this, subtype_t type);
15590 ! void gstPoll(const Message&);
15591 ! static void gstHTTPSourceSetAgent(GObject *source, GParamSpec *unused, gpointer user_data);
15593 ! struct SubtitlePage
15595 ! enum { Unknown, Pango, Vob } type;
15596 ! ePangoSubtitlePage pango_page;
15597 ! eVobSubtitlePage vob_page;
15598 ! };
15600 ! std::list<SubtitlePage> m_subtitle_pages;
15601 ! ePtr<eTimer> m_subtitle_sync_timer;
15603 ! ePtr<eTimer> m_streamingsrc_timeout;
15604 ! pts_t m_prev_decoder_time;
15605 ! int m_decoder_time_valid_state;
15607 ! void pushSubtitles();
15608 ! void pullSubtitle();
15609 ! void sourceTimeout();
15610 ! int m_subs_to_pull;
15611 ! sourceStream m_sourceinfo;
15612 ! eSingleLock m_subs_to_pull_lock;
15613 ! gulong m_subs_to_pull_handler_id;
15615 ! RESULT seekToImpl(pts_t to);
15617 ! gint m_aspect, m_width, m_height, m_framerate, m_progressive;
15618 ! std::string m_useragent;
15619 ! RESULT trickSeek(int ratio);
15620 ! };
15622 ! #endif
15623 Only in Enigma2PC_orig: rollback_lirc_support.diff