560 Commits

Author SHA1 Message Date
GetAway
3ff02b06f2 ShowPicture: return boolean expression 2019-01-12 11:48:14 +01:00
Thilo Graf
da0d4290a3 version_hal: simplify methodes
adopt method names similar to cs name convention
2019-01-02 17:30:05 +01:00
Thilo Graf
9bd798def2 configure: remove config from separat include dir
Not really needed
2019-01-02 17:29:34 +01:00
Thilo Graf
3869c32e82 configure: add missing entry
build was broken
2019-01-01 21:03:12 +01:00
Thilo Graf
ed8e3743d5 version_hal.cpp/h: add methodes to get package data 2019-01-01 16:03:12 +01:00
Thilo Graf
bc9eca8588 configure: add additional config header
config.h was not usable with neutrino.
2018-12-31 11:21:41 +01:00
Thilo Graf
1e47a62926 .gitignore: ignore some unneeded config and local stuff
picked from mpx branch
2018-12-31 11:20:31 +01:00
Jacek Jendrzej
4fecdd558a fix generic compil 2018-12-01 12:35:02 +01:00
Jacek Jendrzej
2e8aa93895 add getFD 2018-02-17 13:28:03 +01:00
Jacek Jendrzej
8d6b3f71c0 add dumb functions for streaminfo2 compil 2017-12-13 17:26:57 +01:00
Jacek Jendrzej
2673ba0940 fix possible segfault 2017-12-07 11:39:27 +01:00
Jacek Jendrzej
78b3403303 fix generic compil 2017-12-07 11:13:28 +01:00
Jacek Jendrzej
dd01a95ddb Revert "remove unused"
This reverts commit 3f9525e42e.
2017-11-03 19:57:28 +01:00
Jacek Jendrzej
3f9525e42e remove unused 2017-11-03 19:01:09 +01:00
Jacek Jendrzej
a47c399a19 fix generic build 2017-11-03 18:27:35 +01:00
Thilo Graf
056db018ab version 0.2.0-generic-pc
for generic-pc
2017-11-02 20:26:37 +01:00
Thilo Graf
793ae7a605 version 1.0.0-mpx
hd51 support
2017-11-02 20:12:56 +01:00
Thilo Graf
29a96a35bd adjust .gitignore for untracked files 2017-11-02 20:11:56 +01:00
Thilo Graf
c723af9313 add default files 2017-11-02 20:11:18 +01:00
Thilo Graf
328c93fb0d add update script 2017-11-02 20:11:12 +01:00
Jacek Jendrzej
6100244f5e return current_video_system 2017-08-23 14:30:12 +02:00
Jacek Jendrzej
41212e3c1a add GetVideoSystem() 2017-06-18 13:15:35 +02:00
Jacek Jendrzej
d1569e6114 fix compil 2017-06-15 13:20:22 +02:00
Jacek Jendrzej
497e31c3fd fix KEY_STOP typo 2017-04-15 14:18:47 +02:00
Jacek Jendrzej
ef8868cbbd fix error with empty video buffer 2017-03-22 19:29:57 +01:00
Jacek Jendrzej
757cce78af fix scale screenshot with clutterfb 2017-03-22 18:59:39 +01:00
Jacek Jendrzej
9823295de1 supplement to 85819d69ee, fix2 2017-03-22 17:37:37 +01:00
svenhoefer
c376875c39 Merge remote-tracking branch 'neutrino-mp/master' 2017-03-21 10:48:27 +01:00
svenhoefer
0f857a1836 - generic-pc/clutterfb.cpp: fix my stupid c/p error :/ 2017-03-20 20:58:24 +01:00
svenhoefer
055803dbac - generic-pc: add some more and change some existing keys; ...
I've tried to keep the functions on the right keys. 'r' for Radio,
't' for TV and so on.
2017-03-20 17:58:54 +01:00
Jacek Jendrzej
809c9047ea generic-pc/video.cpp dont set output format with negative height size 2017-03-20 14:30:16 +01:00
Stefan Seyfried
c3f4432496 libtriple: fix hw_caps build 2017-03-19 14:08:54 +01:00
svenhoefer
8709d3ad85 - .gitignore: add compile 2017-03-19 02:03:48 +01:00
Jacek Jendrzej
85819d69ee fix error handling in swscale 2017-03-18 15:12:21 +01:00
svenhoefer
e8ad377b4f - generic-pc/audio.cpp: add default-section to c->codec_id switch ...
to avoid compiler warnings
2017-03-17 11:19:27 +01:00
Jacek Jendrzej
ca355eecd1 check if av_image_fill_arrays return error 2017-03-16 19:06:06 +01:00
Stefan Seyfried
8a1bf4f41e Merge pull request #1 from tuxbox-neutrino/master
Some fixes by Jacek. :)
2017-03-15 20:49:39 +01:00
Jacek Jendrzej
89bd4b00c4 add GetScreenImage to cVideo 2017-03-15 19:07:35 +01:00
Jacek Jendrzej
e68a82cd50 fix audio video rate info 2017-03-14 21:31:02 +01:00
svenhoefer
82a6c40bc4 - cs_api.h: add missing cs_get_chip_type() dummy 2017-03-11 15:28:47 +01:00
Stefan Seyfried
4aed33ff9c hw_caps: add caps for 14:9 AR and broken tuner driver 2017-02-26 19:43:42 +01:00
Stefan Seyfried
d812ac52c5 spark/video: add missing O_CLOEXEC to memory fd 2017-02-19 17:54:56 +01:00
Stefan Seyfried
dac47fd266 pwrmngr: promote standby message to "info" 2017-02-19 17:54:19 +01:00
Stefan Seyfried
9715204498 generic/video: better A/V sync with clutterfb 2017-02-19 17:53:30 +01:00
Stefan Seyfried
9348cef2a6 generic/clutterfb: implement PIG 2017-02-19 17:52:12 +01:00
Stefan Seyfried
0226277758 triple: fix narrowing warning in video_td, add FD_CLOEXEC 2017-02-11 19:00:51 +01:00
Stefan Seyfried
aa683951fc td: fix GetScreenImage() for OSD-only mode 2017-02-09 00:02:57 +01:00
Stefan Seyfried
a5aeb217c5 acinclude: remove unused TUXBOX_APPS_* stuff 2017-02-04 09:23:46 +01:00
Stefan Seyfried
575107b5e1 configure: get rid of TUXBOX_APPS_*PKGCONFIG macros
Use PKG_PROG_PKG_CONFIG / PKG_CHECK_MODULES instead of home-grown macros
2017-02-04 09:23:46 +01:00
Stefan Seyfried
42fb4fe182 generic-pc: port audio/video decoders to newer ffmpeg API
this reduces the amount of deprecation warnings wih newer
ffmpeg releases quite a bit :-)
2016-11-12 17:47:02 +01:00
Stefan Seyfried
43a28b317c generic-pc: fix video shutdown 2016-11-03 11:33:42 +01:00
Stefan Seyfried
2525823506 generic-pc/video: fix stillpicture race condition 2016-10-30 15:57:18 +01:00
Stefan Seyfried
95d07cdfc9 generic-pc: add alternative clutter based framebuffer
Add a framebuffer implementation based on clutter instead of "raw"
OpenGL. The performance is slightly worse, but it might bring some
platform abstraction and other benefits for the future.
2016-10-30 13:08:34 +01:00
Stefan Seyfried
acac2e4f5a generic-pc: fix build with newer ffmpeg 2016-10-22 11:31:31 +02:00
Stefan Seyfried
fd2f0f1fd4 cPlayback: implement new libcoolstream interfaces
a new "Start" and changed "SelectSubtitles" function are
implemented to fix compilation (mostly stubbed out, though)
2016-10-22 11:29:32 +02:00
Stefan Seyfried
db3ec7352e hardware_caps: add boxarch field 2016-01-22 19:02:33 +01:00
Stefan Seyfried
42267080f9 libeplayer3: enable streams that use http auth 2016-01-09 15:43:30 +01:00
Stefan Seyfried
be9ebb472a libeplayer3: fix signed/unsigend comparison warning 2016-01-08 17:40:50 +01:00
Stefan Seyfried
635ce08a89 libspark: allow to seek backwards from EOF in cPlayback 2016-01-08 17:34:49 +01:00
Stefan Seyfried
238f2636d6 libspark: allow streams to play for more than 10 seconds
Neutrino determines "end of file" amongst others by checking if
the current position is less than one second before file length.
So for the streaming case, alwas pretend to be two seconds behind.
2016-01-08 17:29:56 +01:00
Stefan Seyfried
23c64535be libeplayer3: speed up Player::Stop() 2016-01-08 17:28:25 +01:00
Stefan Seyfried
66cc42cb19 libeplayer3: add comments to input class, fix warning 2016-01-08 17:27:51 +01:00
max10
d7403705d9 test aac 2016-01-08 17:23:35 +01:00
Stefan Seyfried
444ccdad5d libeplayer3: disable debug output printf's 2016-01-08 17:16:19 +01:00
Stefan Seyfried
042057b565 libeplayer3: add aac_adtstoasc bitstream filter
Add the aac_adtstoasc bitstream filter for AAC streams. In the
cases where it is not needed, it does not seem to hurt, and in
other cases it fixes audio playback.
TODO: improve the handling of the bsfc allocation / deallocation,
      this should go in a Track() destructor or similar.
2016-01-08 17:03:04 +01:00
Stefan Seyfried
18db6acbc2 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...)
2015-12-25 19:08:31 +01:00
Stefan Seyfried
d22660a4a1 add video_cs.h header to reduce number of #ifdefs needed 2015-12-25 16:28:06 +01:00
Stefan Seyfried
7613411406 ca: add SlotType parameter to SendCAPMT() 2015-12-13 16:45:27 +01:00
Stefan Seyfried
e7f5c17256 add cPlayback::GetReadCount() 2015-12-13 16:16:24 +01:00
Stefan Seyfried
d863ebc181 generic: fix build with newer openSUSE ffmpeg packages 2015-12-13 13:03:38 +01:00
Stefan Seyfried
a0037c51f0 spark: clear video in StopPicture()
this fixes video playback after audioplayer or upnp browser
2015-03-07 19:40:48 +01:00
Stefan Seyfried
49a9834ac5 spark/record: move buffer allocation outside record thread
move the allocation of the recording buffer outside the
recording thread, so that allocation failures can be
communicated as "failure to start recording" instantly
2015-03-07 18:59:04 +01:00
Stefan Seyfried
ef2df97bde libeplayer3: allow disabling of AAC hardware decoder
export HAL_AAC_SWDEC=1 before starting neutrino and
the (slow) software decoder will be used
2015-03-07 18:45:46 +01:00
max10
8f9a53e40c so it is better thx DboxOldie 2015-03-07 18:31:47 +01:00
max10
f163af47d2 add aac.cpp THX DboxOldie 2015-03-07 18:31:37 +01:00
Stefan Seyfried
00b856173d libspark/playback_libeplayer3: fix EOF signalling 2015-02-28 19:59:28 +01:00
Stefan Seyfried
0a53f3467e spark: select highest quality stream for multi-program streams 2015-02-27 20:06:01 +01:00
martii
9663f535cd libspark/hardware_caps: set has_SCART unconditionally 2015-02-27 18:31:33 +01:00
martii
3ba5512abc libspark: complement vendor ids 2015-02-27 18:30:59 +01:00
martii
0ec87d5a95 libspark/hardware_caps: recognize dvfd [untested] 2015-02-27 18:30:00 +01:00
martii
908df1e86e libspark/hw_caps: check vfd version first (needed to discriminate between Pingulux and Pingulux Plus) 2015-02-27 18:29:44 +01:00
Stefan Seyfried
ab076a85f8 spark: do not freeze/continue in GetScreenImage() 2015-02-25 21:47:36 +01:00
Stefan Seyfried
0dc812e80f spark: implement GetScreenImage for video and audio 2015-02-25 00:51:10 +01:00
Stefan Seyfried
3b6333cc59 spark: implement cRecord::GetStatus() 2015-02-22 22:23:59 +01:00
Stefan Seyfried
1df6cfc16d libspark: port a prior version of martii's cRecord
This imports most of the changes of martii's cRecord
https://gitorious.org/neutrino-hd/martiis-libstb-hal,
commmit 23bea61473
2015-02-22 22:21:33 +01:00
Stefan Seyfried
efb860f20d libtriple: remove absolute file names 2015-02-22 12:33:20 +01:00
Stefan Seyfried
f5e9cceb64 libeplayer3: remove absolute file names
this makes debug output nicer to read for out-of-tree builds
2015-02-22 12:08:47 +01:00
Stefan Seyfried
5007debb3a libspark: tone down cDemux debug messages 2015-02-21 22:26:25 +01:00
Stefan Seyfried
5904b79e38 spark: remove dead code from cDemux 2015-02-21 22:25:29 +01:00
Stefan Seyfried
5830d4adc3 spark: remove videodecoder hack from dmx destructor 2015-02-21 22:14:47 +01:00
Stefan Seyfried
d09ff5bb29 Revert "libspark/dmx: try to fix mysterious crash with gcc4.9"
This reverts commit 860d6bdbe7.

