745 Commits

Author SHA1 Message Date
Thilo Graf
ea00f01dcc update version 1.0.2-mpx
eplayer beta
2017-12-21 10:54:07 +01:00
TangoCash
ef4260b6b2 armbox eplayer: reactivate audio, subtitle and chapters 2017-12-21 10:43:24 +01:00
TangoCash
3d6689cfca armbox eplayer: add chapter.c 2017-12-21 10:43:19 +01:00
TangoCash
2a7f1bb1fa armbox eplayer: add chapters 2017-12-21 10:43:13 +01:00
TangoCash
f5c1ff725f armbox eplayer: align to last commits 2017-12-21 10:43:06 +01:00
TangoCash
c15484e01a armbox eplayer: use other tracklist 2017-12-21 10:42:54 +01:00
TangoCash
e5a50e7126 armbox eplayer: add metadata 2017-12-21 10:42:48 +01:00
TangoCash
6bc9d6a949 armbox eplayer: small fix TTX 2017-12-21 10:42:37 +01:00
max_10
3ca9c451a4 libeplayer3-arm: fix playback (thx DboxOldie) 2017-12-21 10:42:12 +01:00
max_10
011f009ece fix video policy 2017-12-21 10:41:26 +01:00
TangoCash
f9b1b8aa58 fix close files 2017-12-21 10:41:15 +01:00
svenhoefer
5d1406b93c - Makefile: disable libstb_hal_test stuff; this completes 188f10dd86
Signed-off-by: Thilo Graf <dbt@novatux.de>
2017-12-21 10:39:31 +01:00
TangoCash
09aa5e9ac5 generic gestreamer align to armbox 2017-12-21 10:38:34 +01:00
TangoCash
fea27b6160 gstreamer: increase seek accuracy 2017-12-21 10:36:54 +01:00
svenhoefer
228b58137c - generic-pc/audio: fix segfault in getAudioInfo() function
Signed-off-by: Thilo Graf <dbt@novatux.de>
2017-12-18 19:49:41 +01:00
TangoCash
c2a574aa4b fix compile 2017-12-18 19:47:21 +01:00
max_10
b75f8393c2 add libeplayer3-arm test 2017-12-18 19:47:06 +01:00
max_10
f28d013972 acinclude: some more minor format changes 2017-12-18 19:46:46 +01:00
max_10
7f081bee8c libeplayer3: code format 2017-12-18 19:46:34 +01:00
max_10
c0ef130e8e armbox: fix write value hex
Signed-off-by: Thilo Graf <dbt@novatux.de>

ax needs hex
2017-12-04 10:39:12 +01:00
Jacek Jendrzej
f5e07c5704 fix max apids 2017-11-23 09:29:40 +01:00
Jacek Jendrzej
188f10dd86 disable test 2017-11-23 08:56:38 +01:00
Jacek Jendrzej
3ac8fa2080 write m2v direct to device 2017-11-22 10:10:01 +01:00
TangoCash
8a3ba60e14 align gststreamer findallpids to eplayers logic 2017-11-21 09:52:58 +01:00
TangoCash
6af94cc719 porting av converter to sh4 2017-11-21 09:52:58 +01:00
Jacek Jendrzej
03446f4122 fix possible memleak 2017-11-17 16:20:42 +01:00
Jacek Jendrzej
6649d6250a convert pix fmt 2017-11-17 15:29:20 +01:00
Jacek Jendrzej
545fb415b2 fix logic and possible memleak 2017-11-17 06:34:13 +01:00
Jacek Jendrzej
e0effa50e2 fix last commit 2017-11-16 19:10:40 +01:00
Jacek Jendrzej
702b8d6085 check alloc AVFormatContext 2017-11-16 19:09:16 +01:00
Jacek Jendrzej
193fcf4ea1 fix close fp 2017-11-16 18:58:13 +01:00
Jacek Jendrzej
e86301004a convert jpg to m2v with libavcodec, need --enable-demuxer=image2 2017-11-16 18:51:01 +01:00
TangoCash
d016c7315e cleanup 2017-11-16 15:06:43 +01:00
TangoCash
afa6b14f46 cleanup 2017-11-16 15:06:43 +01:00
TangoCash
cde1e655f3 fix 0648 caid issue (dbo!!!) 2017-11-14 18:04:54 +01:00
Jacek Jendrzej
32a72a7357 sync with oher repo 2017-11-14 15:24:03 +01:00
Jacek Jendrzej
0b9575ff7f fix merge error 2017-11-14 15:13:13 +01:00
Jacek Jendrzej
5662d18602 fix last commit 2017-11-14 12:55:11 +01:00
Jacek Jendrzej
ceb1620bcd remove double keys 2017-11-14 11:33:38 +01:00
vanhofen
70cdad0db1 - add display_has_statusline member
Signed-off-by: Jacek Jendrzej <satbaby@kawaii.com>
2017-11-14 09:43:22 +01:00
vanhofen
6c0d55da96 - generic-pc: add our proven keymap to glfb 2017-11-14 09:41:02 +01:00
Jacek Jendrzej
64828627ac try to fix possible race condition 2017-11-13 09:44:47 +01:00
Jacek Jendrzej
fc5d505995 init mpegts 2017-11-12 08:58:18 +01:00
Jacek Jendrzej
dcce5347b1 Revert "return false in decoder have no time"
This reverts commit 6f006f1ce9.
2017-11-12 08:57:41 +01:00
Jacek Jendrzej
b67c8b39b5 fix last commit, broken check logic 2017-11-11 17:08:51 +01:00
Jacek Jendrzej
50904a1825 check if tag is gst list 2017-11-11 16:55:02 +01:00
Jacek Jendrzej
6f006f1ce9 return false in decoder have no time 2017-11-11 16:52:38 +01:00
Jacek Jendrzej
2864b81fe2 try to fix freeze with subtitle file , use gst_element_get_state only if need 2017-11-11 16:29:28 +01:00
TangoCash
bc4a9b3329 fix missing close fd (thx dbo) 2017-11-11 15:23:05 +01:00
Jacek Jendrzej
2bbb8a9044 move gchar * sourceName = gst_object_get_name(source); 2017-11-10 16:17:40 +01:00
Jacek Jendrzej
be5bf56314 check m_stream_tags if not NULL 2017-11-10 12:50:15 +01:00
Jacek Jendrzej
d9b7971e30 add check if children not NULL 2017-11-10 12:37:46 +01:00
Jacek Jendrzej
b75667176b fix memleak, init and compil 2017-11-10 12:25:58 +01:00
TangoCash
1e8e9bcc4d gstreamer playback: fix possible race condition 2017-11-10 12:20:28 +01:00
TangoCash
54341f0c48 gstreamer playback: fix possible segfault 2017-11-10 12:20:28 +01:00
TangoCash
31a73a2bd5 gstreamer playback: remove subtitles until fully supported 2017-11-08 10:18:15 +01:00
TangoCash
a811b733d4 gstreamer playback: fix possible segfaults 2017-11-08 10:18:15 +01:00
TangoCash
f170c38f10 CI: fix some caid issues (thx dboxoldie) 2017-11-08 10:18:15 +01:00
Thilo Graf
0040c0d0af Merge branch 'master' of https://github.com/TangoCash/libstb-hal-cst-next.git into mpx
update version 1.0.1

 Conflicts:
	include/hardware_caps.h
	libarmbox/hardware_caps.c
	libduckbox/hardware_caps.c
	libspark/hardware_caps.c
2017-11-06 15:22:18 +01:00
max_10
a513b0bf38 ci: armbox fix cpu load 2017-11-06 00:03:40 +01:00
TangoCash
cdbe044627 fix compile #2 2017-11-05 16:58:19 +01:00
TangoCash
b5820fadde fix compile 2017-11-05 16:57:11 +01:00
max_10
8886015bac armbox: add dvbci (thx DboxOldie) 2017-11-05 16:02:44 +01:00
TangoCash
dfeace50a5 armbox: tryfix cec 2017-11-05 14:25:01 +01:00
TangoCash
7c919eaf32 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-11-05 13:55:23 +01:00
TangoCash
71c9c9d8e3 ci: let stbhal handle close 2017-11-05 13:54:42 +01:00
TangoCash
97f7c230e3 gstreamer playback, cleanup, fix real pid handling 2017-11-04 11:13:48 +01:00
TangoCash
28aa5147c6 gstreamer playback, avoid segfault 2017-11-03 22:35:08 +01:00
TangoCash
cccd010efb gstreamer playback, fix possible segfault #2 2017-11-03 22:30:24 +01:00
TangoCash
161feb4cf4 gstreamer playback, fix possible segfault 2017-11-03 22:25:11 +01:00
TangoCash
8218368064 update generic gstreamer 2017-11-03 21:18:53 +01:00
TangoCash
4b716df43c Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-11-03 13:44:12 +01:00
TangoCash
464838fd24 align 2017-11-03 12:12:32 +01:00
Thilo Graf
969377d8b6 version 1.0.0-mpx
hd51 support
2017-11-02 17:31:37 +01:00
Thilo Graf
917034fcd9 adjust .gitignore for untracked files 2017-11-02 17:25:49 +01:00
Thilo Graf
f9164dafb0 add default files 2017-11-02 17:23:50 +01:00
Thilo Graf
0380de3225 add update script 2017-11-02 17:23:48 +01:00
svenhoefer
5bbfc8fa6d - rename can_set_display_brightness => display_can_set_brightness
Signed-off-by: Thilo Graf <dbt@novatux.de>
2017-11-02 17:23:37 +01:00
svenhoefer
3b7613b778 - add display_can_deepstandby member
Signed-off-by: Thilo Graf <dbt@novatux.de>
2017-11-02 17:22:56 +01:00
Jacek Jendrzej
9a61e6264e fix null list 2017-11-02 14:56:04 +01:00
Jacek Jendrzej
7c4935a1c9 fix get play position 2017-11-02 14:55:52 +01:00
TangoCash
88ce7b707d gstreamer: reset pids at start 2017-11-01 10:02:38 +01:00
TangoCash
ca49904d31 gstreamer playback - get real apid from TS 2017-11-01 00:25:04 +01:00
TangoCash
a725528747 armbox: fullscreen osd ;) 2017-10-31 09:55:45 +01:00
TangoCash
5ef8f2edad gstreamer: fix lang detection 2017-10-30 21:00:23 +01:00
TangoCash
11bccbe4b7 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-10-29 13:25:20 +01:00
max_10
f6ecb88ba0 libdvbci: log cosmetic 2017-10-28 22:29:12 +02:00
TangoCash
564e40bd72 armbox: fix get blank 2017-10-28 22:16:28 +02:00
TangoCash
b443fa07ac fixup gstreamer tags 2017-10-28 19:56:28 +02:00
TangoCash
d908c7a947 armbox: gstreamer tags support 2017-10-28 18:10:04 +02:00
TangoCash
5509c8c0c6 fix coverart 2017-10-27 23:38:20 +02:00
TangoCash
cf81628998 armbox: fix audio playback #2 2017-10-27 22:40:16 +02:00
TangoCash
f9e91b6b42 armbox: fix audio playback 2017-10-27 22:35:02 +02:00
TangoCash
f31f21be0c armbox: add video/audio pid 2017-10-27 22:21:30 +02:00
TangoCash
d70a853a05 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-10-24 19:29:56 +02:00
Jacek Jendrzej
cb33592f3c fix get play position 2017-10-24 19:27:03 +02:00
Jacek Jendrzej
95ff777250 fix null list 2017-10-24 19:26:51 +02:00
max_10
402a0bca87 Merge remote-tracking branch 'tangocash/master' 2017-10-24 14:25:29 +02:00
max_10
2d571948d8 eDVBCISlot forgotten 2017-10-24 00:19:29 +02:00
TangoCash
d17ffb727b Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-10-23 23:38:18 +02:00
max_10
400d8f0ecd rename tSlot -> eDVBCISlot 2017-10-23 23:30:10 +02:00
TangoCash
908cbc3c7c Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-10-23 23:20:36 +02:00
max_10
c41f0ea13d modification sendDateTime 2017-10-23 23:16:18 +02:00
max_10
42811846d7 rename tSlot -> eDVBCISlot 2017-10-23 23:14:22 +02:00
Jacek Jendrzej
3ec44df06f fix uri for http 2017-10-23 20:48:39 +02:00
TangoCash
e4fca206a2 partly revert last commit 2017-10-22 11:03:04 +02:00
TangoCash
07d9206a56 armbox: fix gst playback 2017-10-22 10:46:57 +02:00
TangoCash
6f261730ff armbox: gstreamer - fix init jump, cleanup 2017-10-21 18:28:57 +02:00
Jacek Jendrzej
5ae1ba0530 rmove unused code 2017-10-20 19:41:01 +02:00
TangoCash
36cc88ad7e fix typo 2017-10-19 21:42:11 +02:00
TangoCash
0b69bc17f9 armbox: improve cec 2017-10-19 21:39:55 +02:00
TangoCash
9bdcb65a61 armbox: tryfix cec 2017-10-19 21:12:05 +02:00
TangoCash
99eb4a3c7f armbox: tryfix lost of video device after playing something with gst 2017-10-18 21:05:28 +02:00
max_10
afdef2dc28 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-10-18 12:55:36 +02:00
max_10
fd64d23383 ca_ci: in some situations missing scambled flag (thx DboxOldie) 2017-10-18 12:54:19 +02:00
TangoCash
6d62e3c922 ca_ci: in some situations missing scambled flag (thx dbo) 2017-10-18 12:51:00 +02:00
TangoCash
0dd25ef8fb ca_ci: in some situations missing scambled flag (thx dbo) 2017-10-18 12:50:34 +02:00
TangoCash
4ccbffeb31 armbox: fix still image 2017-10-17 19:53:02 +02:00
TangoCash
18d6e271e2 armbox: fix devices 2017-10-17 18:39:21 +02:00
TangoCash
07b59f07dd armbox add missing header file 2017-10-17 18:39:10 +02:00
TangoCash
a3ecb31bc9 armbox: start implementing cec support 2017-10-17 18:00:36 +02:00
TangoCash
6268ebdb1b partly revert last commit 2017-10-15 18:06:43 +02:00
TangoCash
ec61bd0a3e armbox: let gst playback handle devices 2017-10-15 17:25:04 +02:00
TangoCash
73a12abdb8 armbox: adding header and user_agent to gst playback 2017-10-15 16:55:19 +02:00
TangoCash
fec61c7e1c armbox: gst-playback reformat code 2017-10-15 16:06:48 +02:00
TangoCash
6dcf797dba armbox: fix gst seeking 2017-10-15 15:10:18 +02:00
TangoCash
baf59692c6 fix last commit 2017-10-15 12:26:54 +02:00
TangoCash
8ad83136ce fix last commit 2017-10-15 12:25:20 +02:00
TangoCash
ba0766f0c0 fix gst playback 2017-10-15 12:23:46 +02:00
TangoCash
efc486301f armbox: enable DTS passthrough 2017-10-11 20:42:05 +02:00
TangoCash
a2fc1d51ee Revert "libeplayer3: switch off the teletext sub"
This reverts commit 1356d700be.
2017-10-08 13:14:30 +02:00
TangoCash
e465f24ead Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-10-08 12:53:06 +02:00
TangoCash
8a5b174917 Merge pull request #3 from MaxWiesel/master
:)
2017-10-08 12:44:07 +02:00
max_10
b0f09fd723 armbox: modification GetVideoSystem 2017-10-08 01:08:53 +02:00
max_10
03ca73f8f5 Merge remote-tracking branch 'tangocash/master' 2017-10-07 23:32:49 +02:00
TangoCash
c4d16f29c7 HMDI ac3 passthrough/downmix 2017-10-07 23:20:07 +02:00
TangoCash
0fc12438db armbox: remove audiomixers 2017-10-07 23:02:24 +02:00
max_10
5c0741a8e3 armbox: delete parts of sh4 code 2017-10-07 21:53:16 +02:00
max_10
86244ea952 armbox: remove dead code from cDemux 2017-10-07 21:04:31 +02:00
max_10
a5ee425996 armbox: remove videodecoder hack from dmx destructor 2017-10-07 21:02:27 +02:00
max_10
be07c1a1b7 armbox: use proc_tools 2017-10-07 21:00:08 +02:00
Stefan Seyfried
3f6cee32f4 spark: remove dead code from cDemux 2017-10-07 20:25:44 +02:00
Stefan Seyfried
9f1c5a6c59 spark: remove videodecoder hack from dmx destructor 2017-10-07 20:25:26 +02:00
Stefan Seyfried
b67a0a7e44 spark: fix race condition in cDemux
cDemux destructor was racing with Read() which did lead to all
sorts of nasty crashes because after poll returned, the dmx object
could be gone and its memory replaced with totally different things.
2017-10-07 20:25:11 +02:00
max_10
70d7730f82 fix cherry-pick 2017-10-07 20:24:51 +02:00
Stefan Seyfried
4285d9449d libspark: implement cVideo::GetVideoSystemFormatName() 2017-10-07 20:24:23 +02:00
Stefan Seyfried
1093c2b217 libspark: implement cVideo::GetVideoSystem() 2017-10-07 20:24:02 +02:00
max_10
6b2e3594fa Revert "implement GetVideoSystem"
This reverts commit 23afdef65c.
2017-10-07 20:23:32 +02:00
max_10
5ce57d6f57 Revert "align videomodes"
This reverts commit b66a63553b.
2017-10-07 20:23:15 +02:00
max_10
18f3fbd8b9 Revert "align videomodes"
This reverts commit 7f9a31d29c.
2017-10-07 20:22:40 +02:00
Stefan Seyfried
d57ac2cbdd spark/video: add missing O_CLOEXEC to memory fd 2017-10-07 20:20:44 +02:00
Stefan Seyfried
ba7a351f59 spark/video: implicitly do StopPicture() on CVideo::Start()
This seems to be what the coolstream code does.
TODO: look out for side effects (in radio mode etc...)
2017-10-07 20:19:53 +02:00
Stefan Seyfried
0d30ab013e spark: use proc_tools 2017-10-07 20:19:18 +02:00
max_10
6f914f7a45 add video_cs.h header to reduce number of #ifdefs needed 2017-10-07 19:41:49 +02:00
Stefan Seyfried
ceeb9a4f06 spark: remove dead code from cDemux 2017-10-07 18:10:20 +02:00
Stefan Seyfried
72f78ba5b7 spark: remove videodecoder hack from dmx destructor 2017-10-07 18:08:53 +02:00
Stefan Seyfried
c8f8e457f6 spark: fix race condition in cDemux
cDemux destructor was racing with Read() which did lead to all
sorts of nasty crashes because after poll returned, the dmx object
could be gone and its memory replaced with totally different things.
2017-10-07 18:06:26 +02:00
max_10
394e72444d fix cherry-pick 2017-10-07 17:49:09 +02:00
max_10
70863f46d9 acinclude: remove unused TUXBOX_APPS_* stuff 2017-10-07 17:31:46 +02:00
max_10
b26e5ee586 acinclude: remove unused boxtypes 2017-10-07 17:29:36 +02:00
Stefan Seyfried
57f9165852 libspark: implement cVideo::GetVideoSystemFormatName() 2017-10-07 17:17:11 +02:00
Stefan Seyfried
86b43b40e4 libspark: implement cVideo::GetVideoSystem() 2017-10-07 17:09:40 +02:00
max_10
ff94afb0c2 Revert "implement GetVideoSystem"
This reverts commit 23afdef65c.
2017-10-07 17:08:50 +02:00
max_10
1bd610e6e8 Revert "align videomodes"
This reverts commit b66a63553b.
2017-10-07 17:08:29 +02:00
max_10
196cbf0021 Revert "align videomodes"
This reverts commit 7f9a31d29c.
2017-10-07 17:08:04 +02:00
Stefan Seyfried
d1f2e0d286 spark/video: add missing O_CLOEXEC to memory fd 2017-10-07 17:05:13 +02:00
Stefan Seyfried
e66e7c34e9 spark/video: implicitly do StopPicture() on CVideo::Start()
This seems to be what the coolstream code does.
TODO: look out for side effects (in radio mode etc...)
2017-10-07 17:03:27 +02:00
Stefan Seyfried
f798ff9d71 spark: use proc_tools 2017-10-07 17:02:26 +02:00
max_10
754e529714 Merge remote-tracking branch 'tangocash/master' 2017-10-06 22:38:51 +02:00
TangoCash
6367dfc13f armbox: make open/close device public 2017-10-06 21:57:04 +02:00
max_10
730b2dfb3f Merge remote-tracking branch 'tangocash/master' 2017-10-05 19:26:50 +02:00
TangoCash
36e2ff6d68 re-arrange gstreamer code 2017-10-05 15:27:01 +02:00
TangoCash
cb74eae85b fix audio/video devices 2017-10-05 15:26:25 +02:00
TangoCash
63c02d0f24 fix armbox realname 2017-10-05 15:23:39 +02:00
TangoCash
3ece63839e adding 4k video settings for armbox 2017-10-01 13:35:40 +02:00
TangoCash
e5547c17ed fix generic compile 2017-10-01 12:00:48 +02:00
TangoCash
57ae0340c8 adding 4k video settings for armbox 2017-10-01 11:56:28 +02:00
max_10
b21afd56b1 libarmbox: adjustments 2017-09-26 14:16:42 +02:00
max_10
baf540d79f libarmbox: del libass LDFLAGS 2017-09-26 14:15:14 +02:00
max_10
2054081eeb libarmbox delete unnecessary code 2017-09-25 14:49:38 +02:00
max_10
5b2c79b80b Merge remote-tracking branch 'tangocash/master' 2017-09-19 18:27:01 +02:00
max_10
7cc65ef533 duplicate entry removed 2017-09-19 17:47:21 +02:00
max_10
1356d700be libeplayer3: switch off the teletext sub 2017-09-19 12:13:38 +02:00
TangoCash
b55bbce62d fix armbox vfd 2017-09-18 19:57:12 +02:00
max_10
c2b0d46a4e Merge remote-tracking branch 'tangocash/master' 2017-09-17 21:54:06 +02:00
TangoCash
63cb1f936c armbox: align to demuxes 2017-09-17 20:54:10 +02:00
TangoCash
17b3fefac8 armbox: fix PIG 2017-09-17 20:53:57 +02:00
TangoCash
7e61b2a3ea fix gst flags 2017-09-17 20:37:57 +02:00
max_10
814f92096b cs_api.h: add missing cs_get_chip_type() dummy 2017-09-15 14:29:29 +02:00
max_10
ee1ca3ff65 add video_cs.h header to reduce number of #ifdefs needed 2017-09-15 13:19:21 +02:00
max_10
f7786867c4 acinclude: add arm boxtypes 2017-09-14 23:42:04 +02:00
max_10
ab0c4a8d47 acinclude: remove unused TUXBOX_APPS_* stuff 2017-09-14 23:37:22 +02:00
max_10
7e4b69f3b9 acinclude: remove unused boxtypes 2017-09-14 23:33:45 +02:00
TangoCash
33f05feccc fix armbox frontpanel 2017-09-12 17:12:00 +02:00
TangoCash
d8c3c47b86 adding armbox 2017-09-12 16:10:27 +02:00
TangoCash
79c098ec3d Merge branch 'master' of github.com:TangoCash/libstb-hal-cst-next 2017-09-12 10:08:11 +02:00
TangoCash
1e32448978 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-09-12 10:07:20 +02:00
max_10
88f0252368 avoid segfault when ci handler uses the cs_messenger until neutrino has not register it (thx DboxOldie) 2017-09-01 21:15:17 +02:00
TangoCash
599fd6df5a modify ac3flags 2017-07-28 16:17:30 +02:00
Jacek Jendrzej
181936ae81 fix compile 2017-07-28 16:16:43 +02:00
Jacek Jendrzej
abac47e04d generic-pc/video.cpp dont set output format with negative height size 2017-07-28 16:00:56 +02:00
TangoCash
c6bc573607 small fix for gstreamer 1.0 playback 2017-07-28 15:59:51 +02:00
TangoCash
4b70aa585c small fix for gstreamer 1.0 playback 2017-07-28 15:59:27 +02:00
TangoCash
c14e9d7713 adding initial support for gstreamer 1.0 2017-07-28 15:58:50 +02:00
Jacek Jendrzej
ad24fab431 fix compile 2017-07-15 20:06:13 +02:00
Jacek Jendrzej
2e765e73c2 generic-pc/video.cpp dont set output format with negative height size 2017-07-15 19:58:56 +02:00
TangoCash
717a2ee583 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-06-20 20:14:05 +02:00
TangoCash
42cb750c5e fix indents and brackets 2017-06-20 18:58:09 +02:00
j00zek
dc9ef37866 correct info for dsi87 2017-06-20 18:34:22 +02:00
j00zek
b96dc38eb4 update tuners info 2017-06-20 18:32:08 +02:00
TangoCash
217a92f9ab Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-06-18 12:02:05 +02:00
TangoCash
d83f6dbfe4 re-enabled Display Brightness (thx dbo) 2017-06-17 21:02:05 +02:00
TangoCash
a2a3740c53 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal-cst-next 2017-06-09 14:27:50 +02:00
TangoCash
7f9a31d29c align videomodes 2017-06-09 14:03:09 +02:00
TangoCash
b66a63553b align videomodes 2017-06-09 14:01:47 +02:00
TangoCash
23afdef65c implement GetVideoSystem 2017-06-09 13:25:49 +02:00
TangoCash
fcfd96f8cd small fix for gstreamer 1.0 playback 2017-05-31 22:43:56 +02:00
TangoCash
a1f7fb9217 small fix for gstreamer 1.0 playback 2017-05-31 20:07:43 +02:00
TangoCash
a5198e44d2 adding initial support for gstreamer 1.0 2017-05-31 18:18:59 +02:00
TangoCash
ddc3bf3d30 -playback: fix compiling generic pc 2017-05-04 12:39:23 +02:00
TangoCash
5d72d67cca fix generic compile 2017-04-04 11:03:37 +02:00
TangoCash
ffd2fd0ce4 Merge pull request #2 from Duckbox-Developers/master
fix generic
2017-03-10 21:50:14 +01:00
TangoCash
5628130216 fix generic 2017-03-10 21:49:33 +01:00
TangoCash
44832d72fe Merge pull request #1 from Duckbox-Developers/master
adopt hw_caps
2017-03-10 21:39:48 +01:00
TangoCash
ae3cc86f0b adopt hw_caps 2017-03-10 21:38:31 +01:00
TangoCash
04d7e53c2b modify ac3flags 2016-11-18 16:07:44 +01:00
max
c4c5564b91 Merge pull request #5 from OpenAR-P/duckbox
Enable aac writer and use resmpling for some AAC streams thx Taapat  …
2016-10-31 10:28:36 +01:00
schpuntik
73483990f8 Enable aac writer and use resmpling for some AAC streams thx Taapat and technik 2016-10-31 02:06:05 +01:00
max10
19b576a45c no-stream-info 2016-09-29 20:14:13 +02:00
max10
192f42304e Improve CI handling (thx DboxOldie) 2016-09-18 18:49:44 +02:00
max10
db4a96588e fix ci-logic (thx DboxOldie) 2016-08-13 18:26:21 +02:00
max10
72f27a8fe5 ci-change-service-bug (thx DboxOldie) 2016-08-11 20:49:23 +02:00
max10
7f178d38f9 ci-alc automatically Multi-Decrypt 2016-08-05 23:23:33 +02:00
TangoCash
b60543ad6b add support for H265 supplemental #2 2016-07-24 17:47:34 +02:00
TangoCash
fe78a13e05 add support for H265 supplemental 2016-07-24 17:44:27 +02:00
TangoCash
0bed01e919 add support for H265 2016-07-24 17:14:43 +02:00
max10
37c20923ce simplyfi-c* (thx DboxOldie) 2016-07-11 16:42:18 +02:00
max10
bef98c2e91 add two-same-cip (thx DboxOldie) 2016-07-08 12:13:23 +02:00
max10
9173ae1b47 LocalTV and Entertain-TV streaming 2016-06-30 19:14:36 +02:00
max10
2e2b406af5 fix local-tv 2016-06-25 15:16:41 +02:00
max10
f953aa3b62 fix ci* **04 2016-06-20 00:23:47 +02:00
max10
ffd0f972f9 add channelid-check (thx DboxOldie) 2016-06-15 19:55:18 +02:00
max10
0215a673f5 update for spark uinput 2016-06-12 16:53:31 +02:00
max10
1feb9692c3 fix commit 8d6a7f8c3e 2016-06-05 11:20:38 +02:00
TangoCash
f87bd09bd4 Merge pull request #4 from sid8796/master
add boxmodel hl101
2016-05-14 20:00:21 +02:00
sid8796
9d7cb6de30 add boxmodel hl101 2016-05-14 19:54:05 +03:00
j00zek
63e9f9178f fix compilation with ffmpeg 3.0.1 2016-04-22 12:07:48 +02:00
max10
055fa18dbf re add old calcPts 2016-04-15 21:13:12 +02:00
max10
c340015ab2 fix input avlog thx DboxOldie 2016-04-05 20:33:23 +02:00
max10
379cc9515b Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal 2016-04-03 10:46:05 +02:00
max10
8d6a7f8c3e eplayer fix init tectime aac thx DboxOldie 2016-04-03 10:44:45 +02:00
TangoCash
36f199b2fa porting cookie.patch to generic 2016-04-03 09:35:35 +02:00
max10
182baf4e57 add cookie.patch thx DboxOldie 2016-04-03 00:06:31 +02:00
TangoCash
747c5cb3f1 fix generic compile 2016-03-26 12:23:02 +01:00
TangoCash
944c27e51f fix char conversion 2016-03-26 12:19:37 +01:00
TangoCash
e73708b71c fix last commit 2016-03-26 12:09:34 +01:00
TangoCash
fd23101501 fix header 2016-03-26 12:03:13 +01:00
max10
8e99bc5cac fix spark ca (thx DboxOldie) 2016-02-24 23:27:45 +01:00
max10
741a34541f test c** 2015-12-05 17:55:22 +01:00
max10
295230d947 test c** 2015-12-02 21:49:24 +01:00
max10
92bd8b9ab9 test c** 2015-11-21 18:39:31 +01:00
max10
8a10609125 test c** 2015-11-20 15:40:19 +01:00
max10
46f67aaef0 test c** 2015-11-18 17:16:39 +01:00
max10
91b9bb6c9e test c** 2015-11-18 17:16:23 +01:00
max10
5ed2d1c73e test c** 2015-11-16 15:26:15 +01:00
max10
ca27972f16 test c** 2015-11-15 20:29:20 +01:00
TangoCash
43ded09d01 compile fix 2015-11-14 08:09:44 +01:00
max10
f7b22b485d test c** 2015-11-13 21:13:47 +01:00
max10
6ceed686a6 test c** 2015-11-12 19:31:21 +01:00
max10
9c71111851 Merge branch 'master' of github.com:Duckbox-Developers/libstb-hal 2015-11-11 12:28:12 +01:00
max10
242f8a8c88 add cuberevo_3000hd (Thx to jaro44) 2015-11-11 12:27:05 +01:00
TangoCash
94df5aeb1f fix build neutrino without c** 2015-11-10 23:21:03 +01:00
max10
9f3e34d4ad Adjustment Neutrino 2015-11-10 22:11:56 +01:00
max10
fe8b1237ac test c** 2015-11-10 15:55:48 +01:00
max10
890f4e2ea3 test c** 2015-11-10 00:08:40 +01:00
max10
0bbcfaf171 test c** 2015-11-10 00:00:04 +01:00
TangoCash
7ec6b85fa3 silence debug 2015-07-03 11:30:56 +02:00
max10
ce16e4a603 acinclude.m4: fix spark 2015-05-08 15:21:18 +02:00
Stefan Seyfried
030f06cee2 libeplayer3: try to fix dynamic linking
Conflicts:
	libeplayer3/Makefile.am
	libspark/Makefile.am

Conflicts:
	libeplayer3/Makefile.am
2015-05-04 11:28:58 +02:00
max10
5154d69a30 fix libspark/playback_libeplayer3: switch to lt_info/lt_debug 2015-05-04 11:22:30 +02:00
Stefan Seyfried
ba133fba30 spark: do not freeze/continue in GetScreenImage() 2015-05-04 11:21:12 +02:00
Stefan Seyfried
c1076ec35b fix wrong libtool initialization order
allow to build dynamic libraries (but keep static as default)
2015-05-04 11:20:58 +02:00
Stefan Seyfried
240eecde22 spark: implement GetScreenImage for video and audio
Conflicts:
	libspark/video.cpp
2015-05-04 11:20:02 +02:00
Stefan Seyfried
95cdd648c4 includes: remove *_td.h, we use is *_hal.h now 2015-05-04 11:19:37 +02:00
Stefan Seyfried
1497949fd5 libspark/playback_libeplayer3: fix EOF signalling
Conflicts:
	libspark/playback_libeplayer3.cpp
2015-05-04 11:19:05 +02:00
Stefan Seyfried
5f134156a9 libspark/playback_libeplayer3: switch to lt_info/lt_debug
Conflicts:
	libspark/playback_libeplayer3.cpp
2015-05-04 11:18:16 +02:00
Stefan Seyfried
d6d6b4a242 libeplayer3: remove absolute file names
this makes debug output nicer to read for out-of-tree builds
2015-05-04 11:14:52 +02:00
max10
13740f57b6 spark7162 without evremote2 2015-04-24 22:28:23 +02:00
max10
1bca61569e fix generic-pc: ffmpeg is deprecated 2015-04-22 14:26:19 +02:00
j00zek
b7bb43a670 [cuberevo] fix query model logic 2015-04-07 21:33:06 +02:00
TangoCash
8b534137c9 stop message flooding 2015-03-31 22:51:46 +02:00
j00zek
daa6561b62 [ariva@link200] include in libst-hal 2015-03-21 09:31:30 +01:00
j00zek
5d8fef5dc4 fix last commit 2015-03-21 08:31:21 +01:00
j00zek
c6ae1d4721 add arvia@link200 & co. 2015-03-20 22:34:28 +01:00
max10
53926a6650 Revert "AM_SILENT_RULES on"
This reverts commit 8aa0af7e18.
2015-03-20 14:41:39 +01:00
Stefan Seyfried
c44c3994f7 spark: clear video in StopPicture()
this fixes video playback after audioplayer or upnp browser

Conflicts:
	libspark/video.cpp
2015-03-17 18:41:17 +01:00
zukon
808354b31e add ipbox 9900, 99, 55 2015-03-11 11:45:42 +01:00
max10
45fda79300 remove aac is only required with gcc 4.8.3 2015-01-30 22:15:23 +01:00
max10
8aa0af7e18 AM_SILENT_RULES on 2015-01-27 22:17:54 +01:00
max10
f2ac0106f2 add cuberevo mini/250hd 2015-01-27 22:16:56 +01:00
max10
f5eca251ce fix libspark 2015-01-13 02:28:42 +01:00
smogm
047d3158c5 fix missing compiler include 2015-01-12 20:43:02 +01:00
smogm
467f6976f7 changed raspi to own thread class 2015-01-12 20:36:56 +01:00
smogm
9ed0a0d244 change libeplayer3 to own thread class 2015-01-12 20:26:52 +01:00
smogm
46166da4ec remove unnecessary Makefile.in 2015-01-12 18:47:02 +01:00
smogm
95ee7f9e98 move libthread to libstb-hal 2015-01-12 18:15:08 +01:00
smogm
3ef2eeb8aa fix thread namespace 2015-01-12 16:38:28 +01:00
smogm
c37263f594 add changed files 2015-01-11 18:12:55 +01:00
smogm
626c785081 add mutex and thread abstraction to common files 2015-01-11 17:58:37 +01:00
smogm
78dd12e2dd add mutex and thread abstraction 2015-01-11 17:52:31 +01:00
TangoCash
410b707f76 implement simple gstreamer_plackback 2015-01-03 19:24:37 +01:00
max10
da66fc3db5 fix compiler warning 2014-12-04 19:49:18 +01:00
max10
e05b1f5b85 fix compiler warning 2014-12-04 15:25:12 +01:00
max10
f3ffe33c53 Revert "so it is better thx DboxOldie"
This reverts commit 8c7441e14b.
2014-12-03 22:15:33 +01:00
max10
be0486e1c8 include/cs_frontpanel.h: fix fp_icon OCTAGON1008 2014-11-28 07:31:58 +01:00
max10
e860372343 test aac 2014-11-24 11:27:53 +01:00
max10
1c89a11f5e Revert "test old calcPts"
This reverts commit 3d4245d76d.
2014-11-24 11:07:48 +01:00
max10
4dc3ce3bd1 Revert "fix commit 3d4245d76df9bb23d2b13c7a01f10b594f81459f"
This reverts commit 3ac6db3b5a.
2014-11-24 11:07:36 +01:00
max10
c20a8fa5af Revert "disable logging"
This reverts commit 4798ce2517.
2014-11-24 11:07:22 +01:00
max10
8c7441e14b Revert "so it is better thx DboxOldie"
This reverts commit 4539ca9937.
2014-11-24 11:07:06 +01:00
max10
aa305f6cf6 Revert "test"
This reverts commit 0072b84bcb.
2014-11-24 11:06:54 +01:00
max10
0072b84bcb test 2014-11-20 22:00:23 +01:00
max10
7680e327cb fix include/cs_frontpanel.h 2014-11-12 17:05:57 +01:00
max10
4d24eac927 update include/cs_frontpanel.h 2014-11-11 23:37:17 +01:00
max10
f44923afe0 Revert "Revert "Revert "libspark/record: Implement writer thread. May or may not improve anything."""
This reverts commit a3ba152ccf.
2014-11-05 16:32:33 +01:00
max10
a3ba152ccf Revert "Revert "libspark/record: Implement writer thread. May or may not improve anything.""
This reverts commit 677776e03a.

Conflicts:
	libspark/record.cpp
2014-11-02 17:24:27 +01:00
max10
726153f71f update cs_frontpanel.h ufs922 2014-10-15 22:16:30 +02:00
max10
9cd14c07bb update cs_frontpanel.h thx DboxOldie 2014-10-15 20:51:05 +02:00
max10
4539ca9937 so it is better thx DboxOldie 2014-10-14 07:16:58 +02:00
max10
a20318bad8 record bs_dmx = 2mb / bs = 4mb 2014-10-12 17:46:42 +02:00
max10
4798ce2517 disable logging 2014-10-12 17:43:36 +02:00
max10
3ac6db3b5a fix commit 3d4245d76d 2014-10-08 23:13:26 +02:00
max10
3d4245d76d test old calcPts 2014-10-08 20:05:01 +02:00
max10
db151715a8 add aac.cpp THX DboxOldie 2014-10-08 17:14:10 +02:00
TangoCash
88f8a280fc small fix 2014-10-07 21:22:33 +02:00
max10
a40f13eb6a update gitignore 2014-10-05 18:57:44 +02:00
max10
93dce8ef8b update boxtype 2014-09-29 10:31:36 +02:00
TangoCash
53be1b06b8 cover support for getmetainfo 2014-09-21 18:56:51 +02:00
TangoCash
18814b385a fix timeshift (thx dbo) 2014-09-21 17:34:30 +02:00
max10
49829b1370 fix include 2014-09-16 19:09:28 +02:00
max10
ba13d72719 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-09-04 11:50:11 +02:00
max10
6992b116ca Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-08-31 17:43:47 +02:00
martii
a8499a543b libspark/playback_libeplayer3: fix multi-program handling 2014-08-31 14:28:20 +02:00
martii
04fb4c9add libeplayer3/manager: use AVDISCARD_NONE instead of AVDISCARD_DEFAULT to disable programs 2014-08-31 12:36:22 +02:00
max10
40461c4cce Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-08-25 18:48:21 +02:00
max10
9b523a87e8 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-08-25 18:43:44 +02:00
martii
8c4b1120df libeplayer3/h264: partially revert 9112c4d16d 2014-08-25 18:36:23 +02:00
martii
6c28142914 libspark/playback: don't show program selection dialog if audio or video pid is already selected 2014-08-25 17:42:30 +02:00
max10
7406f38ec9 fix typo 2014-08-22 23:06:18 +02:00
max10
d15025d6b9 Merge remote-tracking branch 'martiis-libstb-hal/master'
Conflicts:
	libspark/playback_libeplayer3.h
2014-08-22 21:25:26 +02:00
martii
9112c4d16d libeplayer3: implement multi-program support 2014-08-22 18:53:52 +02:00
martii
5fe92a546c libeplayer3/h264: simplify 2014-08-22 18:52:45 +02:00
max10
d57d4bb969 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-07-29 17:23:16 +02:00
martii
a3511c9219 libeplayer3/input: amend 545732a12b 2014-07-28 18:02:50 +02:00
martii
409501eaf0 libeplayer3/input: disable avformat logging 2014-07-27 11:09:45 +02:00
martii
545732a12b libeplayer3/input: don't modify avformat stream id 2014-07-27 10:36:43 +02:00
max10
d542e543b6 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-07-21 21:27:06 +02:00
martii
d1908cec2a fix generic compile 2014-07-21 19:35:55 +02:00
martii
67d34a37a7 libeplayer3/Makefile.am: set AUTOMAKE_OPTIONS = subdir-objects 2014-07-19 16:54:12 +02:00
martii
95b67078d1 libeplayer3/writer: minor cleanup, no binary change 2014-07-16 21:47:34 +02:00
max10
f960811a43 Merge remote-tracking branch 'martiis-neutrino-mp/master' 2014-07-07 21:18:33 +02:00
max10
677776e03a Revert "libspark/record: Implement writer thread. May or may not improve anything."
This reverts commit ada3f5e24a.
2014-07-07 21:14:22 +02:00
max10
dcbf062c43 Revert "libspark/record: remove debugging output accidently left in"
This reverts commit 55f7422715.
2014-07-07 21:13:52 +02:00
max10
38f9e896c5 Revert "libspark/record: always fill read buffer"
This reverts commit f77184cb68.
2014-07-07 21:01:47 +02:00
max10
29a5800ff9 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-06-29 18:28:16 +02:00
martii
656aef8328 libspark/audio: add mixer access methods 2014-06-29 13:00:18 +02:00
max10
c047a8d716 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-06-28 11:03:54 +02:00
martii
f77184cb68 libspark/record: always fill read buffer 2014-06-28 09:33:47 +02:00
max10
e9aa2a73bf Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-06-19 12:57:53 +02:00
martii
ac92e6a38e libeplayer3/player: support bluray urls 2014-06-19 10:46:36 +02:00
max10
9206413947 Merge remote-tracking branch 'martiis-libstb-hal/master'
Conflicts:
	libspark/record.cpp
2014-06-08 23:49:58 +02:00
martii
55f7422715 libspark/record: remove debugging output accidently left in 2014-06-08 19:33:17 +02:00
martii
ada3f5e24a libspark/record: Implement writer thread. May or may not improve anything. 2014-06-08 19:27:12 +02:00
max10
db35ba0aa9 . 2014-06-05 21:15:00 +02:00
max10
48e0aeabc9 . 2014-06-04 22:20:39 +02:00
max10
76c498c2a9 . 2014-06-04 22:07:42 +02:00
max10
ad87948717 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-05-29 23:30:15 +02:00
martii
56ece5b5ea libeplayer3/input: allow access to AVFormatContext 2014-05-29 21:57:38 +02:00
max10
71ce14be99 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-05-24 14:10:29 +02:00
martii
9ac03e1046 libeplayer3/writer/pcm.cpp: break potential infinite loop 2014-05-24 13:05:16 +02:00
martii
8ae08d022c libeplayer3/input.cpp: filter duplicated messages 2014-05-24 13:04:06 +02:00
martii
81391c8998 .gitignore: add 'compile' 2014-05-24 13:02:36 +02:00
max10
df3a3db513 update cs_frontpanel.h 2014-05-19 22:38:18 +02:00
max10
03dfbc9cac Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-05-03 22:49:03 +02:00
martii
5450625bc4 libeplayer3/input: no need for alloca() 2014-05-03 14:29:26 +02:00
martii
f93d4cc794 libeplayer3/input: fix SwitchVideo (unused, but anyway) 2014-05-03 12:35:59 +02:00
martii
67f034a6e8 libspark/hardware_caps: set has_SCART unconditionally 2014-05-03 09:45:17 +02:00
martii
d2de1050ba libeplayer3: limit video frame skipping to network streams 2014-05-02 15:05:47 +02:00
martii
84e5a47f24 libeplayer3: skip video until first audio frame was found 2014-05-02 14:52:10 +02:00
martii
dff15731cb libeplayer3: minor adjustments 2014-05-02 13:34:08 +02:00
max10
22ab9e6f89 [init.cpp] fix spark 2014-05-01 17:01:44 +02:00
martii
e2d9a58fc5 libspark: complement vendor ids 2014-05-01 15:06:27 +02:00
martii
c3ad6b5b23 libeplayer3: fix audio switching on already terminated playback 2014-05-01 12:52:38 +02:00
martii
6eea7139a4 libeplayer3/writer: add fd to writer class 2014-05-01 12:51:41 +02:00
martii
b767224487 libeplayer3/writer: add fd to writer class 2014-05-01 12:51:26 +02:00
martii
e2e5582c64 libeplayer3: cleanup AVFormatContext propagation to writers 2014-05-01 10:15:14 +02:00
martii
eebb7d6b39 libeplayer3/input: fix audio flush packet initialization 2014-05-01 10:01:36 +02:00
martii
18d7a15b88 libeplayer3/input: stream duration fix 2014-04-30 19:08:30 +02:00
max10
93297ca5b8 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-04-27 21:51:20 +02:00
martii
4ba8446079 libspark/init: simplify 2014-04-27 18:46:52 +02:00
martii
246f0416eb libeplayer3: remove flac writer (now handled by mp3 writer) 2014-04-27 12:52:15 +02:00
martii
6e01c872da libeplayer3: remove flac writer (now handled by mp3 writer) 2014-04-27 12:51:40 +02:00
martii
87167a7f5d libeplayer3/writer: implement decoder flushing 2014-04-27 12:45:15 +02:00
max10
4dc1171253 add libduckbox 2014-04-27 01:52:05 +02:00
max10
fcf4785716 Merge remote-tracking branch 'martiis-libstb-hal/master' 2014-04-27 00:38:54 +02:00
MaxWiesel
d7fe7683d3 Initial commit 2014-04-26 15:22:46 -07:00
martii
a76f665882 libeplayer3/writer/pcm: remove debug output 2014-04-26 19:54:42 +02:00
martii
4be41e8cf8 libeplayer3/writer/pcm: move reinit code out of packet loop 2014-04-26 19:20:32 +02:00
martii
ad8620e76a libeplayer3/writer: remove constructors/destructors from writer class 2014-04-26 14:57:22 +02:00
martii
8199257e8c libeplayer3/Makefile: minor rewrite 2014-04-26 14:56:15 +02:00
martii
07e6a4a9c1 libeplayer3: move calcPts to Input class 2014-04-26 14:54:38 +02:00
martii
55c516e2d8 libeplayer3/output: unbreak GetFrameCount() 2014-04-26 14:53:43 +02:00
martii
8b416c8c16 libeplayer3/writer/pcm: simplify 2014-04-26 14:53:02 +02:00
martii
9788b2403d libeplayer3/input: unbreak dvbsub pts calculation 2014-04-26 14:51:54 +02:00
martii
e784a6724c libeplayer3/writer/pcm: cleanup 2014-04-21 14:08:40 +02:00
martii
103037e239 libeplayer3/writer/pcm: simplify pts handling 2014-04-21 14:00:51 +02:00
martii
97440704de libeplayer3/writer/pcm: minor adjustments 2014-04-21 13:24:52 +02:00
martii
2e8a96a309 libeplayer3: minimize debug output 2014-04-18 16:20:07 +02:00
martii
b770330731 libeplayer3: fix backward mode 2014-04-18 16:09:54 +02:00
martii
91712236fe libeplayer3: use av_rescale for pts calulations 2014-04-18 11:16:44 +02:00
martii
020be569fa libeplayer3/input: disable noprobe and retry if probing fails 2014-04-18 09:48:28 +02:00
martii
2729075a35 libeplayer3: minor adjustments 2014-04-16 17:26:53 +02:00
martii
c43566e4a0 libeplayer3/writer/pcm: unbreak 2014-04-15 21:59:22 +02:00
martii
b21040d201 libeplayer3/input: don't segv in deconstructor 2014-04-15 19:47:59 +02:00
martii
2289de62e8 libeplayer3: optimizations (untested) 2014-04-15 17:12:22 +02:00
martii
8ccf1ba33b libeplayer3: use uint64_t instead of float/double for position calculations 2014-04-14 21:47:40 +02:00
martii
31230e5b19 libeplayer3/output: reset stream variables after Close() 2014-04-13 21:29:26 +02:00
martii
51b2ace4e4 libeplayer3: minor optimization 2014-04-13 19:29:07 +02:00
martii
958b5f6a2c libeplayer3/input: increase probesize 2014-04-13 16:30:33 +02:00
martii
aeec7f13a0 unbreak generic build 2014-04-13 10:07:06 +02:00
martii
7b0ea65fcd libeplayer3/input: fix AV_CODEC_ID_MP2 usage 2014-04-12 16:53:55 +02:00
martii
6b763f8393 libspark/playback_libeplayer3: no need to check for player 2014-04-12 13:11:01 +02:00
martii
79935f4821 libspark: unbreak timeshift 2014-04-11 20:12:54 +02:00
martii
51891e653f libeplayer3 adjustments 2014-04-11 18:40:39 +02:00
martii
4b681a4412 libeplayer3: cast away compiler warning 2014-04-11 14:49:42 +02:00
martii
d212bcfbc5 libeplayer3: cleanup 2014-04-11 14:20:22 +02:00
martii
9c0088b6d5 libeplayer3: ffmpeg now provides teletext details in codec->extradata 2014-04-11 14:11:36 +02:00
martii
17b828f6f2 libeplayer3: cleanup 2014-04-10 23:51:17 +02:00
martii
908ff30629 libeplayer3: work around duplicate ffmpeg stream ids by comparing stream addresses instead of pids (plus a couple of optimizations) 2014-04-10 23:35:38 +02:00
martii
98666dd735 libeplayer3/input: rename some variables 2014-04-10 20:47:44 +02:00
martii
2626355684 libeplayer3/output: remove redundant videofd check 2014-04-10 20:46:39 +02:00
martii
36869c9088 libeplayer3/writer: unsigned char => uint8_t 2014-04-10 20:45:57 +02:00
martii
b2368cc64f libeplayer3/Makefile: disable debugging flags 2014-04-09 22:07:12 +02:00
martii
b6a2310df6 libeplayer3: extend API 2014-04-09 22:06:41 +02:00
martii
708505d804 libeplayer is now C++, no more need for extern "C" to access Neutrino functions 2014-04-08 20:42:17 +02:00
martii
1b926b4921 libeplayer3: rename player thread 2014-04-08 20:24:22 +02:00
martii
af7ca7de2e libeplayer3: change compile options 2014-04-08 20:12:35 +02:00
martii
0a9b607d43 libeplayer3: track update: remove redundant teletext pid from return string 2014-04-08 20:10:05 +02:00
martii
7d49d4d32b libeplayer3: continue refresh 2014-04-08 20:02:07 +02:00
martii
42efb5c739 libeplayer3: cleanups 2014-04-07 23:00:03 +02:00
martii
82984ebd1e libeplayer3: rename files 2014-04-07 21:34:01 +02:00
martii
d8eaa8ed5b libeplayer3: remove debug.h 2014-04-07 21:28:20 +02:00
martii
b08abf6b52 libeplayer3: merge Playback to Player class 2014-04-07 21:25:30 +02:00
martii
a965fe4359 libeplayer3: implement Playback and Input classes 2014-04-07 21:01:35 +02:00
martii
cba7a708be libeplayer3: implement Playback and Input classes 2014-04-07 21:01:02 +02:00
martii
6c1f7c13bd libeplayer3: implement Manager class 2014-04-06 21:12:56 +02:00
martii
97883bde13 libeplayer3: rename linuxdvb.cpp => output.cpp 2014-04-06 18:21:31 +02:00
martii
cd3d91fa38 libeplayer3: implement Output class 2014-04-06 18:19:00 +02:00
martii
558b9410a8 libeplayer3: eliminate intermediate output layer 2014-04-06 13:30:20 +02:00
martii
e85f1dd4d1 libeplayer3: rename common.h => player.h 2014-04-06 12:13:50 +02:00
martii
1df8efeecd libeplayer3: rename common.h => player.h 2014-04-06 12:13:18 +02:00
martii
dd527fdfba libeplayer3: rename Content_t => Player 2014-04-06 12:11:40 +02:00
martii
70f58d2cf5 libeplayer3: remove unused code 2014-04-06 11:39:11 +02:00
martii
889d68740c libeplayer3: implement Writer class 2014-04-06 11:35:17 +02:00
martii
27d4c15952 libeplayer: simplify writer/pcm 2014-04-05 19:32:58 +02:00
martii
aa98de5993 libeplayer3: remove writeReverseData (unused) 2014-04-05 17:50:22 +02:00
martii
492b7f1b8d libeplayer3: cleanup pcm writer 2014-04-05 17:44:42 +02:00
martii
58b9518db1 libeplayer: cleanup writers 2014-04-05 16:40:03 +02:00
martii
5f2f008800 libeplayer3: unbreak ipcm 2014-04-05 16:34:03 +02:00
martii
1c380d1167 libeplayer3: let writers use AVPacket 2014-04-05 16:17:57 +02:00
martii
ec307c0f09 libeplayer3: c++ adjustments 2014-04-05 16:02:06 +02:00
martii
b6c1f8a5e3 libeplayer3: rename to c++ 2014-04-05 16:01:12 +02:00
martii
dbdf3b8b8e libeplayer3: delete include/aac.h (unused) 2014-04-05 13:27:13 +02:00
martii
97f95c8385 libeplayer3: remove wmv version (unused) 2014-04-05 13:26:24 +02:00
martii
6fa9a5a495 libeplayer: remove inject_raw_pcm (unused) 2014-04-05 13:24:39 +02:00
martii
21a7d427fd libeplayer3: move audio resampling to dedicated ipcm writer 2014-04-05 13:21:58 +02:00
martii
abc8d3661e libeplayer3: move width/height/framerate/timescale calculation to writers 2014-04-05 11:36:49 +02:00
martii
0895d29e2a libeplayer3: change extradata handling 2014-04-05 11:05:37 +02:00
martii
f217be304a libeplayer3: remove writer/wma.c and writer/aac.c (handled by ffmpeg instead) 2014-04-05 10:39:55 +02:00
martii
6328d3746e libeplayer3: make ffmpeg data available to manager, output and writer 2014-04-05 10:16:30 +02:00
martii
e5237866c4 libeplayer3: cleanup types 2014-04-05 10:01:52 +02:00
martii
10e201b279 libeplayer3: remove tools 2014-04-05 09:51:24 +02:00
martii
e50710dcdf libeplayer3: remove tools 2014-04-05 09:50:56 +02:00
martii
212a414a5e libeplayer/container_ffmpeg: switch to ffmpeg 2.0 API 2014-04-03 18:10:03 +02:00
martii
d2c6b63cc2 libeplayer3/container_ffmpeg: remove latestPts variable 2014-03-26 17:59:50 +01:00
martii
acef549ccd libeplayer3: more cleanups 2014-03-23 17:55:12 +01:00
martii
e08eadd574 libeplayer3: remove no longer needed teletext output handling 2014-03-23 14:46:31 +01:00
martii
daaa1ca8df libeplayer3: change teletext handling to directly inject packets in tuxtext 2014-03-23 13:54:40 +01:00
martii
4ca4f581d5 libeplayer3: cleanup unused code 2014-03-23 10:31:53 +01:00
martii
40f3aa97eb libeplayer3/container_ffmpeg: fix seek bitrate calculation 2014-03-23 10:09:17 +01:00
martii
b030449f72 libspark/hardware_caps: recognize dvfd [untested] 2014-03-22 17:23:51 +01:00
martii
65062ff495 libeplayer3/container_ffmpeg: don't set pts if audio-only 2014-03-22 14:18:37 +01:00
martii
af29c27d3a libeplayer3: initalize AVSubtitle 2014-03-22 13:27:34 +01:00
martii
ffb31db9fb libeplayer3: remove debugging output; abort if neither an audio nor a video stream is available 2014-03-22 13:26:29 +01:00
martii
c3278d9c3e cleanup 2014-03-21 23:27:37 +01:00
martii
351defa567 libeplayer3: remove subtitle.h 2014-03-21 22:37:55 +01:00
martii
9543bce812 libeplayer3/container_ffmpeg: drop subtitle.h include 2014-03-21 22:34:48 +01:00
martii
9e00f61071 libeplayer3: cleanup 2014-03-21 20:18:17 +01:00
martii
8c577d8e6f libeplayer3: subtitles will now be displayed by neutrino 2014-03-21 20:15:01 +01:00
martii
1853f87202 fix generic-pc 2014-03-16 07:40:17 +01:00
martii
d9e8e98678 libeplayer3: let neutrino handle bitmap subtitles 2014-03-16 07:29:38 +01:00
martii
12b070bc88 eplayer3: fix playback termination handling 2014-03-09 14:24:50 +01:00
martii
56b3c7e01d eplayer3: fix playback termination handling 2014-03-09 14:16:45 +01:00
Stefan Seyfried
8231b7f0db update ca.h to currently used interface 2014-02-28 18:55:42 +01:00
Stefan Seyfried
61a76eb83a include/mmi: fix spelling (but keep compatibility) 2014-02-28 18:54:24 +01:00
martii
687a244b61 [spark] video: change psi settings on demand only 2014-01-20 17:57:02 +01:00
martii
cf8f9bc8af [spark] fix setting psi controls 2014-01-19 17:24:52 +01:00
martii
1c676196af libeplayer3/libspark: cPlayback: implement retrieval of metadata 2014-01-19 12:25:35 +01:00
martii
4ab0e8f89e libeplayer3/container_ffmpeg: fix metadata access 2014-01-18 16:54:41 +01:00
martii
908464559c rename cPlayback::isPlaying() => cPlayback::IsPlaying() 2014-01-12 14:13:14 +01:00
martii
950cb9323d libspark/video: indent, no binary change 2014-01-11 13:13:51 +01:00
martii
626a48ccfb libeplayer3/playback: fix seeking/neutrino bookmarks 2013-12-28 22:44:10 +01:00
Stefan Seyfried
68f6b54413 sync seife 2013-12-28 18:36:30 +01:00
Stefan Seyfried
b802566789 libspark: add missing unistd.h includes for gcc 4.7+ 2013-12-28 18:14:41 +01:00
martii
450ac45c30 libeplayer3, libspark/playback_libeplayer3: chapter support 2013-12-23 16:47:29 +01:00
martii
2258a2fd3a libeplayer3/container_ffmpeg: only log ffmpeg errors at debug_level > 10 2013-12-17 15:39:11 +01:00
martii
4a4bb1e06f libeplayer3/container_ffmpeg: don't modify AVPacket internals (I don't believe this actually hurts, but better safe than sorry) 2013-12-15 19:23:15 +01:00
martii
9b7139ada1 libeplayer3/linuxdvb: reduce debug spam 2013-12-15 15:14:35 +01:00
martii
43b0c8c184 libspark/playback: speed up abort 2013-12-11 09:13:25 +01:00
martii
3df4924af5 libeplayer3: cleanup, indent 2013-12-09 16:47:15 +01:00
martii
f840fb0c60 libeplayer3: fix audio recoding, yt aac stuttering should be gone now 2013-12-09 12:15:37 +01:00
martii
21a984f1a1 tools/spark_fp: add flashing period option 2013-11-28 09:55:42 +01:00
martii
d43560ab2b libeplayer3/playback: disable debugging output 2013-11-23 14:40:28 +01:00
martii
8e23cdbad7 libeplayer3/ffmpeg: minor cleanup 2013-11-22 18:08:00 +01:00
martii
3e42b225f0 fix last commits 2013-11-21 23:15:35 +01:00
martii
2d652aab01 libeplayer3: run through indent, no binary change 2013-11-21 19:40:47 +01:00
martii
2c2ca45360 libeplayer3/container: fix compiler warning 2013-11-21 19:28:57 +01:00
martii
71c48b5faf libeplayer3/ffmpeg: rearrange seeking code 2013-11-21 19:25:20 +01:00
martii
df8103d5bb libeplayer3/ffmpeg: don't initialize container if context already exists 2013-11-21 18:18:13 +01:00
martii
0feee1d3b4 libeplayer3: fix seeking 2013-11-19 22:38:26 +01:00
martii
ecf5bb30fb libeplayer3/ffmpeg: add 3gp and ogm extensions 2013-11-19 19:33:33 +01:00
martii
ea558898b9 libeplayer3: modify fast-backward 2013-11-17 15:24:33 +01:00
martii
8f0f5dd29a tools/spark_fp: add option for enabling/disabling icons 2013-11-13 20:37:46 +01:00
martii
a56e611a05 libspark/audio, libeplayer3: audio type adjustments 2013-11-11 12:30:47 +01:00
martii
de39d0cdc7 libstb-hal/libspark/playback: add method for retrieving read-count 2013-11-04 14:15:21 +01:00
martii
a4f3af23bf libspark/playback: add more player checks 2013-11-03 14:31:45 +01:00
martii
7c4100b856 libspark/playback: SuspendSubtitle: check for player being valid 2013-11-03 14:28:52 +01:00
martii
539f41f46d libeplayer3: speed up termination 2013-11-02 16:02:33 +01:00
martii
8df85c94e8 unbreak generic-pc build 2013-11-02 15:12:10 +01:00
martii
773553ddb5 libspark/player, libeplayer3/ffmpeg: improve termination handling 2013-11-02 12:58:29 +01:00
martii
eda54c7cea libspark/player: use int instead of short in some places 2013-10-31 15:58:49 +01:00
martii
d13fc04473 libspark/audio: align to player2 2013-10-30 18:28:52 +01:00
martii
42bf8cb685 libspark/audio: add EAC3 support 2013-10-29 21:47:18 +01:00
martii
e44c547d78 Revert "libspark/video: enable/disable analogue output when leaving/entering standby mode (experimental and untested)"
This reverts commit 8062db2387.
2013-10-21 19:41:48 +02:00
martii
8062db2387 libspark/video: enable/disable analogue output when leaving/entering standby mode (experimental and untested) 2013-10-20 18:46:33 +02:00
martii
e065094e11 libeplayer3/ffmpeg: minor cleanup 2013-10-12 19:11:17 +02:00
martii
6f4449e1c5 Merge remote-tracking branch 'seife/master' 2013-10-06 14:41:32 +02:00
martii
848730507b sync with seife 2013-10-06 10:16:33 +02:00
martii
782bc95fd5 libspark/playback_libeplayer3: fix GetPts() 2013-10-05 10:42:21 +02:00
martii
70806da6ed libspark/audio: always use /proc/stb/avs/0/volume to set volume 2013-10-03 17:56:16 +02:00
martii
83201e0199 unbreak generic-pc build 2013-09-15 15:53:49 +02:00
martii
1756351a36 [SPARK] cVideo::ShowPicture: add optional argument for destination m2v 2013-09-06 22:23:22 +02:00
martii
938a6c4491 libspark/playback_libeplayer3: assume that libeplayer3 can handle arbitrary URLs 2013-08-18 20:03:47 +02:00
martii
19fd4c7ad2 libeplayer3/playback: convert mms urls to mmst instead of rtsp 2013-08-18 19:10:18 +02:00
martii
2477b3f497 libspark/hw_caps: check vfd version first (needed to discriminate between Pingulux and Pingulux Plus) 2013-08-18 10:52:43 +02:00
martii
2f5c51abc6 libeplayer3/manager: initialize track IDs 2013-08-16 19:50:20 +02:00
martii
124cd8e4ba libeplayer3: tracks update is now lock-free 2013-08-16 19:35:07 +02:00
martii
093862d85d libeplayer3/container_ffmpeg: mutex fix 2013-08-16 14:33:30 +02:00
martii
672b5d10d2 libeplayer3/wmv: revert to (almost) original version 2013-08-15 17:05:55 +02:00
martii
86e70db211 libspark/audio_mixer: don't try to free() stack-allocated snd_mixer_selem_id 2013-08-14 20:48:09 +02:00
martii
75e5268a3c libspark: implement SetColorFormat() 2013-08-11 12:39:20 +02:00
martii
89d1587513 libspark/dmx.cpp: print pid if addPid fails 2013-08-06 16:07:49 +02:00
martii
46a5151f07 libeplayer/text_srt: minor optimization 2013-08-04 16:42:21 +02:00
martii
5579633b0c libeplayer3: drop non-shared framebuffer support 2013-08-04 16:22:07 +02:00
martii
a9b0cee5a1 libeplayer3: unbreak srt subs 2013-08-04 16:21:39 +02:00
martii
50cc7f726c revert 286675f430 2013-08-02 15:07:15 +02:00
martii
286675f430 libeplayer3: divx fix 2013-08-02 14:37:03 +02:00
martii
6f531ed8b0 libeplayer3: cleanup 2013-08-02 12:44:51 +02:00
martii
f7d530de36 libeplayer3: vc1, wmv: use InsertPesHeader for initial PES headers, too 2013-08-02 08:37:17 +02:00
martii
b3f4ef99a1 libeplayer3/output/writer/: remove PesHeader memset (both wrong and unneeded) 2013-08-01 20:35:22 +02:00
martii
5aa75077cd libeplayer3 optimizations 2013-07-29 18:35:48 +02:00
martii
88c0ce06cb libeplayer3/container_ass: cosmetics 2013-07-28 14:40:30 +02:00
martii
95d99e1da6 libeplayer3/container_ffmpeg: cleanup 2013-07-28 13:04:20 +02:00
martii
d0d31f9998 libeplayer3/writer/framebuffer: small optimization 2013-07-28 12:33:24 +02:00
martii
2b91afacec generic-pc build fix 2013-07-28 12:20:01 +02:00
martii
3404980bc9 libeplayer3/container_ass: set thread name 2013-07-28 11:40:42 +02:00
martii
aa43e83a7c libeplayer3/pcm: cleanup 2013-07-28 10:12:36 +02:00
martii
411037021c libeplayer3/pcm: minor clean-up, no code change 2013-07-28 10:06:21 +02:00
martii
f8a789f7a6 Fix libeplayer3's broken PCM injection implementation. Jumps in movieplayer now works without losing a/v sync. 2013-07-28 09:54:39 +02:00
martii
c9e0755f02 libeplayer3/container_ffmpeg: don't flush instead of clear 2013-07-27 12:24:50 +02:00
martii
b64bdcb370 libeplayer3: use uint32_t for frame buffer access 2013-07-27 11:17:49 +02:00
martii
cf5687bc37 libeplayer3/continer_ass: crude hack to improve subtitle readability 2013-07-27 09:24:51 +02:00
martii
84b264ad87 libeplayer3/subtitles/spark: use backbuffer and blit 2013-07-27 08:12:03 +02:00
martii
441f337b48 libeplayer3/container_ass: font size adjusted 2013-07-26 22:50:26 +02:00
martii
c25b717b43 libeplayer/playback: disable subtitle init hack 2013-07-26 21:39:57 +02:00
martii
f199c329ad libeplayer3/subtitle: reduce debugging level 2013-07-26 20:29:01 +02:00
martii
35da5243e7 libeplayer3: initial attempt to unbreak ass/ssa subtitles 2013-07-26 16:59:58 +02:00
martii
c70b669a3d libeplayer/linuxdvb: cleanup 2013-07-24 21:38:31 +02:00
martii
6a658a2a6d libeplayer3/containter_ffmpeg: fix track update 2013-07-24 20:42:17 +02:00
martii
45bc6e3610 libeplayer3/container_ffmpeg: no need for copying the input packet 2013-07-23 21:45:44 +02:00
martii
c5fd4c8c3e libeplayer/container_ffmpeg: subtitle fix 2013-07-23 21:00:14 +02:00
martii
b78249cd02 libeplayer3/container_ffmpeg.c: re-order packet.data check (not sure whether this is needed at all) 2013-07-22 18:39:11 +02:00
martii
093fcac8fd libeplayer/container_ffmpeg: correct misplaced brackets 2013-07-21 19:50:14 +02:00
martii
034ab89f28 libeplayer3/container_ffmpeg: initialize stream ids, if unset 2013-07-21 19:02:58 +02:00
martii
ee3f84913a libeplayer3/container_ffmpeg: av_samples_alloc: use actual number for channels 2013-07-21 16:17:18 +02:00
martii
2a3a69b5a1 libeplayer3/container_ffmpeg: align av_samples_alloc buffer 2013-07-21 16:11:53 +02:00
martii
5db41a87e3 libeplayer3/container_ffmpeg: fix mono->stereo conversion 2013-07-21 14:54:57 +02:00
martii
b914c7bb32 libeplayer/container_ffmpeg: audio pts fix 2013-07-21 12:06:38 +02:00
martii
867e0a33e9 libeplayer3: remove outdated include/stm_ioctl.h 2013-07-20 15:36:22 +02:00
martii
1f0340cf19 container_ffmpeg: flush streams immediately after seek 2013-07-20 09:08:31 +02:00
martii
d4e42d28b4 libeplayer3: cleanup 2013-07-19 14:36:25 +02:00
martii
54e719207a libeplayer: reduce debugging output 2013-07-19 10:43:56 +02:00
martii
0c4711b209 h264: don't mess with packet length 2013-07-19 10:30:04 +02:00
martii
12b77f59a7 libeplayer3/h264: unbreak 2013-07-14 16:07:15 +02:00
martii
7438ff07b2 libeplayer3/container_ffmpeg: No attributes needed for mutex init 2013-07-14 15:17:36 +02:00
martii
ad36db9281 libeplayer3 cleanup 2013-07-14 14:55:48 +02:00
martii
c74138e765 libeplayer3/h264 cleanup 2013-07-14 13:36:19 +02:00
martii
443adcf6d0 libeplayer3: experimental h.264 playback fix 2013-07-14 13:30:50 +02:00
martii
33d6a1c7ca libeplayer3: cleanup 2013-07-14 10:04:05 +02:00
martii
fb16fc2ffb libeplayer3: use actual pids instead of indexes 2013-07-12 22:34:39 +02:00
martii
fcb9984000 ffmpeg-2.0 2013-07-10 19:27:57 +02:00
martii
1512840369 libeplayer3/container_ffmpeg: revert swr_next_pts call 2013-07-07 16:20:01 +02:00
martii
e80f8646e7 libeplayer3: minor changes 2013-07-07 15:59:55 +02:00
martii
f97060bcd6 libeplayer3: re-enable audio after seeking (still broken) 2013-07-07 10:34:29 +02:00
martii
c3ed9ba3f5 libeplayer3: need to call avcodec_free_frame after swresample, too 2013-07-06 17:06:01 +02:00
martii
5d8e40ba04 libspark/hardware_caps: lie for Pingulux SCART support 2013-06-27 21:31:15 +02:00
martii
fc9108b06a libspark/playback_libeplayer3: no need for alloca() 2013-06-26 22:37:35 +02:00
martii
178fac0e8d libspark: experimental pip changes (doesn't work; needs driver support) 2013-06-20 13:29:54 +02:00
martii
bb86b78aad sync with seife 2013-06-19 12:41:13 +02:00
martii
b8ad6fe246 libeplayer3: the mp3 handler can easily take care of vorbis data, too. 2013-06-13 20:58:08 +02:00
martii
5369d7496e libeplayer3: vorbis can easily be handled by the mp3 writer 2013-06-10 15:49:38 +02:00
martii
04cb2f24ff libeplayer3/h264: disable debugging 2013-06-10 15:11:13 +02:00
martii
9d4502b7fe libeplayer3: get rid of compiler warnings 2013-06-10 15:06:00 +02:00
martii
b5d81733f1 libeplayer3: drop legacy ffmpeg support 2013-06-10 13:13:52 +02:00
martii
db994be096 libeplayer/h264: Fix playback. 2013-06-10 12:38:47 +02:00
martii
23bea61473 cleanup 2013-06-08 15:39:35 +02:00
martii
eae9d7a7a1 libeplayer3: deactivate debugging 2013-06-08 12:34:19 +02:00
martii
6f384fc6b6 libeplayer3: cleanup 2013-06-08 12:05:36 +02:00
martii
a09c2518bc libeplayer3: further malloc-memcpy-write -> writev replacements; not fully regression tested 2013-06-08 11:15:09 +02:00
martii
8d8aa01f98 libeplayer3/h264: replace malloc/memcpy/write with writev 2013-06-08 10:19:40 +02:00
martii
e10d6a5a18 ShowPicture: revert API change 2013-06-07 16:21:04 +02:00
martii
4e439cdb41 libeplayer3: drop buffering code due to crashes 2013-06-07 15:16:29 +02:00
martii
ac072c5a41 libspark/playback: youtube URLs are easily longer than 400 bytes 2013-06-07 13:56:23 +02:00
martii
b018b10a66 sync 2013-06-01 17:21:07 +02:00
martii
8a68eb3f15 replace libavresample with libswresample 2013-06-01 13:47:47 +02:00
martii
8b533c3c59 generic-pc/glfb: use r/g/y/b keys as additional color keys 2013-06-01 12:29:30 +02:00
martii
a89b6f294e generic-pc: fix audio (2nd try) 2013-06-01 10:37:36 +02:00
martii
b8a8c07786 generic-pc: fix audio 2013-05-31 18:08:07 +02:00
martii
4e4dd50bb8 copy api changes from spark to generic 2013-05-31 13:27:04 +02:00
martii
0aec8dda78 Merge remote-tracking branch 'seife/master' 2013-05-27 17:38:35 +02:00
martii
236c2401f1 revert audio_mixer changes 2013-05-26 14:24:31 +02:00
martii
f70b1457cc libspark/audio_mixer: load alsa-lib temporarily only (fix) 2013-05-26 12:42:08 +02:00
martii
c09fc914a4 libspark/audio_mixer: load alsa-lib temporarily only 2013-05-26 10:56:08 +02:00
martii
151fd39d45 Merge remote-tracking branch 'seife/master' 2013-05-26 08:09:50 +02:00
martii
4e9395f788 libspark/video: use VIDEO_STILLPICTURE with NULL pointer to blank screen 2013-05-25 16:48:30 +02:00
martii
781cf7f389 libspark/video: ShowPicture: fix malloc size 2013-05-25 12:53:25 +02:00
martii
cde83d893d Merge remote-tracking branch 'seife/master' 2013-05-25 12:38:21 +02:00
martii
e68c20dfbe libspark/video: add missing newline 2013-05-25 11:24:32 +02:00
martii
18b798bee2 libspark/video: ShowPicture: use VIDEO_STILLPICTURE 2013-05-25 08:42:06 +02:00
martii
f88d47b0f2 libspark/video: ShowPicture: add flag to indicate that input file is already m2v and doesn't need to be converted 2013-05-18 15:29:19 +02:00
martii
a5cc6ae698 cleanup 2013-05-10 14:01:52 +02:00
martii
145b098d92 sync 2013-05-06 18:01:49 +02:00
martii
ec3f82441e Merge remote-tracking branch 'seife/master' 2013-05-04 20:52:54 +02:00
martii
ff374c6070 libeplayer reverse play: experimental adjustment to find previous I-frame 2013-04-11 17:59:22 +02:00
martii
5025a6e645 libeplayer3: fix segv 2013-04-10 20:41:44 +02:00
martii
e9be2bed37 eplayer3: subtitle fixes 2013-04-01 11:57:36 +02:00
martii
0962c08e90 crude hack for movieplayer tuxtxt integration 2013-03-31 11:55:51 +02:00
martii
f6f9f03152 libspark: drop irmp 2013-03-30 14:31:10 +01:00
martii
65b1a8e51a libspark/playback_libeplayer3: initialize return values 2013-03-30 09:39:49 +01:00
martii
2b11ad1880 teletext handling changes 2013-03-29 18:14:52 +01:00
martii
beac99d8b0 libeplayer3: dynamically update pid list 2013-03-25 20:42:36 +01:00
martii
683aa6dfd2 Merge remote-tracking branch 'seife/master' 2013-03-25 18:16:40 +01:00
martii
46754e01b1 adapt Pig() to blitter-based OSD border 2013-03-22 21:54:55 +01:00
martii
5548017dc7 libeplayer3/playback_libeplayer3: change noprobe handling 2013-03-18 18:49:00 +01:00
martii
f5c97eaf88 libeplayer/container_ffmpeg: use injected PCM for raw PCM, too 2013-03-17 09:47:18 +01:00
martii
ecd0dac595 libeplayer3/container_ffmpeg: handle .wtv extensions, too 2013-03-16 19:43:25 +01:00
martii
934296f8b7 libeplayer3/container_ffmpeg: fix WMA playback 2013-03-16 18:24:49 +01:00
martii
d02696233c libeplayer3: add callback to abort avformat_open_input 2013-03-10 15:44:30 +01:00
martii
a865a4779a libeplayer3/container_ffmpeg: cleanup 2013-03-09 16:40:54 +01:00
martii
8430f6f37c libeplayer3/container_ffmpeg: cleanup 2013-03-09 16:37:05 +01:00
martii
1a2aa05948 libeplayer3: merge buffered IO code from TDT; implement proper audio resampling 2013-03-09 14:47:34 +01:00
martii
404c0a2b2d libeplayer3/container_ffmpeg: minor cleanup 2013-03-04 19:22:47 +01:00
martii
2cd0da9170 Merge remote-tracking branch 'seife/master' 2013-03-04 17:38:14 +01:00
martii
828049ccbb libeplayer3/container_ffmpeg: no need to scale the buffer 2013-03-04 17:37:44 +01:00
martii
faeac91113 libeplayer3: this may improve recovery from broken streams 2013-03-03 20:55:39 +01:00
martii
9464d9eadb Merge remote-tracking branch 'seife/master' 2013-03-03 13:50:12 +01:00
martii
fbb9dcbb03 libeplayer3: switch back to software decoding for AAC; crude fix for PCM injection (newer ffmpeg versions return floats instead of shorts), injected PCM streams (OGG, for example), will now work again. I'd be grateful if anybody with a deeper understanding of the FFMPEG API would supply a cleaner fix ... 2013-03-03 13:38:39 +01:00
martii
3085e72c01 libeplayer: set 65535 as maximum PES length 2013-02-26 19:57:15 +01:00
martii
c964a090dd libeplayer: assume unlimited PES length for too large packets 2013-02-26 19:56:08 +01:00
martii
1d70357b45 libspark/playback: let GetPosition return false on EOF 2013-02-26 19:55:29 +01:00
martii
94b05dbdc0 sync with seife 2013-02-24 20:13:12 +01:00
martii
8a90d4311f libspark/hw caps: add 7111 stb ids 2013-02-24 11:07:14 +01:00
martii
e571a79932 libspark/hw_caps: add more stb ids, add boxtype 2013-02-24 10:46:14 +01:00
martii
a8668dc453 pic2m2v: remove verbosity level from ffmpeg due to incompatibility with the 0.8 branch 2013-02-24 09:52:16 +01:00
martii
4e13bfb4f0 remove untested code for 7162 support 2013-02-22 18:57:13 +01:00
martii
8a234a84bb hardware_caps: set CEC flag for SPARK 2013-02-12 21:18:45 +01:00
martii
366aaea114 hwcaps: add fe_offset_max for spark 2013-02-11 19:40:42 +01:00
martii
4f89348d43 spark_fp: augment usage output 2013-02-08 22:20:26 +01:00
martii
25a0179c83 spark_fp: add support for setting aotom hotkeys 2013-02-08 21:39:16 +01:00
martii
2e83762e95 spark_fp: small fix 2013-02-03 15:20:06 +01:00
martii
5d64ecf5fb sync with seife 2013-01-30 19:13:45 +01:00
martii
4929656233 fix spark_fp usage 2013-01-28 18:08:21 +01:00
martii
f744cf4d05 spark_fp: fix last patch, no binary change 2013-01-27 19:45:34 +01:00
martii
9d5cb7b443 spark_fp: re-added disabled code, no binary change 2013-01-27 19:42:07 +01:00
martii
25704f084d add support for sane aotom power-off from graugans, see http://www.dbox2-tuning.net/forum/viewtopic.php?f=69&t=50261 and corresponding driver/kernel patches 2013-01-27 19:13:27 +01:00
martii
d481adb2b8 libeplayer3: experimental fixes 2013-01-17 18:37:45 +01:00
martii
51941092e3 rename hwcap variable 2013-01-13 18:30:00 +01:00
martii
c734caa83a hwcaps: use FE_OFFSET environment variable 2012-12-26 15:45:37 +01:00
martii
39d38a38d9 revert volume calculation to original implementation 2012-12-17 16:33:07 +01:00
martii
932fba6516 libspark: work around driver bug 2012-12-16 21:21:15 +01:00
martii
4720ec559c libspark/pwrmngr: don't fall-back to default cpu frequency 2012-12-09 10:18:03 +01:00
martii
82a0c1aa10 add dmx offset to hw-caps 2012-12-08 11:58:50 +01:00
martii
079d28cc86 libspark/playback_libeplayer3: treat rtmp/mms as http stream 2012-11-14 14:20:31 +01:00
martii
6e74f47285 libeplayer/playback: initialize length to -1 2012-11-12 14:20:55 +01:00
martii
dcb1512663 libeplayer3 fix 2012-11-10 13:41:59 +01:00
martii
3d5353cbd8 libeplayer3: check for valid avContext pointer 2012-11-09 17:43:11 +01:00
martii
9150713e46 improve subtitle handling 2012-11-06 14:34:31 +01:00
martii
994bd78e4e sync 2012-11-04 18:46:58 +01:00
martii
aa0681a555 libspark/libeplayer: rudimentary subtitle support, probably unstable 2012-11-04 15:39:48 +01:00
martii
2f886cae89 fix red led recording state 2012-11-03 18:48:33 +01:00
martii
241de088cb libspark: fix volume-to-/proc/stb/avs/0/volume mapping 2012-11-01 11:45:05 +01:00
martii
aca3da1f29 get rid of most compiler warnings 2012-10-27 18:08:29 +02:00
martii
bc74c7528b enable wav payback (16 bit le) (from TDT, thanks hellmaster1024) 2012-10-27 18:07:02 +02:00
martii
669a91f8b7 sync 2012-10-12 14:42:48 +02:00
martii
9f3ac6d7d7 Merge remote-tracking branch 'seife/master' 2012-10-09 17:00:46 +02:00
martii
22d9e34f29 libeplayer3: disable noprobe hack 2012-10-04 09:42:28 +02:00
martii
e27fd37cad sync 2012-10-04 09:32:05 +02:00
martii
4e93e9cc48 sync 2012-10-01 18:35:21 +02:00
martii
eb5f5dc9ae merge 2012-09-22 16:27:06 +02:00
martii
53e9396bc1 spark input device handling: add function for reopening 2012-09-18 16:25:35 +02:00
martii
586ff9d657 Merge remote-tracking branch 'seife/master' 2012-09-18 13:33:02 +02:00
martii
462353e9dd add VFDGETVERSION support 2012-09-12 20:25:15 +02:00
martii
9c22d47bc3 audio_mixer: correct conversion 2012-09-05 20:49:47 +02:00
martii
7cd67c9fad spark: add volume control for alsa mixer 2012-09-05 19:08:45 +02:00
martii
1ccc2ee75a eplayer3 h263 fix 2012-08-31 12:33:59 +02:00
martii
260a6fcc2f cast sizeof to signed to avoid compiler warning 2012-08-16 22:10:55 +02:00
martii
2bdab523e5 Merge remote-tracking branch 'seife/master' 2012-08-16 22:05:33 +02:00
martii
d7d11fdd0d fix indent 2012-08-13 18:42:15 +02:00
martii
c2a9c1a6df libspark/video.cpp: I tend to believe that comparing signed and unsigned would break for st.st_size < 4 2012-08-12 10:04:35 +02:00
martii
92731e6fe3 libeplayer3: add support for teletext and dvbsubtitle streams 2012-08-04 13:31:28 +02:00
martii
d6bdeb0ff0 fix some movieplayer issues 2012-07-27 20:09:26 +02:00
martii
1d0e6663c4 libeplayer3: sync with tdt 2012-07-21 21:03:59 +02:00
martii
450fc1966a libspark/record.cpp: user configurable buffer sizes 2012-07-21 16:32:00 +02:00
martii
2ca16aedac Merge remote-tracking branch 'seife/master' 2012-07-15 20:13:18 +02:00
martii
3a9a21c8ee spark_fp: add options for setting led status 2012-07-14 13:15:41 +02:00
martii
fded24562f spark_fp: add options for setting led status 2012-07-14 13:12:50 +02:00
martii
d38bef08f4 spark record: set dmx to non-blocking mode, change buffer size 2012-07-13 16:31:31 +02:00
martii
b1f92d8e9c video_lib.h header adapted to match one of the previous changes 2012-07-13 16:30:43 +02:00
martii
7f45271ad2 input handling: copy input data from secondary devices to the main rc device 2012-07-13 16:29:53 +02:00
martii
bcaf83a8c7 spark powermanager: SetCpuFreq now actually does what its name says 2012-07-13 16:27:13 +02:00
martii
6e8bdf5c34 spark video: implement SetControl 2012-07-13 16:26:22 +02:00
martii
249d2964ac spark dmx: less debugging output; set buffer size 2012-07-13 16:25:48 +02:00
martii
d03f3c8fee spark audio: add support for channel specific volume 2012-07-13 16:24:18 +02:00
martii
6f1de0cd6c spark_fp: don't touch LEDs on shutdown 2012-07-13 16:23:04 +02:00
martii
752e1e4368 support newer ffmpeg versions 2012-07-13 16:22:19 +02:00
343 changed files with 50146 additions and 9996 deletions

10
.gitignore vendored
View File

@@ -1,19 +1,21 @@
/aclocal.m4
/autom4te.cache/
Makefile.in
/compile
/config.guess
/config.h.in
/config.sub
*/*-config.h
*/*-config.h.in
/configure
/compile
*.directory
/depcomp
/install-sh
/ltmain.sh
/m4/
/missing
*.*~
*.a
*.la
*.lai
*.lo
*.o
*.Plo
*.Po

2127
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -2,16 +2,18 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libstb-hal.la
libstb_hal_la_SOURCES =
SUBDIRS = common tools
SUBDIRS = common tools libthread
#bin_PROGRAMS = libstb-hal-test
libstb_hal_la_LIBADD = \
common/libcommon.la
common/libcommon.la \
libthread/libthread.la
libstb_hal_la_LDFLAGS = -version-info 1:0:1
AM_CPPFLAGS = \
-I$(top_srcdir)/include
libstb_hal_test_SOURCES = libtest.cpp
libstb_hal_test_LDADD = libstb-hal.la
#libstb_hal_test_SOURCES = libtest.cpp
#libstb_hal_test_LDADD = libstb-hal.la
# there has to be a better way to do this...
if BOXTYPE_TRIPLE
@@ -36,28 +38,32 @@ libstb_hal_la_LIBADD += \
endif
endif
if BOXTYPE_SPARK
#libstb_hal_test_LDADD += -lasound
SUBDIRS += libspark libeplayer3
libstb_hal_la_LIBADD += \
libspark/libspark.la \
libeplayer3/libeplayer3.la
endif
if BOXTYPE_DUCKBOX
#libstb_hal_test_LDADD += -lasound
SUBDIRS += libduckbox libeplayer3 libdvbci
libstb_hal_la_LIBADD += \
libduckbox/libduckbox.la \
libeplayer3/libeplayer3.la \
libdvbci/libdvbci.la
endif
if BOXTYPE_ARMBOX
#libstb_hal_test_LDADD += -lasound
SUBDIRS += libarmbox libdvbci
libstb_hal_la_LIBADD += \
libarmbox/libarmbox.la \
libdvbci/libdvbci.la
pkginclude_HEADERS = \
include/audio_hal.h \
include/ca_cs.h \
include/ca.h \
include/cs_api.h \
include/cs_types.h \
include/dmx_cs.h \
include/dmx_hal.h \
include/glfb.h \
include/hardware_caps.h \
include/init_cs.h \
include/init_td.h \
include/mmi.h \
include/playback.h \
include/playback_hal.h \
include/pwrmngr.h \
include/record_hal.h \
include/version_hal.h \
include/video_cs.h
if !ENABLE_GSTREAMER_10
SUBDIRS += libeplayer3-arm
libstb_hal_la_LIBADD += \
libeplayer3-arm/libeplayer3_arm.la
endif
endif

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
libstb-hal
==========

View File

@@ -1,24 +1,27 @@
AC_DEFUN([TUXBOX_APPS],[
AC_DEFUN([TUXBOX_APPS], [
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
AC_SYS_LARGEFILE
AC_GNU_SOURCE
AC_ARG_WITH(target,
[ --with-target=TARGET target for compilation [[native,cdk]]],
[TARGET="$withval"],[TARGET="native"])
AS_HELP_STRING([--with-target=TARGET], [target for compilation [[native,cdk]]]),
[TARGET="$withval"],
[TARGET="native"])
AC_ARG_WITH(targetprefix,
[ --with-targetprefix=PATH prefix relative to target root (only applicable in cdk mode)],
[targetprefix="$withval"],[targetprefix="NONE"])
AS_HELP_STRING([--with-targetprefix=PATH], [prefix relative to target root (only applicable in cdk mode)]),
[TARGET_PREFIX="$withval"],
[TARGET_PREFIX=""])
AC_ARG_WITH(debug,
[ --without-debug disable debugging code],
[DEBUG="$withval"],[DEBUG="yes"])
AS_HELP_STRING([--without-debug], [disable debugging code @<:@default=no@:>@]),
[DEBUG="$withval"],
[DEBUG="yes"])
if test "$DEBUG" = "yes"; then
DEBUG_CFLAGS="-g3 -ggdb"
AC_DEFINE(DEBUG,1,[Enable debug messages])
AC_DEFINE(DEBUG, 1, [enable debugging code])
fi
AC_MSG_CHECKING(target)
@@ -33,15 +36,29 @@ if test "$TARGET" = "native"; then
if test "$prefix" = "NONE"; then
prefix=/usr/local
fi
TARGET_PREFIX=$prefix
if test "$exec_prefix" = "NONE"; then
exec_prefix=$prefix
fi
targetprefix=$prefix
elif test "$TARGET" = "cdk"; then
AC_MSG_RESULT(cdk)
if test "$prefix" = "NONE"; then
AC_MSG_ERROR(invalid prefix, you need to specify one in cdk mode)
if test "$CC" = "" -a "$CXX" = ""; then
AC_MSG_ERROR([you need to specify variables CC or CXX in cdk])
fi
if test "$targetprefix" = "NONE"; then
targetprefix=""
if test "$CFLAGS" = "" -o "$CXXFLAGS" = ""; then
AC_MSG_ERROR([you need to specify variables CFLAGS and CXXFLAGS in cdk])
fi
if test "$prefix" = "NONE"; then
AC_MSG_ERROR([invalid prefix, you need to specify one in cdk mode])
fi
if test "$TARGET_PREFIX" != "NONE"; then
AC_DEFINE_UNQUOTED(TARGET_PREFIX, "$TARGET_PREFIX", [The targets prefix])
fi
if test "$TARGET_PREFIX" = "NONE"; then
AC_MSG_ERROR([invalid targetprefix, you need to specify one in cdk mode])
TARGET_PREFIX=""
fi
else
AC_MSG_RESULT(none)
@@ -50,13 +67,14 @@ fi
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_SYS_LARGEFILE
])
dnl expand nested ${foo}/bar
AC_DEFUN([TUXBOX_EXPAND_VARIABLE],[__$1="$2"
AC_DEFUN([TUXBOX_EXPAND_VARIABLE], [
__$1="$2"
for __CNT in false false false false true; do dnl max 5 levels of indirection
$1=`eval echo "$__$1"`
echo ${$1} | grep -q '\$' || break # 'grep -q' is POSIX, exit if no $ in variable
__$1="${$1}"
@@ -64,16 +82,16 @@ AC_DEFUN([TUXBOX_EXPAND_VARIABLE],[__$1="$2"
$__CNT && AC_MSG_ERROR([can't expand variable $1=$2]) dnl bail out if we did not expand
])
AC_DEFUN([TUXBOX_APPS_DIRECTORY_ONE],[
AC_ARG_WITH($1,[ $6$7 [[PREFIX$4$5]]],[
AC_DEFUN([TUXBOX_APPS_DIRECTORY_ONE], [
AC_ARG_WITH($1, AS_HELP_STRING([$6], [$7 [[PREFIX$4$5]]], [32], [79]), [
_$2=$withval
if test "$TARGET" = "cdk"; then
$2=`eval echo "${targetprefix}$withval"` # no indirection possible IMNSHO
$2=`eval echo "$TARGET_PREFIX$withval"` # no indirection possible IMNSHO
else
$2=$withval
fi
TARGET_$2=${$2}
],[
], [
# RFC 1925: "you can always add another level of indirection..."
TUXBOX_EXPAND_VARIABLE($2,"${$3}$5")
if test "$TARGET" = "cdk"; then
@@ -83,14 +101,12 @@ AC_ARG_WITH($1,[ $6$7 [[PREFIX$4$5]]],[
fi
TARGET_$2=$_$2
])
dnl automake <= 1.6 don't support this
dnl AC_SUBST($2)
AC_DEFINE_UNQUOTED($2,"$_$2",$7)
AC_SUBST(TARGET_$2)
])
AC_DEFUN([TUXBOX_APPS_DIRECTORY],[
AC_DEFUN([TUXBOX_APPS_DIRECTORY], [
AC_REQUIRE([TUXBOX_APPS])
if test "$TARGET" = "cdk"; then
@@ -98,35 +114,32 @@ if test "$TARGET" = "cdk"; then
sysconfdir="\${prefix}/etc"
localstatedir="\${prefix}/var"
libdir="\${prefix}/lib"
targetdatadir="\${targetprefix}/share"
targetsysconfdir="\${targetprefix}/etc"
targetlocalstatedir="\${targetprefix}/var"
targetlibdir="\${targetprefix}/lib"
targetdatadir="\${TARGET_PREFIX}/share"
targetsysconfdir="\${TARGET_PREFIX}/etc"
targetlocalstatedir="\${TARGET_PREFIX}/var"
targetlibdir="\${TARGET_PREFIX}/lib"
fi
TUXBOX_APPS_DIRECTORY_ONE(configdir,CONFIGDIR,localstatedir,/var,/tuxbox/config,
[--with-configdir=PATH ],[where to find the config files])
TUXBOX_APPS_DIRECTORY_ONE(configdir, CONFIGDIR, localstatedir, /var, /tuxbox/config,
[--with-configdir=PATH], [where to find config files])
TUXBOX_APPS_DIRECTORY_ONE(datadir,DATADIR,datadir,/share,/tuxbox,
[--with-datadir=PATH ],[where to find data])
TUXBOX_APPS_DIRECTORY_ONE(datadir, DATADIR, datadir, /share, /tuxbox,
[--with-datadir=PATH], [where to find data files])
TUXBOX_APPS_DIRECTORY_ONE(fontdir,FONTDIR,datadir,/share,/fonts,
[--with-fontdir=PATH ],[where to find the fonts])
TUXBOX_APPS_DIRECTORY_ONE(fontdir, FONTDIR, datadir, /share, /fonts,
[--with-fontdir=PATH], [where to find fonts])
TUXBOX_APPS_DIRECTORY_ONE(gamesdir,GAMESDIR,localstatedir,/var,/tuxbox/games,
[--with-gamesdir=PATH ],[where games data is stored])
TUXBOX_APPS_DIRECTORY_ONE(gamesdir, GAMESDIR, localstatedir, /var, /tuxbox/games,
[--with-gamesdir=PATH], [where to find games])
TUXBOX_APPS_DIRECTORY_ONE(libdir,LIBDIR,libdir,/lib,/tuxbox,
[--with-libdir=PATH ],[where to find the internal libs])
TUXBOX_APPS_DIRECTORY_ONE(libdir, LIBDIR, libdir, /lib, /tuxbox,
[--with-libdir=PATH], [where to find internal libs])
TUXBOX_APPS_DIRECTORY_ONE(plugindir,PLUGINDIR,libdir,/lib,/tuxbox/plugins,
[--with-plugindir=PATH ],[where to find the plugins])
TUXBOX_APPS_DIRECTORY_ONE(plugindir, PLUGINDIR, libdir, /lib, /tuxbox/plugins,
[--with-plugindir=PATH], [where to find plugins])
TUXBOX_APPS_DIRECTORY_ONE(ucodedir,UCODEDIR,localstatedir,/var,/tuxbox/ucodes,
[--with-ucodedir=PATH ],[where to find the ucodes])
TUXBOX_APPS_DIRECTORY_ONE(themesdir,THEMESDIR,datadir,/share,/tuxbox/neutrino/themes,
[--with-themesdir=PATH ],[where to find the themes (don't change)])
TUXBOX_APPS_DIRECTORY_ONE(themesdir, THEMESDIR, datadir, /share, /tuxbox/neutrino/themes,
[--with-themesdir=PATH], [where to find themes])
])
dnl automake <= 1.6 needs this specifications
@@ -136,136 +149,270 @@ AC_SUBST(FONTDIR)
AC_SUBST(GAMESDIR)
AC_SUBST(LIBDIR)
AC_SUBST(PLUGINDIR)
AC_SUBST(UCODEDIR)
AC_SUBST(THEMESDIR)
dnl end workaround
AC_DEFUN([TUXBOX_BOXTYPE],[
AC_ARG_WITH(boxtype,
[ --with-boxtype valid values: dbox2,tripledragon,dreambox,ipbox,coolstream,spark,azbox,generic],
[ --with-boxtype valid values: tripledragon,spark,azbox,generic,duckbox,spark7162,armbox],
[case "${withval}" in
dbox2|dreambox|ipbox|tripledragon|coolstream|spark|azbox|generic)
tripledragon|azbox|generic)
BOXTYPE="$withval"
;;
;;
spark|spark7162)
BOXTYPE="spark"
BOXMODEL="$withval"
;;
dm*)
BOXTYPE="dreambox"
BOXMODEL="$withval"
;;
;;
ufs*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
atevio*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
fortis*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
octagon*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
hs7*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
dp*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
cuberevo*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
ipbox*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
arivalink200)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
tf*)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
hl101)
BOXTYPE="duckbox"
BOXMODEL="$withval"
;;
vusolo4k)
BOXTYPE="armbox"
BOXMODEL="$withval"
;;
hd51)
BOXTYPE="armbox"
BOXMODEL="$withval"
;;
*)
AC_MSG_ERROR([bad value $withval for --with-boxtype]) ;;
esac], [BOXTYPE="generic"])
AC_MSG_ERROR([bad value $withval for --with-boxtype])
;;
esac],
[BOXTYPE="generic"])
AC_ARG_WITH(boxmodel,
[ --with-boxmodel valid for dreambox: dm500, dm500plus, dm600pvr, dm56x0, dm7000, dm7020, dm7025
valid for ipbox: ip200, ip250, ip350, ip400],
AS_HELP_STRING([--with-boxmodel], [valid for generic: raspi])
AS_HELP_STRING([], [valid for duckbox: ufs910, ufs912, ufs913, ufs922, atevio7500, fortis_hdbox, octagon1008, hs7110, hs7810a, hs7119, hs7819, dp7000, cuberevo, cuberevo_mini, cuberevo_mini2, cuberevo_250hd, cuberevo_2000hd, cuberevo_3000hd, ipbox9900, ipbox99, ipbox55, arivalink200, tf7700, hl101])
AS_HELP_STRING([], [valid for spark: spark, spark7162])
AS_HELP_STRING([], [valid for armbox: hd51, vusolo4k]),
[case "${withval}" in
dm500|dm500plus|dm600pvr|dm56x0|dm7000|dm7020|dm7025)
if test "$BOXTYPE" = "dreambox"; then
ufs910|ufs912|ufs913|ufs922|atevio7500|fortis_hdbox|octagon1008|hs7110|hs7810a|hs7119|hs7819|dp7000|cuberevo|cuberevo_mini|cuberevo_mini2|cuberevo_250hd|cuberevo_2000hd|cuberevo_3000hd|ipbox9900|ipbox99|ipbox55|arivalink200|tf7700|hl101)
if test "$BOXTYPE" = "duckbox"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
ip200|ip250|ip350|ip400)
if test "$BOXTYPE" = "ipbox"; then
;;
spark|spark7162)
if test "$BOXTYPE" = "spark"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
;;
vusolo4k)
if test "$BOXTYPE" = "armbox"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
hd51)
if test "$BOXTYPE" = "armbox"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
raspi)
if test "$BOXTYPE" = "generic"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
;;
*)
AC_MSG_ERROR([unsupported value $withval for --with-boxmodel])
;;
esac],
[if test "$BOXTYPE" = "dreambox" -o "$BOXTYPE" = "ipbox" && test -z "$BOXMODEL"; then
AC_MSG_ERROR([Dreambox/IPBox needs --with-boxmodel])
fi])
;;
esac])
AC_SUBST(BOXTYPE)
AC_SUBST(BOXMODEL)
AM_CONDITIONAL(BOXTYPE_AZBOX, test "$BOXTYPE" = "azbox")
AM_CONDITIONAL(BOXTYPE_DBOX2, test "$BOXTYPE" = "dbox2")
AM_CONDITIONAL(BOXTYPE_TRIPLE, test "$BOXTYPE" = "tripledragon")
AM_CONDITIONAL(BOXTYPE_SPARK, test "$BOXTYPE" = "spark")
AM_CONDITIONAL(BOXTYPE_DREAMBOX, test "$BOXTYPE" = "dreambox")
AM_CONDITIONAL(BOXTYPE_IPBOX, test "$BOXTYPE" = "ipbox")
AM_CONDITIONAL(BOXTYPE_COOL, test "$BOXTYPE" = "coolstream")
AM_CONDITIONAL(BOXTYPE_GENERIC, test "$BOXTYPE" = "generic")
AM_CONDITIONAL(BOXTYPE_DUCKBOX, test "$BOXTYPE" = "duckbox")
AM_CONDITIONAL(BOXTYPE_ARMBOX, test "$BOXTYPE" = "armbox")
AM_CONDITIONAL(BOXMODEL_DM500,test "$BOXMODEL" = "dm500")
AM_CONDITIONAL(BOXMODEL_DM500PLUS,test "$BOXMODEL" = "dm500plus")
AM_CONDITIONAL(BOXMODEL_DM600PVR,test "$BOXMODEL" = "dm600pvr")
AM_CONDITIONAL(BOXMODEL_DM56x0,test "$BOXMODEL" = "dm56x0")
AM_CONDITIONAL(BOXMODEL_DM7000,test "$BOXMODEL" = "dm7000" -o "$BOXMODEL" = "dm7020" -o "$BOXMODEL" = "dm7025")
AM_CONDITIONAL(BOXMODEL_UFS910, test "$BOXMODEL" = "ufs910")
AM_CONDITIONAL(BOXMODEL_UFS912, test "$BOXMODEL" = "ufs912")
AM_CONDITIONAL(BOXMODEL_UFS913, test "$BOXMODEL" = "ufs913")
AM_CONDITIONAL(BOXMODEL_UFS922, test "$BOXMODEL" = "ufs922")
AM_CONDITIONAL(BOXMODEL_SPARK, test "$BOXMODEL" = "spark")
AM_CONDITIONAL(BOXMODEL_SPARK7162, test "$BOXMODEL" = "spark7162")
AM_CONDITIONAL(BOXMODEL_ATEVIO7500, test "$BOXMODEL" = "atevio7500")
AM_CONDITIONAL(BOXMODEL_FORTIS_HDBOX, test "$BOXMODEL" = "fortis_hdbox")
AM_CONDITIONAL(BOXMODEL_OCTAGON1008, test "$BOXMODEL" = "octagon1008")
AM_CONDITIONAL(BOXMODEL_HS7110, test "$BOXMODEL" = "hs7110")
AM_CONDITIONAL(BOXMODEL_HS7810A, test "$BOXMODEL" = "hs7810a")
AM_CONDITIONAL(BOXMODEL_HS7119, test "$BOXMODEL" = "hs7119")
AM_CONDITIONAL(BOXMODEL_HS7819, test "$BOXMODEL" = "hs7819")
AM_CONDITIONAL(BOXMODEL_DP7000, test "$BOXMODEL" = "dp7000")
AM_CONDITIONAL(BOXMODEL_IP200,test "$BOXMODEL" = "ip200")
AM_CONDITIONAL(BOXMODEL_IP250,test "$BOXMODEL" = "ip250")
AM_CONDITIONAL(BOXMODEL_IP350,test "$BOXMODEL" = "ip350")
AM_CONDITIONAL(BOXMODEL_IP400,test "$BOXMODEL" = "ip400")
AM_CONDITIONAL(BOXMODEL_CUBEREVO, test "$BOXMODEL" = "cuberevo")
AM_CONDITIONAL(BOXMODEL_CUBEREVO_MINI, test "$BOXMODEL" = "cuberevo_mini")
AM_CONDITIONAL(BOXMODEL_CUBEREVO_MINI2, test "$BOXMODEL" = "cuberevo_mini2")
AM_CONDITIONAL(BOXMODEL_CUBEREVO_250HD, test "$BOXMODEL" = "cuberevo_250hd")
AM_CONDITIONAL(BOXMODEL_CUBEREVO_2000HD, test "$BOXMODEL" = "cuberevo_2000hd")
AM_CONDITIONAL(BOXMODEL_CUBEREVO_3000HD, test "$BOXMODEL" = "cuberevo_3000hd")
AM_CONDITIONAL(BOXMODEL_IPBOX9900, test "$BOXMODEL" = "ipbox9900")
AM_CONDITIONAL(BOXMODEL_IPBOX99, test "$BOXMODEL" = "ipbox99")
AM_CONDITIONAL(BOXMODEL_IPBOX55, test "$BOXMODEL" = "ipbox55")
AM_CONDITIONAL(BOXMODEL_ARIVALINK200, test "$BOXMODEL" = "arivalink200")
AM_CONDITIONAL(BOXMODEL_TF7700, test "$BOXMODEL" = "tf7700")
AM_CONDITIONAL(BOXMODEL_HL101, test "$BOXMODEL" = "hl101")
AM_CONDITIONAL(BOXMODEL_RASPI,test "$BOXMODEL" = "raspi")
AM_CONDITIONAL(BOXMODEL_HD51, test "$BOXMODEL" = "hd51")
AM_CONDITIONAL(BOXMODEL_VUSOLO4K, test "$BOXMODEL" = "vusolo4k")
if test "$BOXTYPE" = "dbox2"; then
AC_DEFINE(HAVE_DBOX_HARDWARE, 1, [building for a dbox2])
elif test "$BOXTYPE" = "azbox"; then
AM_CONDITIONAL(BOXMODEL_RASPI, test "$BOXMODEL" = "raspi")
if test "$BOXTYPE" = "azbox"; then
AC_DEFINE(HAVE_AZBOX_HARDWARE, 1, [building for an azbox])
elif test "$BOXTYPE" = "tripledragon"; then
AC_DEFINE(HAVE_TRIPLEDRAGON, 1, [building for a tripledragon])
elif test "$BOXTYPE" = "spark"; then
AC_DEFINE(HAVE_SPARK_HARDWARE, 1, [building for a spark st7111 box])
elif test "$BOXTYPE" = "dreambox"; then
AC_DEFINE(HAVE_DREAMBOX_HARDWARE, 1, [building for a dreambox])
elif test "$BOXTYPE" = "ipbox"; then
AC_DEFINE(HAVE_IPBOX_HARDWARE, 1, [building for an ipbox])
elif test "$BOXTYPE" = "coolstream"; then
AC_DEFINE(HAVE_COOL_HARDWARE, 1, [building for a coolstream])
AC_DEFINE(HAVE_SPARK_HARDWARE, 1, [building for a goldenmedia 990 or edision pingulux])
AC_DEFINE(HAVE_SH4_HARDWARE, 1, [building for a sh4 box])
elif test "$BOXTYPE" = "duckbox"; then
AC_DEFINE(HAVE_DUCKBOX_HARDWARE, 1, [building for a duckbox])
AC_DEFINE(HAVE_SH4_HARDWARE, 1, [building for a sh4 box])
elif test "$BOXTYPE" = "generic"; then
AC_DEFINE(HAVE_GENERIC_HARDWARE, 1, [building for a generic device like a standard PC])
elif test "$BOXTYPE" = "armbox"; then
AC_DEFINE(HAVE_ARM_HARDWARE, 1, [building for an armbox])
fi
# TODO: do we need more defines?
if test "$BOXMODEL" = "dm500"; then
AC_DEFINE(BOXMODEL_DM500, 1, [dreambox 500])
elif test "$BOXMODEL" = "ip200"; then
AC_DEFINE(BOXMODEL_IP200, 1, [ipbox 200])
elif test "$BOXMODEL" = "ip250"; then
AC_DEFINE(BOXMODEL_IP250, 1, [ipbox 250])
elif test "$BOXMODEL" = "ip350"; then
AC_DEFINE(BOXMODEL_IP350, 1, [ipbox 350])
elif test "$BOXMODEL" = "ip400"; then
AC_DEFINE(BOXMODEL_IP400, 1, [ipbox 400])
if test "$BOXMODEL" = "ufs910"; then
AC_DEFINE(BOXMODEL_UFS910, 1, [ufs910])
elif test "$BOXMODEL" = "ufs912"; then
AC_DEFINE(BOXMODEL_UFS912, 1, [ufs912])
elif test "$BOXMODEL" = "ufs913"; then
AC_DEFINE(BOXMODEL_UFS913, 1, [ufs913])
elif test "$BOXMODEL" = "ufs922"; then
AC_DEFINE(BOXMODEL_UFS922, 1, [ufs922])
elif test "$BOXMODEL" = "spark"; then
AC_DEFINE(BOXMODEL_SPARK, 1, [spark])
elif test "$BOXMODEL" = "spark7162"; then
AC_DEFINE(BOXMODEL_SPARK7162, 1, [spark7162])
elif test "$BOXMODEL" = "atevio7500"; then
AC_DEFINE(BOXMODEL_ATEVIO7500, 1, [atevio7500])
elif test "$BOXMODEL" = "fortis_hdbox"; then
AC_DEFINE(BOXMODEL_FORTIS_HDBOX, 1, [fortis_hdbox])
elif test "$BOXMODEL" = "octagon1008"; then
AC_DEFINE(BOXMODEL_OCTAGON1008, 1, [octagon1008])
elif test "$BOXMODEL" = "hs7110"; then
AC_DEFINE(BOXMODEL_HS7110, 1, [hs7110])
elif test "$BOXMODEL" = "hs7810a"; then
AC_DEFINE(BOXMODEL_HS7810A, 1, [hs7810a])
elif test "$BOXMODEL" = "hs7119"; then
AC_DEFINE(BOXMODEL_HS7119, 1, [hs7119])
elif test "$BOXMODEL" = "hs7819"; then
AC_DEFINE(BOXMODEL_HS7819, 1, [hs7819])
elif test "$BOXMODEL" = "dp7000"; then
AC_DEFINE(BOXMODEL_DP7000, 1, [dp7000])
elif test "$BOXMODEL" = "cuberevo"; then
AC_DEFINE(BOXMODEL_CUBEREVO, 1, [cuberevo])
elif test "$BOXMODEL" = "cuberevo_mini"; then
AC_DEFINE(BOXMODEL_CUBEREVO_MINI, 1, [cuberevo_mini])
elif test "$BOXMODEL" = "cuberevo_mini2"; then
AC_DEFINE(BOXMODEL_CUBEREVO_MINI2, 1, [cuberevo_mini2])
elif test "$BOXMODEL" = "cuberevo_250hd"; then
AC_DEFINE(BOXMODEL_CUBEREVO_250HD, 1, [cuberevo_250hd])
elif test "$BOXMODEL" = "cuberevo_2000hd"; then
AC_DEFINE(BOXMODEL_CUBEREVO_2000HD, 1, [cuberevo_2000hd])
elif test "$BOXMODEL" = "cuberevo_3000hd"; then
AC_DEFINE(BOXMODEL_CUBEREVO_3000HD, 1, [cuberevo_3000hd])
elif test "$BOXMODEL" = "ipbox9900"; then
AC_DEFINE(BOXMODEL_IPBOX9900, 1, [ipbox9900])
elif test "$BOXMODEL" = "ipbox99"; then
AC_DEFINE(BOXMODEL_IPBOX99, 1, [ipbox99])
elif test "$BOXMODEL" = "ipbox55"; then
AC_DEFINE(BOXMODEL_IPBOX55, 1, [ipbox55])
elif test "$BOXMODEL" = "arivalink200"; then
AC_DEFINE(BOXMODEL_ARIVALINK200, 1, [arivalink200])
elif test "$BOXMODEL" = "tf7700"; then
AC_DEFINE(BOXMODEL_TF7700, 1, [tf7700])
elif test "$BOXMODEL" = "hl101"; then
AC_DEFINE(BOXMODEL_HL101, 1, [hl101])
elif test "$BOXMODEL" = "hd51"; then
AC_DEFINE(BOXMODEL_HD51, 1, [hd51])
elif test "$BOXMODEL" = "vusolo4k"; then
AC_DEFINE(BOXMODEL_VUSOLO4K, 1, [vusolo4k])
elif test "$BOXMODEL" = "raspi"; then
AC_DEFINE(BOXMODEL_RASPI, 1, [Raspberry pi])
AC_DEFINE(BOXMODEL_RASPI, 1, [raspberry pi])
fi
])
dnl backward compatiblity
AC_DEFUN([AC_GNU_SOURCE],
[AH_VERBATIM([_GNU_SOURCE],
[/* Enable GNU extensions on systems that have them. */
AC_DEFUN([AC_GNU_SOURCE], [
AH_VERBATIM([_GNU_SOURCE], [
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif])dnl
#endif
])dnl
AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl
AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
AC_DEFINE([_GNU_SOURCE])
])
AC_DEFUN([AC_PROG_EGREP],
[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
[if echo a | (grep -E '(a|b)') >/dev/null 2>&1
then ac_cv_prog_egrep='grep -E'
else ac_cv_prog_egrep='egrep'
fi])
EGREP=$ac_cv_prog_egrep
AC_SUBST([EGREP])
AC_DEFUN([AC_PROG_EGREP], [
AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], [
if echo a | (grep -E '(a|b)') >/dev/null 2>&1; then
ac_cv_prog_egrep='grep -E'
else
ac_cv_prog_egrep='egrep'
fi
])
EGREP=$ac_cv_prog_egrep
AC_SUBST([EGREP])
])

View File

@@ -1,8 +1,7 @@
noinst_LTLIBRARIES = libazbox.la
AM_CPPFLAGS = \
-I$(top_srcdir)/common \
-I$(top_srcdir)/include
-I$(top_srcdir)/common
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = -lpthread
@@ -14,5 +13,6 @@ libazbox_la_SOURCES = \
audio.cpp \
init.cpp \
playback.cpp \
pwrmngr.cpp \
record.cpp

View File

@@ -9,7 +9,7 @@
#include <proc_tools.h>
#include "audio_hal.h"
#include "audio_lib.h"
#include "lt_debug.h"
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
@@ -20,55 +20,54 @@
cAudio * audioDecoder = NULL;
typedef struct audio_pdata
{
int fd;
int clipfd;
int mixer_fd;
int mixer_num;
} audio_pdata;
#define P ((audio_pdata *)pdata)
cAudio::cAudio(void *, void *, void *)
{
pdata = calloc(1, sizeof(audio_pdata));
P->clipfd = -1;
P->mixer_fd = -1;
P->fd = open(AUDIO_DEVICE, O_RDONLY|O_CLOEXEC);
if (P->fd < 0)
lt_info("%s: open failed (%m)\n", __func__);
muted = false;
fd = -1;
clipfd = -1;
mixer_fd = -1;
openDevice();
Muted = false;
}
cAudio::~cAudio(void)
{
if (P->fd >= 0) {
ioctl(P->fd, AUDIO_CONTINUE); /* enigma2 also does CONTINUE before close... */
close(P->fd);
P->fd = -1;
closeDevice();
}
void cAudio::openDevice(void)
{
lt_debug("%s\n", __func__);
if (fd < 0)
{
if ((fd = open(AUDIO_DEVICE, O_RDONLY|O_CLOEXEC)) < 0)
lt_info("openDevice: open failed (%m)\n");
do_mute(true, false);
}
if (P->clipfd >= 0)
close(P->clipfd);
if (P->mixer_fd >= 0)
close(P->mixer_fd);
free(pdata);
else
lt_info("openDevice: already open (fd = %d)\n", fd);
}
int cAudio::mute(void)
void cAudio::closeDevice(void)
{
return SetMute(true);
lt_debug("%s\n", __func__);
ioctl(fd, AUDIO_CONTINUE); /* enigma2 also does CONTINUE before close... */
if (fd >= 0)
close(fd);
fd = -1;
if (clipfd >= 0)
close(clipfd);
clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
}
int cAudio::unmute(void)
int cAudio::do_mute(bool enable, bool remember)
{
return SetMute(false);
}
lt_debug("%s(%d, %d)\n", __func__, enable, remember);
int cAudio::SetMute(bool enable)
{
lt_debug("%s(%d)\n", __func__, enable);
muted = enable;
if (remember)
Muted = enable;
#if 0
/* does not work? */
if (ioctl(fd, AUDIO_SET_MUTE, enable) < 0 )
@@ -97,14 +96,14 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
lt_debug("%s(%d, %d)\n", __func__, left, right);
volume = (left + right) / 2;
if (P->clipfd != -1 && P->mixer_fd != -1) {
if (clipfd != -1 && mixer_fd != -1) {
int tmp = 0;
/* not sure if left / right is correct here, but it is always the same anyways ;-) */
if (! muted)
if (! Muted)
tmp = left << 8 | right;
int ret = ioctl(P->mixer_fd, MIXER_WRITE(P->mixer_num), &tmp);
int ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp);
if (ret == -1)
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, P->mixer_num, tmp);
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp);
return ret;
}
@@ -112,7 +111,7 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
mixer.volume_left = map_volume(left);
mixer.volume_right = map_volume(right);
if (ioctl(P->fd, AUDIO_SET_MIXER, &mixer) < 0)
if (ioctl(fd, AUDIO_SET_MIXER, &mixer) < 0)
lt_info("%s: AUDIO_SET_MIXER failed (%m)\n", __func__);
return 0;
@@ -122,16 +121,16 @@ int cAudio::Start(void)
{
lt_debug("%s\n", __func__);
int ret;
ioctl(P->fd, AUDIO_CONTINUE);
ret = ioctl(P->fd, AUDIO_PLAY);
ioctl(fd, AUDIO_CONTINUE);
ret = ioctl(fd, AUDIO_PLAY);
return ret;
}
int cAudio::Stop(void)
{
lt_debug("%s\n", __func__);
ioctl(P->fd, AUDIO_STOP);
ioctl(P->fd, AUDIO_CONTINUE); /* no idea why we have to stop and then continue => enigma2 does it, too */
ioctl(fd, AUDIO_STOP);
ioctl(fd, AUDIO_CONTINUE); /* no idea why we have to stop and then continue => enigma2 does it, too */
return 0;
}
@@ -143,7 +142,7 @@ bool cAudio::Pause(bool /*Pcm*/)
void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
{
lt_debug("%s %d\n", __func__, Mode);
ioctl(P->fd, AUDIO_SET_AV_SYNC, Mode);
ioctl(fd, AUDIO_SET_AV_SYNC, Mode);
};
//AUDIO_ENCODING_AC3
@@ -159,6 +158,7 @@ void cAudio::SetStreamType(AUDIO_FORMAT type)
{
int bypass = AUDIO_STREAMTYPE_MPEG;
lt_debug("%s %d\n", __func__, type);
StreamType = type;
switch (type)
{
@@ -175,7 +175,7 @@ void cAudio::SetStreamType(AUDIO_FORMAT type)
// Normaly the encoding should be set using AUDIO_SET_ENCODING
// But as we implemented the behavior to bypass (cause of e2) this is correct here
if (ioctl(P->fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
if (ioctl(fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
lt_info("%s: AUDIO_SET_BYPASS_MODE failed (%m)\n", __func__);
};
@@ -191,12 +191,12 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
const char *dsp_dev = getenv("DSP_DEVICE");
const char *mix_dev = getenv("MIX_DEVICE");
lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian);
if (P->clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __func__, P->clipfd);
if (clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd);
return -1;
}
P->mixer_num = -1;
P->mixer_fd = -1;
mixer_num = -1;
mixer_fd = -1;
/* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE
* if this device cannot be opened, we fall back to the internal OSS device
* Example:
@@ -213,8 +213,8 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
}
lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */
/* the tdoss dsp driver seems to work only on the second open(). really. */
P->clipfd = open(dsp_dev, O_WRONLY|O_CLOEXEC);
if (P->clipfd < 0) {
clipfd = open(dsp_dev, O_WRONLY|O_CLOEXEC);
if (clipfd < 0) {
lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__);
return -1;
}
@@ -223,29 +223,29 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
fmt = AFMT_S16_BE;
else
fmt = AFMT_S16_LE;
if (ioctl(P->clipfd, SNDCTL_DSP_SETFMT, &fmt))
if (ioctl(clipfd, SNDCTL_DSP_SETFMT, &fmt))
perror("SNDCTL_DSP_SETFMT");
if (ioctl(P->clipfd, SNDCTL_DSP_CHANNELS, &ch))
if (ioctl(clipfd, SNDCTL_DSP_CHANNELS, &ch))
perror("SNDCTL_DSP_CHANNELS");
if (ioctl(P->clipfd, SNDCTL_DSP_SPEED, &srate))
if (ioctl(clipfd, SNDCTL_DSP_SPEED, &srate))
perror("SNDCTL_DSP_SPEED");
if (ioctl(P->clipfd, SNDCTL_DSP_RESET))
if (ioctl(clipfd, SNDCTL_DSP_RESET))
perror("SNDCTL_DSP_RESET");
if (!mix_dev)
return 0;
P->mixer_fd = open(mix_dev, O_RDWR|O_CLOEXEC);
if (P->mixer_fd < 0) {
mixer_fd = open(mix_dev, O_RDWR|O_CLOEXEC);
if (mixer_fd < 0) {
lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev);
/* not a real error */
return 0;
}
if (ioctl(P->mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__);
devmask = 0;
}
if (ioctl(P->mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) {
if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) {
lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__);
stereo = 0;
}
@@ -253,8 +253,8 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
if (usable == 0) {
lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n",
__func__, devmask, stereo);
close(P->mixer_fd);
P->mixer_fd = -1;
close(mixer_fd);
mixer_fd = -1;
return 0; /* TODO: should we treat this as error? */
}
/* __builtin_popcount needs GCC, it counts the set bits... */
@@ -265,14 +265,14 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
__func__, devmask, stereo, __func__);
const char *tmp = getenv("MIX_NUMBER");
if (tmp)
P->mixer_num = atoi(tmp);
mixer_num = atoi(tmp);
lt_info("%s: mixer_num is %d -> device %08x\n",
__func__, P->mixer_num, (P->mixer_num >= 0) ? (1 << P->mixer_num) : 0);
__func__, mixer_num, (mixer_num >= 0) ? (1 << mixer_num) : 0);
/* no error checking, you'd better know what you are doing... */
} else {
P->mixer_num = 0;
mixer_num = 0;
while (!(usable & 0x01)) {
P->mixer_num++;
mixer_num++;
usable >>= 1;
}
}
@@ -285,11 +285,11 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
{
int ret;
// lt_debug("cAudio::%s\n", __FUNCTION__);
if (P->clipfd <= 0) {
if (clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1;
}
ret = write(P->clipfd, buffer, size);
ret = write(clipfd, buffer, size);
if (ret < 0)
lt_info("%s: write error (%m)\n", __FUNCTION__);
return ret;
@@ -298,15 +298,15 @@ int cAudio::WriteClip(unsigned char *buffer, int size)
int cAudio::StopClip()
{
lt_debug("%s\n", __FUNCTION__);
if (P->clipfd <= 0) {
if (clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1;
}
close(P->clipfd);
P->clipfd = -1;
if (P->mixer_fd >= 0)
close(P->mixer_fd);
P->mixer_fd = -1;
close(clipfd);
clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
setVolume(volume, volume);
return 0;
};
@@ -370,15 +370,10 @@ void cAudio::SetHdmiDD(bool enable)
lt_debug("%s %d\n", __func__, enable);
};
#define AUDIO_BYPASS_ON 0
#define AUDIO_BYPASS_OFF 1
void cAudio::SetSpdifDD(bool enable)
{
lt_debug("%s %d\n", __func__, enable);
//setBypassMode(!enable);
int mode = enable ? AUDIO_BYPASS_ON : AUDIO_BYPASS_OFF;
if (ioctl(P->fd, AUDIO_SET_BYPASS_MODE, mode) < 0)
lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode);
setBypassMode(!enable);
};
void cAudio::ScheduleMute(bool On)
@@ -391,7 +386,8 @@ void cAudio::EnableAnalogOut(bool enable)
lt_debug("%s %d\n", __FUNCTION__, enable);
};
#if 0
#define AUDIO_BYPASS_ON 0
#define AUDIO_BYPASS_OFF 1
void cAudio::setBypassMode(bool disable)
{
lt_debug("%s %d\n", __func__, disable);
@@ -400,4 +396,3 @@ void cAudio::setBypassMode(bool disable)
lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode);
return;
}
#endif

98
azbox/audio_lib.h Normal file
View File

@@ -0,0 +1,98 @@
/* public header file */
#ifndef _AUDIO_LIB_H_
#define _AUDIO_LIB_H_
#include "../common/cs_types.h"
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio
{
friend class cPlayback;
private:
int fd;
bool Muted;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode;
bool started;
int volume;
void openDevice(void);
void closeDevice(void);
int do_mute(bool enable, bool remember);
void setBypassMode(bool disable);
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(bool remember = true) { return do_mute(true, remember); };
int unmute(bool remember = true) { return do_mute(false, remember); };
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return Muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported();
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
};
#endif

1
azbox/cs_api.h Symbolic link
View File

@@ -0,0 +1 @@
../libspark/cs_api.h

View File

@@ -30,13 +30,11 @@
#include <cstring>
#include <cstdio>
#include <string>
#include <sys/ioctl.h>
#include "dmx_hal.h"
#include "dmx_lib.h"
#include "lt_debug.h"
/* Ugh... see comment in destructor for details... */
#include "video_hal.h"
#include "video_priv.h"
#include "video_lib.h"
extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
@@ -44,8 +42,14 @@ extern cVideo *videoDecoder;
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \
} while(0);
cDemux *videoDemux = NULL;
@@ -84,6 +88,9 @@ cDemux::cDemux(int n)
else
num = n;
fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
}
cDemux::~cDemux()
@@ -158,6 +165,8 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP);
close(fd);
fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL)
{
dmx_tp_count--;
@@ -264,13 +273,11 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc;
}
bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask)
{
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
if (len > DMX_FILTER_SIZE)
{
@@ -279,7 +286,6 @@ bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filt
}
s_flt.pid = pid;
s_flt.timeout = timeout;
flt = filter[0];
memcpy(s_flt.filter.filter, filter, len);
memcpy(s_flt.filter.mask, mask, len);
if (negmask != NULL)
@@ -383,11 +389,8 @@ bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filt
return true;
}
bool cDemux::pesFilter(const unsigned short _pid)
bool cDemux::pesFilter(const unsigned short pid)
{
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure
* what it is good for...
@@ -494,7 +497,7 @@ void cDemux::getSTC(int64_t * STC)
lt_debug("%s #%d\n", __func__, num);
int64_t pts = 0;
if (videoDecoder)
pts = videoDecoder->vdec->GetPTS();
pts = videoDecoder->GetPTS();
*STC = pts;
}

1
azbox/dmx_cs.h Normal file
View File

@@ -0,0 +1 @@
#include "dmx_lib.h"

70
azbox/dmx_lib.h Normal file
View File

@@ -0,0 +1,70 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -2,7 +2,7 @@
* determine the capabilities of the hardware.
* part of libstb-hal
*
* (C) 2010-2012,2016 Stefan Seyfried
* (C) 2010-2012 Stefan Seyfried
*
* License: GPL v2 or later
*/
@@ -30,9 +30,8 @@ hw_caps_t *get_hwcaps(void)
caps.display_type = HW_DISPLAY_LINE_TEXT;
caps.has_HDMI = 1;
caps.display_xres = 8;
caps.display_has_statusline = 0;
caps.display_can_deepstandby = 0;
caps.display_can_set_brightness = 0;
caps.display_has_statusline = 0;
strcpy(caps.boxvendor, "AZBox");
const char *tmp;
char buf[64];
@@ -48,7 +47,6 @@ hw_caps_t *get_hwcaps(void)
}
else
strcpy(caps.boxname, "(unknown model)");
strcpy(caps.boxarch, "mipsel");
return &caps;
}

View File

@@ -1,5 +1,5 @@
#include <unistd.h>
#include "init_td.h"
#include "init_lib.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args)

5
azbox/init_lib.h Normal file
View File

@@ -0,0 +1,5 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -50,7 +50,7 @@
#define IN_FILE "/tmp/rmfp.in2"
#define OUT_FILE "/tmp/rmfp.out2"
#include "playback_hal.h"
#include "playback.h"
extern "C"{
#include "e2mruainclude.h"
@@ -73,38 +73,8 @@ static time_t monotonic_ms(void)
}
#endif
class PBPrivate
{
public:
bool rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen);
void run_rmfp(void);
PBPrivate(void) {
playing = 0;
thread_started = false;
eof = false;
open_success = false;
pthread_mutex_init(&rmfp_cmd_mutex, NULL);
};
~PBPrivate(void) {
pthread_mutex_destroy(&rmfp_cmd_mutex);
};
int duration;
int playing;
int speed;
playmode_t pmode;
uint16_t apid;
uint16_t subpid;
bool eof;
bool open_success;
bool thread_started;
pthread_t thread;
pthread_mutex_t rmfp_cmd_mutex;
char *fname;
};
/* the mutex makes sure that commands are not interspersed */
bool PBPrivate::rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen)
bool cPlayback::rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen)
{
lt_info("%s: %d %d %d %d\n", __func__, cmd, param, has_param, buflen);
bool ret = true;
@@ -171,21 +141,21 @@ bool PBPrivate::rmfp_command(int cmd, int param, bool has_param, char *buf, int
* the output will be buffered after starting up and we will only
* see "Playback has started..." after the player exits
*/
void PBPrivate::run_rmfp()
void cPlayback::run_rmfp()
{
lt_debug("%s: starting\n", __func__);
thread_started = true;
//Watch for the space at the end
std::string base = "rmfp_player -dram 1 -ve 1 -waitexit ";
std::string filename(fname);
std::string filename(mfilename);
std::string file = '"' + filename + '"';
std::string final = base + file;
if (pmode == PLAYMODE_TS && duration != 0)
if (playMode == PLAYMODE_TS && mduration != 0)
{
std::stringstream du;
du << (duration /** 60000LL*/);
final = base + "-duration " + du.str() + " " + file;
std::stringstream duration;
duration << (mduration /** 60000LL*/);
final = base + "-duration " + duration.str() + " " + file;
}
pid_t pid = 0;
@@ -220,7 +190,7 @@ void PBPrivate::run_rmfp()
else if (strstr(output, "End of file..."))
{
playing = 1; /* this can happen without "Playback has started..." */
eof = true;
eof_reached = true;
lt_info("%s: ===================> eof_reached = true\n", __func__);
}
}
@@ -236,14 +206,14 @@ void PBPrivate::run_rmfp()
playing = 2;
else
playing = 0;
eof = true;
eof_reached = true;
pthread_exit(NULL);
}
/* helper function to call the cpp thread loop */
void *execute_rua_thread(void *c)
{
PBPrivate *obj = (PBPrivate *)c;
cPlayback *obj = (cPlayback *)c;
lt_info_c("%s\n", __func__);
obj->run_rmfp();
/* free(obj); // this is most likely wrong */
@@ -258,11 +228,11 @@ bool cPlayback::Open(playmode_t PlayMode)
"PLAYMODE_TS",
"PLAYMODE_FILE"
};
pd->pmode = PlayMode;
if (pd->pmode > 1)
playMode = PlayMode;
if (playMode > 1)
{
lt_info("%s: PlayMode %d out of range!\n", __func__, PlayMode);
pd->pmode = PLAYMODE_FILE;
playMode = PLAYMODE_FILE;
}
lt_info("%s: mode %d (%s)\n", __func__, PlayMode, aPLAYMODE[PlayMode]);
@@ -283,7 +253,7 @@ bool cPlayback::Open(playmode_t PlayMode)
if (i > 10)
{
lt_info("%s: ERROR - player is not idle after 10 seconds!\n", __func__);
pd->open_success = false;
open_success = false;
return false;
}
sleep(1);
@@ -296,15 +266,10 @@ bool cPlayback::Open(playmode_t PlayMode)
unlink(IN_FILE);
unlink(OUT_FILE);
pd->open_success = true;
open_success = true;
return 0;
}
bool cPlayback::Start(std::string /*filename*/, std::string /*headers*/)
{
return false;
}
//Used by Fileplay
bool cPlayback::Start(char *filename, unsigned short vpid, int vtype, unsigned short _apid,
int ac3, unsigned int duration)
@@ -313,49 +278,49 @@ bool cPlayback::Start(char *filename, unsigned short vpid, int vtype, unsigned s
lt_info("%s: filename=%s\n", __func__, filename);
lt_info("%s: vpid=%u vtype=%d apid=%u ac3=%d duration=%i open_success=%d\n",
__func__, vpid, vtype, _apid, ac3, duration, pd->open_success);
__func__, vpid, vtype, _apid, ac3, duration, open_success);
if (!pd->open_success)
if (!open_success)
return false;
pd->eof = false;
eof_reached = false;
//create playback path
pd->apid = 0;
pd->subpid = 0;
pd->fname = filename;
pd->duration = duration;
if (pthread_create(&pd->thread, 0, execute_rua_thread, pd) != 0)
apid = 0;
subpid = 0;
mfilename = filename;
mduration = duration;
if (pthread_create(&thread, 0, execute_rua_thread, this) != 0)
{
lt_info("%s: error creating rmfp_player thread! (out of memory?)\n", __func__);
ret = false;
}
while (! pd->playing)
while (! playing)
sleep(1);
if (pd->playing == 2)
pd->playing = 0;
if (playing == 2)
playing = 0;
return ret;
}
void cPlayback::Close(void)
{
lt_info("%s: playing %d thread_started %d\n", __func__, pd->playing, pd->thread_started);
lt_info("%s: playing %d thread_started %d\n", __func__, playing, thread_started);
if (pd->thread_started)
if (thread_started)
{
pd->rmfp_command(KEY_COMMAND_QUIT_ALL, 0, false, NULL, 0);
rmfp_command(KEY_COMMAND_QUIT_ALL, 0, false, NULL, 0);
if (pthread_join(pd->thread, NULL))
if (pthread_join(thread, NULL))
lt_info("%s: error joining rmfp thread (%m)\n", __func__);
pd->playing = 0;
pd->thread_started = false;
playing = 0;
thread_started = false;
}
else
lt_info("%s: Warning: thread_started == false!\n", __func__);
if (pd->open_success)
if (open_success)
{
proc_put("/proc/player", "1", 2);
pd->open_success = false;
open_success = false;
lt_info("%s: /proc/player switched to '1'\n", __func__);
usleep(1000000);
}
@@ -364,39 +329,39 @@ void cPlayback::Close(void)
bool cPlayback::SetAPid(unsigned short pid, int /*ac3*/)
{
lt_info("%s: pid %i\n", __func__, pid);
if (pid != pd->apid) {
pd->rmfp_command(KEY_COMMAND_SWITCH_AUDIO, pid, true, NULL, 0);
pd->apid = pid;
if (pid != apid) {
rmfp_command(KEY_COMMAND_SWITCH_AUDIO, pid, true, NULL, 0);
apid = pid;
}
return true;
}
bool cPlayback::SelectSubtitles(int pid, std::string /*charset*/)
bool cPlayback::SelectSubtitles(int pid)
{
lt_info("%s: pid %i\n", __func__, pid);
if (pid != pd->subpid)
if (pid != subpid)
{
pd->rmfp_command(KEY_COMMAND_SWITCH_SUBS, pid, true, NULL, 0);
pd->subpid = pid;
rmfp_command(KEY_COMMAND_SWITCH_SUBS, pid, true, NULL, 0);
subpid = pid;
}
return true;
}
bool cPlayback::SetSpeed(int speed)
{
lt_info("%s: playing %d speed %d\n", __func__, pd->playing, speed);
lt_info("%s: playing %d speed %d\n", __func__, playing, speed);
if (!pd->playing)
if (!playing)
return false;
pd->speed = speed;
playback_speed = speed;
if (speed > 1 || speed < 0)
pd->rmfp_command(CUSTOM_COMMAND_TRICK_SEEK, speed, true, NULL, 0);
rmfp_command(CUSTOM_COMMAND_TRICK_SEEK, speed, true, NULL, 0);
else if (speed == 0)
pd->rmfp_command(KEY_COMMAND_PAUSE, 0, false, NULL, 0);
rmfp_command(KEY_COMMAND_PAUSE, 0, false, NULL, 0);
else
pd->rmfp_command(KEY_COMMAND_PLAY, 0, false, NULL, 0);
rmfp_command(KEY_COMMAND_PLAY, 0, false, NULL, 0);
return true;
}
@@ -413,22 +378,22 @@ bool cPlayback::GetSpeed(int &/*speed*/) const
// in milliseconds
bool cPlayback::GetPosition(int &position, int &duration)
{
lt_debug("%s: playing %d\n", __func__, pd->playing);
lt_debug("%s: playing %d\n", __func__, playing);
if (pd->eof)
if (eof_reached)
{
position = pd->duration;
duration = pd->duration;
position = mduration;
duration = mduration;
return true;
}
if (!pd->playing)
if (!playing)
return false;
char buf[32];
/* custom command 222 returns "12345\n1234\n",
* first line is duration, second line is position */
if (! pd->rmfp_command(222, 0, false, buf, 32))
if (! rmfp_command(222, 0, false, buf, 32))
return false;
duration = atoi(buf);
char *p = strchr(buf, '\n');
@@ -439,11 +404,11 @@ bool cPlayback::GetPosition(int &position, int &duration)
if (duration == 0)
duration = position + 1000;
if (pd->pmode == PLAYMODE_TS)
if (playMode == PLAYMODE_TS)
{
if (position > pd->duration)
pd->duration = position + 1000;
duration = pd->duration;
if (position > mduration)
mduration = position + 1000;
duration = mduration;
return true;
}
return true;
@@ -451,23 +416,23 @@ bool cPlayback::GetPosition(int &position, int &duration)
bool cPlayback::SetPosition(int position, bool absolute)
{
lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, pd->playing);
lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, playing);
if (!pd->playing)
if (!playing)
return false;
int seconds = position / 1000;;
if (absolute)
{
pd->rmfp_command(KEY_COMMAND_SEEK_TO_TIME, seconds, true, NULL, 0);
rmfp_command(KEY_COMMAND_SEEK_TO_TIME, seconds, true, NULL, 0);
return true;
}
if (position > 0)
pd->rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_FWD, seconds, true, NULL, 0);
rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_FWD, seconds, true, NULL, 0);
else if (position < 0)
pd->rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_BWD, seconds, true, NULL, 0);
rmfp_command(CUSTOM_COMMAND_SEEK_RELATIVE_BWD, seconds, true, NULL, 0);
return true;
}
@@ -475,7 +440,7 @@ void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t
{
lt_info("%s\n", __func__);
char buf[32];
pd->rmfp_command(CUSTOM_COMMAND_AUDIO_COUNT, 0, false, buf, 3);
rmfp_command(CUSTOM_COMMAND_AUDIO_COUNT, 0, false, buf, 3);
unsigned int audio_count = atoi(buf);
*numpida = audio_count;
@@ -486,7 +451,7 @@ void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t
char streamidstring[11];
char audio_lang[21];
memset(buf, 0, sizeof(buf));
pd->rmfp_command(CUSTOM_COMMAND_GET_AUDIO_BY_ID, aid, true, buf, 32);
rmfp_command(CUSTOM_COMMAND_GET_AUDIO_BY_ID, aid, true, buf, 32);
memcpy(streamidstring, buf, 10);
streamidstring[10] = '\0';
memcpy(audio_lang, buf + 10, 20);
@@ -504,7 +469,7 @@ void cPlayback::FindAllSubs(uint16_t *spids, unsigned short *supported, uint16_t
lt_info("%s\n", __func__);
char buf[32];
pd->rmfp_command(CUSTOM_COMMAND_SUBS_COUNT, 0, false, buf, 3);
rmfp_command(CUSTOM_COMMAND_SUBS_COUNT, 0, false, buf, 3);
unsigned int spu_count = atoi(buf);
*numpids = spu_count;
@@ -515,7 +480,7 @@ void cPlayback::FindAllSubs(uint16_t *spids, unsigned short *supported, uint16_t
char streamidstring[11];
char spu_lang[21];
memset(buf, 0, sizeof(buf));
pd->rmfp_command(CUSTOM_COMMAND_GET_SUB_BY_ID, sid, true, buf, 32);
rmfp_command(CUSTOM_COMMAND_GET_SUB_BY_ID, sid, true, buf, 32);
memcpy(streamidstring, buf, 10);
streamidstring[10] = '\0';
memcpy(spu_lang, buf + 10, 20);
@@ -539,36 +504,18 @@ void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string
titles.clear();
}
void cPlayback::GetTitles(std::vector<int> &playlists, std::vector<std::string> &titles, int &current)
{
playlists.clear();
titles.clear();
current = 0;
}
void cPlayback::SetTitle(int /*title*/)
{
}
void cPlayback::RequestAbort(void)
{
}
uint64_t cPlayback::GetReadCount(void)
{
return 0;
}
cPlayback::cPlayback(int /*num*/)
{
lt_info("%s: constructor\n", __func__);
pd = new PBPrivate();
playing = 0;
thread_started = false;
eof_reached = false;
open_success = false;
pthread_mutex_init(&rmfp_cmd_mutex, NULL);
}
cPlayback::~cPlayback()
{
lt_info("%s\n", __func__);
delete pd;
pd = NULL;
pthread_mutex_destroy(&rmfp_cmd_mutex);
}

62
azbox/playback.h Normal file
View File

@@ -0,0 +1,62 @@
#ifndef __PLAYBACK_H
#define __PLAYBACK_H
#include <string>
#include <stdint.h>
#include <vector>
typedef enum {
PLAYMODE_TS = 0,
PLAYMODE_FILE,
} playmode_t;
class cPlayback
{
private:
pthread_mutex_t rmfp_cmd_mutex;
int playing;
bool eof_reached;
int playback_speed;
playmode_t playMode;
bool open_success;
uint16_t apid;
uint16_t subpid;
char *mfilename;
int mduration;
pthread_t thread;
bool thread_started;
/* private functions */
bool rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen);
public:
cPlayback(int num = 0);
~cPlayback();
void run_rmfp();
bool Open(playmode_t PlayMode);
void Close(void);
bool Start(char *filename, unsigned short vpid, int vtype, unsigned short apid,
int ac3, unsigned int duration);
bool SetAPid(unsigned short pid, int ac3);
bool SetSpeed(int speed);
bool GetSpeed(int &speed) const;
bool GetPosition(int &position, int &duration); /* pos: current time in ms, dur: file length in ms */
bool SetPosition(int position, bool absolute = false); /* position: jump in ms */
void FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language);
void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language);
bool SelectSubtitles(int pid);
void GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
#if 0
// Functions that are not used by movieplayer.cpp:
bool Stop(void);
bool GetOffset(off64_t &offset);
bool IsPlaying(void) const { return playing; }
bool IsEnabled(void) const { return enabled; }
void * GetHandle(void);
void * GetDmHandle(void);
int GetCurrPlaybackSpeed(void) const { return nPlaybackSpeed; }
void PlaybackNotify (int Event, void *pData, void *pTag);
void DMNotify(int Event, void *pTsBuf, void *Tag);
#endif
};
#endif

1
azbox/pwrmngr.cpp Symbolic link
View File

@@ -0,0 +1 @@
../libspark/pwrmngr.cpp

1
azbox/pwrmngr.h Symbolic link
View File

@@ -0,0 +1 @@
../libspark/pwrmngr.h

1
azbox/record_lib.h Symbolic link
View File

@@ -0,0 +1 @@
../libspark/record_lib.h

View File

@@ -37,9 +37,7 @@
#include <proc_tools.h>
#include "video_hal.h"
#include "video_priv.h"
#include "video_lib.h"
#define VIDEO_DEVICE "/dev/dvb/adapter0/video0"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)
@@ -77,22 +75,12 @@ static void show_iframe(int fd, unsigned char *iframe, size_t st_size);
#define VIDEO_STREAMTYPE_MPEG1 6
cVideo::cVideo(int, void *, void *, unsigned int)
{
vdec = new VDec();
}
cVideo::~cVideo(void)
{
delete vdec;
vdec = NULL;
}
VDec::VDec(void)
{
lt_debug("%s\n", __FUNCTION__);
//croppingMode = VID_DISPMODE_NORM;
//outputformat = VID_OUTFMT_RGBC_SVIDEO;
scartvoltage = -1;
video_standby = 0;
fd = -1;
@@ -123,17 +111,17 @@ VDec::VDec(void)
close(blankfd);
}
openDevice();
Pig(-1, -1, -1, -1, 1, 1);
Pig(-1, -1, -1, -1);
}
VDec::~VDec(void)
cVideo::~cVideo(void)
{
closeDevice();
if (blank_data)
free(blank_data);
}
void VDec::openDevice(void)
void cVideo::openDevice(void)
{
int n = 0;
lt_debug("%s\n", __func__);
@@ -155,7 +143,7 @@ retry:
playstate = VIDEO_STOPPED;
}
void VDec::closeDevice(void)
void cVideo::closeDevice(void)
{
lt_debug("%s\n", __func__);
if (fd >= 0)
@@ -193,11 +181,6 @@ int cVideo::setAspectRatio(int aspect, int mode)
}
int cVideo::getAspectRatio(void)
{
return vdec->getAspectRatio();
}
int VDec::getAspectRatio(void)
{
video_size_t s;
if (fd == -1)
@@ -215,7 +198,7 @@ int VDec::getAspectRatio(void)
return s.aspect_ratio * 2 + 1;
}
int cVideo::setCroppingMode(void)
int cVideo::setCroppingMode(int /*vidDispMode_t format*/)
{
return 0;
#if 0
@@ -232,16 +215,6 @@ int cVideo::setCroppingMode(void)
}
int cVideo::Start(void * /*PcrChannel*/, unsigned short /*PcrPid*/, unsigned short /*VideoPid*/, void * /*hChannel*/)
{
return vdec->Start();
}
int cVideo::Stop(bool blank)
{
return vdec->Stop(blank);
}
int VDec::Start(void)
{
lt_debug("%s playstate=%d\n", __FUNCTION__, playstate);
#if 0
@@ -254,7 +227,7 @@ int VDec::Start(void)
return fop(ioctl, VIDEO_PLAY);
}
int VDec::Stop(bool blank)
int cVideo::Stop(bool blank)
{
lt_debug("%s(%d)\n", __FUNCTION__, blank);
if (stillpicture)
@@ -269,12 +242,7 @@ int VDec::Stop(bool blank)
return fop(ioctl, VIDEO_STOP, blank ? 1 : 0);
}
int cVideo::setBlank(int b)
{
return vdec->setBlank(b);
}
int VDec::setBlank(int)
int cVideo::setBlank(int)
{
pthread_mutex_lock(&stillp_mutex);
if (blank_data)
@@ -323,7 +291,7 @@ int cVideo::SetVideoSystem(int video_system, bool remember)
int cVideo::getPlayState(void)
{
return vdec->playstate;
return playstate;
}
void cVideo::SetVideoMode(analog_mode_t mode)
@@ -351,14 +319,8 @@ void cVideo::SetVideoMode(analog_mode_t mode)
proc_put("/proc/stb/avs/0/colorformat", m, strlen(m));
}
bool cVideo::ShowPicture(const char * fname)
void cVideo::ShowPicture(const char * fname)
{
return vdec->ShowPicture(fname);
}
bool VDec::ShowPicture(const char * fname)
{
bool ret = false;
lt_debug("%s(%s)\n", __func__, fname);
char destname[512];
char cmd[512];
@@ -370,18 +332,18 @@ bool VDec::ShowPicture(const char * fname)
{
/* does not work and the driver does not seem to like it */
lt_info("%s: video_standby == true\n", __func__);
return ret;
return;
}
if (fd < 0)
{
lt_info("%s: decoder not opened\n", __func__);
return ret;
lt_info("%s: decoder not opened?\n", __func__);
return;
}
strcpy(destname, "/var/cache");
if (stat(fname, &st2))
{
lt_info("%s: could not stat %s (%m)\n", __func__, fname);
return ret;
return;
}
mkdir(destname, 0755);
/* the cache filename is (example for /share/tuxbox/neutrino/icons/radiomode.jpg):
@@ -431,25 +393,19 @@ bool VDec::ShowPicture(const char * fname)
read(mfd, iframe, st.st_size);
show_iframe(fd, iframe, st.st_size);
free(iframe);
ret = true;
out:
close(mfd);
pthread_mutex_unlock(&stillp_mutex);
return ret;
return;
}
void cVideo::StopPicture()
{
lt_debug("%s\n", __func__);
vdec->stillpicture = false;
stillpicture = false;
}
void cVideo::Standby(unsigned int bOn)
{
vdec->Standby(bOn);
}
void VDec::Standby(unsigned int bOn)
{
lt_debug("%s(%d)\n", __func__, bOn);
if (bOn)
@@ -472,12 +428,26 @@ int cVideo::getBlank(void)
return !ret;
}
void cVideo::Pig(int x, int y, int w, int h, int osd_w, int osd_h)
/* this function is regularly called, checks if video parameters
changed and triggers appropriate actions */
void cVideo::VideoParamWatchdog(void)
{
vdec->Pig(x, y, w, h, osd_w, osd_h);
#if 0
static unsigned int _v_info = (unsigned int) -1;
unsigned int v_info;
if (fd == -1)
return;
ioctl(fd, MPEG_VID_GET_V_INFO_RAW, &v_info);
if (_v_info != v_info)
{
lt_debug("%s params changed. old: %08x new: %08x\n", __FUNCTION__, _v_info, v_info);
setAspectRatio(-1, -1);
}
_v_info = v_info;
#endif
}
void VDec::Pig(int x, int y, int w, int h, int osd_w, int osd_h)
void cVideo::Pig(int x, int y, int w, int h, int osd_w, int osd_h)
{
char buffer[64];
int _x, _y, _w, _h;
@@ -539,11 +509,6 @@ static inline int rate2csapi(int rate)
}
void cVideo::getPictureInfo(int &width, int &height, int &rate)
{
vdec->getPictureInfo(width, height, rate);
}
void VDec::getPictureInfo(int &width, int &height, int &rate)
{
video_size_t s;
int r;
@@ -589,11 +554,6 @@ void cVideo::SetSyncMode(AVSYNC_TYPE mode)
};
int cVideo::SetStreamType(VIDEO_FORMAT type)
{
return vdec->SetStreamType(type);
}
int VDec::SetStreamType(VIDEO_FORMAT type)
{
static const char *VF[] = {
"VIDEO_FORMAT_MPEG2",
@@ -625,7 +585,7 @@ int VDec::SetStreamType(VIDEO_FORMAT type)
return 0;
}
int64_t VDec::GetPTS(void)
int64_t cVideo::GetPTS(void)
{
int64_t pts = 0;
if (ioctl(fd, VIDEO_GET_PTS, &pts) < 0)

196
azbox/video_lib.h Normal file
View File

@@ -0,0 +1,196 @@
#ifndef _VIDEO_TD_H
#define _VIDEO_TD_H
#include <linux/dvb/video.h>
#include "../common/cs_types.h"
#include "dmx_lib.h"
typedef enum {
ANALOG_SD_RGB_CINCH = 0x00,
ANALOG_SD_YPRPB_CINCH,
ANALOG_HD_RGB_CINCH,
ANALOG_HD_YPRPB_CINCH,
ANALOG_SD_RGB_SCART = 0x10,
ANALOG_SD_YPRPB_SCART,
ANALOG_HD_RGB_SCART,
ANALOG_HD_YPRPB_SCART,
ANALOG_SCART_MASK = 0x10
} analog_mode_t;
typedef enum {
VIDEO_FORMAT_MPEG2 = 0,
VIDEO_FORMAT_MPEG4,
VIDEO_FORMAT_VC1,
VIDEO_FORMAT_JPEG,
VIDEO_FORMAT_GIF,
VIDEO_FORMAT_PNG
} VIDEO_FORMAT;
typedef enum {
VIDEO_SD = 0,
VIDEO_HD,
VIDEO_120x60i,
VIDEO_320x240i,
VIDEO_1440x800i,
VIDEO_360x288i
} VIDEO_DEFINITION;
typedef enum {
VIDEO_FRAME_RATE_23_976 = 0,
VIDEO_FRAME_RATE_24,
VIDEO_FRAME_RATE_25,
VIDEO_FRAME_RATE_29_97,
VIDEO_FRAME_RATE_30,
VIDEO_FRAME_RATE_50,
VIDEO_FRAME_RATE_59_94,
VIDEO_FRAME_RATE_60
} VIDEO_FRAME_RATE;
typedef enum {
DISPLAY_AR_1_1,
DISPLAY_AR_4_3,
DISPLAY_AR_14_9,
DISPLAY_AR_16_9,
DISPLAY_AR_20_9,
DISPLAY_AR_RAW,
} DISPLAY_AR;
typedef enum {
DISPLAY_AR_MODE_PANSCAN = 0,
DISPLAY_AR_MODE_LETTERBOX,
DISPLAY_AR_MODE_NONE,
DISPLAY_AR_MODE_PANSCAN2
} DISPLAY_AR_MODE;
typedef enum {
VIDEO_DB_DR_NEITHER = 0,
VIDEO_DB_ON,
VIDEO_DB_DR_BOTH
} VIDEO_DB_DR;
typedef enum {
VIDEO_PLAY_STILL = 0,
VIDEO_PLAY_CLIP,
VIDEO_PLAY_TRICK,
VIDEO_PLAY_MOTION,
VIDEO_PLAY_MOTION_NO_SYNC
} VIDEO_PLAY_MODE;
typedef enum {
VIDEO_STD_NTSC,
VIDEO_STD_SECAM,
VIDEO_STD_PAL,
VIDEO_STD_480P,
VIDEO_STD_576P,
VIDEO_STD_720P60,
VIDEO_STD_1080I60,
VIDEO_STD_720P50,
VIDEO_STD_1080I50,
VIDEO_STD_1080P30,
VIDEO_STD_1080P24,
VIDEO_STD_1080P25,
VIDEO_STD_AUTO,
VIDEO_STD_1080P50, /* SPARK only */
VIDEO_STD_MAX
} VIDEO_STD;
/* not used, for dummy functions */
typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER,
VIDEO_HDMI_CEC_MODE_RECORDER
} VIDEO_HDMI_CEC_MODE;
typedef enum
{
VIDEO_CONTROL_BRIGHTNESS = 0,
VIDEO_CONTROL_CONTRAST,
VIDEO_CONTROL_SATURATION,
VIDEO_CONTROL_HUE,
VIDEO_CONTROL_SHARPNESS,
VIDEO_CONTROL_MAX = VIDEO_CONTROL_SHARPNESS
} VIDEO_CONTROL;
class cVideo
{
friend class cDemux;
friend class cPlayback;
private:
/* video device */
int fd;
/* apparently we cannot query the driver's state
=> remember it */
video_play_state_t playstate;
int /*vidDispMode_t*/ croppingMode;
int /*vidOutFmt_t*/ outputformat;
int scartvoltage;
VIDEO_FORMAT StreamType;
VIDEO_DEFINITION VideoDefinition;
DISPLAY_AR DisplayAR;
VIDEO_PLAY_MODE SyncMode;
DISPLAY_AR_MODE ARMode;
VIDEO_DB_DR eDbDr;
DISPLAY_AR PictureAR;
VIDEO_FRAME_RATE FrameRate;
int video_standby;
int64_t GetPTS(void);
void openDevice(void);
void closeDevice(void);
public:
/* constructor & destructor */
cVideo(int mode, void *, void *, unsigned int unit = 0);
~cVideo(void);
void * GetTVEnc() { return NULL; };
void * GetTVEncSD() { return NULL; };
/* aspect ratio */
int getAspectRatio(void);
void getPictureInfo(int &width, int &height, int &rate);
int setAspectRatio(int aspect, int mode);
/* cropping mode */
int setCroppingMode(int x = 0 /*vidDispMode_t x = VID_DISPMODE_NORM*/);
/* get play state */
int getPlayState(void);
/* blank on freeze */
int getBlank(void);
int setBlank(int enable);
/* change video play state. Parameters are all unused. */
int Start(void *PcrChannel = NULL, unsigned short PcrPid = 0, unsigned short VideoPid = 0, void *x = NULL);
int Stop(bool blank = true);
bool Pause(void);
/* set video_system */
int SetVideoSystem(int video_system, bool remember = true);
int SetStreamType(VIDEO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE mode);
bool SetCECMode(VIDEO_HDMI_CEC_MODE) { return true; };
void SetCECAutoView(bool) { return; };
void SetCECAutoStandby(bool) { return; };
void ShowPicture(const char * fname);
void StopPicture();
void Standby(unsigned int bOn);
void Pig(int x, int y, int w, int h, int osd_w = 1064, int osd_h = 600);
void SetControl(int, int) { return; };
void VideoParamWatchdog(void);
void setContrast(int val);
void SetVideoMode(analog_mode_t mode);
void SetDBDR(int) { return; };
void SetAudioHandle(void *) { return; };
void SetAutoModes(int [VIDEO_STD_MAX]) { return; };
int OpenVBI(int) { return 0; };
int CloseVBI(void) { return 0; };
int StartVBI(unsigned short) { return 0; };
int StopVBI(void) { return 0; };
void SetDemux(cDemux *dmx);
};
#endif

View File

@@ -1,60 +0,0 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* private video functions, to be used only inside libstb-hal
*/
#ifndef __video_priv__
#define __video_priv__
#include <video_hal.h>
#include <linux/dvb/video.h>
class VDec
{
public:
/* all public, used inside libstb-hal only anyways... */
int fd; /* video device fd */
/* apparently we cannot query the driver's state
=> remember it */
video_play_state_t playstate;
int video_standby;
bool stillpicture;
/* constructor & destructor */
VDec(void);
~VDec(void);
/* used directly by cVideo */
int getAspectRatio(void);
void getPictureInfo(int &width, int &height, int &rate);
int Start(void);
int Stop(bool blank = true);
int setBlank(int blank);
int SetStreamType(VIDEO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE mode);
bool ShowPicture(const char * fname);
void Standby(unsigned int bOn);
void Pig(int x, int y, int w, int h, int osd_w, int osd_h);
/* used internally by dmx */
int64_t GetPTS(void);
/* used internally by playback */
void openDevice(void);
void closeDevice(void);
};
#endif

View File

@@ -1,13 +1,33 @@
noinst_LTLIBRARIES = libcommon.la
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = -lpthread
if BOXTYPE_DUCKBOX
AM_CXXFLAGS += \
-I $(top_srcdir)/include
-I $(top_srcdir)/include \
-I $(top_srcdir)/libdvbci
endif
if BOXTYPE_ARMBOX
AM_CXXFLAGS += \
-I $(top_srcdir)/include \
-I $(top_srcdir)/libdvbci
endif
if BOXTYPE_DUCKBOX
libcommon_la_SOURCES = \
ca.cpp \
lt_debug.c \
proc_tools.c \
pwrmngr.cpp \
version_hal.cpp
ca_ci.cpp
else
if BOXTYPE_ARMBOX
libcommon_la_SOURCES = \
ca_ci.cpp
else
libcommon_la_SOURCES = \
ca.cpp
endif
endif
libcommon_la_SOURCES += \
lt_debug.cpp \
proc_tools.c

View File

@@ -1,6 +1,9 @@
/*
* dummy functions to implement ca_cs.h interface
*/
#if HAVE_DUCKBOX_HARDWARE || HAVE_ARM_HARDWARE
#include "ca_ci.h"
#else
#ifndef __CA_LIBTRIPLE_H_
#define __CA_LIBTRIPLE_H_
@@ -8,15 +11,12 @@
#include "cs_types.h"
#include <vector>
#include <set>
typedef std::set<int> ca_map_t;
typedef ca_map_t::iterator ca_map_iterator_t;
typedef std::vector<u16> CaIdVector;
typedef std::vector<u16>::iterator CaIdVectorIterator;
typedef std::vector<u16>::const_iterator CaIdVectorConstIterator;
enum CA_INIT_MASK {
CA_INIT_SC = 1,
CA_INIT_SC = 1,
CA_INIT_CI,
CA_INIT_BOTH
};
@@ -24,7 +24,7 @@ enum CA_INIT_MASK {
enum CA_SLOT_TYPE {
CA_SLOT_TYPE_SMARTCARD,
CA_SLOT_TYPE_CI,
CA_SLOT_TYPE_ALL,
CA_SLOT_TYPE_ALL
};
enum CA_MESSAGE_FLAGS {
@@ -67,13 +67,18 @@ enum CA_MESSAGE_MSGID {
CA_MESSAGE_MSG_MMI_CLOSE,
CA_MESSAGE_MSG_INTERNAL,
CA_MESSAGE_MSG_PMT_ARRIVED,
CA_MESSAGE_MSG_CAPMT_ARRIVED,
CA_MESSAGE_MSG_CAT_ARRIVED,
CA_MESSAGE_MSG_ECM_ARRIVED,
CA_MESSAGE_MSG_EMM_ARRIVED,
CA_MESSAGE_MSG_CHANNEL_CHANGE,
CA_MESSAGE_MSG_EXIT,
CA_MESSAGE_MSG_GUI_READY,
CA_MESSAGE_MSG_EXIT
};
typedef std::set<int> ca_map_t;
typedef ca_map_t::iterator ca_map_iterator_t;
typedef struct CA_MESSAGE {
uint32_t MsgId;
enum CA_SLOT_TYPE SlotType;
@@ -95,9 +100,9 @@ public:
uint32_t GetNumberSmartCardSlots(void);
static cCA *GetInstance(void);
bool SendPMT(int Unit, unsigned char *Data, int Len, CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL);
bool SendCAPMT(u64 /*Source*/, u8 /*DemuxSource*/, u8 /*DemuxMask*/, const unsigned char * /*CAPMT*/, u32 /*CAPMTLen*/, const unsigned char * /*RawPMT*/, u32 /*RawPMTLen*/, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL) { (void)SlotType; return true; };
bool SendCAPMT(u64 /*Source*/, u8 /*DemuxSource*/, u8 /*DemuxMask*/, const unsigned char * /*CAPMT*/, u32 /*CAPMTLen*/, const unsigned char * /*RawPMT*/, u32 /*RawPMTLen*/, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL, unsigned char scrambled = 0, ca_map_t camap ={0}, int mode = 0, bool enable = false) { (void)SlotType;(void)scrambled;(void)camap;(void)mode;(void)enable; return true; };
// bool SendCAPMT(u64 /*Source*/, u8 /*DemuxSource*/, u8 /*DemuxMask*/, const unsigned char * /*CAPMT*/, u32 /*CAPMTLen*/, const unsigned char * /*RawPMT*/, u32 /*RawPMTLen*/) { return true; };
bool SendCAPMT(u64 /*Source*/, u8 /*DemuxSource*/, u8 /*DemuxMask*/, const unsigned char * /*CAPMT*/, u32 /*CAPMTLen*/, const unsigned char * /*RawPMT*/, u32 /*RawPMTLen*/, enum CA_SLOT_TYPE
/*SlotType*/, unsigned char /*scrambled = 0*/, ca_map_t /*camap = std::set<int>()*/, int /*mode = 0*/, bool /*enabled = false*/) { return true; };
bool SendMessage(const CA_MESSAGE *Msg);
void SetInitMask(enum CA_INIT_MASK InitMask);
int GetCAIDS(CaIdVector & /*Caids*/) { return 0; };
@@ -112,7 +117,10 @@ public:
void InputAnswer(enum CA_SLOT_TYPE, uint32_t Slot, uint8_t * Data, int Len);
void MenuClose(enum CA_SLOT_TYPE, uint32_t Slot);
void SetTSClock(u32 /*Speed*/) { return; };
bool checkChannelID(u64 /*chanID*/) { return false; };
void setCheckLiveSlot(int /*check*/) { return; };
virtual ~cCA();
};
#endif // __CA_LIBTRIPLE_H_
#endif // HAVE_DUCKBOX_HARDWARE

1769
common/ca_ci.cpp Normal file

File diff suppressed because it is too large Load Diff

350
common/ca_ci.h Normal file
View File

@@ -0,0 +1,350 @@
#ifndef __CA_H_
#define __CA_H_
#include <stdint.h>
#include <asm/types.h>
#include <pthread.h>
#include <list>
#include <queue>
#include <vector>
#include <set>
#include "mmi.h"
#include "cs_types.h"
#include "cs_api.h"
/* constants taken from dvb-apps */
#define T_SB 0x80 // sb primitive h<--m
#define T_RCV 0x81 // receive primitive h-->m
#define T_CREATE_T_C 0x82 // create transport connection primitive h-->m
#define T_C_T_C_REPLY 0x83 // ctc reply primitive h<--m
#define T_DELETE_T_C 0x84 // delete tc primitive h<->m
#define T_D_T_C_REPLY 0x85 // dtc reply primitive h<->m
#define T_REQUEST_T_C 0x86 // request transport connection primitive h<--m
#define T_NEW_T_C 0x87 // new tc / reply to t_request primitive h-->m
#define T_T_C_ERROR 0x77 // error creating tc primitive h-->m
#define T_DATA_LAST 0xA0 // convey data from higher constructed h<->m
#define T_DATA_MORE 0xA1 // convey data from higher constructed h<->m
/* max multi decrypt per ci-cam */
#define CI_MAX_MULTI 5
enum CA_INIT_MASK {
CA_INIT_SC = 1,
CA_INIT_CI,
CA_INIT_BOTH
};
enum CA_SLOT_TYPE {
CA_SLOT_TYPE_SMARTCARD,
CA_SLOT_TYPE_CI,
CA_SLOT_TYPE_ALL
};
enum CA_MESSAGE_FLAGS {
CA_MESSAGE_EMPTY = (1 << 0),
CA_MESSAGE_HAS_PARAM1_DATA = (1 << 1), /// Free after use!
CA_MESSAGE_HAS_PARAM1_INT = (1 << 2),
CA_MESSAGE_HAS_PARAM1_PTR = (1 << 3),
CA_MESSAGE_HAS_PARAM2_INT = (1 << 4),
CA_MESSAGE_HAS_PARAM2_PTR = (1 << 5),
CA_MESSAGE_HAS_PARAM2_DATA = (1 << 6),
CA_MESSAGE_HAS_PARAM3_DATA = (1 << 7), /// Free after use!
CA_MESSAGE_HAS_PARAM3_INT = (1 << 8),
CA_MESSAGE_HAS_PARAM3_PTR = (1 << 9),
CA_MESSAGE_HAS_PARAM4_INT = (1 << 10),
CA_MESSAGE_HAS_PARAM4_PTR = (1 << 11),
CA_MESSAGE_HAS_PARAM4_DATA = (1 << 12),
CA_MESSAGE_HAS_PARAM5_INT = (1 << 13),
CA_MESSAGE_HAS_PARAM5_PTR = (1 << 14),
CA_MESSAGE_HAS_PARAM5_DATA = (1 << 15),
CA_MESSAGE_HAS_PARAM6_INT = (1 << 16),
CA_MESSAGE_HAS_PARAM6_PTR = (1 << 17),
CA_MESSAGE_HAS_PARAM6_DATA = (1 << 18),
CA_MESSAGE_HAS_PARAM1_LONG = (1 << 19),
CA_MESSAGE_HAS_PARAM2_LONG = (1 << 20),
CA_MESSAGE_HAS_PARAM3_LONG = (1 << 21),
CA_MESSAGE_HAS_PARAM4_LONG = (1 << 22)
};
enum CA_MESSAGE_MSGID {
CA_MESSAGE_MSG_INSERTED,
CA_MESSAGE_MSG_REMOVED,
CA_MESSAGE_MSG_INIT_OK,
CA_MESSAGE_MSG_INIT_FAILED,
CA_MESSAGE_MSG_MMI_MENU,
CA_MESSAGE_MSG_MMI_MENU_ENTER,
CA_MESSAGE_MSG_MMI_MENU_ANSWER,
CA_MESSAGE_MSG_MMI_LIST,
CA_MESSAGE_MSG_MMI_TEXT,
CA_MESSAGE_MSG_MMI_REQ_INPUT,
CA_MESSAGE_MSG_MMI_CLOSE,
CA_MESSAGE_MSG_INTERNAL,
CA_MESSAGE_MSG_PMT_ARRIVED,
CA_MESSAGE_MSG_CAPMT_ARRIVED,
CA_MESSAGE_MSG_CAT_ARRIVED,
CA_MESSAGE_MSG_ECM_ARRIVED,
CA_MESSAGE_MSG_EMM_ARRIVED,
CA_MESSAGE_MSG_CHANNEL_CHANGE,
CA_MESSAGE_MSG_GUI_READY,
CA_MESSAGE_MSG_EXIT
};
typedef struct CA_MESSAGE {
uint32_t MsgId;
enum CA_SLOT_TYPE SlotType;
int Slot;
uint32_t Flags;
union {
uint8_t *Data[4];
uint32_t Param[4];
void *Ptr[4];
uint64_t ParamLong[4];
} Msg;
} CA_MESSAGE;
typedef std::set<int> ca_map_t;
typedef ca_map_t::iterator ca_map_iterator_t;
typedef std::vector<u16> bSIDVector;
typedef std::vector<u16> CaIdVector;
typedef std::vector<u16>::iterator CaIdVectorIterator;
typedef std::vector<u16>::const_iterator CaIdVectorConstIterator;
#define CA_MESSAGE_SIZE sizeof(CA_MESSAGE)
#define CA_MESSAGE_ENTRIES 256
#define CA_MESSAGE_ENTRIES_CI 128
#define CA_MESSAGE_ENTRIES_SC 64
#ifndef CS_CA_PDATA
#define CS_CA_PDATA void
#endif
typedef enum {
TUNER_A,
TUNER_B,
TUNER_C,
TUNER_D
} source_t;
typedef enum {
eDataTimeout,
eDataError,
eDataReady,
eDataWrite,
eDataStatusChanged
} eData;
typedef enum {
eStatusNone,
eStatusWait,
eStatusReset
} eStatus;
struct queueData
{
__u8 prio;
unsigned char *data;
unsigned int len;
queueData(unsigned char *_data, unsigned int _len, __u8 _prio = 0)
:prio(_prio), data(_data), len(_len)
{
}
bool operator < ( const struct queueData &a ) const
{
return prio < a.prio;
}
};
class eDVBCIMMISession;
class eDVBCIApplicationManagerSession;
class eDVBCICAManagerSession;
class eDVBCIContentControlManagerSession;
typedef struct
{
pthread_t slot_thread;
unsigned int slot;
int fd;
int connection_id;
eStatus status;
int receivedLen;
unsigned char* receivedData;
void* pClass;
bool pollConnection;
bool camIsReady;
eDVBCIMMISession* mmiSession;
eDVBCIApplicationManagerSession* appSession;
eDVBCICAManagerSession* camgrSession;
eDVBCIContentControlManagerSession* ccmgrSession;
bool hasAppManager;
bool hasMMIManager;
bool hasCAManager;
bool hasCCManager;
bool hasDateTime;
bool mmiOpened;
bool init;
bool ccmgr_ready;
char ci_dev[32];
char name[512];
bool newPids;
bool newCapmt;
bool multi;
bool recordUse[CI_MAX_MULTI];
bool liveUse[CI_MAX_MULTI];
u16 SID[CI_MAX_MULTI];
u64 TP;
int ci_use_count;
u32 pmtlen;
u8 source;
u8 camask;
unsigned char pmtdata[1024 * 4];
int counter;
CaIdVector cam_caids;
std::priority_queue<queueData> sendqueue;
std::vector<u16> pids;
bSIDVector bsids;
unsigned char lastKey[32];
unsigned char scrambled;
u8 lastParity;
bool DataLast;
bool DataRCV;
bool SidBlackListed;
/* private data */
void *private_data;
} eDVBCISlot;
eData sendData(eDVBCISlot *slot, unsigned char* data, int len);
typedef std::list<eDVBCISlot*>::iterator SlotIt;
/// CA module class
class cCA {
private:
/// Static instance of the CA module
// static cCA *inst;
/// Private constructor (singleton method)
cCA(void);
/// Private data for the CA module
CS_CA_PDATA *privateData;
/// set inputs with tuner letter in tsmux
void setInputs();
/// write ci info file to /tmp
void write_ci_info(int slot, CaIdVector caids);
/// delete ci info file
void del_ci_info(int slot);
/// extract audio / video pids from capmt
void extractPids(eDVBCISlot* slot);
/// ci module is detected
void ci_inserted(eDVBCISlot* slot);
/// ci module is removed
void ci_removed(eDVBCISlot* slot);
/// decode the tpdu tag
void process_tpdu(eDVBCISlot* slot, unsigned char tpdu_tag, __u8* data, int asn_data_length, int con_id);
/// set flag of running ci record to false
bool StopRecordCI( u64 TP, u16 SID, u8 source, u32 calen);
/// set flag of running ci live-tv to false
bool StopLiveCI( u64 TP, u16 SID, u8 source, u32 calen);
/// find an unused ci slot for use with service
SlotIt FindFreeSlot(u64 tpid, u8 source, u16 sid, ca_map_t camap, u8 scrambled);
/// get slot iterator by slot number
SlotIt GetSlot(unsigned int slot);
/// send buffered capmt to ci modul
bool SendCaPMT(eDVBCISlot* slot);
/// send a dummy capmt to ci for deactivating
bool SendNullPMT(eDVBCISlot* slot);
/// set ci source
void setSource(eDVBCISlot* slot);
/// set demux source
void setInputSource(eDVBCISlot* slot, bool ci);
/// check if data in queue
bool checkQueueSize(eDVBCISlot* slot);
enum CA_INIT_MASK initMask;
int num_slots;
bool init;
void SendPMT();
pthread_mutex_t ciMutex;
std::list<eDVBCISlot*> slot_data;
pthread_t slot_thread;
public:
/// sh4 unused
bool Init(void);
/// init ci and start the loop
cCA(int Slots);
/// Returns the number of CI slots
uint32_t GetNumberCISlots(void);
/// Returns the number of Smartcard slots
uint32_t GetNumberSmartCardSlots(void);
/// Singleton
static cCA *GetInstance(void);
/// Send PMT to a individual or to all available modules (DEPRECATED)
bool SendPMT(int Unit, unsigned char *Data, int Len, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL);
/// Sends a message to the CA thread
bool SendMessage(const CA_MESSAGE *Msg);
/// Sets which modules to initialize. It is only
/// possible to change this once!
/// sh4 unused
void SetInitMask(enum CA_INIT_MASK InitMask);
/// Sets the frequency (in Hz) of the TS stream input (only valid for CI)
/// sh4 unused
void SetTSClock(u32 Speed);
/// Start the CA module
/// sh4 unused
bool Start(void);
/// Stops the CA module
/// sh4 unused
void Stop(void);
/// Notify that the GUI is ready to receive messages
/// (CA messages coming from a module)
/// sh4 unused
void Ready(bool Set);
/// Resets a module (if possible)
/// sh4 unused
void ModuleReset(enum CA_SLOT_TYPE, uint32_t Slot);
/// Checks if a module is present
bool ModulePresent(enum CA_SLOT_TYPE, uint32_t Slot);
/// Returns the module name in array Name
void ModuleName(enum CA_SLOT_TYPE, uint32_t Slot, char *Name);
/// Notify the module we want to enter menu
void MenuEnter(enum CA_SLOT_TYPE, uint32_t Slot);
/// Notify the module with our answer (choice nr)
void MenuAnswer(enum CA_SLOT_TYPE, uint32_t Slot, uint32_t choice);
/// Notify the module with our answer (binary)
void InputAnswer(enum CA_SLOT_TYPE, uint32_t Slot, uint8_t * Data, int Len);
/// Notify the module we closed the menu
void MenuClose(enum CA_SLOT_TYPE, uint32_t Slot);
/// Get the supported CAIDs
int GetCAIDS(CaIdVector &Caids);
/// Send a CA-PMT object and Raw unparsed PMT to the CA layer
bool SendCAPMT(u64 /*Source*/, u8 /*DemuxSource*/, u8 /*DemuxMask*/, const unsigned char * /*CAPMT*/, u32 /*CAPMTLen*/, const unsigned char * /*RawPMT*/, u32 /*RawPMTLen*/, enum CA_SLOT_TYPE SlotType = CA_SLOT_TYPE_ALL,
unsigned char scrambled = 0, ca_map_t camap = std::set<int>(), int mode = 0, bool enabled = false);
/// sh4 unused
bool SendDateTime(void);
/// the main loop
void slot_pollthread(void *c);
/// check if current channel uses any ci module
bool checkChannelID(u64 chanID);
/// set checking for live-tv use ci to true
void setCheckLiveSlot(int check);
/// as the name says
bool CheckCerts(void);
/// Virtual destructor
virtual ~cCA();
};
#endif ///__CA_H_

1
common/hardware_caps.h Symbolic link
View File

@@ -0,0 +1 @@
../include/hardware_caps.h

View File

@@ -21,16 +21,10 @@
#define HAL_DEBUG_RECORD 7
#define HAL_DEBUG_ALL ((1<<8)-1)
#ifdef __cplusplus
extern "C" {
#endif
extern int debuglevel;
void hal_set_threadname(const char *name);
void _lt_debug(int facility, const void *, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
void _lt_info(int facility, const void *, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
void lt_debug_init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,51 +0,0 @@
/*
* (C) 2018 Thilo Graf
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libstb-hal-config.h>
#include <version_hal.h>
void hal_get_lib_version(hal_libversion_t *ver)
{
if (!ver)
return;
//init struct
*ver = {"",0,0,0,"","",""};
#ifdef VERSION
ver->vVersion = VERSION;
#endif
#ifdef PACKAGE_VERSION_MAJOR
ver->vMajor = PACKAGE_VERSION_MAJOR;
#endif
#ifdef PACKAGE_VERSION_MAJOR
ver->vMinor = PACKAGE_VERSION_MINOR;
#endif
#ifdef PACKAGE_VERSION_MINOR
ver->vPatch = PACKAGE_VERSION_MICRO;
#endif
#ifdef PACKAGE_NAME
ver->vName = PACKAGE_NAME;
#endif
#ifdef PACKAGE_STRING
ver->vStr = PACKAGE_STRING;
#endif
#ifdef PACKAGE_VERSION_GIT
ver->vGitDescribe = PACKAGE_VERSION_GIT;
#endif
}

View File

@@ -1,28 +1,9 @@
# explicit defines for separate revision handling
define(ver_major, 0)
define(ver_minor, 2)
define(ver_micro, 1)
# sync with current git
define(ver_git, m4_esyscmd([
GITBRANCH=$(git rev-parse --abbrev-ref HEAD);
GITDESCRIBE=$(git describe --always --tags --dirty);
printf "$GITDESCRIBE $GITBRANCH"
]))
AC_PACKAGE_NAME, PACKAGE_NAME_LIBSTB_HAL
AC_INIT([Tuxbox-libstb-hal], [ver_major.ver_minor.ver_micro])
AC_INIT([libstb-hal], [1.0.2])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([libstb-hal-config.h:config.h.in])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
AC_CONFIG_MACRO_DIR([m4])
AC_GNU_SOURCE
AC_DEFINE(PACKAGE_VERSION_MAJOR, ver_major, [Major version number])
AC_DEFINE(PACKAGE_VERSION_MINOR, ver_minor, [Minor version number])
AC_DEFINE(PACKAGE_VERSION_MICRO, ver_micro, [Micro version number])
AC_DEFINE(PACKAGE_VERSION_GIT, "ver_git", [internal vcs version info])
TUXBOX_APPS
TUXBOX_APPS_DIRECTORY
TUXBOX_BOXTYPE
@@ -39,66 +20,61 @@ AC_DISABLE_STATIC
AC_SYS_LARGEFILE
AC_PROG_LIBTOOL
AC_ARG_ENABLE(clutter,
AS_HELP_STRING(--enable-clutter, use clutter instead of OpenGL),
,[enable_clutter=no])
AM_CONDITIONAL(USE_CLUTTER,test "$enable_clutter" = "yes")
AM_CONDITIONAL(USE_OPENGL,test "$enable_clutter" = "no")
if test "$enable_clutter" = "yes"; then
AC_DEFINE(USE_CLUTTER,1,[use clutter instead of opengl])
else
AC_DEFINE(USE_OPENGL,1,[use opengl instead of clutter])
fi
if test x"$BOXTYPE" = x"tripledragon"; then
PKG_CHECK_MODULES([DIRECTFB], [directfb])
fi
if test x$BOXTYPE = xgeneric; then
if test x"$enable_clutter" = xyes; then
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0])
fi
if test x$BOXMODEL != xraspi; then
PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1])
PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0])
# don't know which version is exactly needed here...
PKG_CHECK_MODULES([SWSCALE], [libswscale])
else
# openmaxil are the broadcom userspace libs
# my yocto (openembedded) layer has an openmaxil package built from userland git.
# Use that if available. If not, just fall back to /opt/vc/...
# can be overridden with OMX_CFLAGS= OMX_LIBS= variables...
#
PKG_CHECK_MODULES([OMX], [openmaxil], echo "OpenMAX/IL userspace package found. Good.",
[ echo "OpenMAX/IL package not found, assuming /opt/vc/..."
OMX_CFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads/ -I/opt/vc/include/interface/vmcs_host/linux"
OMX_LIBS="-L/opt/vc/lib/ -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -pthread"
])
# raspbian has no current versions and only libav instead of ffmpeg... :-(
PKG_CHECK_MODULES([AVFORMAT], [libavformat])
PKG_CHECK_MODULES([AVCODEC], [libavcodec])
fi
PKG_CHECK_MODULES([SWRESAMPLE], [libswresample])
# don't know which version is exactly needed here...
PKG_CHECK_MODULES([AVUTIL], [libavutil])
AC_ARG_ENABLE(gstreamer_01,
AS_HELP_STRING(--enable-gstreamer_01, use gstreamer 0.10 playback),
,[enable_gstreamer_01=no])
AM_CONDITIONAL(ENABLE_GSTREAMER_01,test "$enable_gstreamer_01" = "yes")
if test "$enable_gstreamer_01" = "yes"; then
AC_DEFINE(ENABLE_GSTREAMER_01, 1, [use gstreamer 0.10 playback])
PKG_CHECK_MODULES([GSTREAMER], [gstreamer-0.10])
PKG_CHECK_MODULES([GSTREAMER_INTERFACES], [gstinterfaces-0.10])
fi
if test x$BOXTYPE = xspark; then
# versions are probably not correct :-(
AC_ARG_ENABLE(gstreamer_10,
AS_HELP_STRING(--enable-gstreamer_10, use gstreamer 1.0 playback),
,[enable_gstreamer_10=no])
AM_CONDITIONAL(ENABLE_GSTREAMER_10, test "$enable_gstreamer_10" = "yes")
if test "$enable_gstreamer_10" = "yes"; then
AC_DEFINE(ENABLE_GSTREAMER_10, 1, [use gstreamer 1.0 playback])
PKG_CHECK_MODULES([GSTREAMER], [gstreamer-1.0])
PKG_CHECK_MODULES([GSTREAMER_AUDIO], [gstreamer-audio-1.0])
PKG_CHECK_MODULES([GSTREAMER_VIDEO], [gstreamer-video-1.0])
fi
if test x$BOXTYPE = xarmbox -a "$enable_gstreamer_10" = "yes"; then
PKG_CHECK_MODULES([GSTREAMER], [gstreamer-1.0])
PKG_CHECK_MODULES([GSTREAMER_AUDIO], [gstreamer-audio-1.0])
PKG_CHECK_MODULES([GSTREAMER_VIDEO], [gstreamer-video-1.0])
fi
if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then
PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1])
PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0])
PKG_CHECK_MODULES([SWRESAMPLE], [libswresample])
# don't know which version is exactly needed here...
PKG_CHECK_MODULES([AVUTIL], [libavutil])
PKG_CHECK_MODULES([SWSCALE], [libswscale])
PKG_CHECK_MODULES([SWRESAMPLE], [libswresample])
fi
AC_OUTPUT([
Makefile
common/Makefile
libeplayer3/Makefile
libeplayer3-arm/Makefile
libthread/Makefile
azbox/Makefile
generic-pc/Makefile
libduckbox/Makefile
libdvbci/Makefile
libtriple/Makefile
libspark/Makefile
libarmbox/Makefile
raspi/Makefile
tools/Makefile
])

View File

@@ -1,41 +1,47 @@
noinst_LTLIBRARIES = libgeneric.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
AM_CPPFLAGS += -Wfatal-errors
AM_CPPFLAGS += \
-I$(top_srcdir)/common \
-I$(top_srcdir)/include \
@AVUTIL_CFLAGS@ \
@CLUTTER_CFLAGS@
-I$(top_srcdir)/common
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \
-lao \
-lOpenThreads \
-lglut -lGL -lGLU -lGLEW -lao \
@AVFORMAT_LIBS@ \
@AVUTIL_LIBS@ \
@AVCODEC_LIBS@ \
@SWRESAMPLE_LIBS@ \
@SWSCALE_LIBS@ \
@CLUTTER_LIBS@
if USE_OPENGL
AM_LDFLAGS += -lglut -lGL -lGLU -lGLEW -lao
endif
@SWSCALE_LIBS@
libgeneric_la_SOURCES = \
hardware_caps.c \
dmx.cpp \
video.cpp \
audio.cpp \
glfb.cpp \
init.cpp \
playback.cpp \
pwrmngr.cpp \
record.cpp
if USE_CLUTTER
libgeneric_la_SOURCES += clutterfb.cpp
if ENABLE_GSTREAMER_01
libgeneric_la_SOURCES += \
playback_gst_01.cpp
AM_LDFLAGS += \
-lgstreamer-0.10 \
-lgstinterfaces-0.10
else
if ENABLE_GSTREAMER_10
libgeneric_la_SOURCES += \
playback_gst_10.cpp
AM_LDFLAGS += \
-lgstreamer-1.0 \
-lgsttag-1.0 \
-lgstmpegts-1.0
else
libgeneric_la_SOURCES += \
playback.cpp
endif
if USE_OPENGL
libgeneric_la_SOURCES += glfb.cpp
endif

View File

@@ -22,51 +22,54 @@
#include <cstdio>
#include <cstdlib>
#include "audio_hal.h"
#include "audio_priv.h"
#include "dmx_hal.h"
#include "audio_lib.h"
#include "dmx_lib.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_AUDIO, this, args)
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
#include <ao/ao.h>
}
/* ffmpeg buf 2k */
#define INBUF_SIZE 0x0800
/* my own buf 16k */
#define DMX_BUF_SZ 0x4000
cAudio * audioDecoder = NULL;
ADec *adec = NULL;
extern cDemux *audioDemux;
static uint8_t *dmxbuf = NULL;
static int bufpos;
extern bool HAL_nodec;
static cAudio *gThiz = NULL;
static ao_device *adevice = NULL;
static ao_sample_format sformat;
static AVCodecContext *c= NULL;
cAudio::cAudio(void *, void *, void *)
{
adec = new ADec();
}
cAudio::~cAudio(void)
{
delete adec;
}
ADec::ADec(void)
{
adevice = NULL;
dmxbuf = NULL;
bufpos = 0;
c = NULL;
thread_started = false;
if (!HAL_nodec)
dmxbuf = (uint8_t *)malloc(DMX_BUF_SZ);
bufpos = 0;
curr_pts = 0;
gThiz = this;
ao_initialize();
}
ADec::~ADec(void)
cAudio::~cAudio(void)
{
closeDevice();
free(dmxbuf);
if (adevice)
ao_close(adevice);
@@ -74,19 +77,19 @@ ADec::~ADec(void)
ao_shutdown();
}
int cAudio::mute(void)
void cAudio::openDevice(void)
{
return SetMute(true);
lt_debug("%s\n", __func__);
}
int cAudio::unmute(void)
void cAudio::closeDevice(void)
{
return SetMute(false);
lt_debug("%s\n", __func__);
}
int cAudio::SetMute(bool enable)
int cAudio::do_mute(bool enable, bool remember)
{
lt_debug("%s(%d)\n", __func__, enable);
lt_debug("%s(%d, %d)\n", __func__, enable, remember);
return 0;
}
@@ -97,31 +100,21 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
}
int cAudio::Start(void)
{
return adec->Start();
}
int cAudio::Stop(void)
{
return adec->Stop();
}
int ADec::Start(void)
{
lt_debug("%s >\n", __func__);
if (! HAL_nodec)
start();
Thread::startThread();
lt_debug("%s <\n", __func__);
return 0;
}
int ADec::Stop(void)
int cAudio::Stop(void)
{
lt_debug("%s >\n", __func__);
if (thread_started)
{
thread_started = false;
join();
Thread::joinThread();
}
lt_debug("%s <\n", __func__);
return 0;
@@ -148,11 +141,6 @@ int cAudio::setChannel(int /*channel*/)
};
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int le)
{
return adec->PrepareClipPlay(ch, srate, bits, le);
}
int ADec::PrepareClipPlay(int ch, int srate, int bits, int le)
{
lt_debug("%s ch %d srate %d bits %d le %d adevice %p\n", __func__, ch, srate, bits, le, adevice);;
int driver;
@@ -179,11 +167,6 @@ int ADec::PrepareClipPlay(int ch, int srate, int bits, int le)
};
int cAudio::WriteClip(unsigned char *buffer, int size)
{
return adec->WriteClip(buffer, size);
}
int ADec::WriteClip(unsigned char *buffer, int size)
{
lt_debug("cAudio::%s buf 0x%p size %d\n", __func__, buffer, size);
if (!adevice) {
@@ -211,45 +194,14 @@ int cAudio::StopClip()
};
void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &mode)
{
adec->getAudioInfo(type, layer, freq, bitrate, mode);
}
void ADec::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &mode)
{
type = 0;
layer = 0; /* not used */
freq = 0;
bitrate = 0; /* not used, but easy to get :-) */
mode = 0; /* default: stereo */
printf("cAudio::getAudioInfo c %p\n", c);
if (c) {
switch (c->codec_id) {
case AV_CODEC_ID_MP2:
type = AUDIO_FMT_MPEG;
break;
case AV_CODEC_ID_MP3:
type = AUDIO_FMT_MP3;
break;
case AV_CODEC_ID_AC3:
case AV_CODEC_ID_TRUEHD:
type = AUDIO_FMT_DOLBY_DIGITAL;
break;
case AV_CODEC_ID_EAC3:
type = AUDIO_FMT_DD_PLUS;
break;
case AV_CODEC_ID_AAC:
type = AUDIO_FMT_AAC;
break;
case AV_CODEC_ID_DTS:
type = AUDIO_FMT_DTS;
break;
case AV_CODEC_ID_MLP:
type = AUDIO_FMT_MLP;
break;
default:
break;
}
type = (c->codec_id != AV_CODEC_ID_MP2); /* only mpeg / not mpeg is indicated */
freq = c->sample_rate;
bitrate = c->bit_rate;
if (c->channels == 1)
@@ -287,7 +239,7 @@ void ADec::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &mod
}
}
lt_debug("%s t: %d l: %d f: %d b: %d m: %d codec_id: %x\n",
__func__, type, layer, freq, bitrate, mode, c?c->codec_id:-1);
__func__, type, layer, freq, bitrate, mode, c ? c->codec_id : 0);
};
void cAudio::SetSRS(int /*iq_enable*/, int /*nmgr_enable*/, int /*iq_mode*/, int /*iq_level*/)
@@ -315,12 +267,17 @@ void cAudio::EnableAnalogOut(bool enable)
lt_debug("%s %d\n", __func__, enable);
};
static int _my_read(void *, uint8_t *buf, int buf_size)
void cAudio::setBypassMode(bool disable)
{
return adec->my_read(buf, buf_size);
lt_debug("%s %d\n", __func__, disable);
}
int ADec::my_read(uint8_t *buf, int buf_size)
static int _my_read(void *, uint8_t *buf, int buf_size)
{
return gThiz->my_read(buf, buf_size);
}
int cAudio::my_read(uint8_t *buf, int buf_size)
{
int tmp = 0;
if (audioDecoder && bufpos < DMX_BUF_SZ - 4096) {
@@ -347,7 +304,7 @@ int ADec::my_read(uint8_t *buf, int buf_size)
return tmp;
}
void ADec::run()
void cAudio::run()
{
lt_info("====================== start decoder thread ================================\n");
/* libavcodec & friends */
@@ -399,31 +356,28 @@ void ADec::run()
lt_info("%s: nb_streams: %d, should be 1!\n", __func__, avfc->nb_streams);
goto out;
}
p = avfc->streams[0]->codecpar;
if (p->codec_type != AVMEDIA_TYPE_AUDIO)
lt_info("%s: stream 0 no audio codec? 0x%x\n", __func__, p->codec_type);
if (avfc->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
lt_info("%s: stream 0 no audio codec? 0x%x\n", __func__, avfc->streams[0]->codec->codec_type);
codec = avcodec_find_decoder(p->codec_id);
c = avfc->streams[0]->codec;
codec = avcodec_find_decoder(c->codec_id);
if (!codec) {
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(p->codec_id));
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(c->codec_id));
goto out;
}
if (c)
av_free(c);
c = avcodec_alloc_context3(codec);
if (avcodec_open2(c, codec, NULL) < 0) {
lt_info("%s: avcodec_open2() failed\n", __func__);
goto out;
}
frame = av_frame_alloc();
if (!frame) {
lt_info("%s: av_frame_alloc failed\n", __func__);
lt_info("%s: avcodec_alloc_frame failed\n", __func__);
goto out2;
}
/* output sample rate, channels, layout could be set here if necessary */
o_ch = p->channels; /* 2 */
o_sr = p->sample_rate; /* 48000 */
o_layout = p->channel_layout; /* AV_CH_LAYOUT_STEREO */
o_ch = c->channels; /* 2 */
o_sr = c->sample_rate; /* 48000 */
o_layout = c->channel_layout; /* AV_CH_LAYOUT_STEREO */
if (sformat.channels != o_ch || sformat.rate != o_sr ||
sformat.byte_format != AO_FMT_NATIVE || sformat.bits != 16 || adevice == NULL)
{
@@ -438,9 +392,8 @@ void ADec::run()
adevice = ao_open_live(driver, &sformat, NULL);
ai = ao_driver_info(driver);
lt_info("%s: changed params ch %d srate %d bits %d adevice %p\n",
__func__, o_ch, o_sr, 16, adevice);
if(ai)
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
__func__, o_ch, o_sr, 16, adevice);;
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
driver, ai->name, ai->short_name, ai->author);
}
#if 0
@@ -451,10 +404,10 @@ void ADec::run()
#endif
av_get_sample_fmt_string(tmp, sizeof(tmp), c->sample_fmt);
lt_info("decoding %s, sample_fmt %d (%s) sample_rate %d channels %d\n",
avcodec_get_name(p->codec_id), c->sample_fmt, tmp, p->sample_rate, p->channels);
avcodec_get_name(c->codec_id), c->sample_fmt, tmp, c->sample_rate, c->channels);
swr = swr_alloc_set_opts(swr,
o_layout, AV_SAMPLE_FMT_S16, o_sr, /* output */
p->channel_layout, c->sample_fmt, p->sample_rate, /* input */
c->channel_layout, c->sample_fmt, c->sample_rate, /* input */
0, NULL);
if (! swr) {
lt_info("could not alloc resample context\n");
@@ -468,15 +421,15 @@ void ADec::run()
avcodec_decode_audio4(c, frame, &gotframe, &avpkt);
if (gotframe && thread_started) {
int out_linesize;
obuf_sz = av_rescale_rnd(swr_get_delay(swr, p->sample_rate) +
frame->nb_samples, o_sr, p->sample_rate, AV_ROUND_UP);
obuf_sz = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) +
frame->nb_samples, o_sr, c->sample_rate, AV_ROUND_UP);
if (obuf_sz > obuf_sz_max) {
lt_info("obuf_sz: %d old: %d\n", obuf_sz, obuf_sz_max);
av_free(obuf);
if (av_samples_alloc(&obuf, &out_linesize, o_ch,
frame->nb_samples, AV_SAMPLE_FMT_S16, 1) < 0) {
lt_info("av_samples_alloc failed\n");
av_packet_unref(&avpkt);
av_free_packet(&avpkt);
break; /* while (thread_started) */
}
obuf_sz_max = obuf_sz;
@@ -489,7 +442,7 @@ void ADec::run()
obuf_sz, AV_SAMPLE_FMT_S16, 1);
ao_play(adevice, (char *)obuf, o_buf_sz);
}
av_packet_unref(&avpkt);
av_free_packet(&avpkt);
}
// ao_close(adevice); /* can take long :-( */
av_free(obuf);
@@ -498,7 +451,6 @@ void ADec::run()
av_frame_free(&frame);
out2:
avcodec_close(c);
av_free(c);
c = NULL;
out:
avformat_close_input(&avfc);

105
generic-pc/audio_lib.h Normal file
View File

@@ -0,0 +1,105 @@
/* public header file */
#ifndef _AUDIO_LIB_H_
#define _AUDIO_LIB_H_
#include <stdint.h>
#include <thread_abstraction.h>
#include "../common/cs_types.h"
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio : public Thread
{
friend class cPlayback;
private:
int fd;
bool Muted;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode;
bool started;
bool thread_started;
int volume;
int64_t curr_pts;
void openDevice(void);
void closeDevice(void);
int do_mute(bool enable, bool remember);
void setBypassMode(bool disable);
void run();
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
int64_t getPts() { return curr_pts; }
void *GetHandle() { return NULL; };
/* shut up */
int mute(bool remember = true) { return do_mute(true, remember); };
int unmute(bool remember = true) { return do_mute(false, remember); };
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return Muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported();
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
int my_read(uint8_t *buf, int buf_size);
};
#endif

View File

@@ -1,54 +0,0 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* private stuff for the audio decoder, only used inside libstb-hal
*/
#include <OpenThreads/Thread>
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
#include <ao/ao.h>
}
class ADec : public OpenThreads::Thread
{
public:
ADec();
~ADec();
int Start();
int Stop();
int PrepareClipPlay(int ch, int srate, int bits, int le);
int WriteClip(unsigned char *buffer, int size);
void getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &mode);
int my_read(uint8_t *buf, int buf_size);
int64_t getPts() { return curr_pts; };
private:
bool thread_started;
int64_t curr_pts;
void run();
ao_device *adevice;
ao_sample_format sformat;
uint8_t *dmxbuf;
int bufpos;
AVCodecContext *c;
AVCodecParameters *p;
};

View File

@@ -1,523 +0,0 @@
/*
Framebuffer implementation using clutter https://developer.gnome.org/clutter/
Copyright (C) 2016 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
based on the openGL framebuffer implementation
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
TODO: AV-Sync code is "experimental" at best
*/
#include "config.h"
#include <vector>
#include <sys/types.h>
#include <signal.h>
#include <cstdio>
#include <cstring>
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "glfb_priv.h"
#include "video_priv.h"
#include "audio_priv.h"
#include <clutter/x11/clutter-x11.h>
#include "lt_debug.h"
#define lt_debug_c(args...) _lt_debug(HAL_DEBUG_INIT, NULL, args)
#define lt_info_c(args...) _lt_info(HAL_DEBUG_INIT, NULL, args)
#define lt_debug(args...) _lt_debug(HAL_DEBUG_INIT, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_INIT, this, args)
extern VDec *vdec;
extern ADec *adec;
/* the private class that does stuff only needed inside libstb-hal.
* is used e.g. by cVideo... */
GLFbPC *glfb_priv = NULL;
GLFramebuffer::GLFramebuffer(int x, int y)
{
Init();
glfb_priv = new GLFbPC(x, y, osd_buf);
si = glfb_priv->getScreenInfo();
start();
while (!glfb_priv->mInitDone)
usleep(1);
}
GLFramebuffer::~GLFramebuffer()
{
glfb_priv->mShutDown = true;
join();
delete glfb_priv;
glfb_priv = NULL;
}
void GLFramebuffer::blit()
{
glfb_priv->blit();
}
GLFbPC::GLFbPC(int x, int y, std::vector<unsigned char> &buf): mReInit(true), mShutDown(false), mInitDone(false)
{
osd_buf = &buf;
mState.width = x;
mState.height = y;
mX = &_mX[0];
mY = &_mY[0];
*mX = x;
*mY = y;
av_reduce(&mOA.num, &mOA.den, x, y, INT_MAX);
mVA = mOA; /* initial aspect ratios are from the FB resolution, those */
_mVA = mVA; /* will be updated by the videoDecoder functions anyway */
mVAchanged = true;
mCrop = DISPLAY_AR_MODE_PANSCAN;
zoom = 1.0;
xscale = 1.0;
const char *tmp = getenv("GLFB_FULLSCREEN");
mFullscreen = !!(tmp);
mState.blit = true;
last_apts = 0;
/* linux framebuffer compat mode */
si.bits_per_pixel = 32;
si.xres = mState.width;
si.xres_virtual = si.xres;
si.yres = mState.height;
si.yres_virtual = si.yres;
si.blue.length = 8;
si.blue.offset = 0;
si.green.length = 8;
si.green.offset = 8;
si.red.length = 8;
si.red.offset = 16;
si.transp.length = 8;
si.transp.offset = 24;
unlink("/tmp/neutrino.input");
mkfifo("/tmp/neutrino.input", 0600);
input_fd = open("/tmp/neutrino.input", O_RDWR|O_CLOEXEC|O_NONBLOCK);
if (input_fd < 0)
lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__);
initKeys();
}
GLFbPC::~GLFbPC()
{
mShutDown = true;
if (input_fd >= 0)
close(input_fd);
osd_buf->clear();
}
void GLFbPC::initKeys()
{
/*
Keep in sync with initKeys() in glfb.cpp
*/
mKeyMap[CLUTTER_KEY_Up] = KEY_UP;
mKeyMap[CLUTTER_KEY_Down] = KEY_DOWN;
mKeyMap[CLUTTER_KEY_Left] = KEY_LEFT;
mKeyMap[CLUTTER_KEY_Right] = KEY_RIGHT;
mKeyMap[CLUTTER_KEY_F1] = KEY_RED;
mKeyMap[CLUTTER_KEY_F2] = KEY_GREEN;
mKeyMap[CLUTTER_KEY_F3] = KEY_YELLOW;
mKeyMap[CLUTTER_KEY_F4] = KEY_BLUE;
mKeyMap[CLUTTER_KEY_F5] = KEY_RECORD;
mKeyMap[CLUTTER_KEY_F6] = KEY_PLAY;
mKeyMap[CLUTTER_KEY_F7] = KEY_PAUSE;
mKeyMap[CLUTTER_KEY_F8] = KEY_STOP;
mKeyMap[CLUTTER_KEY_F9] = KEY_FORWARD;
mKeyMap[CLUTTER_KEY_F10] = KEY_REWIND;
mKeyMap[CLUTTER_KEY_F11] = KEY_NEXT;
mKeyMap[CLUTTER_KEY_F12] = KEY_PREVIOUS;
mKeyMap[CLUTTER_KEY_Page_Up] = KEY_PAGEUP;
mKeyMap[CLUTTER_KEY_Page_Down] = KEY_PAGEDOWN;
mKeyMap[CLUTTER_KEY_Return] = KEY_OK;
mKeyMap[CLUTTER_KEY_Escape] = KEY_EXIT;
mKeyMap['0'] = KEY_0;
mKeyMap['1'] = KEY_1;
mKeyMap['2'] = KEY_2;
mKeyMap['3'] = KEY_3;
mKeyMap['4'] = KEY_4;
mKeyMap['5'] = KEY_5;
mKeyMap['6'] = KEY_6;
mKeyMap['7'] = KEY_7;
mKeyMap['8'] = KEY_8;
mKeyMap['9'] = KEY_9;
mKeyMap['+'] = KEY_VOLUMEUP;
mKeyMap['-'] = KEY_VOLUMEDOWN;
mKeyMap['.'] = KEY_MUTE;
mKeyMap['a'] = KEY_AUDIO;
mKeyMap['e'] = KEY_EPG;
// ['f'] is reserved to toggle fullscreen;
mKeyMap['g'] = KEY_GAMES;
mKeyMap['h'] = KEY_HELP;
mKeyMap['i'] = KEY_INFO;
mKeyMap['m'] = KEY_MENU;
mKeyMap['p'] = KEY_POWER;
mKeyMap['r'] = KEY_RADIO;
mKeyMap['s'] = KEY_SUBTITLE;
mKeyMap['t'] = KEY_TV;
mKeyMap['v'] = KEY_VIDEO;
mKeyMap['z'] = KEY_SLEEP;
/* shift keys */
mKeyMap['F'] = KEY_FAVORITES;
mKeyMap['M'] = KEY_MODE;
mKeyMap['S'] = KEY_SAT;
mKeyMap['T'] = KEY_TEXT;
mKeyMap['W'] = KEY_WWW;
}
static ClutterActor *stage = NULL;
static ClutterActor *fb_actor = NULL;
static ClutterActor *vid_actor = NULL;
static ClutterTimeline *tl = NULL;
void GLFramebuffer::run()
{
int argc = 1;
int x = glfb_priv->mState.width;
int y = glfb_priv->mState.height;
/* some dummy commandline for GLUT to be happy */
char *a = (char *)"neutrino";
char **argv = (char **)malloc(sizeof(char *) * 2);
argv[0] = a;
argv[1] = NULL;
lt_info("GLFB: GL thread starting x %d y %d\n", x, y);
if (clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS) {
lt_info("GLFB: error initializing clutter\n");
return;
}
lt_info("GLFB: %s:%d\n", __func__, __LINE__);
ClutterColor stage_color = { 0, 0, 0, 255 };
stage = clutter_stage_new();
clutter_actor_set_size(stage, x, y);
clutter_actor_set_background_color(stage, &stage_color);
clutter_actor_set_content_gravity(stage, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
//g_signal_connect(stage, "destroy", G_CALLBACK(clutter_main_quit), NULL);
g_signal_connect(stage, "key-press-event", G_CALLBACK(GLFbPC::keyboardcb), (void *)1);
g_signal_connect(stage, "key-release-event", G_CALLBACK(GLFbPC::keyboardcb), NULL);
clutter_stage_set_user_resizable(CLUTTER_STAGE (stage), TRUE);
clutter_actor_grab_key_focus(stage);
clutter_actor_show(stage);
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = x * y * 4 * 2;
osd_buf.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf.data());
/* video plane is below FB plane, so it comes first */
vid_actor = clutter_actor_new();
ClutterContent *fb = clutter_image_new();
/* osd_buf, because it starts up black */
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf.data(), COGL_PIXEL_FORMAT_BGR_888, x, y, x*3, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed? (vid)\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(vid_actor, fb);
g_object_unref(fb);
clutter_actor_set_size(vid_actor, x, y);
clutter_actor_set_position(vid_actor, 0, 0);
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0));
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0));
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_X, 0));
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_Y, 0));
clutter_actor_set_content_gravity(vid_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
clutter_actor_set_pivot_point(vid_actor, 0.5, 0.5);
clutter_actor_add_child(stage, vid_actor);
clutter_actor_show(vid_actor);
fb_actor = clutter_actor_new();
fb = clutter_image_new();
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf.data(), COGL_PIXEL_FORMAT_BGRA_8888, x, y, x*4, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed? (osd)\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(fb_actor, fb);
g_object_unref(fb);
clutter_actor_set_size(fb_actor, x, y);
clutter_actor_set_position(fb_actor, 0, 0);
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0));
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0));
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_X, 0));
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_Y, 0));
clutter_actor_set_content_gravity(fb_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
clutter_actor_add_child(stage, fb_actor);
clutter_actor_show(fb_actor);
glfb_priv->mInitDone = true; /* signal that setup is finished */
tl = clutter_timeline_new(100);
g_signal_connect(tl, "new-frame", G_CALLBACK(GLFbPC::rendercb), NULL);
clutter_timeline_set_repeat_count(tl, -1);
clutter_timeline_start(tl);
clutter_main();
g_object_unref(tl);
free(argv);
lt_info("GLFB: GL thread stopping\n");
}
/* static */ void GLFbPC::rendercb()
{
glfb_priv->render();
}
/* static */ bool GLFbPC::keyboardcb(ClutterActor * /*actor*/, ClutterEvent *event, gpointer user_data)
{
guint key = clutter_event_get_key_symbol (event);
int keystate = user_data ? 1 : 0;
lt_debug_c("GLFB::%s: 0x%x, %d\n", __func__, key, keystate);
struct input_event ev;
if (key == 'f' && keystate)
{
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on");
glfb_priv->mFullscreen = !(glfb_priv->mFullscreen);
glfb_priv->mReInit = true;
return true;
}
std::map<int, int>::const_iterator i = glfb_priv->mKeyMap.find(key);
if (i == glfb_priv->mKeyMap.end())
return true;
ev.code = i->second;
ev.value = keystate; /* key own */
ev.type = EV_KEY;
gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code);
write(glfb_priv->input_fd, &ev, sizeof(ev));
return true;
}
int sleep_us = 30000;
void GLFbPC::render()
{
if(mShutDown)
clutter_main_quit();
mReInitLock.lock();
if (vdec && vdec->pig_changed)
{
mReInit = true;
vdec->pig_changed = false;
}
if (mReInit)
{
int xoff = 0;
int yoff = 0;
mVAchanged = true;
mReInit = false;
#if 0
mX = &_mX[mFullscreen];
mY = &_mY[mFullscreen];
#endif
*mX = *mY * mOA.num / mOA.den;
if (mFullscreen) {
clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), TRUE);
clutter_actor_show(stage);
clutter_stage_ensure_redraw(CLUTTER_STAGE(stage));
} else {
clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), FALSE);
// *mX = *mY * mOA.num / mOA.den;
clutter_actor_set_size(stage, *mX, *mY);
}
lt_info("%s: reinit mX:%d mY:%d xoff:%d yoff:%d fs %d\n",
__func__, *mX, *mY, xoff, yoff, mFullscreen);
}
mReInitLock.unlock();
bltDisplayBuffer(); /* decoded video stream */
if (mState.blit) {
/* only blit manually after fb->blit(), this helps to find missed blit() calls */
mState.blit = false;
lt_debug("GLFB::%s blit!\n", __func__);
bltOSDBuffer(); /* OSD */
}
if (mVAchanged)
{
mVAchanged = false;
zoom = 1.0;
float xzoom = 1.0;
//xscale = 1.0;
int cmp = av_cmp_q(mVA, mOA);
const AVRational a149 = { 14, 9 };
switch (cmp) {
default:
case INT_MIN: /* invalid */
case 0: /* identical */
lt_debug("%s: mVA == mOA (or fullscreen mode :-)\n", __func__);
break;
case 1: /* mVA > mOA -- video is wider than display */
lt_debug("%s: mVA > mOA\n", __func__);
switch (mCrop) {
case DISPLAY_AR_MODE_PANSCAN:
zoom = av_q2d(mVA) / av_q2d(mOA);
break;
case DISPLAY_AR_MODE_LETTERBOX:
break;
case DISPLAY_AR_MODE_PANSCAN2:
zoom = av_q2d(a149) / av_q2d(mOA);
break;
case DISPLAY_AR_MODE_NONE:
xzoom = av_q2d(mOA) / av_q2d(mVA);
zoom = av_q2d(mVA) / av_q2d(mOA);
break;
default:
break;
}
break;
case -1: /* mVA < mOA -- video is taller than display */
lt_debug("%s: mVA < mOA\n", __func__);
switch (mCrop) {
case DISPLAY_AR_MODE_LETTERBOX:
break;
case DISPLAY_AR_MODE_PANSCAN2:
if (av_cmp_q(a149, mOA) < 0) {
zoom = av_q2d(mVA) * av_q2d(a149) / av_q2d(mOA);
break;
}
/* fallthrough for output format 14:9 */
case DISPLAY_AR_MODE_PANSCAN:
zoom = av_q2d(mOA) / av_q2d(mVA);
break;
case DISPLAY_AR_MODE_NONE:
xzoom = av_q2d(mOA) / av_q2d(mVA);
break;
default:
break;
}
break;
}
if (vdec &&
vdec->pig_x >= 0 && vdec->pig_y >= 0 &&
vdec->pig_w > 0 && vdec->pig_h > 0) {
int ox = mState.width - vdec->pig_w;
int oy = mState.height - vdec->pig_h;
float ppx = vdec->pig_x / (float) ox;
float ppy = vdec->pig_y / (float) oy;
zoom = zoom * (float)vdec->pig_w / mState.width;
clutter_actor_set_pivot_point(vid_actor, ppx, ppy);
} else {
clutter_actor_set_pivot_point(vid_actor, 0.5, 0.5);
}
lt_debug("zoom: %f xscale: %f xzoom: %f\n", zoom, xscale,xzoom);
clutter_actor_set_scale(vid_actor, xscale*zoom*xzoom, zoom);
}
clutter_timeline_stop(tl);
clutter_timeline_set_delay(tl, sleep_us/1000);
clutter_timeline_start(tl);
}
void GLFbPC::bltOSDBuffer()
{
// lt_info("%s\n", __func__);
int x = glfb_priv->mState.width;
int y = glfb_priv->mState.height;
ClutterContent *fb = clutter_image_new();
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf->data(), COGL_PIXEL_FORMAT_BGRA_8888, x, y, x*4, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed?\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(fb_actor, fb);
g_object_unref(fb);
clutter_actor_show(fb_actor);
}
void GLFbPC::bltDisplayBuffer()
{
// lt_info("GLFB::%s vdec: %p\n", __func__, vdec);
if (!vdec) /* cannot start yet */
return;
static bool warn = true;
VDec::SWFramebuffer *buf = vdec->getDecBuf();
if (!buf) {
if (warn)
lt_info("GLFB::%s did not get a buffer...\n", __func__);
warn = false;
return;
}
warn = true;
int w = buf->width(), h = buf->height();
if (w == 0 || h == 0)
return;
AVRational a = buf->AR();
if (a.den != 0 && a.num != 0 && av_cmp_q(a, _mVA)) {
_mVA = a;
/* _mVA is the raw buffer's aspect, mVA is the real scaled output aspect */
av_reduce(&mVA.num, &mVA.den, w * a.num, h * a.den, INT_MAX);
// mVA.num: 16 mVA.den: 9 w: 720 h: 576
// 16*576/720/9 = 1.42222
xscale = (double)mVA.num*h/(double)mVA.den/w;
mVAchanged = true;
}
ClutterContent *fb = clutter_image_new();
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), &(*buf)[0], COGL_PIXEL_FORMAT_BGR_888, w, h, w*3, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed?\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(vid_actor, fb);
g_object_unref(fb);
clutter_actor_show(vid_actor);
/* "rate control" mechanism starts here...
* this implementation is pretty naive and not working too well, but
* better this than nothing... :-) */
int64_t apts = 0;
int64_t vpts = buf->pts();
if (adec)
apts = adec->getPts();
if (apts != last_apts) {
int rate, dummy1, dummy2;
if (apts < vpts)
sleep_us = (sleep_us * 2 + (vpts - apts)*10/9) / 3;
else if (sleep_us > 1000)
sleep_us -= 1000;
last_apts = apts;
vdec->getPictureInfo(dummy1, dummy2, rate);
if (rate > 0)
rate = 2000000 / rate; /* limit to half the frame rate */
else
rate = 50000; /* minimum 20 fps */
if (sleep_us > rate)
sleep_us = rate;
else if (sleep_us < 1)
sleep_us = 1;
}
lt_debug("vpts: 0x%" PRIx64 " apts: 0x%" PRIx64 " diff: %6.3f sleep_us %d buf %d\n",
buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, vdec->buf_num);
}

1
generic-pc/cs_api.h Symbolic link
View File

@@ -0,0 +1 @@
../libspark/cs_api.h

View File

@@ -32,21 +32,26 @@
#include <cstdio>
#include <string>
#include <unistd.h>
#include <sys/ioctl.h>
#include "dmx_hal.h"
#include "dmx_lib.h"
#include "lt_debug.h"
/* needed for getSTC :-( */
#include "video_priv.h"
extern VDec *vdec;
#include "video_lib.h"
extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \
} while(0);
cDemux *videoDemux = NULL;
@@ -65,12 +70,15 @@ static const char *DMX_T[] = {
};
/* map the device numbers. for now only demux0 is used */
static const char *devname[] = {
#define NUM_DEMUXDEV 1
static const char *devname[NUM_DEMUXDEV] = {
"/dev/dvb/adapter0/demux0",
"/dev/dvb/adapter0/demux0",
"/dev/dvb/adapter0/demux0"
};
#define NUM_DEMUX 1
static int dmx_source[NUM_DEMUX] = { 0 };
static bool init[NUM_DEMUXDEV] = { false };
/* uuuugly */
static int dmx_tp_count = 0;
#define MAX_TS_COUNT 8
@@ -87,6 +95,9 @@ cDemux::cDemux(int n)
else
num = n;
fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
}
cDemux::~cDemux()
@@ -152,6 +163,8 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP);
close(fd);
fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL)
{
dmx_tp_count--;
@@ -243,13 +256,11 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc;
}
bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask)
{
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
if (len > DMX_FILTER_SIZE)
{
@@ -258,7 +269,6 @@ bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filt
}
s_flt.pid = pid;
s_flt.timeout = timeout;
flt = filter[0];
memcpy(s_flt.filter.filter, filter, len);
memcpy(s_flt.filter.mask, mask, len);
if (negmask != NULL)
@@ -359,11 +369,8 @@ bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filt
return true;
}
bool cDemux::pesFilter(const unsigned short _pid)
bool cDemux::pesFilter(const unsigned short pid)
{
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure
* what it is good for...
@@ -474,8 +481,8 @@ void cDemux::removePid(unsigned short Pid)
void cDemux::getSTC(int64_t * STC)
{
int64_t pts = 0;
if (vdec)
pts = vdec->GetPTS();
if (videoDecoder)
pts = videoDecoder->GetPTS();
*STC = pts;
}
@@ -490,12 +497,28 @@ int cDemux::getUnit(void)
bool cDemux::SetSource(int unit, int source)
{
lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source);
//lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source);
//return true;
if (unit >= NUM_DEMUX || unit < 0) {
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return false;
}
lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source);
if (source < 0 || source >= NUM_DEMUXDEV)
lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source);
else
dmx_source[unit] = source;
return true;
}
int cDemux::GetSource(int unit)
{
lt_info_c("%s(%d): not implemented yet\n", __func__, unit);
return 0;
//lt_info_c("%s(%d): not implemented yet\n", __func__, unit);
//return 0;
if (unit >= NUM_DEMUX || unit < 0) {
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return -1;
}
lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]);
return dmx_source[unit];
}

1
generic-pc/dmx_cs.h Normal file
View File

@@ -0,0 +1 @@
#include "dmx_lib.h"

70
generic-pc/dmx_lib.h Normal file
View File

@@ -0,0 +1,70 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -22,7 +22,6 @@
TODO: AV-Sync code is "experimental" at best
*/
#include "config.h"
#include <vector>
#include <sys/types.h>
@@ -38,9 +37,10 @@
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "glfb_priv.h"
#include "video_priv.h"
#include "audio_priv.h"
#include "glfb.h"
#include <GL/glx.h>
#include "video_lib.h"
#include "audio_lib.h"
#include "lt_debug.h"
@@ -50,39 +50,13 @@
#define lt_info(args...) _lt_info(HAL_DEBUG_INIT, this, args)
extern VDec *vdec;
extern ADec *adec;
extern cVideo *videoDecoder;
extern cAudio *audioDecoder;
/* the private class that does stuff only needed inside libstb-hal.
* is used e.g. by cVideo... */
GLFbPC *glfb_priv = NULL;
static GLFramebuffer *gThiz = 0; /* GLUT does not allow for an arbitrary argument to the render func */
GLFramebuffer::GLFramebuffer(int x, int y)
GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mInitDone(false)
{
Init();
glfb_priv = new GLFbPC(x, y, osd_buf);
si = glfb_priv->getScreenInfo();
start();
while (!glfb_priv->mInitDone)
usleep(1);
}
GLFramebuffer::~GLFramebuffer()
{
glfb_priv->mShutDown = true;
join();
delete glfb_priv;
glfb_priv = NULL;
}
void GLFramebuffer::blit()
{
glfb_priv->blit();
}
GLFbPC::GLFbPC(int x, int y, std::vector<unsigned char> &buf): mReInit(true), mShutDown(false), mInitDone(false)
{
osd_buf = &buf;
mState.width = x;
mState.height = y;
mX = &_mX[0];
@@ -103,19 +77,19 @@ GLFbPC::GLFbPC(int x, int y, std::vector<unsigned char> &buf): mReInit(true), mS
last_apts = 0;
/* linux framebuffer compat mode */
si.bits_per_pixel = 32;
si.xres = mState.width;
si.xres_virtual = si.xres;
si.yres = mState.height;
si.yres_virtual = si.yres;
si.blue.length = 8;
si.blue.offset = 0;
si.green.length = 8;
si.green.offset = 8;
si.red.length = 8;
si.red.offset = 16;
si.transp.length = 8;
si.transp.offset = 24;
screeninfo.bits_per_pixel = 32;
screeninfo.xres = mState.width;
screeninfo.xres_virtual = screeninfo.xres;
screeninfo.yres = mState.height;
screeninfo.yres_virtual = screeninfo.yres;
screeninfo.blue.length = 8;
screeninfo.blue.offset = 0;
screeninfo.green.length = 8;
screeninfo.green.offset = 8;
screeninfo.red.length = 8;
screeninfo.red.offset = 16;
screeninfo.transp.length = 8;
screeninfo.transp.offset = 24;
unlink("/tmp/neutrino.input");
mkfifo("/tmp/neutrino.input", 0600);
@@ -123,22 +97,21 @@ GLFbPC::GLFbPC(int x, int y, std::vector<unsigned char> &buf): mReInit(true), mS
if (input_fd < 0)
lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__);
initKeys();
Thread::startThread();
while (!mInitDone)
usleep(1);
}
GLFbPC::~GLFbPC()
GLFramebuffer::~GLFramebuffer()
{
mShutDown = true;
Thread::joinThread();
if (input_fd >= 0)
close(input_fd);
osd_buf->clear();
}
void GLFbPC::initKeys()
void GLFramebuffer::initKeys()
{
/*
Keep in sync with initKeys() in clutterfb.cpp
*/
mSpecialMap[GLUT_KEY_UP] = KEY_UP;
mSpecialMap[GLUT_KEY_DOWN] = KEY_DOWN;
mSpecialMap[GLUT_KEY_LEFT] = KEY_LEFT;
@@ -159,8 +132,8 @@ void GLFbPC::initKeys()
mSpecialMap[GLUT_KEY_F11] = KEY_NEXT;
mSpecialMap[GLUT_KEY_F12] = KEY_PREVIOUS;
mSpecialMap[GLUT_KEY_PAGE_UP] = KEY_PAGEUP;
mSpecialMap[GLUT_KEY_PAGE_DOWN] = KEY_PAGEDOWN;
mSpecialMap[GLUT_KEY_PAGE_UP] = KEY_PAGEUP;
mSpecialMap[GLUT_KEY_PAGE_DOWN] = KEY_PAGEDOWN;
mKeyMap[0x0d] = KEY_OK;
mKeyMap[0x1b] = KEY_EXIT;
@@ -203,21 +176,9 @@ void GLFbPC::initKeys()
void GLFramebuffer::run()
{
int argc = 1;
int x = glfb_priv->mState.width;
int y = glfb_priv->mState.height;
/* some dummy commandline for GLUT to be happy */
char const *argv[2] = { "neutrino", 0 };
lt_info("GLFB: GL thread starting x %d y %d\n", x, y);
glutInit(&argc, const_cast<char **>(argv));
glutInitWindowSize(x, y);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Neutrino");
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = x * y * 4 * 2;
osd_buf.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf.data());
glfb_priv->mInitDone = true; /* signal that setup is finished */
setupCtx();
setupOSDBuffer();
mInitDone = true; /* signal that setup is finished */
/* init the good stuff */
GLenum err = glewInit();
@@ -232,15 +193,16 @@ void GLFramebuffer::run()
}
else
{
gThiz = this;
glutSetCursor(GLUT_CURSOR_NONE);
glutDisplayFunc(GLFbPC::rendercb);
glutKeyboardFunc(GLFbPC::keyboardcb);
glutSpecialFunc(GLFbPC::specialcb);
glutReshapeFunc(GLFbPC::resizecb);
glfb_priv->setupGLObjects(); /* needs GLEW prototypes */
glutDisplayFunc(GLFramebuffer::rendercb);
glutKeyboardFunc(GLFramebuffer::keyboardcb);
glutSpecialFunc(GLFramebuffer::specialcb);
glutReshapeFunc(GLFramebuffer::resizecb);
setupGLObjects(); /* needs GLEW prototypes */
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop();
glfb_priv->releaseGLObjects();
releaseGLObjects();
}
}
else
@@ -248,20 +210,21 @@ void GLFramebuffer::run()
lt_info("GLFB: GL thread stopping\n");
}
#if 0
void GLFbPC::setupCtx()
void GLFramebuffer::setupCtx()
{
int argc = 1;
/* some dummy commandline for GLUT to be happy */
char const *argv[2] = { "neutrino", 0 };
lt_info("GLFB: GL thread starting x %d y %d\n", mX[0], mY[0]);
lt_info("GLFB: GL thread starting\n");
glutInit(&argc, const_cast<char **>(argv));
glutInitWindowSize(mX[0], mY[0]);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Neutrino");
GLWinID = glXGetCurrentDrawable(); // this was the holy grail to get the right window handle for gstreamer :D
}
void GLFbPC::setupOSDBuffer()
void GLFramebuffer::setupOSDBuffer()
{ /* the OSD buffer size can be decoupled from the actual
window size since the GL can blit-stretch with no
trouble at all, ah, the luxury of ignorance... */
@@ -270,13 +233,12 @@ void GLFbPC::setupOSDBuffer()
{
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = mState.width * mState.height * 4 * 2;
osd_buf->resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf->data());
mOSDBuffer.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes\n", fbmem);
}
}
#endif
void GLFbPC::setupGLObjects()
void GLFramebuffer::setupGLObjects()
{
unsigned char buf[4] = { 0, 0, 0, 0 }; /* 1 black pixel */
glGenTextures(1, &mState.osdtex);
@@ -304,7 +266,7 @@ void GLFbPC::setupGLObjects()
}
void GLFbPC::releaseGLObjects()
void GLFramebuffer::releaseGLObjects()
{
glDeleteBuffers(1, &mState.pbo);
glDeleteBuffers(1, &mState.displaypbo);
@@ -313,56 +275,56 @@ void GLFbPC::releaseGLObjects()
}
/* static */ void GLFbPC::rendercb()
/* static */ void GLFramebuffer::rendercb()
{
glfb_priv->render();
gThiz->render();
}
/* static */ void GLFbPC::keyboardcb(unsigned char key, int /*x*/, int /*y*/)
/* static */ void GLFramebuffer::keyboardcb(unsigned char key, int /*x*/, int /*y*/)
{
lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
struct input_event ev;
if (key == 'f')
{
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on");
glfb_priv->mFullscreen = !(glfb_priv->mFullscreen);
glfb_priv->mReInit = true;
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, gThiz->mFullscreen?"off":"on");
gThiz->mFullscreen = !(gThiz->mFullscreen);
gThiz->mReInit = true;
return;
}
std::map<unsigned char, int>::const_iterator i = glfb_priv->mKeyMap.find(key);
if (i == glfb_priv->mKeyMap.end())
std::map<unsigned char, int>::const_iterator i = gThiz->mKeyMap.find(key);
if (i == gThiz->mKeyMap.end())
return;
ev.code = i->second;
ev.value = 1; /* key own */
ev.type = EV_KEY;
gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code);
write(glfb_priv->input_fd, &ev, sizeof(ev));
write(gThiz->input_fd, &ev, sizeof(ev));
ev.value = 0; /* neutrino is stupid, so push key up directly after key down */
write(glfb_priv->input_fd, &ev, sizeof(ev));
write(gThiz->input_fd, &ev, sizeof(ev));
}
/* static */ void GLFbPC::specialcb(int key, int /*x*/, int /*y*/)
/* static */ void GLFramebuffer::specialcb(int key, int /*x*/, int /*y*/)
{
lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
struct input_event ev;
std::map<int, int>::const_iterator i = glfb_priv->mSpecialMap.find(key);
if (i == glfb_priv->mSpecialMap.end())
std::map<int, int>::const_iterator i = gThiz->mSpecialMap.find(key);
if (i == gThiz->mSpecialMap.end())
return;
ev.code = i->second;
ev.value = 1;
ev.type = EV_KEY;
gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code);
write(glfb_priv->input_fd, &ev, sizeof(ev));
write(gThiz->input_fd, &ev, sizeof(ev));
ev.value = 0;
write(glfb_priv->input_fd, &ev, sizeof(ev));
write(gThiz->input_fd, &ev, sizeof(ev));
}
int sleep_us = 30000;
void GLFbPC::render()
void GLFramebuffer::render()
{
if(mShutDown)
glutLeaveMainLoop();
@@ -490,12 +452,12 @@ void GLFbPC::render()
glutPostRedisplay();
}
/* static */ void GLFbPC::resizecb(int w, int h)
/* static */ void GLFramebuffer::resizecb(int w, int h)
{
glfb_priv->checkReinit(w, h);
gThiz->checkReinit(w, h);
}
void GLFbPC::checkReinit(int x, int y)
void GLFramebuffer::checkReinit(int x, int y)
{
static int last_x = 0, last_y = 0;
@@ -515,7 +477,7 @@ void GLFbPC::checkReinit(int x, int y)
last_y = y;
}
void GLFbPC::drawSquare(float size, float x_factor)
void GLFramebuffer::drawSquare(float size, float x_factor)
{
GLfloat vertices[] = {
1.0f, 1.0f,
@@ -533,17 +495,17 @@ void GLFbPC::drawSquare(float size, float x_factor)
1.0, 1.0,
};
if (x_factor > -99.0) { /* x_factor == -100 => OSD */
if (vdec &&
vdec->pig_x > 0 && vdec->pig_y > 0 &&
vdec->pig_w > 0 && vdec->pig_h > 0) {
if (videoDecoder &&
videoDecoder->pig_x > 0 && videoDecoder->pig_y > 0 &&
videoDecoder->pig_w > 0 && videoDecoder->pig_h > 0) {
/* these calculations even consider cropping and panscan mode
* maybe this could be done with some clever opengl tricks? */
double w2 = (double)mState.width * 0.5l;
double h2 = (double)mState.height * 0.5l;
double x = (double)(vdec->pig_x - w2) / w2 / x_factor / size;
double y = (double)(h2 - vdec->pig_y) / h2 / size;
double w = (double)vdec->pig_w / w2;
double h = (double)vdec->pig_h / h2;
double x = (double)(videoDecoder->pig_x - w2) / w2 / x_factor / size;
double y = (double)(h2 - videoDecoder->pig_y) / h2 / size;
double w = (double)videoDecoder->pig_w / w2;
double h = (double)videoDecoder->pig_h / h2;
x += ((1.0l - x_factor * size) / 2.0l) * w / x_factor / size;
y += ((size - 1.0l) / 2.0l) * h / size;
vertices[0] = x + w; /* top right x */
@@ -571,11 +533,11 @@ void GLFbPC::drawSquare(float size, float x_factor)
}
void GLFbPC::bltOSDBuffer()
void GLFramebuffer::bltOSDBuffer()
{
/* FIXME: copy each time */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER, osd_buf->size(), osd_buf->data(), GL_STREAM_DRAW_ARB);
glBufferData(GL_PIXEL_UNPACK_BUFFER, mOSDBuffer.size(), &mOSDBuffer[0], GL_STREAM_DRAW_ARB);
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mState.width, mState.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
@@ -583,15 +545,15 @@ void GLFbPC::bltOSDBuffer()
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
void GLFbPC::bltDisplayBuffer()
void GLFramebuffer::bltDisplayBuffer()
{
if (!vdec) /* cannot start yet */
if (!videoDecoder) /* cannot start yet */
return;
static bool warn = true;
VDec::SWFramebuffer *buf = vdec->getDecBuf();
cVideo::SWFramebuffer *buf = videoDecoder->getDecBuf();
if (!buf) {
if (warn)
lt_info("GLFB::%s did not get a buffer...\n", __func__);
lt_debug("GLFB::%s did not get a buffer...\n", __func__);
warn = false;
return;
}
@@ -620,9 +582,10 @@ void GLFbPC::bltDisplayBuffer()
* this implementation is pretty naive and not working too well, but
* better this than nothing... :-) */
int64_t apts = 0;
int64_t vpts = buf->pts();
if (adec)
apts = adec->getPts();
/* 18000 is the magic value for A/V sync in my libao->pulseaudio->intel_hda setup */
int64_t vpts = buf->pts() + 18000;
if (audioDecoder)
apts = audioDecoder->getPts();
if (apts != last_apts) {
int rate, dummy1, dummy2;
if (apts < vpts)
@@ -630,7 +593,7 @@ void GLFbPC::bltDisplayBuffer()
else if (sleep_us > 1000)
sleep_us -= 1000;
last_apts = apts;
vdec->getPictureInfo(dummy1, dummy2, rate);
videoDecoder->getPictureInfo(dummy1, dummy2, rate);
if (rate > 0)
rate = 2000000 / rate; /* limit to half the frame rate */
else
@@ -641,5 +604,11 @@ void GLFbPC::bltDisplayBuffer()
sleep_us = 1;
}
lt_debug("vpts: 0x%" PRIx64 " apts: 0x%" PRIx64 " diff: %6.3f sleep_us %d buf %d\n",
buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, vdec->buf_num);
buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, videoDecoder->buf_num);
}
void GLFramebuffer::clear()
{
/* clears front and back buffer */
memset(&mOSDBuffer[0], 0, mOSDBuffer.size());
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013,2016 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,46 +14,44 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
********************************************************************
private stuff of the GLFB thread that is only used inside libstb-hal
and not exposed to the application.
*/
#ifndef __glfb_priv__
#define __glfb_priv__
#include <OpenThreads/Mutex>
#ifndef __glthread__
#define __glthread__
#include <thread_abstraction.h>
#include <mutex_abstraction.h>
#include <vector>
#include <map>
#if USE_OPENGL
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <linux/fb.h> /* for screeninfo etc. */
#endif
#if USE_CLUTTER
#include <clutter/clutter.h>
#endif
#include "glfb.h"
extern "C" {
#include <libavutil/rational.h>
}
class GLFbPC
class GLFramebuffer : public Thread
{
public:
GLFbPC(int x, int y, std::vector<unsigned char> &buf);
~GLFbPC();
std::vector<unsigned char> *getOSDBuffer() { return osd_buf; } /* pointer to OSD bounce buffer */
GLFramebuffer(int x, int y);
~GLFramebuffer();
void run();
std::vector<unsigned char> *getOSDBuffer() { return &mOSDBuffer; } /* pointer to OSD bounce buffer */
int getOSDWidth() { return mState.width; }
int getOSDHeight() { return mState.height; }
void blit() { mState.blit = true; };
fb_var_screeninfo getScreenInfo() { return si; }
void blit() { mState.blit = true; }
void setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; }
/* just make everything public for simplicity - this is only used inside libstb-hal anyway
void clear();
fb_var_screeninfo getScreenInfo() { return screeninfo; }
int getWindowID() { return GLWinID; }
private:
*/
fb_var_screeninfo si;
fb_var_screeninfo screeninfo;
int *mX;
int *mY;
int _mX[2]; /* output window size */
@@ -65,59 +63,45 @@ private:
float zoom; /* for cropping */
float xscale; /* and aspect ratio */
int mCrop; /* DISPLAY_AR_MODE */
int GLWinID;
bool mFullscreen; /* fullscreen? */
bool mReInit; /* setup things for GL */
OpenThreads::Mutex mReInitLock;
Mutex mReInitLock;
bool mShutDown; /* if set main loop is left */
bool mInitDone; /* condition predicate */
// OpenThreads::Condition mInitCond; /* condition variable for init */
// mutable OpenThreads::Mutex mMutex; /* lock our data */
std::vector<unsigned char> *osd_buf; /* silly bounce buffer */
std::vector<unsigned char> mOSDBuffer; /* silly bounce buffer */
#if USE_OPENGL
std::map<unsigned char, int> mKeyMap;
std::map<int, int> mSpecialMap;
#endif
#if USE_CLUTTER
std::map<int, int> mKeyMap;
#endif
int input_fd;
int64_t last_apts;
void run();
static void rendercb(); /* callback for GLUT */
void render(); /* actual render function */
#if USE_OPENGL
static void keyboardcb(unsigned char key, int x, int y);
static void specialcb(int key, int x, int y);
static void resizecb(int w, int h);
void checkReinit(int w, int h); /* e.g. in case window was resized */
void initKeys(); /* setup key bindings for window */
void setupCtx(); /* create the window and make the context current */
void setupOSDBuffer(); /* create the OSD buffer */
void setupGLObjects(); /* PBOs, textures and stuff */
void releaseGLObjects();
void drawSquare(float size, float x_factor = 1); /* do not be square */
#endif
#if USE_CLUTTER
static bool keyboardcb(ClutterActor *actor, ClutterEvent *event, gpointer user_data);
#endif
void initKeys(); /* setup key bindings for window */
#if 0
void setupCtx(); /* create the window and make the context current */
void setupOSDBuffer(); /* create the OSD buffer */
#endif
struct {
int width; /* width and height, fixed for a framebuffer instance */
int height;
bool blit;
#if USE_OPENGL
GLuint osdtex; /* holds the OSD texture */
GLuint pbo; /* PBO we use for transfer to texture */
GLuint displaytex; /* holds the display texture */
GLuint displaypbo;
#endif
bool blit;
} mState;
void bltOSDBuffer();

View File

@@ -7,8 +7,12 @@
* License: GPL v2 or later
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <hardware_caps.h>
#include <sys/utsname.h>
@@ -29,9 +33,7 @@ hw_caps_t *get_hwcaps(void)
caps.has_HDMI = 1;
caps.display_xres = 8;
caps.display_can_deepstandby = 0;
caps.display_can_set_brightness = 0;
caps.display_has_statusline = 0;
caps.has_button_vformat = 0;
strcpy(caps.boxvendor, "Generic");
strcpy(caps.boxname, "PC");
if (! uname(&u))

View File

@@ -1,8 +1,7 @@
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include "init_td.h"
#include "init_lib.h"
#include "lt_debug.h"
#include "glfb.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)

5
generic-pc/init_lib.h Normal file
View File

@@ -0,0 +1,5 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -1,6 +1,6 @@
#include <stdio.h>
#include "playback_hal.h"
#include "playback.h"
static const char * FILENAME = "playback-dummy";
@@ -13,25 +13,25 @@ void cPlayback::Close(void)
{
}
bool cPlayback::Start(std::string /*filename*/, std::string /*headers*/)
bool cPlayback::Start(std::string filename, std::string headers)
{
return false;
return Start((char*) filename.c_str(),0,0,0,0,0, headers);
}
bool cPlayback::Start(char * filename, unsigned short vpid, int vtype, unsigned short apid, int ac3, unsigned int duration)
bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers)
{
printf("%s:%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d duration=%i\n",
FILENAME, __func__, filename, vpid, vtype, apid, ac3, duration);
return true;
}
bool cPlayback::SetAPid(unsigned short pid, int /*ac3*/)
bool cPlayback::SetAPid(int pid, bool /*ac3*/)
{
printf("%s:%s pid %i\n", FILENAME, __func__, pid);
return true;
}
bool cPlayback::SelectSubtitles(int pid, std::string /*charset*/)
bool cPlayback::SelectSubtitles(int pid)
{
printf("%s:%s pid %i\n", FILENAME, __func__, pid);
return true;
@@ -39,7 +39,7 @@ bool cPlayback::SelectSubtitles(int pid, std::string /*charset*/)
bool cPlayback::SetSpeed(int speed)
{
printf("%s:%s speed %d\n", FILENAME, __func__, speed);
printf("%s:%s playing %d speed %d\n", FILENAME, __func__, playing, speed);
return true;
}
@@ -62,16 +62,53 @@ bool cPlayback::SetPosition(int position, bool)
return true;
}
void cPlayback::FindAllPids(uint16_t *, unsigned short *, uint16_t *numpida, std::string *)
void cPlayback::FindAllPids(int *, unsigned int *, unsigned int *numpida, std::string *)
{
printf("%s:%s\n", FILENAME, __func__);
*numpida = 0;
}
void cPlayback::FindAllSubs(uint16_t *, unsigned short *, uint16_t *numpida, std::string *)
void cPlayback::FindAllSubtitlePids(int * /*pids*/, unsigned int *numpids, std::string * /*language*/)
{
*numpids = 0;
}
bool cPlayback::SetSubtitlePid(int /*pid*/)
{
return true;
}
void cPlayback::GetPts(uint64_t &/*pts*/)
{
}
bool cPlayback::SetTeletextPid(int /*pid*/)
{
return true;
}
void cPlayback::FindAllTeletextsubtitlePids(int *, unsigned int *numpids, std::string *, int *, int *)
{
*numpids = 0;
}
void cPlayback::SuspendSubtitle(bool /*b*/)
{
}
void cPlayback::RequestAbort()
{
}
int cPlayback::GetTeletextPid(void)
{
return -1;
}
void cPlayback::FindAllSubs(uint16_t * /*pids*/, unsigned short * /*supp*/, uint16_t *num, std::string * /*lang*/)
{
printf("%s:%s\n", FILENAME, __func__);
*numpida = 0;
*num = 0;
}
void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)
@@ -80,21 +117,20 @@ void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string
titles.clear();
}
void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
{
keys.clear();
values.clear();
}
void cPlayback::GetTitles(std::vector<int> &playlists, std::vector<std::string> &titles, int &current)
{
playlists.clear();
titles.clear();
current = 0;
}
void cPlayback::SetTitle(int /*title*/)
{
}
void cPlayback::RequestAbort(void)
{
}
uint64_t cPlayback::GetReadCount(void)
{
return 0;

58
generic-pc/playback.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef __PLAYBACK_H
#define __PLAYBACK_H
#include <string>
#include <stdint.h>
#include <vector>
typedef enum {
PLAYMODE_TS = 0,
PLAYMODE_FILE,
} playmode_t;
struct AVFormatContext;
class cPlayback
{
private:
bool playing;
int mAudioStream;
int mSubtitleStream;
int mTeletextStream;
public:
cPlayback(int);
bool Open(playmode_t PlayMode);
void Close(void);
bool Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers = "");
bool Start(std::string filename, std::string headers = "");
bool SetAPid(int pid, bool ac3);
bool SetSubtitlePid(int pid);
bool SetTeletextPid(int pid);
int GetAPid(void) { return mAudioStream; }
int GetVPid(void);
int GetSubtitlePid(void) { return mSubtitleStream; }
int GetTeletextPid(void);
void SuspendSubtitle(bool);
int GetFirstTeletextPid(void);
bool SetSpeed(int speed);
bool GetSpeed(int &speed) const;
bool GetPosition(int &position, int &duration);
void GetPts(uint64_t &pts);
bool SetPosition(int position, bool absolute = false);
void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language);
void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language);
void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage, int *mags, int *pages);
void RequestAbort(void);
bool IsPlaying(void) { return false; }
uint64_t GetReadCount(void);
void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language);
bool SelectSubtitles(int pid);
void GetTitles(std::vector<int> &playlists, std::vector<std::string> &titles, int &current);
void SetTitle(int title);
void GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
void GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
//
~cPlayback();
AVFormatContext *GetAVFormatContext(){ return NULL; }
void ReleaseAVFormatContext() {}
};
#endif

103
generic-pc/playback_gst.h Normal file
View File

@@ -0,0 +1,103 @@
/*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __PLAYBACK_CS_H
#define __PLAYBACK_CS_H
#include <string>
#include <stdint.h>
#include <vector>
#include <config.h>
typedef enum
{
STATE_STOP,
STATE_PLAY,
STATE_PAUSE,
STATE_FF,
STATE_REW,
STATE_SLOW
} playstate_t;
typedef enum
{
PLAYMODE_TS = 0,
PLAYMODE_FILE,
} playmode_t;
struct AVFormatContext;
class cPlayback
{
private:
bool playing, first;
bool decoders_closed;
int mSpeed;
int mAudioStream;
int init_jump;
public:
playstate_t playstate;
cPlayback(int);
bool Open(playmode_t PlayMode);
void Close(void);
bool Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers = "");
bool Start(std::string filename, std::string headers = "");
bool Play(void);
bool SyncAV(void);
bool Stop(void);
bool SetAPid(int pid, bool ac3);
bool SetSubtitlePid(int pid);
bool SetTeletextPid(int pid);
void trickSeek(int ratio);
bool SetSpeed(int speed);
bool SetSlow(int slow);
bool GetSpeed(int &speed) const;
bool GetPosition(int &position, int &duration);
void GetPts(uint64_t &pts);
int GetAPid(void);
int GetVPid(void);
int GetSubtitlePid(void);
bool SetPosition(int position, bool absolute = false);
void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language);
void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language);
void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage, int *mags, int *pages);
void RequestAbort(void);
void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language);
bool SelectSubtitles(int pid);
uint64_t GetReadCount(void);
void GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
void GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
AVFormatContext *GetAVFormatContext();
void ReleaseAVFormatContext();
std::string extra_headers;
std::string user_agent;
//
~cPlayback();
void getMeta();
};
#endif

View File

@@ -0,0 +1,822 @@
/*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <pthread.h>
#include <syscall.h>
#include "dmx_lib.h"
#include "audio_lib.h"
#include "video_lib.h"
#include "glfb.h"
#include "playback_gst.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(HAL_DEBUG_PLAYBACK, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_PLAYBACK, this, args)
#define lt_debug_c(args...) _lt_debug(HAL_DEBUG_PLAYBACK, NULL, args)
#define lt_info_c(args...) _lt_info(HAL_DEBUG_PLAYBACK, NULL, args)
static const char * FILENAME = "[playback.cpp]";
#include <gst/gst.h>
#include <gst/pbutils/missing-plugins.h>
#include <gst/interfaces/xoverlay.h>
typedef enum
{
GST_PLAY_FLAG_VIDEO = 0x00000001,
GST_PLAY_FLAG_AUDIO = 0x00000002,
GST_PLAY_FLAG_TEXT = 0x00000004,
GST_PLAY_FLAG_VIS = 0x00000008,
GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010,
GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020,
GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040,
GST_PLAY_FLAG_DOWNLOAD = 0x00000080,
GST_PLAY_FLAG_BUFFERING = 0x000000100
} GstPlayFlags;
GstElement * m_gst_playbin = NULL;
GstElement * audioSink = NULL;
GstElement * videoSink = NULL;
gchar * uri = NULL;
GstTagList * m_stream_tags = 0;
static int end_eof = 0;
extern GLFramebuffer *glfb;
gint match_sinktype(GstElement *element, gpointer type)
{
return strcmp(g_type_name(G_OBJECT_TYPE(element)), (const char*)type);
}
GstBusSyncReply Gst_bus_call(GstBus * bus, GstMessage *msg, gpointer user_data)
{
gchar * sourceName;
// source
GstObject * source;
source = GST_MESSAGE_SRC(msg);
if (!GST_IS_OBJECT(source))
return GST_BUS_DROP;
sourceName = gst_object_get_name(source);
switch (GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_EOS:
{
g_message("End-of-stream");
end_eof = 1;
break;
}
case GST_MESSAGE_ERROR:
{
gchar * debug;
GError *err;
gst_message_parse_error(msg, &err, &debug);
g_free (debug);
lt_info_c( "%s:%s - GST_MESSAGE_ERROR: %s (%i) from %s\n", FILENAME, __FUNCTION__, err->message, err->code, sourceName );
if ( err->domain == GST_STREAM_ERROR )
{
if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND )
{
if ( g_strrstr(sourceName, "videosink") )
lt_info_c( "%s:%s - GST_MESSAGE_ERROR: videosink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event???
else if ( g_strrstr(sourceName, "audiosink") )
lt_info_c( "%s:%s - GST_MESSAGE_ERROR: audioSink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event???
}
}
g_error_free(err);
end_eof = 1; // NOTE: just to exit
break;
}
case GST_MESSAGE_INFO:
{
gchar *debug;
GError *inf;
gst_message_parse_info (msg, &inf, &debug);
g_free (debug);
if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE )
{
if ( g_strrstr(sourceName, "videosink") )
lt_info_c( "%s:%s - GST_MESSAGE_INFO: videosink\n", FILENAME, __FUNCTION__ ); //FIXME: how shall playback handle this event???
}
g_error_free(inf);
break;
}
case GST_MESSAGE_TAG:
{
GstTagList *tags, *result;
gst_message_parse_tag(msg, &tags);
result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_REPLACE);
if (result)
{
if (m_stream_tags)
gst_tag_list_free(m_stream_tags);
m_stream_tags = result;
}
const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0);
if ( gv_image )
{
GstBuffer *buf_image;
buf_image = gst_value_get_buffer (gv_image);
int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644);
if(fd >= 0)
{
int ret = write(fd, GST_BUFFER_DATA(buf_image), GST_BUFFER_SIZE(buf_image));
close(fd);
lt_info_c( "%s:%s - GST_MESSAGE_INFO: cPlayback::state /tmp/.id3coverart %d bytes written\n", FILENAME, __FUNCTION__ , ret);
}
//FIXME: how shall playback handle this event???
}
gst_tag_list_free(tags);
lt_info_c( "%s:%s - GST_MESSAGE_INFO: update info tags\n", FILENAME, __FUNCTION__); //FIXME: how shall playback handle this event???
break;
}
case GST_MESSAGE_STATE_CHANGED:
{
if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin))
break;
GstState old_state, new_state;
gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
if(old_state == new_state)
break;
lt_info_c( "%s:%s - GST_MESSAGE_STATE_CHANGED: state transition %s -> %s\n", FILENAME, __FUNCTION__, gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state);
switch(transition)
{
case GST_STATE_CHANGE_NULL_TO_READY:
{
} break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
{
GstIterator *children;
if (audioSink)
{
gst_object_unref(GST_OBJECT(audioSink));
audioSink = NULL;
}
if (videoSink)
{
gst_object_unref(GST_OBJECT(videoSink));
videoSink = NULL;
}
children = gst_bin_iterate_recurse(GST_BIN(m_gst_playbin));
audioSink = GST_ELEMENT_CAST(gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, (gpointer)"GstDVBAudioSink"));
videoSink = GST_ELEMENT_CAST(gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, (gpointer)"GstDVBVideoSink"));
gst_iterator_free(children);
} break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
{
} break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
{
} break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
{
if (audioSink)
{
gst_object_unref(GST_OBJECT(audioSink));
audioSink = NULL;
}
if (videoSink)
{
gst_object_unref(GST_OBJECT(videoSink));
videoSink = NULL;
}
} break;
case GST_STATE_CHANGE_READY_TO_NULL:
{
} break;
}
break;
}
#if 0
case GST_MESSAGE_ELEMENT:
{
if(gst_structure_has_name(gst_message_get_structure(msg), "prepare-xwindow-id"))
{
// set window id
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC (msg)), glfb->getWindowID());
// reshape window
gst_x_overlay_set_render_rectangle(GST_X_OVERLAY(GST_MESSAGE_SRC (msg)), 0, 0, glfb->getOSDWidth(), glfb->getOSDHeight());
// sync frames
gst_x_overlay_expose(GST_X_OVERLAY(GST_MESSAGE_SRC (msg)));
}
}
#endif
break;
default:
break;
}
return GST_BUS_DROP;
}
cPlayback::cPlayback(int num)
{
lt_info( "%s:%s\n", FILENAME, __FUNCTION__);
const gchar *nano_str;
guint major, minor, micro, nano;
gst_init(NULL, NULL);
gst_version (&major, &minor, &micro, &nano);
if (nano == 1)
nano_str = "(CVS)";
else if (nano == 2)
nano_str = "(Prerelease)";
else
nano_str = "";
lt_info( "%s:%s - This program is linked against GStreamer %d.%d.%d %s\n",
FILENAME, __FUNCTION__,
major, minor, micro, nano_str);
mAudioStream = 0;
mSpeed = 0;
playing = false;
playstate = STATE_STOP;
}
cPlayback::~cPlayback()
{
lt_info( "%s:%s\n", FILENAME, __FUNCTION__);
//FIXME: all deleting stuff is done in Close()
}
//Used by Fileplay
bool cPlayback::Open(playmode_t PlayMode)
{
lt_info("%s: PlayMode %d\n", __func__, PlayMode);
return true;
}
// used by movieplay
void cPlayback::Close(void)
{
lt_info( "%s:%s\n", FILENAME, __FUNCTION__);
Stop();
// disconnect bus handler
if (m_gst_playbin)
{
// disconnect sync handler callback
GstBus * bus = gst_pipeline_get_bus(GST_PIPELINE (m_gst_playbin));
gst_bus_set_sync_handler(bus, NULL, NULL);
gst_object_unref(bus);
lt_info( "%s:%s - GST bus handler closed\n", FILENAME, __FUNCTION__);
}
if (m_stream_tags)
gst_tag_list_free(m_stream_tags);
// close gst
if (m_gst_playbin)
{
if (audioSink)
{
gst_object_unref(GST_OBJECT(audioSink));
audioSink = NULL;
lt_info( "%s:%s - GST audio Sink closed\n", FILENAME, __FUNCTION__);
}
if (videoSink)
{
gst_object_unref(GST_OBJECT(videoSink));
videoSink = NULL;
lt_info( "%s:%s - GST video Sink closed\n", FILENAME, __FUNCTION__);
}
// unref m_gst_playbin
gst_object_unref (GST_OBJECT (m_gst_playbin));
lt_info( "%s:%s - GST playbin closed\n", FILENAME, __FUNCTION__);
m_gst_playbin = NULL;
}
}
// start
bool cPlayback::Start(std::string filename, std::string headers)
{
return Start((char*) filename.c_str(),0,0,0,0,0, headers);
}
bool cPlayback::Start(char *filename, int /*vpid*/, int /*vtype*/, int /*apid*/, int /*ac3*/, int /*duration*/, std::string headers)
{
lt_info( "%s:%s\n", FILENAME, __FUNCTION__);
mAudioStream = 0;
//create playback path
char file[400] = {""};
bool isHTTP = false;
if(!strncmp("http://", filename, 7))
{
isHTTP = true;
}
else if(!strncmp("file://", filename, 7))
{
isHTTP = false;
}
else if(!strncmp("upnp://", filename, 7))
{
isHTTP = true;
}
else if(!strncmp("rtmp://", filename, 7))
{
isHTTP = true;
}
else if(!strncmp("rtsp://", filename, 7))
{
isHTTP = true;
}
else if(!strncmp("mms://", filename, 6))
{
isHTTP = true;
}
else
strcat(file, "file://");
strcat(file, filename);
if (isHTTP)
uri = g_uri_escape_string(filename, G_URI_RESERVED_CHARS_GENERIC_DELIMITERS, true);
else
uri = g_filename_to_uri(filename, NULL, NULL);
lt_info("%s:%s - filename=%s\n", FILENAME, __FUNCTION__, filename);
// create gst pipeline
m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
if(m_gst_playbin)
{
lt_info("%s:%s - m_gst_playbin\n", FILENAME, __FUNCTION__);
guint flags;
g_object_get(G_OBJECT (m_gst_playbin), "flags", &flags, NULL);
/* avoid video conversion, let the (hardware) sinks handle that */
flags |= GST_PLAY_FLAG_NATIVE_VIDEO;
/* volume control is done by hardware */
flags &= ~GST_PLAY_FLAG_SOFT_VOLUME;
g_object_set(G_OBJECT (m_gst_playbin), "uri", uri, NULL);
g_object_set(G_OBJECT (m_gst_playbin), "flags", flags, NULL);
//gstbus handler
GstBus * bus = gst_pipeline_get_bus( GST_PIPELINE(m_gst_playbin) );
gst_bus_set_sync_handler(bus, Gst_bus_call, NULL);
gst_object_unref(bus);
// state playing
gst_element_set_state(GST_ELEMENT(m_gst_playbin), GST_STATE_PLAYING);
playing = true;
playstate = STATE_PLAY;
}
else
{
lt_info("%s:%s - failed to create GStreamer pipeline!, sorry we can not play\n", FILENAME, __FUNCTION__);
playing = false;
return false;
}
g_free(uri);
// set buffer size
/* increase the default 2 second / 2 MB buffer limitations to 5s / 5MB */
int m_buffer_size = 5*1024*1024;
//g_object_set(G_OBJECT(m_gst_playbin), "buffer-duration", 5LL * GST_SECOND, NULL);
g_object_set(G_OBJECT(m_gst_playbin), "buffer-size", m_buffer_size, NULL);
return true;
}
bool cPlayback::Play(void)
{
lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
if(playing == true)
return true;
if(m_gst_playbin)
{
gst_element_set_state(GST_ELEMENT(m_gst_playbin), GST_STATE_PLAYING);
playing = true;
playstate = STATE_PLAY;
}
lt_info("%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
return playing;
}
bool cPlayback::Stop(void)
{
if(playing == false)
return false;
lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
// stop
if(m_gst_playbin)
{
gst_element_set_state(m_gst_playbin, GST_STATE_NULL);
}
playing = false;
lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
playstate = STATE_STOP;
return true;
}
bool cPlayback::SetAPid(int pid , bool /*ac3*/)
{
lt_info("%s: pid %i\n", __func__, pid);
int current_audio;
if(pid != mAudioStream)
{
g_object_set (G_OBJECT (m_gst_playbin), "current-audio", pid, NULL);
printf("%s: switched to audio stream %i\n", __FUNCTION__, pid);
mAudioStream = pid;
}
return true;
}
void cPlayback::trickSeek(int ratio)
{
bool validposition = false;
gint64 pos = 0;
int position;
int duration;
if( GetPosition(position, duration) )
{
validposition = true;
pos = position;
}
gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
if (validposition)
{
if(ratio >= 0.0)
gst_element_seek(m_gst_playbin, ratio, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP), GST_SEEK_TYPE_SET, pos, GST_SEEK_TYPE_SET, -1);
else
gst_element_seek(m_gst_playbin, ratio, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP), GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, pos);
}
}
bool cPlayback::SetSpeed(int speed)
{
lt_info( "%s:%s speed %d\n", FILENAME, __FUNCTION__, speed);
if(playing == false)
return false;
if(m_gst_playbin)
{
// pause
if(speed == 0)
{
gst_element_set_state(m_gst_playbin, GST_STATE_PAUSED);
//trickSeek(0);
playstate = STATE_PAUSE;
}
// play/continue
else if(speed == 1)
{
trickSeek(1);
//gst_element_set_state(m_gst_playbin, GST_STATE_PLAYING);
//
playstate = STATE_PLAY;
}
//ff
else if(speed > 1)
{
trickSeek(speed);
//
playstate = STATE_FF;
}
//rf
else if(speed < 0)
{
trickSeek(speed);
//
playstate = STATE_REW;
}
}
mSpeed = speed;
return true;
}
bool cPlayback::SetSlow(int slow)
{
lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
if(playing == false)
return false;
if(m_gst_playbin)
{
trickSeek(0.5);
}
playstate = STATE_SLOW;
mSpeed = slow;
return true;
}
bool cPlayback::GetSpeed(int &speed) const
{
speed = mSpeed;
return true;
}
// in milliseconds
bool cPlayback::GetPosition(int &position, int &duration)
{
if(playing == false)
return false;
//EOF
if(end_eof)
{
end_eof = 0;
return false;
}
if(m_gst_playbin)
{
//position
GstFormat fmt = GST_FORMAT_TIME; //Returns time in nanosecs
gint64 pts = 0;
unsigned long long int sec = 0;
gst_element_query_position(m_gst_playbin, &fmt, &pts);
position = pts / 1000000.0;
// duration
GstFormat fmt_d = GST_FORMAT_TIME; //Returns time in nanosecs
double length = 0;
gint64 len;
gst_element_query_duration(m_gst_playbin, &fmt_d, &len);
length = len / 1000000.0;
if(length < 0)
length = 0;
duration = (int)(length);
}
return true;
}
bool cPlayback::SetPosition(int position, bool absolute)
{
lt_info("%s: pos %d abs %d playing %d\n", __func__, position, absolute, playing);
if(playing == false)
return false;
gint64 time_nanoseconds;
gint64 pos;
GstFormat fmt = GST_FORMAT_TIME;
if(m_gst_playbin)
{
gst_element_query_position(m_gst_playbin, &fmt, &pos);
time_nanoseconds = pos + (position * 1000000.0);
if(time_nanoseconds < 0)
time_nanoseconds = 0;
gst_element_seek(m_gst_playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time_nanoseconds, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
}
return true;
}
void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string * language)
{
lt_info( "%s:%s\n", FILENAME, __FUNCTION__);
if(m_gst_playbin)
{
gint i, n_audio = 0;
//GstStructure * structure = NULL;
// get audio
g_object_get (m_gst_playbin, "n-audio", &n_audio, NULL);
printf("%s: %d audio\n", __FUNCTION__, n_audio);
if(n_audio == 0)
return;
for (i = 0; i < n_audio; i++)
{
// apids
apids[i]=i;
GstPad * pad = 0;
g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad);
GstCaps * caps = gst_pad_get_negotiated_caps(pad);
if (!caps)
continue;
GstStructure * structure = gst_caps_get_structure(caps, 0);
//const gchar *g_type = gst_structure_get_name(structure);
//if (!structure)
//return atUnknown;
//ac3flags[0] = 0;
// ac3flags
if ( gst_structure_has_name (structure, "audio/mpeg"))
{
gint mpegversion, layer = -1;
if (!gst_structure_get_int (structure, "mpegversion", &mpegversion))
//return atUnknown;
ac3flags[i] = 0;
switch (mpegversion)
{
case 1:
/*
{
gst_structure_get_int (structure, "layer", &layer);
if ( layer == 3 )
return atMP3;
else
return atMPEG;
ac3flags[0] = 4;
break;
}
*/
ac3flags[i] = 4;
case 2:
//return atAAC;
ac3flags[i] = 5;
case 4:
//return atAAC;
ac3flags[i] = 5;
default:
//return atUnknown;
ac3flags[i] = 0;
}
}
else if ( gst_structure_has_name (structure, "audio/x-ac3") || gst_structure_has_name (structure, "audio/ac3") )
//return atAC3;
ac3flags[i] = 1;
else if ( gst_structure_has_name (structure, "audio/x-dts") || gst_structure_has_name (structure, "audio/dts") )
//return atDTS;
ac3flags[i] = 6;
else if ( gst_structure_has_name (structure, "audio/x-raw-int") )
//return atPCM;
ac3flags[i] = 0;
gst_caps_unref(caps);
}
// numpids
*numpida=i;
}
}
void cPlayback::getMeta()
{
if(playing)
return;
}
bool cPlayback::SyncAV(void)
{
lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
if(playing == false )
return false;
return true;
}
void cPlayback::RequestAbort()
{
}
void cPlayback::FindAllSubs(uint16_t *, unsigned short *, uint16_t *numpida, std::string *)
{
printf("%s:%s\n", FILENAME, __func__);
*numpida = 0;
}
void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)
{
positions.clear();
titles.clear();
}
bool cPlayback::SelectSubtitles(int pid)
{
printf("%s:%s pid %i\n", FILENAME, __func__, pid);
return true;
}
void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
{
keys.clear();
values.clear();
}
void cPlayback::FindAllTeletextsubtitlePids(int *, unsigned int *numpids, std::string *, int *, int *)
{
*numpids = 0;
}
void cPlayback::FindAllSubtitlePids(int * /*pids*/, unsigned int *numpids, std::string * /*language*/)
{
*numpids = 0;
}
bool cPlayback::SetSubtitlePid(int /*pid*/)
{
return true;
}
void cPlayback::GetPts(uint64_t &/*pts*/)
{
}
bool cPlayback::SetTeletextPid(int /*pid*/)
{
return true;
}
uint64_t cPlayback::GetReadCount()
{
return 0;
}

File diff suppressed because it is too large Load Diff

1
generic-pc/pwrmngr.cpp Symbolic link
View File

@@ -0,0 +1 @@
../libspark/pwrmngr.cpp

1
generic-pc/pwrmngr.h Symbolic link
View File

@@ -0,0 +1 @@
../libspark/pwrmngr.h

1
generic-pc/record_lib.h Symbolic link
View File

@@ -0,0 +1 @@
../libspark/record_lib.h

View File

@@ -23,7 +23,6 @@
* TODO: buffer handling surely needs some locking...
*/
#include "config.h"
#include <unistd.h>
#include <cstring>
#include <cstdio>
@@ -31,7 +30,6 @@
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
@@ -40,26 +38,17 @@ extern "C" {
/* my own buf 256k */
#define DMX_BUF_SZ 0x20000
#if USE_OPENGL
#define VDEC_PIXFMT AV_PIX_FMT_RGB32
#endif
#if USE_CLUTTER
#define VDEC_PIXFMT AV_PIX_FMT_BGR24
#endif
#include "video_hal.h"
#include "dmx_hal.h"
#include "glfb_priv.h"
#include "video_priv.h"
#include "video_lib.h"
#include "dmx_lib.h"
#include "glfb.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_VIDEO, this, args)
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_VIDEO, NULL, args)
VDec *vdec = NULL;
cVideo *videoDecoder = NULL;
extern cDemux *videoDemux;
extern GLFbPC *glfb_priv;
extern GLFramebuffer *glfb;
int system_rev = 0;
extern bool HAL_nodec;
@@ -79,13 +68,6 @@ static const AVRational aspect_ratios[6] = {
cVideo::cVideo(int, void *, void *, unsigned int)
{
lt_debug("%s\n", __func__);
vdec = new VDec();
/* quick hack to export private stuff to other libstb-hal modules */
::vdec = vdec;
}
VDec::VDec()
{
av_register_all();
if (!HAL_nodec)
dmxbuf = (uint8_t *)malloc(DMX_BUF_SZ);
@@ -97,35 +79,20 @@ VDec::VDec()
buf_in = 0;
buf_out = 0;
pig_x = pig_y = pig_w = pig_h = 0;
pig_changed = false;
display_aspect = DISPLAY_AR_16_9;
display_crop = DISPLAY_AR_MODE_LETTERBOX;
v_format = VIDEO_FORMAT_MPEG2;
output_h = 0;
stillpicture = false;
}
VDec::~VDec(void)
{
free(dmxbuf);
}
cVideo::~cVideo(void)
{
Stop();
/* ouch :-( */
// videoDecoder = NULL;
delete vdec;
::vdec = NULL;
videoDecoder = NULL;
}
int cVideo::setAspectRatio(int vformat, int cropping)
{
return vdec->setAspectRatio(vformat, cropping);
}
int VDec::setAspectRatio(int vformat, int cropping)
{
lt_info("%s(%d, %d)\n", __func__, vformat, cropping);
if (vformat >= 0)
@@ -133,16 +100,11 @@ int VDec::setAspectRatio(int vformat, int cropping)
if (cropping >= 0)
display_crop = (DISPLAY_AR_MODE) cropping;
if (display_aspect < DISPLAY_AR_RAW && output_h > 0) /* don't know what to do with this */
glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
return 0;
}
int cVideo::getAspectRatio(void)
{
return vdec->getAspectRatio();
}
int VDec::getAspectRatio(void)
{
buf_m.lock();
int ret = 0;
@@ -171,36 +133,26 @@ int VDec::getAspectRatio(void)
return ret;
}
int cVideo::setCroppingMode(void)
int cVideo::setCroppingMode(int)
{
return 0;
}
int cVideo::Start(void *, unsigned short, unsigned short, void *)
{
return vdec->Start();
}
int cVideo::Stop(bool b)
{
return vdec->Stop(b);
}
int VDec::Start()
{
lt_debug("%s running %d >\n", __func__, thread_running);
if (!thread_running && !HAL_nodec)
OpenThreads::Thread::start();
Thread::startThread();
lt_debug("%s running %d <\n", __func__, thread_running);
return 0;
}
int VDec::Stop(bool)
int cVideo::Stop(bool)
{
lt_debug("%s running %d >\n", __func__, thread_running);
if (thread_running) {
thread_running = false;
OpenThreads::Thread::join();
Thread::joinThread();
}
lt_debug("%s running %d <\n", __func__, thread_running);
return 0;
@@ -211,29 +163,7 @@ int cVideo::setBlank(int)
return 1;
}
int cVideo::GetVideoSystem()
{
return vdec->GetVideoSystem();
}
int VDec::GetVideoSystem()
{
int current_video_system = VIDEO_STD_1080I50;
if(dec_w < 720)
current_video_system = VIDEO_STD_PAL;
else if(dec_w > 720 && dec_w <= 1280)
current_video_system = VIDEO_STD_720P50;
return current_video_system;
}
int cVideo::SetVideoSystem(int system, bool)
{
return vdec->SetVideoSystem(system);
}
int VDec::SetVideoSystem(int system)
{
int h;
switch(system)
@@ -266,39 +196,39 @@ int VDec::SetVideoSystem(int system)
lt_info("%s: unhandled value %d\n", __func__, system);
return 0;
}
// v_std = (VIDEO_STD) system;
v_std = (VIDEO_STD) system;
output_h = h;
if (display_aspect < DISPLAY_AR_RAW && output_h > 0) /* don't know what to do with this */
glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
return 0;
}
int cVideo::GetVideoSystem()
{
int current_video_system = VIDEO_STD_1080I50;
if(dec_w < 720)
current_video_system = VIDEO_STD_PAL;
else if(dec_w > 720 && dec_w <= 1280)
current_video_system = VIDEO_STD_720P50;
return 0;
}
int cVideo::getPlayState(void)
{
return 1;
return VIDEO_PLAYING;
}
void cVideo::SetVideoMode(analog_mode_t)
{
}
bool cVideo::ShowPicture(const char *fname)
void cVideo::ShowPicture(const char *fname, const char *)
{
return vdec->ShowPicture(fname);
}
bool VDec::ShowPicture(const char *fname)
{
bool ret = false;
lt_info("%s(%s)\n", __func__, fname);
if (access(fname, R_OK))
return ret;
still_m.lock();
stillpicture = true;
buf_num = 0;
buf_in = 0;
buf_out = 0;
still_m.unlock();
return;
unsigned int i;
int stream_id = -1;
@@ -306,14 +236,13 @@ bool VDec::ShowPicture(const char *fname)
int len;
AVFormatContext *avfc = NULL;
AVCodecContext *c = NULL;
AVCodecParameters *p = NULL;
AVCodec *codec;
AVFrame *frame, *rgbframe;
AVPacket avpkt;
if (avformat_open_input(&avfc, fname, NULL, NULL) < 0) {
lt_info("%s: Could not open file %s\n", __func__, fname);
return ret;
return;
}
if (avformat_find_stream_info(avfc, NULL) < 0) {
@@ -321,18 +250,17 @@ bool VDec::ShowPicture(const char *fname)
goto out_close;
}
for (i = 0; i < avfc->nb_streams; i++) {
if (avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (avfc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
stream_id = i;
break;
}
}
if (stream_id < 0)
goto out_close;
p = avfc->streams[stream_id]->codecpar;
codec = avcodec_find_decoder(p->codec_id);
c = avcodec_alloc_context3(codec);
if (avcodec_open2(c, codec, NULL) < 0) {
lt_info("%s: Could not find/open the codec, id 0x%x\n", __func__, p->codec_id);
c = avfc->streams[stream_id]->codec;
codec = avcodec_find_decoder(c->codec_id);
if (!avcodec_open2(c, codec, NULL) < 0) {
lt_info("%s: Could not find/open the codec, id 0x%x\n", __func__, c->codec_id);
goto out_close;
}
frame = av_frame_alloc();
@@ -349,15 +277,15 @@ bool VDec::ShowPicture(const char *fname)
len = avcodec_decode_video2(c, frame, &got_frame, &avpkt);
if (len < 0) {
lt_info("%s: avcodec_decode_video2 %d\n", __func__, len);
av_packet_unref(&avpkt);
av_free_packet(&avpkt);
goto out_free;
}
if (avpkt.size > len)
lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len);
if (got_frame) {
unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1);
unsigned int need = avpicture_get_size(PIX_FMT_RGB32, c->width, c->height);
struct SwsContext *convert = sws_getContext(c->width, c->height, c->pix_fmt,
c->width, c->height, VDEC_PIXFMT,
c->width, c->height, PIX_FMT_RGB32,
SWS_BICUBIC, 0, 0, 0);
if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__);
@@ -366,8 +294,8 @@ bool VDec::ShowPicture(const char *fname)
SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need)
f->resize(need);
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT,
c->width, c->height, 1);
avpicture_fill((AVPicture *)rgbframe, &(*f)[0], PIX_FMT_RGB32,
c->width, c->height);
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
rgbframe->data, rgbframe->linesize);
sws_freeContext(convert);
@@ -380,33 +308,26 @@ bool VDec::ShowPicture(const char *fname)
buf_in %= VDEC_MAXBUFS;
buf_num++;
if (buf_num > (VDEC_MAXBUFS - 1)) {
lt_info("%s: buf_num overflow\n", __func__);
lt_debug("%s: buf_num overflow\n", __func__);
buf_out++;
buf_out %= VDEC_MAXBUFS;
buf_num--;
}
buf_m.unlock();
ret = true;
}
}
av_packet_unref(&avpkt);
av_free_packet(&avpkt);
out_free:
avcodec_close(c);
av_free(c);
av_frame_free(&frame);
av_frame_free(&rgbframe);
out_close:
avformat_close_input(&avfc);
lt_debug("%s(%s) end\n", __func__, fname);
return ret;
}
void cVideo::StopPicture()
{
lt_info("%s\n", __func__);
vdec->still_m.lock();
vdec->stillpicture = false;
vdec->still_m.unlock();
}
void cVideo::Standby(unsigned int)
@@ -418,55 +339,19 @@ int cVideo::getBlank(void)
return 0;
}
void cVideo::Pig(int x, int y, int w, int h, int, int)
{
vdec->Pig(x, y, w, h);
}
void VDec::Pig(int x, int y, int w, int h)
void cVideo::Pig(int x, int y, int w, int h, int /*osd_w*/, int /*osd_h*/, int /*startx*/, int /*starty*/, int /*endx*/, int /*endy*/)
{
pig_x = x;
pig_y = y;
pig_w = w;
pig_h = h;
pig_changed = true;
}
void cVideo::getPictureInfo(int &width, int &height, int &rate)
{
vdec->getPictureInfo(width, height, rate);
}
void VDec::getPictureInfo(int &width, int &height, int &rate)
{
width = dec_w;
height = dec_h;
switch (dec_r) {
case 23://23.976fps
rate = VIDEO_FRAME_RATE_23_976;
break;
case 24:
rate = VIDEO_FRAME_RATE_24;
break;
case 25:
rate = VIDEO_FRAME_RATE_25;
break;
case 29://29,976fps
rate = VIDEO_FRAME_RATE_29_97;
break;
case 30:
rate = VIDEO_FRAME_RATE_30;
break;
case 50:
rate = VIDEO_FRAME_RATE_50;
break;
case 60:
rate = VIDEO_FRAME_RATE_60;
break;
default:
rate = dec_r;
break;
}
rate = dec_r;
}
void cVideo::SetSyncMode(AVSYNC_TYPE)
@@ -474,17 +359,12 @@ void cVideo::SetSyncMode(AVSYNC_TYPE)
};
int cVideo::SetStreamType(VIDEO_FORMAT v)
{
return vdec->SetStreamType(v);
}
int VDec::SetStreamType(VIDEO_FORMAT v)
{
v_format = v;
return 0;
}
VDec::SWFramebuffer *VDec::getDecBuf(void)
cVideo::SWFramebuffer *cVideo::getDecBuf(void)
{
buf_m.lock();
if (buf_num == 0) {
@@ -523,11 +403,10 @@ static int my_read(void *, uint8_t *buf, int buf_size)
return tmp;
}
void VDec::run(void)
void cVideo::run(void)
{
lt_info("====================== start decoder thread ================================\n");
AVCodec *codec;
AVCodecParameters *p = NULL;
AVCodecContext *c= NULL;
AVFormatContext *avfc = NULL;
AVInputFormat *inp;
@@ -568,21 +447,20 @@ void VDec::run(void)
lt_info("%s: nb_streams %d, should be 1 => retry\n", __func__, avfc->nb_streams);
if (av_read_frame(avfc, &avpkt) < 0)
lt_info("%s: av_read_frame < 0\n", __func__);
av_packet_unref(&avpkt);
av_free_packet(&avpkt);
if (! thread_running)
goto out;
}
p = avfc->streams[0]->codecpar;
if (p->codec_type != AVMEDIA_TYPE_VIDEO)
lt_info("%s: no video codec? 0x%x\n", __func__, p->codec_type);
if (avfc->streams[0]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
lt_info("%s: no video codec? 0x%x\n", __func__, avfc->streams[0]->codec->codec_type);
codec = avcodec_find_decoder(p->codec_id);
c = avfc->streams[0]->codec;
codec = avcodec_find_decoder(c->codec_id);
if (!codec) {
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(p->codec_id));
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(c->codec_id));
goto out;
}
c = avcodec_alloc_context3(codec);
if (avcodec_open2(c, codec, NULL) < 0) {
lt_info("%s: Could not open codec\n", __func__);
goto out;
@@ -610,17 +488,16 @@ void VDec::run(void)
lt_info("%s: avcodec_decode_video2 %d\n", __func__, len);
warn_d = time(NULL);
}
av_packet_unref(&avpkt);
av_free_packet(&avpkt);
continue;
}
if (avpkt.size > len)
lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len);
still_m.lock();
if (got_frame && ! stillpicture) {
unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1);
if (got_frame) {
unsigned int need = avpicture_get_size(PIX_FMT_RGB32, c->width, c->height);
convert = sws_getCachedContext(convert,
c->width, c->height, c->pix_fmt,
c->width, c->height, VDEC_PIXFMT,
c->width, c->height, PIX_FMT_RGB32,
SWS_BICUBIC, 0, 0, 0);
if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__);
@@ -629,8 +506,8 @@ void VDec::run(void)
SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need)
f->resize(need);
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT,
c->width, c->height, 1);
avpicture_fill((AVPicture *)rgbframe, &(*f)[0], PIX_FMT_RGB32,
c->width, c->height);
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
rgbframe->data, rgbframe->linesize);
if (dec_w != c->width || dec_h != c->height) {
@@ -643,18 +520,8 @@ void VDec::run(void)
f->width(c->width);
f->height(c->height);
int64_t vpts = av_frame_get_best_effort_timestamp(frame);
/* a/v delay determined experimentally :-) */
#if USE_OPENGL
if (v_format == VIDEO_FORMAT_MPEG2)
vpts += 90000*4/10; /* 400ms */
else
vpts += 90000*3/10; /* 300ms */
#endif
#if USE_CLUTTER
/* no idea why there's a difference between OpenGL and clutter rendering... */
if (v_format == VIDEO_FORMAT_MPEG2)
vpts += 90000*3/10; /* 300ms */
#endif
f->pts(vpts);
AVRational a = av_guess_sample_aspect_ratio(avfc, avfc->streams[0], frame);
f->AR(a);
@@ -662,7 +529,7 @@ void VDec::run(void)
buf_in %= VDEC_MAXBUFS;
buf_num++;
if (buf_num > (VDEC_MAXBUFS - 1)) {
lt_info("%s: buf_num overflow\n", __func__);
lt_debug("%s: buf_num overflow\n", __func__);
buf_out++;
buf_out %= VDEC_MAXBUFS;
buf_num--;
@@ -673,15 +540,12 @@ void VDec::run(void)
lt_debug("%s: time_base: %d/%d, ticks: %d rate: %d pts 0x%" PRIx64 "\n", __func__,
c->time_base.num, c->time_base.den, c->ticks_per_frame, dec_r,
av_frame_get_best_effort_timestamp(frame));
} else
lt_info("%s: got_frame: %d stillpicture: %d\n", __func__, got_frame, stillpicture);
still_m.unlock();
av_packet_unref(&avpkt);
}
av_free_packet(&avpkt);
}
sws_freeContext(convert);
out2:
avcodec_close(c);
av_free(c);
av_frame_free(&frame);
av_frame_free(&rgbframe);
out:
@@ -690,67 +554,39 @@ void VDec::run(void)
av_free(pIOCtx);
/* reset output buffers */
bufpos = 0;
still_m.lock();
if (!stillpicture) {
buf_num = 0;
buf_in = 0;
buf_out = 0;
}
still_m.unlock();
buf_num = 0;
buf_in = 0;
buf_out = 0;
lt_info("======================== end decoder thread ================================\n");
}
static bool swscale(unsigned char *src, unsigned char *dst, int sw, int sh, int dw, int dh, AVPixelFormat sfmt)
static bool swscale(unsigned char *src, unsigned char *dst, int sw, int sh, int dw, int dh)
{
bool ret = false;
int len = 0;
struct SwsContext *scale = NULL;
scale = sws_getCachedContext(scale, sw, sh, sfmt, dw, dh, AV_PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0);
AVFrame *sframe, *dframe;
scale = sws_getCachedContext(scale, sw, sh, PIX_FMT_RGB32, dw, dh, PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0);
if (!scale) {
lt_info_c("%s: ERROR setting up SWS context\n", __func__);
return ret;
return false;
}
AVFrame *sframe = av_frame_alloc();
AVFrame *dframe = av_frame_alloc();
if (sframe && dframe) {
len = av_image_fill_arrays(sframe->data, sframe->linesize, &(src)[0], sfmt, sw, sh, 1);
if(len>-1)
ret = true;
if(ret && (len = av_image_fill_arrays(dframe->data, dframe->linesize, &(dst)[0], AV_PIX_FMT_RGB32, dw, dh, 1)<0))
ret = false;
if(ret && (len = sws_scale(scale, sframe->data, sframe->linesize, 0, sh, dframe->data, dframe->linesize)<0))
ret = false;
else
ret = true;
}else{
sframe = av_frame_alloc();
dframe = av_frame_alloc();
if (!sframe || !dframe) {
lt_info_c("%s: could not alloc sframe (%p) or dframe (%p)\n", __func__, sframe, dframe);
ret = false;
goto out;
}
if(sframe){
av_frame_free(&sframe);
sframe = NULL;
}
if(dframe){
av_frame_free(&dframe);
dframe = NULL;
}
if(scale){
sws_freeContext(scale);
scale = NULL;
}
lt_info_c("%s: %s scale %ix%i to %ix%i ,len %i\n",ret?" ":"ERROR",__func__, sw, sh, dw, dh,len);
avpicture_fill((AVPicture *)sframe, &(src[0]), PIX_FMT_RGB32, sw, sh);
avpicture_fill((AVPicture *)dframe, &(dst[0]), PIX_FMT_RGB32, dw, dh);
sws_scale(scale, sframe->data, sframe->linesize, 0, sh, dframe->data, dframe->linesize);
out:
av_frame_free(&sframe);
av_frame_free(&dframe);
sws_freeContext(scale);
return ret;
}
bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video, bool get_osd, bool scale_to_video)
{
return vdec->GetScreenImage(data, xres,yres,get_video,get_osd,scale_to_video);
}
bool VDec::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video, bool get_osd, bool scale_to_video)
bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video, bool get_osd, bool scale_to_video)
{
lt_info("%s: data 0x%p xres %d yres %d vid %d osd %d scale %d\n",
__func__, data, xres, yres, get_video, get_osd, scale_to_video);
@@ -758,8 +594,8 @@ bool VDec::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_
std::vector<unsigned char> *osd = NULL;
std::vector<unsigned char> s_osd; /* scaled OSD */
int vid_w = 0, vid_h = 0;
int osd_w = glfb_priv->getOSDWidth();
int osd_h = glfb_priv->getOSDHeight();
int osd_w = glfb->getOSDWidth();
int osd_h = glfb->getOSDHeight();
xres = osd_w;
yres = osd_h;
if (get_video) {
@@ -777,42 +613,24 @@ bool VDec::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_
xres = vid_w * a.num / a.den;
}
}
if(video.empty()){
get_video=false;
xres = osd_w;
yres = osd_h;
}
if (get_osd)
osd = glfb_priv->getOSDBuffer();
unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, xres, yres, 1);
osd = glfb->getOSDBuffer();
unsigned int need = avpicture_get_size(PIX_FMT_RGB32, xres, yres);
data = (unsigned char *)realloc(data, need); /* will be freed by caller */
if (data == NULL) /* out of memory? */
return false;
if (get_video) {
#if USE_OPENGL //memcpy dont work with copy BGR24 to RGB32
if (vid_w != xres || vid_h != yres){ /* scale video into data... */
#endif
bool ret = swscale(&video[0], data, vid_w, vid_h, xres, yres,VDEC_PIXFMT);
if(!ret){
free(data);
return false;
}
#if USE_OPENGL //memcpy dont work with copy BGR24 to RGB32
}else{ /* get_video and no fancy scaling needed */
if (vid_w != xres || vid_h != yres) /* scale video into data... */
swscale(&video[0], data, vid_w, vid_h, xres, yres);
else /* get_video and no fancy scaling needed */
memcpy(data, &video[0], xres * yres * sizeof(uint32_t));
}
#endif
}
if (get_osd && (osd_w != xres || osd_h != yres)) {
/* rescale osd */
s_osd.resize(need);
bool ret = swscale(&(*osd)[0], &s_osd[0], osd_w, osd_h, xres, yres,AV_PIX_FMT_RGB32);
if(!ret){
free(data);
return false;
}
swscale(&(*osd)[0], &s_osd[0], osd_w, osd_h, xres, yres);
osd = &s_osd;
}
@@ -846,7 +664,7 @@ bool VDec::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_
return true;
}
int64_t VDec::GetPTS(void)
int64_t cVideo::GetPTS(void)
{
int64_t pts = 0;
buf_m.lock();

223
generic-pc/video_lib.h Normal file
View File

@@ -0,0 +1,223 @@
#ifndef _VIDEO_TD_H
#define _VIDEO_TD_H
#include <thread_abstraction.h>
#include <mutex_abstraction.h>
#include <vector>
#include <linux/dvb/video.h>
#include "../common/cs_types.h"
#include "dmx_lib.h"
extern "C" {
#include <libavutil/rational.h>
}
typedef enum {
ANALOG_SD_RGB_CINCH = 0x00,
ANALOG_SD_YPRPB_CINCH,
ANALOG_HD_RGB_CINCH,
ANALOG_HD_YPRPB_CINCH,
ANALOG_SD_RGB_SCART = 0x10,
ANALOG_SD_YPRPB_SCART,
ANALOG_HD_RGB_SCART,
ANALOG_HD_YPRPB_SCART,
ANALOG_SCART_MASK = 0x10
} analog_mode_t;
typedef enum {
VIDEO_FORMAT_MPEG2 = 0,
VIDEO_FORMAT_MPEG4_H264,
VIDEO_FORMAT_VC1,
VIDEO_FORMAT_JPEG,
VIDEO_FORMAT_GIF,
VIDEO_FORMAT_PNG,
VIDEO_FORMAT_MPEG4_H265,
VIDEO_FORMAT_AVS = 16
} VIDEO_FORMAT;
typedef enum {
VIDEO_SD = 0,
VIDEO_HD,
VIDEO_120x60i,
VIDEO_320x240i,
VIDEO_1440x800i,
VIDEO_360x288i
} VIDEO_DEFINITION;
typedef enum {
VIDEO_FRAME_RATE_23_976 = 0,
VIDEO_FRAME_RATE_24,
VIDEO_FRAME_RATE_25,
VIDEO_FRAME_RATE_29_97,
VIDEO_FRAME_RATE_30,
VIDEO_FRAME_RATE_50,
VIDEO_FRAME_RATE_59_94,
VIDEO_FRAME_RATE_60
} VIDEO_FRAME_RATE;
typedef enum {
DISPLAY_AR_1_1,
DISPLAY_AR_4_3,
DISPLAY_AR_14_9,
DISPLAY_AR_16_9,
DISPLAY_AR_20_9,
DISPLAY_AR_RAW,
} DISPLAY_AR;
typedef enum {
DISPLAY_AR_MODE_PANSCAN = 0,
DISPLAY_AR_MODE_LETTERBOX,
DISPLAY_AR_MODE_NONE,
DISPLAY_AR_MODE_PANSCAN2
} DISPLAY_AR_MODE;
typedef enum {
VIDEO_DB_DR_NEITHER = 0,
VIDEO_DB_ON,
VIDEO_DB_DR_BOTH
} VIDEO_DB_DR;
typedef enum {
VIDEO_PLAY_STILL = 0,
VIDEO_PLAY_CLIP,
VIDEO_PLAY_TRICK,
VIDEO_PLAY_MOTION,
VIDEO_PLAY_MOTION_NO_SYNC
} VIDEO_PLAY_MODE;
typedef enum {
VIDEO_STD_NTSC,
VIDEO_STD_SECAM,
VIDEO_STD_PAL,
VIDEO_STD_480P,
VIDEO_STD_576P,
VIDEO_STD_720P60,
VIDEO_STD_1080I60,
VIDEO_STD_720P50,
VIDEO_STD_1080I50,
VIDEO_STD_1080P30,
VIDEO_STD_1080P24,
VIDEO_STD_1080P25,
VIDEO_STD_AUTO,
VIDEO_STD_1080P50, /* SPARK only */
VIDEO_STD_MAX
} VIDEO_STD;
/* not used, for dummy functions */
typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER,
VIDEO_HDMI_CEC_MODE_RECORDER
} VIDEO_HDMI_CEC_MODE;
typedef enum
{
VIDEO_CONTROL_BRIGHTNESS = 0,
VIDEO_CONTROL_CONTRAST,
VIDEO_CONTROL_SATURATION,
VIDEO_CONTROL_HUE,
VIDEO_CONTROL_SHARPNESS,
VIDEO_CONTROL_MAX = VIDEO_CONTROL_SHARPNESS
} VIDEO_CONTROL;
#define VDEC_MAXBUFS 0x30
class cVideo : public Thread
{
friend class GLFramebuffer;
friend class cDemux;
private:
/* called from GL thread */
class SWFramebuffer : public std::vector<unsigned char>
{
public:
SWFramebuffer() : mWidth(0), mHeight(0) {}
void width(int w) { mWidth = w; }
void height(int h) { mHeight = h; }
void pts(uint64_t p) { mPts = p; }
void AR(AVRational a) { mAR = a; }
int width() const { return mWidth; }
int height() const { return mHeight; }
int64_t pts() const { return mPts; }
AVRational AR() const { return mAR; }
private:
int mWidth;
int mHeight;
int64_t mPts;
AVRational mAR;
};
int buf_in, buf_out, buf_num;
int64_t GetPTS(void);
public:
/* constructor & destructor */
cVideo(int mode, void *, void *, unsigned int unit = 0);
~cVideo(void);
void * GetTVEnc() { return NULL; };
void * GetTVEncSD() { return NULL; };
/* aspect ratio */
int getAspectRatio(void);
void getPictureInfo(int &width, int &height, int &rate);
int setAspectRatio(int aspect, int mode);
/* cropping mode */
int setCroppingMode(int x = 0 /*vidDispMode_t x = VID_DISPMODE_NORM*/);
/* get play state */
int getPlayState(void);
/* blank on freeze */
int getBlank(void);
int setBlank(int enable);
/* change video play state. Parameters are all unused. */
int Start(void *PcrChannel = NULL, unsigned short PcrPid = 0, unsigned short VideoPid = 0, void *x = NULL);
int Stop(bool blank = true);
bool Pause(void);
/* set video_system */
int SetVideoSystem(int video_system, bool remember = true);
int GetVideoSystem();
int SetStreamType(VIDEO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE mode);
bool SetCECMode(VIDEO_HDMI_CEC_MODE) { return true; };
void SetCECAutoView(bool) { return; };
void SetCECAutoStandby(bool) { return; };
void ShowPicture(const char * fname, const char * destname = NULL);
void StopPicture();
void Standby(unsigned int bOn);
void Pig(int x, int y, int w, int h, int osd_w = 1064, int osd_h = 600, int startx = 0, int starty = 0, int endx = 1279, int endy = 719);
void SetControl(int, int) { return; };
void setContrast(int val);
void SetVideoMode(analog_mode_t mode);
void SetDBDR(int) { return; };
void SetAudioHandle(void *) { return; };
void SetAutoModes(int [VIDEO_STD_MAX]) { return; };
int OpenVBI(int) { return 0; };
int CloseVBI(void) { return 0; };
int StartVBI(unsigned short) { return 0; };
int StopVBI(void) { return 0; };
void SetDemux(cDemux *dmx);
bool GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video = true, bool get_osd = false, bool scale_to_video = false);
SWFramebuffer *getDecBuf(void);
private:
void run();
SWFramebuffer buffers[VDEC_MAXBUFS];
int dec_w, dec_h;
int dec_r;
bool w_h_changed;
bool thread_running;
VIDEO_FORMAT v_format;
VIDEO_STD v_std;
//OpenThreads::Mutex buf_m;
Mutex buf_m;
DISPLAY_AR display_aspect;
DISPLAY_AR_MODE display_crop;
int output_h;
int pig_x;
int pig_y;
int pig_w;
int pig_h;
};
#endif

View File

@@ -1,109 +0,0 @@
/*
Copyright 2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __vdec__
#include <OpenThreads/Thread>
#include <OpenThreads/Mutex>
#include "video_hal.h"
extern "C" {
#include <libavutil/rational.h>
}
#define VDEC_MAXBUFS 0x40
class VDec : public OpenThreads::Thread
{
friend class GLFbPC;
friend class cDemux;
friend class cVideo;
private:
/* called from GL thread */
class SWFramebuffer : public std::vector<unsigned char>
{
public:
SWFramebuffer() : mWidth(0), mHeight(0) {}
void width(int w) { mWidth = w; }
void height(int h) { mHeight = h; }
void pts(uint64_t p) { mPts = p; }
void AR(AVRational a) { mAR = a; }
int width() const { return mWidth; }
int height() const { return mHeight; }
int64_t pts() const { return mPts; }
AVRational AR() const { return mAR; }
private:
int mWidth;
int mHeight;
int64_t mPts;
AVRational mAR;
};
int buf_in, buf_out, buf_num;
public:
/* constructor & destructor */
VDec(void);
~VDec(void);
/* aspect ratio */
int getAspectRatio(void);
int setAspectRatio(int aspect, int mode);
void getPictureInfo(int &width, int &height, int &rate);
#if 0
/* cropping mode */
int setCroppingMode(int x = 0 /*vidDispMode_t x = VID_DISPMODE_NORM*/);
/* get play state */
int getPlayState(void);
/* blank on freeze */
int getBlank(void);
int setBlank(int enable);
#endif
int GetVideoSystem();
int SetVideoSystem(int system);
/* change video play state. Parameters are all unused. */
int Start();
int Stop(bool blank = true);
int SetStreamType(VIDEO_FORMAT type);
bool ShowPicture(const char * fname);
void Pig(int x, int y, int w, int h);
bool GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video = true, bool get_osd = false, bool scale_to_video = false);
SWFramebuffer *getDecBuf(void);
int64_t GetPTS(void);
private:
void run();
SWFramebuffer buffers[VDEC_MAXBUFS];
int dec_w, dec_h;
int dec_r;
bool w_h_changed;
bool thread_running;
VIDEO_FORMAT v_format;
OpenThreads::Mutex buf_m;
DISPLAY_AR display_aspect;
DISPLAY_AR_MODE display_crop;
int output_h;
VIDEO_STD v_std;
int pig_x;
int pig_y;
int pig_w;
int pig_h;
bool pig_changed;
OpenThreads::Mutex still_m;
bool stillpicture;
};
#endif

View File

@@ -1,99 +1,22 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __audio_hal__
#define __audio_hal__
#include <stdint.h>
#include <cs_types.h>
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio
{
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(void);
int unmute(void);
int SetMute(bool enable);
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported();
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
private:
bool muted;
int volume;
void *pdata;
};
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/audio_td.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/audio_lib.h"
#include "../libduckbox/audio_mixer.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/audio_lib.h"
#include "../libspark/audio_mixer.h"
#elif HAVE_ARM_HARDWARE
#include "../libarmbox/audio_lib.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/audio_lib.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/audio_lib.h"
#else
#include "../generic-pc/audio_lib.h"
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif

View File

@@ -1 +1 @@
#include "ca.h"
#include "../common/ca.h"

View File

@@ -0,0 +1,23 @@
#ifndef _CONDITION_ABSTRACTION_H
#define _CONDITION_ABSTRACTION_H
#include <pthread.h>
#include "mutex_abstraction.h"
class Condition
{
pthread_cond_t mCondition;
Condition(const Condition&);
const Condition& operator=(const Condition&);
public:
Condition();
virtual ~Condition();
virtual int wait(Mutex* const aMutex);
virtual int broadcast();
virtual int signal();
};
#endif

View File

@@ -1,67 +1,20 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_td.h"
typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
#if 0
enum CS_LOG_MODULE {
CS_LOG_CI = 0,
CS_LOG_HDMI_CEC,
CS_LOG_HDMI,
CS_LOG_VIDEO,
CS_LOG_VIDEO_DRM,
CS_LOG_AUDIO,
CS_LOG_DEMUX,
CS_LOG_DENC,
CS_LOG_PVR_RECORD,
CS_LOG_PVR_PLAY,
CS_LOG_POWER_CTRL,
CS_LOG_POWER_CLK,
CS_LOG_MEM,
CS_LOG_API,
};
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/cs_api.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/cs_api.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/cs_api.h"
#elif HAVE_ARM_HARDWARE
#include "../libarmbox/cs_api.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/cs_api.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/cs_api.h"
#else
#include "../generic-pc/cs_api.h"
#endif
inline void cs_api_init()
{
init_td_api();
};
inline void cs_api_exit()
{
shutdown_td_api();
};
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
static inline void cs_register_messenger(cs_messenger) { return; };
static inline void cs_deregister_messenger(void) { return; };
//cs_messenger cs_get_messenger(void);
#if 0
// Logging functions
void cs_log_enable(void);
void cs_log_disable(void);
void cs_log_message(const char *prefix, const char *fmt, ...);
void cs_log_module_enable(enum CS_LOG_MODULE module);
void cs_log_module_disable(enum CS_LOG_MODULE module);
void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...);
// TS Routing
unsigned int cs_get_ts_output(void);
int cs_set_ts_output(unsigned int port);
// Serial nr and revision accessors
unsigned long long cs_get_serial(void);
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

320
include/cs_frontpanel.h Normal file
View File

@@ -0,0 +1,320 @@
#ifndef __DUCKBOX_VFD__
#define __DUCKBOX_VFD__
#define VFDDISPLAYCHARS 0xc0425a00
#define VFDWRITECGRAM 0x40425a01
#define VFDBRIGHTNESS 0xc0425a03
#define VFDPWRLED 0xc0425a04
#define VFDDRIVERINIT 0xc0425a08
#define VFDICONDISPLAYONOFF 0xc0425a0a
#define VFDDISPLAYWRITEONOFF 0xc0425a05
#define VFDCLEARICONS 0xc0425af6
#define VFDSETRF 0xc0425af7
#define VFDSETFAN 0xc0425af8
#define VFDGETWAKEUPMODE 0xc0425af9
#define VFDGETTIME 0xc0425afa
#define VFDSETTIME 0xc0425afb
#define VFDSTANDBY 0xc0425afc
#define VFDREBOOT 0xc0425afd
#define VFDSETLED 0xc0425afe
#define VFDSETMODE 0xc0425aff
#define VFDGETWAKEUPTIME 0xc0425b00
#define VFDGETVERSION 0xc0425b01
#define VFDSETDISPLAYTIME 0xc0425b02
#define VFDSETTIMEMODE 0xc0425b03
#define VFDDISPLAYCLR 0xc0425b00
typedef enum {
#if defined(BOXMODEL_OCTAGON1008)
ICON_DOLBY = 0x10,
ICON_DTS,
ICON_VIDEO,
ICON_AUDIO,
ICON_LINK,
ICON_HDD,
ICON_DISC,
ICON_DVB,
ICON_DVD,
ICON_TIME,
ICON_TIMER,
ICON_CARD,
ICON_1,
ICON_2,
ICON_KEY,
ICON_16_9,
ICON_USB,
ICON_CRYPTED,
ICON_PLAY,
ICON_REWIND,
ICON_PAUSE,
ICON_FF,
ICON_REC,
ICON_ARROW,
ICON_COLON1,
ICON_COLON2,
ICON_COLON3,
ICON_MAX,
FP_ICON_USB = ICON_USB,
FP_ICON_HD = ICON_16_9,
FP_ICON_HDD = ICON_HDD,
FP_ICON_LOCK = ICON_CRYPTED,
FP_ICON_BT,
FP_ICON_MP3,
FP_ICON_MUSIC,
FP_ICON_DD = ICON_DOLBY,
FP_ICON_MAIL,
FP_ICON_MUTE = ICON_TIME,
FP_ICON_PLAY = ICON_PLAY,
FP_ICON_PAUSE = ICON_PAUSE,
FP_ICON_FF = ICON_FF,
FP_ICON_FR = ICON_REWIND,
FP_ICON_REC = ICON_REC,
FP_ICON_CLOCK = ICON_TIMER,
FP_ICON_RADIO = ICON_AUDIO,
FP_ICON_TV = ICON_VIDEO,
FP_ICON_DOWNLOAD = ICON_LINK,
FP_ICON_CAM1 = ICON_REC,
#elif defined(BOXMODEL_FORTIS_HDBOX)
ICON_USB = 0x10,
ICON_STANDBY,
ICON_SAT,
ICON_REC,
ICON_TIMESHIFT,
ICON_TIMER,
ICON_HD,
ICON_SCRAMBLED,
ICON_DOLBY,
ICON_MUTE,
ICON_TUNER1,
ICON_TUNER2,
ICON_MP3,
ICON_REPEAT,
ICON_Play,
ICON_TER,
ICON_FILE,
ICON_480i,
ICON_480p,
ICON_576i,
ICON_576p,
ICON_720p,
ICON_1080i,
ICON_1080p,
ICON_Circ0,
ICON_Circ1,
ICON_Circ2,
ICON_Circ3,
ICON_Circ4,
ICON_Circ5,
ICON_Circ6,
ICON_Circ7,
ICON_Circ8,
ICON_COLON1,
ICON_COLON2,
ICON_COLON3,
ICON_COLON4,
ICON_TV,
ICON_RADIO,
ICON_MAX,
FP_ICON_USB = ICON_USB,
FP_ICON_REC = ICON_REC,
FP_ICON_CAM1 = ICON_REC,
FP_ICON_TIMESHIFT = ICON_TIMESHIFT,
FP_ICON_CLOCK = ICON_TIMER,
FP_ICON_HD = ICON_HD,
FP_ICON_LOCK = ICON_SCRAMBLED,
FP_ICON_DD = ICON_DOLBY,
FP_ICON_MUTE = ICON_MUTE,
FP_ICON_BT = 0,
FP_ICON_MP3 = ICON_MP3,
FP_ICON_PLAY = ICON_Play,
FP_ICON_PAUSE = 0,
FP_ICON_HDD = 0,
FP_ICON_MAIL = 0,
FP_ICON_FF = 0,
FP_ICON_FR = 0,
FP_ICON_RADIO = ICON_RADIO,
FP_ICON_TV = ICON_TV,
FP_ICON_MUSIC = ICON_RADIO,
FP_ICON_MAX = ICON_MAX
#elif defined(BOXMODEL_UFS910) || defined(BOXMODEL_UFS922) || defined(BOXMODEL_UFS912) || defined(BOXMODEL_UFS913)
FP_ICON_USB = 0x10,
FP_ICON_HD,
FP_ICON_HDD,
FP_ICON_LOCK,
FP_ICON_BT,
FP_ICON_MP3,
FP_ICON_MUSIC,
FP_ICON_DD,
FP_ICON_MAIL,
FP_ICON_MUTE,
FP_ICON_PLAY,
FP_ICON_PAUSE,
FP_ICON_FF,
FP_ICON_FR,
FP_ICON_REC,
FP_ICON_CLOCK,
FP_ICON_MAX,
FP_ICON_CAM1 = FP_ICON_REC,
FP_ICON_TV = 0,
FP_ICON_RADIO = FP_ICON_MUSIC,
FP_ICON_RECORD = FP_ICON_REC,
FP_ICON_DOWNLOAD = 0,
FP_ICON_TIMESHIFT = 0
#elif defined(BOXMODEL_IPBOX9900) || defined(BOXMODEL_IPBOX99)
ICON_STANDBY,
ICON_SAT,
ICON_REC,
ICON_TIMESHIFT,
ICON_TIMER,
ICON_HD,
ICON_SCRAMBLED,
ICON_MUTE,
ICON_TUNER1,
ICON_TUNER2,
ICON_MP3,
ICON_REPEAT,
ICON_PLAY,
ICON_PAUSE,
ICON_TER,
ICON_FILE,
ICON_480I,
ICON_480P,
ICON_576I,
ICON_576P,
ICON_720P,
ICON_1080I,
ICON_1080P,
ICON_TV,
ICON_RADIO,
ICON_MAX,
FP_ICON_480P = ICON_480P,
FP_ICON_480I = ICON_480I,
FP_ICON_576P = ICON_576P,
FP_ICON_576I = ICON_576I,
FP_ICON_PLAY = ICON_PLAY,
FP_ICON_PAUSE = ICON_PAUSE,
FP_ICON_1080P = 0x0A,
FP_ICON_1080I = 0x09,
FP_ICON_720P = 0x08,
FP_ICON_POWER = 0x00,
FP_ICON_HD = 0x05,
FP_ICON_RADIO = 0x0D,
FP_ICON_MP3 = FP_ICON_RADIO,
FP_ICON_MUSIC = FP_ICON_RADIO,
FP_ICON_DD = 0x04,
FP_ICON_REC = 0x03,
FP_ICON_FF = 0,
FP_ICON_FR = 0,
FP_ICON_USB = 0,
FP_ICON_HDD = 0,
FP_ICON_MUTE = 0,
FP_ICON_CLOCK = 0,
FP_ICON_CAM1 = 0,
FP_ICON_LOCK = 0,
FP_ICON_DOWNLOAD = 0,
FP_ICON_TIMESHIFT = FP_ICON_REC,
FP_ICON_TV = 0,
FP_ICON_MAIL = 0,
FP_ICON_BT = 0,
#else
FP_ICON_USB = 0x10,
FP_ICON_HD,
FP_ICON_HDD,
FP_ICON_LOCK,
FP_ICON_BT,
FP_ICON_MP3,
FP_ICON_MUSIC,
FP_ICON_DD,
FP_ICON_MAIL,
FP_ICON_MUTE,
FP_ICON_PLAY,
FP_ICON_PAUSE,
FP_ICON_FF,
FP_ICON_FR,
FP_ICON_REC,
FP_ICON_CLOCK,
FP_ICON_CAM1 = FP_ICON_REC,
FP_ICON_TV = FP_ICON_MUSIC,
FP_ICON_RADIO = FP_ICON_MUSIC,
FP_ICON_RECORD = FP_ICON_REC,
FP_ICON_DOWNLOAD,
FP_ICON_TIMESHIFT,
#endif
#if !defined(BOXMODEL_UFS910) && !defined(BOXMODEL_UFS922) && !defined(BOXMODEL_UFS912) && !defined(BOXMODEL_UFS913) && !defined(BOXMODEL_FORTIS_HDBOX)
FP_ICON_MAX
#endif
} fp_icon;
typedef enum {
FP_FLAG_NONE = 0x00,
FP_FLAG_SCROLL_ON = 0x01, /* switch scrolling on */
FP_FLAG_SCROLL_LTR = 0x02, /* scroll from left to rightinstead of default right to left direction (i.e. for arabic text) */
FP_FLAG_SCROLL_SIO = 0x04, /* start/stop scrolling with empty screen (scroll in/out) */
FP_FLAG_SCROLL_DELAY = 0x08, /* delayed scroll start */
FP_FLAG_ALIGN_LEFT = 0x10, /* align the text in display from the left (default) */
FP_FLAG_ALIGN_RIGHT = 0x20, /* align the text in display from the right (arabic) */
FP_FLAG_UPDATE_SCROLL_POS = 0x40, /* update the current position for scrolling */
} fp_flag;
typedef struct {
unsigned char brightness;
unsigned char flags;
unsigned char current_hour;
unsigned char current_minute;
unsigned char timer_minutes_hi;
unsigned char timer_minutes_lo;
} fp_standby_data_t;
typedef enum {
FP_LED_1_ON = 0x81,
FP_LED_2_ON = 0x82,
FP_LED_3_ON = 0x83,
FP_LED_1_OFF = 0x01,
FP_LED_2_OFF = 0x02,
FP_LED_3_OFF = 0x03,
} fp_led_ctrl_t;
typedef struct {
unsigned char source;
unsigned char time_minutes_hi;
unsigned char time_minutes_lo;
} fp_wakeup_data_t;
typedef enum {
FP_WAKEUP_SOURCE_TIMER = 0x01,
FP_WAKEUP_SOURCE_BUTTON = 0x02,
FP_WAKEUP_SOURCE_REMOTE = 0x04,
FP_WAKEUP_SOURCE_PWLOST = 0x7F,
FP_WAKEUP_SOURCE_POWER = 0xFF
} fp_wakeup_source;
typedef struct {
unsigned short addr;
unsigned short cmd;
} fp_standby_cmd_data_t;
typedef enum {
FP_DISPLAY_TEXT_NONE = 0,
FP_DISPLAY_TEXT_LIMITED,
FP_DISPLAY_TEXT_ALL,
} fp_display_text_type_t;
typedef enum {
FP_DISPLAY_TYPE_NONE = 0,
FP_DISPLAY_TYPE_VFD,
FP_DISPLAY_TYPE_OLED,
FP_DISPLAY_TYPE_LED_SEGMENT
} fp_display_type_t;
typedef struct {
fp_display_type_t display_type;
unsigned short xres, yres;
unsigned int segment_count;
fp_display_text_type_t text_support;
bool number_support;
} fp_display_caps_t;
#endif /* __DUCKBOX_VFD__ */

View File

@@ -1,97 +1,20 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __dmx_hal__
#define __dmx_hal__
#include <cstdlib>
#include <vector>
#include <inttypes.h>
/* at least on td, config.h needs to be included before... */
#ifndef HAVE_TRIPLEDRAGON
#include <linux/dvb/dmx.h>
#else /* TRIPLEDRAGON */
extern "C" {
#include <hardware/xp/xp_osd_user.h>
}
#if defined DMX_FILTER_SIZE
#undef DMX_FILTER_SIZE
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/dmx_td.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/dmx_lib.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/dmx_lib.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/dmx_lib.h"
#elif HAVE_ARM_HARDWARE
#include "../libarmbox/dmx_lib.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/dmx_lib.h"
#else
#include "../generic-pc/dmx_lib.h"
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif
#define DMX_FILTER_SIZE FILTER_LENGTH
#endif /* TRIPLEDRAGON */
#include <cs_types.h>
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cRecord;
class cPlayback;
class cDemux
{
friend class cRecord;
friend class cPlayback;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
cDemux(int num = 0);
~cDemux();
int getFD(void) { return fd; }; /* needed by cPlayback class */
private:
void removePid(unsigned short Pid); /* needed by cRecord class */
int num;
int fd;
int buffersize;
uint16_t pid;
uint8_t flt;
std::vector<pes_pids> pesfds;
DMX_CHANNEL_TYPE dmx_type;
void *pdata;
};
#endif //__dmx_hal__

View File

@@ -1,42 +1,10 @@
/*
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __glfb__
#define __glfb__
#include <OpenThreads/Thread>
#include <vector>
#include <linux/fb.h> /* for screeninfo etc. */
class GLFramebuffer : public OpenThreads::Thread
{
public:
GLFramebuffer(int x, int y);
~GLFramebuffer();
std::vector<unsigned char> *getOSDBuffer() { return &osd_buf; } /* pointer to OSD bounce buffer */
void blit();
fb_var_screeninfo getScreenInfo() { return si; }
private:
fb_var_screeninfo si;
std::vector<unsigned char> osd_buf; /* silly bounce buffer */
void run(); /* for OpenThreads::Thread */
void setup();
void blit_osd();
void *pdata; /* not yet used */
};
#include <config.h>
#if HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/glfb.h"
#else
#include "../generic-pc/glfb.h"
#endif
#else
#error glfb.h only works with HAVE_GENERIC_HARDWARE defined
#endif

View File

@@ -36,13 +36,14 @@ typedef struct hw_caps
display_type_t display_type;
int display_xres; /* x resolution or chars per line */
int display_yres;
int display_can_deepstandby;
int display_can_set_brightness;
int display_can_deepstandby;
int display_has_statusline;
int has_button_vformat;
char boxvendor[64];
char boxname[64];
char boxarch[64];
int boxtype;
int has_CI;
} hw_caps_t;
hw_caps_t *get_hwcaps(void);

View File

@@ -5,7 +5,30 @@
#define MAX_MMI_TEXT_LEN 255
#define MAX_MMI_CHOICE_TEXT_LEN 255
typedef enum {
MMI_TOP_MENU_SUBS = 1,
MMI_TOP_MENU_EVENTS,
MMI_TOP_MENU_TOKENS,
MMI_TOP_MENU_PIN,
MMI_TOP_MENU_MATURE,
MMI_TOP_MENU_ABOUT
} MMI_MENU_CURRENT;
typedef enum {
MMI_MENU_LEVEL_MAIN = 0,
MMI_MENU_LEVEL_MATURE,
MMI_MENU_LEVEL_ASK_PIN_MATURE
} MMI_MENU_LEVEL;
typedef enum {
MMI_PIN_LEVEL_ASK_OLD = 0,
MMI_PIN_LEVEL_CHECK_CURRENT,
MMI_PIN_LEVEL_ASK_REPEAT,
MMI_PIN_LEVEL_CHECK_AND_CHANGE
} MMI_PIN_LEVEL;
typedef struct {
int slot;
int choice_nb;
char title[MAX_MMI_TEXT_LEN];
char subtitle[MAX_MMI_TEXT_LEN];
@@ -14,6 +37,7 @@ typedef struct {
} MMI_MENU_LIST_INFO;
typedef struct {
int slot;
int blind;
int answerlen;
char enquiryText[MAX_MMI_TEXT_LEN];

View File

@@ -0,0 +1,25 @@
#ifndef _MUTEX_ABSTRACTION_H
#define _MUTEX_ABSTRACTION_H
#include <pthread.h>
class Mutex
{
friend class Condition;
pthread_mutex_t mMutex;
Mutex(const Mutex&);
const Mutex& operator=(const Mutex&);
protected:
explicit Mutex(int);
public:
Mutex();
virtual ~Mutex();
virtual void lock();
virtual void unlock();
};
#endif

View File

@@ -1 +1,2 @@
#include <config.h>
#include "playback_hal.h"

View File

@@ -1,82 +1,28 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __playback_hal__
#define __playback_hal__
#include <string>
#include <stdint.h>
#include <vector>
extern "C" {
#include <libavformat/avformat.h>
}
/*
* This is actually the max number that could be returned by
* FindAllPids() / FindAllSubs().
* not yet implemented, most archs return max. 10 PIDs.
*/
#define MAX_PLAYBACK_PIDS 40
typedef enum {
PLAYMODE_TS = 0,
PLAYMODE_FILE,
} playmode_t;
class PBPrivate;
class cPlayback
{
public:
bool Open(playmode_t PlayMode);
void Close(void);
bool Start(char *filename, unsigned short vpid, int vtype, unsigned short apid, int ac3, unsigned int duration);
bool Start(std::string filename, std::string headers = "");
bool Stop(void);
bool SetAPid(unsigned short pid, int audio_flag);
bool SetSpeed(int speed);
bool GetSpeed(int &speed) const;
bool GetPosition(int &position, int &duration);
bool SetPosition(int position, bool absolute = false);
void FindAllPids(uint16_t *pids, unsigned short *aud_flags, uint16_t *num, std::string *language);
void FindAllPids(int *apids, unsigned int *ac3flags, uint32_t *numpida, std::string *language){FindAllPids((uint16_t*)apids, (unsigned short*)ac3flags, (uint16_t*) numpida, language);}
void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *num, std::string *language);
bool SelectSubtitles(int pid, std::string charset = "");
void GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
void RequestAbort();
void GetTitles(std::vector<int> &playlists, std::vector<std::string> &titles, int &current);
void SetTitle(int title);
uint64_t GetReadCount(void);
void FindAllTeletextsubtitlePids(int *, unsigned int *numpids, std::string *, int *, int *){*numpids = 0;}
void FindAllSubtitlePids(int * /*pids*/, unsigned int *numpids, std::string * /*language*/){*numpids = 0;}
int GetSubtitlePid(void){return 0;}
bool SetTeletextPid(int /*pid*/){return true;}
int GetAPid(){return 0;}
void GetMetadata(std::vector<std::string> /*&keys*/, std::vector<std::string> /*&values*/){}
void GetPts(uint64_t &/*pts*/){}
bool SetSubtitlePid(int /*pid*/){return false;}
AVFormatContext *GetAVFormatContext(){return NULL;}
void ReleaseAVFormatContext(){}
//
cPlayback(int num = 0);
~cPlayback();
private:
PBPrivate *pd;
};
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/playback_td.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/playback_libeplayer3.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/playback_libeplayer3.h"
#elif HAVE_ARM_HARDWARE
#if ENABLE_GSTREAMER_10
#include "../libarmbox/playback_gst.h"
#else
#include "../libarmbox/playback_libeplayer3.h"
#endif
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/playback.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/playback.h"
#else
#if ENABLE_GSTREAMER
#include "../generic-pc/playback_gst.h"
#else
#include "../generic-pc/playback.h"
#endif
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif

View File

@@ -1,47 +1,20 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __pwrmngr_hal__
#define __pwrmngr_hal__
class cCpuFreqManager
{
public:
cCpuFreqManager(void);
void Up(void);
void Down(void);
void Reset(void);
bool SetCpuFreq(unsigned long CpuFreq);
bool SetDelta(unsigned long Delta);
unsigned long GetCpuFreq(void);
unsigned long GetDelta(void);
};
class cPowerManager
{
public:
cPowerManager(void);
virtual ~cPowerManager();
bool Open(void);
void Close(void);
bool SetStandby(bool Active, bool Passive);
};
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/pwrmngr.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/pwrmngr.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/pwrmngr.h"
#elif HAVE_ARM_HARDWARE
#include "../libarmbox/pwrmngr.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/pwrmngr.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/pwrmngr.h"
#else
#include "../generic-pc/pwrmngr.h"
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif

View File

@@ -1,41 +1,20 @@
/*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __record_hal__
#define __record_hal__
#define REC_STATUS_OK 0
#define REC_STATUS_SLOW 1
#define REC_STATUS_OVERFLOW 2
class RecData;
class cRecord
{
public:
cRecord(int num = 0);
~cRecord();
bool Open();
bool Start(int fd, unsigned short vpid, unsigned short *apids, int numapids, uint64_t ch = 0);
bool Stop(void);
bool AddPid(unsigned short pid);
int GetStatus();
void ResetStatus();
bool ChangePids(unsigned short vpid, unsigned short *apids, int numapids);
private:
RecData *pd;
};
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/record_td.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/record_lib.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/record_lib.h"
#elif HAVE_ARM_HARDWARE
#include "../libarmbox/record_lib.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/record_lib.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/record_lib.h"
#else
#include "../generic-pc/record_lib.h"
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif

16
include/reentrant_mutex.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef _REENTRANT_MUTEX_H
#define _REENTRANT_MUTEX_H
#include "mutex_abstraction.h"
class ReentrantMutex : public Mutex
{
ReentrantMutex(const ReentrantMutex&);
const ReentrantMutex& operator=(const ReentrantMutex&);
public:
ReentrantMutex();
virtual ~ReentrantMutex();
};
#endif

18
include/scoped_lock.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _SCOPED_LOCK_H
#define _SCOPED_LOCK_H
#include "mutex_abstraction.h"
class ScopedLock
{
Mutex& mMutex;
ScopedLock(const ScopedLock&);
const ScopedLock& operator=(const ScopedLock&);
public:
ScopedLock(Mutex&);
~ScopedLock();
};
#endif

View File

@@ -0,0 +1,30 @@
#ifndef _THREAD_ABSTRACTION_H
#define _THREAD_ABSTRACTION_H
#include <pthread.h>
class Thread
{
bool mIsRunning;
pthread_t mThread;
static void* runThread(void*);
Thread(const Thread&);
const Thread& operator=(const Thread&);
public:
Thread();
virtual ~Thread();
int startThread();
int cancelThread();
int detachThread();
int joinThread();
int setCancelModeDisable();
int setSchedulePriority(int);
protected:
virtual void run() = 0;
};
#endif

View File

@@ -1,22 +0,0 @@
#ifndef __VERSION_HAL_H__
#define __VERSION_HAL_H__
#include <string>
// library version functions
typedef struct hal_libversion_t
{
std::string vVersion;
int vMajor;
int vMinor;
int vPatch;;
std::string vName;
std::string vStr;
std::string vGitDescribe;
} hal_libversion_struct_t;
void hal_get_lib_version(hal_libversion_t *ver);
#endif //__VERSION_HAL_H__

View File

@@ -1,213 +1,24 @@
/*
Copyright 2010-2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _VIDEO_LIB_H
#define _VIDEO_LIB_H
#include <vector>
#include <cs_types.h>
typedef enum {
ANALOG_SD_RGB_CINCH = 0x00,
ANALOG_SD_YPRPB_CINCH,
ANALOG_HD_RGB_CINCH,
ANALOG_HD_YPRPB_CINCH,
ANALOG_SD_RGB_SCART = 0x10,
ANALOG_SD_YPRPB_SCART,
ANALOG_HD_RGB_SCART,
ANALOG_HD_YPRPB_SCART,
ANALOG_SCART_MASK = 0x10
} analog_mode_t;
typedef enum {
VIDEO_FORMAT_MPEG2 = 0,
VIDEO_FORMAT_MPEG4, /* H264 */
VIDEO_FORMAT_VC1,
VIDEO_FORMAT_JPEG,
VIDEO_FORMAT_GIF,
VIDEO_FORMAT_PNG,
VIDEO_FORMAT_DIVX,/* DIVX 3.11 */
VIDEO_FORMAT_MPEG4PART2,/* MPEG4 SVH, MPEG4 SP, MPEG4 ASP, DIVX4,5,6 */
VIDEO_FORMAT_REALVIDEO8,
VIDEO_FORMAT_REALVIDEO9,
VIDEO_FORMAT_ON2_VP6,
VIDEO_FORMAT_ON2_VP8,
VIDEO_FORMAT_SORENSON_SPARK,
VIDEO_FORMAT_H263,
VIDEO_FORMAT_H263_ENCODER,
VIDEO_FORMAT_H264_ENCODER,
VIDEO_FORMAT_MPEG4PART2_ENCODER,
VIDEO_FORMAT_AVS,
VIDEO_FORMAT_VIP656,
VIDEO_FORMAT_UNSUPPORTED
} VIDEO_FORMAT;
typedef enum {
VIDEO_SD = 0,
VIDEO_HD,
VIDEO_120x60i,
VIDEO_320x240i,
VIDEO_1440x800i,
VIDEO_360x288i
} VIDEO_DEFINITION;
typedef enum {
VIDEO_FRAME_RATE_23_976 = 0,
VIDEO_FRAME_RATE_24,
VIDEO_FRAME_RATE_25,
VIDEO_FRAME_RATE_29_97,
VIDEO_FRAME_RATE_30,
VIDEO_FRAME_RATE_50,
VIDEO_FRAME_RATE_59_94,
VIDEO_FRAME_RATE_60
} VIDEO_FRAME_RATE;
typedef enum {
DISPLAY_AR_1_1,
DISPLAY_AR_4_3,
DISPLAY_AR_14_9,
DISPLAY_AR_16_9,
DISPLAY_AR_20_9,
DISPLAY_AR_RAW,
} DISPLAY_AR;
typedef enum {
DISPLAY_AR_MODE_PANSCAN = 0,
DISPLAY_AR_MODE_LETTERBOX,
DISPLAY_AR_MODE_NONE,
DISPLAY_AR_MODE_PANSCAN2
} DISPLAY_AR_MODE;
typedef enum {
VIDEO_DB_DR_NEITHER = 0,
VIDEO_DB_ON,
VIDEO_DB_DR_BOTH
} VIDEO_DB_DR;
typedef enum {
VIDEO_PLAY_STILL = 0,
VIDEO_PLAY_CLIP,
VIDEO_PLAY_TRICK,
VIDEO_PLAY_MOTION,
VIDEO_PLAY_MOTION_NO_SYNC
} VIDEO_PLAY_MODE;
typedef enum {
VIDEO_STD_NTSC,
VIDEO_STD_SECAM,
VIDEO_STD_PAL,
VIDEO_STD_480P,
VIDEO_STD_576P,
VIDEO_STD_720P60,
VIDEO_STD_1080I60,
VIDEO_STD_720P50,
VIDEO_STD_1080I50,
VIDEO_STD_1080P30,
VIDEO_STD_1080P24,
VIDEO_STD_1080P25,
VIDEO_STD_1080P50,
VIDEO_STD_1080P60,
VIDEO_STD_AUTO,
VIDEO_STD_MAX
} VIDEO_STD;
/* not used, for dummy functions */
typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER,
VIDEO_HDMI_CEC_MODE_RECORDER
} VIDEO_HDMI_CEC_MODE;
typedef enum
{
VIDEO_CONTROL_BRIGHTNESS = 0,
VIDEO_CONTROL_CONTRAST,
VIDEO_CONTROL_SATURATION,
VIDEO_CONTROL_HUE,
VIDEO_CONTROL_SHARPNESS,
VIDEO_CONTROL_MAX = VIDEO_CONTROL_SHARPNESS
} VIDEO_CONTROL;
class cDemux;
class cPlayback;
class VDec;
class cVideo
{
friend class cPlayback;
friend class cDemux;
public:
/* constructor & destructor */
cVideo(int mode, void *, void *, unsigned int unit = 0);
~cVideo(void);
void * GetTVEnc() { return NULL; };
void * GetTVEncSD() { return NULL; };
/* aspect ratio */
int getAspectRatio(void);
void getPictureInfo(int &width, int &height, int &rate);
int setAspectRatio(int aspect, int mode);
/* cropping mode */
int setCroppingMode(void);
/* get play state */
int getPlayState(void);
/* blank on freeze */
int getBlank(void);
int setBlank(int enable);
/* change video play state. Parameters are all unused. */
int Start(void *PcrChannel = NULL, unsigned short PcrPid = 0, unsigned short VideoPid = 0, void *x = NULL);
int Stop(bool blank = true);
bool Pause(void);
int GetVideoSystem();
/* set video_system */
int SetVideoSystem(int video_system, bool remember = true);
int SetStreamType(VIDEO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE mode);
bool SetCECMode(VIDEO_HDMI_CEC_MODE) { return true; };
void SetCECAutoView(bool) { return; };
void SetCECAutoStandby(bool) { return; };
bool ShowPicture(const char * fname);
void StopPicture();
void Standby(unsigned int bOn);
void Pig(int x, int y, int w, int h, int osd_w = 1064, int osd_h = 600);
void SetControl(int, int) { return; };
void setContrast(int val);
void SetVideoMode(analog_mode_t mode);
void SetDBDR(int) { return; };
void SetAudioHandle(void *) { return; };
void SetAutoModes(int [VIDEO_STD_MAX]) { return; };
int OpenVBI(int) { return 0; };
int CloseVBI(void) { return 0; };
int StartVBI(unsigned short) { return 0; };
int StopVBI(void) { return 0; };
void SetDemux(cDemux *dmx);
bool GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video = true, bool get_osd = false, bool scale_to_video = false);
private:
VDec *vdec;
void *pdata;
};
#include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/video_td.h"
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/video_lib.h"
#elif HAVE_SPARK_HARDWARE
#include "../libspark/video_lib.h"
#elif HAVE_ARM_HARDWARE
#include "../libarmbox/video_lib.h"
#elif HAVE_AZBOX_HARDWARE
#include "../azbox/video_lib.h"
#elif HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/video_lib.h"
#else
#include "../generic-pc/video_lib.h"
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif
#if STB_HAL_VIDEO_HAS_GETSCREENIMAGE
#define SCREENSHOT 1
#endif

44
libarmbox/Makefile.am Normal file
View File

@@ -0,0 +1,44 @@
noinst_LTLIBRARIES = libarmbox.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
AM_CPPFLAGS += \
-I$(top_srcdir)/common \
-I$(top_srcdir)/include
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \
-lOpenThreads \
@AVFORMAT_LIBS@ \
@AVUTIL_LIBS@ \
@AVCODEC_LIBS@ \
@SWRESAMPLE_LIBS@ \
-lpthread -lasound -lrt
libarmbox_la_SOURCES = \
hardware_caps.c \
dmx.cpp \
video.cpp \
audio.cpp \
init.cpp \
pwrmngr.cpp \
record.cpp
if ENABLE_GSTREAMER_10
libarmbox_la_SOURCES += \
playback_gst.cpp
AM_LDFLAGS += \
-lgstreamer-1.0 \
-lgsttag-1.0 \
-lgstmpegts-1.0
else
libarmbox_la_SOURCES += \
playback_libeplayer3.cpp
AM_CPPFLAGS += \
-I$(top_srcdir)/libeplayer3-arm/include
AM_LDFLAGS += \
-lass
endif

415
libarmbox/audio.cpp Normal file
View File

@@ -0,0 +1,415 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/dvb/audio.h>
#include <proc_tools.h>
#include "audio_lib.h"
//#include "audio_mixer.h"
#include "lt_debug.h"
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_AUDIO, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_AUDIO, this, args)
#include <linux/soundcard.h>
cAudio * audioDecoder = NULL;
cAudio::cAudio(void *, void *, void *)
{
fd = -1;
clipfd = -1;
mixer_fd = -1;
openDevice();
Muted = false;
}
cAudio::~cAudio(void)
{
closeDevice();
}
void cAudio::openDevice(void)
{
if (fd < 0)
{
if ((fd = open(AUDIO_DEVICE, O_RDWR)) < 0)
lt_info("openDevice: open failed (%m)\n");
fcntl(fd, F_SETFD, FD_CLOEXEC);
do_mute(true, false);
}
else
lt_info("openDevice: already open (fd = %d)\n", fd);
}
void cAudio::closeDevice(void)
{
if (fd > -1) {
close(fd);
fd = -1;
}
if (clipfd > -1) {
close(clipfd);
clipfd = -1;
}
if (mixer_fd > -1) {
close(mixer_fd);
mixer_fd = -1;
}
}
int cAudio::do_mute(bool enable, bool remember)
{
lt_debug("%s(%d, %d)\n", __FUNCTION__, enable, remember);
char str[4];
if (remember)
Muted = enable;
sprintf(str, "%d", Muted);
proc_put("/proc/stb/audio/j1_mute", str, strlen(str));
if (!enable)
{
int f = open("/proc/stb/avs/0/volume", O_RDWR);
read(f, str, 4);
close(f);
str[3] = '\0';
proc_put("/proc/stb/avs/0/volume", str, strlen(str));
}
return 0;
}
int map_volume(const int volume)
{
unsigned char vol = volume;
if (vol > 100)
vol = 100;
vol = 63 - vol * 63 / 100;
return vol;
}
int cAudio::setVolume(unsigned int left, unsigned int right)
{
lt_debug("%s(%d, %d)\n", __func__, left, right);
volume = (left + right) / 2;
int v = map_volume(volume);
#if 0
if (clipfd != -1 && mixer_fd != -1) {
int tmp = 0;
/* not sure if left / right is correct here, but it is always the same anyways ;-) */
if (! Muted)
tmp = left << 8 | right;
int ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp);
if (ret == -1)
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp);
return ret;
}
#endif
char str[4];
sprintf(str, "%d", v);
proc_put("/proc/stb/avs/0/volume", str, strlen(str));
return 0;
}
int cAudio::Start(void)
{
int ret;
ret = ioctl(fd, AUDIO_PLAY);
return ret;
}
int cAudio::Stop(void)
{
return ioctl(fd, AUDIO_STOP);
}
bool cAudio::Pause(bool Pcm)
{
ioctl(fd, Pcm ? AUDIO_PAUSE : AUDIO_CONTINUE, 1);
return true;
}
void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
{
lt_debug("%s %d\n", __func__, Mode);
ioctl(fd, AUDIO_SET_AV_SYNC, Mode);
}
// E2 streamtype values. These correspond to
// player2/linux/drivers/media/dvb/stm/dvb/dvb_audio.c:AudioIoctlSetBypassMode
#define AUDIO_STREAMTYPE_AC3 0
#define AUDIO_STREAMTYPE_MPEG 1
#define AUDIO_STREAMTYPE_DTS 2
#define AUDIO_STREAMTYPE_AAC 8
#define AUDIO_STREAMTYPE_AACHE 9
void cAudio::SetStreamType(AUDIO_FORMAT type)
{
int bypass = AUDIO_STREAMTYPE_MPEG;
lt_debug("%s %d\n", __FUNCTION__, type);
StreamType = type;
switch (type)
{
case AUDIO_FMT_DD_PLUS:
case AUDIO_FMT_DOLBY_DIGITAL:
bypass = AUDIO_STREAMTYPE_AC3;
break;
case AUDIO_FMT_AAC:
bypass = AUDIO_STREAMTYPE_AAC;
break;
case AUDIO_FMT_AAC_PLUS:
bypass = AUDIO_STREAMTYPE_AACHE;
break;
case AUDIO_FMT_DTS:
bypass = AUDIO_STREAMTYPE_DTS;
break;
default:
break;
}
// Normaly the encoding should be set using AUDIO_SET_ENCODING
// But as we implemented the behavior to bypass (cause of e2) this is correct here
if (ioctl(fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
lt_info("%s: AUDIO_SET_BYPASS_MODE failed (%m)\n", __func__);
}
int cAudio::setChannel(int channel)
{
lt_debug("%s %d\n", __FUNCTION__, channel);
return 0;
}
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
{
int fmt;
unsigned int devmask, stereo, usable;
const char *dsp_dev = getenv("DSP_DEVICE");
const char *mix_dev = getenv("MIX_DEVICE");
lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian);
if (clipfd > -1) {
lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd);
return -1;
}
mixer_num = -1;
/* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE
* if this device cannot be opened, we fall back to the internal OSS device
* Example:
* modprobe snd-usb-audio
* export DSP_DEVICE=/dev/sound/dsp2
* export MIX_DEVICE=/dev/sound/mixer2
* neutrino
*/
if ((!dsp_dev) || (access(dsp_dev, W_OK))) {
if (dsp_dev)
lt_info("%s: DSP_DEVICE is set (%s) but cannot be opened,"
" fall back to /dev/dsp\n", __func__, dsp_dev);
dsp_dev = "/dev/dsp";
}
if ((!mix_dev) || (access(mix_dev, W_OK))) {
if (mix_dev)
lt_info("%s: MIX_DEVICE is set (%s) but cannot be opened,"
" fall back to /dev/mixer\n", __func__, dsp_dev);
mix_dev = "/dev/mixer";
}
lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */
/* the tdoss dsp driver seems to work only on the second open(). really. */
clipfd = open(dsp_dev, O_WRONLY);
if (clipfd < 0) {
lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__);
return -1;
}
fcntl(clipfd, F_SETFD, FD_CLOEXEC);
/* no idea if we ever get little_endian == 0 */
if (little_endian)
fmt = AFMT_S16_BE;
else
fmt = AFMT_S16_LE;
if (ioctl(clipfd, SNDCTL_DSP_SETFMT, &fmt))
perror("SNDCTL_DSP_SETFMT");
if (ioctl(clipfd, SNDCTL_DSP_CHANNELS, &ch))
perror("SNDCTL_DSP_CHANNELS");
if (ioctl(clipfd, SNDCTL_DSP_SPEED, &srate))
perror("SNDCTL_DSP_SPEED");
if (ioctl(clipfd, SNDCTL_DSP_RESET))
perror("SNDCTL_DSP_RESET");
if (!mix_dev)
return 0;
mixer_fd = open(mix_dev, O_RDWR);
if (mixer_fd < 0) {
lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev);
/* not a real error */
return 0;
}
if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__);
devmask = 0;
}
if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) {
lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__);
stereo = 0;
}
usable = devmask & stereo;
if (usable == 0) {
lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n",
__func__, devmask, stereo);
close(mixer_fd);
mixer_fd = -1;
return 0; /* TODO: should we treat this as error? */
}
/* __builtin_popcount needs GCC, it counts the set bits... */
if (__builtin_popcount (usable) != 1) {
/* TODO: this code is not yet tested as I have only single-mixer devices... */
lt_info("%s: more than one mixer control: devmask %08x stereo %08x\n"
"%s: querying MIX_NUMBER environment variable...\n",
__func__, devmask, stereo, __func__);
const char *tmp = getenv("MIX_NUMBER");
if (tmp)
mixer_num = atoi(tmp);
lt_info("%s: mixer_num is %d -> device %08x\n",
__func__, mixer_num, (mixer_num >= 0) ? (1 << mixer_num) : 0);
/* no error checking, you'd better know what you are doing... */
} else {
mixer_num = 0;
while (!(usable & 0x01)) {
mixer_num++;
usable >>= 1;
}
}
setVolume(volume, volume);
return 0;
}
int cAudio::WriteClip(unsigned char *buffer, int size)
{
int ret;
// lt_debug("cAudio::%s\n", __FUNCTION__);
if (clipfd < 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1;
}
ret = write(clipfd, buffer, size);
if (ret < 0)
lt_info("%s: write error (%m)\n", __FUNCTION__);
return ret;
};
int cAudio::StopClip()
{
lt_debug("%s\n", __FUNCTION__);
if (clipfd < 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1;
}
close(clipfd);
clipfd = -1;
if (mixer_fd >= -1) {
close(mixer_fd);
mixer_fd = -1;
}
setVolume(volume, volume);
return 0;
};
void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &mode)
{
lt_debug("%s\n", __FUNCTION__);
type = 0;
layer = 0;
freq = 0;
bitrate = 0;
mode = 0;
#if 0
unsigned int atype;
static const int freq_mpg[] = {44100, 48000, 32000, 0};
static const int freq_ac3[] = {48000, 44100, 32000, 0};
scratchl2 i;
if (ioctl(fd, MPEG_AUD_GET_DECTYP, &atype) < 0)
perror("cAudio::getAudioInfo MPEG_AUD_GET_DECTYP");
if (ioctl(fd, MPEG_AUD_GET_STATUS, &i) < 0)
perror("cAudio::getAudioInfo MPEG_AUD_GET_STATUS");
type = atype;
#if 0
/* this does not work, some of the values are negative?? */
AMPEGStatus A;
memcpy(&A, &i.word00, sizeof(i.word00));
layer = A.audio_mpeg_layer;
mode = A.audio_mpeg_mode;
bitrate = A.audio_mpeg_bitrate;
switch(A.audio_mpeg_frequency)
#endif
/* layer and bitrate are not used anyway... */
layer = 0; //(i.word00 >> 17) & 3;
bitrate = 0; //(i.word00 >> 12) & 3;
switch (type)
{
case 0: /* MPEG */
mode = (i.word00 >> 6) & 3;
freq = freq_mpg[(i.word00 >> 10) & 3];
break;
case 1: /* AC3 */
mode = (i.word00 >> 28) & 7;
freq = freq_ac3[(i.word00 >> 16) & 3];
break;
default:
mode = 0;
freq = 0;
}
//fprintf(stderr, "type: %d layer: %d freq: %d bitrate: %d mode: %d\n", type, layer, freq, bitrate, mode);
#endif
};
void cAudio::SetSRS(int /*iq_enable*/, int /*nmgr_enable*/, int /*iq_mode*/, int /*iq_level*/)
{
lt_debug("%s\n", __FUNCTION__);
};
void cAudio::SetHdmiDD(bool enable)
{
const char *opt[] = { "downmix", "passthrough" };
lt_debug("%s %d\n", __func__, enable);
proc_put("/proc/stb/audio/ac3", opt[enable], strlen(opt[enable]));
}
void cAudio::SetSpdifDD(bool enable)
{
//using this function for dts passthrough
const char *opt[] = { "downmix", "passthrough" };
lt_debug("%s %d\n", __func__, enable);
proc_put("/proc/stb/audio/dts", opt[enable], strlen(opt[enable]));
}
void cAudio::ScheduleMute(bool On)
{
lt_debug("%s %d\n", __FUNCTION__, On);
}
void cAudio::EnableAnalogOut(bool enable)
{
lt_debug("%s %d\n", __FUNCTION__, enable);
}
#define AUDIO_BYPASS_ON 0
#define AUDIO_BYPASS_OFF 1
void cAudio::setBypassMode(bool disable)
{
int mode = disable ? AUDIO_BYPASS_OFF : AUDIO_BYPASS_ON;
if (ioctl(fd, AUDIO_SET_BYPASS_MODE, mode) < 0)
lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode);
}

100
libarmbox/audio_lib.h Normal file
View File

@@ -0,0 +1,100 @@
/* public header file */
#ifndef _AUDIO_TD_H_
#define _AUDIO_TD_H_
#include "../common/cs_types.h"
typedef enum
{
AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE;
typedef enum {
HDMI_ENCODED_OFF,
HDMI_ENCODED_AUTO,
HDMI_ENCODED_FORCED
} HDMI_ENCODED_MODE;
typedef enum
{
AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG,
AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS,
AUDIO_FMT_AVS,
AUDIO_FMT_MLP,
AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class mixerVolume;
class cAudio
{
friend class cPlayback;
private:
int fd;
bool Muted;
int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode;
bool started;
int volume;
int do_mute(bool enable, bool remember);
void setBypassMode(bool disable);
public:
/* construct & destruct */
cAudio(void *, void *, void *);
~cAudio(void);
void openDevice(void);
void closeDevice(void);
void *GetHandle() { return NULL; };
/* shut up */
int mute(bool remember = true) { return do_mute(true, remember); };
int unmute(bool remember = true) { return do_mute(false, remember); };
/* volume, min = 0, max = 255 */
int setVolume(unsigned int left, unsigned int right);
int getVolume(void) { return volume;}
bool getMuteStatus(void) { return Muted; };
/* start and stop audio */
int Start(void);
int Stop(void);
bool Pause(bool Pcm = true);
void SetStreamType(AUDIO_FORMAT type);
AUDIO_FORMAT GetStreamType(void) { return StreamType; }
void SetSyncMode(AVSYNC_TYPE Mode);
/* select channels */
int setChannel(int channel);
int PrepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian);
int WriteClip(unsigned char * buffer, int size);
int StopClip();
void getAudioInfo(int &type, int &layer, int& freq, int &bitrate, int &mode);
void SetSRS(int iq_enable, int nmgr_enable, int iq_mode, int iq_level);
bool IsHdmiDDSupported() { return true; };
void SetHdmiDD(bool enable);
void SetSpdifDD(bool enable);
void ScheduleMute(bool On);
void EnableAnalogOut(bool enable);
};
#endif

67
libarmbox/cs_api.h Normal file
View File

@@ -0,0 +1,67 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_lib.h"
typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
#if 0
enum CS_LOG_MODULE {
CS_LOG_CI = 0,
CS_LOG_HDMI_CEC,
CS_LOG_HDMI,
CS_LOG_VIDEO,
CS_LOG_VIDEO_DRM,
CS_LOG_AUDIO,
CS_LOG_DEMUX,
CS_LOG_DENC,
CS_LOG_PVR_RECORD,
CS_LOG_PVR_PLAY,
CS_LOG_POWER_CTRL,
CS_LOG_POWER_CLK,
CS_LOG_MEM,
CS_LOG_API,
};
#endif
inline void cs_api_init()
{
init_td_api();
};
inline void cs_api_exit()
{
shutdown_td_api();
};
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
void cs_register_messenger(cs_messenger messenger);
static inline void cs_deregister_messenger(void) { return; };
//cs_messenger cs_get_messenger(void);
#if 0
// Logging functions
void cs_log_enable(void);
void cs_log_disable(void);
void cs_log_message(const char *prefix, const char *fmt, ...);
void cs_log_module_enable(enum CS_LOG_MODULE module);
void cs_log_module_disable(enum CS_LOG_MODULE module);
void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...);
// TS Routing
unsigned int cs_get_ts_output(void);
int cs_set_ts_output(unsigned int port);
// Serial nr and revision accessors
unsigned long long cs_get_serial(void);
#endif
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

559
libarmbox/dmx.cpp Normal file
View File

@@ -0,0 +1,559 @@
/*
* cDemux implementation for arm receivers (tested on mutant hd51
* hardware)
*
* derived from libtriple/dmx_td.cpp
*
* (C) 2010-2013 Stefan Seyfried
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
#include <inttypes.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <string>
#include "dmx_lib.h"
#include "lt_debug.h"
#include "video_lib.h"
/* needed for getSTC... */
extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \
} while(0);
cDemux *videoDemux = NULL;
cDemux *audioDemux = NULL;
static const char *DMX_T[] = {
"DMX_INVALID",
"DMX_VIDEO",
"DMX_AUDIO",
"DMX_PES",
"DMX_PSI",
"DMX_PIP",
"DMX_TP",
"DMX_PCR"
};
/* this is the number of different cDemux() units, not the number of
* /dev/dvb/.../demuxX devices! */
#define NUM_DEMUX 4
/* the current source of each cDemux unit */
static int dmx_source[NUM_DEMUX] = { 0, 0, 0, 0 };
/* map the device numbers. */
#define NUM_DEMUXDEV 8
static const char *devname[NUM_DEMUXDEV] = {
"/dev/dvb/adapter0/demux0",
"/dev/dvb/adapter0/demux1",
"/dev/dvb/adapter0/demux2",
"/dev/dvb/adapter0/demux3",
"/dev/dvb/adapter0/demux4",
"/dev/dvb/adapter0/demux5",
"/dev/dvb/adapter0/demux6",
"/dev/dvb/adapter0/demux7"
};
/* did we already DMX_SET_SOURCE on that demux device? */
static bool init[NUM_DEMUXDEV] = { false, false, false, false, false, false, false, false };
cDemux::cDemux(int n)
{
if (n < 0 || n >= NUM_DEMUX)
{
lt_info("%s ERROR: n invalid (%d)\n", __FUNCTION__, n);
num = 0;
}
else
num = n;
fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
last_source = -1;
}
cDemux::~cDemux()
{
lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd);
Close();
}
bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize)
{
if (fd > -1)
lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd);
dmx_type = pes_type;
buffersize = uBufferSize;
/* return code is unchecked anyway... */
return true;
}
bool cDemux::_open(void)
{
int flags = O_RDWR|O_CLOEXEC;
int devnum = dmx_source[num];
if (last_source == devnum) {
lt_debug("%s #%d: source (%d) did not change\n", __func__, num, last_source);
if (fd > -1)
return true;
}
if (fd > -1) {
/* we changed source -> close and reopen the fd */
lt_debug("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n",
__func__, num, fd, last_source, devnum);
close(fd);
}
if (dmx_type != DMX_PSI_CHANNEL)
flags |= O_NONBLOCK;
fd = open(devname[devnum], flags);
if (fd < 0)
{
lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]);
return false;
}
lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__,
num, DMX_T[dmx_type], dmx_type, buffersize, fd);
/* this would actually need locking, but the worst that weill happen is, that
* we'll DMX_SET_SOURCE twice per device, so don't bother... */
if (!init[devnum])
{
/* this should not change anything... */
int n = DMX_SOURCE_FRONT0 + devnum;
lt_info("%s: setting %s to source %d\n", __func__, devname[devnum], n);
if (ioctl(fd, DMX_SET_SOURCE, &n) < 0)
lt_info("%s DMX_SET_SOURCE failed!\n", __func__);
else
init[devnum] = true;
}
if (buffersize == 0)
buffersize = 0xffff; // may or may not be reasonable --martii
if (buffersize > 0)
{
/* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */
if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0)
lt_info("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__);
}
last_source = devnum;
return true;
}
void cDemux::Close(void)
{
lt_debug("%s #%d, fd = %d\n", __FUNCTION__, num, fd);
if (fd < 0)
{
lt_info("%s #%d: not open!\n", __FUNCTION__, num);
return;
}
pesfds.clear();
ioctl(fd, DMX_STOP);
close(fd);
fd = -1;
if (measure)
return;
}
bool cDemux::Start(bool)
{
if (fd < 0)
{
lt_info("%s #%d: not open!\n", __FUNCTION__, num);
return false;
}
ioctl(fd, DMX_START);
return true;
}
bool cDemux::Stop(void)
{
if (fd < 0)
{
lt_info("%s #%d: not open!\n", __FUNCTION__, num);
return false;
}
ioctl(fd, DMX_STOP);
return true;
}
int cDemux::Read(unsigned char *buff, int len, int timeout)
{
#if 0
if (len != 4095 && timeout != 10)
fprintf(stderr, "cDemux::%s #%d fd: %d type: %s len: %d timeout: %d\n",
__FUNCTION__, num, fd, DMX_T[dmx_type], len, timeout);
#endif
if (fd < 0)
{
lt_info("%s #%d: not open!\n", __func__, num);
return -1;
}
int rc;
int to = timeout;
struct pollfd ufds;
ufds.fd = fd;
ufds.events = POLLIN|POLLPRI|POLLERR;
ufds.revents = 0;
/* hack: if the frontend loses and regains lock, the demuxer often will not
* return from read(), so as a "emergency exit" for e.g. NIT scan, set a (long)
* timeout here */
if (dmx_type == DMX_PSI_CHANNEL && timeout <= 0)
to = 60 * 1000;
if (to > 0)
{
retry:
rc = ::poll(&ufds, 1, to);
if (!rc)
{
if (timeout == 0) /* we took the emergency exit */
{
dmx_err("timed out for timeout=0!, %s", "", 0);
return -1; /* this timeout is an error */
}
return 0; // timeout
}
else if (rc < 0)
{
dmx_err("poll: %s,", strerror(errno), 0)
//lt_info("%s poll: %m\n", __FUNCTION__);
/* happens, when running under gdb... */
if (errno == EINTR)
goto retry;
return -1;
}
#if 0
if (ufds.revents & POLLERR) /* POLLERR means buffer error, i.e. buffer overflow */
{
dmx_err("received %s,", "POLLERR", ufds.revents);
/* this seems to happen sometimes at recording start, without bad effects */
return 0;
}
#endif
if (ufds.revents & POLLHUP) /* we get POLLHUP if e.g. a too big DMX_BUFFER_SIZE was set */
{
dmx_err("received %s,", "POLLHUP", ufds.revents);
return -1;
}
if (!(ufds.revents & POLLIN)) /* we requested POLLIN but did not get it? */
{
dmx_err("received %s, please report!", "POLLIN", ufds.revents);
return 0;
}
}
rc = ::read(fd, buff, len);
//fprintf(stderr, "fd %d ret: %d\n", fd, rc);
if (rc < 0)
dmx_err("read: %s", strerror(errno), 0);
return rc;
}
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask)
{
memset(&s_flt, 0, sizeof(s_flt));
_open();
if (len > DMX_FILTER_SIZE)
{
lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE);
len = DMX_FILTER_SIZE;
}
s_flt.pid = pid;
s_flt.timeout = timeout;
memcpy(s_flt.filter.filter, filter, len);
memcpy(s_flt.filter.mask, mask, len);
if (negmask != NULL)
memcpy(s_flt.filter.mode, negmask, len);
s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC;
int to = 0;
switch (filter[0]) {
case 0x00: /* program_association_section */
to = 2000;
break;
case 0x01: /* conditional_access_section */
to = 6000;
break;
case 0x02: /* program_map_section */
to = 1500;
break;
case 0x03: /* transport_stream_description_section */
to = 10000;
break;
/* 0x04 - 0x3F: reserved */
case 0x40: /* network_information_section - actual_network */
to = 10000;
break;
case 0x41: /* network_information_section - other_network */
to = 15000;
break;
case 0x42: /* service_description_section - actual_transport_stream */
to = 10000;
break;
/* 0x43 - 0x45: reserved for future use */
case 0x46: /* service_description_section - other_transport_stream */
to = 10000;
break;
/* 0x47 - 0x49: reserved for future use */
case 0x4A: /* bouquet_association_section */
to = 11000;
break;
/* 0x4B - 0x4D: reserved for future use */
case 0x4E: /* event_information_section - actual_transport_stream, present/following */
to = 2000;
break;
case 0x4F: /* event_information_section - other_transport_stream, present/following */
to = 10000;
break;
/* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */
/* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */
case 0x70: /* time_date_section */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
s_flt.flags |= DMX_ONESHOT;
//s_flt.pid = 0x0014;
to = 30000;
break;
case 0x71: /* running_status_section */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
to = 0;
break;
case 0x72: /* stuffing_section */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
to = 0;
break;
case 0x73: /* time_offset_section */
s_flt.flags |= DMX_ONESHOT;
//s_flt.pid = 0x0014;
to = 30000;
break;
/* 0x74 - 0x7D: reserved for future use */
case 0x7E: /* discontinuity_information_section */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
to = 0;
break;
case 0x7F: /* selection_information_section */
to = 0;
break;
/* 0x80 - 0x8F: ca_message_section */
/* 0x90 - 0xFE: user defined */
/* 0xFF: reserved */
default:
break;
// return -1;
}
/* the negmask == NULL is a hack: the users of negmask are PMT-update
* and sectionsd EIT-Version change. And they really want no timeout
* if timeout == 0 instead of "default timeout" */
if (timeout == 0 && negmask == NULL)
s_flt.timeout = to;
lt_debug("%s #%d pid:0x%04hx fd:%d type:%s len:%d to:%d flags:%x flt[0]:%02x\n", __func__, num,
pid, fd, DMX_T[dmx_type], len, s_flt.timeout,s_flt.flags, s_flt.filter.filter[0]);
#if 0
fprintf(stderr,"filt: ");for(int i=0;i<FILTER_LENGTH;i++)fprintf(stderr,"%02hhx ",s_flt.filter[i]);fprintf(stderr,"\n");
fprintf(stderr,"mask: ");for(int i=0;i<FILTER_LENGTH;i++)fprintf(stderr,"%02hhx ",s_flt.mask [i]);fprintf(stderr,"\n");
fprintf(stderr,"posi: ");for(int i=0;i<FILTER_LENGTH;i++)fprintf(stderr,"%02hhx ",s_flt.positive[i]);fprintf(stderr,"\n");
#endif
ioctl (fd, DMX_STOP);
if (ioctl(fd, DMX_SET_FILTER, &s_flt) < 0)
return false;
return true;
}
bool cDemux::pesFilter(const unsigned short pid)
{
/* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure
* what it is good for...
if (pid <= 0x0001 && dmx_type != DMX_PCR_ONLY_CHANNEL)
return false;
*/
if ((pid >= 0x0002 && pid <= 0x000f) || pid >= 0x1fff)
return false;
lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]);
_open();
memset(&p_flt, 0, sizeof(p_flt));
p_flt.pid = pid;
p_flt.output = DMX_OUT_DECODER;
p_flt.input = DMX_IN_FRONTEND;
p_flt.flags = 0;
switch (dmx_type) {
case DMX_PCR_ONLY_CHANNEL:
p_flt.pes_type = DMX_PES_PCR;
break;
case DMX_AUDIO_CHANNEL:
p_flt.pes_type = DMX_PES_AUDIO;
break;
case DMX_VIDEO_CHANNEL:
p_flt.pes_type = DMX_PES_VIDEO;
break;
case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */
p_flt.pes_type = DMX_PES_VIDEO1;
break;
case DMX_PES_CHANNEL:
p_flt.pes_type = DMX_PES_OTHER;
p_flt.output = DMX_OUT_TAP;
break;
case DMX_TP_CHANNEL:
p_flt.pes_type = DMX_PES_OTHER;
p_flt.output = DMX_OUT_TSDEMUX_TAP;
break;
default:
lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type);
return false;
}
return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0);
}
void cDemux::SetSyncMode(AVSYNC_TYPE /*mode*/)
{
lt_debug("%s #%d\n", __FUNCTION__, num);
}
void *cDemux::getBuffer()
{
lt_debug("%s #%d\n", __FUNCTION__, num);
return NULL;
}
void *cDemux::getChannel()
{
lt_debug("%s #%d\n", __FUNCTION__, num);
return NULL;
}
bool cDemux::addPid(unsigned short Pid)
{
lt_debug("%s: pid 0x%04hx\n", __func__, Pid);
pes_pids pfd;
int ret;
if (dmx_type != DMX_TP_CHANNEL)
{
lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid);
return false;
}
_open();
if (fd == -1)
lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid);
pfd.fd = fd; /* dummy */
pfd.pid = Pid;
pesfds.push_back(pfd);
ret = (ioctl(fd, DMX_ADD_PID, &Pid));
if (ret < 0)
lt_info("%s: DMX_ADD_PID (%m) pid=%hx\n", __func__, Pid);
return (ret != -1);
}
void cDemux::removePid(unsigned short Pid)
{
if (dmx_type != DMX_TP_CHANNEL)
{
lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid);
return;
}
for (std::vector<pes_pids>::iterator i = pesfds.begin(); i != pesfds.end(); ++i)
{
if ((*i).pid == Pid) {
lt_debug("removePid: removing demux fd %d pid 0x%04x\n", fd, Pid);
if (ioctl(fd, DMX_REMOVE_PID, Pid) < 0)
lt_info("%s: (DMX_REMOVE_PID, 0x%04hx): %m\n", __func__, Pid);
pesfds.erase(i);
return; /* TODO: what if the same PID is there multiple times */
}
}
lt_info("%s pid 0x%04x not found\n", __FUNCTION__, Pid);
}
void cDemux::getSTC(int64_t * STC)
{
/* apparently I can only get the PTS of the video decoder,
* but that's good enough for dvbsub */
lt_debug("%s #%d\n", __func__, num);
int64_t pts = 0;
if (videoDecoder)
pts = videoDecoder->GetPTS();
*STC = pts;
}
int cDemux::getUnit(void)
{
lt_debug("%s #%d\n", __FUNCTION__, num);
/* just guessed that this is the right thing to do.
right now this is only used by the CA code which is stubbed out
anyway */
return num;
}
bool cDemux::SetSource(int unit, int source)
{
if (unit >= NUM_DEMUX || unit < 0) {
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return false;
}
lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source);
if (source < 0 || source >= NUM_DEMUXDEV)
lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source);
else
dmx_source[unit] = source;
return true;
}
int cDemux::GetSource(int unit)
{
if (unit >= NUM_DEMUX || unit < 0) {
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return -1;
}
lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]);
return dmx_source[unit];
}

1
libarmbox/dmx_cs.h Normal file
View File

@@ -0,0 +1 @@
#include "dmx_lib.h"

72
libarmbox/dmx_lib.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
int last_source;
bool _open(void);
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * unused = NULL, int bufsize = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

44
libarmbox/hardware_caps.c Normal file
View File

@@ -0,0 +1,44 @@
/*
* determine the capabilities of the hardware.
* part of libstb-hal
*
* (C) 2010-2012 Stefan Seyfried
*
* License: GPL v2 or later
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <hardware_caps.h>
#define FP_DEV "/dev/dbox/oled0"
static int initialized = 0;
static hw_caps_t caps;
hw_caps_t *get_hwcaps(void)
{
if (initialized)
return &caps;
memset(&caps, 0, sizeof(hw_caps_t));
initialized = 1;
caps.has_CI = 1;
caps.can_cec = 1;
caps.can_shutdown = 1;
caps.display_xres = 16;
caps.display_type = HW_DISPLAY_LINE_TEXT;
caps.display_can_set_brightness = 1;
caps.display_has_statusline = 0;
caps.has_HDMI = 1;
strcpy(caps.boxvendor, "AX-Technologies");
strcpy(caps.boxname, "HD51");
strcpy(caps.boxarch, "BCM7251S");
return &caps;
}

49
libarmbox/init.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include <stdio.h>
#include "init_lib.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pwrmngr.h"
#include <proc_tools.h>
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args)
static bool initialized = false;
void init_td_api()
{
if (!initialized)
lt_debug_init();
lt_info("%s begin, initialized=%d, debug=0x%02x\n", __FUNCTION__, (int)initialized, debuglevel);
if (!initialized)
{
cCpuFreqManager f;
f.SetCpuFreq(0); /* CPUFREQ == 0 is the trigger for leaving standby */
char buffer[64];
sprintf(buffer, "%x", 0);
proc_put("/proc/stb/fb/dst_top", buffer, strlen(buffer));
proc_put("/proc/stb/fb/dst_left", buffer, strlen(buffer));
sprintf(buffer, "%x", 576);
proc_put("/proc/stb/fb/dst_height", buffer, strlen(buffer));
sprintf(buffer, "%x", 720);
proc_put("/proc/stb/fb/dst_width", buffer, strlen(buffer));
sprintf(buffer, "%x", 1);
proc_put("/proc/stb/fb/dst_apply", buffer, strlen(buffer));
}
initialized = true;
lt_info("%s end\n", __FUNCTION__);
}
void shutdown_td_api()
{
lt_info("%s, initialized = %d\n", __FUNCTION__, (int)initialized);
initialized = false;
}

2
libarmbox/init_cs.h Normal file
View File

@@ -0,0 +1,2 @@
#warning using init_cs.h from libspark
#include "init_lib.h"

5
libarmbox/init_lib.h Normal file
View File

@@ -0,0 +1,5 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

1014
libarmbox/linux-uapi-cec.h Normal file

File diff suppressed because it is too large Load Diff

1180
libarmbox/playback_gst.cpp Normal file

File diff suppressed because it is too large Load Diff

103
libarmbox/playback_gst.h Normal file
View File

@@ -0,0 +1,103 @@
/*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __PLAYBACK_CS_H
#define __PLAYBACK_CS_H
#include <string>
#include <stdint.h>
#include <vector>
#include <config.h>
typedef enum
{
STATE_STOP,
STATE_PLAY,
STATE_PAUSE,
STATE_FF,
STATE_REW,
STATE_SLOW
} playstate_t;
typedef enum
{
PLAYMODE_TS = 0,
PLAYMODE_FILE,
} playmode_t;
struct AVFormatContext;
class cPlayback
{
private:
bool playing, first;
bool decoders_closed;
int mSpeed;
int mAudioStream;
int init_jump;
public:
playstate_t playstate;
cPlayback(int);
bool Open(playmode_t PlayMode);
void Close(void);
bool Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers = "");
bool Start(std::string filename, std::string headers = "");
bool Play(void);
bool SyncAV(void);
bool Stop(void);
bool SetAPid(int pid, bool ac3);
bool SetSubtitlePid(int pid);
bool SetTeletextPid(int pid);
void trickSeek(int ratio);
bool SetSpeed(int speed);
bool SetSlow(int slow);
bool GetSpeed(int &speed) const;
bool GetPosition(int &position, int &duration);
void GetPts(uint64_t &pts);
int GetAPid(void);
int GetVPid(void);
int GetSubtitlePid(void);
bool SetPosition(int position, bool absolute = false);
void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language);
void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language);
void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage, int *mags, int *pages);
void RequestAbort(void);
void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language);
bool SelectSubtitles(int pid);
uint64_t GetReadCount(void);
void GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
void GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
AVFormatContext *GetAVFormatContext();
void ReleaseAVFormatContext();
std::string extra_headers;
std::string user_agent;
//
~cPlayback();
void getMeta();
};
#endif

View File

@@ -0,0 +1,699 @@
#define __USE_FILE_OFFSET64 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <audio_lib.h>
#include <video_lib.h>
#include <common.h>
extern OutputHandler_t OutputHandler;
extern PlaybackHandler_t PlaybackHandler;
extern ContainerHandler_t ContainerHandler;
extern ManagerHandler_t ManagerHandler;
#include "playback_libeplayer3.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(HAL_DEBUG_PLAYBACK, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_PLAYBACK, this, args)
static Context_t *player = NULL;
extern cAudio *audioDecoder;
extern cVideo *videoDecoder;
//Used by Fileplay
bool cPlayback::Open(playmode_t PlayMode)
{
if (PlayMode != PLAYMODE_TS)
{
audioDecoder->closeDevice();
videoDecoder->closeDevice();
decoders_closed = true;
}
pm = PlayMode;
fn_ts = "";
fn_xml = "";
last_size = 0;
nPlaybackSpeed = 0;
init_jump = -1;
if (player)
free(player);
player = NULL;
player = (Context_t *) malloc(sizeof(Context_t));
if (player)
{
player->playback = &PlaybackHandler;
player->output = &OutputHandler;
player->container = &ContainerHandler;
player->manager = &ManagerHandler;
lt_info("%s - player output name: %s\n", __func__, player->output->Name);
}
//Registration of output devices
if (player && player->output)
{
player->output->Command(player, OUTPUT_ADD, (void *)"audio");
player->output->Command(player, OUTPUT_ADD, (void *)"video");
}
return 0;
}
void cPlayback::Close(void)
{
lt_info("%s\n", __func__);
//Dagobert: movieplayer does not call stop, it calls close ;)
Stop();
if (decoders_closed)
{
audioDecoder->openDevice();
videoDecoder->openDevice();
decoders_closed = false;
}
}
bool cPlayback::Start(std::string filename, std::string headers)
{
return Start((char *) filename.c_str(), 0, 0, 0, 0, 0, headers);
}
bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int, std::string headers)
{
bool ret = false;
bool isHTTP = false;
no_probe = false;
lt_info("%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d\n", __func__, filename, vpid, vtype, apid, ac3);
init_jump = -1;
//create playback path
mAudioStream = 0;
mSubtitleStream = -1;
mTeletextStream = -1;
unlink("/tmp/.id3coverart");
std::string file;
if (*filename == '/')
file = "file://";
file += filename;
if ((file.find(":31339/id=") != std::string::npos) || (file.find(":10000") != std::string::npos) || (file.find(":8001/") != std::string::npos)) // for LocalTV and Entertain-TV streaming
no_probe = true;
if (file.substr(0, 7) == "file://")
{
if (file.substr(file.length() - 3) == ".ts")
{
fn_ts = file.substr(7);
fn_xml = file.substr(7, file.length() - 9);
fn_xml += "xml";
no_probe = true;
}
}
else
isHTTP = true;
PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL};
if (player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) == 0)
{
if (pm == PLAYMODE_TS)
{
struct stat64 s;
if (!stat64(file.c_str(), &s))
last_size = s.st_size;
ret = true;
videoDecoder->Stop(false);
audioDecoder->Stop();
}
else
{
//AUDIO
if(player && player->manager && player->manager->audio) {
char ** TrackList = NULL;
player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("AudioTrack List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2) {
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
}
}
//SUB
if(player && player->manager && player->manager->subtitle) {
char ** TrackList = NULL;
player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("SubtitleTrack List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2) {
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
}
}
/*
//Teletext
if(player && player->manager && player->manager->teletext) {
char ** TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("TeletextTrack List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2) {
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
}
}
*/
//Chapters
if(player && player->manager && player->manager->chapter) {
char ** TrackList = NULL;
player->manager->chapter->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("Chapter List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2) {
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
}
}
playing = true;
player->output->Command(player, OUTPUT_OPEN, NULL);
ret = (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0);
if (ret && !isHTTP)
playing = ret = (player->playback->Command(player, PLAYBACK_PAUSE, NULL) == 0);
}
}
return ret;
}
bool cPlayback::Stop(void)
{
lt_info("%s playing %d\n", __func__, playing);
if (player && player->playback)
player->playback->Command(player, PLAYBACK_STOP, NULL);
if (player && player->output)
player->output->Command(player, OUTPUT_CLOSE, NULL);
if (player && player->output)
{
player->output->Command(player, OUTPUT_DEL, (void *)"audio");
player->output->Command(player, OUTPUT_DEL, (void *)"video");
}
if (player && player->playback)
player->playback->Command(player, PLAYBACK_CLOSE, NULL);
playing = false;
return true;
}
bool cPlayback::SetAPid(int pid, bool /* ac3 */)
{
lt_info("%s\n", __func__);
int i = pid;
if (pid != mAudioStream)
{
if (player && player->playback)
player->playback->Command(player, PLAYBACK_SWITCH_AUDIO, (void *)&i);
mAudioStream = pid;
}
return true;
}
bool cPlayback::SetVPid(int pid)
{
lt_info("%s\n", __func__);
return true;
}
bool cPlayback::SetSubtitlePid(int pid)
{
lt_info("%s\n", __func__);
int i = pid;
if (pid != mSubtitleStream)
{
if (player && player->playback)
player->playback->Command(player, PLAYBACK_SWITCH_SUBTITLE, (void *)&i);
mSubtitleStream = pid;
}
return true;
}
bool cPlayback::SetTeletextPid(int pid)
{
lt_info("%s\n", __func__);
int i = pid;
if (pid != mTeletextStream)
{
//if(player && player->playback)
//player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i);
mTeletextStream = pid;
}
return true;
}
bool cPlayback::SetSpeed(int speed)
{
lt_info("%s playing %d speed %d\n", __func__, playing, speed);
if (!decoders_closed)
{
audioDecoder->closeDevice();
videoDecoder->closeDevice();
decoders_closed = true;
usleep(500000);
if (player && player->output && player->playback)
{
player->output->Command(player, OUTPUT_OPEN, NULL);
if (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0)
playing = true;
}
}
if (!playing)
return false;
if (player && player->playback)
{
int result = 0;
nPlaybackSpeed = speed;
if (speed > 1)
{
/* direction switch ? */
if (player->playback->BackWard)
{
int r = 0;
result = player->playback->Command(player, PLAYBACK_FASTBACKWARD, (void *)&r);
printf("result = %d\n", result);
}
result = player->playback->Command(player, PLAYBACK_FASTFORWARD, (void *)&speed);
}
else if (speed < 0)
{
/* direction switch ? */
if (player->playback->isForwarding)
{
result = player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
printf("result = %d\n", result);
}
result = player->playback->Command(player, PLAYBACK_FASTBACKWARD, (void *)&speed);
}
else if (speed == 0)
{
/* konfetti: hmmm accessing the member isn't very proper */
if ((player->playback->isForwarding) || (!player->playback->BackWard))
player->playback->Command(player, PLAYBACK_PAUSE, NULL);
else
{
int _speed = 0; /* means end of reverse playback */
player->playback->Command(player, PLAYBACK_FASTBACKWARD, (void *)&_speed);
}
}
else
{
result = player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
}
if (init_jump > -1)
{
SetPosition(init_jump);
init_jump = -1;
}
if (result != 0)
{
printf("returning false\n");
return false;
}
}
return true;
}
bool cPlayback::GetSpeed(int &speed) const
{
lt_debug("%s\n", __func__);
speed = nPlaybackSpeed;
return true;
}
void cPlayback::GetPts(uint64_t &pts)
{
if (player && player->playback)
player->playback->Command(player, PLAYBACK_PTS, (void *)&pts);
}
// in milliseconds
bool cPlayback::GetPosition(int &position, int &duration)
{
bool got_duration = false;
lt_debug("%s %d %d\n", __func__, position, duration);
/* hack: if the file is growing (timeshift), then determine its length
* by comparing the mtime with the mtime of the xml file */
if (pm == PLAYMODE_TS)
{
struct stat64 s;
if (!stat64(fn_ts.c_str(), &s))
{
if (!playing || last_size != s.st_size)
{
last_size = s.st_size;
time_t curr_time = s.st_mtime;
if (!stat64(fn_xml.c_str(), &s))
{
duration = (curr_time - s.st_mtime) * 1000;
if (!playing)
return true;
got_duration = true;
}
}
}
}
if (!playing)
return false;
if (player && player->playback && !player->playback->isPlaying)
{
lt_info("%s !!!!EOF!!!! < -1\n", __func__);
position = duration + 1000;
return false;
}
int64_t vpts = 0;
if (player && player->playback)
player->playback->Command(player, PLAYBACK_PTS, &vpts);
if (vpts <= 0)
{
//printf("ERROR: vpts==0");
}
else
{
/* len is in nanoseconds. we have 90 000 pts per second. */
position = vpts / 90;
}
if (got_duration)
return true;
int64_t length = 0;
if (player && player->playback)
player->playback->Command(player, PLAYBACK_LENGTH, &length);
if (length <= 0)
duration = duration + 1000;
else
duration = length * 1000;
return true;
}
bool cPlayback::SetPosition(int position, bool absolute)
{
lt_info("%s %d\n", __func__, position);
if (!playing)
{
/* the calling sequence is:
* Start() - paused
* SetPosition() - which fails if not running
* SetSpeed() - to start playing
* so let's remember the initial jump position and later jump to it
*/
init_jump = position;
return false;
}
int64_t pos = (position / 1000.0);
if (player && player->playback)
player->playback->Command(player, absolute ? PLAYBACK_SEEK_ABS : PLAYBACK_SEEK, (void *)&pos);
return true;
}
void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language)
{
lt_info("%s\n", __func__);
int max_numpida = *numpida;
*numpida = 0;
if(player && player->manager && player->manager->audio) {
char ** TrackList = NULL;
player->manager->audio->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("AudioTrack List\n");
int i = 0,j=0;
for (i = 0,j=0; TrackList[i] != NULL; i+=2,j++) {
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
if (j < max_numpida) {
int _pid;
char _lang[strlen(TrackList[i])];
if (2 == sscanf(TrackList[i], "%d %s\n", &_pid, _lang)) {
apids[j]=_pid;
// atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC
if( !strncmp("A_MPEG/L3", TrackList[i+1], 9))
ac3flags[j] = 3;
if( !strncmp("A_MP3", TrackList[i+1], 5))
ac3flags[j] = 4;
else if(!strncmp("A_AC3", TrackList[i+1], 5))
ac3flags[j] = 1;
else if(!strncmp("A_EAC3", TrackList[i+1], 6))
ac3flags[j] = 7;
else if(!strncmp("A_DTS", TrackList[i+1], 5))
ac3flags[j] = 6;
else if(!strncmp("A_AAC", TrackList[i+1], 5))
ac3flags[j] = 5;
else if(!strncmp("A_PCM", TrackList[i+1], 5))
ac3flags[j] = 0; //todo
else if(!strncmp("A_VORBIS", TrackList[i+1], 8))
ac3flags[j] = 0; //todo
else if(!strncmp("A_FLAC", TrackList[i+1], 6))
ac3flags[j] = 0; //todo
else
ac3flags[j] = 0; //todo
language[j]=std::string(_lang);
}
}
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
*numpida=j;
}
}
}
void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language)
{
lt_info("%s\n", __func__);
int max_numpids = *numpids;
*numpids = 0;
if (player && player->manager && player->manager->subtitle)
{
char **TrackList = NULL;
player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL)
{
printf("SubtitleTrack List\n");
int i = 0, j = 0;
for (i = 0, j = 0; TrackList[i] != NULL; i += 2, j++)
{
printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]);
if (j < max_numpids)
{
int _pid;
char _lang[strlen(TrackList[i])];
if (2 == sscanf(TrackList[i], "%d %s\n", &_pid, _lang))
{
pids[j] = _pid;
language[j] = std::string(_lang);
}
}
free(TrackList[i]);
free(TrackList[i + 1]);
}
free(TrackList);
*numpids = j;
}
}
}
void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, std::string *language, int *mags, int *pages)
{
lt_info("%s\n", __func__);
int max_numpids = *numpids;
*numpids = 0;
/*
if(player && player->manager && player->manager->teletext) {
char ** TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("Teletext List\n");
int i = 0,j=0;
for (i = 0,j=0; TrackList[i] != NULL; i+=2) {
int type = 0;
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
if (j < max_numpids) {
int _pid;
if (2 != sscanf(TrackList[i], "%*d %d %*s %d %*d %*d", &_pid, &type))
continue;
if (type != 2 && type != 5) // return subtitles only
continue;
pids[j]=_pid;
language[j]=std::string(TrackList[i]);
j++;
}
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
*numpids=j;
}
}
*/
}
int cPlayback::GetTeletextPid(void)
{
lt_info("%s\n", __func__);
int pid = -1;
/*
if(player && player->manager && player->manager->teletext) {
char ** TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("Teletext List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2) {
int type = 0;
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
if (pid < 0) {
if (2 != sscanf(TrackList[i], "%*d %d %*s %d %*d %*d", &pid, &type))
continue;
if (type != 1)
pid = -1;
}
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
}
}
*/
printf("teletext pid id %d (0x%x)\n", pid, pid);
return pid;
}
#if 0
/* dummy functions for subtitles */
void cPlayback::FindAllSubs(uint16_t * /*pids*/, unsigned short * /*supp*/, uint16_t *num, std::string * /*lang*/)
{
*num = 0;
}
bool cPlayback::SelectSubtitles(int /*pid*/)
{
return false;
}
#endif
void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)
{
positions.clear();
titles.clear();
if(player && player->manager && player->manager->chapter) {
char ** TrackList = NULL;
player->manager->chapter->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("%s: Chapter List\n", __func__);
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2) {
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
int pos = atoi(TrackList[i]);
std::string title(TrackList[i + 1]);
positions.push_back(pos);
titles.push_back(title);
free(TrackList[i]);
free(TrackList[i+1]);
}
free(TrackList);
}
}
}
void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
{
keys.clear();
values.clear();
char **metadata = NULL;
if (player && player->playback)
{
player->playback->Command(player, PLAYBACK_METADATA, &metadata);
if (metadata)
{
for (char **m = metadata; *m;)
{
keys.push_back(*m);
free(*m++);
values.push_back(*m);
free(*m++);
}
free(metadata);
}
}
}
cPlayback::cPlayback(int num __attribute__((unused)))
{
lt_info("%s\n", __func__);
playing = false;
decoders_closed = false;
}
cPlayback::~cPlayback()
{
lt_info("%s\n", __func__);
if (player)
free(player);
player = NULL;
}
void cPlayback::RequestAbort()
{
if (player && player->playback)
{
player->playback->abortRequested = 1;
while (player->playback->isPlaying)
usleep(100000);
}
}
bool cPlayback::IsPlaying()
{
if (player && player->playback)
return player->playback->isPlaying;
return false;
}
uint64_t cPlayback::GetReadCount()
{
//if (player && player->playback) {
//return player->playback->readCount;
//}
return 0;
}
AVFormatContext *cPlayback::GetAVFormatContext()
{
return NULL;
}
void cPlayback::ReleaseAVFormatContext()
{
}
#if 0
bool cPlayback::IsPlaying(void) const
{
lt_info("%s\n", __func__);
/* konfetti: there is no event/callback mechanism in libeplayer2
* so in case of ending playback we have no information on a
* terminated stream currently (or did I oversee it?).
* So let's ask the player the state.
*/
if (playing)
{
return player->playback->isPlaying;
}
return playing;
}
#endif

View File

@@ -0,0 +1,91 @@
#ifndef __HAL_PLAYBACK_H
#define __HAL_PLAYBACK_H
#include <string>
#include <vector>
typedef enum
{
PLAYMODE_TS = 0,
PLAYMODE_FILE
} playmode_t;
struct AVFormatContext;
class cPlayback
{
friend class CStreamInfo2;
private:
bool enabled;
bool playing;
bool no_probe;
int nPlaybackSpeed;
int mAudioStream;
int mSubtitleStream;
int mTeletextStream;
bool Stop(void);
bool decoders_closed;
playmode_t pm;
std::string fn_ts;
std::string fn_xml;
off64_t last_size;
int init_jump;
public:
cPlayback(int num = 0);
~cPlayback();
bool Open(playmode_t PlayMode);
void Close(void);
bool Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers = "");
bool Start(std::string filename, std::string headers = "");
bool SetAPid(int pid, bool ac3 = false);
bool SetVPid(int pid);
bool SetSubtitlePid(int pid);
bool SetTeletextPid(int pid);
int GetAPid(void)
{
return mAudioStream;
};
int GetVPid(void)
{
return 0;
};
int GetSubtitlePid(void)
{
return mSubtitleStream;
};
int GetTeletextPid(void);
bool SetSpeed(int speed);
bool GetSpeed(int &speed) const;
bool GetPosition(int &position, int &duration);
void GetPts(uint64_t &pts);
bool SetPosition(int position, bool absolute = false);
void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language);
void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language);
void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage, int *mags, int *pages);
void RequestAbort(void);
bool IsPlaying(void);
uint64_t GetReadCount(void);
void GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
void GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
AVFormatContext *GetAVFormatContext();
void ReleaseAVFormatContext();
#if 0
void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language);
bool SelectSubtitles(int pid);
// Functions that are not used by movieplayer.cpp:
bool GetOffset(off64_t &offset);
bool IsPlaying(void) const;
bool IsEnabled(void) const;
void *GetHandle(void);
void *GetDmHandle(void);
int GetCurrPlaybackSpeed(void) const;
void PlaybackNotify(int Event, void *pData, void *pTag);
void DMNotify(int Event, void *pTsBuf, void *Tag);
#endif
};
#endif

32
libarmbox/pwrmngr.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include <stdio.h>
#include "pwrmngr.h"
#include "lt_debug.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PWRMNGR, this, args)
void cCpuFreqManager::Up(void) { lt_debug("%s\n", __FUNCTION__); }
void cCpuFreqManager::Down(void) { lt_debug("%s\n", __FUNCTION__); }
void cCpuFreqManager::Reset(void) { lt_debug("%s\n", __FUNCTION__); }
/* those function dummies return true or "harmless" values */
bool cCpuFreqManager::SetDelta(unsigned long) { lt_debug("%s\n", __FUNCTION__); return true; }
unsigned long cCpuFreqManager::GetCpuFreq(void) { lt_debug("%s\n", __FUNCTION__); return 0; }
unsigned long cCpuFreqManager::GetDelta(void) { lt_debug("%s\n", __FUNCTION__); return 0; }
//
cCpuFreqManager::cCpuFreqManager(void) { lt_debug("%s\n", __FUNCTION__); }
bool cPowerManager::SetState(PWR_STATE) { lt_debug("%s\n", __FUNCTION__); return true; }
bool cPowerManager::Open(void) { lt_debug("%s\n", __FUNCTION__); return true; }
void cPowerManager::Close(void) { lt_debug("%s\n", __FUNCTION__); }
//
bool cPowerManager::SetStandby(bool Active, bool Passive) { lt_debug("%s(%d, %d)\n", __FUNCTION__, Active, Passive); return true; }
bool cCpuFreqManager::SetCpuFreq(unsigned long f) { lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false"); return true; }
//
cPowerManager::cPowerManager(void) { lt_debug("%s\n", __FUNCTION__); }
cPowerManager::~cPowerManager() { lt_debug("%s\n", __FUNCTION__); }

53
libarmbox/pwrmngr.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef __PWRMNGR_H__
#define __PWRMNGR_H__
// -- cCpuFreqManager ----------------------------------------------------------
class cCpuFreqManager {
private:
unsigned long startCpuFreq;
unsigned long delta;
public:
void Up(void);
void Down(void);
void Reset(void);
//
bool SetCpuFreq(unsigned long CpuFreq);
bool SetDelta(unsigned long Delta);
unsigned long GetCpuFreq(void);
unsigned long GetDelta(void);
//
cCpuFreqManager(void);
};
// -- cPowerManageger ----------------------------------------------------------
typedef enum
{
PWR_INIT = 1,
PWR_FULL_ACTIVE, /* all devices/clocks up */
PWR_ACTIVE_STANDBY,
PWR_PASSIVE_STANDBY,
PWR_INVALID
} PWR_STATE;
class cPowerManager {
private:
bool init;
bool opened;
PWR_STATE powerState;
//
static void ApplicationCallback(void *, void *, signed long, void *, void *) {}
bool SetState(PWR_STATE PowerState);
public:
bool Open(void);
void Close(void);
//
bool SetStandby(bool Active, bool Passive);
//
cPowerManager(void);
virtual ~cPowerManager();
};
#endif // __PWRMNGR_H__

383
libarmbox/record.cpp Normal file
View File

@@ -0,0 +1,383 @@
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <inttypes.h>
#include <cstdio>
#include <cstring>
#include <aio.h>
#include "record_lib.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args)
/* helper functions to call the cpp thread loops */
void *execute_record_thread(void *c)
{
cRecord *obj = (cRecord *)c;
obj->RecordThread();
return NULL;
}
void *execute_writer_thread(void *c)
{
cRecord *obj = (cRecord *)c;
obj->WriterThread();
return NULL;
}
cRecord::cRecord(int num, int bs_dmx, int bs)
{
lt_info("%s %d\n", __func__, num);
dmx = NULL;
record_thread_running = false;
file_fd = -1;
exit_flag = RECORD_STOPPED;
dmx_num = num;
bufsize = bs;
bufsize_dmx = bs_dmx;
failureCallback = NULL;
failureData = NULL;
}
cRecord::~cRecord()
{
lt_info("%s: calling ::Stop()\n", __func__);
Stop();
lt_info("%s: end\n", __func__);
}
bool cRecord::Open(void)
{
lt_info("%s\n", __func__);
exit_flag = RECORD_STOPPED;
return true;
}
#if 0
// unused
void cRecord::Close(void)
{
lt_info("%s: \n", __func__);
}
#endif
bool cRecord::Start(int fd, unsigned short vpid, unsigned short *apids, int numpids, uint64_t)
{
lt_info("%s: fd %d, vpid 0x%03x\n", __func__, fd, vpid);
int i;
if (!dmx)
dmx = new cDemux(dmx_num);
dmx->Open(DMX_TP_CHANNEL, NULL, bufsize_dmx);
dmx->pesFilter(vpid);
for (i = 0; i < numpids; i++)
dmx->addPid(apids[i]);
file_fd = fd;
exit_flag = RECORD_RUNNING;
if (posix_fadvise(file_fd, 0, 0, POSIX_FADV_DONTNEED))
perror("posix_fadvise");
i = pthread_create(&record_thread, 0, execute_record_thread, this);
if (i != 0)
{
exit_flag = RECORD_FAILED_READ;
errno = i;
lt_info("%s: error creating thread! (%m)\n", __func__);
delete dmx;
dmx = NULL;
return false;
}
record_thread_running = true;
return true;
}
bool cRecord::Stop(void)
{
lt_info("%s\n", __func__);
if (exit_flag != RECORD_RUNNING)
lt_info("%s: status not RUNNING? (%d)\n", __func__, exit_flag);
exit_flag = RECORD_STOPPED;
if (record_thread_running)
pthread_join(record_thread, NULL);
record_thread_running = false;
/* We should probably do that from the destructor... */
if (!dmx)
lt_info("%s: dmx == NULL?\n", __func__);
else
delete dmx;
dmx = NULL;
if (file_fd != -1)
close(file_fd);
else
lt_info("%s: file_fd not open??\n", __func__);
file_fd = -1;
return true;
}
bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int numapids)
{
std::vector<pes_pids> pids;
int j;
bool found;
unsigned short pid;
lt_info("%s\n", __func__);
if (!dmx) {
lt_info("%s: DMX = NULL\n", __func__);
return false;
}
pids = dmx->getPesPids();
/* the first PID is the video pid, so start with the second PID... */
for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) {
found = false;
pid = (*i).pid;
for (j = 0; j < numapids; j++) {
if (pid == apids[j]) {
found = true;
break;
}
}
if (!found)
dmx->removePid(pid);
}
for (j = 0; j < numapids; j++) {
found = false;
for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) {
if ((*i).pid == apids[j]) {
found = true;
break;
}
}
if (!found)
dmx->addPid(apids[j]);
}
return true;
}
bool cRecord::AddPid(unsigned short pid)
{
std::vector<pes_pids> pids;
lt_info("%s: \n", __func__);
if (!dmx) {
lt_info("%s: DMX = NULL\n", __func__);
return false;
}
pids = dmx->getPesPids();
for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) {
if ((*i).pid == pid)
return true; /* or is it an error to try to add the same PID twice? */
}
return dmx->addPid(pid);
}
void cRecord::WriterThread()
{
char threadname[17];
strncpy(threadname, "WriterThread", sizeof(threadname));
threadname[16] = 0;
prctl (PR_SET_NAME, (unsigned long)&threadname);
unsigned int chunk = 0;
while (!sem_wait(&sem)) {
if (!io_len[chunk]) // empty, assume end of recording
return;
unsigned char *p_buf = io_buf[chunk];
size_t p_len = io_len[chunk];
while (p_len) {
ssize_t written = write(file_fd, p_buf, p_len);
if (written < 0)
break;
p_len -= written;
p_buf += written;
}
if (posix_fadvise(file_fd, 0, 0, POSIX_FADV_DONTNEED))
perror("posix_fadvise");
chunk++;
chunk %= RECORD_WRITER_CHUNKS;
}
}
void cRecord::RecordThread()
{
lt_info("%s: begin\n", __func__);
char threadname[17];
strncpy(threadname, "RecordThread", sizeof(threadname));
threadname[16] = 0;
prctl (PR_SET_NAME, (unsigned long)&threadname);
int readsize = bufsize/16;
int buf_pos = 0;
int count = 0;
int queued = 0;
uint8_t *buf;
struct aiocb a;
buf = (uint8_t *)malloc(bufsize);
lt_info("BUFSIZE=0x%x READSIZE=0x%x\n", bufsize, readsize);
if (!buf)
{
exit_flag = RECORD_FAILED_MEMORY;
lt_info("%s: unable to allocate buffer! (out of memory)\n", __func__);
if (failureCallback)
failureCallback(failureData);
lt_info("%s: end\n", __func__);
pthread_exit(NULL);
}
int val = fcntl(file_fd, F_GETFL);
if (fcntl(file_fd, F_SETFL, val|O_APPEND))
lt_info("%s: O_APPEND? (%m)\n", __func__);
memset(&a, 0, sizeof(a));
a.aio_fildes = file_fd;
a.aio_sigevent.sigev_notify = SIGEV_NONE;
dmx->Start();
int overflow_count = 0;
bool overflow = false;
int r = 0;
while (exit_flag == RECORD_RUNNING)
{
if (buf_pos < bufsize)
{
if (overflow_count) {
lt_info("%s: Overflow cleared after %d iterations\n", __func__, overflow_count);
overflow_count = 0;
}
int toread = bufsize - buf_pos;
if (toread > readsize)
toread = readsize;
ssize_t s = dmx->Read(buf + buf_pos, toread, 50);
lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, buf_pos, (int)s, bufsize - buf_pos);
if (s < 0)
{
if (errno != EAGAIN && (errno != EOVERFLOW || !overflow))
{
lt_info("%s: read failed: %m\n", __func__);
exit_flag = RECORD_FAILED_READ;
break;
}
}
else
{
overflow = false;
buf_pos += s;
if (count > 100)
{
if (buf_pos < bufsize / 2)
continue;
}
else
{
count += 1;
}
}
}
else
{
if (!overflow)
overflow_count = 0;
overflow = true;
if (!(overflow_count % 10))
lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count);
}
r = aio_error(&a);
if (r == EINPROGRESS)
{
lt_debug("%s: aio in progress, free: %d\n", __func__, bufsize - buf_pos);
continue;
}
// not calling aio_return causes a memory leak --martii
r = aio_return(&a);
if (r < 0)
{
exit_flag = RECORD_FAILED_FILE;
lt_debug("%s: aio_return = %d (%m)\n", __func__, r);
break;
}
else
lt_debug("%s: aio_return = %d, free: %d\n", __func__, r, bufsize - buf_pos);
if (posix_fadvise(file_fd, 0, 0, POSIX_FADV_DONTNEED))
perror("posix_fadvise");
if (queued)
{
memmove(buf, buf + queued, buf_pos - queued);
buf_pos -= queued;
}
queued = buf_pos;
a.aio_buf = buf;
a.aio_nbytes = queued;
r = aio_write(&a);
if (r)
{
lt_info("%s: aio_write %d (%m)\n", __func__, r);
exit_flag = RECORD_FAILED_FILE;
break;
}
}
dmx->Stop();
while (true) /* write out the unwritten buffer content */
{
lt_debug("%s: run-out write, buf_pos %d\n", __func__, buf_pos);
r = aio_error(&a);
if (r == EINPROGRESS)
{
usleep(50000);
continue;
}
r = aio_return(&a);
if (r < 0)
{
exit_flag = RECORD_FAILED_FILE;
lt_info("%s: aio_result: %d (%m)\n", __func__, r);
break;
}
if (!queued)
break;
memmove(buf, buf + queued, buf_pos - queued);
buf_pos -= queued;
queued = buf_pos;
a.aio_buf = buf;
a.aio_nbytes = queued;
r = aio_write(&a);
}
free(buf);
#if 0
// TODO: do we need to notify neutrino about failing recording?
CEventServer eventServer;
eventServer.registerEvent2(NeutrinoMessages::EVT_RECORDING_ENDED, CEventServer::INITID_NEUTRINO, "/tmp/neutrino.sock");
stream2file_status2_t s;
s.status = exit_flag;
strncpy(s.filename,basename(myfilename),512);
s.filename[511] = '\0';
strncpy(s.dir,dirname(myfilename),100);
s.dir[99] = '\0';
eventServer.sendEvent(NeutrinoMessages::EVT_RECORDING_ENDED, CEventServer::INITID_NEUTRINO, &s, sizeof(s));
printf("[stream2file]: pthreads exit code: %i, dir: '%s', filename: '%s' myfilename: '%s'\n", exit_flag, s.dir, s.filename, myfilename);
#endif
if ((exit_flag != RECORD_STOPPED) && failureCallback)
failureCallback(failureData);
lt_info("%s: end\n", __func__);
pthread_exit(NULL);
}
int cRecord::GetStatus()
{
return (exit_flag == RECORD_STOPPED) ? REC_STATUS_STOPPED : REC_STATUS_OK;
}
void cRecord::ResetStatus()
{
return;
}

57
libarmbox/record_lib.h Normal file
View File

@@ -0,0 +1,57 @@
#ifndef __RECORD_TD_H
#define __RECORD_TD_H
#include <pthread.h>
#include <semaphore.h>
#include "dmx_lib.h"
#define REC_STATUS_OK 0
#define REC_STATUS_SLOW 1
#define REC_STATUS_OVERFLOW 2
#define REC_STATUS_STOPPED 4
typedef enum {
RECORD_RUNNING,
RECORD_STOPPED,
RECORD_FAILED_READ, /* failed to read from DMX */
RECORD_FAILED_OVERFLOW, /* cannot write fast enough */
RECORD_FAILED_FILE, /* cannot write to file */
RECORD_FAILED_MEMORY /* out of memory */
} record_state_t;
class cRecord
{
private:
int file_fd;
int dmx_num;
cDemux *dmx;
pthread_t record_thread;
bool record_thread_running;
record_state_t exit_flag;
int state;
int bufsize;
int bufsize_dmx;
void (*failureCallback)(void *);
void *failureData;
sem_t sem;
#define RECORD_WRITER_CHUNKS 16
unsigned char *io_buf[RECORD_WRITER_CHUNKS];
size_t io_len[RECORD_WRITER_CHUNKS];
public:
cRecord(int num = 0, int bs_dmx = 2048 * 1024, int bs = 4096 * 1024);
void setFailureCallback(void (*f)(void *), void *d) { failureCallback = f; failureData = d; }
~cRecord();
bool Open();
bool Start(int fd, unsigned short vpid, unsigned short *apids, int numapids, uint64_t ch = 0);
bool Stop(void);
bool AddPid(unsigned short pid);
int GetStatus();
void ResetStatus();
bool ChangePids(unsigned short vpid, unsigned short *apids, int numapids);
void RecordThread();
void WriterThread();
};
#endif

1065
libarmbox/video.cpp Normal file

File diff suppressed because it is too large Load Diff

254
libarmbox/video_lib.h Normal file
View File

@@ -0,0 +1,254 @@
#ifndef _VIDEO_TD_H
#define _VIDEO_TD_H
#include <linux/dvb/video.h>
#include "../common/cs_types.h"
#include "dmx_lib.h"
typedef struct cs_vs_format_t
{
char format[16];
} cs_vs_format_struct_t;
typedef enum {
ANALOG_SD_RGB_CINCH = 0x00,
ANALOG_SD_YPRPB_CINCH,
ANALOG_HD_RGB_CINCH,
ANALOG_HD_YPRPB_CINCH,
ANALOG_SD_RGB_SCART = 0x10,
ANALOG_SD_YPRPB_SCART,
ANALOG_HD_RGB_SCART,
ANALOG_HD_YPRPB_SCART,
ANALOG_SCART_MASK = 0x10
} analog_mode_t;
typedef enum {
COLORFORMAT_RGB = 0x10, // keep compatible with analog_mode_t
COLORFORMAT_YUV,
COLORFORMAT_CVBS,
COLORFORMAT_SVIDEO,
COLORFORMAT_HDMI_RGB,
COLORFORMAT_HDMI_YCBCR444,
COLORFORMAT_HDMI_YCBCR422
} COLOR_FORMAT;
typedef enum {
VIDEO_FORMAT_MPEG2 = 0,
VIDEO_FORMAT_MPEG4_H264,
VIDEO_FORMAT_VC1,
VIDEO_FORMAT_JPEG,
VIDEO_FORMAT_GIF,
VIDEO_FORMAT_PNG,
VIDEO_FORMAT_MPEG4_H265,
VIDEO_FORMAT_AVS = 16
} VIDEO_FORMAT;
typedef enum {
VIDEO_SD = 0,
VIDEO_HD,
VIDEO_120x60i,
VIDEO_320x240i,
VIDEO_1440x800i,
VIDEO_360x288i
} VIDEO_DEFINITION;
typedef enum {
VIDEO_FRAME_RATE_23_976 = 0,
VIDEO_FRAME_RATE_24,
VIDEO_FRAME_RATE_25,
VIDEO_FRAME_RATE_29_97,
VIDEO_FRAME_RATE_30,
VIDEO_FRAME_RATE_50,
VIDEO_FRAME_RATE_59_94,
VIDEO_FRAME_RATE_60
} VIDEO_FRAME_RATE;
typedef enum {
DISPLAY_AR_1_1,
DISPLAY_AR_4_3,
DISPLAY_AR_14_9,
DISPLAY_AR_16_9,
DISPLAY_AR_20_9,
DISPLAY_AR_RAW
} DISPLAY_AR;
typedef enum {
DISPLAY_AR_MODE_PANSCAN = 0,
DISPLAY_AR_MODE_LETTERBOX,
DISPLAY_AR_MODE_NONE,
DISPLAY_AR_MODE_PANSCAN2
} DISPLAY_AR_MODE;
typedef enum {
VIDEO_DB_DR_NEITHER = 0,
VIDEO_DB_ON,
VIDEO_DB_DR_BOTH
} VIDEO_DB_DR;
typedef enum {
VIDEO_PLAY_STILL = 0,
VIDEO_PLAY_CLIP,
VIDEO_PLAY_TRICK,
VIDEO_PLAY_MOTION,
VIDEO_PLAY_MOTION_NO_SYNC
} VIDEO_PLAY_MODE;
typedef enum {
VIDEO_STD_NTSC,
VIDEO_STD_SECAM,
VIDEO_STD_PAL,
VIDEO_STD_480P,
VIDEO_STD_576P,
VIDEO_STD_720P60,
VIDEO_STD_1080I60,
VIDEO_STD_720P50,
VIDEO_STD_1080I50,
VIDEO_STD_1080P30,
VIDEO_STD_1080P24,
VIDEO_STD_1080P25,
VIDEO_STD_1080P50,
VIDEO_STD_1080P60,
VIDEO_STD_1080P2397,
VIDEO_STD_1080P2997,
VIDEO_STD_2160P24,
VIDEO_STD_2160P25,
VIDEO_STD_2160P30,
VIDEO_STD_2160P50,
VIDEO_STD_AUTO,
VIDEO_STD_MAX = VIDEO_STD_AUTO
} VIDEO_STD;
typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER = 3,
VIDEO_HDMI_CEC_MODE_RECORDER = 1
} VIDEO_HDMI_CEC_MODE;
typedef enum
{
VIDEO_CONTROL_BRIGHTNESS = 0,
VIDEO_CONTROL_CONTRAST,
VIDEO_CONTROL_SATURATION,
VIDEO_CONTROL_HUE,
VIDEO_CONTROL_SHARPNESS,
VIDEO_CONTROL_MAX = VIDEO_CONTROL_SHARPNESS
} VIDEO_CONTROL;
struct cec_message
{
unsigned char address;
unsigned char length;
unsigned char data[256];
}__attribute__((packed));
#define cec_rx_message cec_message
struct addressinfo
{
unsigned char logical;
unsigned char physical[2];
unsigned char type;
};
class cVideo
{
friend class cDemux;
friend class cPlayback;
private:
/* video device */
int fd;
unsigned int devnum;
/* apparently we cannot query the driver's state
=> remember it */
video_play_state_t playstate;
int /*vidDispMode_t*/ croppingMode;
int /*vidOutFmt_t*/ outputformat;
VIDEO_FORMAT StreamType;
VIDEO_DEFINITION VideoDefinition;
DISPLAY_AR DisplayAR;
VIDEO_PLAY_MODE SyncMode;
DISPLAY_AR_MODE ARMode;
VIDEO_DB_DR eDbDr;
DISPLAY_AR PictureAR;
VIDEO_FRAME_RATE FrameRate;
int video_standby;
int brightness;
int contrast;
int saturation;
int hue;
/* used internally by dmx */
int64_t GetPTS(void);
unsigned char physicalAddress[2];
bool standby_cec_activ,autoview_cec_activ;
unsigned char deviceType, logicalAddress;
int hdmiFd;
public:
/* constructor & destructor */
cVideo(int mode, void *, void *, unsigned int unit = 0);
~cVideo(void);
/* used internally by playback */
void openDevice(void);
void closeDevice(void);
void * GetTVEnc() { return NULL; };
void * GetTVEncSD() { return NULL; };
/* aspect ratio */
int getAspectRatio(void);
void getPictureInfo(int &width, int &height, int &rate);
int setAspectRatio(int aspect, int mode);
/* cropping mode */
int setCroppingMode(int x = 0 /*vidDispMode_t x = VID_DISPMODE_NORM*/);
/* get play state */
int getPlayState(void);
/* blank on freeze */
int getBlank(void);
int setBlank(int enable);
/* change video play state. Parameters are all unused. */
int Start(void *PcrChannel = NULL, unsigned short PcrPid = 0, unsigned short VideoPid = 0, void *x = NULL);
int Stop(bool blank = true);
bool Pause(void);
/* get video system infos */
int GetVideoSystem(void);
/* when system = -1 then use current video system */
void GetVideoSystemFormatName(cs_vs_format_t* format, int system);
/* set video_system */
int SetVideoSystem(int video_system, bool remember = true);
int SetStreamType(VIDEO_FORMAT type);
void SetSyncMode(AVSYNC_TYPE mode);
bool SetCECMode(VIDEO_HDMI_CEC_MODE);
void SetCECAutoView(bool);
void SetCECAutoStandby(bool);
void GetCECAddressInfo();
void SendCECMessage(struct cec_message &message);
void SetCECState(bool state);
void ReportPhysicalAddress();
void ShowPicture(const char * fname);
void StopPicture();
void Standby(unsigned int bOn);
void Pig(int x, int y, int w, int h, int osd_w = 1064, int osd_h = 600, int startx = 0, int starty = 0, int endx = 1279, int endy = 719);
void SetControl(int, int);
void setContrast(int val);
void SetVideoMode(analog_mode_t mode);
void SetDBDR(int) { return; };
void SetAudioHandle(void *) { return; };
void SetAutoModes(int [VIDEO_STD_MAX]) { return; };
int OpenVBI(int) { return 0; };
int CloseVBI(void) { return 0; };
int StartVBI(unsigned short) { return 0; };
int StopVBI(void) { return 0; };
void SetDemux(cDemux *dmx);
void SetColorFormat(COLOR_FORMAT color_format);
bool GetScreenImage(unsigned char * &data, int &xres, int &yres, bool get_video = true, bool get_osd = false, bool scale_to_video = false);
};
#endif

27
libduckbox/Makefile.am Normal file
View File

@@ -0,0 +1,27 @@
noinst_LTLIBRARIES = libduckbox.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
AM_CPPFLAGS += \
-I$(top_srcdir)/common \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libeplayer3/include
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \
@AVFORMAT_LIBS@ \
@AVUTIL_LIBS@ \
@AVCODEC_LIBS@ \
@SWRESAMPLE_LIBS@ \
-lpthread -lasound -lass -lrt
libduckbox_la_SOURCES = \
hardware_caps.c \
dmx.cpp \
video.cpp \
audio.cpp \
audio_mixer.cpp \
init.cpp \
playback_libeplayer3.cpp \
pwrmngr.cpp \
record.cpp

Some files were not shown because too many files have changed in this diff Show More