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
7 ! <map context="ListboxActions">
8 ! <device name="keyboard">
9 ! <key id="a" mapto="up" flags="mr" />
10 ! <key id="b" mapto="down" flags="mr" />
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" />
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" />
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" />
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" />
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" />
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" />
84 ! <map context="InfobarEPGActions">
85 ! <key id="KEY_INFO" mapto="showEventInfo" flags="b" />
86 ! <key id="KEY_INFO" mapto="showEventInfoPlugin" flags="l" />
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" /-->
94 ! <device name="dreambox ir keyboard">
95 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
97 ! <device name="dreambox remote control (native)">
98 ! <key id="KEY_RED" mapto="instantRecord" flags="b" />
100 ! <device name="Xlib">
101 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
105 ! <map context="InfobarExtensions">
106 ! <key id="KEY_BLUE" mapto="extensions" flags="b" />
109 ! <map context="SatlistShortcutAction">
110 ! <key id="KEY_BLUE" mapto="nothingconnected" flags="b" />
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" />
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" />
137 ! <map context="InputAsciiActions">
138 ! <device name="Console">
139 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
141 ! <device name="SDL">
142 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
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" />
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" />
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" />
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" />
186 ! <map context="InfobarMenuActions">
187 ! <key id="KEY_MENU" mapto="mainMenu" flags="mr" />
188 ! <key id="KEY_SPACE" mapto="mainMenu" flags="mr" />
191 ! <map context="MenuActions">
192 ! <key id="KEY_MENU" mapto="menu" flags="mr" />
193 ! <key id="KEY_SPACE" mapto="menu" flags="mr" />
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" />
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" />
209 ! <map context="InfobarAudioSelectionActions">
210 ! <device name="dreambox remote control (native)">
211 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
213 ! <device name="dreambox ir keyboard">
214 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
216 ! <device name="dreambox advanced remote control (native)">
217 ! <key id="KEY_YELLOW" mapto="audioSelection" flags="b" />
219 ! <device name="Xlib">
220 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
224 ! <map context="InfobarSubserviceSelectionActions">
225 ! <key id="KEY_GREEN" mapto="subserviceSelection" flags="b" />
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" />
238 ! <device name="dreambox advanced remote control (native)">
239 ! <key id="KEY_TV" mapto="exit" flags="m" />
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" />
255 ! <map context="PowerKeyActions">
256 ! <key id="KEY_POWER" mapto="powerdown" flags="m" />
257 ! <key id="KEY_POWER" mapto="powerup" flags="b" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
386 ! <device name="dreambox ir keyboard">
387 ! <key id="KEY_REWIND" mapto="timeshiftActivateEnd" flags="m" />
388 ! <key id="KEY_PAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
390 ! <device name="Xlib">
391 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
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" />
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" />
407 ! <map context="MoviePlayerActions">
408 ! <device name="dreambox remote control (native)">
409 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
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" />
415 ! <device name="dreambox ir keyboard">
416 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
418 ! <device name="Xlib">
419 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
420 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
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" />
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" />
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" />
442 ! <map context="MediaPlayerCueSheetActions">
443 ! <device name="dreambox remote control (native)">
444 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
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" />
450 ! <device name="dreambox ir keyboard">
451 ! <key id="KEY_TAB" mapto="toggleMark" flags="m" />
455 ! <map context="VirtualKeyboardActions">
456 ! <key id="KEY_TEXT" mapto="showVirtualKeyboard" flags="m" />
459 ! <map context="InfobarTeletextActions">
460 ! <key id="KEY_TEXT" mapto="startTeletext" flags="m" />
463 ! <map context="InfobarRdsActions">
464 ! <key id="KEY_TEXT" mapto="startRassInteractive" flags="m" />
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" />
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" />
489 ! <map context="ChannelSelectEPGActions">
490 ! <key id="KEY_INFO" mapto="showEPGList" flags="m" />
493 ! <map context="ChannelSelectEditActions">
494 ! <key id="KEY_MENU" mapto="contextMenu" flags="m" />
495 ! <key id="KEY_SPACE" mapto="contextMenu" flags="m" />
498 ! <map context="TvRadioActions">
499 ! <key id="KEY_TV" mapto="keyTV" flags="m" />
500 ! <key id="KEY_RADIO" mapto="keyRadio" flags="m" />
503 ! <map context="TimerEditActions">
504 ! <key id="KEY_INFO" mapto="log" flags="m" />
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" />
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" />
530 ! <map context="EventViewEPGActions">
531 ! <key id="KEY_YELLOW" mapto="openSingleServiceEPG" flags="m" />
532 ! <key id="KEY_BLUE" mapto="openMultiServiceEPG" flags="m" />
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" />
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" />
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" />
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" />
580 ! <map context="WindowActions">
584 ! <map context="HelpActions">
585 ! <key id="KEY_HELP" mapto="displayHelp" flags="m" />
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" />
599 ! <map context="StandbyActions">
600 ! <key id="KEY_POWER" mapto="power" flags="m" />
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" />
626 ! <map context="CiSelectionActions">
627 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
628 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
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" />
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" />
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" />
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" />
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" />
688 ! <map context="ListboxActions">
689 ! <device name="keyboard">
690 ! <key id="a" mapto="up" flags="mr" />
691 ! <key id="b" mapto="down" flags="mr" />
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" />
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" />
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" />
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" />
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" />
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" />
764 ! <map context="InfobarEPGActions">
765 ! <key id="KEY_INFO" mapto="showEventInfo" flags="b" />
766 ! <key id="KEY_INFO" mapto="showEventInfoPlugin" flags="l" />
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" /-->
774 ! <device name="dreambox ir keyboard">
775 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
777 ! <device name="dreambox remote control (native)">
778 ! <key id="KEY_RED" mapto="instantRecord" flags="b" />
780 ! <device name="Xlib">
781 ! <key id="KEY_RECORD" mapto="instantRecord" flags="m" />
785 ! <map context="InfobarExtensions">
786 ! <key id="KEY_BLUE" mapto="extensions" flags="b" />
789 ! <map context="SatlistShortcutAction">
790 ! <key id="KEY_BLUE" mapto="nothingconnected" flags="b" />
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" />
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" />
817 ! <map context="InputAsciiActions">
818 ! <device name="Console">
819 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
821 ! <device name="SDL">
822 ! <key id="KEY_ASCII" mapto="gotAsciiCode" flags="mr" />
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" />
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" />
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" />
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" />
866 ! <map context="InfobarMenuActions">
867 ! <key id="KEY_MENU" mapto="mainMenu" flags="mr" />
868 ! <key id="KEY_SPACE" mapto="mainMenu" flags="mr" />
871 ! <map context="MenuActions">
872 ! <key id="KEY_MENU" mapto="menu" flags="mr" />
873 ! <key id="KEY_SPACE" mapto="menu" flags="mr" />
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" />
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" />
889 ! <map context="InfobarAudioSelectionActions">
890 ! <device name="dreambox remote control (native)">
891 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
893 ! <device name="dreambox ir keyboard">
894 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
896 ! <device name="dreambox advanced remote control (native)">
897 ! <key id="KEY_YELLOW" mapto="audioSelection" flags="b" />
899 ! <device name="Xlib">
900 ! <key id="KEY_AUDIO" mapto="audioSelection" flags="m" />
904 ! <map context="InfobarSubserviceSelectionActions">
905 ! <key id="KEY_GREEN" mapto="subserviceSelection" flags="b" />
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" />
918 ! <device name="dreambox advanced remote control (native)">
919 ! <key id="KEY_TV" mapto="exit" flags="m" />
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" />
935 ! <map context="PowerKeyActions">
936 ! <key id="KEY_POWER" mapto="powerdown" flags="m" />
937 ! <key id="KEY_POWER" mapto="powerup" flags="b" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
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" />
1072 ! <device name="dreambox ir keyboard">
1073 ! <key id="KEY_REWIND" mapto="timeshiftActivateEnd" flags="m" />
1074 ! <key id="KEY_PAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
1076 ! <device name="Xlib">
1077 ! <key id="KEY_PLAYPAUSE" mapto="timeshiftActivateEndAndPause" flags="m" />
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" />
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" />
1093 ! <map context="MoviePlayerActions">
1094 ! <device name="dreambox remote control (native)">
1095 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
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" />
1101 ! <device name="dreambox ir keyboard">
1102 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
1104 ! <device name="Xlib">
1105 ! <key id="KEY_TV" mapto="leavePlayer" flags="m" />
1106 ! <key id="KEY_STOP" mapto="leavePlayer" flags="m" />
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" />
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" />
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" />
1128 ! <map context="MediaPlayerCueSheetActions">
1129 ! <device name="dreambox remote control (native)">
1130 ! <key id="KEY_0" mapto="toggleMark" flags="m" />
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" />
1136 ! <device name="dreambox ir keyboard">
1137 ! <key id="KEY_TAB" mapto="toggleMark" flags="m" />
1141 ! <map context="VirtualKeyboardActions">
1142 ! <key id="KEY_TEXT" mapto="showVirtualKeyboard" flags="m" />
1145 ! <map context="InfobarTeletextActions">
1146 ! <key id="KEY_TEXT" mapto="startTeletext" flags="m" />
1149 ! <map context="InfobarRdsActions">
1150 ! <key id="KEY_TEXT" mapto="startRassInteractive" flags="m" />
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" />
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" />
1175 ! <map context="ChannelSelectEPGActions">
1176 ! <key id="KEY_INFO" mapto="showEPGList" flags="m" />
1177 ! <key id="KEY_EPG" mapto="showEPGList" flags="m" />
1180 ! <map context="ChannelSelectEditActions">
1181 ! <key id="KEY_MENU" mapto="contextMenu" flags="m" />
1182 ! <key id="KEY_SPACE" mapto="contextMenu" flags="m" />
1185 ! <map context="TvRadioActions">
1186 ! <key id="KEY_TV" mapto="keyTV" flags="m" />
1187 ! <key id="KEY_RADIO" mapto="keyRadio" flags="m" />
1190 ! <map context="TimerEditActions">
1191 ! <key id="KEY_INFO" mapto="log" flags="m" />
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" />
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" />
1217 ! <map context="EventViewEPGActions">
1218 ! <key id="KEY_YELLOW" mapto="openSingleServiceEPG" flags="m" />
1219 ! <key id="KEY_BLUE" mapto="openMultiServiceEPG" flags="m" />
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" />
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" />
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" />
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" />
1263 ! <map context="WindowActions">
1266 ! <map context="HelpActions">
1267 ! <key id="KEY_HELP" mapto="displayHelp" flags="m" />
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" />
1281 ! <map context="StandbyActions">
1282 ! <key id="KEY_POWER" mapto="power" flags="m" />
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" />
1308 ! <map context="CiSelectionActions">
1309 ! <key id="KEY_LEFT" mapto="left" flags="mr" />
1310 ! <key id="KEY_RIGHT" mapto="right" flags="mr" />
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" />
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" />
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" />
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" />
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" />
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" />
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
1383 - // --- cTimeMs ---------------------------------------------------------------
1385 - cTimeMs::cTimeMs(int 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) {
1408 - initialized = true;
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()
1417 - # warning Posix monotonic clock not available
1420 - if (gettimeofday(&t, NULL) == 0)
1421 - return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
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;
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
1446 bool Lock(cMutex *Mutex);
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);
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
1469 libenigma_driver_a_SOURCES += \
1477 libenigma_driver_a_SOURCES += \
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
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();
1520 ! bypass = ISO_13818_AUDIO;
1523 ! bypass = STREAM_AUDIO_AC3;
1526 ! bypass = HDMV_AUDIO_82_DTS;
1535 ! bypass = HDMV_AUDIO_80_PCM;
1538 ! bypass = HDMV_AUDIO_86_DTS_HD_MA;
1542 ! xineLib->setAudioType(pid, bypass);
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)
1574 ! val = AUDIO_MONO_LEFT;
1577 ! val = AUDIO_MONO_RIGHT;
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)");
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;
1622 ! streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
1625 ! streamtype = VIDEO_STREAMTYPE_MPEG1;
1628 ! streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
1631 ! streamtype = VIDEO_STREAMTYPE_VC1;
1634 ! streamtype = VIDEO_STREAMTYPE_VC1_SM;
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();
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);
1679 ! int eDVBVideo::setFastForward(int skip)
1681 ! eDebug("VIDEO_FAST_FORWARD(%d)", skip);
1687 ! int eDVBVideo::getPTS(pts_t &now)
1689 ! cXineLib *xineLib = cXineLib::getInstance();
1691 ! int ret = 0;//xineLib->getPTS(now);
1695 ! eDebug("VIDEO_GET_PTS failed(%m)");
1699 ! eDVBVideo::~eDVBVideo() {}
1701 ! void eDVBVideo::video_event(int)
1703 ! struct video_event evt;
1704 ! eDebug("VIDEO_GET_EVENT");
1706 ! if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
1707 ! eDebug("failed (%m)");
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);
1725 ! eDebug("unhandled DVBAPI Video Event %d", evt.type);
1730 ! DEFINE_REF(eDVBPCR);
1732 ! eDVBPCR::eDVBPCR(int dev) : m_dev(dev) {}
1734 ! int eDVBPCR::startPid(int pid)
1736 ! eDebug("DEMUX_START - pcr");
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");
1758 ! void eDVBTText::stop()
1760 ! eDebug("DEMUX_STOP - ttx");
1763 ! eDVBTText::~eDVBTText() {}
1765 ! DEFINE_REF(eTSMPEGDecoder);
1767 ! int eTSMPEGDecoder::setState()
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)
1791 ! if (m_changed & changeVideo)
1799 ! if (m_changed & changeAudio)
1805 ! if (m_changed & changeText)
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))
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))
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))
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))
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}
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]);
1870 ! m_video->unfreeze();
1872 ! m_video->freeze();
1874 ! if (changed & (changeState|changeAudio) && m_audio)
1877 ! m_audio->unfreeze();
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());
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");
1900 ! fprintf(fp, "%x", delay*90);
1902 ! m_pcm_delay = delay;
1909 ! RESULT eTSMPEGDecoder::setHwAC3Delay(int delay)
1911 ! if ( delay != m_ac3_delay )
1913 ! FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
1916 ! fprintf(fp, "%x", delay*90);
1918 ! m_ac3_delay = delay;
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;
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;
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;
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)
1987 ! m_audio->setChannel(channel);
1988 ! m_audio_channel=channel;
1991 ! eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
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;
2011 ! RESULT eTSMPEGDecoder::setTextPID(int textpid)
2013 ! if (m_textpid != textpid)
2015 ! m_changed |= changeText;
2016 ! m_textpid = textpid;
2021 ! RESULT eTSMPEGDecoder::setSyncMaster(int who)
2026 ! RESULT eTSMPEGDecoder::set()
2028 ! return setState();
2031 ! RESULT eTSMPEGDecoder::play()
2033 ! printf("eTSMPEGDecoder play\n");
2034 ! if (m_state == statePlay)
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)
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))
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))
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)
2085 ! m_state = stateTrickmode;
2086 ! m_changed |= changeState;
2087 ! return setState();
2090 ! RESULT eTSMPEGDecoder::flush()
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 */
2107 ! return m_video->getPTS(pts);
2112 ! if (what == 2) /* audio */
2115 ! return m_audio->getPTS(pts);
2123 ! RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
2125 ! m_radio_pic = filename;
2129 ! RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
2131 ! if (m_decoder == 0)
2133 ! eDebug("showSinglePic %s", filename);
2134 ! int f = open(filename, O_RDONLY);
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;
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)))
2165 ! if ((iframe[3] >> 4) != 0xE) // no pes header
2166 ! write(m_video_clip_fd, pes_header, sizeof(pes_header));
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);
2179 ! eDebug("couldnt open %s", filename);
2185 ! eDebug("only show single pics on first decoder");
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));
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();
2249 ! bypass = ISO_13818_AUDIO;
2252 ! bypass = STREAM_AUDIO_AC3;
2255 ! bypass = HDMV_AUDIO_82_DTS;
2264 ! bypass = HDMV_AUDIO_80_PCM;
2267 ! bypass = HDMV_AUDIO_86_DTS_HD_MA;
2270 ! xineLib->setAudioType(pid, bypass);
2271 ! xineLib->playVideo();
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)
2302 ! val = AUDIO_MONO_LEFT;
2305 ! val = AUDIO_MONO_RIGHT;
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)");
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;
2350 ! streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
2353 ! streamtype = VIDEO_STREAMTYPE_MPEG1;
2356 ! streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
2359 ! streamtype = VIDEO_STREAMTYPE_VC1;
2362 ! streamtype = VIDEO_STREAMTYPE_VC1_SM;
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();
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);
2411 ! int eDVBVideo::setFastForward(int skip)
2413 ! eDebug("VIDEO_FAST_FORWARD(%d)", skip);
2419 ! int eDVBVideo::getPTS(pts_t &now)
2421 ! cXineLib *xineLib = cXineLib::getInstance();
2423 ! int ret = 0;//xineLib->getPTS(now);
2427 ! eDebug("VIDEO_GET_PTS failed(%m)");
2431 ! eDVBVideo::~eDVBVideo() {}
2433 ! void eDVBVideo::video_event(int)
2435 ! struct video_event evt;
2436 ! eDebug("VIDEO_GET_EVENT");
2438 ! if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
2439 ! eDebug("failed (%m)");
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);
2457 ! eDebug("unhandled DVBAPI Video Event %d", evt.type);
2462 ! DEFINE_REF(eDVBPCR);
2464 ! eDVBPCR::eDVBPCR(int dev) : m_dev(dev) {}
2466 ! int eDVBPCR::startPid(int pid)
2468 ! eDebug("DEMUX_START - pcr");
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");
2490 ! void eDVBTText::stop()
2492 ! eDebug("DEMUX_STOP - ttx");
2495 ! eDVBTText::~eDVBTText() {}
2497 ! DEFINE_REF(eTSMPEGDecoder);
2499 ! int eTSMPEGDecoder::setState()
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)
2523 ! if (m_changed & changeVideo)
2531 ! if (m_changed & changeAudio)
2537 ! if (m_changed & changeText)
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))
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))
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))
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))
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}
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]);
2602 ! m_video->unfreeze();
2604 ! m_video->freeze();
2606 ! if (changed & (changeState|changeAudio) && m_audio)
2609 ! m_audio->unfreeze();
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());
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");
2632 ! fprintf(fp, "%x", delay*90);
2634 ! m_pcm_delay = delay;
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");
2648 ! fprintf(fp, "%x", delay*90);
2650 ! m_ac3_delay = delay;
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;
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;
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;
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)
2719 ! m_audio->setChannel(channel);
2720 ! m_audio_channel=channel;
2723 ! eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
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;
2743 ! RESULT eTSMPEGDecoder::setTextPID(int textpid)
2745 ! if (m_textpid != textpid)
2747 ! m_changed |= changeText;
2748 ! m_textpid = textpid;
2753 ! RESULT eTSMPEGDecoder::setSyncMaster(int who)
2758 ! RESULT eTSMPEGDecoder::set()
2760 ! return setState();
2763 ! RESULT eTSMPEGDecoder::play()
2765 ! printf("eTSMPEGDecoder play\n");
2766 ! if (m_state == statePlay)
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)
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))
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))
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)
2817 ! m_state = stateTrickmode;
2818 ! m_changed |= changeState;
2819 ! return setState();
2822 ! RESULT eTSMPEGDecoder::flush()
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 */
2839 ! return m_video->getPTS(pts);
2844 ! if (what == 2) /* audio */
2847 ! return m_audio->getPTS(pts);
2855 ! RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
2857 ! m_radio_pic = filename;
2861 ! RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
2863 ! if (m_decoder == 0)
2865 ! eDebug("showSinglePic %s", filename);
2866 ! int f = open(filename, O_RDONLY);
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;
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)))
2897 ! if ((iframe[3] >> 4) != 0xE) // no pes header
2898 ! write(m_video_clip_fd, pes_header, sizeof(pes_header));
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);
2911 ! eDebug("couldnt open %s", filename);
2917 ! eDebug("only show single pics on first decoder");
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));
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
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);
2960 ! int m_dev, m_is_freezed;
2962 ! enum { aMPEG, aAC3, aDTS, aAAC, aAACHE, aLPCM, aDTSHD };
2963 ! eDVBAudio(int dev);
2964 ! enum { aMonoLeft, aStereo, aMonoRight };
2965 ! void setChannel(int channel);
2967 ! int startPid(int pid, int type);
2972 ! int getPTS(pts_t &now);
2973 ! virtual ~eDVBAudio();
2976 ! class eDVBVideo: public iObject, public Object
2978 ! DECLARE_REF(eDVBVideo);
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;
2988 ! enum { MPEG2, MPEG4_H264, MPEG1, MPEG4_Part2, VC1, VC1_SM };
2989 ! eDVBVideo(int dev);
2991 ! int startPid(int pid, int type=MPEG2);
2995 ! int setSlowMotion(int repeat);
2996 ! int setFastForward(int skip);
2998 ! int getPTS(pts_t &now);
2999 ! virtual ~eDVBVideo();
3002 ! class eDVBPCR: public iObject
3004 ! DECLARE_REF(eDVBPCR);
3009 ! int startPid(int pid);
3011 ! virtual ~eDVBPCR();
3014 ! class eDVBTText: public iObject
3016 ! DECLARE_REF(eDVBTText);
3020 ! eDVBTText(int dev);
3021 ! int startPid(int pid);
3023 ! virtual ~eDVBTText();
3026 ! class eTSMPEGDecoder: public Object, public iTSMPEGDecoder
3028 ! DECLARE_REF(eTSMPEGDecoder);
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;
3047 ! int m_changed, m_decoder;
3049 ! int m_ff_sm_ratio;
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
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);
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
3088 ! stateDecoderFastForward,
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 */
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);
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);
3129 ! int m_dev, m_is_freezed;
3131 ! enum { aMPEG, aAC3, aDTS, aAAC, aAACHE, aLPCM, aDTSHD };
3132 ! eDVBAudio(int dev);
3133 ! enum { aMonoLeft, aStereo, aMonoRight };
3134 ! void setChannel(int channel);
3136 ! int startPid(int pid, int type);
3141 ! int getPTS(pts_t &now);
3142 ! virtual ~eDVBAudio();
3145 ! class eDVBVideo: public iObject, public Object
3147 ! DECLARE_REF(eDVBVideo);
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;
3157 ! enum { MPEG2, MPEG4_H264, MPEG1, MPEG4_Part2, VC1, VC1_SM };
3158 ! eDVBVideo(int dev);
3160 ! int startPid(int pid, int type=MPEG2);
3164 ! int setSlowMotion(int repeat);
3165 ! int setFastForward(int skip);
3167 ! int getPTS(pts_t &now);
3168 ! virtual ~eDVBVideo();
3171 ! class eDVBPCR: public iObject
3173 ! DECLARE_REF(eDVBPCR);
3178 ! int startPid(int pid);
3180 ! virtual ~eDVBPCR();
3183 ! class eDVBTText: public iObject
3185 ! DECLARE_REF(eDVBTText);
3189 ! eDVBTText(int dev);
3190 ! int startPid(int pid);
3192 ! virtual ~eDVBTText();
3195 ! class eTSMPEGDecoder: public Object, public iTSMPEGDecoder
3197 ! DECLARE_REF(eTSMPEGDecoder);
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;
3216 ! int m_changed, m_decoder;
3218 ! int m_ff_sm_ratio;
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
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);
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
3257 ! stateDecoderFastForward,
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 */
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);
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
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());
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);
3319 ! } while (in.good());
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"))
3333 ! if (!strcasecmp(cvalue, "false"))
3336 ! return defaultValue;
3339 ! gXlibDC::gXlibDC() : m_pump(eApp, 1)
3341 ! double res_h, res_v;
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);
3356 ! if(!XInitThreads())
3358 ! eFatal("XInitThreads() failed\n");
3362 ! if((display = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
3363 ! eFatal("XOpenDisplay() failed.\n");
3367 ! screen = XDefaultScreen(display);
3370 ! width = DisplayWidth( display, screen );
3371 ! height = DisplayHeight( display, screen );
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;
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
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()
3421 ! thread_stop = true;
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);
3444 ! driver->keyPressed(event);
3447 ! void gXlibDC::pumpEvent(const XKeyEvent &event)
3449 ! switch (event.type) {
3452 ! switch (event.keycode) {
3454 ! if (event.type==KeyPress) {
3455 ! fullscreen_switch();
3459 ! if (event.type==KeyPress) {
3460 ! eDebug("Enigma2 Quit");
3461 ! extern void quitMainloop(int exit_code);
3473 ! /*void gSDLDC::pushEvent(enum event code, void *data1, void *data2)
3477 ! event.type = SDL_USEREVENT;
3478 ! event.user.code = code;
3479 ! event.user.data1 = data1;
3480 ! event.user.data2 = data2;
3482 ! SDL_PushEvent(&event);
3485 ! void gXlibDC::exec(const gOpcode *o)
3487 ! switch (o->opcode)
3489 ! case gOpcode::flush:
3491 ! xineLib->showOsd();
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) {
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() {
3532 ! width = DisplayWidth( display, screen );
3533 ! height = DisplayHeight( display, screen );
3535 ! width = windowWidth;
3536 ! height = windowHeight;
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);
3554 ! XResizeWindow(display, window, windowWidth, windowHeight);
3558 ! xineLib->updateWindowSize(width, height);
3559 ! xineLib->showOsd();
3562 ! void gXlibDC::fullscreen_switch() {
3563 ! printf("FULLSCREEN EVENT\n");
3565 ! updateWindowState();
3568 ! void gXlibDC::evFlip()
3570 ! //SDL_Flip(m_screen);
3573 ! void gXlibDC::thread()
3577 ! int x11_fd = ConnectionNumber(display);
3578 ! thread_stop = false;
3580 ! struct timeval tv;
3583 ! while (!thread_stop) {
3585 ! FD_SET(x11_fd, &in_fds);
3587 ! tv.tv_usec = 100000;
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)
3602 ! XKeyEvent& xKeyEvent = (XKeyEvent&)event;
3603 ! m_pump.send(xKeyEvent);
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);
3616 ! xineLib->showOsd();
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)
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");
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());
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);
3675 ! } while (in.good());
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"))
3689 ! if (!strcasecmp(cvalue, "false"))
3692 ! return defaultValue;
3695 ! gXlibDC::gXlibDC() : m_pump(eApp, 1)
3697 ! double res_h, res_v;
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);
3712 ! if(!XInitThreads())
3714 ! eFatal("XInitThreads() failed\n");
3718 ! if((display = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
3719 ! eFatal("XOpenDisplay() failed.\n");
3723 ! screen = XDefaultScreen(display);
3726 ! width = DisplayWidth( display, screen );
3727 ! height = DisplayHeight( display, screen );
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;
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
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()
3777 ! thread_stop = true;
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);
3800 ! driver->keyPressed(event);
3803 ! void gXlibDC::pumpEvent(const XKeyEvent &event)
3805 ! switch (event.type) {
3808 ! switch (event.keycode) {
3810 ! if (event.type==KeyPress) {
3811 ! fullscreen_switch();
3815 ! if (event.type==KeyPress) {
3816 ! eDebug("Enigma2 Quit");
3817 ! extern void quitMainloop(int exit_code);
3830 ! /*void gSDLDC::pushEvent(enum event code, void *data1, void *data2)
3834 ! event.type = SDL_USEREVENT;
3835 ! event.user.code = code;
3836 ! event.user.data1 = data1;
3837 ! event.user.data2 = data2;
3839 ! SDL_PushEvent(&event);
3842 ! void gXlibDC::exec(const gOpcode *o)
3844 ! switch (o->opcode)
3846 ! case gOpcode::flush:
3848 ! xineLib->showOsd();
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) {
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() {
3889 ! width = DisplayWidth( display, screen );
3890 ! height = DisplayHeight( display, screen );
3892 ! width = windowWidth;
3893 ! height = windowHeight;
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);
3911 ! XResizeWindow(display, window, windowWidth, windowHeight);
3915 ! xineLib->updateWindowSize(width, height);
3916 ! xineLib->showOsd();
3919 ! void gXlibDC::fullscreen_switch() {
3920 ! printf("FULLSCREEN EVENT\n");
3922 ! updateWindowState();
3925 ! void gXlibDC::evFlip()
3927 ! //SDL_Flip(m_screen);
3930 ! void gXlibDC::thread()
3934 ! int x11_fd = ConnectionNumber(display);
3935 ! thread_stop = false;
3937 ! struct timeval tv;
3940 ! while (!thread_stop) {
3942 ! FD_SET(x11_fd, &in_fds);
3944 ! tv.tv_usec = 100000;
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)
3959 ! XKeyEvent& xKeyEvent = (XKeyEvent&)event;
3960 ! m_pump.send(xKeyEvent);
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);
3973 ! xineLib->showOsd();
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)
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
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";
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);
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);
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)) ) {
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);
4060 ! m_windowAspectRatio = 0;
4068 ! cXineLib::~cXineLib() {
4073 ! xine_stop(stream);
4074 ! xine_close(stream);
4078 ! xine_event_dispose_queue(xine_queue);
4082 ! _x_demux_flush_engine(stream);
4084 ! xine_dispose(stream);
4089 ! xine_close_audio_driver(xine, ao_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) {
4109 ! osdHeight = height;
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");
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;
4153 ! event.type = XINE_EVENT_SET_VIDEO_STREAMTYPE;
4154 ! event.data = &videoData;
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");
4190 ! case XINE_EVENT_NBC_STATS:
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();
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);
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;
4230 ! printf("xine_event_handler(): event->type: %d\n", event->type);
4235 ! void cXineLib::pumpEvent(const iTSMPEGDecoder::videoEvent &event)
4240 ! int cXineLib::getVideoWidth()
4245 ! int cXineLib::getVideoHeight()
4250 ! int cXineLib::getVideoFrameRate()
4252 ! return m_framerate;
4255 ! int cXineLib::getVideoAspect()
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;
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);
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;
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);
4348 ! case XINE_VO_ASPECT_4_3:
4349 ! printf("XINE_VO_ASPECT_4_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4350 ! switch (m_aspect) {
4352 ! printf("m_policy43 %d\n", m_policy43);
4353 ! switch (m_policy43) {
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);
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);
4372 ! printf("m_policy169 %d\n", m_policy169);
4373 ! switch (m_policy169) {
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);
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);
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);
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);
4402 ! case XINE_VO_ASPECT_ANAMORPHIC: //16:9
4403 ! printf("XINE_VO_ASPECT_ANAMORPHIC (16:9) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4404 ! switch (m_aspect) {
4406 ! switch (m_policy43) {
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);
4413 ! case 1: // nonlinear
4414 ! printf("4:3 NONLINEAR\n");
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);
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");
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);
4436 ! printf("m_policy169 %d\n", m_policy169);
4437 ! switch (m_policy169) {
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);
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);
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);
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";
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);
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);
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)) ) {
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);
4524 ! m_windowAspectRatio = 0;
4532 ! cXineLib::~cXineLib() {
4537 ! xine_stop(stream);
4538 ! xine_close(stream);
4542 ! xine_event_dispose_queue(xine_queue);
4546 ! _x_demux_flush_engine(stream);
4548 ! xine_dispose(stream);
4553 ! xine_close_audio_driver(xine, ao_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) {
4575 ! osdHeight = height;
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);
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;
4632 ! event.type = XINE_EVENT_SET_VIDEO_STREAMTYPE;
4633 ! event.data = &videoData;
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) {
4653 ! if (!xine_open(stream, mrl))
4655 ! eWarning("xine_open failed!");
4659 ! if (!xine_play(stream, 0, 0))
4661 ! eWarning("xine_play failed!");
4664 ! videoPlayed = true;
4668 ! cXineLib::VideoPause()
4670 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
4676 ! cXineLib::VideoResume()
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);
4688 ! cXineLib::VideoGeriT(pts_t Sar)
4689 ! {// 10 saniye Geri Sarma
4691 ! xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
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);
4702 ! cXineLib::VideoIleriF()
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);
4714 ! cXineLib::VideoPosisyon()
4716 ! xine_get_pos_length (stream, &VposStream, &Vpos, &Vlength);
4725 ! XINE_FINE_SPEED_NORMAL
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");
4749 ! case XINE_EVENT_NBC_STATS:
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();
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);
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;
4789 ! printf("xine_event_handler(): event->type: %d\n", event->type);
4794 ! void cXineLib::pumpEvent(const iTSMPEGDecoder::videoEvent &event)
4799 ! int cXineLib::getVideoWidth()
4804 ! int cXineLib::getVideoHeight()
4809 ! int cXineLib::getVideoFrameRate()
4811 ! return m_framerate;
4814 ! int cXineLib::getVideoAspect()
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;
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);
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;
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);
4907 ! case XINE_VO_ASPECT_4_3:
4908 ! printf("XINE_VO_ASPECT_4_3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4909 ! switch (m_aspect) {
4911 ! printf("m_policy43 %d\n", m_policy43);
4912 ! switch (m_policy43) {
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);
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);
4931 ! printf("m_policy169 %d\n", m_policy169);
4932 ! switch (m_policy169) {
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);
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);
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);
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);
4961 ! case XINE_VO_ASPECT_ANAMORPHIC: //16:9
4962 ! printf("XINE_VO_ASPECT_ANAMORPHIC (16:9) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
4963 ! switch (m_aspect) {
4965 ! switch (m_policy43) {
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);
4972 ! case 1: // nonlinear
4973 ! printf("4:3 NONLINEAR\n");
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);
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");
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);
4995 ! printf("m_policy169 %d\n", m_policy169);
4996 ! switch (m_policy169) {
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);
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);
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
5034 ! #ifndef __lib_gdi_xineLib_h
5035 ! #define __lib_gdi_xineLib_h
5037 ! #include <lib/gdi/gpixmap.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);
5047 ! static cXineLib *instance;
5050 ! xine_stream_t *stream;
5051 ! xine_video_port_t *vo_port;
5052 ! xine_audio_port_t *ao_port;
5054 ! xine_event_queue_t *xine_queue;
5056 ! xine_streamtype_data_t videoData, audioData;
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);
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);
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);
5115 ! #ifndef __lib_gdi_xineLib_h
5116 ! #define __lib_gdi_xineLib_h
5118 ! #include <lib/gdi/gpixmap.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);
5128 ! static cXineLib *instance;
5131 ! xine_stream_t *stream;
5132 ! xine_video_port_t *vo_port;
5133 ! xine_audio_port_t *ao_port;
5135 ! xine_event_queue_t *xine_queue;
5137 ! xine_streamtype_data_t videoData, audioData;
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);
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);
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);
5178 ! int VideoResume();
5179 ! int VideoPosisyon();
5180 ! int VideoIleriF();
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);
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
5212 ! #include <lib/base/eerror.h>
5213 ! #include <lib/base/object.h>
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!
5245 ! class eStaticServiceDVBInformation: public iStaticServiceInformation
5247 ! DECLARE_REF(eStaticServiceDVBInformation);
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);
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));
5273 ! ePtr<iStaticServiceInformation> service_info;
5274 ! if (!service_center->info(parent, service_info))
5276 ! if (!service_info->getName(parent, name))
5277 ! name=buildShortName(name) + " - ";
5290 ! int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
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!!");
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);
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;
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))
5336 ! if (!feparm->getSystem(system))
5338 ! ePyObject dict = PyDict_New();
5341 ! case iDVBFrontend::feSatellite:
5343 ! eDVBFrontendParametersSatellite s;
5344 ! feparm->getDVBS(s);
5345 ! PutSatelliteDataToDict(dict, s);
5348 ! case iDVBFrontend::feTerrestrial:
5350 ! eDVBFrontendParametersTerrestrial t;
5351 ! feparm->getDVBT(t);
5352 ! PutTerrestrialDataToDict(dict, t);
5355 ! case iDVBFrontend::feCable:
5357 ! eDVBFrontendParametersCable c;
5358 ! feparm->getDVBC(c);
5359 ! PutCableDataToDict(dict, c);
5363 ! eDebug("unknown frontend type %d", system);
5378 ! DEFINE_REF(eStaticServiceDVBBouquetInformation);
5380 ! RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
5382 ! ePtr<iDVBChannelList> db;
5383 ! ePtr<eDVBResourceManager> res;
5386 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
5388 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
5391 ! if ((err = res->getChannelList(db)) != 0)
5393 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
5397 ! eBouquet *bouquet=0;
5398 ! if ((err = db->getBouquet(ref, bouquet)) != 0)
5400 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
5404 ! if ( bouquet && bouquet->m_bouquet_name.length() )
5406 ! name = bouquet->m_bouquet_name;
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!");
5426 ! if (res->getChannelList(db))
5428 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no channel list!");
5432 ! eBouquet *bouquet=0;
5433 ! if (db->getBouquet(ref, bouquet))
5435 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. getBouquet failed!");
5439 ! int prio_order = eDVBFrontend::getTypePriorityOrder();
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
5453 ! ((const eServiceReferenceDVB&)*it).getChannelID(chid);
5454 ! int tmp=res->canAllocateChannel(chid, chid_ignore, simulate);
5459 ! case 30000: // cached DVB-T channel
5460 ! case 1: // DVB-T frontend
5461 ! tmp = prio_map[prio_order][2];
5463 ! case 40000: // cached DVB-C channel
5465 ! tmp = prio_map[prio_order][1];
5468 ! tmp = prio_map[prio_order][0];
5473 ! m_playable_service = *it;
5480 ! m_playable_service = eServiceReference();
5484 ! int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
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;
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);
5512 ! DEFINE_REF(eStaticServiceDVBPVRInformation);
5514 ! eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &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())
5525 ! else if (!m_parser.m_name.empty())
5526 ! name = m_parser.m_name;
5530 ! size_t n = name.rfind('/');
5531 ! if (n != std::string::npos)
5532 ! name = name.substr(n + 1);
5537 ! int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
5539 ! ASSERT(ref == m_ref);
5541 ! eDVBTSTools tstools;
5544 ! stat(ref.path.c_str(), &s);
5546 ! if (tstools.openFile(ref.path.c_str(), 1))
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()))
5557 ! /* otherwise, re-calc length and update meta file */
5559 ! if (tstools.calcLen(len))
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)
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;
5582 ! return iServiceInformation::resNA;
5584 ! return iServiceInformation::resNA;
5588 ! std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int 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;
5603 ! PyObject *eStaticServiceDVBPVRInformation::getInfoObject(const eServiceReference &r, int what)
5607 ! case iServiceInformation::sFileSize:
5608 ! return PyLong_FromLongLong(m_parser.m_filesize);
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);
5622 ! if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
5632 ! class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
5634 ! DECLARE_REF(eDVBPVRServiceOfflineOperations);
5635 ! eServiceReferenceDVB m_ref;
5637 ! eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
5639 ! RESULT deleteFromDisk(int simulate);
5640 ! RESULT getListOfFilenames(std::list<std::string> &);
5644 ! DEFINE_REF(eDVBPVRServiceOfflineOperations);
5646 ! eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
5650 ! RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
5656 ! std::list<std::string> res;
5657 ! if (getListOfFilenames(res))
5660 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
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());
5668 ! eraser->erase(i->c_str());
5670 ! ::unlink(i->c_str());
5677 ! RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
5680 ! res.push_back(m_ref.path);
5682 ! // handling for old splitted recordings (enigma 1)
5687 ! snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
5689 ! if (stat(buf, &s) < 0)
5691 ! res.push_back(buf);
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");
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);
5716 ! int err = f.open(m_ref.path.c_str(), 0);
5721 ! off_t length = f.length();
5722 ! unsigned char buffer[188*256*4];
5725 ! eDebug("at %08llx / %08llx (%d %%)", offset, length, (int)(offset * 100 / length));
5726 ! int r = f.read(offset, buffer, sizeof(buffer));
5732 ! parser.parseData(offset, buffer, r);
5741 ! DEFINE_REF(eServiceFactoryDVB)
5743 ! eServiceFactoryDVB::eServiceFactoryDVB()
5745 ! ePtr<eServiceCenter> sc;
5747 ! eServiceCenter::getPrivInstance(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);
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;
5785 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
5787 ! eDebug("no resource manager");
5790 ! if ((err = res->getChannelList(db)) != 0)
5792 ! eDebug("no channel list");
5796 ! ePtr<eDVBChannelQuery> q;
5798 ! if (!m_parent.path.empty())
5800 ! eDVBChannelQuery::compile(q, m_parent.path);
5803 ! eDebug("compile query failed");
5808 ! if ((err = db->startQuery(m_query, q, m_parent)) != 0)
5810 ! eDebug("startQuery failed");
5817 ! RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
5819 ! eServiceReferenceDVB ref;
5824 ! while (!m_query->getNextResult(ref))
5825 ! list.push_back(ref);
5828 ! list.sort(iListableServiceCompare(this));
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
5845 ! // unknown format string chars are returned as python None values !
5846 ! PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
5849 ! std::list<eServiceReference> tmplist;
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)
5876 ! case 'R': // service reference (swig)object
5877 ! tmp = NEW_eServiceReference(ref);
5879 ! case 'C': // service reference compare string
5880 ! tmp = PyString_FromString(ref.toCompareString().c_str());
5882 ! case 'S': // service reference string
5883 ! tmp = PyString_FromString(ref.toString().c_str());
5885 ! case 'N': // service name
5886 ! if (service_center)
5888 ! service_center->info(ref, sptr);
5892 ! sptr->getName(ref, name);
5894 ! // filter short name brakets
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());
5906 ! tmp = PyString_FromString("<n/a>");
5908 ! case 'n': // short service name
5909 ! if (service_center)
5911 ! service_center->info(ref, sptr);
5915 ! sptr->getName(ref, name);
5916 ! name = buildShortName(name);
5917 ! if (name.length())
5918 ! tmp = PyString_FromString(name.c_str());
5922 ! tmp = PyString_FromString("<n/a>");
5928 ! Py_INCREF(Py_None);
5935 ! PyTuple_SET_ITEM(tuple, i, tmp);
5937 ! PyList_SET_ITEM(ret, cnt, tmp);
5941 ! PyList_SET_ITEM(ret, cnt, tuple);
5944 ! return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
5947 ! RESULT eDVBServiceList::getNext(eServiceReference &ref)
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))
5965 ! if (db->getBouquet(m_parent, m_bouquet) != 0)
5976 ! RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
5980 ! return m_bouquet->addService(ref, before);
5983 ! RESULT eDVBServiceList::removeService(eServiceReference &ref)
5987 ! return m_bouquet->removeService(ref);
5990 ! RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
5994 ! return m_bouquet->moveService(ref, pos);
5997 ! RESULT eDVBServiceList::flushChanges()
6001 ! return m_bouquet->flushChanges();
6004 ! RESULT eDVBServiceList::setListName(const std::string &name)
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);
6017 ! // check resources...
6018 ! ptr = new eDVBServicePlay(ref, service);
6022 ! RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
6024 ! if (ref.path.empty())
6026 ! ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
6035 ! RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
6037 ! ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
6038 ! if (list->startQuery())
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;
6066 ! /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
6072 ! RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
6074 ! if (ref.path.empty())
6080 ! ptr = new eDVBPVRServiceOfflineOperations(ref);
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;
6093 ! eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
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
6101 ! ePtr<iDVBChannelList> db;
6102 ! ePtr<eDVBResourceManager> res;
6105 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
6107 ! eDebug("no resource manager");
6110 ! if ((err = res->getChannelList(db)) != 0)
6112 ! eDebug("no channel list");
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!");
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)
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);
6153 ! xineLib = cXineLib::getInstance();
6154 ! xine_connection = CONNECT(xineLib->m_event, eDVBServicePlay::video_event);
6157 ! eDVBServicePlay::~eDVBServicePlay()
6161 ! eDVBMetaParser meta;
6162 ! int ret=meta.parseFile(m_reference.path);
6166 ! meta.m_service_data="";
6167 ! sprintf(tmp, "f:%x", m_dvb_service->m_flags);
6168 ! meta.m_service_data += tmp;
6170 ! for (int x=0; x < eDVBService::cacheMax; ++x)
6172 ! int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
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()
6192 ! ePtr<eServiceEvent> m_event_now, m_event_next;
6193 ! getEvent(m_event_now, 0);
6194 ! getEvent(m_event_next, 1);
6197 ! eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
6199 ! eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
6201 ! m_event((iPlayableService*)this, evUpdatedEventInfo);
6204 ! void eDVBServicePlay::serviceEvent(int event)
6206 ! m_tune_state = 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();
6218 ! sid = ref.getServiceID().get();
6219 ! if ( ref.getParentTransportStreamID().get() &&
6220 ! ref.getParentTransportStreamID() != ref.getTransportStreamID() )
6221 ! m_event_handler.startOther(m_demux, sid);
6223 ! m_event_handler.start(m_demux, sid);
6225 ! m_event((iPlayableService*)this, evTunedIn);
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);
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)
6246 ! if (m_first_program_info & 1 && m_is_pvr)
6248 ! m_first_program_info &= ~1;
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);
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");
6272 ! case eDVBServicePMTHandler::eventPreStart:
6275 ! case eDVBServicePMTHandler::eventEOF:
6276 ! m_event((iPlayableService*)this, evEOF);
6278 ! case eDVBServicePMTHandler::eventSOF:
6279 ! m_event((iPlayableService*)this, evSOF);
6284 ! void eDVBServicePlay::serviceEventTimeshift(int event)
6288 ! case eDVBServicePMTHandler::eventNewProgramInfo:
6289 ! eDebug("eventNewProgramInfo TS");
6290 ! if (m_timeshift_active)
6293 ! if (m_first_program_info & 2)
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);
6304 ! m_cue->setSkipmode(m_skipmode * 90000); /* convert to 90000 per second */
6305 ! if (m_fastforward != 1)
6306 ! m_decoder->setFastForward(m_fastforward);
6308 ! m_decoder->setTrickmode();
6312 ! m_first_program_info &= ~2;
6314 ! m_event((iPlayableService*)this, evUpdatedInfo);
6317 ! case eDVBServicePMTHandler::eventSOF:
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);
6342 ! m_event((iPlayableService*)this, evSOF);
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");
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);
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);
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. */
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();
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);
6408 ! /* inject EIT if there is a stored one */
6409 ! std::string filename = service.path;
6410 ! filename.erase(filename.length()-2, 2);
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);
6424 ! RESULT eDVBServicePlay::stop()
6426 ! printf("eDVBServicePlay::stop\n");
6427 ! /* add bookmark for last play position */
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();
6445 ! if (getLength(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. */
6464 ! printf("close(m_fd_dst) %d\n", m_fd_dst);
6468 ! m_service_handler_timeshift.free();
6469 ! m_service_handler.free();
6471 ! if (m_is_pvr && m_cuesheet_changed)
6474 ! /* save cuesheet only when main file is accessible. */
6475 ! if (!::stat(m_reference.path.c_str(), &s))
6478 ! m_event((iPlayableService*)this, evStopped);
6482 ! RESULT eDVBServicePlay::setTarget(int target)
6484 ! m_is_primary = !target;
6488 ! RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
6490 ! connection = new eConnection((iPlayableService*)this, m_event.connect(event));
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))
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);
6516 ! m_slowmotion = ratio;
6517 ! return m_decoder->setSlowMotion(ratio);
6523 ! RESULT eDVBServicePlay::setFastForward(int ratio)
6525 ! eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
6527 ! return setFastForward_internal(ratio);
6530 ! RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
6532 ! int skipmode, ffratio, ret = 0;
6539 ! } else if (ratio > 0)
6543 ! } else if (!ratio)
6547 ! } else // if (ratio < 0)
6553 ! if (m_skipmode != skipmode)
6555 ! eDebug("setting cue skipmode to %d", skipmode);
6557 ! m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
6560 ! m_skipmode = skipmode;
6563 ! eDebug("trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
6565 ! m_fastforward = ffratio;
6571 ! ; /* return m_decoder->play(); is done in caller*/
6572 ! else if (ffratio != 1)
6573 ! ret = m_decoder->setFastForward(ffratio);
6575 ! ret = m_decoder->setTrickmode();
6578 ! eDebug("final seek after trickplay ret %d", seekTo(pos));
6583 ! RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
6585 ! if (m_is_pvr || m_timeshift_enabled)
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))
6603 ! return pvr_channel->getLength(len);
6606 ! RESULT eDVBServicePlay::pause()
6608 ! eDebug("eDVBServicePlay::pause");
6609 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
6614 ! return m_decoder->pause();
6619 ! RESULT eDVBServicePlay::unpause()
6621 ! eDebug("eDVBServicePlay::unpause");
6622 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
6627 ! return m_decoder->play();
6632 ! RESULT eDVBServicePlay::seekTo(pts_t to)
6634 ! eDebug("eDVBServicePlay::seekTo: jump %lld", to);
6636 ! if (!m_decode_demux)
6639 ! ePtr<iDVBPVRChannel> pvr_channel;
6641 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
6647 ! m_cue->seekTo(0, to);
6648 ! m_dvb_subtitle_pages.clear();
6649 ! m_subtitle_pages.clear();
6654 ! RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
6656 ! eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
6658 ! if (!m_decode_demux)
6661 ! ePtr<iDVBPVRChannel> pvr_channel;
6663 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
6668 ! /* HACK until we have skip-AP api */
6669 ! if ((to > 0) && (to < 100))
6677 ! m_cue->seekTo(mode, to);
6678 ! m_dvb_subtitle_pages.clear();
6679 ! m_subtitle_pages.clear();
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))
6692 ! r = xineLib->getPTS(pos);
6697 ! return pvr_channel->getCurrentPosition(m_decode_demux, pos, 1);
6700 ! RESULT eDVBServicePlay::setTrickmode(int trick)
6702 ! /* currently unimplemented */
6706 ! RESULT eDVBServicePlay::isCurrentlySeekable()
6711 ! ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
6712 ! if (m_decoder->getVideoProgressive() == -1)
6718 ! RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
6724 ! RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
6730 ! RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
6736 ! RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
6742 ! RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
6748 ! RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
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");
6762 ! tspath.append("/");
6763 ! /* we need enough diskspace */
6765 ! if (statfs(tspath.c_str(), &fs) < 0)
6767 ! eDebug("statfs failed!");
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)");
6783 ! RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
6794 ! RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
6800 ! RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
6806 ! RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
6812 ! RESULT eDVBServicePlay::getName(std::string &name)
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);
6825 ! else if (!m_reference.name.empty())
6826 ! eStaticServiceDVBInformation().getName(m_reference, name);
6828 ! name = "DVB service";
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;
6853 ! case sVideoHeight:
6855 ! // return m_decoder->getVideoHeight();
6856 ! return xineLib->getVideoHeight();
6860 ! // return m_decoder->getVideoWidth();
6861 ! return xineLib->getVideoWidth();
6865 ! // return m_decoder->getVideoFrameRate();
6866 ! return xineLib->getVideoFrameRate();
6868 ! case sProgressive:
6870 ! return m_decoder->getVideoProgressive();
6875 ! // aspect = m_decoder->getVideoAspect();
6876 ! int aspect = xineLib->getVideoAspect();
6878 ! if (aspect == -1 && no_program_info)
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())
6893 ! case 1: // 4:3 SD PAL
6895 ! case 3: // 16:9 SD PAL
6896 ! case 4: // > 16:9 PAL
6897 ! case 5: // 4:3 SD NTSC
6899 ! case 7: // 16:9 SD NTSC
6900 ! case 8: // > 16:9 NTSC
6903 ! case 9: // 4:3 HD PAL
6905 ! case 0xB: // 16:9 HD PAL
6906 ! case 0xC: // > 16:9 HD PAL
6907 ! case 0xD: // 4:3 HD NTSC
6909 ! case 0xF: // 16:9 HD NTSC
6910 ! case 0x10: // > 16:9 HD PAL
6911 ! return data->getComponentType();
6921 ! case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
6923 ! if (m_dvb_service)
6925 ! int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
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;
6932 ! if (m_dvb_service)
6934 ! int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
6937 ! apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
6941 ! if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
6943 ! if (m_dvb_service)
6945 ! int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
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;
6965 ! std::string eDVBServicePlay::getInfoString(int w)
6970 ! if (!m_dvb_service) return "";
6971 ! return m_dvb_service->m_provider_name;
6973 ! return m_reference.toString();
6977 ! return iServiceInformation::getInfoString(w);
6980 ! PyObject *eDVBServicePlay::getInfoObject(int w)
6985 ! return m_service_handler.getCaIds();
6987 ! return m_service_handler.getCaIds(true);
6988 ! case sTransponderData:
6989 ! return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
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))
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))
7012 ! int max = program.audioStreams.size();
7015 ! for (i = 0; i < max; ++i)
7016 ! if (program.audioStreams[i].pid == m_current_audio_pid)
7022 ! RESULT eDVBServicePlay::selectTrack(unsigned int i)
7024 ! int ret = selectAudioStream(i);
7026 ! if (m_decoder->set())
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))
7040 ! if (i >= program.audioStreams.size())
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";
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;
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))
7086 ! if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
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");
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.)
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);
7161 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
7162 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
7166 ! h.resetCachedProgram();
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)
7180 ! if (m_dvb_service)
7181 ! m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
7183 ! m_decoder->setAudioChannel(i);
7187 ! std::string eDVBServicePlay::getText(int x)
7189 ! if (m_rds_decoder)
7193 ! return convertLatin1UTF8(m_rds_decoder->getRadioText());
7195 ! return convertLatin1UTF8(m_rds_decoder->getRtpText());
7200 ! void eDVBServicePlay::rdsDecoderEvent(int what)
7204 ! case eDVBRdsDecoder::RadioTextChanged:
7205 ! m_event((iPlayableService*)this, evUpdatedRadioText);
7207 ! case eDVBRdsDecoder::RtpTextChanged:
7208 ! m_event((iPlayableService*)this, evUpdatedRtpText);
7210 ! case eDVBRdsDecoder::RassInteractivePicMaskChanged:
7211 ! m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
7213 ! case eDVBRdsDecoder::RecvRassSlidePic:
7214 ! m_event((iPlayableService*)this, evUpdatedRassSlidePic);
7219 ! void eDVBServicePlay::showRassSlidePicture()
7221 ! if (m_rds_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());
7229 ! eDebug("empty filename for rass slide picture received!!");
7232 ! eDebug("no MPEG Decoder to show iframes avail");
7235 ! eDebug("showRassSlidePicture called.. but not decoder");
7238 ! void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
7240 ! if (m_rds_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());
7248 ! eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
7251 ! eDebug("no MPEG Decoder to show iframes avail");
7254 ! eDebug("showRassInteractivePic called.. but not decoder");
7257 ! ePyObject eDVBServicePlay::getRassInteractiveMask()
7259 ! if (m_rds_decoder)
7260 ! return m_rds_decoder->getRassPictureMask();
7264 ! int eDVBServiceBase::getFrontendInfo(int w)
7266 ! eUsePtr<iDVBChannel> channel;
7267 ! if(m_service_handler.getChannel(channel))
7269 ! ePtr<iDVBFrontend> fe;
7270 ! if(channel->getFrontend(fe))
7272 ! return fe->readFrontendData(w);
7275 ! PyObject *eDVBServiceBase::getFrontendData()
7277 ! ePyObject ret = PyDict_New();
7280 ! eUsePtr<iDVBChannel> channel;
7281 ! if(!m_service_handler.getChannel(channel))
7283 ! ePtr<iDVBFrontend> fe;
7284 ! if(!channel->getFrontend(fe))
7285 ! fe->getFrontendData(ret);
7293 ! PyObject *eDVBServiceBase::getFrontendStatus()
7295 ! ePyObject ret = PyDict_New();
7298 ! eUsePtr<iDVBChannel> channel;
7299 ! if(!m_service_handler.getChannel(channel))
7301 ! ePtr<iDVBFrontend> fe;
7302 ! if(!channel->getFrontend(fe))
7303 ! fe->getFrontendStatus(ret);
7311 ! PyObject *eDVBServiceBase::getTransponderData(bool original)
7313 ! ePyObject ret = PyDict_New();
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);
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);
7348 ! int eDVBServicePlay::getNumberOfSubservices()
7350 ! ePtr<eServiceEvent> evt;
7351 ! if (!m_event_handler.getEvent(evt, 0))
7352 ! return evt->getNumOfLinkageServices();
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))
7364 ! sub.type=eServiceReference::idInvalid;
7368 ! RESULT eDVBServicePlay::startTimeshift()
7370 ! ePtr<iDVBDemux> demux;
7372 ! eDebug("Start timeshift!");
7374 ! if (m_timeshift_enabled)
7377 ! /* start recording with the data demux. */
7378 ! if (m_service_handler.getDataDemux(demux))
7381 ! demux->createTSRecorder(m_record);
7385 ! std::string tspath;
7386 ! if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
7387 ! eDebug("could not query ts path");
7390 ! tspath.append("/timeshift.XXXXXX");
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);
7402 ! if (m_timeshift_fd < 0)
7408 ! m_record->setTargetFD(m_timeshift_fd);
7410 ! m_timeshift_enabled = 1;
7412 ! updateTimeshiftPids();
7413 ! m_record->start();
7418 ! RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
7420 ! if (!m_timeshift_enabled)
7426 ! m_timeshift_enabled = 0;
7431 ! close(m_timeshift_fd);
7432 ! eDebug("remove timeshift file");
7433 ! eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
7438 ! int eDVBServicePlay::isTimeshiftActive()
7440 ! return m_timeshift_enabled && m_timeshift_active;
7443 ! RESULT eDVBServicePlay::activateTimeshift()
7445 ! if (!m_timeshift_enabled)
7448 ! if (!m_timeshift_active)
7450 ! switchToTimeshift();
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);
7473 ! void eDVBServicePlay::setCutList(ePyObject list)
7475 ! if (!PyList_Check(list))
7477 ! int size = PyList_Size(list);
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");
7490 ! if (PyTuple_Size(tuple) != 2)
7492 ! eDebug("cutlist entries need to be a 2-tuple");
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));
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))
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())
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;
7582 ! void eDVBServicePlay::switchToLive()
7584 ! if (!m_timeshift_active)
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)
7602 ! m_decode_demux = 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();
7615 ! m_cue = new eCueSheet();
7616 ! m_timeshift_active = 1;
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)
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.");
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.");
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)
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;
7702 ! m_decoder = new eTSMPEGDecoder(m_is_primary ? 0 : 1);
7705 ! h.getDecodeDemux(m_decode_demux);
7706 ! if (m_decode_demux)
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);
7734 ! m_cue->setDecodingDemux(m_decode_demux, m_decoder);
7740 ! m_timeshift_changed = 0;
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();
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);
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)
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);
7805 ! m_decoder->play();
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");
7839 ! eDebug("loading cuts..");
7842 ! unsigned long long where;
7843 ! unsigned int what;
7845 ! if (!fread(&where, sizeof(where), 1, f))
7847 ! if (!fread(&what, sizeof(what), 1, f))
7850 ! #if BYTE_ORDER == LITTLE_ENDIAN
7851 ! where = bswap_64(where);
7853 ! what = ntohl(what);
7858 ! m_cue_entries.insert(cueEntry(where, what));
7861 ! eDebug("%zd entries", m_cue_entries.size());
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");
7878 ! unsigned long long where;
7881 ! for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
7883 ! #if BYTE_ORDER == BIG_ENDIAN
7886 ! where = bswap_64(i->where);
7888 ! what = htonl(i->what);
7889 ! fwrite(&where, sizeof(where), 1, f);
7890 ! fwrite(&what, sizeof(what), 1, f);
7896 ! m_cuesheet_changed = 0;
7899 ! void eDVBServicePlay::cutlistToCuesheet()
7903 ! eDebug("no cue sheet");
7908 ! if (!m_cutlist_enabled)
7910 ! m_cue->commitSpans();
7911 ! eDebug("cutlists were disabled");
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;
7925 ! if (i == m_cue_entries.end())
7927 ! if (!have_any_span && !in)
7931 ! if (i->what == 0) /* in */
7935 ! } else if (i->what == 1) /* out */
7937 ! else /* mark (2) or last play position (3) */
7955 ! have_any_span = 1;
7956 ! m_cue->addSourceSpan(in, out);
7962 ! if (i == m_cue_entries.end())
7965 ! m_cue->commitSpans();
7968 ! RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
7970 ! if (m_subtitle_widget)
7971 ! disableSubtitles(parent);
7974 ! int tuplesize = PyTuple_Size(tuple);
7977 ! if (!PyTuple_Check(tuple))
7980 ! if (tuplesize < 1)
7983 ! entry = PyTuple_GET_ITEM(tuple, 0);
7985 ! if (!PyInt_Check(entry))
7988 ! type = PyInt_AsLong(entry);
7990 ! if (type == 1) // teletext subtitles
7992 ! int page, magazine, pid;
7993 ! if (tuplesize < 4)
7996 ! if (!m_teletext_parser)
7998 ! eDebug("enable teletext subtitles.. no parser !!!");
8002 ! entry = PyTuple_GET_ITEM(tuple, 1);
8003 ! if (!PyInt_Check(entry))
8005 ! pid = PyInt_AsLong(entry);
8007 ! entry = PyTuple_GET_ITEM(tuple, 2);
8008 ! if (!PyInt_Check(entry))
8010 ! page = PyInt_AsLong(entry);
8012 ! entry = PyTuple_GET_ITEM(tuple, 3);
8013 ! if (!PyInt_Check(entry))
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 !!!");
8031 ! if (tuplesize < 4)
8034 ! entry = PyTuple_GET_ITEM(tuple, 1);
8035 ! if (!PyInt_Check(entry))
8037 ! pid = PyInt_AsLong(entry);
8039 ! entry = PyTuple_GET_ITEM(tuple, 2);
8040 ! if (!PyInt_Check(entry))
8042 ! composition_page_id = PyInt_AsLong(entry);
8044 ! entry = PyTuple_GET_ITEM(tuple, 3);
8045 ! if (!PyInt_Check(entry))
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));
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)");
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);
8084 ! PyObject *eDVBServicePlay::getCachedSubtitle()
8086 ! if (m_dvb_service)
8088 ! int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
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
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
8112 ! PyObject *eDVBServicePlay::getSubtitleList()
8114 ! if (!m_teletext_parser)
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.");
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);
8149 ! added_ttx_pages.insert(hash);
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);
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);
8192 ! void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
8194 ! if (m_subtitle_widget)
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)
8213 ! enum { TELETEXT, DVB } type;
8214 ! eDVBTeletextSubtitlePage page;
8215 ! eDVBSubtitlePage dvb_page;
8217 ! if (!m_subtitle_pages.empty())
8219 ! page = m_subtitle_pages.front();
8221 ! show_time = page.m_pts;
8223 ! else if (!m_dvb_subtitle_pages.empty())
8225 ! dvb_page = m_dvb_subtitle_pages.front();
8227 ! show_time = dvb_page.m_show_time;
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");
8247 ! eDebug("[late (%d ms)]", -diff / 90);
8250 ! if (abs(diff) > 1800000)
8252 ! eDebug("[invalid]... immediate show!");
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();
8265 ! eDebug("display dvb subtitle Page %lld", show_time);
8266 ! m_subtitle_widget->setPage(dvb_page);
8267 ! m_dvb_subtitle_pages.pop_front();
8271 ! eDebug("start subtitle delay %d", diff / 90);
8272 ! m_subtitle_sync_timer->start(diff / 90, 1);
8278 ! void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
8280 ! if (m_subtitle_widget)
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();
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();
8312 ! void eDVBServicePlay::setAC3Delay(int delay)
8314 ! if (m_dvb_service)
8315 ! m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
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);
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());
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);
8346 ! case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
8347 ! m_event((iPlayableService*)this, evVideoFramerateChanged);
8349 ! case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
8350 ! m_event((iPlayableService*)this, evVideoProgressiveChanged);
8357 ! RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
8363 ! PyObject *eDVBServicePlay::getStreamingData()
8365 ! eDVBServicePMTHandler::program program;
8366 ! if (m_service_handler.getProgramInfo(program))
8371 ! ePyObject r = program.createPythonObject();
8372 ! ePtr<iDVBDemux> demux;
8373 ! if (!m_service_handler.getDataDemux(demux))
8376 ! if (!demux->getCADemuxID(demux_id))
8377 ! PutToDict(r, "demux", demux_id);
8384 ! DEFINE_REF(eDVBServicePlay)
8386 ! PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
8390 ! case iServiceInformation::sTransponderData:
8391 ! return eStaticServiceDVBInformation().getInfoObject(ref, w);
8395 ! return iStaticServiceInformation::getInfoObject(ref, w);
8398 ! eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");
8400 ! #include <lib/base/eerror.h>
8401 ! #include <lib/base/object.h>
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!
8433 ! class eStaticServiceDVBInformation: public iStaticServiceInformation
8435 ! DECLARE_REF(eStaticServiceDVBInformation);
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);
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));
8461 ! ePtr<iStaticServiceInformation> service_info;
8462 ! if (!service_center->info(parent, service_info))
8464 ! if (!service_info->getName(parent, name))
8465 ! name=buildShortName(name) + " - ";
8478 ! int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
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!!");
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);
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;
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))
8524 ! if (!feparm->getSystem(system))
8526 ! ePyObject dict = PyDict_New();
8529 ! case iDVBFrontend::feSatellite:
8531 ! eDVBFrontendParametersSatellite s;
8532 ! feparm->getDVBS(s);
8533 ! PutSatelliteDataToDict(dict, s);
8536 ! case iDVBFrontend::feTerrestrial:
8538 ! eDVBFrontendParametersTerrestrial t;
8539 ! feparm->getDVBT(t);
8540 ! PutTerrestrialDataToDict(dict, t);
8543 ! case iDVBFrontend::feCable:
8545 ! eDVBFrontendParametersCable c;
8546 ! feparm->getDVBC(c);
8547 ! PutCableDataToDict(dict, c);
8551 ! eDebug("unknown frontend type %d", system);
8566 ! DEFINE_REF(eStaticServiceDVBBouquetInformation);
8568 ! RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
8570 ! ePtr<iDVBChannelList> db;
8571 ! ePtr<eDVBResourceManager> res;
8574 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
8576 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
8579 ! if ((err = res->getChannelList(db)) != 0)
8581 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
8585 ! eBouquet *bouquet=0;
8586 ! if ((err = db->getBouquet(ref, bouquet)) != 0)
8588 ! eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
8592 ! if ( bouquet && bouquet->m_bouquet_name.length() )
8594 ! name = bouquet->m_bouquet_name;
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!");
8614 ! if (res->getChannelList(db))
8616 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no channel list!");
8620 ! eBouquet *bouquet=0;
8621 ! if (db->getBouquet(ref, bouquet))
8623 ! eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. getBouquet failed!");
8627 ! int prio_order = eDVBFrontend::getTypePriorityOrder();
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
8641 ! ((const eServiceReferenceDVB&)*it).getChannelID(chid);
8642 ! int tmp=res->canAllocateChannel(chid, chid_ignore, simulate);
8647 ! case 30000: // cached DVB-T channel
8648 ! case 1: // DVB-T frontend
8649 ! tmp = prio_map[prio_order][2];
8651 ! case 40000: // cached DVB-C channel
8653 ! tmp = prio_map[prio_order][1];
8656 ! tmp = prio_map[prio_order][0];
8661 ! m_playable_service = *it;
8668 ! m_playable_service = eServiceReference();
8672 ! int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
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;
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);
8700 ! DEFINE_REF(eStaticServiceDVBPVRInformation);
8702 ! eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &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())
8713 ! else if (!m_parser.m_name.empty())
8714 ! name = m_parser.m_name;
8718 ! size_t n = name.rfind('/');
8719 ! if (n != std::string::npos)
8720 ! name = name.substr(n + 1);
8725 ! int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
8727 ! ASSERT(ref == m_ref);
8729 ! eDVBTSTools tstools;
8732 ! stat(ref.path.c_str(), &s);
8734 ! if (tstools.openFile(ref.path.c_str(), 1))
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()))
8745 ! /* otherwise, re-calc length and update meta file */
8747 ! if (tstools.calcLen(len))
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)
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;
8770 ! return iServiceInformation::resNA;
8772 ! return iServiceInformation::resNA;
8776 ! std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int 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;
8791 ! PyObject *eStaticServiceDVBPVRInformation::getInfoObject(const eServiceReference &r, int what)
8795 ! case iServiceInformation::sFileSize:
8796 ! return PyLong_FromLongLong(m_parser.m_filesize);
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);
8810 ! if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
8820 ! class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
8822 ! DECLARE_REF(eDVBPVRServiceOfflineOperations);
8823 ! eServiceReferenceDVB m_ref;
8825 ! eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
8827 ! RESULT deleteFromDisk(int simulate);
8828 ! RESULT getListOfFilenames(std::list<std::string> &);
8832 ! DEFINE_REF(eDVBPVRServiceOfflineOperations);
8834 ! eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
8838 ! RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
8844 ! std::list<std::string> res;
8845 ! if (getListOfFilenames(res))
8848 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
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());
8856 ! eraser->erase(i->c_str());
8858 ! ::unlink(i->c_str());
8865 ! RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
8868 ! res.push_back(m_ref.path);
8870 ! // handling for old splitted recordings (enigma 1)
8875 ! snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
8877 ! if (stat(buf, &s) < 0)
8879 ! res.push_back(buf);
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");
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);
8904 ! int err = f.open(m_ref.path.c_str(), 0);
8909 ! off_t length = f.length();
8910 ! unsigned char buffer[188*256*4];
8913 ! eDebug("at %08llx / %08llx (%d %%)", offset, length, (int)(offset * 100 / length));
8914 ! int r = f.read(offset, buffer, sizeof(buffer));
8920 ! parser.parseData(offset, buffer, r);
8929 ! DEFINE_REF(eServiceFactoryDVB)
8931 ! eServiceFactoryDVB::eServiceFactoryDVB()
8933 ! ePtr<eServiceCenter> sc;
8935 ! eServiceCenter::getPrivInstance(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);
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;
8973 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
8975 ! eDebug("no resource manager");
8978 ! if ((err = res->getChannelList(db)) != 0)
8980 ! eDebug("no channel list");
8984 ! ePtr<eDVBChannelQuery> q;
8986 ! if (!m_parent.path.empty())
8988 ! eDVBChannelQuery::compile(q, m_parent.path);
8991 ! eDebug("compile query failed");
8996 ! if ((err = db->startQuery(m_query, q, m_parent)) != 0)
8998 ! eDebug("startQuery failed");
9005 ! RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
9007 ! eServiceReferenceDVB ref;
9012 ! while (!m_query->getNextResult(ref))
9013 ! list.push_back(ref);
9016 ! list.sort(iListableServiceCompare(this));
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
9033 ! // unknown format string chars are returned as python None values !
9034 ! PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
9037 ! std::list<eServiceReference> tmplist;
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)
9064 ! case 'R': // service reference (swig)object
9065 ! tmp = NEW_eServiceReference(ref);
9067 ! case 'C': // service reference compare string
9068 ! tmp = PyString_FromString(ref.toCompareString().c_str());
9070 ! case 'S': // service reference string
9071 ! tmp = PyString_FromString(ref.toString().c_str());
9073 ! case 'N': // service name
9074 ! if (service_center)
9076 ! service_center->info(ref, sptr);
9080 ! sptr->getName(ref, name);
9082 ! // filter short name brakets
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());
9094 ! tmp = PyString_FromString("<n/a>");
9096 ! case 'n': // short service name
9097 ! if (service_center)
9099 ! service_center->info(ref, sptr);
9103 ! sptr->getName(ref, name);
9104 ! name = buildShortName(name);
9105 ! if (name.length())
9106 ! tmp = PyString_FromString(name.c_str());
9110 ! tmp = PyString_FromString("<n/a>");
9116 ! Py_INCREF(Py_None);
9123 ! PyTuple_SET_ITEM(tuple, i, tmp);
9125 ! PyList_SET_ITEM(ret, cnt, tmp);
9129 ! PyList_SET_ITEM(ret, cnt, tuple);
9132 ! return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
9135 ! RESULT eDVBServiceList::getNext(eServiceReference &ref)
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))
9153 ! if (db->getBouquet(m_parent, m_bouquet) != 0)
9164 ! RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
9168 ! return m_bouquet->addService(ref, before);
9171 ! RESULT eDVBServiceList::removeService(eServiceReference &ref)
9175 ! return m_bouquet->removeService(ref);
9178 ! RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
9182 ! return m_bouquet->moveService(ref, pos);
9185 ! RESULT eDVBServiceList::flushChanges()
9189 ! return m_bouquet->flushChanges();
9192 ! RESULT eDVBServiceList::setListName(const std::string &name)
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);
9205 ! // check resources...
9206 ! ptr = new eDVBServicePlay(ref, service);
9210 ! RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
9212 ! if (ref.path.empty())
9214 ! ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
9223 ! RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
9225 ! ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
9226 ! if (list->startQuery())
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;
9254 ! /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
9260 ! RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
9262 ! if (ref.path.empty())
9268 ! ptr = new eDVBPVRServiceOfflineOperations(ref);
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;
9281 ! eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
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
9289 ! ePtr<iDVBChannelList> db;
9290 ! ePtr<eDVBResourceManager> res;
9293 ! if ((err = eDVBResourceManager::getInstance(res)) != 0)
9295 ! eDebug("no resource manager");
9298 ! if ((err = res->getChannelList(db)) != 0)
9300 ! eDebug("no channel list");
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!");
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)
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);
9341 ! xineLib = cXineLib::getInstance();
9342 ! xine_connection = CONNECT(xineLib->m_event, eDVBServicePlay::video_event);
9345 ! eDVBServicePlay::~eDVBServicePlay()
9349 ! eDVBMetaParser meta;
9350 ! int ret=meta.parseFile(m_reference.path);
9354 ! meta.m_service_data="";
9355 ! sprintf(tmp, "f:%x", m_dvb_service->m_flags);
9356 ! meta.m_service_data += tmp;
9358 ! for (int x=0; x < eDVBService::cacheMax; ++x)
9360 ! int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
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()
9380 ! ePtr<eServiceEvent> m_event_now, m_event_next;
9381 ! getEvent(m_event_now, 0);
9382 ! getEvent(m_event_next, 1);
9385 ! eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
9387 ! eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
9389 ! m_event((iPlayableService*)this, evUpdatedEventInfo);
9392 ! void eDVBServicePlay::serviceEvent(int event)
9394 ! m_tune_state = 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();
9406 ! sid = ref.getServiceID().get();
9407 ! if ( ref.getParentTransportStreamID().get() &&
9408 ! ref.getParentTransportStreamID() != ref.getTransportStreamID() )
9409 ! m_event_handler.startOther(m_demux, sid);
9411 ! m_event_handler.start(m_demux, sid);
9413 ! m_event((iPlayableService*)this, evTunedIn);
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);
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)
9434 ! if (m_first_program_info & 1 && m_is_pvr)
9436 ! m_first_program_info &= ~1;
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);
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");
9460 ! case eDVBServicePMTHandler::eventPreStart:
9463 ! case eDVBServicePMTHandler::eventEOF:
9464 ! m_event((iPlayableService*)this, evEOF);
9466 ! case eDVBServicePMTHandler::eventSOF:
9467 ! m_event((iPlayableService*)this, evSOF);
9472 ! void eDVBServicePlay::serviceEventTimeshift(int event)
9476 ! case eDVBServicePMTHandler::eventNewProgramInfo:
9477 ! eDebug("eventNewProgramInfo TS");
9478 ! if (m_timeshift_active)
9481 ! if (m_first_program_info & 2)
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);
9492 ! m_cue->setSkipmode(m_skipmode * 90000); /* convert to 90000 per second */
9493 ! if (m_fastforward != 1)
9494 ! m_decoder->setFastForward(m_fastforward);
9496 ! m_decoder->setTrickmode();
9500 ! m_first_program_info &= ~2;
9502 ! m_event((iPlayableService*)this, evUpdatedInfo);
9505 ! case eDVBServicePMTHandler::eventSOF:
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);
9530 ! m_event((iPlayableService*)this, evSOF);
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");
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);
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);
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. */
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();
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);
9596 ! /* inject EIT if there is a stored one */
9597 ! std::string filename = service.path;
9598 ! filename.erase(filename.length()-2, 2);
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);
9612 ! RESULT eDVBServicePlay::stop()
9614 ! printf("eDVBServicePlay::stop\n");
9615 ! /* add bookmark for last play position */
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();
9633 ! if (getLength(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. */
9652 ! printf("close(m_fd_dst) %d\n", m_fd_dst);
9656 ! m_service_handler_timeshift.free();
9657 ! m_service_handler.free();
9659 ! if (m_is_pvr && m_cuesheet_changed)
9662 ! /* save cuesheet only when main file is accessible. */
9663 ! if (!::stat(m_reference.path.c_str(), &s))
9666 ! m_event((iPlayableService*)this, evStopped);
9670 ! RESULT eDVBServicePlay::setTarget(int target)
9672 ! m_is_primary = !target;
9676 ! RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
9678 ! connection = new eConnection((iPlayableService*)this, m_event.connect(event));
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))
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);
9704 ! m_slowmotion = ratio;
9705 ! return m_decoder->setSlowMotion(ratio);
9711 ! RESULT eDVBServicePlay::setFastForward(int ratio)
9713 ! eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
9715 ! return setFastForward_internal(ratio);
9718 ! RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
9720 ! int skipmode, ffratio, ret = 0;
9727 ! } else if (ratio > 0)
9731 ! } else if (!ratio)
9735 ! } else // if (ratio < 0)
9741 ! if (m_skipmode != skipmode)
9743 ! eDebug("setting cue skipmode to %d", skipmode);
9745 ! m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
9748 ! m_skipmode = skipmode;
9751 ! eDebug("trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
9753 ! m_fastforward = ffratio;
9759 ! ; /* return m_decoder->play(); is done in caller*/
9760 ! else if (ffratio != 1)
9761 ! ret = m_decoder->setFastForward(ffratio);
9763 ! ret = m_decoder->setTrickmode();
9766 ! eDebug("final seek after trickplay ret %d", seekTo(pos));
9771 ! RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
9773 ! if (m_is_pvr || m_timeshift_enabled)
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))
9791 ! return pvr_channel->getLength(len);
9794 ! RESULT eDVBServicePlay::pause()
9796 ! eDebug("eDVBServicePlay::pause");
9797 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
9802 ! return m_decoder->pause();
9807 ! RESULT eDVBServicePlay::unpause()
9809 ! eDebug("eDVBServicePlay::unpause");
9810 ! setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
9815 ! return m_decoder->play();
9820 ! RESULT eDVBServicePlay::seekTo(pts_t to)
9822 ! eDebug("eDVBServicePlay::seekTo: jump %lld", to);
9824 ! if (!m_decode_demux)
9827 ! ePtr<iDVBPVRChannel> pvr_channel;
9829 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
9835 ! m_cue->seekTo(0, to);
9836 ! m_dvb_subtitle_pages.clear();
9837 ! m_subtitle_pages.clear();
9842 ! RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
9844 ! eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
9846 ! if (!m_decode_demux)
9849 ! ePtr<iDVBPVRChannel> pvr_channel;
9851 ! if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
9856 ! /* HACK until we have skip-AP api */
9857 ! if ((to > 0) && (to < 100))
9865 ! m_cue->seekTo(mode, to);
9866 ! m_dvb_subtitle_pages.clear();
9867 ! m_subtitle_pages.clear();
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))
9880 ! r = xineLib->getPTS(pos);
9885 ! return pvr_channel->getCurrentPosition(m_decode_demux, pos, 1);
9888 ! RESULT eDVBServicePlay::setTrickmode(int trick)
9890 ! /* currently unimplemented */
9894 ! RESULT eDVBServicePlay::isCurrentlySeekable()
9899 ! ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
9900 ! if (m_decoder->getVideoProgressive() == -1)
9906 ! RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
9912 ! RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
9918 ! RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
9924 ! RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
9930 ! RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
9936 ! RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
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");
9950 ! tspath.append("/");
9951 ! /* we need enough diskspace */
9953 ! if (statfs(tspath.c_str(), &fs) < 0)
9955 ! eDebug("statfs failed!");
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)");
9971 ! RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
9982 ! RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
9988 ! RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
9994 ! RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
10000 ! RESULT eDVBServicePlay::getName(std::string &name)
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())
10013 ! else if (!m_reference.name.empty())
10014 ! eStaticServiceDVBInformation().getName(m_reference, name);
10016 ! name = "DVB service";
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;
10041 ! case sVideoHeight:
10043 ! // return m_decoder->getVideoHeight();
10044 ! return xineLib->getVideoHeight();
10046 ! case sVideoWidth:
10048 ! // return m_decoder->getVideoWidth();
10049 ! return xineLib->getVideoWidth();
10053 ! // return m_decoder->getVideoFrameRate();
10054 ! return xineLib->getVideoFrameRate();
10056 ! case sProgressive:
10058 ! return m_decoder->getVideoProgressive();
10063 ! // aspect = m_decoder->getVideoAspect();
10064 ! int aspect = xineLib->getVideoAspect();
10066 ! if (aspect == -1 && no_program_info)
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())
10081 ! case 1: // 4:3 SD PAL
10083 ! case 3: // 16:9 SD PAL
10084 ! case 4: // > 16:9 PAL
10085 ! case 5: // 4:3 SD NTSC
10087 ! case 7: // 16:9 SD NTSC
10088 ! case 8: // > 16:9 NTSC
10091 ! case 9: // 4:3 HD PAL
10093 ! case 0xB: // 16:9 HD PAL
10094 ! case 0xC: // > 16:9 HD PAL
10095 ! case 0xD: // 4:3 HD NTSC
10097 ! case 0xF: // 16:9 HD NTSC
10098 ! case 0x10: // > 16:9 HD PAL
10099 ! return data->getComponentType();
10109 ! case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
10111 ! if (m_dvb_service)
10113 ! int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
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;
10120 ! if (m_dvb_service)
10122 ! int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
10125 ! apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
10129 ! if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
10131 ! if (m_dvb_service)
10133 ! int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
10134 ! if (pcrpid != -1)
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;
10153 ! std::string eDVBServicePlay::getInfoString(int w)
10158 ! if (!m_dvb_service) return "";
10159 ! return m_dvb_service->m_provider_name;
10160 ! case sServiceref:
10161 ! return m_reference.toString();
10165 ! return iServiceInformation::getInfoString(w);
10168 ! PyObject *eDVBServicePlay::getInfoObject(int w)
10173 ! return m_service_handler.getCaIds();
10175 ! return m_service_handler.getCaIds(true);
10176 ! case sTransponderData:
10177 ! return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
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))
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))
10200 ! int max = program.audioStreams.size();
10203 ! for (i = 0; i < max; ++i)
10204 ! if (program.audioStreams[i].pid == m_current_audio_pid)
10210 ! RESULT eDVBServicePlay::selectTrack(unsigned int i)
10212 ! int ret = selectAudioStream(i);
10214 ! if (m_decoder->set())
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))
10228 ! if (i >= program.audioStreams.size())
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";
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;
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))
10274 ! if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
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");
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.)
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);
10349 ! m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
10350 ! m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
10354 ! h.resetCachedProgram();
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);
10371 ! m_decoder->setAudioChannel(i);
10375 ! std::string eDVBServicePlay::getText(int x)
10377 ! if (m_rds_decoder)
10381 ! return convertLatin1UTF8(m_rds_decoder->getRadioText());
10383 ! return convertLatin1UTF8(m_rds_decoder->getRtpText());
10388 ! void eDVBServicePlay::rdsDecoderEvent(int what)
10392 ! case eDVBRdsDecoder::RadioTextChanged:
10393 ! m_event((iPlayableService*)this, evUpdatedRadioText);
10395 ! case eDVBRdsDecoder::RtpTextChanged:
10396 ! m_event((iPlayableService*)this, evUpdatedRtpText);
10398 ! case eDVBRdsDecoder::RassInteractivePicMaskChanged:
10399 ! m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
10401 ! case eDVBRdsDecoder::RecvRassSlidePic:
10402 ! m_event((iPlayableService*)this, evUpdatedRassSlidePic);
10407 ! void eDVBServicePlay::showRassSlidePicture()
10409 ! if (m_rds_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());
10417 ! eDebug("empty filename for rass slide picture received!!");
10420 ! eDebug("no MPEG Decoder to show iframes avail");
10423 ! eDebug("showRassSlidePicture called.. but not decoder");
10426 ! void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
10428 ! if (m_rds_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());
10436 ! eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
10439 ! eDebug("no MPEG Decoder to show iframes avail");
10442 ! eDebug("showRassInteractivePic called.. but not decoder");
10445 ! ePyObject eDVBServicePlay::getRassInteractiveMask()
10447 ! if (m_rds_decoder)
10448 ! return m_rds_decoder->getRassPictureMask();
10452 ! int eDVBServiceBase::getFrontendInfo(int w)
10454 ! eUsePtr<iDVBChannel> channel;
10455 ! if(m_service_handler.getChannel(channel))
10457 ! ePtr<iDVBFrontend> fe;
10458 ! if(channel->getFrontend(fe))
10460 ! return fe->readFrontendData(w);
10463 ! PyObject *eDVBServiceBase::getFrontendData()
10465 ! ePyObject ret = PyDict_New();
10468 ! eUsePtr<iDVBChannel> channel;
10469 ! if(!m_service_handler.getChannel(channel))
10471 ! ePtr<iDVBFrontend> fe;
10472 ! if(!channel->getFrontend(fe))
10473 ! fe->getFrontendData(ret);
10481 ! PyObject *eDVBServiceBase::getFrontendStatus()
10483 ! ePyObject ret = PyDict_New();
10486 ! eUsePtr<iDVBChannel> channel;
10487 ! if(!m_service_handler.getChannel(channel))
10489 ! ePtr<iDVBFrontend> fe;
10490 ! if(!channel->getFrontend(fe))
10491 ! fe->getFrontendStatus(ret);
10499 ! PyObject *eDVBServiceBase::getTransponderData(bool original)
10501 ! ePyObject ret = PyDict_New();
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);
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);
10536 ! int eDVBServicePlay::getNumberOfSubservices()
10538 ! ePtr<eServiceEvent> evt;
10539 ! if (!m_event_handler.getEvent(evt, 0))
10540 ! return evt->getNumOfLinkageServices();
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))
10552 ! sub.type=eServiceReference::idInvalid;
10556 ! RESULT eDVBServicePlay::startTimeshift()
10558 ! ePtr<iDVBDemux> demux;
10560 ! eDebug("Start timeshift!");
10562 ! if (m_timeshift_enabled)
10565 ! /* start recording with the data demux. */
10566 ! if (m_service_handler.getDataDemux(demux))
10569 ! demux->createTSRecorder(m_record);
10573 ! std::string tspath;
10574 ! if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
10575 ! eDebug("could not query ts path");
10578 ! tspath.append("/timeshift.XXXXXX");
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);
10590 ! if (m_timeshift_fd < 0)
10596 ! m_record->setTargetFD(m_timeshift_fd);
10598 ! m_timeshift_enabled = 1;
10600 ! updateTimeshiftPids();
10601 ! m_record->start();
10606 ! RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
10608 ! if (!m_timeshift_enabled)
10614 ! m_timeshift_enabled = 0;
10616 ! m_record->stop();
10619 ! close(m_timeshift_fd);
10620 ! eDebug("remove timeshift file");
10621 ! eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
10626 ! int eDVBServicePlay::isTimeshiftActive()
10628 ! return m_timeshift_enabled && m_timeshift_active;
10631 ! RESULT eDVBServicePlay::activateTimeshift()
10633 ! if (!m_timeshift_enabled)
10636 ! if (!m_timeshift_active)
10638 ! switchToTimeshift();
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);
10661 ! void eDVBServicePlay::setCutList(ePyObject list)
10663 ! if (!PyList_Check(list))
10665 ! int size = PyList_Size(list);
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");
10678 ! if (PyTuple_Size(tuple) != 2)
10680 ! eDebug("cutlist entries need to be a 2-tuple");
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));
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))
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())
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;
10770 ! void eDVBServicePlay::switchToLive()
10772 ! if (!m_timeshift_active)
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)
10790 ! m_decode_demux = 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();
10803 ! m_cue = new eCueSheet();
10804 ! m_timeshift_active = 1;
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)
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.");
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.");
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)
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;
10890 ! m_decoder = new eTSMPEGDecoder(m_is_primary ? 0 : 1);
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);
10922 ! m_cue->setDecodingDemux(m_decode_demux, m_decoder);
10928 ! m_timeshift_changed = 0;
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();
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);
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)
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);
10993 ! m_decoder->play();
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");
11027 ! eDebug("loading cuts..");
11030 ! unsigned long long where;
11031 ! unsigned int what;
11033 ! if (!fread(&where, sizeof(where), 1, f))
11035 ! if (!fread(&what, sizeof(what), 1, f))
11038 ! #if BYTE_ORDER == LITTLE_ENDIAN
11039 ! where = bswap_64(where);
11041 ! what = ntohl(what);
11046 ! m_cue_entries.insert(cueEntry(where, what));
11049 ! eDebug("%zd entries", m_cue_entries.size());
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");
11066 ! unsigned long long where;
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;
11074 ! where = bswap_64(i->where);
11076 ! what = htonl(i->what);
11077 ! fwrite(&where, sizeof(where), 1, f);
11078 ! fwrite(&what, sizeof(what), 1, f);
11084 ! m_cuesheet_changed = 0;
11087 ! void eDVBServicePlay::cutlistToCuesheet()
11091 ! eDebug("no cue sheet");
11096 ! if (!m_cutlist_enabled)
11098 ! m_cue->commitSpans();
11099 ! eDebug("cutlists were disabled");
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;
11113 ! if (i == m_cue_entries.end())
11115 ! if (!have_any_span && !in)
11119 ! if (i->what == 0) /* in */
11123 ! } else if (i->what == 1) /* out */
11124 ! out = i++->where;
11125 ! else /* mark (2) or last play position (3) */
11138 ! if (out > length)
11143 ! have_any_span = 1;
11144 ! m_cue->addSourceSpan(in, out);
11150 ! if (i == m_cue_entries.end())
11153 ! m_cue->commitSpans();
11156 ! RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
11158 ! if (m_subtitle_widget)
11159 ! disableSubtitles(parent);
11162 ! int tuplesize = PyTuple_Size(tuple);
11165 ! if (!PyTuple_Check(tuple))
11168 ! if (tuplesize < 1)
11171 ! entry = PyTuple_GET_ITEM(tuple, 0);
11173 ! if (!PyInt_Check(entry))
11176 ! type = PyInt_AsLong(entry);
11178 ! if (type == 1) // teletext subtitles
11180 ! int page, magazine, pid;
11181 ! if (tuplesize < 4)
11184 ! if (!m_teletext_parser)
11186 ! eDebug("enable teletext subtitles.. no parser !!!");
11190 ! entry = PyTuple_GET_ITEM(tuple, 1);
11191 ! if (!PyInt_Check(entry))
11193 ! pid = PyInt_AsLong(entry);
11195 ! entry = PyTuple_GET_ITEM(tuple, 2);
11196 ! if (!PyInt_Check(entry))
11198 ! page = PyInt_AsLong(entry);
11200 ! entry = PyTuple_GET_ITEM(tuple, 3);
11201 ! if (!PyInt_Check(entry))
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 !!!");
11219 ! if (tuplesize < 4)
11222 ! entry = PyTuple_GET_ITEM(tuple, 1);
11223 ! if (!PyInt_Check(entry))
11225 ! pid = PyInt_AsLong(entry);
11227 ! entry = PyTuple_GET_ITEM(tuple, 2);
11228 ! if (!PyInt_Check(entry))
11230 ! composition_page_id = PyInt_AsLong(entry);
11232 ! entry = PyTuple_GET_ITEM(tuple, 3);
11233 ! if (!PyInt_Check(entry))
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));
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)");
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);
11272 ! PyObject *eDVBServicePlay::getCachedSubtitle()
11274 ! if (m_dvb_service)
11276 ! int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
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
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
11300 ! PyObject *eDVBServicePlay::getSubtitleList()
11302 ! if (!m_teletext_parser)
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.");
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);
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);
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);
11380 ! void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
11382 ! if (m_subtitle_widget)
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)
11401 ! enum { TELETEXT, DVB } type;
11402 ! eDVBTeletextSubtitlePage page;
11403 ! eDVBSubtitlePage dvb_page;
11405 ! if (!m_subtitle_pages.empty())
11407 ! page = m_subtitle_pages.front();
11409 ! show_time = page.m_pts;
11411 ! else if (!m_dvb_subtitle_pages.empty())
11413 ! dvb_page = m_dvb_subtitle_pages.front();
11415 ! show_time = dvb_page.m_show_time;
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");
11435 ! eDebug("[late (%d ms)]", -diff / 90);
11438 ! if (abs(diff) > 1800000)
11440 ! eDebug("[invalid]... immediate show!");
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();
11453 ! eDebug("display dvb subtitle Page %lld", show_time);
11454 ! m_subtitle_widget->setPage(dvb_page);
11455 ! m_dvb_subtitle_pages.pop_front();
11459 ! eDebug("start subtitle delay %d", diff / 90);
11460 ! m_subtitle_sync_timer->start(diff / 90, 1);
11466 ! void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
11468 ! if (m_subtitle_widget)
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();
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();
11500 ! void eDVBServicePlay::setAC3Delay(int delay)
11502 ! if (m_dvb_service)
11503 ! m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
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);
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());
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);
11534 ! case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
11535 ! m_event((iPlayableService*)this, evVideoFramerateChanged);
11537 ! case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
11538 ! m_event((iPlayableService*)this, evVideoProgressiveChanged);
11545 ! RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
11551 ! PyObject *eDVBServicePlay::getStreamingData()
11553 ! eDVBServicePMTHandler::program program;
11554 ! if (m_service_handler.getProgramInfo(program))
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);
11572 ! DEFINE_REF(eDVBServicePlay)
11574 ! PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
11578 ! case iServiceInformation::sTransponderData:
11579 ! return eStaticServiceDVBInformation().getInfoObject(ref, w);
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
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);
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);
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);
11666 ! RESULT eServiceFactoryMP3::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
11672 ! RESULT eServiceFactoryMP3::list(const eServiceReference &, ePtr<iListableService> &ptr)
11678 ! RESULT eServiceFactoryMP3::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
11680 ! ptr = m_service_info;
11684 ! class eMP3ServiceOfflineOperations: public iServiceOfflineOperations
11686 ! DECLARE_REF(eMP3ServiceOfflineOperations);
11687 ! eServiceReference m_ref;
11689 ! eMP3ServiceOfflineOperations(const eServiceReference &ref);
11691 ! RESULT deleteFromDisk(int simulate);
11692 ! RESULT getListOfFilenames(std::list<std::string> &);
11693 ! RESULT reindex();
11696 ! DEFINE_REF(eMP3ServiceOfflineOperations);
11698 ! eMP3ServiceOfflineOperations::eMP3ServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReference&)ref)
11702 ! RESULT eMP3ServiceOfflineOperations::deleteFromDisk(int simulate)
11708 ! std::list<std::string> res;
11709 ! if (getListOfFilenames(res))
11712 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
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());
11720 ! eraser->erase(i->c_str());
11722 ! ::unlink(i->c_str());
11729 ! RESULT eMP3ServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
11732 ! res.push_back(m_ref.path);
11736 ! RESULT eMP3ServiceOfflineOperations::reindex()
11742 ! RESULT eServiceFactoryMP3::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
11744 ! ptr = new eMP3ServiceOfflineOperations(ref);
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() )
11770 ! size_t last = ref.path.rfind('/');
11771 ! if (last != std::string::npos)
11772 ! name = ref.path.substr(last+1);
11779 ! int eStaticServiceMP3Info::getLength(const eServiceReference &ref)
11784 ! int eStaticServiceMP3Info::getInfo(const eServiceReference &ref, int w)
11788 ! case iServiceInformation::sTimeCreate:
11791 ! if(stat(ref.path.c_str(), &s) == 0)
11793 ! return s.st_mtime;
11795 ! return iServiceInformation::resNA;
11799 ! return iServiceInformation::resNA;
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, '.');
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;
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);
11909 ! if ( ret == -1 ) // this is a "REAL" VCD
11910 ! uri = g_strdup_printf ("vcd://");
11912 ! uri = g_filename_to_uri(filename, NULL, NULL);
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);
11931 ! GstElement *subsink = gst_element_factory_make("appsink", "subtitle_sink");
11933 ! eDebug("eServiceMP3::sorry, can't play: missing gst-plugin-appsink");
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);
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");
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)
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));
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);
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)
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;
12048 ! RESULT eServiceMP3::setTarget(int target)
12053 ! RESULT eServiceMP3::pause(ePtr<iPauseableService> &ptr)
12059 ! RESULT eServiceMP3::setSlowMotion(int ratio)
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()
12076 ! getPlayPosition(ppos);
12078 ! ppos += 90000*m_currentTrickRatio;
12083 ! m_seekTimeout->stop();
12089 ! m_seekTimeout->stop();
12095 ! // iPausableService
12096 ! RESULT eServiceMP3::pause()
12098 ! if (!m_gst_playbin || m_state != stRunning)
12101 ! gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
12106 ! RESULT eServiceMP3::unpause()
12108 ! if (!m_gst_playbin || m_state != stRunning)
12111 ! gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
12116 ! /* iSeekableService */
12117 ! RESULT eServiceMP3::seek(ePtr<iSeekableService> &ptr)
12123 ! RESULT eServiceMP3::getLength(pts_t &pts)
12125 ! if (!m_gst_playbin)
12128 ! if (m_state != stRunning)
12131 ! GstFormat fmt = GST_FORMAT_TIME;
12134 ! if (!gst_element_query_duration(m_gst_playbin, &fmt, &len))
12136 ! /* len is in nanoseconds. we have 90 000 pts per second. */
12138 ! pts = len / 11111;
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");
12157 ! RESULT eServiceMP3::seekTo(pts_t to)
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;
12176 ! RESULT eServiceMP3::trickSeek(gdouble ratio)
12178 ! if (!m_gst_playbin)
12181 ! return seekRelative(0, 0);
12183 ! GstEvent *s_event;
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;
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));
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");
12218 ! RESULT eServiceMP3::seekRelative(int direction, pts_t to)
12220 ! if (!m_gst_playbin)
12224 ! getPlayPosition(ppos);
12225 ! ppos += to * direction;
12233 ! RESULT eServiceMP3::getPlayPosition(pts_t &pts)
12235 ! GstFormat fmt = GST_FORMAT_TIME;
12237 ! GstElement *sink;
12240 ! if (!m_gst_playbin)
12242 ! if (m_state != stRunning)
12245 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
12248 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
12253 ! gchar *name = gst_element_get_name(sink);
12254 ! gboolean use_get_decoder_time = strstr(name, "dvbaudiosink") || strstr(name, "dvbvideosink");
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");
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);
12273 ! RESULT eServiceMP3::setTrickmode(int trick)
12275 ! /* trickmode is not yet supported by our dvbmediasinks. */
12279 ! RESULT eServiceMP3::isCurrentlySeekable()
12281 ! int ret = 3; // seeking and fast/slow winding possible
12282 ! GstElement *sink;
12284 ! if (!m_gst_playbin)
12286 ! if (m_state != stRunning)
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)
12294 ! ret &= ~2; // only seeking possible
12295 ! gst_object_unref(sink);
12298 ! g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
12300 ! ret &= ~2; // only seeking possible
12301 ! gst_object_unref(sink);
12308 ! RESULT eServiceMP3::info(ePtr<iServiceInformation>&i)
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);
12329 ! int eServiceMP3::getInfo(int w)
12331 ! const gchar *tag = 0;
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;
12344 ! case sTagTitleSortname:
12345 ! case sTagArtistSortname:
12346 ! case sTagAlbumSortname:
12348 ! case sTagComposer:
12350 ! case sTagComment:
12351 ! case sTagExtendedComment:
12352 ! case sTagLocation:
12353 ! case sTagHomepage:
12354 ! case sTagDescription:
12355 ! case sTagVersion:
12357 ! case sTagOrganization:
12358 ! case sTagCopyright:
12359 ! case sTagCopyrightURI:
12360 ! case sTagContact:
12361 ! case sTagLicense:
12362 ! case sTagLicenseURI:
12364 ! case sTagAudioCodec:
12365 ! case sTagVideoCodec:
12366 ! case sTagEncoder:
12367 ! case sTagLanguageCode:
12368 ! case sTagKeywords:
12369 ! case sTagChannelMode:
12371 ! return resIsString;
12372 ! case sTagTrackGain:
12373 ! case sTagTrackPeak:
12374 ! case sTagAlbumGain:
12375 ! case sTagAlbumPeak:
12376 ! case sTagReferenceLevel:
12377 ! case sTagBeatsPerMinute:
12379 ! case sTagPreviewImage:
12380 ! case sTagAttachment:
12381 ! return resIsPyObject;
12382 ! case sTagTrackNumber:
12383 ! tag = GST_TAG_TRACK_NUMBER;
12385 ! case sTagTrackCount:
12386 ! tag = GST_TAG_TRACK_COUNT;
12388 ! case sTagAlbumVolumeNumber:
12389 ! tag = GST_TAG_ALBUM_VOLUME_NUMBER;
12391 ! case sTagAlbumVolumeCount:
12392 ! tag = GST_TAG_ALBUM_VOLUME_COUNT;
12394 ! case sTagBitrate:
12395 ! tag = GST_TAG_BITRATE;
12397 ! case sTagNominalBitrate:
12398 ! tag = GST_TAG_NOMINAL_BITRATE;
12400 ! case sTagMinimumBitrate:
12401 ! tag = GST_TAG_MINIMUM_BITRATE;
12403 ! case sTagMaximumBitrate:
12404 ! tag = GST_TAG_MAXIMUM_BITRATE;
12407 ! tag = GST_TAG_SERIAL;
12409 ! case sTagEncoderVersion:
12410 ! tag = GST_TAG_ENCODER_VERSION;
12419 ! if (!m_stream_tags || !tag)
12423 ! if (gst_tag_list_get_uint(m_stream_tags, tag, &value))
12424 ! return (int) value;
12429 ! std::string eServiceMP3::getInfoString(int w)
12431 ! if ( !m_stream_tags && w < sUser && w > 26 )
12433 ! const gchar *tag = 0;
12437 ! tag = GST_TAG_TITLE;
12440 ! tag = GST_TAG_ARTIST;
12443 ! tag = GST_TAG_ALBUM;
12445 ! case sTagTitleSortname:
12446 ! tag = GST_TAG_TITLE_SORTNAME;
12448 ! case sTagArtistSortname:
12449 ! tag = GST_TAG_ARTIST_SORTNAME;
12451 ! case sTagAlbumSortname:
12452 ! tag = GST_TAG_ALBUM_SORTNAME;
12456 ! if (gst_tag_list_get_date(m_stream_tags, GST_TAG_DATE, &date))
12459 ! g_date_strftime (res, sizeof(res), "%Y-%M-%D", date);
12460 ! return (std::string)res;
12463 ! case sTagComposer:
12464 ! tag = GST_TAG_COMPOSER;
12467 ! tag = GST_TAG_GENRE;
12469 ! case sTagComment:
12470 ! tag = GST_TAG_COMMENT;
12472 ! case sTagExtendedComment:
12473 ! tag = GST_TAG_EXTENDED_COMMENT;
12475 ! case sTagLocation:
12476 ! tag = GST_TAG_LOCATION;
12478 ! case sTagHomepage:
12479 ! tag = GST_TAG_HOMEPAGE;
12481 ! case sTagDescription:
12482 ! tag = GST_TAG_DESCRIPTION;
12484 ! case sTagVersion:
12485 ! tag = GST_TAG_VERSION;
12488 ! tag = GST_TAG_ISRC;
12490 ! case sTagOrganization:
12491 ! tag = GST_TAG_ORGANIZATION;
12493 ! case sTagCopyright:
12494 ! tag = GST_TAG_COPYRIGHT;
12496 ! case sTagCopyrightURI:
12497 ! tag = GST_TAG_COPYRIGHT_URI;
12499 ! case sTagContact:
12500 ! tag = GST_TAG_CONTACT;
12502 ! case sTagLicense:
12503 ! tag = GST_TAG_LICENSE;
12505 ! case sTagLicenseURI:
12506 ! tag = GST_TAG_LICENSE_URI;
12509 ! tag = GST_TAG_CODEC;
12511 ! case sTagAudioCodec:
12512 ! tag = GST_TAG_AUDIO_CODEC;
12514 ! case sTagVideoCodec:
12515 ! tag = GST_TAG_VIDEO_CODEC;
12517 ! case sTagEncoder:
12518 ! tag = GST_TAG_ENCODER;
12520 ! case sTagLanguageCode:
12521 ! tag = GST_TAG_LANGUAGE_CODE;
12523 ! case sTagKeywords:
12524 ! tag = GST_TAG_KEYWORDS;
12526 ! case sTagChannelMode:
12527 ! tag = "channel-mode";
12530 ! return m_errorInfo.error_message;
12537 ! if (gst_tag_list_get_string(m_stream_tags, tag, &value))
12539 ! std::string res = value;
12546 ! PyObject *eServiceMP3::getInfoObject(int w)
12548 ! const gchar *tag = 0;
12549 ! bool isBuffer = false;
12552 ! case sTagTrackGain:
12553 ! tag = GST_TAG_TRACK_GAIN;
12555 ! case sTagTrackPeak:
12556 ! tag = GST_TAG_TRACK_PEAK;
12558 ! case sTagAlbumGain:
12559 ! tag = GST_TAG_ALBUM_GAIN;
12561 ! case sTagAlbumPeak:
12562 ! tag = GST_TAG_ALBUM_PEAK;
12564 ! case sTagReferenceLevel:
12565 ! tag = GST_TAG_REFERENCE_LEVEL;
12567 ! case sTagBeatsPerMinute:
12568 ! tag = GST_TAG_BEATS_PER_MINUTE;
12571 ! tag = GST_TAG_IMAGE;
12574 ! case sTagPreviewImage:
12575 ! tag = GST_TAG_PREVIEW_IMAGE;
12578 ! case sTagAttachment:
12579 ! tag = GST_TAG_ATTACHMENT;
12588 ! const GValue *gv_buffer = gst_tag_list_get_value_index(m_stream_tags, tag, 0);
12591 ! GstBuffer *buffer;
12592 ! buffer = gst_value_get_buffer (gv_buffer);
12593 ! return PyBuffer_FromMemory(GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
12598 ! gdouble value = 0.0;
12599 ! gst_tag_list_get_double(m_stream_tags, tag, &value);
12600 ! return PyFloat_FromDouble(value);
12606 ! RESULT eServiceMP3::audioChannel(ePtr<iAudioChannelSelection> &ptr)
12612 ! RESULT eServiceMP3::audioTracks(ePtr<iAudioTrackSelection> &ptr)
12618 ! RESULT eServiceMP3::subtitle(ePtr<iSubtitleOutput> &ptr)
12624 ! RESULT eServiceMP3::audioDelay(ePtr<iAudioDelay> &ptr)
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)
12645 ! getPlayPosition(ppos);
12650 ! int ret = selectAudioStream(i);
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", ¤t_audio, NULL);
12664 ! if ( current_audio == i )
12666 ! eDebug ("eServiceMP3::switched to audio stream %i", current_audio);
12667 ! m_currentAudioStream = i;
12673 ! int eServiceMP3::getCurrentChannel()
12678 ! RESULT eServiceMP3::selectChannel(int i)
12680 ! eDebug("eServiceMP3::selectChannel(%i)",i);
12684 ! RESULT eServiceMP3::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
12686 ! if (i >= m_audioStreams.size())
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";
12706 ! info.m_description = "???";*/
12707 ! if (info.m_language.empty())
12708 ! info.m_language = m_audioStreams[i].language_code;
12712 ! subtype_t getSubtitleType(GstPad* pad, gchar *g_codec=NULL)
12714 ! subtype_t type = stUnknown;
12715 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
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") )
12725 ! else if ( !strcmp(g_type, "text/x-pango-markup") )
12727 ! else if ( !strcmp(g_type, "text/plain") )
12728 ! type = stPlainText;
12729 ! else if ( !strcmp(g_type, "subpicture/x-pgs") )
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") )
12739 ! else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
12741 ! else if ( !strcmp(g_codec, "ASS") )
12743 ! else if ( !strcmp(g_codec, "UTF-8 plain text") )
12744 ! type = stPlainText;
12746 ! eDebug("getSubtitleType::unsupported subtitle codec %s", g_codec);
12749 ! eDebug("getSubtitleType::unidentifiable subtitle stream!");
12754 ! void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
12758 ! gchar *sourceName;
12759 ! GstObject *source;
12760 ! source = GST_MESSAGE_SRC(msg);
12761 ! if (!GST_IS_OBJECT(source))
12763 ! sourceName = gst_object_get_name(source);
12766 ! if (gst_message_get_structure(msg))
12767 ! string = gst_structure_to_string(gst_message_get_structure(msg));
12769 ! string = g_strdup(GST_MESSAGE_TYPE_NAME(msg));
12770 ! eDebug("eTsRemoteSource::gst_message from %s: %s", sourceName, string);
12773 ! switch (GST_MESSAGE_TYPE (msg))
12775 ! case GST_MESSAGE_EOS:
12776 ! m_event((iPlayableService*)this, evEOF);
12778 ! case GST_MESSAGE_STATE_CHANGED:
12780 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
12783 ! GstState old_state, new_state;
12784 ! gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
12786 ! if(old_state == new_state)
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:
12798 ! case GST_STATE_CHANGE_READY_TO_PAUSED:
12800 ! GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
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);
12812 ! case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
12814 ! if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout )
12815 ! m_streamingsrc_timeout->stop();
12817 ! case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
12820 ! case GST_STATE_CHANGE_PAUSED_TO_READY:
12823 ! case GST_STATE_CHANGE_READY_TO_NULL:
12829 ! case GST_MESSAGE_ERROR:
12833 ! gst_message_parse_error (msg, &err, &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);
12849 ! case GST_MESSAGE_INFO:
12854 ! gst_message_parse_info (msg, &inf, &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);
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);
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);
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));
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);
12892 ! case GST_MESSAGE_ASYNC_DONE:
12894 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
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 )
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;
12919 ! g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad);
12920 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
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);
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;
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);
12963 ! g_signal_emit_by_name (m_gst_playbin, "get-text-pad", i, &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);
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);
12980 ! case GST_MESSAGE_ELEMENT:
12982 ! if (const GstStructure *msgstruct = gst_message_get_structure(msg))
12984 ! if ( gst_is_missing_plugin_message(msg) )
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);
13001 ! const gchar *eventname = gst_structure_get_name(msgstruct);
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);
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);
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);
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);
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));
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)
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) {
13104 ! gst_structure_get_int (structure, "layer", &layer);
13105 ! if ( layer == 3 )
13116 ! return atUnknown;
13120 ! else if ( gst_structure_has_name (structure, "audio/x-ac3") || gst_structure_has_name (structure, "audio/ac3") )
13122 ! else if ( gst_structure_has_name (structure, "audio/x-dts") || gst_structure_has_name (structure, "audio/dts") )
13124 ! else if ( gst_structure_has_name (structure, "audio/x-raw-int") )
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)
13144 ! else if (msg.type == 3)
13145 ! gstTextpadHasCAPS_synced(msg.d.pad);
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)
13174 ! g_object_get (G_OBJECT (pad), "caps", &caps, NULL);
13176 ! eDebug("gstTextpadHasCAPS:: signal::caps = %s", gst_caps_to_string(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];
13187 ! subs.type = stUnknown;
13191 ! if ( subs.type == stUnknown )
13193 ! GstTagList *tags;
13194 ! // eDebug("gstGhostpadHasCAPS::m_subtitleStreams[%i].type == stUnknown...", m_currentSubtitleStream);
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;
13209 ! m_subtitleStreams.push_back(subs);
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);
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);
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);
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)
13264 ! eDebug("unsupported subpicture... ignoring");
13267 ! gst_buffer_unref(buffer);
13270 ! gst_object_unref(sink);
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);
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;
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);
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())
13336 ! RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
13338 ! eDebug ("eServiceMP3::enableSubtitles m_currentSubtitleStream=%i this=%p",m_currentSubtitleStream, this);
13340 ! int tuplesize = PyTuple_Size(tuple);
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))
13352 ! if (tuplesize < 1)
13354 ! entry = PyTuple_GET_ITEM(tuple, 1);
13355 ! if (!PyInt_Check(entry))
13357 ! pid = PyInt_AsLong(entry);
13358 ! entry = PyTuple_GET_ITEM(tuple, 2);
13359 ! if (!PyInt_Check(entry))
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);
13387 ! eDebug("eServiceMP3::enableSubtitles needs a tuple as 2nd argument!\n"
13388 ! "for gst subtitles (2, subtitle_stream_count, subtitle_type)");
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;
13401 ! PyObject *eServiceMP3::getCachedSubtitle()
13403 ! // eDebug("eServiceMP3::getCachedSubtitle");
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;
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);
13437 ! eDebug("eServiceMP3::getSubtitleList finished");
13441 ! RESULT eServiceMP3::streamed(ePtr<iStreamedService> &ptr)
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));
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);
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)
13482 ! GstElement *sink;
13483 ! int config_delay_int = delay;
13484 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
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);
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);
13503 ! gchar *name = gst_element_get_name(sink);
13504 ! if (strstr(name, "dvbaudiosink"))
13505 ! eTSMPEGDecoder::setHwAC3Delay(config_delay_int);
13507 ! gst_object_unref(sink);
13512 ! void eServiceMP3::setPCMDelay(int delay)
13514 ! pcm_delay = delay;
13515 ! if (!m_gst_playbin || m_state != stRunning)
13519 ! GstElement *sink;
13520 ! int config_delay_int = delay;
13521 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
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);
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);
13540 ! gchar *name = gst_element_get_name(sink);
13541 ! if (strstr(name, "dvbaudiosink"))
13542 ! eTSMPEGDecoder::setHwPCMDelay(config_delay_int);
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);
13551 ! gst_object_unref(sink);
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);
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);
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);
13631 ! RESULT eServiceFactoryMP3::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
13637 ! RESULT eServiceFactoryMP3::list(const eServiceReference &, ePtr<iListableService> &ptr)
13643 ! RESULT eServiceFactoryMP3::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
13645 ! ptr = m_service_info;
13649 ! class eMP3ServiceOfflineOperations: public iServiceOfflineOperations
13651 ! DECLARE_REF(eMP3ServiceOfflineOperations);
13652 ! eServiceReference m_ref;
13654 ! eMP3ServiceOfflineOperations(const eServiceReference &ref);
13656 ! RESULT deleteFromDisk(int simulate);
13657 ! RESULT getListOfFilenames(std::list<std::string> &);
13658 ! RESULT reindex();
13661 ! DEFINE_REF(eMP3ServiceOfflineOperations);
13663 ! eMP3ServiceOfflineOperations::eMP3ServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReference&)ref)
13667 ! RESULT eMP3ServiceOfflineOperations::deleteFromDisk(int simulate)
13673 ! std::list<std::string> res;
13674 ! if (getListOfFilenames(res))
13677 ! eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
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());
13685 ! eraser->erase(i->c_str());
13687 ! ::unlink(i->c_str());
13694 ! RESULT eMP3ServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
13697 ! res.push_back(m_ref.path);
13701 ! RESULT eMP3ServiceOfflineOperations::reindex()
13707 ! RESULT eServiceFactoryMP3::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
13709 ! ptr = new eMP3ServiceOfflineOperations(ref);
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() )
13735 ! size_t last = ref.path.rfind('/');
13736 ! if (last != std::string::npos)
13737 ! name = ref.path.substr(last+1);
13744 ! int eStaticServiceMP3Info::getLength(const eServiceReference &ref)
13749 ! int eStaticServiceMP3Info::getInfo(const eServiceReference &ref, int w)
13753 ! case iServiceInformation::sTimeCreate:
13756 ! if(stat(ref.path.c_str(), &s) == 0)
13758 ! return s.st_mtime;
13760 ! return iServiceInformation::resNA;
13764 ! return iServiceInformation::resNA;
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);
13795 ! eServiceMP3::~eServiceMP3()
13796 ! {printf("Sira=2\n");
13797 ! if (m_state == stRunning)
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));
13809 ! RESULT eServiceMP3::start()
13811 ! printf("Sira=3\n");
13813 ! //ASSERT(m_state == stIdle);
13815 ! m_state = stRunning;
13816 ! m_event(this, evStart);
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)
13834 ! m_state = stStopped;
13835 ! cXineLib *xineLib = cXineLib::getInstance();
13836 ! xineLib->stopVideo();
13840 ! RESULT eServiceMP3::setTarget(int target)
13845 ! RESULT eServiceMP3::pause(ePtr<iPauseableService> &ptr)
13846 ! {printf("Sira=104\n");
13851 ! RESULT eServiceMP3::setSlowMotion(int ratio)
13852 ! {printf("Sira=102\n");
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");
13868 ! getPlayPosition(ppos);
13870 ! ppos += 90000*m_currentTrickRatio;
13875 ! m_seekTimeout->stop();
13881 ! m_seekTimeout->stop();
13887 ! // iPausableService
13888 ! RESULT eServiceMP3::pause()
13890 ! if (m_state != stRunning)
13893 ! cXineLib *xineLib = cXineLib::getInstance();
13894 ! xineLib->VideoPause();
13899 ! RESULT eServiceMP3::unpause()
13900 ! {printf("Sira=91\n");
13902 ! if (m_state != stRunning)
13905 ! cXineLib *xineLib = cXineLib::getInstance();
13906 ! xineLib->VideoResume();
13911 ! /* iSeekableService */
13912 ! RESULT eServiceMP3::seek(ePtr<iSeekableService> &ptr)
13918 ! RESULT eServiceMP3::getLength(pts_t &pts)
13920 ! if (m_state != stRunning)
13923 ! cXineLib *xineLib = cXineLib::getInstance();
13924 ! xineLib->VideoPosisyon();
13925 ! pts=xineLib->Vlength*90;
13929 ! RESULT eServiceMP3::seekToImpl(pts_t to)
13930 ! {printf("Sira=8\n");
13934 ! RESULT eServiceMP3::seekTo(pts_t to)
13936 ! printf("Sira=9\n");
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);
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);
13967 ! RESULT eServiceMP3::getPlayPosition(pts_t &pts)
13970 ! if (m_state != stRunning)
13973 ! cXineLib *xineLib = cXineLib::getInstance();
13974 ! xineLib->VideoPosisyon();
13975 ! pts=xineLib->Vpos*90;
13979 ! RESULT eServiceMP3::setTrickmode(int trick)
13980 ! {printf("Sira=11-1\n");
13981 ! /* trickmode is not yet supported by our dvbmediasinks. */
13985 ! RESULT eServiceMP3::isCurrentlySeekable()
13987 ! printf("Sira=13\n");
13988 ! if (m_state != stRunning)
13991 ! int ret = 3; // seeking and fast/slow winding possible
13995 ! RESULT eServiceMP3::info(ePtr<iServiceInformation>&i)
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);
14016 ! int eServiceMP3::getInfo(int w)
14018 ! printf("Sira=15\n");
14020 ! const gchar *tag = 0;
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;
14033 ! case sTagTitleSortname:
14034 ! case sTagArtistSortname:
14035 ! case sTagAlbumSortname:
14037 ! case sTagComposer:
14039 ! case sTagComment:
14040 ! case sTagExtendedComment:
14041 ! case sTagLocation:
14042 ! case sTagHomepage:
14043 ! case sTagDescription:
14044 ! case sTagVersion:
14046 ! case sTagOrganization:
14047 ! case sTagCopyright:
14048 ! case sTagCopyrightURI:
14049 ! case sTagContact:
14050 ! case sTagLicense:
14051 ! case sTagLicenseURI:
14053 ! case sTagAudioCodec:
14054 ! case sTagVideoCodec:
14055 ! case sTagEncoder:
14056 ! case sTagLanguageCode:
14057 ! case sTagKeywords:
14058 ! case sTagChannelMode:
14060 ! return resIsString;
14061 ! case sTagTrackGain:
14062 ! case sTagTrackPeak:
14063 ! case sTagAlbumGain:
14064 ! case sTagAlbumPeak:
14065 ! case sTagReferenceLevel:
14066 ! case sTagBeatsPerMinute:
14068 ! case sTagPreviewImage:
14069 ! case sTagAttachment:
14070 ! return resIsPyObject;
14078 ! if (!m_stream_tags || !tag)
14084 ! std::string eServiceMP3::getInfoString(int w)
14086 ! printf("Sira=16\n");
14091 ! PyObject *eServiceMP3::getInfoObject(int w)
14093 ! printf("Sira=17\n");
14097 ! RESULT eServiceMP3::audioChannel(ePtr<iAudioChannelSelection> &ptr)
14103 ! RESULT eServiceMP3::audioTracks(ePtr<iAudioTrackSelection> &ptr)
14109 ! RESULT eServiceMP3::subtitle(ePtr<iSubtitleOutput> &ptr)
14115 ! RESULT eServiceMP3::audioDelay(ePtr<iAudioDelay> &ptr)
14121 ! int eServiceMP3::getNumberOfTracks()
14123 ! return m_audioStreams.size();
14126 ! int eServiceMP3::getCurrentTrack()
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)
14136 ! getPlayPosition(ppos);
14141 ! int ret = selectAudioStream(i);
14150 ! int eServiceMP3::selectAudioStream(int i)
14152 ! printf("Sira=18\n");
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", ¤t_audio, NULL);
14157 ! if ( current_audio == i )
14159 ! eDebug ("eServiceMP3::switched to audio stream %i", current_audio);
14160 ! m_currentAudioStream = i;
14166 ! int eServiceMP3::getCurrentChannel()
14171 ! RESULT eServiceMP3::selectChannel(int i)
14173 ! eDebug("eServiceMP3::selectChannel(%i)",i);
14177 ! RESULT eServiceMP3::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
14178 ! {printf("Sira=19\n");
14179 ! if (i >= m_audioStreams.size())
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";
14199 ! info.m_description = "???";*/
14200 ! if (info.m_language.empty())
14201 ! info.m_language = m_audioStreams[i].language_code;
14205 ! subtype_t getSubtitleType(GstPad* pad, gchar *g_codec=NULL)
14207 ! printf("Sira=20\n");
14209 ! subtype_t type = stUnknown;
14210 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
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") )
14220 ! else if ( !strcmp(g_type, "text/x-pango-markup") )
14222 ! else if ( !strcmp(g_type, "text/plain") )
14223 ! type = stPlainText;
14224 ! else if ( !strcmp(g_type, "subpicture/x-pgs") )
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") )
14234 ! else if ( !strcmp(g_codec, "SubStation Alpha") || !strcmp(g_codec, "SSA") )
14236 ! else if ( !strcmp(g_codec, "ASS") )
14238 ! else if ( !strcmp(g_codec, "UTF-8 plain text") )
14239 ! type = stPlainText;
14241 ! eDebug("getSubtitleType::unsupported subtitle codec %s", g_codec);
14244 ! eDebug("getSubtitleType::unidentifiable subtitle stream!");
14249 ! void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
14251 ! printf("Sira=21\n");
14255 ! gchar *sourceName;
14256 ! GstObject *source;
14257 ! source = GST_MESSAGE_SRC(msg);
14258 ! if (!GST_IS_OBJECT(source))
14260 ! sourceName = gst_object_get_name(source);
14263 ! if (gst_message_get_structure(msg))
14264 ! string = gst_structure_to_string(gst_message_get_structure(msg));
14266 ! string = g_strdup(GST_MESSAGE_TYPE_NAME(msg));
14267 ! eDebug("eTsRemoteSource::gst_message from %s: %s", sourceName, string);
14270 ! switch (GST_MESSAGE_TYPE (msg))
14272 ! case GST_MESSAGE_EOS:
14273 ! m_event((iPlayableService*)this, evEOF);
14275 ! case GST_MESSAGE_STATE_CHANGED:
14277 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
14280 ! GstState old_state, new_state;
14281 ! gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
14283 ! if(old_state == new_state)
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:
14295 ! case GST_STATE_CHANGE_READY_TO_PAUSED:
14297 ! GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink");
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);
14309 ! case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
14311 ! if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout )
14312 ! m_streamingsrc_timeout->stop();
14314 ! case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
14317 ! case GST_STATE_CHANGE_PAUSED_TO_READY:
14320 ! case GST_STATE_CHANGE_READY_TO_NULL:
14326 ! case GST_MESSAGE_ERROR:
14330 ! gst_message_parse_error (msg, &err, &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);
14346 ! case GST_MESSAGE_INFO:
14351 ! gst_message_parse_info (msg, &inf, &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);
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);
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);
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));
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);
14389 ! case GST_MESSAGE_ASYNC_DONE:
14391 ! if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
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 )
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;
14416 ! g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad);
14417 ! GstCaps* caps = gst_pad_get_negotiated_caps(pad);
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);
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;
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);
14460 ! g_signal_emit_by_name (m_gst_playbin, "get-text-pad", i, &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);
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);
14477 ! case GST_MESSAGE_ELEMENT:
14479 ! if (const GstStructure *msgstruct = gst_message_get_structure(msg))
14481 ! if ( gst_is_missing_plugin_message(msg) )
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);
14498 ! const gchar *eventname = gst_structure_get_name(msgstruct);
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);
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);
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);
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);
14567 ! g_free (sourceName);*/
14570 ! GstBusSyncReply eServiceMP3::gstBusSyncHandler(GstBus *bus, GstMessage *message, gpointer user_data)
14572 ! printf("Sira=22\n");
14574 ! eServiceMP3 *_this = (eServiceMP3*)user_data;
14575 ! _this->m_pump.send(Message(1));
14577 ! return GST_BUS_PASS;*/
14580 ! void eServiceMP3::gstHTTPSourceSetAgent(GObject *object, GParamSpec *unused, gpointer user_data)
14582 ! printf("Sira=23\n");
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");
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) {
14607 ! gst_structure_get_int (structure, "layer", &layer);
14608 ! if ( layer == 3 )
14619 ! return atUnknown;
14623 ! else if ( gst_structure_has_name (structure, "audio/x-ac3") || gst_structure_has_name (structure, "audio/ac3") )
14625 ! else if ( gst_structure_has_name (structure, "audio/x-dts") || gst_structure_has_name (structure, "audio/dts") )
14627 ! else if ( gst_structure_has_name (structure, "audio/x-raw-int") )
14630 ! return atUnknown;*/
14633 ! void eServiceMP3::gstPoll(const Message &msg)
14636 ! printf("Sira=25\n");
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)
14650 ! else if (msg.type == 3)
14651 ! gstTextpadHasCAPS_synced(msg.d.pad);
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");
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");
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");
14686 ! g_object_get (G_OBJECT (pad), "caps", &caps, NULL);
14688 ! eDebug("gstTextpadHasCAPS:: signal::caps = %s", gst_caps_to_string(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];
14699 ! subs.type = stUnknown;
14703 ! if ( subs.type == stUnknown )
14705 ! GstTagList *tags;
14706 ! // eDebug("gstGhostpadHasCAPS::m_subtitleStreams[%i].type == stUnknown...", m_currentSubtitleStream);
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;
14721 ! m_subtitleStreams.push_back(subs);
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");
14738 ! GstElement *sink;
14739 ! g_object_get (G_OBJECT (m_gst_playbin), "text-sink", &sink, NULL);
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);
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);
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)
14778 ! eDebug("unsupported subpicture... ignoring");
14781 ! gst_buffer_unref(buffer);
14784 ! gst_object_unref(sink);
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);
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;
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);
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");
14854 ! eDebug ("eServiceMP3::enableSubtitles m_currentSubtitleStream=%i this=%p",m_currentSubtitleStream, this);
14856 ! int tuplesize = PyTuple_Size(tuple);
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))
14868 ! if (tuplesize < 1)
14870 ! entry = PyTuple_GET_ITEM(tuple, 1);
14871 ! if (!PyInt_Check(entry))
14873 ! pid = PyInt_AsLong(entry);
14874 ! entry = PyTuple_GET_ITEM(tuple, 2);
14875 ! if (!PyInt_Check(entry))
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);
14903 ! eDebug("eServiceMP3::enableSubtitles needs a tuple as 2nd argument!\n"
14904 ! "for gst subtitles (2, subtitle_stream_count, subtitle_type)");
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;
14917 ! PyObject *eServiceMP3::getCachedSubtitle()
14919 ! // eDebug("eServiceMP3::getCachedSubtitle");
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;
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);
14953 ! eDebug("eServiceMP3::getSubtitleList finished");
14957 ! RESULT eServiceMP3::streamed(ePtr<iStreamedService> &ptr)
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));
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);
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");
14996 ! ac3_delay = delay;
14997 ! if (!m_gst_playbin || m_state != stRunning)
15001 ! GstElement *sink;
15002 ! int config_delay_int = delay;
15003 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
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);
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);
15022 ! gchar *name = gst_element_get_name(sink);
15023 ! if (strstr(name, "dvbaudiosink"))
15024 ! eTSMPEGDecoder::setHwAC3Delay(config_delay_int);
15026 ! gst_object_unref(sink);
15031 ! void eServiceMP3::setPCMDelay(int delay)
15033 ! printf("Sira=33\n");
15035 ! pcm_delay = delay;
15036 ! if (!m_gst_playbin || m_state != stRunning)
15040 ! GstElement *sink;
15041 ! int config_delay_int = delay;
15042 ! g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
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);
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);
15061 ! gchar *name = gst_element_get_name(sink);
15062 ! if (strstr(name, "dvbaudiosink"))
15063 ! eTSMPEGDecoder::setHwPCMDelay(config_delay_int);
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);
15072 ! gst_object_unref(sink);
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
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);
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);
15113 ! ePtr<eStaticServiceMP3Info> m_service_info;
15116 ! class eStaticServiceMP3Info: public iStaticServiceInformation
15118 ! DECLARE_REF(eStaticServiceMP3Info);
15119 ! friend class eServiceFactoryMP3;
15120 ! eStaticServiceMP3Info();
15122 ! RESULT getName(const eServiceReference &ref, std::string &name);
15123 ! int getLength(const eServiceReference &ref);
15124 ! int getInfo(const eServiceReference &ref, int w);
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);
15139 ! virtual ~eServiceMP3();
15141 ! // iPlayableService
15142 ! RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
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
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);
15209 ! int getAC3Delay();
15210 ! int getPCMDelay();
15211 ! void setAC3Delay(int);
15212 ! void setPCMDelay(int);
15214 ! struct audioStream
15217 ! audiotype_t type;
15218 ! std::string language_code; /* iso-639, if available. */
15219 ! std::string codec; /* clear text codec description */
15221 ! :pad(0), type(atUnknown)
15225 ! struct subtitleStream
15229 ! std::string language_code; /* iso-639, if available. */
15235 ! struct sourceStream
15237 ! audiotype_t audiotype;
15238 ! containertype_t containertype;
15240 ! bool is_streaming;
15242 ! :audiotype(atUnknown), containertype(ctNone), is_video(FALSE), is_streaming(FALSE)
15246 ! struct bufferInfo
15248 ! int bufferPercent;
15251 ! int64_t bufferingLeft;
15253 ! :bufferPercent(0), avgInRate(0), avgOutRate(0), bufferingLeft(-1)
15259 ! std::string error_message;
15260 ! std::string missing_codec;
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;
15284 ! stIdle, stRunning, stStopped,
15287 ! GstElement *m_gst_playbin;
15288 ! GstTagList *m_stream_tags;
15295 ! Message(int type)
15298 ! Message(int type, GstPad *pad)
15306 ! GstPad *pad; // for msg type 3
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;
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);
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);
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);
15384 ! ePtr<eStaticServiceMP3Info> m_service_info;
15387 ! class eStaticServiceMP3Info: public iStaticServiceInformation
15389 ! DECLARE_REF(eStaticServiceMP3Info);
15390 ! friend class eServiceFactoryMP3;
15391 ! eStaticServiceMP3Info();
15393 ! RESULT getName(const eServiceReference &ref, std::string &name);
15394 ! int getLength(const eServiceReference &ref);
15395 ! int getInfo(const eServiceReference &ref, int w);
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);
15410 ! virtual ~eServiceMP3();
15412 ! // iPlayableService
15413 ! RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
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
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);
15480 ! int getAC3Delay();
15481 ! int getPCMDelay();
15482 ! void setAC3Delay(int);
15483 ! void setPCMDelay(int);
15485 ! struct audioStream
15488 ! audiotype_t type;
15489 ! std::string language_code; /* iso-639, if available. */
15490 ! std::string codec; /* clear text codec description */
15492 ! :pad(0), type(atUnknown)
15496 ! struct subtitleStream
15500 ! std::string language_code; /* iso-639, if available. */
15506 ! struct sourceStream
15508 ! audiotype_t audiotype;
15509 ! containertype_t containertype;
15511 ! bool is_streaming;
15513 ! :audiotype(atUnknown), containertype(ctNone), is_video(FALSE), is_streaming(FALSE)
15517 ! struct bufferInfo
15519 ! int bufferPercent;
15522 ! int64_t bufferingLeft;
15524 ! :bufferPercent(0), avgInRate(0), avgOutRate(0), bufferingLeft(-1)
15530 ! std::string error_message;
15531 ! std::string missing_codec;
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;
15555 ! stIdle, stRunning, stStopped,
15558 ! GstElement *m_gst_playbin;
15559 ! GstTagList *m_stream_tags;
15566 ! Message(int type)
15569 ! Message(int type, GstPad *pad)
15577 ! GstPad *pad; // for msg type 3
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;
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);
15623 Only in Enigma2PC_orig: rollback_lirc_support.diff