as known by now, this had nothing to do with gcc4.9, but with
the cDemux destructor racing with cDemux::Read()
2015-02-20 09:37:34 +01:00
Stefan Seyfried
2bb5b8e8a9 libspark/playback: fix hds streams by selecting a program
right now there is no way to specify which program to play,
just the first one is selected
2015-02-20 09:34:36 +01:00
Stefan Seyfried
e878f5f751 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.
2015-02-20 09:30:19 +01:00
Stefan Seyfried
860d6bdbe7 libspark/dmx: try to fix mysterious crash with gcc4.9 2015-02-15 19:54:37 +01:00
Stefan Seyfried
8e36402902 libeplayer3: try to fix dynamic linking 2015-02-13 19:55:54 +01:00
Stefan Seyfried
d1674e2327 libspark/playback_libeplayer3: switch to lt_info/lt_debug 2015-02-13 19:26:12 +01:00
Stefan Seyfried
62283244b4 spark: fix compiler warning in CVideo 2015-02-13 19:13:05 +01:00
martii
4e02a62e48 libspark/video: add missing newline 2015-02-13 18:33:38 +01:00
martii
8dd2a4091b libspark/video: ShowPicture: use VIDEO_STILLPICTURE 2015-02-13 18:32:02 +01:00
Stefan Seyfried
2f24c2bcba libspark/irmp: fix compiler warning 2015-02-13 18:20:58 +01:00
Stefan Seyfried
c2d2be320f libeplayer3: fix compiler warning 2015-02-13 18:15:48 +01:00
Stefan Seyfried
64f4702691 includes: remove *_td.h, we use is *_hal.h now 2015-02-13 18:13:10 +01:00
Stefan Seyfried
78f49580e0 use audio_hal.h and dmx_hal.h instead of *_td.h 2015-02-13 18:11:16 +01:00
Stefan Seyfried
100830e805 spark: use pkg-config for ffmpeg ldflags 2015-02-13 18:08:46 +01:00
Stefan Seyfried
d4365037f6 libeplayer: disable subtitle code
current neutrino is not prepared for this, so comment
it out to fix linking
2015-02-13 17:57:55 +01:00
Stefan Seyfried
dc5067e5d2 playback_libeplayer3: mention contributors in file header 2015-02-13 17:56:41 +01:00
Stefan Seyfried
270e282d1f spark: adpapt playback_libeplayer3 to martii's eplayer3 code
Most of this code is from martii, (see the original repo at
https://gitorious.org/neutrino-hd/martiis-libstb-hal). Unfortunately
our code bases have diverged enough that a proper merge or cherry-
picking with git, preserving authorship and history was not possible.
I do not claim authorship for most of this.
2015-02-13 17:48:47 +01:00
Stefan Seyfried
535b12d63a Merge branch 'martii-libeplayer3'
This merges the libeplayer3 changes from martii.
Does not even compile yet, libspark/player code needs
to be fixed first.

Conflicts:
  libeplayer3/Makefile.am libeplayer3/README
  libeplayer3/include/manager.h libeplayer3/include/misc.h
  libeplayer3/include/output.h libeplayer3/include/pes.h
  libeplayer3/include/writer.h
2015-02-13 11:58:21 +01:00
Stefan Seyfried
fc799dc6bf triple: remove videodecoder hack from dmx destructor 2015-02-06 19:56:19 +01:00
Stefan Seyfried
56e6d04719 triple: set audioDecoder to NULL in destructor
this avoids blowing up in the CPlayback destructor
2015-02-06 19:52:49 +01:00
Stefan Seyfried
746fe7bf87 triple: abuse dmx->getBuffer as 'dmx running' indicator 2015-02-06 19:46:30 +01:00
Stefan Seyfried
757f7de70c libeplayer3: add "subdir-objects" automake option 2015-01-26 10:20:48 +01:00
martii
67a6810022 libeplayer3/manager: use AVDISCARD_NONE instead of AVDISCARD_DEFAULT to disable programs 2014-08-31 12:36:22 +02:00
martii
79c203676f libeplayer3/h264: partially revert 9112c4d16d 2014-08-25 18:36:23 +02:00
martii
ad0b3175c1 libeplayer3: implement multi-program support 2014-08-22 18:53:52 +02:00
martii
099ccfe6bb libeplayer3/h264: simplify 2014-08-22 18:52:45 +02:00
martii
d4a8c87ec3 libeplayer3/input: amend 545732a12b 2014-07-28 18:02:50 +02:00
martii
760b46a373 libeplayer3/input: disable avformat logging 2014-07-27 11:09:45 +02:00
martii
8449c055e0 libeplayer3/input: don't modify avformat stream id 2014-07-27 10:36:43 +02:00
martii
8dd6d00ef1 libeplayer3/Makefile.am: set AUTOMAKE_OPTIONS = subdir-objects 2014-07-19 16:54:12 +02:00
martii
286955f888 libeplayer3/writer: minor cleanup, no binary change 2014-07-16 21:47:34 +02:00
martii
e7381352d4 libeplayer3/player: support bluray urls 2014-06-19 10:46:36 +02:00
martii
4e2ff2ce6d libeplayer3/input: allow access to AVFormatContext 2014-05-29 21:57:38 +02:00
martii
23d912c034 libeplayer3/writer/pcm.cpp: break potential infinite loop 2014-05-24 13:05:16 +02:00
martii
fe095b5a2c libeplayer3/input.cpp: filter duplicated messages 2014-05-24 13:04:06 +02:00
Stefan Seyfried
45576494e5 raspi: fix audio decoding with newer libavcodec
Current libavcodec does no longer always return S16 sample format, but
the conversion needs to be done explicitly. Use libswscale for that.
Not tested on raspbian, only on yocto/ffmpeg.
2014-05-03 21:01:38 +02:00
martii
33726e48d0 libeplayer3/input: no need for alloca() 2014-05-03 14:29:26 +02:00
martii
96ae9b1d40 libeplayer3/input: fix SwitchVideo (unused, but anyway) 2014-05-03 12:35:59 +02:00
martii
263f211cbe libeplayer3: limit video frame skipping to network streams 2014-05-02 15:05:47 +02:00
martii
b0a734c607 libeplayer3: skip video until first audio frame was found 2014-05-02 14:52:10 +02:00
martii
3c2f594147 libeplayer3: minor adjustments 2014-05-02 13:34:08 +02:00
martii
e7d95eb3d3 libeplayer3: fix audio switching on already terminated playback 2014-05-01 12:52:38 +02:00
martii
5ffbeafa49 libeplayer3/writer: add fd to writer class 2014-05-01 12:51:41 +02:00
martii
65890b2e14 libeplayer3/writer: add fd to writer class 2014-05-01 12:51:26 +02:00
martii
de993ea5b1 libeplayer3: cleanup AVFormatContext propagation to writers 2014-05-01 10:15:14 +02:00
martii
64a524ab5c libeplayer3/input: fix audio flush packet initialization 2014-05-01 10:01:36 +02:00
martii
5ab9e2deda libeplayer3/input: stream duration fix 2014-04-30 19:08:30 +02:00
martii
ef58a765bb libeplayer3: remove flac writer (now handled by mp3 writer) 2014-04-27 12:52:15 +02:00
martii
0fe0e5ce6d libeplayer3: remove flac writer (now handled by mp3 writer) 2014-04-27 12:51:40 +02:00
martii
f9931b3b1b libeplayer3/writer: implement decoder flushing 2014-04-27 12:45:15 +02:00
martii
d195c29769 libeplayer3/writer/pcm: remove debug output 2014-04-26 19:54:42 +02:00
martii
8128fe3289 libeplayer3/writer/pcm: move reinit code out of packet loop 2014-04-26 19:20:32 +02:00
martii
32e8bd8252 libeplayer3/writer: remove constructors/destructors from writer class 2014-04-26 14:57:22 +02:00
martii
35ff3bb69c libeplayer3/Makefile: minor rewrite 2014-04-26 14:56:15 +02:00
martii
1b4b110c26 libeplayer3: move calcPts to Input class 2014-04-26 14:54:38 +02:00
martii
fc658e27b0 libeplayer3/output: unbreak GetFrameCount() 2014-04-26 14:53:43 +02:00
martii
40557ac647 libeplayer3/writer/pcm: simplify 2014-04-26 14:53:02 +02:00
martii
dd7db83276 libeplayer3/input: unbreak dvbsub pts calculation 2014-04-26 14:51:54 +02:00
martii
a6b0acda6d libeplayer3/writer/pcm: cleanup 2014-04-21 14:08:40 +02:00
martii
bdc242d29b libeplayer3/writer/pcm: simplify pts handling 2014-04-21 14:00:51 +02:00
martii
6906e9f929 libeplayer3/writer/pcm: minor adjustments 2014-04-21 13:24:52 +02:00
martii
25811b99be libeplayer3: minimize debug output 2014-04-18 16:20:07 +02:00
martii
c5426c8596 libeplayer3: fix backward mode 2014-04-18 16:09:54 +02:00
martii
ae1bcb466b libeplayer3: use av_rescale for pts calulations 2014-04-18 11:16:44 +02:00
martii
9d6397ac35 libeplayer3/input: disable noprobe and retry if probing fails 2014-04-18 09:48:28 +02:00
martii
12845ab18c libeplayer3: minor adjustments 2014-04-16 17:26:53 +02:00
martii
a3eb634030 libeplayer3/writer/pcm: unbreak 2014-04-15 21:59:22 +02:00
martii
06449fcbfd libeplayer3/input: don't segv in deconstructor 2014-04-15 19:47:59 +02:00
martii
b4ec2c34b9 libeplayer3: optimizations (untested) 2014-04-15 17:12:22 +02:00
martii
62d526f799 libeplayer3: use uint64_t instead of float/double for position calculations 2014-04-14 21:47:40 +02:00
martii
046da3c411 libeplayer3/output: reset stream variables after Close() 2014-04-13 21:29:26 +02:00
martii
578dc39595 libeplayer3: minor optimization 2014-04-13 19:29:07 +02:00
martii
d53589353e libeplayer3/input: increase probesize 2014-04-13 16:30:33 +02:00
martii
4b648be6fa libeplayer3/input: fix AV_CODEC_ID_MP2 usage 2014-04-12 16:53:55 +02:00
martii
a8a2d917fb libeplayer3 adjustments 2014-04-11 18:40:39 +02:00
martii
bbe2472f2d libeplayer3: cast away compiler warning 2014-04-11 14:49:42 +02:00
martii
4da9260b54 libeplayer3: cleanup 2014-04-11 14:20:22 +02:00
martii
1a808def2f libeplayer3: ffmpeg now provides teletext details in codec->extradata 2014-04-11 14:11:36 +02:00
martii
6c594a7cda libeplayer3: cleanup 2014-04-10 23:51:17 +02:00
martii
be26d8d46b 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
478a83efad libeplayer3/input: rename some variables 2014-04-10 20:47:44 +02:00
martii
3f30607fbd libeplayer3/output: remove redundant videofd check 2014-04-10 20:46:39 +02:00
martii
5f340ec4a8 libeplayer3/writer: unsigned char => uint8_t 2014-04-10 20:45:57 +02:00
martii
33d7a29134 libeplayer3/Makefile: disable debugging flags 2014-04-09 22:07:12 +02:00
martii
6c340eb752 libeplayer3: extend API 2014-04-09 22:06:41 +02:00
martii
eafc00a861 libeplayer is now C++, no more need for extern "C" to access Neutrino functions 2014-04-08 20:42:17 +02:00
martii
2fc7cac404 libeplayer3: rename player thread 2014-04-08 20:24:22 +02:00
martii
7bb603a8af libeplayer3: change compile options 2014-04-08 20:12:35 +02:00
martii
bfbe8ed51a libeplayer3: track update: remove redundant teletext pid from return string 2014-04-08 20:10:05 +02:00
martii
cb3db6256c libeplayer3: continue refresh 2014-04-08 20:02:07 +02:00
martii
fcd1dc8399 libeplayer3: cleanups 2014-04-07 23:00:03 +02:00
martii
5448fb35bf libeplayer3: rename files 2014-04-07 21:34:01 +02:00
martii
514398ad2a libeplayer3: remove debug.h 2014-04-07 21:28:20 +02:00
martii
12c9643978 libeplayer3: merge Playback to Player class 2014-04-07 21:25:30 +02:00
martii
ca5effe1bc libeplayer3: implement Playback and Input classes 2014-04-07 21:01:02 +02:00
martii
1112111e2d libeplayer3: implement Manager class 2014-04-06 21:12:56 +02:00
martii
2067355059 libeplayer3: rename linuxdvb.cpp => output.cpp 2014-04-06 18:21:31 +02:00
martii
6e37a5bcc1 libeplayer3: implement Output class 2014-04-06 18:19:00 +02:00
martii
f945fe34aa libeplayer3: eliminate intermediate output layer 2014-04-06 13:30:20 +02:00
martii
2777eb4788 libeplayer3: rename common.h => player.h 2014-04-06 12:13:18 +02:00
martii
85fcd7379d libeplayer3: rename Content_t => Player 2014-04-06 12:11:40 +02:00
martii
7bf5a5f290 libeplayer3: remove unused code 2014-04-06 11:39:11 +02:00
martii
d97d2a84d8 libeplayer3: implement Writer class 2014-04-06 11:35:17 +02:00
martii
25948637ab libeplayer: simplify writer/pcm 2014-04-05 19:32:58 +02:00
martii
06c260681f libeplayer3: remove writeReverseData (unused) 2014-04-05 17:50:22 +02:00
martii
23bad752df libeplayer3: cleanup pcm writer 2014-04-05 17:44:42 +02:00
martii
9f9d1b64ce libeplayer: cleanup writers 2014-04-05 16:40:03 +02:00
martii
896a08e145 libeplayer3: unbreak ipcm 2014-04-05 16:34:03 +02:00
martii
1a04102c23 libeplayer3: let writers use AVPacket 2014-04-05 16:17:57 +02:00
martii
2d0ca622f8 libeplayer3: c++ adjustments 2014-04-05 16:02:06 +02:00
martii
97f1aff64f libeplayer3: rename to c++ 2014-04-05 16:01:12 +02:00
martii
15964474f3 libeplayer3: delete include/aac.h (unused) 2014-04-05 13:27:13 +02:00
martii
4ccc66e6cc libeplayer3: remove wmv version (unused) 2014-04-05 13:26:24 +02:00
martii
7a80a1f3e1 libeplayer: remove inject_raw_pcm (unused) 2014-04-05 13:24:39 +02:00
martii
500e8e8eac libeplayer3: move audio resampling to dedicated ipcm writer 2014-04-05 13:21:58 +02:00
martii
ff13f75588 libeplayer3: move width/height/framerate/timescale calculation to writers 2014-04-05 11:36:49 +02:00
martii
85bcfb4a17 libeplayer3: change extradata handling 2014-04-05 11:05:37 +02:00
martii
5e2d44cc5d libeplayer3: remove writer/wma.c and writer/aac.c (handled by ffmpeg instead) 2014-04-05 10:39:55 +02:00
martii
01144c864b libeplayer3: make ffmpeg data available to manager, output and writer 2014-04-05 10:16:30 +02:00
martii
a4baa13ed1 libeplayer3: cleanup types 2014-04-05 10:01:52 +02:00
martii
46cd3a2703 libeplayer3: remove tools 2014-04-05 09:51:24 +02:00
martii
9fbb682eda libeplayer3: remove tools 2014-04-05 09:50:56 +02:00
martii
ff24109403 libeplayer/container_ffmpeg: switch to ffmpeg 2.0 API 2014-04-03 18:10:03 +02:00
martii
794ced8b3d libeplayer3/container_ffmpeg: remove latestPts variable 2014-03-26 17:59:50 +01:00
martii
4f32aa4ea0 libeplayer3: more cleanups 2014-03-23 17:55:12 +01:00
martii
a0cd63ce87 libeplayer3: remove no longer needed teletext output handling 2014-03-23 14:46:31 +01:00
martii
9eb23c78f4 libeplayer3: change teletext handling to directly inject packets in tuxtext 2014-03-23 13:54:40 +01:00
martii
173880cb31 libeplayer3: cleanup unused code 2014-03-23 10:31:53 +01:00
martii
6fcfafc604 libeplayer3/container_ffmpeg: fix seek bitrate calculation 2014-03-23 10:09:17 +01:00
martii
7767f23a0f libeplayer3/container_ffmpeg: don't set pts if audio-only 2014-03-22 14:18:37 +01:00
martii
243bbc3f5b libeplayer3: initalize AVSubtitle 2014-03-22 13:27:34 +01:00
martii
dc9f75646c libeplayer3: remove debugging output; abort if neither an audio nor a video stream is available 2014-03-22 13:26:29 +01:00
martii
2c4979f6b5 cleanup 2014-03-21 23:27:37 +01:00
martii
77dce975a3 libeplayer3: remove subtitle.h 2014-03-21 22:37:55 +01:00
martii
6572e5538c libeplayer3/container_ffmpeg: drop subtitle.h include 2014-03-21 22:34:48 +01:00
martii
9393207c4c libeplayer3: cleanup 2014-03-21 20:18:17 +01:00
martii
cd7c6086d2 libeplayer3: subtitles will now be displayed by neutrino 2014-03-21 20:15:01 +01:00
martii
f60e040d03 libeplayer3: let neutrino handle bitmap subtitles 2014-03-16 07:29:38 +01:00
martii
0e55c3f01b eplayer3: fix playback termination handling 2014-03-09 14:24:50 +01:00
martii
76a42bda44 eplayer3: fix playback termination handling 2014-03-09 14:16:45 +01:00
Stefan Seyfried
d71950c4a2 start versioning libstb-hal 2014-02-23 15:13:15 +01:00
Stefan Seyfried
bbb50fc606 add dummy cPlayback GetTitles() and SetTitle(); 2014-02-23 15:02:31 +01:00
Stefan Seyfried
3ff4fd923b libtriple: do not read from invalid dmx 2014-02-23 14:38:58 +01:00
Stefan Seyfried
043bde93c1 update ca.h to currently used interface 2014-01-28 15:04:24 +01:00
Stefan Seyfried
4e30d5ded6 triple: hack cDemux::GetSource() 2014-01-25 20:23:51 +01:00
Stefan Seyfried
39103f03d2 remove obsolete copies of mmi.h 2014-01-23 13:18:19 +01:00
Stefan Seyfried
e3f53de4ae include/mmi: fix spelling (but keep compatibility) 2014-01-23 13:16:27 +01:00
martii
8da0fecb53 libeplayer3/libspark: cPlayback: implement retrieval of metadata 2014-01-19 12:25:35 +01:00
martii
5fb12c8048 libeplayer3/container_ffmpeg: fix metadata access 2014-01-18 16:54:41 +01:00
martii
dd242bda4a libeplayer3/playback: fix seeking/neutrino bookmarks 2013-12-30 12:26:02 +01:00
martii
0df645f5c7 libeplayer3, libspark/playback_libeplayer3: chapter support 2013-12-30 12:25:54 +01:00
martii
1073220ff4 libeplayer3/container_ffmpeg: only log ffmpeg errors at debug_level > 10 2013-12-30 12:17:42 +01:00
martii
ff099b9356 libeplayer3/container_ffmpeg: don't modify AVPacket internals (I don't believe this actually hurts, but better safe than sorry) 2013-12-30 12:17:31 +01:00
martii
80daefef90 libeplayer3/linuxdvb: reduce debug spam 2013-12-30 12:16:33 +01:00
martii
6546462c4e libspark/playback: speed up abort 2013-12-30 12:16:04 +01:00
martii
51a920d26f libeplayer3: cleanup, indent 2013-12-30 12:15:38 +01:00
martii
31482f5286 libeplayer3: fix audio recoding, yt aac stuttering should be gone now 2013-12-30 12:15:15 +01:00
martii
6c84031759 libeplayer3/playback: disable debugging output 2013-12-30 12:14:55 +01:00
martii
32ec25ec4d libeplayer3/ffmpeg: minor cleanup 2013-12-30 12:14:47 +01:00
martii
62df38174e fix last commits 2013-12-30 12:14:41 +01:00
martii
129206c5db libeplayer3: run through indent, no binary change 2013-12-30 12:14:09 +01:00
martii
c229a6019d libeplayer3/container: fix compiler warning 2013-12-30 12:11:34 +01:00
martii
051507623e libeplayer3/ffmpeg: rearrange seeking code 2013-12-30 12:10:59 +01:00
martii
455749f311 libeplayer3/ffmpeg: don't initialize container if context already exists 2013-12-30 12:10:46 +01:00
martii
db48911f37 libeplayer3: fix seeking 2013-12-30 12:10:32 +01:00
martii
7142d4de2d libeplayer3/ffmpeg: add 3gp and ogm extensions 2013-12-30 12:10:19 +01:00
martii
9b1c3353de libeplayer3: modify fast-backward 2013-12-30 12:09:49 +01:00
martii
a2631567fe tools/spark_fp: add flashing period option 2013-12-30 12:08:17 +01:00
martii
af5f30ae92 tools/spark_fp: add option for enabling/disabling icons 2013-12-30 12:05:02 +01:00
martii
ed9299c780 libspark/audio, libeplayer3: audio type adjustments 2013-12-30 11:32:36 +01:00
martii
be656d7cee libeplayer3/playback: fix seeking/neutrino bookmarks 2013-12-28 22:44:10 +01:00
Stefan Seyfried
beab047387 playback: add MAX_PLAYBACK_PIDS define
TODO: actually fix the code to return more than 10 PIDs.
2013-12-28 19:38:28 +01:00
Stefan Seyfried
f082c8dcd0 libspark: add missing librt to linker flags 2013-12-26 11:14:19 +01:00
Stefan Seyfried
4b8568d79a libspark: add missing unistd.h includes for gcc 4.7+ 2013-12-26 10:53:49 +01:00
martii
9b6880102e libeplayer3, libspark/playback_libeplayer3: chapter support 2013-12-23 16:47:29 +01:00
Stefan Seyfried
d76cf27929 pic2m2v: implement as a script
The C code was only calling ffmpeg binary anyway...
Additionally create a md5 sum of the input file to avoid
unnecessary conversions.
2013-12-21 23:56:11 +01:00
martii
4db66e226f libeplayer3/container_ffmpeg: only log ffmpeg errors at debug_level > 10 2013-12-17 15:39:11 +01:00
martii
2b1bb1f9ca 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
76bdd325c1 libeplayer3/linuxdvb: reduce debug spam 2013-12-15 15:14:35 +01:00
martii
b08a39c4c1 libspark/playback: speed up abort 2013-12-11 09:13:25 +01:00
martii
b6ba5ea298 libeplayer3: cleanup, indent 2013-12-09 16:47:15 +01:00
martii
8ce41532e7 libeplayer3: fix audio recoding, yt aac stuttering should be gone now 2013-12-09 12:15:37 +01:00
Stefan Seyfried
e4dba8b30e libtriple: avoid race conditions in cVideo::ShowPicture
ShowPicture() and Stop() were racing, and the calling order from
neutrino seems to be not necessarily "correct". With gcc-4.8 /
glibc-2.16 binaries it happened that on switching to radio mode,
ShowPicture() was called and then the Stop() from stopping video
playback happened. This broke the stillpicture. Fix by adding more
locks and explicitly bailing out of Stop() if a picture is shown.
2013-12-02 00:58:37 +01:00
Stefan Seyfried
f403e3b3e2 libtriple: load blank mpegs from DATADIR 2013-12-02 00:57:55 +01:00
Stefan Seyfried
1590198998 libtriple: fix build with yocto gcc-4.8.1/eglibc-2.16 toolchain 2013-11-24 20:47:56 +01:00
martii
2a720c6106 libeplayer3/playback: disable debugging output 2013-11-23 14:40:28 +01:00
martii
11191c62dd libeplayer3/ffmpeg: minor cleanup 2013-11-22 18:08:00 +01:00
martii
ad4a850426 fix last commits 2013-11-21 23:15:35 +01:00
martii
4b5391ad4d libeplayer3: run through indent, no binary change 2013-11-21 19:40:47 +01:00
martii
76f873e191 libeplayer3/container: fix compiler warning 2013-11-21 19:28:57 +01:00
martii
6de629b4af libeplayer3/ffmpeg: rearrange seeking code 2013-11-21 19:25:20 +01:00
martii
7e39d85631 libeplayer3/ffmpeg: don't initialize container if context already exists 2013-11-21 18:18:13 +01:00
martii
615f8d9708 libeplayer3: fix seeking 2013-11-19 22:38:26 +01:00
martii
6094f51e2d libeplayer3/ffmpeg: add 3gp and ogm extensions 2013-11-19 19:33:33 +01:00
martii
6fc19089c4 libeplayer3: modify fast-backward 2013-11-17 15:24:33 +01:00
martii
d61e9f4f2b libspark/audio, libeplayer3: audio type adjustments 2013-11-11 12:30:47 +01:00
Stefan Seyfried
5137575c11 libspark/eplayer3: fix ffmpeg linker flags 2013-11-09 23:18:08 +01:00
Stefan Seyfried
db22215f9e libspark: fix build after libeplayer update
only build tested for now.
2013-11-09 22:47:44 +01:00
Stefan Seyfried
a2a4651c46 libeplayer3: fix merge errors 2013-11-09 22:45:13 +01:00
martii
068769c110 libstb-hal/libspark/playback: add method for retrieving read-count 2013-11-09 22:40:08 +01:00
martii
6cff3e3377 libeplayer3: speed up termination 2013-11-09 22:39:41 +01:00
martii
6b3062d3ec libspark/player, libeplayer3/ffmpeg: improve termination handling 2013-11-09 22:39:32 +01:00
martii
7738a24be1 libspark/player: use int instead of short in some places 2013-11-09 22:37:56 +01:00
martii
fc06947ba7 libeplayer3/ffmpeg: minor cleanup 2013-11-09 22:36:26 +01:00
martii
e01a3d5312 libeplayer3/playback: convert mms urls to mmst instead of rtsp 2013-11-09 22:36:19 +01:00
martii
ff63d40176 libeplayer3/manager: initialize track IDs 2013-11-09 22:36:08 +01:00
martii
545a3208d4 libeplayer3: tracks update is now lock-free 2013-11-09 22:35:45 +01:00
martii
7645863bfb libeplayer3/container_ffmpeg: mutex fix 2013-11-09 22:35:38 +01:00
martii
f20fc1f81d libeplayer3/wmv: revert to (almost) original version 2013-11-09 22:35:30 +01:00
martii
60dd40a5ad libeplayer/text_srt: minor optimization 2013-11-09 22:35:23 +01:00
martii
07709ce1cd libeplayer3: drop non-shared framebuffer support 2013-11-09 22:00:19 +01:00
martii
a51f79352b libeplayer3: unbreak srt subs 2013-11-09 21:58:57 +01:00
martii
1a3ac317c2 libeplayer3: cleanup 2013-11-09 21:58:43 +01:00
martii
37c573041a libeplayer3: vc1, wmv: use InsertPesHeader for initial PES headers, too 2013-11-09 21:58:36 +01:00
martii
0fa7469487 libeplayer3/output/writer/: remove PesHeader memset (both wrong and unneeded) 2013-11-09 21:58:17 +01:00
martii
95d724ced0 libeplayer3 optimizations 2013-11-09 21:58:05 +01:00
martii
aa5f59c5e6 libeplayer3/container_ass: cosmetics 2013-11-09 21:56:28 +01:00
martii
998607edfc libeplayer3/container_ffmpeg: cleanup 2013-11-09 21:56:21 +01:00
martii
6931fcd838 libeplayer3/writer/framebuffer: small optimization 2013-11-09 21:56:14 +01:00
martii
027660da47 libeplayer3/container_ass: set thread name 2013-11-09 21:56:08 +01:00
martii
3bc8b09638 libeplayer3/pcm: cleanup 2013-11-09 21:55:59 +01:00
martii
5b9837b3a9 libeplayer3/pcm: minor clean-up, no code change 2013-11-09 21:55:51 +01:00
martii
d9e8115cae Fix libeplayer3's broken PCM injection implementation. Jumps in movieplayer now works without losing a/v sync. 2013-11-09 21:55:43 +01:00
martii
75da827371 libeplayer3/container_ffmpeg: don't flush instead of clear 2013-11-09 21:55:34 +01:00
martii
8e0c61ead0 libeplayer3: use uint32_t for frame buffer access 2013-11-09 21:55:23 +01:00
martii
9f27e84225 libeplayer3/continer_ass: crude hack to improve subtitle readability 2013-11-09 21:54:46 +01:00
martii
e7f0879153 libeplayer3/subtitles/spark: use backbuffer and blit 2013-11-09 21:54:22 +01:00
martii
185acae677 libeplayer3/container_ass: font size adjusted 2013-11-09 21:53:35 +01:00
martii
d301826998 libeplayer/playback: disable subtitle init hack 2013-11-09 21:53:27 +01:00
martii
864bd7d422 libeplayer3/subtitle: reduce debugging level 2013-11-09 21:53:18 +01:00
martii
c550a79d7c libeplayer3: initial attempt to unbreak ass/ssa subtitles 2013-11-09 21:53:12 +01:00
martii
5a255e9c4a libeplayer/linuxdvb: cleanup 2013-11-09 21:53:05 +01:00
martii
019b2a5dca libeplayer3/containter_ffmpeg: fix track update 2013-11-09 21:52:59 +01:00
martii
6395850a91 libeplayer3/container_ffmpeg: no need for copying the input packet 2013-11-09 21:52:50 +01:00
martii
0c295bcfc0 libeplayer/container_ffmpeg: subtitle fix 2013-11-09 21:52:42 +01:00
martii
10488303fc libeplayer3/container_ffmpeg.c: re-order packet.data check (not sure whether this is needed at all) 2013-11-09 21:52:35 +01:00
martii
c212dae7b1 libeplayer/container_ffmpeg: correct misplaced brackets 2013-11-09 21:52:15 +01:00
martii
8ba924c471 libeplayer3/container_ffmpeg: initialize stream ids, if unset 2013-11-09 21:51:37 +01:00
martii
e30ad7d035 libeplayer3/container_ffmpeg: av_samples_alloc: use actual number for channels 2013-11-09 21:51:21 +01:00
martii
c7ddfbf8be libeplayer3/container_ffmpeg: align av_samples_alloc buffer 2013-11-09 21:50:41 +01:00
martii
8f06d2558e libeplayer3/container_ffmpeg: fix mono->stereo conversion 2013-11-09 21:50:24 +01:00
martii
e3f1d23acc libeplayer/container_ffmpeg: audio pts fix 2013-11-09 21:50:08 +01:00
martii
1c296f02bf libeplayer3: remove outdated include/stm_ioctl.h 2013-11-09 21:49:47 +01:00
martii
40b3c4459d container_ffmpeg: flush streams immediately after seek 2013-11-09 21:49:39 +01:00
martii
396077ccb2 libeplayer3: cleanup 2013-11-09 21:49:31 +01:00
martii
a49a33c983 libeplayer: reduce debugging output 2013-11-09 21:49:21 +01:00
martii
852d4e69ea h264: don't mess with packet length 2013-11-09 21:49:13 +01:00
martii
b59343cf69 libeplayer3/h264: unbreak 2013-11-09 21:48:29 +01:00
martii
80a86fa72f libeplayer3/container_ffmpeg: No attributes needed for mutex init 2013-11-09 21:48:14 +01:00
martii
9d51907c5d libeplayer3 cleanup 2013-11-09 21:47:45 +01:00
martii
51f112dabb libeplayer3/h264 cleanup 2013-11-09 21:47:32 +01:00
martii
f61395efdf libeplayer3: experimental h.264 playback fix 2013-11-09 21:47:01 +01:00
martii
b9c8d61b3a libeplayer3: cleanup 2013-11-09 21:46:43 +01:00
martii
8affebdef6 libeplayer3: use actual pids instead of indexes 2013-11-09 21:46:26 +01:00
martii
12f6a51f49 ffmpeg-2.0 2013-11-09 21:42:04 +01:00
martii
22d4f40fb9 libeplayer3/container_ffmpeg: revert swr_next_pts call 2013-11-09 21:41:41 +01:00
martii
dfa1a3e32b libeplayer3: minor changes 2013-11-09 21:41:30 +01:00
martii
dc85e1c284 libeplayer3: re-enable audio after seeking (still broken) 2013-11-09 21:39:30 +01:00
martii
5e38511807 libeplayer3: need to call avcodec_free_frame after swresample, too 2013-11-09 21:39:09 +01:00
martii
0a386a264d libeplayer3: the mp3 handler can easily take care of vorbis data, too. 2013-11-09 21:38:39 +01:00
martii
8e64b9c7b1 libeplayer3: vorbis can easily be handled by the mp3 writer 2013-11-09 21:38:21 +01:00
martii
96c0c7c3a5 libeplayer3/h264: disable debugging 2013-11-09 21:37:47 +01:00
martii
c3bbda3e9c libeplayer3: get rid of compiler warnings 2013-11-09 21:37:38 +01:00
martii
dd618fc883 libeplayer3: drop legacy ffmpeg support 2013-11-09 21:35:48 +01:00
martii
fffbbacd74 libeplayer/h264: Fix playback. 2013-11-09 21:34:52 +01:00
martii
267788f14e libeplayer3: deactivate debugging 2013-11-09 21:34:42 +01:00
martii
f5091bcd35 libeplayer3: cleanup 2013-11-09 21:31:50 +01:00
martii
546eb23e0e libeplayer3: further malloc-memcpy-write -> writev replacements; not fully regression tested 2013-11-09 21:27:07 +01:00
martii
9556f935bf libeplayer3/h264: replace malloc/memcpy/write with writev 2013-11-09 21:25:19 +01:00
martii
4e0f7f9a91 libeplayer3: drop buffering code due to crashes 2013-11-09 21:25:10 +01:00
martii
9ce0d977b1 replace libavresample with libswresample 2013-11-09 21:24:46 +01:00
martii
d5b57e281d libeplayer reverse play: experimental adjustment to find previous I-frame 2013-11-09 21:21:00 +01:00
martii
9edd4277c3 libeplayer3: fix segv 2013-11-09 21:20:52 +01:00
martii
2368ec790f eplayer3: subtitle fixes 2013-11-09 21:20:43 +01:00
martii
fec74fdcc7 crude hack for movieplayer tuxtxt integration 2013-11-09 21:20:34 +01:00
martii
6106d014e9 teletext handling changes 2013-11-09 21:20:14 +01:00
martii
8d3fba60a3 libeplayer3: dynamically update pid list 2013-11-09 21:19:21 +01:00
martii
a2e60ad48a libeplayer/container_ffmpeg: use injected PCM for raw PCM, too 2013-11-09 21:18:39 +01:00
martii
ed7c956e7f libeplayer3/container_ffmpeg: handle .wtv extensions, too 2013-11-09 21:18:32 +01:00
martii
4569654545 libeplayer3/container_ffmpeg: fix WMA playback 2013-11-09 21:18:24 +01:00
martii
9b2d5761a9 libeplayer3: add callback to abort avformat_open_input 2013-11-09 21:18:11 +01:00
martii
b976862530 libeplayer3/container_ffmpeg: cleanup 2013-11-09 21:17:37 +01:00
martii
aae498250b libeplayer3: merge buffered IO code from TDT; implement proper audio resampling 2013-11-09 21:15:30 +01:00
martii
fb8c2f33d1 libeplayer3/container_ffmpeg: minor cleanup 2013-11-09 21:15:04 +01:00
martii
824b328ec1 libeplayer3/container_ffmpeg: no need to scale the buffer 2013-11-09 21:14:30 +01:00
martii
a01b70f226 libeplayer3: this may improve recovery from broken streams 2013-11-09 21:14:21 +01:00
martii
dc95df1150 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-11-09 21:14:12 +01:00
martii
78307db056 libeplayer: set 65535 as maximum PES length 2013-11-09 21:14:04 +01:00
martii
e99a8fd76a libeplayer: assume unlimited PES length for too large packets 2013-11-09 21:13:56 +01:00
martii
0bee4efa6e libeplayer3: experimental fixes 2013-11-09 21:13:47 +01:00
martii
fd72343f69 libeplayer/playback: initialize length to -1 2013-11-09 21:13:25 +01:00
martii
525cd01c2c libeplayer3 fix 2013-11-09 21:13:18 +01:00
martii
1c1d85e582 libeplayer3: check for valid avContext pointer 2013-11-09 21:13:10 +01:00
martii
4cf92f8102 improve subtitle handling 2013-11-09 21:12:50 +01:00
martii
f0446eeeb2 libspark/libeplayer: rudimentary subtitle support, probably unstable 2013-11-09 21:12:20 +01:00
martii
1cc9619c49 get rid of most compiler warnings 2013-11-09 21:11:32 +01:00
martii
e94b7daf85 fix indent 2013-11-09 21:08:33 +01:00
martii
d431e60284 libeplayer3: add support for teletext and dvbsubtitle streams 2013-11-09 21:02:35 +01:00
Stefan Seyfried
8563837c8b libtriple: fix memory allocation size 2013-11-09 18:00:08 +01:00
Stefan Seyfried
4c74b822ca spark: add missing initialization of flt variable 2013-11-09 14:39:29 +01:00
Stefan Seyfried
8f7e6e981f generic-pc: fix exporting of vdec 2013-11-09 14:16:29 +01:00
Stefan Seyfried
2dd8dd1d20 raspi: rename EGL_CFLAGS to OMX_CFLAGS
we are not really interested in EGL but in OpenMAX ;-)
2013-11-07 10:53:25 +01:00
martii
33b204df8a libstb-hal/libspark/playback: add method for retrieving read-count 2013-11-04 14:15:21 +01:00
Stefan Seyfried
1b5a6076d9 raspi: comment unused variable which breaks newer ffmpeg 2013-11-03 14:18:45 +01:00
Stefan Seyfried
e953af61c2 raspi: update egl configure hack 2013-11-03 14:18:07 +01:00
Stefan Seyfried
32d83d32c5 raspi: use egl packages if available 2013-11-03 13:30:51 +01:00
Stefan Seyfried
ecab8ca7c0 install library headers 2013-11-03 01:28:07 +01:00
Stefan Seyfried
95a20e181b all: clean up cRecord header, hide private stuff 2013-11-03 01:04:27 +01:00
Stefan Seyfried
fc0300416b all: clean up pwrmngr header file 2013-11-03 00:15:19 +01:00
Stefan Seyfried
e746daaf5a all: clean up cPlayback header, hide private stuff
compile tested only ;)
2013-11-02 23:39:31 +01:00
Stefan Seyfried
d94e47c757 spark: use proc_tools 2013-11-02 20:24:56 +01:00
Stefan Seyfried
1311c58e35 move glfb.h to include dir 2013-11-02 20:23:56 +01:00
Stefan Seyfried
1166d49486 all: clean up cAudio header, separate private stuff 2013-11-02 20:06:29 +01:00
Stefan Seyfried
69527185a9 all: clean up cVideo header, separate private stuff 2013-11-02 18:44:34 +01:00
Stefan Seyfried
5a56339925 all: clean up cDemux headers 2013-11-02 16:44:39 +01:00
martii
77f26b69a6 libeplayer3: speed up termination 2013-11-02 16:02:33 +01:00
Stefan Seyfried
60cc22c58a all: clean up cs_api.h / init_td.h 2013-11-02 14:27:47 +01:00
martii
7434bcacae libspark/player, libeplayer3/ffmpeg: improve termination handling 2013-11-02 12:58:29 +01:00
Stefan Seyfried
0bfaccd2ee generic-pc: clean up cAudio header, separate private stuff 2013-11-01 21:52:05 +01:00
Stefan Seyfried
50b1d46af1 raspi: clean up cAudio header 2013-11-01 21:09:27 +01:00
Stefan Seyfried
9563559afb generic-pc: remove unused stuff from playback.h header 2013-11-01 20:47:31 +01:00
Stefan Seyfried
cc973092ed generic-pc: fix build with gcc 4.8 2013-11-01 20:38:30 +01:00
Stefan Seyfried
04ae3878cc raspi: add missing include dir 2013-11-01 20:36:28 +01:00
martii
ab3a145c63 libspark/player: use int instead of short in some places 2013-10-31 15:58:49 +01:00
Stefan Seyfried
d0a4a496ec generic-pc: rework glfb / cVideo internals
* hide implementation details in private classes / objects
* remove unneccessary internals from library include files
The goal is to finally have identical include files for all
platforms to faciliate easy cross-platform library installation.
2013-10-31 08:48:44 +01:00
Stefan Seyfried
91775a6029 move dependent headers into one directory
in preparation of proper installation of the lib
2013-10-27 14:34:45 +01:00
Stefan Seyfried
ffc375869b raspi: add support for MPEG2
TODO: check if the MPEG2 license is present (and warn if not)
2013-10-22 01:14:58 +02:00
Stefan Seyfried
de0950ffa9 raspi: cover the linux framebuffer with black background 2013-10-22 00:37:19 +02:00
Stefan Seyfried
c697d633aa generic-pc: don't crash in getAudioInfo if no codec is set 2013-10-21 17:44:31 +02:00
Stefan Seyfried
03754e8bc5 playback: add dummy RequestAbort() functions 2013-10-21 17:32:21 +02:00
Stefan Seyfried
0b1c4bcb9c raspi: first try of aspect ratio setting
this needs more work / testing with 4:3 input material
2013-10-21 00:29:01 +02:00
Stefan Seyfried
a78e983d5f raspi: improve set_volume 2013-10-21 00:21:56 +02:00
Stefan Seyfried
e0f5184900 raspi: first implementation of PIG in AVDec 2013-10-21 00:08:47 +02:00
Stefan Seyfried
824c602fb6 raspi/glfb: export info about display 2013-10-21 00:02:34 +02:00
Stefan Seyfried
0e49bfdb00 raspi/avdec: improve demux read function 2013-10-20 22:36:52 +02:00
Stefan Seyfried
2f7cb6401f raspi/AVDec: various improvements for A/V decoders
* retry on errors in the decoding loop
* better interaction with avcodec_omx
2013-10-20 01:11:36 +02:00
Stefan Seyfried
2784941b7e raspi/avcodec_omx: various hacks to the state machine
* fix invalid locking when for MSG_NEWCHANNEL
* fix restarting video decoder with proper omx teardown
2013-10-20 01:05:30 +02:00
Stefan Seyfried
b424d34536 raspi/codec: fix memleak when skipping packets 2013-10-20 01:04:40 +02:00
Stefan Seyfried
4c13442e05 raspi/avdec: allow setting audio out via RASPI_AUDIO variable 2013-10-20 01:02:56 +02:00
Stefan Seyfried
d71ae5b4f9 raspi/omx_utils: fix ordering of shutdown sequence
apparently, all ports need to be disabled before the inter-component
tunnels are teared down, otherwise video_decodeRIL:image pool objects
will leak
see http://www.raspberrypi.org/phpBB3/viewtopic.php?f=70&t=48177
2013-10-20 00:47:03 +02:00
Stefan Seyfried
d736e87d4e raspi/glfb: clean up objects on exit, remove double buffer 2013-10-20 00:03:12 +02:00
Stefan Seyfried
48df8f882a raspi: fix ordering of AVDec and GLFB
it looks like the videocore libs are leaking objects if
OMX_Init() is called after the dispmanx setup, so do it
in the correct order
2013-10-19 22:59:41 +02:00
Stefan Seyfried
fa1eadcc56 fix wrong libtool initialization order
allow to build dynamic libraries (but keep static as default)
2013-10-14 00:35:55 +02:00
Stefan Seyfried
06035e8ea1 raspi/avcodec_omx: set thread names 2013-10-13 22:51:30 +02:00
Stefan Seyfried
e9b6f6c88b lt_debug: use C linkage, allows usage from non-C++ code 2013-10-13 22:43:19 +02:00
Stefan Seyfried
510b655710 raspi: use decoder implementation from pidvbip
* remove ilclient
* use a decoder implementation similar to pidvbip instead,
  see https://github.com/linuxstb/pidvbip
* video is decoded in hardware (videocore)
* audio is decoded by libavcodec
* add a AVDec wrapper class for both audio and video decoders
* very raw, needs more polishing. But decodes audio and video :-)
* only tested with h264
2013-10-13 22:36:45 +02:00
martii
ec58e86ae4 libeplayer3/ffmpeg: minor cleanup 2013-10-12 19:11:17 +02:00
Stefan Seyfried
19b0ff20e1 raspi: add first try of video decoder implementation
This is very raw and unfinished, it clearly needs some more polishing.
But it decodes h264 channels :-)
2013-10-10 00:10:21 +02:00
Stefan Seyfried
0f9bc4f95c raspi: switch demux target to internal decoder 2013-10-10 00:05:55 +02:00
Stefan Seyfried
7c942c3745 raspi: add ilclient files
these are from the raspberrypi firmware git example apps that
show how to use the videocore for encoding / decoding.
I'll try to use them for accessing the a / v decoders.
License is 3-Clause BSD and thus compatible with GPLv2.
2013-10-09 23:50:50 +02:00
martii
2f7d1b15e0 libeplayer3/playback: convert mms urls to mmst instead of rtsp 2013-08-18 19:10:18 +02:00
martii
7d34affd1d libeplayer3/manager: initialize track IDs 2013-08-16 19:50:20 +02:00
martii
370efa3852 libeplayer3: tracks update is now lock-free 2013-08-16 19:35:07 +02:00
martii
d1a2ceaa67 libeplayer3/container_ffmpeg: mutex fix 2013-08-16 14:33:30 +02:00
martii
f5f0eb0f26 libeplayer3/wmv: revert to (almost) original version 2013-08-15 17:05:55 +02:00
martii
2c6b721987 libeplayer/text_srt: minor optimization 2013-08-04 16:42:21 +02:00
martii
cb34d91c57 libeplayer3: drop non-shared framebuffer support 2013-08-04 16:22:07 +02:00
martii
be2ae1cbd8 libeplayer3: unbreak srt subs 2013-08-04 16:21:39 +02:00
martii
baff0efeb4 revert 286675f430 2013-08-02 15:07:15 +02:00
martii
78ae8e8a62 libeplayer3: divx fix 2013-08-02 14:37:03 +02:00
martii
45f4924ee4 libeplayer3: cleanup 2013-08-02 12:44:51 +02:00
martii
9dd8efc76d libeplayer3: vc1, wmv: use InsertPesHeader for initial PES headers, too 2013-08-02 08:37:17 +02:00
martii
9987291e36 libeplayer3/output/writer/: remove PesHeader memset (both wrong and unneeded) 2013-08-01 20:35:22 +02:00
martii
3738572731 libeplayer3 optimizations 2013-07-29 18:35:48 +02:00
martii
e11af5361b libeplayer3/container_ass: cosmetics 2013-07-28 14:40:30 +02:00
martii
81aeb8f182 libeplayer3/container_ffmpeg: cleanup 2013-07-28 13:04:20 +02:00
martii
6147c3ef5e libeplayer3/writer/framebuffer: small optimization 2013-07-28 12:33:24 +02:00
martii
ef7ba87754 libeplayer3/container_ass: set thread name 2013-07-28 11:40:42 +02:00
martii
1215ab73a3 libeplayer3/pcm: cleanup 2013-07-28 10:12:36 +02:00
martii
373976ca3d libeplayer3/pcm: minor clean-up, no code change 2013-07-28 10:06:21 +02:00
martii
c004f52cca 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
4433f4ad43 libeplayer3/container_ffmpeg: don't flush instead of clear 2013-07-27 12:24:50 +02:00
martii
34cb8f4030 libeplayer3: use uint32_t for frame buffer access 2013-07-27 11:17:49 +02:00
martii
b6d6afc07f libeplayer3/continer_ass: crude hack to improve subtitle readability 2013-07-27 09:24:51 +02:00
martii
1fa3303cf7 libeplayer3/subtitles/spark: use backbuffer and blit 2013-07-27 08:12:03 +02:00
martii
6dba65cd53 libeplayer3/container_ass: font size adjusted 2013-07-26 22:50:26 +02:00
martii
0572e368df libeplayer/playback: disable subtitle init hack 2013-07-26 21:39:57 +02:00
martii
bed6d04851 libeplayer3/subtitle: reduce debugging level 2013-07-26 20:29:01 +02:00
martii
fbb8780418 libeplayer3: initial attempt to unbreak ass/ssa subtitles 2013-07-26 16:59:58 +02:00
martii
5734870578 libeplayer/linuxdvb: cleanup 2013-07-24 21:38:31 +02:00
martii
23da35350a libeplayer3/containter_ffmpeg: fix track update 2013-07-24 20:42:17 +02:00
martii
32f4d0b60b libeplayer3/container_ffmpeg: no need for copying the input packet 2013-07-23 21:45:44 +02:00
martii
65f9fc02d4 libeplayer/container_ffmpeg: subtitle fix 2013-07-23 21:00:14 +02:00
martii
2f34f9fd12 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
1523ad974e libeplayer/container_ffmpeg: correct misplaced brackets 2013-07-21 19:50:14 +02:00
martii
ccc7f61813 libeplayer3/container_ffmpeg: initialize stream ids, if unset 2013-07-21 19:02:58 +02:00
martii
ac29852565 libeplayer3/container_ffmpeg: av_samples_alloc: use actual number for channels 2013-07-21 16:17:18 +02:00
martii
d461967885 libeplayer3/container_ffmpeg: align av_samples_alloc buffer 2013-07-21 16:11:53 +02:00
martii
23356fa5d8 libeplayer3/container_ffmpeg: fix mono->stereo conversion 2013-07-21 14:54:57 +02:00
martii
a4f6f6e6b4 libeplayer/container_ffmpeg: audio pts fix 2013-07-21 12:06:38 +02:00
martii
f8787493bf libeplayer3: remove outdated include/stm_ioctl.h 2013-07-20 15:36:22 +02:00
martii
6bb00d7bc7 container_ffmpeg: flush streams immediately after seek 2013-07-20 09:08:31 +02:00
martii
a1c809cd47 libeplayer3: cleanup 2013-07-19 14:36:25 +02:00
martii
025e2082e9 libeplayer: reduce debugging output 2013-07-19 10:43:56 +02:00
martii
44f19e563a h264: don't mess with packet length 2013-07-19 10:30:04 +02:00
martii
876c7e95e1 libeplayer3/h264: unbreak 2013-07-14 16:07:15 +02:00
martii
ea4054f258 libeplayer3/container_ffmpeg: No attributes needed for mutex init 2013-07-14 15:17:36 +02:00
martii
43f6a4cdb6 libeplayer3 cleanup 2013-07-14 14:55:48 +02:00
martii
13a488c1e3 libeplayer3/h264 cleanup 2013-07-14 13:36:19 +02:00
martii
28a5f96c8b libeplayer3: experimental h.264 playback fix 2013-07-14 13:30:50 +02:00
martii
ec73a2bcd4 libeplayer3: cleanup 2013-07-14 10:04:05 +02:00
martii
29d549ff3f libeplayer3: use actual pids instead of indexes 2013-07-12 22:34:39 +02:00
martii
233c330e4c ffmpeg-2.0 2013-07-10 19:27:57 +02:00
martii
42018c2f9c libeplayer3/container_ffmpeg: revert swr_next_pts call 2013-07-07 16:20:01 +02:00
martii
83756d1f9b libeplayer3: minor changes 2013-07-07 15:59:55 +02:00
martii
59d83d0bd4 libeplayer3: re-enable audio after seeking (still broken) 2013-07-07 10:34:29 +02:00
martii
fcd2c1b246 libeplayer3: need to call avcodec_free_frame after swresample, too 2013-07-06 17:06:01 +02:00
martii
4037122259 sync with seife 2013-06-19 12:41:13 +02:00
Stefan Seyfried
03c9c65bea modernize configure.ac and Makefile.am
autoconf-1.13 has new warnings, silence them by updating
the buildsystem
2013-06-16 22:16:12 +02:00
martii
b2eb2038d7 libeplayer3: the mp3 handler can easily take care of vorbis data, too. 2013-06-13 20:58:08 +02:00
martii
d2ee743530 libeplayer3: vorbis can easily be handled by the mp3 writer 2013-06-10 15:49:38 +02:00
martii
17a2a6553a libeplayer3/h264: disable debugging 2013-06-10 15:11:13 +02:00
martii
65e69b07fb libeplayer3: get rid of compiler warnings 2013-06-10 15:06:00 +02:00
martii
997af12a20 libeplayer3: drop legacy ffmpeg support 2013-06-10 13:13:52 +02:00
martii
429a9df2a5 libeplayer/h264: Fix playback. 2013-06-10 12:38:47 +02:00
martii
4b5228cfb0 libeplayer3: deactivate debugging 2013-06-08 12:34:19 +02:00
martii
4f56cae01d libeplayer3: cleanup 2013-06-08 12:05:36 +02:00
martii
6e25a6f00f libeplayer3: further malloc-memcpy-write -> writev replacements; not fully regression tested 2013-06-08 11:15:09 +02:00
martii
0d54652815 libeplayer3/h264: replace malloc/memcpy/write with writev 2013-06-08 10:19:40 +02:00
martii
076715fd68 libeplayer3: drop buffering code due to crashes 2013-06-07 15:16:29 +02:00
martii
b035d8ef59 replace libavresample with libswresample 2013-06-01 13:47:47 +02:00
martii
7b8f5aede9 libeplayer reverse play: experimental adjustment to find previous I-frame 2013-04-11 17:59:22 +02:00
martii
093b3fd51a libeplayer3: fix segv 2013-04-10 20:41:44 +02:00
martii
4a7c1fb975 eplayer3: subtitle fixes 2013-04-01 11:57:36 +02:00
martii
f3f3a49b87 crude hack for movieplayer tuxtxt integration 2013-03-31 11:55:51 +02:00
martii
76992e2f0c teletext handling changes 2013-03-29 18:14:52 +01:00
martii
997d162cd3 libeplayer3: dynamically update pid list 2013-03-25 20:42:36 +01:00
martii
9e74193f34 libeplayer3/playback_libeplayer3: change noprobe handling 2013-03-18 18:49:00 +01:00
martii
1a499b7054 libeplayer/container_ffmpeg: use injected PCM for raw PCM, too 2013-03-17 09:47:18 +01:00
martii
bd87abd06b libeplayer3/container_ffmpeg: handle .wtv extensions, too 2013-03-16 19:43:25 +01:00
martii
0cdfdc60ae libeplayer3/container_ffmpeg: fix WMA playback 2013-03-16 18:24:49 +01:00
martii
f546bd5218 libeplayer3: add callback to abort avformat_open_input 2013-03-10 15:44:30 +01:00
martii
bf87a25c4d libeplayer3/container_ffmpeg: cleanup 2013-03-09 16:40:54 +01:00
martii
ee0e87dc05 libeplayer3/container_ffmpeg: cleanup 2013-03-09 16:37:05 +01:00
martii
78c53d1baa libeplayer3: merge buffered IO code from TDT; implement proper audio resampling 2013-03-09 14:47:34 +01:00
martii
ba9ba931ed libeplayer3/container_ffmpeg: minor cleanup 2013-03-04 19:22:47 +01:00
martii
4417f2549d libeplayer3/container_ffmpeg: no need to scale the buffer 2013-03-04 17:37:44 +01:00
martii
8d5e5a7cd2 libeplayer3: this may improve recovery from broken streams 2013-03-03 20:55:39 +01:00
martii
d4c0cfe133 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
17f3713093 libeplayer: set 65535 as maximum PES length 2013-02-26 19:57:15 +01:00
martii
9bb9a8d5fd libeplayer: assume unlimited PES length for too large packets 2013-02-26 19:56:08 +01:00
martii
a367d1f5db sync with seife 2013-01-30 19:13:45 +01:00
martii
3641f0ef6f libeplayer3: experimental fixes 2013-01-17 18:37:45 +01:00
Stefan Seyfried
3f2a7a8809 deuglify library build
* build intermediate libraries for each subdirectory
* link those libs in main directory instead of single objects
* ugly hack in configure.ac to disable dynamic lib for now
2012-12-01 13:29:27 +01:00
martii
a8bb8bb705 libeplayer/playback: initialize length to -1 2012-11-12 14:20:55 +01:00
martii
0243da9367 libeplayer3 fix 2012-11-10 13:41:59 +01:00
martii
83fe4c7174 libeplayer3: check for valid avContext pointer 2012-11-09 17:43:11 +01:00
martii
0d9281063b improve subtitle handling 2012-11-06 14:34:31 +01:00
martii
4a7345e6e6 sync 2012-11-04 18:46:58 +01:00
martii
41daed4748 libspark/libeplayer: rudimentary subtitle support, probably unstable 2012-11-04 15:39:48 +01:00
Stefan Seyfried
e544fab4f2 libeplayer3: sync with tdt git commit 06fe782fd6
This ports this commit:
    Author: Matthias <matthias@Build-VM.(none)>
    Date:   Fri Oct 26 19:54:46 2012 +0200

        [libeplayer3] enable wav payback (16 bit le)
2012-11-03 17:25:52 +01:00
martii
986b39c04e get rid of most compiler warnings 2012-10-27 18:08:29 +02:00
martii
65c64c77b4 enable wav payback (16 bit le) (from TDT, thanks hellmaster1024) 2012-10-27 18:07:02 +02:00
martii
8b33e32cf8 libeplayer3: disable noprobe hack 2012-10-04 09:42:28 +02:00
martii
bf7e63689d sync 2012-10-04 09:32:05 +02:00
Stefan Seyfried
ed10c47327 libeplayer3: fix invalid free()
according to the man pages....
* dirname() can not return NULL
* the pointer returned by dirname must not be free()d
* strdup() can return NULL
2012-10-04 00:02:51 +02:00
Stefan Seyfried
c048f57223 libeplayer3: sync with tdt git commit fed2a419dc 2012-10-03 23:51:56 +02:00
Stefan Seyfried
df067953b4 libeplayer3: add hack to decrease libavcodec probe size
almost disable the libavcodec format probing when using
"myts://" instead of "file://" urls to improve startup speed
for timeshift etc
2012-10-03 23:22:58 +02:00
martii
07a0da1b99 eplayer3 h263 fix 2012-08-31 12:33:59 +02:00
martii
4d1b35e4ac fix indent 2012-08-13 18:42:15 +02:00
martii
2627072d1d libeplayer3: add support for teletext and dvbsubtitle streams 2012-08-04 13:31:28 +02:00
martii
1bcc899430 fix some movieplayer issues 2012-07-27 20:09:26 +02:00
martii
60aeebb68e libeplayer3: sync with tdt 2012-07-21 21:03:59 +02:00
martii
94d8b8b57d support newer ffmpeg versions 2012-07-13 16:22:19 +02:00
Stefan Seyfried
6f8ce7c8ca libeplayer3: silence a seemingly harmless warning 2012-04-08 17:16:06 +02:00
Stefan Seyfried
91582dc5af libeplayer3: get rid of __FILE__ for shorter logmessages 2012-02-26 16:11:45 +01:00
Stefan Seyfried
b83945b4ce libeplayer3: silence many warnings 2012-02-18 12:06:10 +01:00
Stefan Seyfried
ba958c809d build static libeplayer3 and link eplayer3 and meta against it 2012-02-18 12:05:11 +01:00
Stefan Seyfried
2693d2a21e spark: build libeplayer3 statically into libstb-hal 2012-02-15 00:17:38 +01:00
Stefan Seyfried
1005c3f53e add libeplayer3 from tdt git
This imports libeplayer3 as of commit 9160371ccc6 (2012-02-02)
git://gitorious.org/open-duckbox-project-sh4/tdt.git
It would be better to use the original repo, but I need too many
changes for now :-(
2012-02-14 23:01:24 +01:00
248 changed files with 10063 additions and 20389 deletions

10
.gitignore vendored
View File

@@ -1,21 +1,19 @@
/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

2027
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -2,15 +2,13 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libstb-hal.la
libstb_hal_la_SOURCES =
SUBDIRS = common tools libthread
bin_PROGRAMS = libstb-hal-test
SUBDIRS = common tools
#bin_PROGRAMS = libstb-hal-test
libstb_hal_la_LIBADD = \
common/libcommon.la \
libthread/libthread.la
common/libcommon.la
AM_CPPFLAGS = \
-I$(top_srcdir)/include
libstb_hal_la_LDFLAGS = -version-info 1:0:1
libstb_hal_test_SOURCES = libtest.cpp
libstb_hal_test_LDADD = libstb-hal.la
@@ -38,23 +36,28 @@ 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
libstb_hal_la_LIBADD += \
libarmbox/libarmbox.la
endif
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

View File

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

View File

@@ -84,6 +84,7 @@ AC_ARG_WITH($1,[ $6$7 [[PREFIX$4$5]]],[
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)
@@ -104,25 +105,28 @@ if test "$TARGET" = "cdk"; then
fi
TUXBOX_APPS_DIRECTORY_ONE(configdir,CONFIGDIR,localstatedir,/var,/tuxbox/config,
[--with-configdir=PATH ],[where to find the config files])
[--with-configdir=PATH ],[where to find the config files])
TUXBOX_APPS_DIRECTORY_ONE(datadir,DATADIR,datadir,/share,/tuxbox,
[--with-datadir=PATH ],[where to find data])
[--with-datadir=PATH ],[where to find data])
TUXBOX_APPS_DIRECTORY_ONE(fontdir,FONTDIR,datadir,/share,/fonts,
[--with-fontdir=PATH ],[where to find the fonts])
[--with-fontdir=PATH ],[where to find the fonts])
TUXBOX_APPS_DIRECTORY_ONE(gamesdir,GAMESDIR,localstatedir,/var,/tuxbox/games,
[--with-gamesdir=PATH ],[where games data is stored])
[--with-gamesdir=PATH ],[where games data is stored])
TUXBOX_APPS_DIRECTORY_ONE(libdir,LIBDIR,libdir,/lib,/tuxbox,
[--with-libdir=PATH ],[where to find the internal libs])
[--with-libdir=PATH ],[where to find the internal libs])
TUXBOX_APPS_DIRECTORY_ONE(plugindir,PLUGINDIR,libdir,/lib,/tuxbox/plugins,
[--with-plugindir=PATH ],[where to find the plugins])
[--with-plugindir=PATH ],[where to find the 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)])
[--with-themesdir=PATH ],[where to find the themes (don't change)])
])
dnl automake <= 1.6 needs this specifications
@@ -132,95 +136,38 @@ 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: tripledragon,spark,azbox,generic,duckbox,spark7162,armbox],
[ --with-boxtype valid values: dbox2,tripledragon,dreambox,ipbox,coolstream,spark,azbox,generic],
[case "${withval}" in
tripledragon|azbox|generic)
dbox2|dreambox|ipbox|tripledragon|coolstream|spark|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"
;;
hd51)
BOXTYPE="armbox"
BOXMODEL="$withval"
;;
vusolo4k)
BOXTYPE="armbox"
BOXMODEL="$withval"
;;
*)
AC_MSG_ERROR([bad value $withval for --with-boxtype]) ;;
esac], [BOXTYPE="generic"])
AC_ARG_WITH(boxmodel,
[ --with-boxmodel valid for generic: raspi
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
valid for spark: spark, spark7162
valid for armbox: hd51, vusolo4k],
[ --with-boxmodel valid for dreambox: dm500, dm500plus, dm600pvr, dm56x0, dm7000, dm7020, dm7025
valid for ipbox: ip200, ip250, ip350, ip400],
[case "${withval}" in
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
dm500|dm500plus|dm600pvr|dm56x0|dm7000|dm7020|dm7025)
if test "$BOXTYPE" = "dreambox"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
spark|spark7162)
if test "$BOXTYPE" = "spark"; then
ip200|ip250|ip350|ip400)
if test "$BOXTYPE" = "ipbox"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
@@ -233,141 +180,70 @@ AC_ARG_WITH(boxmodel,
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
;;
vusolo4k)
if test "$BOXTYPE" = "armbox"; then
BOXMODEL="$withval"
else
AC_MSG_ERROR([unknown model $withval for boxtype $BOXTYPE])
fi
;;
*)
AC_MSG_ERROR([unsupported value $withval for --with-boxmodel])
;;
esac])
esac],
[if test "$BOXTYPE" = "dreambox" -o "$BOXTYPE" = "ipbox" && test -z "$BOXMODEL"; then
AC_MSG_ERROR([Dreambox/IPBox needs --with-boxmodel])
fi])
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_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_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_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_HD51,test "$BOXMODEL" = "hd51")
AM_CONDITIONAL(BOXMODEL_VUSOLO4K,test "$BOXMODEL" = "vusolo4k")
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_RASPI,test "$BOXMODEL" = "raspi")
if test "$BOXTYPE" = "azbox"; then
if test "$BOXTYPE" = "dbox2"; then
AC_DEFINE(HAVE_DBOX_HARDWARE, 1, [building for a dbox2])
elif 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 goldenmedia 990 or edision pingulux])
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])
elif test "$BOXTYPE" = "generic"; then
AC_DEFINE(HAVE_GENERIC_HARDWARE, 1, [building for a generic device like a standard PC])
elif test "$BOXTYPE" = "duckbox"; then
AC_DEFINE(HAVE_DUCKBOX_HARDWARE, 1, [building for a duckbox])
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" = "raspi"; then
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])
elif test "$BOXMODEL" = "raspi"; then
AC_DEFINE(BOXMODEL_RASPI, 1, [Raspberry pi])
elif 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 / AX51])
elif test "$BOXMODEL" = "vusolo4k"; then
AC_DEFINE(BOXMODEL_VUSOLO4K, 1, [vusolo4k])
fi
])

View File

@@ -1,7 +1,8 @@
noinst_LTLIBRARIES = libazbox.la
AM_CPPFLAGS = \
-I$(top_srcdir)/common
-I$(top_srcdir)/common \
-I$(top_srcdir)/include
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = -lpthread
@@ -13,6 +14,5 @@ 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_lib.h"
#include "audio_hal.h"
#include "lt_debug.h"
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
@@ -20,54 +20,55 @@
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 *)
{
fd = -1;
clipfd = -1;
mixer_fd = -1;
openDevice();
Muted = false;
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;
}
cAudio::~cAudio(void)
{
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->fd >= 0) {
ioctl(P->fd, AUDIO_CONTINUE); /* enigma2 also does CONTINUE before close... */
close(P->fd);
P->fd = -1;
}
else
lt_info("openDevice: already open (fd = %d)\n", fd);
if (P->clipfd >= 0)
close(P->clipfd);
if (P->mixer_fd >= 0)
close(P->mixer_fd);
free(pdata);
}
void cAudio::closeDevice(void)
int cAudio::mute(void)
{
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;
return SetMute(true);
}
int cAudio::do_mute(bool enable, bool remember)
int cAudio::unmute(void)
{
lt_debug("%s(%d, %d)\n", __func__, enable, remember);
return SetMute(false);
}
if (remember)
Muted = enable;
int cAudio::SetMute(bool enable)
{
lt_debug("%s(%d)\n", __func__, enable);
muted = enable;
#if 0
/* does not work? */
if (ioctl(fd, AUDIO_SET_MUTE, enable) < 0 )
@@ -96,14 +97,14 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
lt_debug("%s(%d, %d)\n", __func__, left, right);
volume = (left + right) / 2;
if (clipfd != -1 && mixer_fd != -1) {
if (P->clipfd != -1 && P->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(mixer_fd, MIXER_WRITE(mixer_num), &tmp);
int ret = ioctl(P->mixer_fd, MIXER_WRITE(P->mixer_num), &tmp);
if (ret == -1)
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp);
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, P->mixer_num, tmp);
return ret;
}
@@ -111,7 +112,7 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
mixer.volume_left = map_volume(left);
mixer.volume_right = map_volume(right);
if (ioctl(fd, AUDIO_SET_MIXER, &mixer) < 0)
if (ioctl(P->fd, AUDIO_SET_MIXER, &mixer) < 0)
lt_info("%s: AUDIO_SET_MIXER failed (%m)\n", __func__);
return 0;
@@ -121,16 +122,16 @@ int cAudio::Start(void)
{
lt_debug("%s\n", __func__);
int ret;
ioctl(fd, AUDIO_CONTINUE);
ret = ioctl(fd, AUDIO_PLAY);
ioctl(P->fd, AUDIO_CONTINUE);
ret = ioctl(P->fd, AUDIO_PLAY);
return ret;
}
int cAudio::Stop(void)
{
lt_debug("%s\n", __func__);
ioctl(fd, AUDIO_STOP);
ioctl(fd, AUDIO_CONTINUE); /* no idea why we have to stop and then continue => enigma2 does it, too */
ioctl(P->fd, AUDIO_STOP);
ioctl(P->fd, AUDIO_CONTINUE); /* no idea why we have to stop and then continue => enigma2 does it, too */
return 0;
}
@@ -142,7 +143,7 @@ bool cAudio::Pause(bool /*Pcm*/)
void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
{
lt_debug("%s %d\n", __func__, Mode);
ioctl(fd, AUDIO_SET_AV_SYNC, Mode);
ioctl(P->fd, AUDIO_SET_AV_SYNC, Mode);
};
//AUDIO_ENCODING_AC3
@@ -158,7 +159,6 @@ 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(fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
if (ioctl(P->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 (clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd);
if (P->clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __func__, P->clipfd);
return -1;
}
mixer_num = -1;
mixer_fd = -1;
P->mixer_num = -1;
P->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. */
clipfd = open(dsp_dev, O_WRONLY|O_CLOEXEC);
if (clipfd < 0) {
P->clipfd = open(dsp_dev, O_WRONLY|O_CLOEXEC);
if (P->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(clipfd, SNDCTL_DSP_SETFMT, &fmt))
if (ioctl(P->clipfd, SNDCTL_DSP_SETFMT, &fmt))
perror("SNDCTL_DSP_SETFMT");
if (ioctl(clipfd, SNDCTL_DSP_CHANNELS, &ch))
if (ioctl(P->clipfd, SNDCTL_DSP_CHANNELS, &ch))
perror("SNDCTL_DSP_CHANNELS");
if (ioctl(clipfd, SNDCTL_DSP_SPEED, &srate))
if (ioctl(P->clipfd, SNDCTL_DSP_SPEED, &srate))
perror("SNDCTL_DSP_SPEED");
if (ioctl(clipfd, SNDCTL_DSP_RESET))
if (ioctl(P->clipfd, SNDCTL_DSP_RESET))
perror("SNDCTL_DSP_RESET");
if (!mix_dev)
return 0;
mixer_fd = open(mix_dev, O_RDWR|O_CLOEXEC);
if (mixer_fd < 0) {
P->mixer_fd = open(mix_dev, O_RDWR|O_CLOEXEC);
if (P->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) {
if (ioctl(P->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) {
if (ioctl(P->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(mixer_fd);
mixer_fd = -1;
close(P->mixer_fd);
P->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)
mixer_num = atoi(tmp);
P->mixer_num = atoi(tmp);
lt_info("%s: mixer_num is %d -> device %08x\n",
__func__, mixer_num, (mixer_num >= 0) ? (1 << mixer_num) : 0);
__func__, P->mixer_num, (P->mixer_num >= 0) ? (1 << P->mixer_num) : 0);
/* no error checking, you'd better know what you are doing... */
} else {
mixer_num = 0;
P->mixer_num = 0;
while (!(usable & 0x01)) {
mixer_num++;
P->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 (clipfd <= 0) {
if (P->clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1;
}
ret = write(clipfd, buffer, size);
ret = write(P->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 (clipfd <= 0) {
if (P->clipfd <= 0) {
lt_info("%s: clipfd not yet opened\n", __FUNCTION__);
return -1;
}
close(clipfd);
clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
close(P->clipfd);
P->clipfd = -1;
if (P->mixer_fd >= 0)
close(P->mixer_fd);
P->mixer_fd = -1;
setVolume(volume, volume);
return 0;
};
@@ -370,10 +370,15 @@ 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);
//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);
};
void cAudio::ScheduleMute(bool On)
@@ -386,8 +391,7 @@ void cAudio::EnableAnalogOut(bool enable)
lt_debug("%s %d\n", __FUNCTION__, enable);
};
#define AUDIO_BYPASS_ON 0
#define AUDIO_BYPASS_OFF 1
#if 0
void cAudio::setBypassMode(bool disable)
{
lt_debug("%s %d\n", __func__, disable);
@@ -396,3 +400,4 @@ void cAudio::setBypassMode(bool disable)
lt_info("%s AUDIO_SET_BYPASS_MODE %d: %m\n", __func__, mode);
return;
}
#endif

View File

@@ -1,98 +0,0 @@
/* 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

View File

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

View File

@@ -30,11 +30,13 @@
#include <cstring>
#include <cstdio>
#include <string>
#include "dmx_lib.h"
#include <sys/ioctl.h>
#include "dmx_hal.h"
#include "lt_debug.h"
/* Ugh... see comment in destructor for details... */
#include "video_lib.h"
#include "video_hal.h"
#include "video_priv.h"
extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
@@ -42,14 +44,8 @@ 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, _f); \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0);
cDemux *videoDemux = NULL;
@@ -88,9 +84,6 @@ cDemux::cDemux(int n)
else
num = n;
fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
}
cDemux::~cDemux()
@@ -165,8 +158,6 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP);
close(fd);
fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL)
{
dmx_tp_count--;
@@ -273,11 +264,13 @@ 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)
{
@@ -286,6 +279,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
}
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)
@@ -389,8 +383,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
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...
@@ -497,7 +494,7 @@ void cDemux::getSTC(int64_t * STC)
lt_debug("%s #%d\n", __func__, num);
int64_t pts = 0;
if (videoDecoder)
pts = videoDecoder->GetPTS();
pts = videoDecoder->vdec->GetPTS();
*STC = pts;
}

View File

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

View File

@@ -1,70 +0,0 @@
#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 Stefan Seyfried
* (C) 2010-2012,2016 Stefan Seyfried
*
* License: GPL v2 or later
*/
@@ -30,7 +30,9 @@ 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;
strcpy(caps.boxvendor, "AZBox");
const char *tmp;
char buf[64];
@@ -46,6 +48,7 @@ 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_lib.h"
#include "init_td.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)

View File

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

View File

@@ -1,62 +0,0 @@
#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

View File

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

View File

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

View File

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

View File

@@ -37,7 +37,9 @@
#include <proc_tools.h>
#include "video_lib.h"
#include "video_hal.h"
#include "video_priv.h"
#define VIDEO_DEVICE "/dev/dvb/adapter0/video0"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)
@@ -75,12 +77,22 @@ 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;
@@ -111,17 +123,17 @@ cVideo::cVideo(int, void *, void *, unsigned int)
close(blankfd);
}
openDevice();
Pig(-1, -1, -1, -1);
Pig(-1, -1, -1, -1, 1, 1);
}
cVideo::~cVideo(void)
VDec::~VDec(void)
{
closeDevice();
if (blank_data)
free(blank_data);
}
void cVideo::openDevice(void)
void VDec::openDevice(void)
{
int n = 0;
lt_debug("%s\n", __func__);
@@ -143,7 +155,7 @@ retry:
playstate = VIDEO_STOPPED;
}
void cVideo::closeDevice(void)
void VDec::closeDevice(void)
{
lt_debug("%s\n", __func__);
if (fd >= 0)
@@ -181,6 +193,11 @@ 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)
@@ -198,7 +215,7 @@ int cVideo::getAspectRatio(void)
return s.aspect_ratio * 2 + 1;
}
int cVideo::setCroppingMode(int /*vidDispMode_t format*/)
int cVideo::setCroppingMode(void)
{
return 0;
#if 0
@@ -215,6 +232,16 @@ int cVideo::setCroppingMode(int /*vidDispMode_t format*/)
}
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
@@ -227,7 +254,7 @@ int cVideo::Start(void * /*PcrChannel*/, unsigned short /*PcrPid*/, unsigned sho
return fop(ioctl, VIDEO_PLAY);
}
int cVideo::Stop(bool blank)
int VDec::Stop(bool blank)
{
lt_debug("%s(%d)\n", __FUNCTION__, blank);
if (stillpicture)
@@ -242,7 +269,12 @@ int cVideo::Stop(bool blank)
return fop(ioctl, VIDEO_STOP, blank ? 1 : 0);
}
int cVideo::setBlank(int)
int cVideo::setBlank(int b)
{
return vdec->setBlank(b);
}
int VDec::setBlank(int)
{
pthread_mutex_lock(&stillp_mutex);
if (blank_data)
@@ -291,7 +323,7 @@ int cVideo::SetVideoSystem(int video_system, bool remember)
int cVideo::getPlayState(void)
{
return playstate;
return vdec->playstate;
}
void cVideo::SetVideoMode(analog_mode_t mode)
@@ -319,8 +351,14 @@ void cVideo::SetVideoMode(analog_mode_t mode)
proc_put("/proc/stb/avs/0/colorformat", m, strlen(m));
}
void cVideo::ShowPicture(const char * fname)
bool 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];
@@ -332,18 +370,18 @@ void cVideo::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;
return ret;
}
if (fd < 0)
{
lt_info("%s: decoder not opened?\n", __func__);
return;
lt_info("%s: decoder not opened\n", __func__);
return ret;
}
strcpy(destname, "/var/cache");
if (stat(fname, &st2))
{
lt_info("%s: could not stat %s (%m)\n", __func__, fname);
return;
return ret;
}
mkdir(destname, 0755);
/* the cache filename is (example for /share/tuxbox/neutrino/icons/radiomode.jpg):
@@ -393,19 +431,25 @@ void cVideo::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;
return ret;
}
void cVideo::StopPicture()
{
lt_debug("%s\n", __func__);
stillpicture = false;
vdec->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)
@@ -428,26 +472,12 @@ int cVideo::getBlank(void)
return !ret;
}
/* this function is regularly called, checks if video parameters
changed and triggers appropriate actions */
void cVideo::VideoParamWatchdog(void)
void cVideo::Pig(int x, int y, int w, int h, int osd_w, int 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
vdec->Pig(x, y, w, h, osd_w, osd_h);
}
void cVideo::Pig(int x, int y, int w, int h, int osd_w, int osd_h)
void VDec::Pig(int x, int y, int w, int h, int osd_w, int osd_h)
{
char buffer[64];
int _x, _y, _w, _h;
@@ -509,6 +539,11 @@ 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;
@@ -554,6 +589,11 @@ 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",
@@ -585,7 +625,7 @@ int cVideo::SetStreamType(VIDEO_FORMAT type)
return 0;
}
int64_t cVideo::GetPTS(void)
int64_t VDec::GetPTS(void)
{
int64_t pts = 0;
if (ioctl(fd, VIDEO_GET_PTS, &pts) < 0)

View File

@@ -1,196 +0,0 @@
#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

60
azbox/video_priv.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* (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,22 +1,13 @@
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)/libdvbci
endif
-I $(top_srcdir)/include
if BOXTYPE_DUCKBOX
libcommon_la_SOURCES = \
ca_ci.cpp
else
libcommon_la_SOURCES = \
ca.cpp
endif
libcommon_la_SOURCES += \
lt_debug.cpp \
proc_tools.c
ca.cpp \
lt_debug.c \
proc_tools.c \
pwrmngr.cpp \
version_hal.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -1,315 +0,0 @@
#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 name[512];
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;
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;
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:
bool Init(void);
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!
void SetInitMask(enum CA_INIT_MASK InitMask);
/// Sets the frequency (in Hz) of the TS stream input (only valid for CI)
void SetTSClock(u32 /*Speed*/) { return; };
/// Start the CA module
bool Start(void);
/// Stops the CA module
void Stop(void);
/// Notify that the GUI is ready to receive messages
/// (CA messages coming from a module)
void Ready(bool Set);
/// Resets a module (if possible)
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*/) { return 0; };
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);
bool StopRecordCI( u64 TP, u16 SID, u8 source, u32 calen);
bool StopLiveCI( u64 TP, u16 SID, u8 source, u32 calen);
SlotIt FindFreeSlot(u64 tpid, u8 source, u16 sid, ca_map_t camap, unsigned char scrambled);
SlotIt GetSlot(unsigned int slot);
bool SendDateTime(void);
bool SendCaPMT(eDVBCISlot* slot);
void slot_pollthread(void *c);
void setSource(eDVBCISlot* slot);
bool checkQueueSize(eDVBCISlot* slot);
void process_tpdu(eDVBCISlot* slot, unsigned char tpdu_tag, __u8* data, int asn_data_length, int con_id);
bool checkChannelID(u64 chanID);
void setCheckLiveSlot(int check);
bool SendNullPMT(eDVBCISlot* slot);
bool CheckCerts(void);
void Test(int slot, CaIdVector caids);
void DelTest(int slot);
/// Virtual destructor
virtual ~cCA();
};
#endif ///__CA_H_

View File

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

View File

@@ -21,10 +21,16 @@
#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,8 +1,28 @@
#include <stdio.h>
#include <cstdlib>
/*
* (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 <config.h>
#include "pwrmngr.h"
#include "lt_debug.h"
#if HAVE_TRIPLEDRAGON
#include <stdio.h>
#include <cstdlib>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
@@ -11,32 +31,50 @@
#include <avs/avs_inf.h>
#include <tdpanel/lcdstuff.h>
#endif
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PWRMNGR, this, args)
#define lt_info(args...) _lt_info(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)
/* cpufreqmanager */
void cCpuFreqManager::Up(void)
{
lt_debug("%s(%d, %d)\n", __FUNCTION__, Active, Passive);
lt_debug("%s\n", __func__);
}
void cCpuFreqManager::Down(void)
{
lt_debug("%s\n", __func__);
}
void cCpuFreqManager::Reset(void)
{
lt_debug("%s\n", __func__);
}
/* those function dummies return true or "harmless" values */
bool cCpuFreqManager::SetDelta(unsigned long)
{
lt_debug("%s\n", __func__);
return true;
}
unsigned long cCpuFreqManager::GetDelta(void)
{
lt_debug("%s\n", __func__);
return 0;
}
unsigned long cCpuFreqManager::GetCpuFreq(void)
{
lt_debug("%s\n", __func__);
return 0;
}
bool cCpuFreqManager::SetCpuFreq(unsigned long f)
{
lt_info("%s(%lu) => set standby = %s\n", __func__, f, f?"true":"false");
#if HAVE_TRIPLEDRAGON
/* actually SetCpuFreq is used to determine if the system is in standby
this is an "elegant" hack, because:
* during a recording, cpu freq is kept "high", even if the box is sent to standby
@@ -47,7 +85,6 @@ bool cCpuFreqManager::SetCpuFreq(unsigned long f)
* f == 0 => max => not standby
* f == 50000000 => min => standby
*/
lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false");
int fd = open("/dev/stb/tdsystem", O_RDONLY);
if (fd < 0)
{
@@ -78,10 +115,38 @@ bool cCpuFreqManager::SetCpuFreq(unsigned long f)
}
close(fd);
#endif
return true;
}
//
cPowerManager::cPowerManager(void) { lt_debug("%s\n", __FUNCTION__); }
cPowerManager::~cPowerManager() { lt_debug("%s\n", __FUNCTION__); }
cCpuFreqManager::cCpuFreqManager(void)
{
lt_debug("%s\n", __func__);
}
/* powermanager */
bool cPowerManager::Open(void)
{
lt_debug("%s\n", __func__);
return true;
}
void cPowerManager::Close(void)
{
lt_debug("%s\n", __func__);
}
bool cPowerManager::SetStandby(bool Active, bool Passive)
{
lt_debug("%s(%d, %d)\n", __func__, Active, Passive);
return true;
}
cPowerManager::cPowerManager(void)
{
lt_debug("%s\n", __func__);
}
cPowerManager::~cPowerManager()
{
lt_debug("%s\n", __func__);
}

51
common/version_hal.cpp Normal file
View File

@@ -0,0 +1,51 @@
/*
* (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,9 +1,28 @@
AC_INIT([libstb-hal], [1.0.0])
# 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])
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
@@ -20,60 +39,66 @@ 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
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
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 ; 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])
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])
PKG_CHECK_MODULES([SWSCALE], [libswscale])
fi
if test x$BOXTYPE = xspark; then
# versions are probably not correct :-(
PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1])
PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0])
PKG_CHECK_MODULES([SWRESAMPLE], [libswresample])
PKG_CHECK_MODULES([AVUTIL], [libavutil])
fi
AC_OUTPUT([
Makefile
common/Makefile
libeplayer3/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,45 +1,41 @@
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 \
-I$(top_srcdir)/common
@AVUTIL_CFLAGS@ \
@CLUTTER_CFLAGS@
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \
-lglut -lGL -lGLU -lGLEW -lao \
-lao \
-lOpenThreads \
@AVFORMAT_LIBS@ \
@AVUTIL_LIBS@ \
@AVCODEC_LIBS@ \
@SWRESAMPLE_LIBS@ \
@SWSCALE_LIBS@
@SWSCALE_LIBS@ \
@CLUTTER_LIBS@
if USE_OPENGL
AM_LDFLAGS += -lglut -lGL -lGLU -lGLEW -lao
endif
libgeneric_la_SOURCES = \
hardware_caps.c \
dmx.cpp \
video.cpp \
audio.cpp \
glfb.cpp \
init.cpp \
pwrmngr.cpp \
playback.cpp \
record.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
else
libgeneric_la_SOURCES += \
playback.cpp
if USE_CLUTTER
libgeneric_la_SOURCES += clutterfb.cpp
endif
if USE_OPENGL
libgeneric_la_SOURCES += glfb.cpp
endif

View File

@@ -22,54 +22,51 @@
#include <cstdio>
#include <cstdlib>
#include "audio_lib.h"
#include "dmx_lib.h"
#include "audio_hal.h"
#include "audio_priv.h"
#include "dmx_hal.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();
}
cAudio::~cAudio(void)
ADec::~ADec(void)
{
closeDevice();
free(dmxbuf);
if (adevice)
ao_close(adevice);
@@ -77,19 +74,19 @@ cAudio::~cAudio(void)
ao_shutdown();
}
void cAudio::openDevice(void)
int cAudio::mute(void)
{
lt_debug("%s\n", __func__);
return SetMute(true);
}
void cAudio::closeDevice(void)
int cAudio::unmute(void)
{
lt_debug("%s\n", __func__);
return SetMute(false);
}
int cAudio::do_mute(bool enable, bool remember)
int cAudio::SetMute(bool enable)
{
lt_debug("%s(%d, %d)\n", __func__, enable, remember);
lt_debug("%s(%d)\n", __func__, enable);
return 0;
}
@@ -100,21 +97,31 @@ 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)
Thread::startThread();
start();
lt_debug("%s <\n", __func__);
return 0;
}
int cAudio::Stop(void)
int ADec::Stop(void)
{
lt_debug("%s >\n", __func__);
if (thread_started)
{
thread_started = false;
Thread::joinThread();
join();
}
lt_debug("%s <\n", __func__);
return 0;
@@ -141,6 +148,11 @@ 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;
@@ -167,6 +179,11 @@ int cAudio::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) {
@@ -194,14 +211,45 @@ 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) {
type = (c->codec_id != AV_CODEC_ID_MP2); /* only mpeg / not mpeg is indicated */
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;
}
freq = c->sample_rate;
bitrate = c->bit_rate;
if (c->channels == 1)
@@ -239,7 +287,7 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m
}
}
lt_debug("%s t: %d l: %d f: %d b: %d m: %d codec_id: %x\n",
__func__, type, layer, freq, bitrate, mode, c->codec_id);
__func__, type, layer, freq, bitrate, mode, c?c->codec_id:-1);
};
void cAudio::SetSRS(int /*iq_enable*/, int /*nmgr_enable*/, int /*iq_mode*/, int /*iq_level*/)
@@ -267,17 +315,12 @@ void cAudio::EnableAnalogOut(bool enable)
lt_debug("%s %d\n", __func__, enable);
};
void cAudio::setBypassMode(bool disable)
{
lt_debug("%s %d\n", __func__, disable);
}
static int _my_read(void *, uint8_t *buf, int buf_size)
{
return gThiz->my_read(buf, buf_size);
return adec->my_read(buf, buf_size);
}
int cAudio::my_read(uint8_t *buf, int buf_size)
int ADec::my_read(uint8_t *buf, int buf_size)
{
int tmp = 0;
if (audioDecoder && bufpos < DMX_BUF_SZ - 4096) {
@@ -304,7 +347,7 @@ int cAudio::my_read(uint8_t *buf, int buf_size)
return tmp;
}
void cAudio::run()
void ADec::run()
{
lt_info("====================== start decoder thread ================================\n");
/* libavcodec & friends */
@@ -356,28 +399,31 @@ void cAudio::run()
lt_info("%s: nb_streams: %d, should be 1!\n", __func__, avfc->nb_streams);
goto out;
}
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);
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);
c = avfc->streams[0]->codec;
codec = avcodec_find_decoder(c->codec_id);
codec = avcodec_find_decoder(p->codec_id);
if (!codec) {
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(c->codec_id));
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(p->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: avcodec_alloc_frame failed\n", __func__);
lt_info("%s: av_frame_alloc failed\n", __func__);
goto out2;
}
/* output sample rate, channels, layout could be set here if necessary */
o_ch = c->channels; /* 2 */
o_sr = c->sample_rate; /* 48000 */
o_layout = c->channel_layout; /* AV_CH_LAYOUT_STEREO */
o_ch = p->channels; /* 2 */
o_sr = p->sample_rate; /* 48000 */
o_layout = p->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)
{
@@ -392,8 +438,9 @@ void cAudio::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);;
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
__func__, o_ch, o_sr, 16, adevice);
if(ai)
lt_info("libao driver: %d name '%s' short '%s' author '%s'\n",
driver, ai->name, ai->short_name, ai->author);
}
#if 0
@@ -404,10 +451,10 @@ void cAudio::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(c->codec_id), c->sample_fmt, tmp, c->sample_rate, c->channels);
avcodec_get_name(p->codec_id), c->sample_fmt, tmp, p->sample_rate, p->channels);
swr = swr_alloc_set_opts(swr,
o_layout, AV_SAMPLE_FMT_S16, o_sr, /* output */
c->channel_layout, c->sample_fmt, c->sample_rate, /* input */
p->channel_layout, c->sample_fmt, p->sample_rate, /* input */
0, NULL);
if (! swr) {
lt_info("could not alloc resample context\n");
@@ -421,15 +468,15 @@ void cAudio::run()
avcodec_decode_audio4(c, frame, &gotframe, &avpkt);
if (gotframe && thread_started) {
int out_linesize;
obuf_sz = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) +
frame->nb_samples, o_sr, c->sample_rate, AV_ROUND_UP);
obuf_sz = av_rescale_rnd(swr_get_delay(swr, p->sample_rate) +
frame->nb_samples, o_sr, p->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_free_packet(&avpkt);
av_packet_unref(&avpkt);
break; /* while (thread_started) */
}
obuf_sz_max = obuf_sz;
@@ -442,7 +489,7 @@ void cAudio::run()
obuf_sz, AV_SAMPLE_FMT_S16, 1);
ao_play(adevice, (char *)obuf, o_buf_sz);
}
av_free_packet(&avpkt);
av_packet_unref(&avpkt);
}
// ao_close(adevice); /* can take long :-( */
av_free(obuf);
@@ -451,6 +498,7 @@ void cAudio::run()
av_frame_free(&frame);
out2:
avcodec_close(c);
av_free(c);
c = NULL;
out:
avformat_close_input(&avfc);

View File

@@ -1,105 +0,0 @@
/* 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

54
generic-pc/audio_priv.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* (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;
};

523
generic-pc/clutterfb.cpp Normal file
View File

@@ -0,0 +1,523 @@
/*
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);
}

View File

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

View File

@@ -32,26 +32,21 @@
#include <cstdio>
#include <string>
#include <unistd.h>
#include "dmx_lib.h"
#include <sys/ioctl.h>
#include "dmx_hal.h"
#include "lt_debug.h"
/* needed for getSTC :-( */
#include "video_lib.h"
extern cVideo *videoDecoder;
#include "video_priv.h"
extern VDec *vdec;
#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); \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0);
cDemux *videoDemux = NULL;
@@ -70,15 +65,12 @@ static const char *DMX_T[] = {
};
/* map the device numbers. for now only demux0 is used */
#define NUM_DEMUXDEV 1
static const char *devname[NUM_DEMUXDEV] = {
static const char *devname[] = {
"/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
@@ -95,9 +87,6 @@ cDemux::cDemux(int n)
else
num = n;
fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
}
cDemux::~cDemux()
@@ -163,8 +152,6 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP);
close(fd);
fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL)
{
dmx_tp_count--;
@@ -256,11 +243,13 @@ 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)
{
@@ -269,6 +258,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
}
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)
@@ -369,8 +359,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
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...
@@ -481,8 +474,8 @@ void cDemux::removePid(unsigned short Pid)
void cDemux::getSTC(int64_t * STC)
{
int64_t pts = 0;
if (videoDecoder)
pts = videoDecoder->GetPTS();
if (vdec)
pts = vdec->GetPTS();
*STC = pts;
}
@@ -497,28 +490,12 @@ int cDemux::getUnit(void)
bool cDemux::SetSource(int unit, int 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;
lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source);
return true;
}
int cDemux::GetSource(int unit)
{
//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];
lt_info_c("%s(%d): not implemented yet\n", __func__, unit);
return 0;
}

View File

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

View File

@@ -1,70 +0,0 @@
#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,6 +22,7 @@
TODO: AV-Sync code is "experimental" at best
*/
#include "config.h"
#include <vector>
#include <sys/types.h>
@@ -37,10 +38,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "glfb.h"
#include <GL/glx.h>
#include "video_lib.h"
#include "audio_lib.h"
#include "glfb_priv.h"
#include "video_priv.h"
#include "audio_priv.h"
#include "lt_debug.h"
@@ -50,13 +50,39 @@
#define lt_info(args...) _lt_info(HAL_DEBUG_INIT, this, args)
extern cVideo *videoDecoder;
extern cAudio *audioDecoder;
extern VDec *vdec;
extern ADec *adec;
static GLFramebuffer *gThiz = 0; /* GLUT does not allow for an arbitrary argument to the render func */
/* 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): mReInit(true), mShutDown(false), mInitDone(false)
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];
@@ -77,19 +103,19 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
last_apts = 0;
/* linux framebuffer compat mode */
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;
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);
@@ -97,39 +123,39 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
if (input_fd < 0)
lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__);
initKeys();
Thread::startThread();
while (!mInitDone)
usleep(1);
}
GLFramebuffer::~GLFramebuffer()
GLFbPC::~GLFbPC()
{
mShutDown = true;
Thread::joinThread();
if (input_fd >= 0)
close(input_fd);
osd_buf->clear();
}
void GLFramebuffer::initKeys()
void GLFbPC::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;
mSpecialMap[GLUT_KEY_RIGHT] = KEY_RIGHT;
mSpecialMap[GLUT_KEY_F1] = KEY_RED;
mSpecialMap[GLUT_KEY_F2] = KEY_GREEN;
mSpecialMap[GLUT_KEY_F3] = KEY_YELLOW;
mSpecialMap[GLUT_KEY_F4] = KEY_BLUE;
mSpecialMap[GLUT_KEY_F1] = KEY_RED;
mSpecialMap[GLUT_KEY_F2] = KEY_GREEN;
mSpecialMap[GLUT_KEY_F3] = KEY_YELLOW;
mSpecialMap[GLUT_KEY_F4] = KEY_BLUE;
mSpecialMap[GLUT_KEY_F5] = KEY_PLAY;
mSpecialMap[GLUT_KEY_F6] = KEY_STOP;
mSpecialMap[GLUT_KEY_F7] = KEY_FORWARD;
mSpecialMap[GLUT_KEY_F8] = KEY_REWIND;
mSpecialMap[GLUT_KEY_F9] = KEY_RECORD;
mSpecialMap[GLUT_KEY_F10] = KEY_PAUSE;
mSpecialMap[GLUT_KEY_F5] = KEY_RECORD;
mSpecialMap[GLUT_KEY_F6] = KEY_PLAY;
mSpecialMap[GLUT_KEY_F7] = KEY_PAUSE;
mSpecialMap[GLUT_KEY_F8] = KEY_STOP;
mSpecialMap[GLUT_KEY_F9] = KEY_FORWARD;
mSpecialMap[GLUT_KEY_F10] = KEY_REWIND;
mSpecialMap[GLUT_KEY_F11] = KEY_NEXT;
mSpecialMap[GLUT_KEY_F12] = KEY_PREVIOUS;
@@ -138,15 +164,6 @@ void GLFramebuffer::initKeys()
mKeyMap[0x0d] = KEY_OK;
mKeyMap[0x1b] = KEY_EXIT;
mKeyMap['e'] = KEY_EPG;
mKeyMap['i'] = KEY_INFO;
mKeyMap['m'] = KEY_MENU;
mKeyMap['+'] = KEY_VOLUMEUP;
mKeyMap['-'] = KEY_VOLUMEDOWN;
mKeyMap['.'] = KEY_MUTE;
mKeyMap['h'] = KEY_HELP;
mKeyMap['p'] = KEY_POWER;
mKeyMap['0'] = KEY_0;
mKeyMap['1'] = KEY_1;
@@ -159,17 +176,48 @@ void GLFramebuffer::initKeys()
mKeyMap['8'] = KEY_8;
mKeyMap['9'] = KEY_9;
mKeyMap['r'] = KEY_RED;
mKeyMap['g'] = KEY_GREEN;
mKeyMap['y'] = KEY_YELLOW;
mKeyMap['b'] = KEY_BLUE;
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;
}
void GLFramebuffer::run()
{
setupCtx();
setupOSDBuffer();
mInitDone = true; /* signal that setup is finished */
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 */
/* init the good stuff */
GLenum err = glewInit();
@@ -184,16 +232,15 @@ void GLFramebuffer::run()
}
else
{
gThiz = this;
glutSetCursor(GLUT_CURSOR_NONE);
glutDisplayFunc(GLFramebuffer::rendercb);
glutKeyboardFunc(GLFramebuffer::keyboardcb);
glutSpecialFunc(GLFramebuffer::specialcb);
glutReshapeFunc(GLFramebuffer::resizecb);
setupGLObjects(); /* needs GLEW prototypes */
glutDisplayFunc(GLFbPC::rendercb);
glutKeyboardFunc(GLFbPC::keyboardcb);
glutSpecialFunc(GLFbPC::specialcb);
glutReshapeFunc(GLFbPC::resizecb);
glfb_priv->setupGLObjects(); /* needs GLEW prototypes */
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop();
releaseGLObjects();
glfb_priv->releaseGLObjects();
}
}
else
@@ -201,21 +248,20 @@ void GLFramebuffer::run()
lt_info("GLFB: GL thread stopping\n");
}
void GLFramebuffer::setupCtx()
#if 0
void GLFbPC::setupCtx()
{
int argc = 1;
/* some dummy commandline for GLUT to be happy */
char const *argv[2] = { "neutrino", 0 };
lt_info("GLFB: GL thread starting\n");
lt_info("GLFB: GL thread starting x %d y %d\n", mX[0], mY[0]);
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 GLFramebuffer::setupOSDBuffer()
void GLFbPC::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... */
@@ -224,12 +270,13 @@ void GLFramebuffer::setupOSDBuffer()
{
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = mState.width * mState.height * 4 * 2;
mOSDBuffer.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes\n", fbmem);
osd_buf->resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf->data());
}
}
#endif
void GLFramebuffer::setupGLObjects()
void GLFbPC::setupGLObjects()
{
unsigned char buf[4] = { 0, 0, 0, 0 }; /* 1 black pixel */
glGenTextures(1, &mState.osdtex);
@@ -257,7 +304,7 @@ void GLFramebuffer::setupGLObjects()
}
void GLFramebuffer::releaseGLObjects()
void GLFbPC::releaseGLObjects()
{
glDeleteBuffers(1, &mState.pbo);
glDeleteBuffers(1, &mState.displaypbo);
@@ -266,56 +313,56 @@ void GLFramebuffer::releaseGLObjects()
}
/* static */ void GLFramebuffer::rendercb()
/* static */ void GLFbPC::rendercb()
{
gThiz->render();
glfb_priv->render();
}
/* static */ void GLFramebuffer::keyboardcb(unsigned char key, int /*x*/, int /*y*/)
/* static */ void GLFbPC::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__, gThiz->mFullscreen?"off":"on");
gThiz->mFullscreen = !(gThiz->mFullscreen);
gThiz->mReInit = true;
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;
}
std::map<unsigned char, int>::const_iterator i = gThiz->mKeyMap.find(key);
if (i == gThiz->mKeyMap.end())
std::map<unsigned char, int>::const_iterator i = glfb_priv->mKeyMap.find(key);
if (i == glfb_priv->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(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
ev.value = 0; /* neutrino is stupid, so push key up directly after key down */
write(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
}
/* static */ void GLFramebuffer::specialcb(int key, int /*x*/, int /*y*/)
/* static */ void GLFbPC::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 = gThiz->mSpecialMap.find(key);
if (i == gThiz->mSpecialMap.end())
std::map<int, int>::const_iterator i = glfb_priv->mSpecialMap.find(key);
if (i == glfb_priv->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(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
ev.value = 0;
write(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
}
int sleep_us = 30000;
void GLFramebuffer::render()
void GLFbPC::render()
{
if(mShutDown)
glutLeaveMainLoop();
@@ -443,12 +490,12 @@ void GLFramebuffer::render()
glutPostRedisplay();
}
/* static */ void GLFramebuffer::resizecb(int w, int h)
/* static */ void GLFbPC::resizecb(int w, int h)
{
gThiz->checkReinit(w, h);
glfb_priv->checkReinit(w, h);
}
void GLFramebuffer::checkReinit(int x, int y)
void GLFbPC::checkReinit(int x, int y)
{
static int last_x = 0, last_y = 0;
@@ -468,7 +515,7 @@ void GLFramebuffer::checkReinit(int x, int y)
last_y = y;
}
void GLFramebuffer::drawSquare(float size, float x_factor)
void GLFbPC::drawSquare(float size, float x_factor)
{
GLfloat vertices[] = {
1.0f, 1.0f,
@@ -486,17 +533,17 @@ void GLFramebuffer::drawSquare(float size, float x_factor)
1.0, 1.0,
};
if (x_factor > -99.0) { /* x_factor == -100 => OSD */
if (videoDecoder &&
videoDecoder->pig_x > 0 && videoDecoder->pig_y > 0 &&
videoDecoder->pig_w > 0 && videoDecoder->pig_h > 0) {
if (vdec &&
vdec->pig_x > 0 && vdec->pig_y > 0 &&
vdec->pig_w > 0 && vdec->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)(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;
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;
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 */
@@ -524,11 +571,11 @@ void GLFramebuffer::drawSquare(float size, float x_factor)
}
void GLFramebuffer::bltOSDBuffer()
void GLFbPC::bltOSDBuffer()
{
/* FIXME: copy each time */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER, mOSDBuffer.size(), &mOSDBuffer[0], GL_STREAM_DRAW_ARB);
glBufferData(GL_PIXEL_UNPACK_BUFFER, osd_buf->size(), osd_buf->data(), 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);
@@ -536,15 +583,15 @@ void GLFramebuffer::bltOSDBuffer()
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
void GLFramebuffer::bltDisplayBuffer()
void GLFbPC::bltDisplayBuffer()
{
if (!videoDecoder) /* cannot start yet */
if (!vdec) /* cannot start yet */
return;
static bool warn = true;
cVideo::SWFramebuffer *buf = videoDecoder->getDecBuf();
VDec::SWFramebuffer *buf = vdec->getDecBuf();
if (!buf) {
if (warn)
lt_debug("GLFB::%s did not get a buffer...\n", __func__);
lt_info("GLFB::%s did not get a buffer...\n", __func__);
warn = false;
return;
}
@@ -573,10 +620,9 @@ void GLFramebuffer::bltDisplayBuffer()
* this implementation is pretty naive and not working too well, but
* better this than nothing... :-) */
int64_t apts = 0;
/* 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();
int64_t vpts = buf->pts();
if (adec)
apts = adec->getPts();
if (apts != last_apts) {
int rate, dummy1, dummy2;
if (apts < vpts)
@@ -584,7 +630,7 @@ void GLFramebuffer::bltDisplayBuffer()
else if (sleep_us > 1000)
sleep_us -= 1000;
last_apts = apts;
videoDecoder->getPictureInfo(dummy1, dummy2, rate);
vdec->getPictureInfo(dummy1, dummy2, rate);
if (rate > 0)
rate = 2000000 / rate; /* limit to half the frame rate */
else
@@ -595,11 +641,5 @@ void GLFramebuffer::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, videoDecoder->buf_num);
}
void GLFramebuffer::clear()
{
/* clears front and back buffer */
memset(&mOSDBuffer[0], 0, mOSDBuffer.size());
buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, vdec->buf_num);
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
Copyright 2012,2013,2016 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,44 +14,46 @@
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 __glthread__
#define __glthread__
#include <thread_abstraction.h>
#include <mutex_abstraction.h>
#ifndef __glfb_priv__
#define __glfb_priv__
#include <OpenThreads/Mutex>
#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 GLFramebuffer : public Thread
class GLFbPC
{
public:
GLFramebuffer(int x, int y);
~GLFramebuffer();
void run();
std::vector<unsigned char> *getOSDBuffer() { return &mOSDBuffer; } /* pointer to OSD bounce buffer */
GLFbPC(int x, int y, std::vector<unsigned char> &buf);
~GLFbPC();
std::vector<unsigned char> *getOSDBuffer() { return osd_buf; } /* pointer to OSD bounce buffer */
int getOSDWidth() { return mState.width; }
int getOSDHeight() { return mState.height; }
void blit() { mState.blit = true; }
void blit() { mState.blit = true; };
fb_var_screeninfo getScreenInfo() { return si; }
void setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; }
void clear();
fb_var_screeninfo getScreenInfo() { return screeninfo; }
int getWindowID() { return GLWinID; }
/* just make everything public for simplicity - this is only used inside libstb-hal anyway
private:
fb_var_screeninfo screeninfo;
*/
fb_var_screeninfo si;
int *mX;
int *mY;
int _mX[2]; /* output window size */
@@ -63,45 +65,59 @@ 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 */
Mutex mReInitLock;
OpenThreads::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> mOSDBuffer; /* silly bounce buffer */
std::vector<unsigned char> *osd_buf; /* 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;
bool blit;
#endif
} mState;
void bltOSDBuffer();

View File

@@ -7,12 +7,8 @@
* 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>
@@ -33,6 +29,9 @@ 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,7 +1,8 @@
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include "init_lib.h"
#include "init_td.h"
#include "lt_debug.h"
#include "glfb.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)

View File

@@ -1,5 +0,0 @@
#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.h"
#include "playback_hal.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 Start((char*) filename.c_str(),0,0,0,0,0, headers);
return false;
}
bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers)
bool cPlayback::Start(char * filename, unsigned short vpid, int vtype, unsigned short apid, int ac3, unsigned int duration)
{
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(int pid, bool /*ac3*/)
bool cPlayback::SetAPid(unsigned short pid, int /*ac3*/)
{
printf("%s:%s pid %i\n", FILENAME, __func__, pid);
return true;
}
bool cPlayback::SelectSubtitles(int pid)
bool cPlayback::SelectSubtitles(int pid, std::string /*charset*/)
{
printf("%s:%s pid %i\n", FILENAME, __func__, pid);
return true;
@@ -39,7 +39,7 @@ bool cPlayback::SelectSubtitles(int pid)
bool cPlayback::SetSpeed(int speed)
{
printf("%s:%s playing %d speed %d\n", FILENAME, __func__, playing, speed);
printf("%s:%s speed %d\n", FILENAME, __func__, speed);
return true;
}
@@ -62,53 +62,16 @@ bool cPlayback::SetPosition(int position, bool)
return true;
}
void cPlayback::FindAllPids(int *, unsigned int *, unsigned int *numpida, std::string *)
void cPlayback::FindAllPids(uint16_t *, unsigned short *, uint16_t *numpida, std::string *)
{
printf("%s:%s\n", FILENAME, __func__);
*numpida = 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;
}
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*/)
void cPlayback::FindAllSubs(uint16_t *, unsigned short *, uint16_t *numpida, std::string *)
{
printf("%s:%s\n", FILENAME, __func__);
*num = 0;
*numpida = 0;
}
void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)
@@ -117,20 +80,26 @@ 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;
}
cPlayback::cPlayback(int /*num*/)
{
printf("%s:%s\n", FILENAME, __func__);

View File

@@ -1,58 +0,0 @@
#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

View File

@@ -1,90 +0,0 @@
/*
*
* 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;
class cPlayback
{
private:
bool playing;
int mSpeed;
int mAudioStream;
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);
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);
//
~cPlayback();
void getMeta();
};
#endif

View File

@@ -1,822 +0,0 @@
/*
*
* 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;
}

View File

@@ -1,832 +0,0 @@
/*
*
* 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/video/videooverlay.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(const GValue *velement, const gchar *type)
{
GstElement *element = GST_ELEMENT_CAST(g_value_get_object(velement));
return strcmp(g_type_name(G_OBJECT_TYPE(element)), 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)
{
GstMapInfo Info;
gst_buffer_map(buf_image, &Info,(GstMapFlags)( GST_MAP_READ));
int ret = write(fd, Info.data, Info.size);
close(fd);
gst_buffer_unmap(buf_image, &Info);
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_debug_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));
GValue r = G_VALUE_INIT;
gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, &r, (gpointer)"GstDVBAudioSink");
audioSink = GST_ELEMENT_CAST(g_value_dup_object (&r));
g_value_unset (&r);
gst_iterator_find_custom(children, (GCompareFunc)match_sinktype, &r, (gpointer)"GstDVBVideoSink");
videoSink = GST_ELEMENT_CAST(g_value_dup_object (&r));
g_value_unset (&r);
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-window-handle"))
{
// set window id
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC (msg)), glfb->getWindowID());
// reshape window
gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC (msg)), 0, 0, glfb->getOSDWidth(), glfb->getOSDHeight());
// sync frames
gst_video_overlay_expose(GST_VIDEO_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, 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 ("playbin", "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, NULL);
gst_object_unref(bus);
// state playing
gst_element_set_state(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_current_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;
}

View File

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

View File

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

View File

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

View File

@@ -23,6 +23,7 @@
* TODO: buffer handling surely needs some locking...
*/
#include "config.h"
#include <unistd.h>
#include <cstring>
#include <cstdio>
@@ -30,6 +31,7 @@
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
@@ -38,17 +40,26 @@ extern "C" {
/* my own buf 256k */
#define DMX_BUF_SZ 0x20000
#include "video_lib.h"
#include "dmx_lib.h"
#include "glfb.h"
#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 "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 GLFramebuffer *glfb;
extern GLFbPC *glfb_priv;
int system_rev = 0;
extern bool HAL_nodec;
@@ -68,6 +79,13 @@ 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);
@@ -79,20 +97,35 @@ cVideo::cVideo(int, void *, void *, unsigned int)
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;
// videoDecoder = NULL;
delete vdec;
::vdec = 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)
@@ -100,11 +133,16 @@ int cVideo::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->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
glfb_priv->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;
@@ -133,26 +171,36 @@ int cVideo::getAspectRatio(void)
return ret;
}
int cVideo::setCroppingMode(int)
int cVideo::setCroppingMode(void)
{
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)
Thread::startThread();
OpenThreads::Thread::start();
lt_debug("%s running %d <\n", __func__, thread_running);
return 0;
}
int cVideo::Stop(bool)
int VDec::Stop(bool)
{
lt_debug("%s running %d >\n", __func__, thread_running);
if (thread_running) {
thread_running = false;
Thread::joinThread();
OpenThreads::Thread::join();
}
lt_debug("%s running %d <\n", __func__, thread_running);
return 0;
@@ -163,7 +211,29 @@ 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)
@@ -196,39 +266,39 @@ int cVideo::SetVideoSystem(int system, bool)
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->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;
glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
return 0;
}
int cVideo::getPlayState(void)
{
return VIDEO_PLAYING;
return 1;
}
void cVideo::SetVideoMode(analog_mode_t)
{
}
void cVideo::ShowPicture(const char *fname, const char *)
bool cVideo::ShowPicture(const char *fname)
{
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;
return ret;
still_m.lock();
stillpicture = true;
buf_num = 0;
buf_in = 0;
buf_out = 0;
still_m.unlock();
unsigned int i;
int stream_id = -1;
@@ -236,13 +306,14 @@ void cVideo::ShowPicture(const char *fname, const char *)
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;
return ret;
}
if (avformat_find_stream_info(avfc, NULL) < 0) {
@@ -250,17 +321,18 @@ void cVideo::ShowPicture(const char *fname, const char *)
goto out_close;
}
for (i = 0; i < avfc->nb_streams; i++) {
if (avfc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
stream_id = i;
break;
}
}
if (stream_id < 0)
goto out_close;
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);
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);
goto out_close;
}
frame = av_frame_alloc();
@@ -277,15 +349,15 @@ void cVideo::ShowPicture(const char *fname, const char *)
len = avcodec_decode_video2(c, frame, &got_frame, &avpkt);
if (len < 0) {
lt_info("%s: avcodec_decode_video2 %d\n", __func__, len);
av_free_packet(&avpkt);
av_packet_unref(&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 = avpicture_get_size(PIX_FMT_RGB32, c->width, c->height);
unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1);
struct SwsContext *convert = sws_getContext(c->width, c->height, c->pix_fmt,
c->width, c->height, PIX_FMT_RGB32,
c->width, c->height, VDEC_PIXFMT,
SWS_BICUBIC, 0, 0, 0);
if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__);
@@ -294,8 +366,8 @@ void cVideo::ShowPicture(const char *fname, const char *)
SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need)
f->resize(need);
avpicture_fill((AVPicture *)rgbframe, &(*f)[0], PIX_FMT_RGB32,
c->width, c->height);
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT,
c->width, c->height, 1);
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
rgbframe->data, rgbframe->linesize);
sws_freeContext(convert);
@@ -308,26 +380,33 @@ void cVideo::ShowPicture(const char *fname, const char *)
buf_in %= VDEC_MAXBUFS;
buf_num++;
if (buf_num > (VDEC_MAXBUFS - 1)) {
lt_debug("%s: buf_num overflow\n", __func__);
lt_info("%s: buf_num overflow\n", __func__);
buf_out++;
buf_out %= VDEC_MAXBUFS;
buf_num--;
}
buf_m.unlock();
ret = true;
}
}
av_free_packet(&avpkt);
av_packet_unref(&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)
@@ -339,19 +418,55 @@ int cVideo::getBlank(void)
return 0;
}
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*/)
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)
{
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;
rate = dec_r;
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;
}
}
void cVideo::SetSyncMode(AVSYNC_TYPE)
@@ -359,12 +474,17 @@ 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;
}
cVideo::SWFramebuffer *cVideo::getDecBuf(void)
VDec::SWFramebuffer *VDec::getDecBuf(void)
{
buf_m.lock();
if (buf_num == 0) {
@@ -403,10 +523,11 @@ static int my_read(void *, uint8_t *buf, int buf_size)
return tmp;
}
void cVideo::run(void)
void VDec::run(void)
{
lt_info("====================== start decoder thread ================================\n");
AVCodec *codec;
AVCodecParameters *p = NULL;
AVCodecContext *c= NULL;
AVFormatContext *avfc = NULL;
AVInputFormat *inp;
@@ -447,20 +568,21 @@ void cVideo::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_free_packet(&avpkt);
av_packet_unref(&avpkt);
if (! thread_running)
goto out;
}
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);
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);
c = avfc->streams[0]->codec;
codec = avcodec_find_decoder(c->codec_id);
codec = avcodec_find_decoder(p->codec_id);
if (!codec) {
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(c->codec_id));
lt_info("%s: Codec for %s not found\n", __func__, avcodec_get_name(p->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;
@@ -488,16 +610,17 @@ void cVideo::run(void)
lt_info("%s: avcodec_decode_video2 %d\n", __func__, len);
warn_d = time(NULL);
}
av_free_packet(&avpkt);
av_packet_unref(&avpkt);
continue;
}
if (avpkt.size > len)
lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len);
if (got_frame) {
unsigned int need = avpicture_get_size(PIX_FMT_RGB32, c->width, c->height);
still_m.lock();
if (got_frame && ! stillpicture) {
unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1);
convert = sws_getCachedContext(convert,
c->width, c->height, c->pix_fmt,
c->width, c->height, PIX_FMT_RGB32,
c->width, c->height, VDEC_PIXFMT,
SWS_BICUBIC, 0, 0, 0);
if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__);
@@ -506,8 +629,8 @@ void cVideo::run(void)
SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need)
f->resize(need);
avpicture_fill((AVPicture *)rgbframe, &(*f)[0], PIX_FMT_RGB32,
c->width, c->height);
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT,
c->width, c->height, 1);
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
rgbframe->data, rgbframe->linesize);
if (dec_w != c->width || dec_h != c->height) {
@@ -520,8 +643,18 @@ void cVideo::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);
@@ -529,7 +662,7 @@ void cVideo::run(void)
buf_in %= VDEC_MAXBUFS;
buf_num++;
if (buf_num > (VDEC_MAXBUFS - 1)) {
lt_debug("%s: buf_num overflow\n", __func__);
lt_info("%s: buf_num overflow\n", __func__);
buf_out++;
buf_out %= VDEC_MAXBUFS;
buf_num--;
@@ -540,12 +673,15 @@ void cVideo::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));
}
av_free_packet(&avpkt);
} else
lt_info("%s: got_frame: %d stillpicture: %d\n", __func__, got_frame, stillpicture);
still_m.unlock();
av_packet_unref(&avpkt);
}
sws_freeContext(convert);
out2:
avcodec_close(c);
av_free(c);
av_frame_free(&frame);
av_frame_free(&rgbframe);
out:
@@ -554,39 +690,67 @@ void cVideo::run(void)
av_free(pIOCtx);
/* reset output buffers */
bufpos = 0;
buf_num = 0;
buf_in = 0;
buf_out = 0;
still_m.lock();
if (!stillpicture) {
buf_num = 0;
buf_in = 0;
buf_out = 0;
}
still_m.unlock();
lt_info("======================== end decoder thread ================================\n");
}
static bool swscale(unsigned char *src, unsigned char *dst, int sw, int sh, int dw, int dh)
static bool swscale(unsigned char *src, unsigned char *dst, int sw, int sh, int dw, int dh, AVPixelFormat sfmt)
{
bool ret = false;
int len = 0;
struct SwsContext *scale = NULL;
AVFrame *sframe, *dframe;
scale = sws_getCachedContext(scale, sw, sh, PIX_FMT_RGB32, dw, dh, PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0);
scale = sws_getCachedContext(scale, sw, sh, sfmt, dw, dh, AV_PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0);
if (!scale) {
lt_info_c("%s: ERROR setting up SWS context\n", __func__);
return false;
return ret;
}
sframe = av_frame_alloc();
dframe = av_frame_alloc();
if (!sframe || !dframe) {
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{
lt_info_c("%s: could not alloc sframe (%p) or dframe (%p)\n", __func__, sframe, dframe);
goto out;
ret = false;
}
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);
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);
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)
{
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);
@@ -594,8 +758,8 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge
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->getOSDWidth();
int osd_h = glfb->getOSDHeight();
int osd_w = glfb_priv->getOSDWidth();
int osd_h = glfb_priv->getOSDHeight();
xres = osd_w;
yres = osd_h;
if (get_video) {
@@ -613,24 +777,42 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge
xres = vid_w * a.num / a.den;
}
}
if(video.empty()){
get_video=false;
xres = osd_w;
yres = osd_h;
}
if (get_osd)
osd = glfb->getOSDBuffer();
unsigned int need = avpicture_get_size(PIX_FMT_RGB32, xres, yres);
osd = glfb_priv->getOSDBuffer();
unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, xres, yres, 1);
data = (unsigned char *)realloc(data, need); /* will be freed by caller */
if (data == NULL) /* out of memory? */
return false;
if (get_video) {
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 */
#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 */
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);
swscale(&(*osd)[0], &s_osd[0], osd_w, osd_h, xres, yres);
bool ret = swscale(&(*osd)[0], &s_osd[0], osd_w, osd_h, xres, yres,AV_PIX_FMT_RGB32);
if(!ret){
free(data);
return false;
}
osd = &s_osd;
}
@@ -664,7 +846,7 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge
return true;
}
int64_t cVideo::GetPTS(void)
int64_t VDec::GetPTS(void)
{
int64_t pts = 0;
buf_m.lock();

View File

@@ -1,223 +0,0 @@
#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

109
generic-pc/video_priv.h Normal file
View File

@@ -0,0 +1,109 @@
/*
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,23 +1,99 @@
#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"
#include "../libarmbox/audio_mixer.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
/*
* (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;
};
#endif

View File

@@ -1,9 +1,6 @@
/*
* dummy functions to implement ca_cs.h interface
*/
#if HAVE_DUCKBOX_HARDWARE
#include "ca_ci.h"
#else
#ifndef __CA_LIBTRIPLE_H_
#define __CA_LIBTRIPLE_H_
@@ -11,12 +8,15 @@
#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,18 +67,13 @@ 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_GUI_READY,
CA_MESSAGE_MSG_EXIT
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;
@@ -100,9 +95,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*/) { 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 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 SendMessage(const CA_MESSAGE *Msg);
void SetInitMask(enum CA_INIT_MASK InitMask);
int GetCAIDS(CaIdVector & /*Caids*/) { return 0; };
@@ -117,10 +112,7 @@ 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

View File

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

View File

@@ -1,23 +0,0 @@
#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,20 +1,67 @@
#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"
/* 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,
};
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
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);
#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_

View File

@@ -1,320 +0,0 @@
#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,20 +1,97 @@
#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
/*
* (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
#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,10 +1,42 @@
#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
/*
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 */
};
#endif

View File

@@ -38,11 +38,11 @@ typedef struct hw_caps
int display_yres;
int display_can_deepstandby;
int display_can_set_brightness;
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,30 +5,7 @@
#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];
@@ -37,7 +14,6 @@ typedef struct {
} MMI_MENU_LIST_INFO;
typedef struct {
int slot;
int blind;
int answerlen;
char enquiryText[MAX_MMI_TEXT_LEN];

View File

@@ -1,25 +0,0 @@
#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,2 +1 @@
#include <config.h>
#include "playback_hal.h"

View File

@@ -1,24 +1,82 @@
#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
#include "../libarmbox/playback_gst.h"
#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
/*
* (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;
};
#endif

View File

@@ -1,20 +1,47 @@
#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
/*
* (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);
};
#endif

View File

@@ -1,20 +1,41 @@
#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
/*
* (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;
};
#endif

View File

@@ -1,16 +0,0 @@
#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

View File

@@ -1,18 +0,0 @@
#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

@@ -1,30 +0,0 @@
#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

22
include/version_hal.h Normal file
View File

@@ -0,0 +1,22 @@
#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,24 +1,213 @@
#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
/*
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;
};
#if STB_HAL_VIDEO_HAS_GETSCREENIMAGE
#define SCREENSHOT 1
#endif

View File

@@ -1,29 +0,0 @@
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 \
-lgstreamer-1.0 \
-lgsttag-1.0 \
-lgstmpegts-1.0
libarmbox_la_SOURCES = \
hardware_caps.c \
dmx.cpp \
video.cpp \
audio.cpp \
init.cpp \
playback_gst.cpp \
pwrmngr.cpp \
record.cpp

View File

@@ -1,480 +0,0 @@
#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;
/*
mixerAnalog = mixerHDMI = mixerSPDIF = NULL;
volumeAnalog = volumeHDMI = volumeSPDIF = 0;
mixersMuted = false
*/
openDevice();
Muted = false;
}
cAudio::~cAudio(void)
{
//closeMixers();
closeDevice();
}
void cAudio::openDevice(void)
{
//openMixers();
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)
{
//closeMixers();
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);
}
#if 0
void cAudio::openMixers(void)
{
if (!mixerAnalog)
mixerAnalog = new mixerVolume("Analog", "1");
if (!mixerHDMI)
mixerHDMI = new mixerVolume("HDMI", "1");
if (!mixerSPDIF)
mixerSPDIF = new mixerVolume("SPDIF", "1");
}
void cAudio::closeMixers(void)
{
delete mixerAnalog;
delete mixerHDMI;
delete mixerSPDIF;
mixerAnalog = mixerHDMI = mixerSPDIF = NULL;
}
void cAudio::setMixerVolume(const char *name, long value, bool remember)
{
if (!strcmp(name, "Analog")) {
mixerAnalog->setVolume(value);
if (remember)
volumeAnalog = value;
}
if (!strcmp(name, "HDMI")) {
mixerHDMI->setVolume(value);
if (remember)
volumeHDMI = value;
}
if (!strcmp(name, "SPDIF")) {
mixerSPDIF->setVolume(value);
if (remember)
volumeSPDIF = value;
}
}
void cAudio::muteMixers(bool m)
{
if (m && !mixersMuted) {
mixersMuted = true;
setMixerVolume("Analog", 0, false);
setMixerVolume("HDMI", 0, false);
setMixerVolume("SPDIF", 0, false);
} else if (!m && mixersMuted) {
mixersMuted = false;
setMixerVolume("Analog", volumeAnalog, false);
setMixerVolume("HDMI", volumeHDMI, false);
setMixerVolume("SPDIF", volumeSPDIF, false);
}
}
#endif

View File

@@ -1,111 +0,0 @@
/* 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);
mixerVolume *mixerAnalog, *mixerHDMI, *mixerSPDIF;
int volumeAnalog, volumeHDMI, volumeSPDIF;
bool mixersMuted;
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);
#if 0
void openMixers(void);
void closeMixers(void);
void setMixerVolume(const char *name, long value, bool remember = true);
void muteMixers(bool m = true);
#endif
};
#endif

View File

@@ -1,68 +0,0 @@
/*
* audio_mixer.cpp
*
* (C) 2012 martii
*
* 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 <audio_mixer.h>
mixerVolume::mixerVolume(const char *name, const char *card, long volume) {
snd_mixer_selem_id_t *sid = NULL;
elem = NULL;
handle = NULL;
min = 0;
max = 100;
char cardId[10];
if (!name || !card)
return;
int cx = snd_card_get_index(card);
if (cx < 0 || cx > 31)
return;
snprintf(cardId, sizeof(cardId), "hw:%i", cx);
if (0 > snd_mixer_open(&handle, 0))
return;
if (0 > snd_mixer_attach(handle, cardId))
return;
if (0 > snd_mixer_selem_register(handle, NULL, NULL))
return;
if (0 > snd_mixer_load(handle))
return;
snd_mixer_selem_id_alloca(&sid);
if (!sid)
return;
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, name);
elem = snd_mixer_find_selem(handle, sid);
if (elem) {
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
setVolume(volume);
}
}
mixerVolume::~mixerVolume()
{
if (handle)
snd_mixer_close(handle);
}
bool mixerVolume::setVolume(long volume) {
return elem
&& (volume > -1)
&& (volume < 101)
&& !snd_mixer_selem_set_playback_volume_all(elem, min + volume * (max - min)/100);
}

View File

@@ -1,36 +0,0 @@
/*
* audio_mixer.h
*
* (C) 2012 martii
*
* 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_MIXER_H__
#define __AUDIO_MIXER_H__
#include <alsa/asoundlib.h>
class mixerVolume
{
private:
long min, max;
snd_mixer_t *handle;
snd_mixer_elem_t* elem;
public:
mixerVolume(const char *selem_name, const char *Card, long volume = -1);
~mixerVolume(void);
bool setVolume(long volume);
};
#endif

View File

@@ -1,67 +0,0 @@
/* 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
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);
#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_

View File

@@ -1,594 +0,0 @@
/*
* cDemux implementation for SH4 receivers (tested on fulan spark and
* fulan spark7162 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/>.
*/
/*
* Theory of operation (or "why is this dmx_source thing so strange and
* what is the _open() good for?")
*
* the sh4 pti driver, driving the /dev/dvb/adapter0/dmxN devices, can
* apparently only map one input to on demux device at a time, so e.g.
* DMX_SOURCE_FRONT1 -> demux0
* DMX_SOURCE_FRONT2 -> demux0
* DMX_SOURCE_FRONT1 -> demux1
* does not work. The driver makes sure that a one-to-one mapping of
* DMX_SOURCE_FRONTn to demuxM is maintained, and it does by e.g changing
* the default of
* FRONT0 -> demux0
* FRONT1 -> demux1
* FRONT2 -> demux2
* to
* FRONT1 -> demux0
* FRONT0 -> demux1
* FRONT2 -> demux2
* if you do a DMX_SET_SOURCE(FRONT1) ioctl on demux0.
* This means, it also changes demux1's source on the SET_SOURCE ioctl on
* demux0, potentially disturbing any operation on demux1 (e.g. recording).
*
* In order to avoid this, I do not change the source->demuxdev mapping
* but instead just always use the demux device that is attached to the
* correct source.
*
* The tricky part is, that the source might actually be changed after
* Open() has been called, so Open() gets a dummy placeholder that just
* sets some variables while the real device open is put into _open().
* _open() gets called later, whenever the device is actually used or
* configured and -- if the source has changed -- closes the old and
* opens the correct new device node.
*/
#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];
}

View File

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

View File

@@ -1,72 +0,0 @@
#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

View File

@@ -1,44 +0,0 @@
/*
* 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 = 0;
caps.can_cec = 1;
caps.can_shutdown = 1;
caps.display_xres = 16;
caps.display_type = HW_DISPLAY_LINE_TEXT;
caps.display_can_deepstandby = 0;
caps.display_can_set_brightness = 1;
caps.has_HDMI = 1;
strcpy(caps.boxvendor, "AX-Technologies");
strcpy(caps.boxname, "HD51");
strcpy(caps.boxarch, "BCM7251S");
return &caps;
}

View File

@@ -1,49 +0,0 @@
#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;
}

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,103 +0,0 @@
/*
*
* 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

@@ -1,102 +0,0 @@
#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; }
#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
unsigned long cCpuFreqManager::GetCpuFreq(void) {
int freq = 0;
if (FILE *pll0 = fopen("/proc/cpu_frequ/pll0_ndiv_mdiv", "r")) {
char buffer[120];
while(fgets(buffer, sizeof(buffer), pll0)) {
if (1 == sscanf(buffer, "SH4 = %d MHZ", &freq))
break;
}
fclose(pll0);
return 1000 * 1000 * (unsigned long) freq;
}
return 0;
}
#else
unsigned long cCpuFreqManager::GetCpuFreq(void) { lt_debug("%s\n", __FUNCTION__); return 0; }
#endif
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)
{
#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
if (f) {
FILE *pll0 = fopen ("/proc/cpu_frequ/pll0_ndiv_mdiv", "w");
if (pll0) {
f /= 1000000;
fprintf(pll0, "%lu\n", (f/10 << 8) | 3);
fclose (pll0);
return false;
}
}
#else
/* actually SetCpuFreq is used to determine if the system is in standby
this is an "elegant" hack, because:
* during a recording, cpu freq is kept "high", even if the box is sent to standby
* the "SetStandby" call is made even if a recording is running
On the TD, setting standby disables the frontend, so we must not do it
if a recording is running.
For now, the values in neutrino are hardcoded:
* f == 0 => max => not standby
* f == 50000000 => min => standby
*/
lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false");
#if 0
int fd = open("/dev/stb/tdsystem", O_RDONLY);
if (fd < 0)
{
perror("open tdsystem");
return false;
}
if (f)
{
ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */
ioctl(fd, IOC_AVS_STANDBY_ENTER);
}
else
{
ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */
ioctl(fd, IOC_AVS_STANDBY_LEAVE);
/* unmute will be done by cAudio::do_mute(). Ugly, but prevents pops */
// ioctl(fd, IOC_AVS_SET_VOLUME, 0); /* max gain */
}
close(fd);
#endif
#endif
return true;
}
//
cPowerManager::cPowerManager(void) { lt_debug("%s\n", __FUNCTION__); }
cPowerManager::~cPowerManager() { lt_debug("%s\n", __FUNCTION__); }

View File

@@ -1,53 +0,0 @@
#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__

View File

@@ -1,383 +0,0 @@
#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;
}

View File

@@ -1,57 +0,0 @@
#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

File diff suppressed because it is too large Load Diff

View File

@@ -1,254 +0,0 @@
#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, 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);
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

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