mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Compare commits
1079 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dd71a004e2 | ||
|
45091fbd72 | ||
|
988d5aebfa | ||
|
8c3671fae6 | ||
|
2a12af481a | ||
|
7817e64695 | ||
|
ebbaa39098 | ||
|
d3dcbbd4f2 | ||
|
3045995bbc | ||
|
1b4233d6ad | ||
|
34aa8fe8b4 | ||
|
baa97e9ff1 | ||
|
03afc4a353 | ||
|
ef4ebeb7ee | ||
|
80d8851e62 | ||
|
ead135f716 | ||
|
49dc61a92c | ||
|
af0309cc40 | ||
|
4ed7421b1c | ||
|
3058354dba | ||
|
20a8c5d240 | ||
|
0749a34342 | ||
|
e595eed57d | ||
|
a7576f0b6c | ||
|
657e5dda5d | ||
|
8fb6a2b24b | ||
|
53cac302d8 | ||
|
2c6c014dd8 | ||
|
a7071f580e | ||
|
de5327a048 | ||
|
7ab94c7bcb | ||
|
0f80fc5e86 | ||
|
d169f30e5c | ||
|
7a1842cba6 | ||
|
e4e9d7a55f | ||
|
ccbef6ce6c | ||
|
7461a1ba3a | ||
|
bb55e3036e | ||
|
bbf2cca198 | ||
|
8ce034d124 | ||
|
4030698007 | ||
|
66fea5c9f1 | ||
|
285574eeaa | ||
|
55cfb057e0 | ||
|
b4c538cff7 | ||
|
5a626fef9f | ||
|
2bcd8ba8f3 | ||
|
2dacc776bd | ||
|
a91d687a1a | ||
|
0d3882d43e | ||
|
72ad601328 | ||
|
2c6fd804f6 | ||
|
c590444b7d | ||
|
4805af7915 | ||
|
171b20a80d | ||
|
d00ae923ab | ||
|
d8ab5dc5c6 | ||
|
292af5d4f4 | ||
|
3d6b31b115 | ||
|
9e523073aa | ||
|
32d8e473fb | ||
|
5cd25df60c | ||
|
52c4816c9c | ||
|
6f6b05ffcb | ||
|
6dd5854b7a | ||
|
83425df0b6 | ||
|
82b09eaa8e | ||
|
ec5b1aadab | ||
|
f786510ba2 | ||
|
f006884e57 | ||
|
c0a005b3cd | ||
|
0c91893643 | ||
|
796da9e0f6 | ||
|
5d539be071 | ||
|
1df138d876 | ||
|
71b0140003 | ||
|
a33adf365d | ||
|
8d82b05071 | ||
|
930e3b4200 | ||
|
2543f2c486 | ||
|
d919817c35 | ||
|
6bbb596968 | ||
|
8aec1974bb | ||
|
b3ad9ec699 | ||
|
87410442b6 | ||
|
305735a886 | ||
|
41b7e1546a | ||
|
f3972e4795 | ||
|
e7ea087a6e | ||
|
749ba57dcc | ||
|
0360b0d0e7 | ||
|
2b495e0f87 | ||
|
32b11e1a53 | ||
|
db81c07b27 | ||
|
1c2401eb6c | ||
|
5828d347f7 | ||
|
9c64622718 | ||
|
f9260d0141 | ||
|
746cdaff01 | ||
|
179d5b87fc | ||
|
51dca45a0c | ||
|
62ad9b41dd | ||
|
8b87a6968a | ||
|
faf562fd4e | ||
|
6a09a2fbd6 | ||
|
bc32ffe2f9 | ||
|
ff16bbd777 | ||
|
f7f8a6b131 | ||
|
a3310e2954 | ||
|
0b08666310 | ||
|
42db3fbee0 | ||
|
bfa25d6276 | ||
|
824c495d33 | ||
|
561be36958 | ||
|
8bd0437497 | ||
|
18c9cef1ea | ||
|
2c66d57d4b | ||
|
29200d040e | ||
|
385738cadd | ||
|
a2591d6e98 | ||
|
fe97a38e77 | ||
|
552f5fc4e7 | ||
|
21d3d489fd | ||
|
78b7e4e252 | ||
|
5d984b606e | ||
|
88b1e30494 | ||
|
939071bf25 | ||
|
655682b5d2 | ||
|
b1418b6bcd | ||
|
35c8b3d22c | ||
|
e5ae02e3fa | ||
|
f0da21ea13 | ||
|
eb35faaf7d | ||
|
05f03d6e38 | ||
|
0d4284df29 | ||
|
cade92cda1 | ||
|
f0bbf64da0 | ||
|
6458f8b581 | ||
|
1770a18598 | ||
|
5f136032a2 | ||
|
63efcf3927 | ||
|
468dc1115e | ||
|
d53e0fd5c3 | ||
|
14b907b01c | ||
|
e0d87da768 | ||
|
42b584e38d | ||
|
a0f79bdd5f | ||
|
4372d55dd1 | ||
|
13672280b6 | ||
|
5b134cb23e | ||
|
87cf0b7a3d | ||
|
8b14723e9e | ||
|
7fe59548cd | ||
|
15f13ac936 | ||
|
5b176f97a4 | ||
|
0bb6f87776 | ||
|
c06d2389e9 | ||
|
548a33c728 | ||
|
4336b55f4e | ||
|
c12c7378e9 | ||
|
a299d8d348 | ||
|
c7bf474a42 | ||
|
8d65cc6dc0 | ||
|
f2b9f0e8dd | ||
|
30f05ba714 | ||
|
76445411a5 | ||
|
4425918d31 | ||
|
6888ea68b6 | ||
|
abb82a2396 | ||
|
6192ca81d9 | ||
|
d06c5efa54 | ||
|
f859b8d2ae | ||
|
035d5fd5b9 | ||
|
93d578d9b8 | ||
|
d756628297 | ||
|
a4cde807bc | ||
|
83c9677899 | ||
|
b14ed38a48 | ||
|
2bf0967a47 | ||
|
7ed306d127 | ||
|
5a029eb29f | ||
|
230adc8235 | ||
|
982a9a5157 | ||
|
c8e4921a0a | ||
|
786245efe5 | ||
|
74460f22bf | ||
|
a843d03af1 | ||
|
d3f3e856e4 | ||
|
be3c6048ed | ||
|
2a0222226a | ||
|
50c3951017 | ||
|
ea1ad945b4 | ||
|
8cde8464eb | ||
|
14b108f104 | ||
|
330dbce1e7 | ||
|
adeb6314fb | ||
|
78a09b5926 | ||
|
d05765c670 | ||
|
a5a4b72d1c | ||
|
955b1c914f | ||
|
5b28aa7e02 | ||
|
f34a6d66a0 | ||
|
104bddc560 | ||
|
e7107b789e | ||
|
f2e71eb668 | ||
|
f275346ecc | ||
|
33b47142e4 | ||
|
5f3d42bcd8 | ||
|
3f2dd916c1 | ||
|
0d50ec57f5 | ||
|
7301f2de08 | ||
|
8c7d387e86 | ||
|
6c5a448dec | ||
|
a84f9a8e19 | ||
|
545613e0e7 | ||
|
ac4da6e380 | ||
|
4d5cbaf57d | ||
|
a4a2466bf4 | ||
|
a0cdfc432a | ||
|
60c858689b | ||
|
9686a9b474 | ||
|
0f6265a97f | ||
|
7b1c097958 | ||
|
58e21d8e37 | ||
|
e1f04cd6fa | ||
|
7775698bac | ||
|
8f52603665 | ||
|
c40fb4b4aa | ||
|
161fa8ead4 | ||
|
115eb9fdb4 | ||
|
b7112ece6c | ||
|
f7c8f582ea | ||
|
ada85b693e | ||
|
a1a8c5d94c | ||
|
505bcee926 | ||
|
c02c081d91 | ||
|
c8566fab77 | ||
|
54c4e69299 | ||
|
31b87544f1 | ||
|
cd3cda2654 | ||
|
c98fdd9120 | ||
|
10ffd08c82 | ||
|
4a199fe4ac | ||
|
98fa6206ac | ||
|
ce23ba64bd | ||
|
02c668a6a9 | ||
|
9de337d2ee | ||
|
fa8c7c35b5 | ||
|
3d13eb002f | ||
|
b2fb654bb3 | ||
|
cd834c79ba | ||
|
65aafacd8e | ||
|
ebd92dcd31 | ||
|
0003d6391c | ||
|
4e52547a59 | ||
|
d3755c92d7 | ||
|
d536cf0947 | ||
|
19a0e3cda7 | ||
|
7fb13b3cbf | ||
|
23d986657a | ||
|
8f1419fff5 | ||
|
b80c22e9c4 | ||
|
f672fe90c1 | ||
|
3d55d3045e | ||
|
7ffc1a5efe | ||
|
36a833053b | ||
|
ad35c9c2d3 | ||
|
1b1465a677 | ||
|
2f6ce68ca7 | ||
|
dee1225fa4 | ||
|
d78d6fba7e | ||
|
80bdc90650 | ||
|
c402d57809 | ||
|
f1836af0b0 | ||
|
eebcc57079 | ||
|
cbc04d73b8 | ||
|
be9eff0fad | ||
|
3f3e47d280 | ||
|
40ca081ff4 | ||
|
c46fd1ff5b | ||
|
55b237dbe8 | ||
|
2b3556b460 | ||
|
d2e0087c4e | ||
|
9a650a4772 | ||
|
f4739f89bf | ||
|
7ade54dfd7 | ||
|
45fde332a0 | ||
|
82cc5c76a4 | ||
|
67a4ba4228 | ||
|
79a3607d0c | ||
|
dffeabbacb | ||
|
9fa7de2036 | ||
|
bacc873896 | ||
|
375d25627d | ||
|
56e2ed2628 | ||
|
ad55da4ef9 | ||
|
272231467a | ||
|
6cb818c7ad | ||
|
c23547c4ca | ||
|
0468b38ff3 | ||
|
ebbc562aab | ||
|
f387bb5e77 | ||
|
c5461ffd9f | ||
|
8c1c92bff6 | ||
|
36be6abfbd | ||
|
f24e93ade1 | ||
|
1a6a518f49 | ||
|
fc7ca12edd | ||
|
bbd36d0610 | ||
|
eebe7c798a | ||
|
76a7bed575 | ||
|
46b480c798 | ||
|
b4a6c36215 | ||
|
121f348379 | ||
|
16fb7967ff | ||
|
88a2ef45ee | ||
|
dd6077eb90 | ||
|
568ca0e773 | ||
|
fa5c9f764a | ||
|
5193fd9d99 | ||
|
a526eee165 | ||
|
848c65fe4f | ||
|
488a13543e | ||
|
3cc0abf6ea | ||
|
35b95c2b00 | ||
|
7630f579e1 | ||
|
8bd2ed1494 | ||
|
f5dba03447 | ||
|
73bcd869dc | ||
|
1dabb9b8c5 | ||
|
5d39daa13c | ||
|
54cf10588d | ||
|
52826ec4c1 | ||
|
ba9ccc12a5 | ||
|
67ea2163f4 | ||
|
1e1cd4554e | ||
|
319df53e87 | ||
|
8e1be83b56 | ||
|
5cfa736ad0 | ||
|
8a282ef267 | ||
|
709055980e | ||
|
576e21f2fd | ||
|
e6bf3b6975 | ||
|
196785ff05 | ||
|
dd9dd76722 | ||
|
aae02a43da | ||
|
ab308bea31 | ||
|
5f3ad4fc9b | ||
|
f031563400 | ||
|
d354d01af7 | ||
|
35b936200f | ||
|
e6c450b346 | ||
|
c813de133b | ||
|
abe61dc903 | ||
|
f624a082ad | ||
|
38703cbf5d | ||
|
930c2cd2eb | ||
|
225c495632 | ||
|
5705ffbd2b | ||
|
6e0f5287ea | ||
|
f63a066b98 | ||
|
6ff6db23bf | ||
|
2af25bc58e | ||
|
2b39c192a6 | ||
|
0873d14614 | ||
|
712523f004 | ||
|
c2634a7ccf | ||
|
e8ae4afd09 | ||
|
96aa4cacae | ||
|
4242fa7f22 | ||
|
abdab18807 | ||
|
12d8ef5a21 | ||
|
6f95a495ab | ||
|
99dad019cc | ||
|
ff2af3dffd | ||
|
294452cd43 | ||
|
820c22775c | ||
|
16f18cbce8 | ||
|
0f10c8824c | ||
|
c5277df361 | ||
|
b83d29764e | ||
|
dd13070260 | ||
|
bd3b6f17e4 | ||
|
1fa861ecb9 | ||
|
2cf207b53e | ||
|
4bd6d6559f | ||
|
4b3fec660a | ||
|
dc160ab570 | ||
|
4c7efcbd02 | ||
|
27c0fffe7c | ||
|
df8f5f4800 | ||
|
71461c6082 | ||
|
61ea56a1bd | ||
|
235c652648 | ||
|
61c00ccae5 | ||
|
084f51c7db | ||
|
18bb52554f | ||
|
b9162ad7bd | ||
|
5300077109 | ||
|
cbc77f1f25 | ||
|
bcee8ad43d | ||
|
336822f672 | ||
|
5543f13051 | ||
|
30eb01ef37 | ||
|
d380b57d28 | ||
|
820a0ddb8a | ||
|
d84ec07ff6 | ||
|
c48d5242ce | ||
|
c057e057f9 | ||
|
fb03134411 | ||
|
732ba55126 | ||
|
49d54df7d0 | ||
|
c89c83f5c1 | ||
|
3e83390fb9 | ||
|
0f9b4b6fd5 | ||
|
bac9c65515 | ||
|
5b9b09a90e | ||
|
43544435fa | ||
|
ac30924cdf | ||
|
675e10d6fb | ||
|
77f438ed85 | ||
|
9dea1502eb | ||
|
e1a71ce7cc | ||
|
53aea17949 | ||
|
1f16ada70c | ||
|
b539134e54 | ||
|
6180dcce45 | ||
|
040f842e6c | ||
|
5cb66f8090 | ||
|
a2b6b142d8 | ||
|
55408b73ca | ||
|
f4b60f0b68 | ||
|
a1af84f29a | ||
|
0e1956bb29 | ||
|
64e8a34281 | ||
|
043929d850 | ||
|
af3cb1c9c3 | ||
|
c6796ac6df | ||
|
6b4911c6a2 | ||
|
ec0e368a7f | ||
|
1275de1b07 | ||
|
746ce7d406 | ||
|
bb4b6901ad | ||
|
a7fdd3c165 | ||
|
1f9832b449 | ||
|
75648e80cf | ||
|
8a7540321d | ||
|
adc7056c9e | ||
|
b1b4a12848 | ||
|
7b77f400a1 | ||
|
4d7455e783 | ||
|
66d66b31dc | ||
|
9c3ce0048a | ||
|
3a3a233994 | ||
|
d5db0c5ba7 | ||
|
dd6c37c13d | ||
|
e4af94d3f9 | ||
|
bf497f4aae | ||
|
6600478675 | ||
|
bbbc36a1e6 | ||
|
361d642660 | ||
|
a72806a0ba | ||
|
a1c53eae1e | ||
|
a4343bdfd9 | ||
|
940e4a7c4d | ||
|
3090d8146f | ||
|
78831a72d5 | ||
|
68f0f24670 | ||
|
6b9c5aa1ac | ||
|
902c83ece3 | ||
|
30650b9c13 | ||
|
5976079fd3 | ||
|
1e3f146707 | ||
|
015b269c21 | ||
|
802544662d | ||
|
41c247b8ff | ||
|
b2d3c92da9 | ||
|
bc295040d0 | ||
|
c441a634a5 | ||
|
c71c3115cc | ||
|
5ae8d1a7a3 | ||
|
0055eeeeb8 | ||
|
5443fd4219 | ||
|
626ae82fee | ||
|
4fd2870720 | ||
|
a9e32ad0a5 | ||
|
165eae9c31 | ||
|
a343b375df | ||
|
28b6ee47e3 | ||
|
ae41be85c8 | ||
|
e7936c8595 | ||
|
5467bc4f24 | ||
|
477fb7dc20 | ||
|
05bfa4b476 | ||
|
630cc496ea | ||
|
c3af5a69da | ||
|
7455fbd2ad | ||
|
ea217de338 | ||
|
1492f6dbc4 | ||
|
e757f10e44 | ||
|
c868265397 | ||
|
e5e0315d34 | ||
|
0224fc5210 | ||
|
b96277e28a | ||
|
b5d8f68b87 | ||
|
0a47b30528 | ||
|
26a40bc174 | ||
|
990bc6a11f | ||
|
91774cf074 | ||
|
9d5ce204aa | ||
|
a9d82331e6 | ||
|
8dcff164fa | ||
|
54b721ebde | ||
|
d19a3fc3b8 | ||
|
950b248220 | ||
|
bc3b6ed601 | ||
|
33bbff2aa5 | ||
|
5c94900026 | ||
|
e02a0a8c88 | ||
|
d8523b0db8 | ||
|
d74dd7a60a | ||
|
c08ed3ce44 | ||
|
19275aa8bb | ||
|
7bbbfb0dee | ||
|
ef7018cca4 | ||
|
f2a2c67152 | ||
|
9719766007 | ||
|
32fb2e8a3e | ||
|
363dee6846 | ||
|
a28d92d049 | ||
|
39294e0147 | ||
|
027ae738a8 | ||
|
ce5e23f209 | ||
|
139a93156b | ||
|
9cf7328452 | ||
|
0bccf29254 | ||
|
ede2e89670 | ||
|
56117751a8 | ||
|
1bce499383 | ||
|
699c073d85 | ||
|
95947a29d5 | ||
|
70f48e6ca3 | ||
|
0a2c88c288 | ||
|
c70d62aeb4 | ||
|
a4a3c63779 | ||
|
a98f6ca354 | ||
|
deb96b372e | ||
|
360d8fe6b1 | ||
|
93102b45e0 | ||
|
fd3bf51f7d | ||
|
79314ab98f | ||
|
38fed8c901 | ||
|
081e9eb45f | ||
|
c0b8666d1f | ||
|
210df9d835 | ||
|
dc775bc5f8 | ||
|
ec47c4f932 | ||
|
25d28e7421 | ||
|
2c74a31afe | ||
|
bae02358a3 | ||
|
f97a59597f | ||
|
6edfcda43a | ||
|
c9c15a727d | ||
|
5324809a91 | ||
|
f69b920dbc | ||
|
a4c851f759 | ||
|
2751e239eb | ||
|
0af3ed548c | ||
|
7cdd4877c3 | ||
|
37acfbd372 | ||
|
e7cd3f0b33 | ||
|
354910faab | ||
|
0f1f277819 | ||
|
3b1b5bde68 | ||
|
82813f48c4 | ||
|
0b9870959b | ||
|
4100b47b37 | ||
|
43c828f8ca | ||
|
b01a1ee818 | ||
|
50211c706a | ||
|
ce42e42ed7 | ||
|
34f572f792 | ||
|
44287ca25e | ||
|
6bed5368e6 | ||
|
4591dcad2c | ||
|
dbcea07600 | ||
|
b76601482f | ||
|
8e9d445248 | ||
|
7d1dde01ba | ||
|
79b57feab6 | ||
|
1a92ae77a0 | ||
|
84b8ea8395 | ||
|
9491948f04 | ||
|
073268bd45 | ||
|
7cfce2fffa | ||
|
a1fda4f218 | ||
|
1a31974789 | ||
|
3d63936a36 | ||
|
2e9060d549 | ||
|
467829af32 | ||
|
9cd28b2ded | ||
|
686831caf5 | ||
|
1efd5e6b7e | ||
|
f90edc1e8b | ||
|
d1ff365767 | ||
|
6132a46768 | ||
|
1f541487e0 | ||
|
1a160e7afe | ||
|
016e10c1b0 | ||
|
6d52c80273 | ||
|
63a32ce483 | ||
|
7170c20c7e | ||
|
7e6667f58f | ||
|
67cb53d587 | ||
|
e622854789 | ||
|
792b9dc45f | ||
|
fe535d25e5 | ||
|
c4cc5e613c | ||
|
0a5a7893a5 | ||
|
f39d31631b | ||
|
8d3ae53bcd | ||
|
d6f57259fa | ||
|
112bfa5897 | ||
|
da105e3bda | ||
|
2e8815ece8 | ||
|
830e30e2fb | ||
|
d60336ba96 | ||
|
44813e56a5 | ||
|
b313d88db1 | ||
|
9e808255f8 | ||
|
fe57c16f6f | ||
|
2d9eb7e25d | ||
|
b7be7c900a | ||
|
e2756f8e9a | ||
|
367557039a | ||
|
31b0feae14 | ||
|
2cc25e65f4 | ||
|
3f9cdea1c1 | ||
|
71601e363e | ||
|
9b9d15438e | ||
|
6121095a30 | ||
|
6773ab35d2 | ||
|
196f2af596 | ||
|
d1ddb39781 | ||
|
882273d508 | ||
|
0aba3abaeb | ||
|
1c7c2f50b0 | ||
|
f345908f77 | ||
|
ab9e7d50a3 | ||
|
834ac04c3b | ||
|
e2ba3d09a5 | ||
|
bac0ca39ba | ||
|
68acf8815c | ||
|
736f2fed42 | ||
|
fdbbbd146a | ||
|
bac165a751 | ||
|
3d488bcf1c | ||
|
39c9fc1199 | ||
|
99dfe9f66a | ||
|
03d6fbec0a | ||
|
5c8d366975 | ||
|
26252c37cd | ||
|
b6080634cc | ||
|
f91468ff9b | ||
|
22cb026e5e | ||
|
be4cdcf170 | ||
|
fd85701a84 | ||
|
1135a1f9d5 | ||
|
d71544d797 | ||
|
08066065e3 | ||
|
a9bd3ca0dc | ||
|
031bbcef40 | ||
|
d6c26af696 | ||
|
12308b3c29 | ||
|
85ae27e372 | ||
|
ce6c90a450 | ||
|
1172937e8a | ||
|
146f2cbd4d | ||
|
8ea018404a | ||
|
5d249c1ae5 | ||
|
09e64c24f2 | ||
|
462e094783 | ||
|
8a09e90f02 | ||
|
bfc3f1f4b2 | ||
|
2b20b9e064 | ||
|
3427e224e3 | ||
|
cf1474fc19 | ||
|
e6068912a4 | ||
|
e59b5bf1af | ||
|
6f315bc235 | ||
|
2491984da3 | ||
|
f1bef11f45 | ||
|
4e46d2bb3b | ||
|
a384d14f92 | ||
|
471c1cc044 | ||
|
1cdbdc548a | ||
|
0f18bd0a6a | ||
|
14f97d0f2a | ||
|
75f28cb0cb | ||
|
9e58503aee | ||
|
18f0ce26fd | ||
|
bc0de5dbc5 | ||
|
4e3325b7f7 | ||
|
3284e941c6 | ||
|
aa40223ff2 | ||
|
04edd69b7a | ||
|
50d268538e | ||
|
3cd5294d8a | ||
|
8a7bc6a0bb | ||
|
894a392640 | ||
|
c3b0347556 | ||
|
2b9e988dd5 | ||
|
b6af7a9cf9 | ||
|
d14adc1e68 | ||
|
5499d5ae84 | ||
|
0a40ce6f9d | ||
|
15927fd097 | ||
|
c17328da87 | ||
|
165aa63d2e | ||
|
fa701228d7 | ||
|
7aef23e97f | ||
|
e6592e6201 | ||
|
38ee88e5ee | ||
|
7d49075079 | ||
|
577d43facf | ||
|
909e6c6249 | ||
|
62596f991e | ||
|
fd7ccc7627 | ||
|
0bcf5d6da6 | ||
|
57513db5c4 | ||
|
70eb639c41 | ||
|
52b1e2a9ff | ||
|
a4b657b040 | ||
|
371e60238a | ||
|
cc306290da | ||
|
eb7816259c | ||
|
735fb20ac6 | ||
|
a429eefbe7 | ||
|
f53815c6ee | ||
|
f2fceac341 | ||
|
968c2ede0d | ||
|
a90a977d68 | ||
|
7ab61f6732 | ||
|
7aae78e8a7 | ||
|
77a1ff8b00 | ||
|
9e6ca94a72 | ||
|
5aa16b7489 | ||
|
d48355c305 | ||
|
519ecddc52 | ||
|
c73e635936 | ||
|
1ed2b21aaa | ||
|
1786dc714d | ||
|
cc1494bfb6 | ||
|
7b1f643977 | ||
|
01b1137284 | ||
|
d99d408fd8 | ||
|
e1d05f0a0f | ||
|
c36d3f5145 | ||
|
ac953f5327 | ||
|
a2b5d4e02b | ||
|
83b139e7ba | ||
|
62494e735f | ||
|
7b3c905a46 | ||
|
ddc4a26457 | ||
|
2457dce862 | ||
|
0c19df09d9 | ||
|
c298cd5714 | ||
|
60d5d9762b | ||
|
22106f6dd3 | ||
|
89f5244007 | ||
|
d34abd6665 | ||
|
fb37e93b04 | ||
|
888c33c890 | ||
|
434bc96c74 | ||
|
9c100c8d0a | ||
|
2eb23cb9f4 | ||
|
9c9c1d9e19 | ||
|
42bdf852da | ||
|
b547141f7a | ||
|
0633053d5d | ||
|
3a71b2e887 | ||
|
cdb5e90515 | ||
|
b5128a6e1c | ||
|
ac7fa82b2f | ||
|
a7fa43fd39 | ||
|
890e57cfab | ||
|
f656e7f6a9 | ||
|
3104f123ca | ||
|
f041cf97a2 | ||
|
8225d3758f | ||
|
202a6b3072 | ||
|
5b88d0bfac | ||
|
8b57eacd1b | ||
|
18e7903b78 | ||
|
5d8302b147 | ||
|
2e8f4b8d21 | ||
|
9c13f76b66 | ||
|
f3e6d39382 | ||
|
4ffd2d6ccd | ||
|
1b2a62623c | ||
|
ad45f801d5 | ||
|
f60d90aeb6 | ||
|
8a519202a8 | ||
|
9c9e200df5 | ||
|
b3b0747328 | ||
|
8f9ff2cfe0 | ||
|
ea94337f96 | ||
|
3e06c99a0a | ||
|
f2807bc782 | ||
|
6464eff516 | ||
|
e1acb774c6 | ||
|
de6d37134c | ||
|
93ec1a9df2 | ||
|
0703fbf527 | ||
|
0e5de67d5f | ||
|
d993d51367 | ||
|
3909ce39ef | ||
|
e8cd0ed7c5 | ||
|
85969bc0bd | ||
|
659f67f04f | ||
|
e2d0f3f845 | ||
|
ed766859d7 | ||
|
5503161fdc | ||
|
e83b09b4eb | ||
|
2e34a10e93 | ||
|
aa838791bf | ||
|
4a6f714153 | ||
|
f736d3a3de | ||
|
471b287f70 | ||
|
1c4865147a | ||
|
b3bc711ed2 | ||
|
ef09e376b1 | ||
|
0a5eb88696 | ||
|
63372cd4aa | ||
|
b9f0e39b1b | ||
|
ebab5f3ec1 | ||
|
6749e4ead9 | ||
|
58c4fd5a0b | ||
|
fccebc816d | ||
|
bf7cc2c04f | ||
|
7f195606ee | ||
|
91e0151674 | ||
|
4aa496b079 | ||
|
4fcd3ba56e | ||
|
77c0de71c4 | ||
|
7c40f797dc | ||
|
189f694710 | ||
|
b02c8b606c | ||
|
24c9e45789 | ||
|
53db7fdc50 | ||
|
70aa4e4247 | ||
|
b26898e6e1 | ||
|
0c2316b638 | ||
|
f42cbac237 | ||
|
b06d9cce37 | ||
|
be92ad13ab | ||
|
3bb447cf8d | ||
|
66c65beea7 | ||
|
be9a6de0ef | ||
|
b3954aefd5 | ||
|
555fe68a01 | ||
|
1ddda558b0 | ||
|
db47cdaa1a | ||
|
7062583ab4 | ||
|
b454a0777f | ||
|
6ba9de491c | ||
|
24b38eb812 | ||
|
14e37ed124 | ||
|
cee82d8659 | ||
|
f5bbf06b60 | ||
|
6b229d7d5f | ||
|
67fff7f4fc | ||
|
6e35f47a3e | ||
|
6514649439 | ||
|
77340e9273 | ||
|
35f73199d4 | ||
|
34c79fdc50 | ||
|
c8e789e12a | ||
|
77173b7057 | ||
|
7fac1d4ae2 | ||
|
52620f147b | ||
|
f3d583b124 | ||
|
fc0094231d | ||
|
aacdeba5d9 | ||
|
761fb103b7 | ||
|
afc17c1168 | ||
|
bfdd611fde | ||
|
ffeb43a38a | ||
|
93f4852ba3 | ||
|
4e460da371 | ||
|
6feb8d8875 | ||
|
57222002b2 | ||
|
4fc8101910 | ||
|
011a984951 | ||
|
105ad61b6f | ||
|
23ea3dcb48 | ||
|
a4b8729e6a | ||
|
687b93b215 | ||
|
8af9abbbb9 | ||
|
25e2dbf031 | ||
|
af56e53315 | ||
|
7a114d640c | ||
|
c5071cc87b | ||
|
0990c279c7 | ||
|
76c32d60f9 | ||
|
ebdac2ddfc | ||
|
caf708b618 | ||
|
40aaf784b9 | ||
|
db1ca2c854 | ||
|
a9f1297022 | ||
|
f8058586f9 | ||
|
ad1352f109 | ||
|
df03740741 | ||
|
a437a3d743 | ||
|
927aa49576 | ||
|
de1ce0b27d | ||
|
a9e1ca63dd | ||
|
4cd251fc48 | ||
|
6d59e2866b | ||
|
da13903228 | ||
|
585f622886 | ||
|
0de69c3899 | ||
|
0238234c52 | ||
|
8b2f500d2a | ||
|
a30563634d | ||
|
e5fde77e56 | ||
|
bfb9c8fddd | ||
|
0402ce9b8e | ||
|
e2f0edd8f6 | ||
|
4f1404e991 | ||
|
9813a9164b | ||
|
b9ba7000bb | ||
|
4c304467ba | ||
|
6a9502ab17 | ||
|
9eda923269 | ||
|
47a6f8fbff | ||
|
c2826000bb | ||
|
7cea5df074 | ||
|
8b9e1f513f | ||
|
fdbf796b6b | ||
|
5ac41bf091 | ||
|
e158021a4d | ||
|
549c499501 | ||
|
838566ea41 | ||
|
6e2f0f695f | ||
|
6f9929b1c0 | ||
|
35d4ceaf37 | ||
|
2e41129c36 | ||
|
1df6a87249 | ||
|
e02d608bce | ||
|
7008aeaf22 | ||
|
ac44e6f2ae | ||
|
1d869c4b36 | ||
|
e7c86c6760 | ||
|
dbf342df3c | ||
|
3cf87dfe8a | ||
|
ea5e373df6 | ||
|
c7256c1c11 | ||
|
7cbced0c12 | ||
|
a84defe86f | ||
|
9dbd953cc2 | ||
|
ea613e6b26 | ||
|
16dd077fb2 | ||
|
4da70bbab1 | ||
|
566c6fa464 | ||
|
b95b85fee4 | ||
|
63ee17701a | ||
|
00e2415b81 | ||
|
6a8a2cf5fb | ||
|
c949ad35cc | ||
|
ae4ffacbda | ||
|
1379b621f7 | ||
|
089b5eb212 | ||
|
7c877edd2d | ||
|
4e22b62192 | ||
|
21c8829783 | ||
|
20791e4d95 | ||
|
f6283b8e91 | ||
|
b936cb366f | ||
|
31e334a332 | ||
|
7a2d3d993c | ||
|
a9acab6b7e | ||
|
a8cbe3a56d | ||
|
dfb9862460 | ||
|
215fde71a3 | ||
|
4bee872c09 | ||
|
e8f557ae5f | ||
|
d7462ae5ad | ||
|
a48a0543c8 | ||
|
ff4aed2227 | ||
|
39f6b6fc6b | ||
|
0b5085f4f0 | ||
|
512cd24e53 | ||
|
83a8d5a561 | ||
|
26fbb921f5 | ||
|
589f5519d7 | ||
|
3592293cca | ||
|
4312dfcf41 | ||
|
94ced5845a | ||
|
a16391ecb0 | ||
|
4ea90cefe8 | ||
|
97eb54738f | ||
|
641acd5709 | ||
|
856f67b4ac | ||
|
71778859a7 | ||
|
47b09cce5d | ||
|
c9fb7eb4d6 | ||
|
3870322888 | ||
|
396f8c96af | ||
|
9bd415d58e | ||
|
8bc6bcf86e | ||
|
54b3135d59 | ||
|
446c3b4cfd | ||
|
adf0dac2c3 | ||
|
1caa78a3e7 | ||
|
e61e1ed425 | ||
|
01d7269904 | ||
|
7c72f79329 | ||
|
bf52b1a2e3 | ||
|
2bdb599fbc | ||
|
3971cc6e88 | ||
|
209b850067 | ||
|
7251fefa89 | ||
|
3c72be23f0 | ||
|
699454ad7f | ||
|
e8fb500819 | ||
|
d6c10fec7b | ||
|
f34be6f5f0 | ||
|
b931724b75 | ||
|
bd6da13a67 | ||
|
f52e8759c5 | ||
|
2090ed6f7c | ||
|
246d5412e0 | ||
|
9b1b6b3ce4 | ||
|
c8c14e31d8 | ||
|
4d0a1db4ac | ||
|
a0f63d40c6 | ||
|
f0537ea0f1 | ||
|
9492231058 | ||
|
c385d5bf0c | ||
|
d377c778a7 | ||
|
17b12a32b0 | ||
|
99321b371a | ||
|
58c9fdc8c5 | ||
|
7fc654eb21 | ||
|
a0a4421278 | ||
|
7a359a958e | ||
|
cd10b439d0 | ||
|
5b76eec1af | ||
|
f55aee0fc1 | ||
|
21957f6e38 | ||
|
fc697bfdb1 | ||
|
818763b332 | ||
|
cc6c05fcf2 | ||
|
f6adb32202 | ||
|
4e1a01959d | ||
|
435978648b | ||
|
c354540a31 | ||
|
8d98b9193b | ||
|
d8e8941c77 | ||
|
d32498f65f | ||
|
29537da370 | ||
|
cbe8542622 | ||
|
fd3bf6c3d2 | ||
|
53ef55410c | ||
|
4263a1a410 | ||
|
37d2bf4d9a | ||
|
6bd7123072 | ||
|
c979ef393b | ||
|
0e4b404102 | ||
|
89de3b6c01 | ||
|
1682e2708d | ||
|
71fb3e84da | ||
|
3bb55dfdde | ||
|
497553d985 | ||
|
d336191ed1 | ||
|
cf7f25fe50 | ||
|
b6b66acfc7 | ||
|
d962999161 |
715
CONTRIBUTORS
715
CONTRIBUTORS
File diff suppressed because it is too large
Load Diff
2
Doxyfile
2
Doxyfile
@ -1658,7 +1658,7 @@ UML_LOOK = NO
|
||||
# the class node. If there are many fields or methods and many nodes the
|
||||
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
|
||||
# threshold limits the number of items for each type to make the size more
|
||||
# managable. Set this to 0 for no limit. Note that the threshold may be
|
||||
# manageable. Set this to 0 for no limit. Note that the threshold may be
|
||||
# exceeded by 50% before the limit is enforced.
|
||||
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
|
146
INSTALL
146
INSTALL
@ -1,7 +1,7 @@
|
||||
Installation of the Video Disk Recorder
|
||||
---------------------------------------
|
||||
|
||||
Version 2.0
|
||||
Version 2.7
|
||||
-----------
|
||||
|
||||
Compiling and running the program:
|
||||
@ -47,9 +47,9 @@ By default the 'vdr' program can be controlled via the PC keyboard.
|
||||
If you want to disable control via the keyboard, you can add NO_KBD=1
|
||||
to the 'make' call, or use the '--no-kbd' option at runtime.
|
||||
|
||||
If you have an infrared remote control unit you can define the REMOTE macro
|
||||
to one of the following values in the 'make' call to make the respective control
|
||||
the default:
|
||||
If you have a LIRC compatible infrared remote control receiver you can define
|
||||
the REMOTE macro to one of the following values in the 'make' call to make
|
||||
the respective control the default:
|
||||
|
||||
REMOTE=LIRC control via the "Linux Infrared Remote Control"
|
||||
(see http://www.lirc.org)
|
||||
@ -73,16 +73,15 @@ port ("Simple Video Disk Recorder Protocol"). By default, it listens
|
||||
on port 6419 (use the --port=PORT option to change this). For details
|
||||
about the SVDRP syntax see the source file 'svdrp.c'.
|
||||
|
||||
WARNING: DUE TO THE OPEN SVDRP PORT THIS PROGRAM MAY CONSTITUTE A
|
||||
======= POTENTIAL SECURITY HAZARD! IF YOU ARE NOT RUNNING VDR IN
|
||||
A CONTROLLED ENVIRONMENT, YOU MAY WANT TO DISABLE SVDRP
|
||||
BY USING '--port=0'!
|
||||
|
||||
The file 'svdrphosts.conf' can be used to define which hosts are allowed
|
||||
to access the SVDRP port. By default only localhost (127.0.0.1) is granted
|
||||
access. If you want to give other hosts access to your SVDRP port you need to
|
||||
add their IP numbers to 'svdrphosts.conf'.
|
||||
|
||||
You can disable SVDRP access entirely by either running VDR with '--port=0',
|
||||
or by removing all entries (including 127.0.0.1 for the localhost) from
|
||||
'svdrphosts.conf'.
|
||||
|
||||
If the program shall run as a daemon, use the --daemon option. This
|
||||
will completely detach it from the terminal and will continue as a
|
||||
background process.
|
||||
@ -94,6 +93,24 @@ vdr:123:respawn:/usr/local/bin/vdr --terminal=/dev/tty8 -w 60
|
||||
|
||||
See the man page vdr(1) for complete information about all command line options.
|
||||
|
||||
Output devices
|
||||
--------------
|
||||
|
||||
VDR by itself doesn't produce any audio or video output. In order to watch
|
||||
live tv or recordings, you will need to use a plugin that supports the actual
|
||||
hardware in your system, for instance:
|
||||
|
||||
Plugin: Device:
|
||||
|
||||
dvbsddevice Full-Featured SD DVB cards (Fujitsu-Siemens Design)
|
||||
ftp://ftp.tvdr.de/vdr/Plugins
|
||||
dvbhddevice Full-featured HD DVB cards (Technotrend TT S2-6400)
|
||||
https://bitbucket.org/powARman/dvbhddevice
|
||||
rpihddevice Raspberry Pi
|
||||
https://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git
|
||||
|
||||
See https://linuxtv.org/vdrwiki/index.php/Output_devices for more.
|
||||
|
||||
Standard compliance
|
||||
-------------------
|
||||
|
||||
@ -134,14 +151,14 @@ displayed correctly. Since BiDi support adds some runtime overhead by requiring
|
||||
additional memory allocation and copying, this feature is not compiled in
|
||||
by default, so that users that have no need for this don't get any overhead.
|
||||
|
||||
Workaround for providers not encoding their EPG data correctly
|
||||
--------------------------------------------------------------
|
||||
Workaround for providers not encoding their DVB SI table strings correctly
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
According to "ETSI EN 300 468" the default character set fo SI data is
|
||||
According to "ETSI EN 300 468" the default character set for SI data is
|
||||
ISO6937. But unfortunately some broadcasters actually use ISO-8859-9 or
|
||||
other encodings, but fail to correctly announce that.
|
||||
Users who want to set the default character set to something different can
|
||||
do this by setting the environment variable VDR_CHARSET_OVERRIDE to something
|
||||
do this by using the command line option --chartab with something
|
||||
like ISO-8859-9.
|
||||
|
||||
Start script with automatic restart in case of hangups:
|
||||
@ -247,23 +264,27 @@ Executing commands before and after a recording:
|
||||
------------------------------------------------
|
||||
|
||||
You can use the '-r' option to define a program or script that gets called
|
||||
before and after a recording is performed, and after an editing process
|
||||
has finished or a recording has been deleted.
|
||||
at various stages of handling recordings.
|
||||
|
||||
The program will be called with two or three (in case of "edited") string
|
||||
parameters. The first parameter is one of
|
||||
The program will be called with two or three string parameters.
|
||||
The first parameter is one of
|
||||
|
||||
before if this is *before* a recording starts
|
||||
started if this is after a recording has *started*
|
||||
after if this is *after* a recording has finished
|
||||
editing if this is before *editing* a recording
|
||||
edited if this is after a recording has been *edited*
|
||||
deleted if this is after a recording has been *deleted*
|
||||
copying if this is before *copying* a recording
|
||||
copied if this is after a recording has been *copied*
|
||||
renamed if this is after a recording has been *renamed*
|
||||
moved if this is after a recording has been *moved*
|
||||
(note that a move across file system borders triggers a sequence
|
||||
of "copying", "copied" and "deleted")
|
||||
|
||||
and the second parameter contains the full name of the recording's
|
||||
and the second and third parameter (if present) contain the full name of the recording's
|
||||
directory (which may not yet exists at that moment in the "before" case).
|
||||
In the "edited" case it will be the name of the edited version (second
|
||||
parameter) and the name of the source version (third parameter).
|
||||
In the "deleted" case the extension of the directory name is ".del"
|
||||
instead of ".rec".
|
||||
See the example below for the exact meaning of these parameters.
|
||||
|
||||
Within this program you can do anything you would like to do before and/or
|
||||
after a recording or after an editing process. However, the program must return
|
||||
@ -279,9 +300,16 @@ case "$1" in
|
||||
before)
|
||||
echo "Before recording $2"
|
||||
;;
|
||||
started)
|
||||
echo "Started recording $2"
|
||||
;;
|
||||
after)
|
||||
echo "After recording $2"
|
||||
;;
|
||||
editing)
|
||||
echo "Editing recording $2"
|
||||
echo "Source recording $3"
|
||||
;;
|
||||
edited)
|
||||
echo "Edited recording $2"
|
||||
echo "Source recording $3"
|
||||
@ -289,6 +317,22 @@ case "$1" in
|
||||
deleted)
|
||||
echo "Deleted recording $2"
|
||||
;;
|
||||
copying)
|
||||
echo "Destination recording $2"
|
||||
echo "Source recording $3"
|
||||
;;
|
||||
copied)
|
||||
echo "Destination recording $2"
|
||||
echo "Source recording $3"
|
||||
;;
|
||||
renamed)
|
||||
echo "New name of recording $2"
|
||||
echo "Old name of recording $3"
|
||||
;;
|
||||
moved)
|
||||
echo "New path of recording $2"
|
||||
echo "Old path of recording $3"
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown state: $1"
|
||||
;;
|
||||
@ -325,38 +369,9 @@ Note that the file system need not be 64-bit proof, since the 'vdr'
|
||||
program splits video files into chunks of about 2GB. You should use
|
||||
a disk with several gigabytes of free space. One GB can store roughly
|
||||
half an hour of SD video data, or 10 minutes of HD video.
|
||||
|
||||
If you have more than one disk and don't want to combine them to form
|
||||
one large logical volume, you can set up several video directories as
|
||||
mount points for these disks. All of these directories must have the
|
||||
same basic name and must end with a numeric part, which starts at 0 for
|
||||
the main directory and has increasing values for the rest of the
|
||||
directories. For example
|
||||
|
||||
/srv/vdr/video0
|
||||
/srv/vdr/video1
|
||||
/srv/vdr/video2
|
||||
|
||||
would be a setup with three directories. You can use more than one
|
||||
numeric digit:
|
||||
|
||||
/mnt/MyVideos/vdr.00
|
||||
/mnt/MyVideos/vdr.01
|
||||
/mnt/MyVideos/vdr.02
|
||||
...
|
||||
/mnt/MyVideos/vdr.11
|
||||
|
||||
would set up twelve disks (wow, what a machine that would be!).
|
||||
|
||||
To use such a multi directory setup, you need to add the '-v' option
|
||||
with the name of the basic directory when running 'vdr':
|
||||
|
||||
vdr -v /srv/vdr/video0
|
||||
|
||||
WARNING: Using multiple disks to form one large video directory this way
|
||||
is deprecated and will be removed from VDR in a future version! Either
|
||||
use one of today's large terabyte disks (preferably with a backup disk
|
||||
in a RAID-1 array), or use something like "mhddfs".
|
||||
Either use one of today's large terabyte disks (preferably with a backup disk
|
||||
in a RAID-1 array), or use something like "mhddfs" to group several disks
|
||||
into one large volume.
|
||||
|
||||
Note that you should not copy any non-VDR files into the video directory,
|
||||
since this might cause a lot of unnecessary disk access when VDR cleans up those
|
||||
@ -416,8 +431,9 @@ access your DiSEqC equipment (see man vdr(5) for details).
|
||||
A special form of DiSEqC is used to connect several receivers to one signal
|
||||
source using only a single cable. This method, known as "Satellite Channel Routing"
|
||||
according to EN50494 (aka "Unicable(TM)", "OLT(TM)", "SatCR", "Single Cable
|
||||
Distribution", "Channel Stacking System" or "Single Cable Interface") uses
|
||||
the file "scr.conf" to specify which SCR channels use which user band frequency.
|
||||
Distribution", "Channel Stacking System" or "Single Cable Interface") or
|
||||
EN50607 (aka "JESS") uses the file "scr.conf" to specify which SCR channels
|
||||
use which user band frequency.
|
||||
|
||||
If DVB-S devices need to be connected to the same satellite cable, but no
|
||||
"Satellite Channel Routing" is available, they can be set to be "bonded" in
|
||||
@ -468,19 +484,17 @@ for a detailed description).
|
||||
|
||||
The recommended PC key assignments are:
|
||||
|
||||
Up, Down, Left, Right Crsr keys in numeric block
|
||||
Menu 'Home' in numeric block
|
||||
Up, Down, Left, Right Cursor keys
|
||||
Menu 'Home'
|
||||
Ok 'Enter'
|
||||
Back 'End' in numeric block
|
||||
Back 'Backspace'
|
||||
Red, Green, Yellow, Blue 'F1'..'F4'
|
||||
0..9 '0'..'9' in top row
|
||||
Power 'P'
|
||||
Volume+/- '+', '-'
|
||||
Mute 'm'
|
||||
0..9 '0'..'9'
|
||||
Volume+/- 'PgUp', 'PgDn'
|
||||
Mute 'F10'
|
||||
|
||||
If you prefer different key assignments, or if the default doesn't work for
|
||||
your keyboard, simply delete the file 'remote.conf' and restart 'vdr' to get
|
||||
into learning mode.
|
||||
If you want to change your key assignments later, simply delete the file
|
||||
'remote.conf' and restart 'vdr' to get into learning mode.
|
||||
|
||||
Generating source code documentation:
|
||||
-------------------------------------
|
||||
|
391
MANUAL
391
MANUAL
@ -1,7 +1,7 @@
|
||||
Video Disk Recorder User's Manual
|
||||
---------------------------------
|
||||
|
||||
Version 2.0
|
||||
Version 2.7
|
||||
-----------
|
||||
|
||||
* Remote Control Keys
|
||||
@ -50,8 +50,8 @@ Version 2.0
|
||||
Next Next/previous channel group (in live tv mode)
|
||||
Prev or next/previous editing mark (in replay mode)
|
||||
|
||||
Channel+ channel up
|
||||
Channel- channel down
|
||||
Channel+ channel up (live view), next error (replay)
|
||||
Channel- channel down (live view), previous error (replay)
|
||||
PrevChannel previous channel
|
||||
|
||||
Power shutdown
|
||||
@ -90,7 +90,7 @@ Version 2.0
|
||||
be treated as part of that number, not as a sort mode toggle. If no numeric
|
||||
key has been pressed for more than one second, the number is reset and '0'
|
||||
functions as sort mode toggle again.
|
||||
(3) In the "Timers" menu, when on the "Day" item, the '0' key toggles between
|
||||
(3) In the "Edit timer" menu, when on the "Day" item, the '0' key toggles between
|
||||
a single shot and a repeating timer. If "Day" indicates a repeating timer,
|
||||
the keys '1'...'7' can be used to toggle the individual days ('1' is Monday).
|
||||
|
||||
@ -264,7 +264,7 @@ Version 2.0
|
||||
|
||||
* Pausing live video
|
||||
|
||||
If you want to pause the live programme you are just watching, simple press
|
||||
If you want to pause the live programme you are just watching, simply press
|
||||
"Menu/Yellow" or "Pause" on your remote control. VDR will start an instant
|
||||
recording of the current channel (just as if you had pressed "Menu/Red" or
|
||||
"Record") and immediately begin replaying that recording. Replay will be
|
||||
@ -276,6 +276,9 @@ Version 2.0
|
||||
in the "Setup/Recording" menu. Recording time will be the same as for
|
||||
any other instant recording, so by default it will record 3 hours (which
|
||||
should be enough for any normal broadcast).
|
||||
Note that the timer that is created for recording the paused live video will
|
||||
always record on the local VDR, even if an "SVDRP default host" has been
|
||||
set for normal timer recordings.
|
||||
|
||||
* Replaying a Recording
|
||||
|
||||
@ -363,15 +366,30 @@ Version 2.0
|
||||
- 0 Toggles an editing mark. If the mark indicator shows a red triangle,
|
||||
the current mark is deleted. Otherwise a new mark is set at the
|
||||
current position.
|
||||
- 4, 6 Move an editing mark back and forward. You need to first jump to
|
||||
an editing mark for this to work.
|
||||
- 1, 3 Move an editing mark back and forward in "adaptive" mode. Pressing
|
||||
either of these keys for the first time moves the mark 120 seconds
|
||||
in the given direction (configurable via "Setup/Replay/Initial
|
||||
duration for adaptive skipping"). Further presses of the same key
|
||||
keep moving the mark by the same value. Once the other key is
|
||||
pressed, the value is divided by 2 (hence the name "adaptive") with
|
||||
every further press of either key. Pressing '1' and '3'
|
||||
alternatingly divides the distance all the way down to a single
|
||||
I-frame. That way a particular place in a recording (for instance
|
||||
the beginning or end of a commercial break) can be found very
|
||||
quickly. If none of these two keys is pressed for a while
|
||||
(configurable via "Setup/Replay/Reset timeout for adaptive
|
||||
skipping") the distance falls back to the initial value.
|
||||
If replay is not in Pause mode, or if there is no mark at the
|
||||
current position, the skip is performed without moving any mark.
|
||||
- 4, 6 Move an editing mark back and forward by one I-frame. You need to
|
||||
first jump to an editing mark for this to work.
|
||||
- 7, 9 Jump back and forward between editing marks. Replay goes into still
|
||||
mode after jumping to a mark. If the current position is at the
|
||||
first or last mark, or if there are no marks at all, these keys
|
||||
jump to the very beginning or end, respectively, of the recording.
|
||||
- 8 Positions replay at a point 3 seconds before the current or next
|
||||
"begin" mark and starts replay.
|
||||
- 2 Start the actual cutting process.
|
||||
- 2 Starts the actual cutting process.
|
||||
|
||||
Editing marks are represented by black, vertical lines in the progress display.
|
||||
A small black triangle at the top of the mark means that this is a "begin"
|
||||
@ -462,6 +480,8 @@ Version 2.0
|
||||
"forever", and a value of 0 means that this recording can be
|
||||
deleted any time if a recording with a higher priority needs disk
|
||||
space.
|
||||
Pattern: The pattern to use for recordings matching events (only available
|
||||
for pattern timers). See section "Pattern timers" below.
|
||||
File: The name under which a recording created through this timer will
|
||||
be stored on disk (the actual name will also contain the date and
|
||||
time, so it is possible to have a "repeating timer" store all its
|
||||
@ -483,6 +503,9 @@ Version 2.0
|
||||
the name of the recording.
|
||||
First day: The date of the first day when this timer shall start recording
|
||||
(only available for repeating timers).
|
||||
Record on: The name of the remote VDR this timer shall record on (only available
|
||||
if there are any remote VDRs connected to this VDR). If this field
|
||||
is empty, the timer will record on the local VDR.
|
||||
|
||||
A timer can also be programmed by pressing the "Red" key on the "Schedule",
|
||||
"Now", "Next" or "Event" menus.
|
||||
@ -490,6 +513,140 @@ Version 2.0
|
||||
The "Red" key in the "Edit timer" menu opens a list of folders, which can be
|
||||
used to define the file name in which the recording will be stored.
|
||||
|
||||
The "Yellow" key in the "Edit timer" menu toggles the timer between "Pattern"
|
||||
and "Regular".
|
||||
|
||||
When editing the "File" field, the "Blue" key in can be used to insert useful
|
||||
macros.
|
||||
|
||||
* Pattern timers
|
||||
|
||||
There are cases where it would make sense to have a more flexible kind of
|
||||
recording timer. For instance, some channels that provide VPS don't always
|
||||
use the exact same VPS time for a series, which is extremely annoying.
|
||||
Or you might want to record all films that have a certain pattern in their
|
||||
title, no matter when they are broadcast. In such cases, "pattern timers"
|
||||
can help.
|
||||
|
||||
In the "Edit timer" menu press the Yellow button to turn a regular timer into
|
||||
a pattern timer. Pressing this button again switches back to regular.
|
||||
|
||||
The following rules apply to pattern timers:
|
||||
|
||||
- Pattern timers can only work for channels that provide EPG data.
|
||||
- When using pattern timers, there should always be at least one free device that
|
||||
can be used to regularly receive the EPG of the pattern timer's channel.
|
||||
- A pattern timer records every matching event on the given channel that overlaps
|
||||
with the given start/stop time. Overlapping events are recorded in full,
|
||||
even if they extend outside the given start/stop interval.
|
||||
- In order to actually record an event, a pattern timer "spawns" a separate timer
|
||||
that does the recording. If there are matching events that would start while
|
||||
the first spawned timer is still recording (due to the start/stop margins), timers
|
||||
for those events are also spawned.
|
||||
- Spawned timers are marked with the flag tfSpawned.
|
||||
- Spawned timers take the Priority, Lifetime and VPS settings from the pattern timer.
|
||||
- The special pattern "*" matches every event. So a timer with
|
||||
a start/stop time of 00:00/23:59 will record every event of that day
|
||||
into separate recordings. Note that when using this pattern there should
|
||||
be no other timers for the same channel, because these might interfere.
|
||||
- Once a timer has been spawned, it is treated like any other regular
|
||||
timer. Any changes made to the corresponding pattern timer thereafter will have
|
||||
no effect on spawned timers. Note that after deleting a spawned timer,
|
||||
the corresponding pattern timer may respawn it.
|
||||
- Recording is done according to the event's begin/end times, either
|
||||
by adding the start/stop margins (for non-VPS timers) or by using the
|
||||
event's running status (for VPS timers).
|
||||
- If the start/stop margins of a spawned timer are reduced because the event
|
||||
before and/or after that timer's event is shorter than the respective margin,
|
||||
the actual recording still uses the full margins.
|
||||
- If the times of the event change, a non-VPS pattern timer automatically adjusts
|
||||
itself to the new times. This also happens if the start/stop margins are changed
|
||||
in the setup.
|
||||
- The recording of a pattern timer is stored under the given file name, just like
|
||||
regular timers do. In addition to the "TITLE" and "EPISODE" macros the file
|
||||
name of a pattern timer can also use "{<}" and "{>}" to reference the part of the
|
||||
event's title before and after the pattern, respectively. For instance,
|
||||
if the event's title is "Abc def ghi" and the pattern is "def ", "{<}"
|
||||
would contain "Abc " and "{>}" would contain "ghi" (note the matching of the
|
||||
blanks). For completeness, "{=}" can be used to reference the matching
|
||||
pattern itself.
|
||||
- In the "Timers" menu pressing the Red button on a pattern timer only toggles the
|
||||
timer between "on" and "off", even if this is a repeating timer.
|
||||
- In the "Timers" menu pattern timers are sorted alphabetically to the end of the
|
||||
list of timers.
|
||||
- A regular timer that is currently recording can't be changed into a pattern timer.
|
||||
- In the "Edit timer" menu the file name and pattern are displayed as
|
||||
separate items. The Yellow button can be used to toggle between a regular
|
||||
timer and a pattern timer. When going from regular to pattern, the Pattern item will
|
||||
be initialized with the base part of the file name.
|
||||
- The characters '^' and '$' can be used at the very beginning and end of
|
||||
the pattern to anchor the pattern to the begin or end of the title.
|
||||
Using both of these will match only titles that consist of exactly the given pattern,
|
||||
with nothing before and nothing after it.
|
||||
- The Pattern field in the "Edit timer" menu allows blanks at the end of the string,
|
||||
which may help to separate the text after the matching pattern.
|
||||
- If the first character of the pattern is '@', an event that matches the
|
||||
rest of the pattern is only recorded if the resulting recording's file
|
||||
name (without any folders) is not contained in the donerecs.data file.
|
||||
This avoids duplicate recordings of the same programme. Timers spawned from
|
||||
such a pattern timer are marked with the flag tfAvoid.
|
||||
- When editing the "File" field of a timer, the Blue button can be pressed to
|
||||
insert one of the macros "TITLE", "EPISODE", "{<}", "{=}" or "{>}",
|
||||
respectively. Pressing the Blue button repeatedly loops through the available
|
||||
macros. The "{...}" macros are only available for pattern timers.
|
||||
- In the "Schedule" and "What's on...?" menus the events that will be recorded
|
||||
by a pattern timer are marked in the same way as regular timers.
|
||||
- The TIMERS column in the LCARS skin doesn't show the basic definitions of
|
||||
pattern timers, it only shows timers actually spawned from pattern timers.
|
||||
|
||||
If the pattern is prepended with '@', the name of the resulting recording (everything
|
||||
after the rightmost '~', or the entire file name, if there is no '~') will be stored
|
||||
in the file donerecs.data, so that multiple recordings of the same programme can be
|
||||
avoided. When using this feature, special care must be taken regarding the recording's
|
||||
file name. For instance, with a combination of
|
||||
|
||||
pattern file name
|
||||
@Columbo Movies~TITLE
|
||||
|
||||
if the event's title is just "Columbo", this pattern timer would only record once,
|
||||
and ignore any future events with that title, even if the episode would be different.
|
||||
So you may want to use the episode name, as in
|
||||
|
||||
pattern file name
|
||||
@Columbo Movies~TITLE - EPISODE
|
||||
|
||||
to make the file name unique. If you have several pattern timers for the same show on
|
||||
different channels, chances are that the broadcasters handle title and episode
|
||||
differently, as for example in
|
||||
|
||||
TITLE EPISODE pattern file name
|
||||
Columbo Blueprint for Murder @^Columbo$ TITLE - EPISODE
|
||||
Columbo - Blueprint for Murder @^Columbo TITLE
|
||||
Columbo: Blueprint for Murder @^Columbo:_ Columbo - {>}
|
||||
|
||||
(note the '_' in the pattern of the third example; this is just used to visualize
|
||||
the blank at the end of the pattern)
|
||||
|
||||
In order to have the same episode result in the same recording file name on all
|
||||
channels, the file name needs to be generated differently for each channel. First
|
||||
you need to decide on a proper combination of title and episode name, preferably
|
||||
one that is already used by one of your channels (let's say the second one).
|
||||
In the first case, title and episode name are correctly put in their respective
|
||||
places, and "TITLE - EPISODE" as file name will do. The second case is our common
|
||||
version, where everything is in the title, so TITLE is just fine. The third case
|
||||
poses a problem, because everything is in the title, but with a different separator.
|
||||
Here the special macro "{>}" can be used in the file name, which contains everything
|
||||
following the matching pattern. There are three macros that can be used here:
|
||||
|
||||
{<} everything before the matching pattern
|
||||
{>} everything after the matching pattern
|
||||
{=} the matching pattern itself (just for completeness)
|
||||
|
||||
As of VDR version 2.5.2, the characters ' ' (blank), ':' and '-' are ignored
|
||||
when checking whether a particular recording has already been made by a pattern
|
||||
timer, making "TITLE - EPISODE" and "TITLE: EPISODE" the same.
|
||||
VDR version 2.6.6 added '/' to this list.
|
||||
|
||||
* Managing folders
|
||||
|
||||
The "Select folder" menu, which can be accessed by pressing the "Red" key in
|
||||
@ -500,9 +657,42 @@ Version 2.0
|
||||
folder name in the list). The "Yellow" key deletes the current folder (note
|
||||
that this will merely delete the folder definition stored in 'folders.conf'
|
||||
and has no effect on existing timers or recordings). The "Blue" key can be
|
||||
used to edit an existing folder definition. The "Red" key selects the current
|
||||
folder, or enters a sub folder. Once a folder has been selected, the entire
|
||||
path of the timer's file name will be replaced with the selected folder.
|
||||
used to edit an existing folder definition. The "Red" key opens a folder that
|
||||
contains sub folders, while pressing Ok selects the current folder. Once a
|
||||
folder has been selected, the entire path of the timer's file name will be
|
||||
replaced with the selected folder.
|
||||
|
||||
In the "Recordings" menu the folders of existing recordings can be renamed or
|
||||
moved by pressing the "Blue" key ("Edit") while the cursor is positioned on
|
||||
a folder. This will open a menu in which the folder's name and location (the
|
||||
"parent" folder) can be edited. If such an operation will result in moving
|
||||
more than one recording, you will be asked for confirmation.
|
||||
The name, folder, priority and lifetime of an individual recording can be
|
||||
changed by pressing the "Blue" key ("Info") while the cursor is positioned
|
||||
on a recording, and in the resulting Info menu pressing the "Blue" key again
|
||||
to bring up the "Edit recording" menu.
|
||||
In the "Edit recording" menu the Red button ("Folder") allows you to select one
|
||||
of your predefined folders. The Green button has multiple functions, depending
|
||||
on what is currently going on with the recording. It can either stop or cancel
|
||||
a cut, move or copy operation. If the button reads "Stop..." it means that the
|
||||
respective operation is already happening, while "Cancel..." means that the
|
||||
operation is still pending execution. If no operation is currently happening
|
||||
and the recording has editing marks, the Button will read "Cut" and triggers
|
||||
cutting the recording (same as pressing '2' while replaying the recording).
|
||||
The Yellow button ("Delete marks") allows you to delete all editing marks from
|
||||
the selected recording (if there are any and the recording is not currently
|
||||
being cut). To directly edit the folder or name of the recording, position the
|
||||
cursor to the respective line and press the Right key to start editing (press
|
||||
Ok to confirm the edit, or Back to return to the previous value). If you want
|
||||
to remove the name of the recording and make the folder name the actual
|
||||
recording's name, you can position the cursor to the "Name:" field and press
|
||||
the '0' key. This will take the last element of the recording's folder path
|
||||
and make it the actual name of the recording. You can do this in turn until
|
||||
the recording is moved all the way up to the root of the video directory.
|
||||
Note that, in case you inadvertently pressed the '0' key, you can leave the
|
||||
"Edit recording" menu with the "Back" key and any changes you have made so far
|
||||
will not be applied. Once you are finished with editing the recording
|
||||
properties, press Ok to confirm the changes.
|
||||
|
||||
* Parameters in the "Setup" menu
|
||||
|
||||
@ -606,6 +796,18 @@ Version 2.0
|
||||
plain recordings. Set this option to "no" if you want folders
|
||||
to be interspersed with recordings when sorted alphabetically.
|
||||
|
||||
Default sort mode for recordings = by time
|
||||
Controls whether recordings are sorted by time or by name.
|
||||
If a particular sort mode has been selected for a folder by
|
||||
pressing '0', the default no longer applies to that folder.
|
||||
|
||||
Sorting direction for recordings = ascending
|
||||
When recordings are sorted "by time", they appear in ascending
|
||||
order (i.e. "oldest" to "newest"). If this parameter is set to
|
||||
"descending", they will be presented "newest" to "oldest.
|
||||
Note that in the latter case, if "Always sort folders first"
|
||||
is "yes", folders will appear in reverse alphabetical order.
|
||||
|
||||
Number keys for characters = yes
|
||||
Controls whether the number keys can be used to enter
|
||||
characters in a text input field. You may want to set this
|
||||
@ -627,6 +829,16 @@ Version 2.0
|
||||
A value of '0' completely turns off scanning on both single
|
||||
and multiple card systems.
|
||||
|
||||
EPG scan max. channel number = 0
|
||||
The EPG scan will only tune to transponders of channels with
|
||||
numbers below this limit. By default all transponders will
|
||||
be scanned.
|
||||
|
||||
EPG pause after scan = no
|
||||
After a complete scan of all transponders (optionally limited
|
||||
by "EPG scan max. channel number") the EPG scan pauses for
|
||||
"EPG scan timeout" hours if this option is set to "yes".
|
||||
|
||||
EPG bugfix level = 3 Some tv stations transmit weirdly formatted EPG data.
|
||||
VDR attempts to fix these bugs up to the given level:
|
||||
0 = no EPG fixing
|
||||
@ -704,15 +916,16 @@ Version 2.0
|
||||
Defines the standard compliance mode:
|
||||
0 = DVB
|
||||
1 = ANSI/SCTE
|
||||
2 = NORDIG
|
||||
|
||||
Video format = 4:3 The video format (or aspect ratio) of the tv set in use
|
||||
(4:3 or 16:9).
|
||||
(4:3 or 16:9). Applies only to SD output devices.
|
||||
|
||||
Video display format = letterbox
|
||||
The display format to use for playing wide screen video on
|
||||
a 4:3 tv set ("pan & scan", "letterbox" or "center cut out").
|
||||
This option is only available if "Video format" is set to
|
||||
4:3.
|
||||
4:3. Applies only to SD output devices.
|
||||
|
||||
Use Dolby Digital = yes
|
||||
Controls whether Dolby Digital tracks appear in the "Audio"
|
||||
@ -776,6 +989,28 @@ Version 2.0
|
||||
are connected to the same sat cable must be set to the same
|
||||
number here.
|
||||
|
||||
Use dish positioner = no
|
||||
By default, the 'P' command code in DiSEqC command sequences
|
||||
is ignored. Set this parameter to 'yes' if you are using a
|
||||
satellite dish positioner.
|
||||
|
||||
Site latitude (degrees) = 0
|
||||
Site longitude (degrees) = 0
|
||||
Set these to the latitude and longitude of your dish's
|
||||
location if you use a satellite dish positioner. Use the
|
||||
"Green" key to switch between north/south and east/west,
|
||||
respectively.
|
||||
|
||||
Max. positioner swing (degrees) = 65
|
||||
Defines the maximum angle by which the positioner can move
|
||||
the dish away from due south (or north) in either direction.
|
||||
The valid range is 0...90.
|
||||
|
||||
Positioner speed (degrees/s) = 1.5
|
||||
Defines the speed at which the positioner moves the dish.
|
||||
The valid range is 0.1...180. This value is used to calculate
|
||||
how long it takes the positioner to reach the target position.
|
||||
|
||||
CAM:
|
||||
|
||||
n CAM Name Shows the CAM slots that are present in this system, where
|
||||
@ -784,7 +1019,19 @@ Version 2.0
|
||||
if it is in the process of being reset, its current status
|
||||
is displayed. The "Red" key can be pressed to enter the CAM
|
||||
menu, and the "Green" key triggers a reset of the selected
|
||||
slot. The "Ok" key also opens the CAM menu.
|
||||
slot. The "Ok" key also opens the CAM menu. The "Yellow" key
|
||||
assigns the selected CAM to a device and switches it to the
|
||||
current channel. The CAM/device combination remains tuned to
|
||||
the current channel until the smart card in the CAM has been
|
||||
activated and thus starts to descramble, or until a recording
|
||||
needs this device. Pressing the "Yellow" key while a CAM is
|
||||
in activation mode cancels the activation. The activation mode
|
||||
remains in effect even if you switch to a different channel
|
||||
(provided there is more than one device in the system) or
|
||||
watch a recording. To activate your smart card simply switch
|
||||
to the channel you want to watch, open the "Setup/CAM" menu,
|
||||
select the CAM that contains the smart card (in case you
|
||||
have more than one CAM) and press the "Yellow" key.
|
||||
|
||||
Recording:
|
||||
|
||||
@ -793,14 +1040,22 @@ Version 2.0
|
||||
after the official end time it shall stop recording.
|
||||
These margins are added automatically to timers that
|
||||
are created from the EPG data.
|
||||
Note that the actual margins used may be smaller than the
|
||||
given values, if the event before and/or after the event
|
||||
to be recorded is shorter than the respective margin.
|
||||
|
||||
Default priority = 50 The default Priority and Lifetime values used when
|
||||
Default lifetime = 99 creating a new timer event. A Lifetime value of 99
|
||||
means that this recording will never be deleted
|
||||
automatically.
|
||||
|
||||
Pause priority = 10 The Priority and Lifetime values used when pausing live
|
||||
Pause lifetime = 1 video.
|
||||
Record key handling = 2
|
||||
Defines what happens if the Record key on the remote control
|
||||
is pressed during live tv.
|
||||
0 = no instant recording
|
||||
1 = confirm instant recording
|
||||
2 = record instantly
|
||||
The default is 2.
|
||||
|
||||
Pause key handling = 2 Defines what happens if the Pause key on the remote control
|
||||
is pressed during live tv.
|
||||
@ -809,6 +1064,9 @@ Version 2.0
|
||||
2 = pause live video
|
||||
The default is 2.
|
||||
|
||||
Pause priority = 10 The Priority and Lifetime values used when pausing live
|
||||
Pause lifetime = 1 video.
|
||||
|
||||
Use episode name = yes Repeating timers use the EPG's 'Episode name' information
|
||||
to create recording file names in a hierarchical structure
|
||||
(for instance to gather all episodes of a series in a
|
||||
@ -896,6 +1154,70 @@ Version 2.0
|
||||
Defines whether the player automatically goes into Pause
|
||||
mode when setting an editing mark.
|
||||
|
||||
Pause replay when jumping to a mark = yes
|
||||
By default replay is automatically paused whenever you jump
|
||||
to an editing mark with the '7' or '9' key in order to allow
|
||||
you to easily adjust those marks. If this option is set to
|
||||
'no', the '9' key will not pause if you are in Play mode and
|
||||
the mark you jump to is not within 3 seconds of the end of
|
||||
the recording.
|
||||
|
||||
Skip edited parts = no Defines whether the edited parts of a recording are
|
||||
automatically skipped during replay. This includes jumping
|
||||
to the first mark if replay starts at the beginning of the
|
||||
recording, and stopping at the last mark.
|
||||
|
||||
Pause replay at last mark = no
|
||||
If enabled, replay of a recording will go into Pause mode
|
||||
when it has reached the last "end" mark (if any). Note that
|
||||
the actual position at which the pause occurs may be a couple
|
||||
of frames before the last "end" mark, depending on how much
|
||||
data is buffered by your output device.
|
||||
|
||||
Initial duration for adaptive skipping (s) = 120
|
||||
Defines the number of seconds to jump from the current replay
|
||||
position in either direction, when pressing the '1' or '3'
|
||||
key for the first time after the "Reset timeout for adaptive
|
||||
skipping".
|
||||
The valid range is 10...600.
|
||||
|
||||
Reset timeout for adaptive skipping (s) = 3
|
||||
Defines the number of seconds after which pressing the
|
||||
'1' or '3' key falls back to the "Initial duration for adaptive
|
||||
skipping".
|
||||
The valid range is 0...10. Setting the timeout to 0 disables
|
||||
the adaptive mode and makes '1' and '3' always skip the number
|
||||
of seconds configured as the initial duration.
|
||||
|
||||
Alternate behavior for adaptive skipping = no
|
||||
When skipping in adaptive mode with the '1' and '3' keys, the
|
||||
distance of the skip is halved with every key press after the
|
||||
first change of direction. While this allows for locating a
|
||||
particular position in a recording very fast, once you make
|
||||
one step too many in the current direction you have no chance
|
||||
of ever reaching the desired point any more. You will have to
|
||||
wait for the timeout to occur and start adaptive skipping anew.
|
||||
If this option is set to 'yes', the skip distance will only be
|
||||
halved if the direction actually changes. That way, even if
|
||||
you missed the target point, you can still back up to it.
|
||||
|
||||
Use Prev/Next keys for adaptive skipping = no
|
||||
Normally the Prev/Next keys jump between editing marks (or
|
||||
the beginning/end of the recording). You can set this option
|
||||
to 'yes' if you want to use these keys for adaptive skipping
|
||||
instead.
|
||||
|
||||
Skip distance with Green/Yellow keys (s) = 60
|
||||
Defines the number of seconds to skip in either direction
|
||||
when pressing the "Green" or "Yellow" key, respectively.
|
||||
The valid range is 5...600.
|
||||
|
||||
Skip distance with Green/Yellow keys in repeat (s) = 60
|
||||
Defines the number of seconds to skip in either direction
|
||||
when pressing and holding the "Green" or "Yellow" key,
|
||||
respectively.
|
||||
The valid range is 5...600.
|
||||
|
||||
Resume ID = 0 Defines an additional ID that can be used in a multi user
|
||||
environment, so that every user has his/her own resume
|
||||
files for each recording. The valid range is 0...99, with
|
||||
@ -919,6 +1241,23 @@ Version 2.0
|
||||
connection after which the connection is automatically
|
||||
closed. Default is 300, a value of 0 means no timeout.
|
||||
|
||||
SVDRP peering = off Activates automatic connections between VDRs in the same
|
||||
network. If set to "any hosts" this VDR will establish
|
||||
connections with any available hosts. If set to "only
|
||||
default host" this VDR will only connect to the VDR with
|
||||
the name defined in "SVDRP default host". If no default
|
||||
host has been defined, the behavior is the same as with
|
||||
"any hosts". To switch from "off" to "only default host",
|
||||
you may need to select "any hosts" first and confirm the
|
||||
dialog by pressing "Ok" in order to be able to select a
|
||||
default host.
|
||||
|
||||
SVDRP host name The name of this VDR, which is used when connecting VDRs
|
||||
via SVDRP. By default, the machine's host name is used.
|
||||
|
||||
SVDRP default host The name of the VDR to be used by default when creating a
|
||||
new timer.
|
||||
|
||||
Zap timeout = 3 The time (in seconds) until a channel counts as "previous"
|
||||
for switching with '0'
|
||||
|
||||
@ -941,7 +1280,7 @@ Version 2.0
|
||||
The time (in milliseconds) between two subsequent key
|
||||
presses generated by the remote control's repeat function.
|
||||
If the remote control in use has a repeat delta that is
|
||||
longer than that given in this parameter, that longer delay
|
||||
longer than that given in this parameter, that longer delta
|
||||
will prevail.
|
||||
Initial channel = The channel ID of the channel that shall be tuned to when
|
||||
VDR starts. Default is empty, which means that it will
|
||||
@ -952,15 +1291,27 @@ Version 2.0
|
||||
VDR was stopped will be used. The valid range is from
|
||||
0 (silent) to 255 (loudest).
|
||||
|
||||
Volume steps = 51 The number of steps the volume will use when moving from
|
||||
the lowest to the highest value. The valid range is from
|
||||
5 to 255.
|
||||
|
||||
Volume linearize = 0 How to linearize the volume control. The valid range is
|
||||
from -20 to 20. A value of 0 results in no linearization.
|
||||
The higher this value is, the more fine grained the control
|
||||
of the volume is for low sound levels. Lower values do the
|
||||
same for high sound levels. This allows you to adjust the
|
||||
more or less linear volume control of your sound card.
|
||||
|
||||
Channels wrap = no During zapping with the "Up" and "Down" keys (or the
|
||||
"Channel+" and "Channel-" keys) the current channel will
|
||||
wrap around the beginning or end of the channel list if
|
||||
this parameter is set to 'yes'.
|
||||
|
||||
Show channel names with source = no
|
||||
Show channel names with source = off
|
||||
If this option is turned on, channel names will be displayed
|
||||
with the source appended to them, as in "ZDF (S)", where
|
||||
'S' stands for "Satellite".
|
||||
with the source appended to them, as in "ZDF (S)" (if the
|
||||
option is set to "type), or "ZDF (S19.2E)" (if it is set to
|
||||
"full"), where 'S' stands for "Satellite".
|
||||
|
||||
Emergency exit = yes If, for some reason, a recording fails because the video
|
||||
data stream is broken, or the CAM doesn't decrypt etc.,
|
||||
|
@ -6,7 +6,7 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Make.config.template 2.19 2013/02/18 10:55:39 kls Exp $
|
||||
# $Id: Make.config.template 5.2 2024/10/11 14:21:04 kls Exp $
|
||||
|
||||
### The C compiler and options:
|
||||
|
||||
@ -16,6 +16,12 @@ CFLAGS = -g -O3 -Wall
|
||||
CXX = g++
|
||||
CXXFLAGS = -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses
|
||||
|
||||
# Use 'make DEBUG=1 ...' to build a debug version of VDR and plugins:
|
||||
ifdef DEBUG
|
||||
CFLAGS += -O0
|
||||
CXXFLAGS += -O0
|
||||
endif
|
||||
|
||||
# Use 'make M32=1 ...' to build a 32-bit version of VDR on a 64-bit machine:
|
||||
ifdef M32
|
||||
CFLAGS += -m32
|
||||
@ -27,17 +33,19 @@ endif
|
||||
# Default directories (adjust as necessary or desired):
|
||||
|
||||
#PREFIX = /usr/local
|
||||
#BINDIR = $(PREFIX)/bin
|
||||
#INCDIR = $(PREFIX)/include
|
||||
#LIBDIR = $(PREFIX)/lib/vdr
|
||||
#LOCDIR = $(PREFIX)/share/locale
|
||||
#MANDIR = $(PREFIX)/share/man
|
||||
#PCDIR = $(PREFIX)/lib/pkgconfig
|
||||
#RESDIR = $(PREFIX)/share/vdr
|
||||
#DVBDIR = /usr/src/v4l-dvb/linux/include/uapi
|
||||
#VDRROOT = $(PREFIX)
|
||||
#BINDIR = $(VDRROOT)/bin
|
||||
#INCDIR = $(VDRROOT)/include
|
||||
#LIBDIR = $(VDRROOT)/lib
|
||||
#LOCDIR = $(VDRROOT)/locale
|
||||
#MANDIR = $(VDRROOT)/man
|
||||
#PCDIR = $(VDRROOT)/pkgconfig
|
||||
#RESDIR = $(VDRROOT)/share
|
||||
#DVBDIR = /usr/include
|
||||
|
||||
#VIDEODIR = /srv/vdr/video
|
||||
#CONFDIR = /var/lib/vdr
|
||||
#ARGSDIR = /etc/vdr/conf.d
|
||||
#CACHEDIR = /var/cache/vdr
|
||||
|
||||
# Overrides for preset/legacy configurations:
|
||||
@ -57,6 +65,7 @@ ifdef ONEDIR
|
||||
VIDEODIR = /video
|
||||
CACHEDIR = $(VIDEODIR)
|
||||
CONFDIR = $(VIDEODIR)
|
||||
ARGSDIR = $(VIDEODIR)/conf.d
|
||||
RESDIR = $(VIDEODIR)
|
||||
endif
|
||||
|
||||
@ -65,12 +74,25 @@ endif
|
||||
#PLGCFG = $(CONFDIR)/plugins.mk
|
||||
|
||||
### The remote control:
|
||||
|
||||
LIRC_DEVICE = /var/run/lirc/lircd
|
||||
### Use this for kernel based driver:
|
||||
#LIRC_DEVICE = /dev/lirc0
|
||||
|
||||
### Define if you always want to use LIRC, independent of the --lirc option:
|
||||
#REMOTE=LIRC
|
||||
|
||||
### Define if you don't want keyboard remote control:
|
||||
#NO_KBD = 1
|
||||
|
||||
### Define if you want vdr to not run as root:
|
||||
#VDR_USER = vdr
|
||||
|
||||
### Define if you want to compile in 'bidi' support:
|
||||
#BIDI = 1
|
||||
|
||||
### Define if you want 'systemd' notification:
|
||||
#SDNOTIFY = 1
|
||||
|
||||
### Fallback for plugins with old makefiles:
|
||||
ifdef PLUGIN
|
||||
CFLAGS += -fPIC
|
||||
|
110
Makefile
110
Makefile
@ -4,23 +4,26 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Makefile 2.54 2013/03/11 15:01:01 kls Exp $
|
||||
# $Id: Makefile 5.4 2024/10/21 19:01:16 kls Exp $
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# Compiler flags:
|
||||
|
||||
PKG_CONFIG ?= pkg-config
|
||||
|
||||
CC ?= gcc
|
||||
CFLAGS ?= -g -O3 -Wall
|
||||
|
||||
CXX ?= g++
|
||||
CXXFLAGS ?= -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses
|
||||
CXXFLAGS += $(CPPFLAGS)
|
||||
|
||||
CDEFINES = -D_GNU_SOURCE
|
||||
CDEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
|
||||
|
||||
LIBS = -ljpeg -lpthread -ldl -lcap -lrt $(shell pkg-config --libs freetype2 fontconfig)
|
||||
INCLUDES ?= $(shell pkg-config --cflags freetype2 fontconfig)
|
||||
LIBS = -ljpeg -lpthread -ldl -lcap -lrt $(shell $(PKG_CONFIG) --libs freetype2 fontconfig)
|
||||
INCLUDES ?= $(shell $(PKG_CONFIG) --cflags freetype2 fontconfig)
|
||||
|
||||
# Directories:
|
||||
|
||||
@ -28,19 +31,29 @@ CWD ?= $(shell pwd)
|
||||
LSIDIR ?= $(CWD)/libsi
|
||||
PLUGINDIR ?= $(CWD)/PLUGINS
|
||||
|
||||
# Failsafe defaults for "make LCLBLD=1":
|
||||
ifdef LCLBLD
|
||||
DESTDIR ?= $(CWD)
|
||||
LOCDIR ?= $(CWD)/locale
|
||||
HDRDIR ?= $(CWD)/include
|
||||
LIBDIR ?= $(PLUGINDIR)/lib
|
||||
endif
|
||||
|
||||
DESTDIR ?=
|
||||
VIDEODIR ?= /srv/vdr/video
|
||||
CONFDIR ?= /var/lib/vdr
|
||||
ARGSDIR ?= /etc/vdr/conf.d
|
||||
CACHEDIR ?= /var/cache/vdr
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
INCDIR ?= $(PREFIX)/include
|
||||
LIBDIR ?= $(PREFIX)/lib/vdr
|
||||
LOCDIR ?= $(PREFIX)/share/locale
|
||||
MANDIR ?= $(PREFIX)/share/man
|
||||
PCDIR ?= $(PREFIX)/lib/pkgconfig
|
||||
RESDIR ?= $(PREFIX)/share/vdr
|
||||
VDRROOT ?= $(PREFIX)
|
||||
BINDIR ?= $(VDRROOT)/bin
|
||||
INCDIR ?= $(VDRROOT)/include
|
||||
LIBDIR ?= $(VDRROOT)/lib/vdr
|
||||
LOCDIR ?= $(VDRROOT)/share/locale
|
||||
MANDIR ?= $(VDRROOT)/share/man
|
||||
PCDIR ?= $(VDRROOT)/lib/pkgconfig
|
||||
RESDIR ?= $(VDRROOT)/share/vdr
|
||||
|
||||
# Source documentation
|
||||
|
||||
@ -51,6 +64,15 @@ DOXYFILE = Doxyfile
|
||||
|
||||
-include Make.config
|
||||
|
||||
# Output control
|
||||
|
||||
ifdef VERBOSE
|
||||
Q =
|
||||
else
|
||||
Q = @
|
||||
endif
|
||||
export Q
|
||||
|
||||
# Mandatory compiler flags:
|
||||
|
||||
CFLAGS += -fPIC
|
||||
@ -66,9 +88,9 @@ endif
|
||||
|
||||
SILIB = $(LSIDIR)/libsi.a
|
||||
|
||||
OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\
|
||||
OBJS = args.o audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\
|
||||
dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
|
||||
lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o\
|
||||
lirc.o menu.o menuitems.o mtd.o nit.o osdbase.o osd.o pat.o player.o plugin.o positioner.o\
|
||||
receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\
|
||||
skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\
|
||||
timers.o tools.o transfer.o vdr.o videodir.o
|
||||
@ -89,9 +111,14 @@ ifdef VDR_USER
|
||||
DEFINES += -DVDR_USER=\"$(VDR_USER)\"
|
||||
endif
|
||||
ifdef BIDI
|
||||
INCLUDES += $(shell pkg-config --cflags fribidi)
|
||||
INCLUDES += $(shell $(PKG_CONFIG) --cflags fribidi)
|
||||
DEFINES += -DBIDI
|
||||
LIBS += $(shell pkg-config --libs fribidi)
|
||||
LIBS += $(shell $(PKG_CONFIG) --libs fribidi)
|
||||
endif
|
||||
ifdef SDNOTIFY
|
||||
INCLUDES += $(shell $(PKG_CONFIG) --silence-errors --cflags libsystemd-daemon || $(PKG_CONFIG) --cflags libsystemd)
|
||||
DEFINES += -DSDNOTIFY
|
||||
LIBS += $(shell $(PKG_CONFIG) --silence-errors --libs libsystemd-daemon || $(PKG_CONFIG) --libs libsystemd)
|
||||
endif
|
||||
|
||||
LIRC_DEVICE ?= /var/run/lirc/lircd
|
||||
@ -99,6 +126,7 @@ LIRC_DEVICE ?= /var/run/lirc/lircd
|
||||
DEFINES += -DLIRC_DEVICE=\"$(LIRC_DEVICE)\"
|
||||
DEFINES += -DVIDEODIR=\"$(VIDEODIR)\"
|
||||
DEFINES += -DCONFDIR=\"$(CONFDIR)\"
|
||||
DEFINES += -DARGSDIR=\"$(ARGSDIR)\"
|
||||
DEFINES += -DCACHEDIR=\"$(CACHEDIR)\"
|
||||
DEFINES += -DRESDIR=\"$(RESDIR)\"
|
||||
DEFINES += -DPLUGINDIR=\"$(LIBDIR)\"
|
||||
@ -114,7 +142,8 @@ all: vdr i18n plugins
|
||||
# Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
# Dependencies:
|
||||
|
||||
@ -128,21 +157,26 @@ $(DEPFILE): Makefile
|
||||
# The main program:
|
||||
|
||||
vdr: $(OBJS) $(SILIB)
|
||||
$(CXX) $(CXXFLAGS) -rdynamic $(LDFLAGS) $(OBJS) $(LIBS) $(SILIB) -o vdr
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -rdynamic $(LDFLAGS) $(OBJS) $(LIBS) $(SILIB) -o vdr
|
||||
|
||||
# The libsi library:
|
||||
|
||||
$(SILIB):
|
||||
$(MAKE) --no-print-directory -C $(LSIDIR) CXXFLAGS="$(CXXFLAGS)" DEFINES="$(CDEFINES)" all
|
||||
$(SILIB): make-libsi
|
||||
@$(MAKE) --no-print-directory -C $(LSIDIR) CXXFLAGS="$(CXXFLAGS)" DEFINES="$(CDEFINES)" all
|
||||
make-libsi: # empty rule makes sure the sub-make for libsi is always called
|
||||
|
||||
# pkg-config file:
|
||||
|
||||
.PHONY: vdr.pc
|
||||
vdr.pc:
|
||||
@echo "bindir=$(BINDIR)" > $@
|
||||
@echo "vdrrootdir=$(VDRROOT)" > $@
|
||||
@echo "bindir=$(BINDIR)" >> $@
|
||||
@echo "incdir=$(INCDIR)" >> $@
|
||||
@echo "mandir=$(MANDIR)" >> $@
|
||||
@echo "configdir=$(CONFDIR)" >> $@
|
||||
@echo "videodir=$(VIDEODIR)" >> $@
|
||||
@echo "configdir=$(CONFDIR)" >> $@
|
||||
@echo "argsdir=$(ARGSDIR)" >> $@
|
||||
@echo "cachedir=$(CACHEDIR)" >> $@
|
||||
@echo "resdir=$(RESDIR)" >> $@
|
||||
@echo "libdir=$(LIBDIR)" >> $@
|
||||
@ -154,7 +188,7 @@ vdr.pc:
|
||||
@echo "" >> $@
|
||||
@echo "Name: VDR" >> $@
|
||||
@echo "Description: Video Disk Recorder" >> $@
|
||||
@echo "URL: http://www.tvdr.de/" >> $@
|
||||
@echo "URL: https://www.tvdr.de/" >> $@
|
||||
@echo "Version: $(VDRVERSION)" >> $@
|
||||
@echo "Cflags: \$${cflags}" >> $@
|
||||
|
||||
@ -168,17 +202,21 @@ I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr.mo, $(notdir
|
||||
I18Npot = $(PODIR)/vdr.pot
|
||||
|
||||
%.mo: %.po
|
||||
msgfmt -c -o $@ $<
|
||||
@echo MO $@
|
||||
$(Q)msgfmt -c -o $@ $<
|
||||
|
||||
$(I18Npot): $(wildcard *.c)
|
||||
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ `ls $^`
|
||||
@echo GT $@
|
||||
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=VDR --package-version=$(VDRVERSION) --msgid-bugs-address='<vdr-bugs@tvdr.de>' -o $@ `ls $^`
|
||||
|
||||
%.po: $(I18Npot)
|
||||
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@echo PO $@
|
||||
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@touch $@
|
||||
|
||||
$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr.mo: $(PODIR)/%.mo
|
||||
install -D -m644 $< $@
|
||||
@echo IN $@
|
||||
$(Q)install -D -m644 $< $@
|
||||
|
||||
.PHONY: i18n
|
||||
i18n: $(I18Nmsgs)
|
||||
@ -220,7 +258,7 @@ plugins: include-dir vdr.pc
|
||||
INCLUDES="-I$(CWD)/include"\
|
||||
$(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR="$(CWD)" || failed="$$failed $$i";\
|
||||
if [ -n "$(LCLBLD)" ] ; then\
|
||||
(cd $(PLUGINDIR)/src/$$i; for l in `find -name 'libvdr-*.so' -o -name 'lib$$i-*.so'`; do install $$l $(LIBDIR)/`basename $$l`.$(APIVERSION); done);\
|
||||
(cd $(PLUGINDIR)/src/$$i; for l in `find -name "libvdr-*.so" -o -name "lib$$i-*.so"`; do install -D $$l $(LIBDIR)/`basename $$l`.$(APIVERSION); done);\
|
||||
if [ -d $(PLUGINDIR)/src/$$i/po ]; then\
|
||||
for l in `ls $(PLUGINDIR)/src/$$i/po/*.mo`; do\
|
||||
install -D -m644 $$l $(LOCDIR)/`basename $$l | cut -d. -f1`/LC_MESSAGES/vdr-$$i.mo;\
|
||||
@ -241,13 +279,13 @@ plugins: include-dir vdr.pc
|
||||
fi;\
|
||||
if [ -n "$$failed" ] ; then echo; echo "*** failed plugins:$$failed"; echo; exit 1; fi
|
||||
|
||||
clean-plugins:
|
||||
@for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do $(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" clean; done
|
||||
clean-plugins: vdr.pc
|
||||
@for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do $(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR="$(CWD)" clean; done
|
||||
@-rm -f $(PLUGINDIR)/lib/lib*-*.so.$(APIVERSION)
|
||||
|
||||
# Install the files (note that 'install-pc' must be first!):
|
||||
|
||||
install: install-pc install-bin install-dirs install-conf install-doc install-plugins install-i18n install-includes
|
||||
install: install-pc install-bin install-conf install-doc install-plugins install-i18n install-includes
|
||||
|
||||
# VDR binary:
|
||||
|
||||
@ -260,11 +298,17 @@ install-bin: vdr
|
||||
install-dirs:
|
||||
@mkdir -p $(DESTDIR)$(VIDEODIR)
|
||||
@mkdir -p $(DESTDIR)$(CONFDIR)
|
||||
@mkdir -p $(DESTDIR)$(ARGSDIR)
|
||||
@mkdir -p $(DESTDIR)$(CACHEDIR)
|
||||
@mkdir -p $(DESTDIR)$(RESDIR)
|
||||
|
||||
install-conf:
|
||||
@cp -pn *.conf $(DESTDIR)$(CONFDIR)
|
||||
install-conf: install-dirs
|
||||
# 'cp -n' may be broken, so let's do it the hard way
|
||||
@for i in *.conf; do\
|
||||
if ! [ -e $(DESTDIR)$(CONFDIR)/$$i ] ; then\
|
||||
cp -p $$i $(DESTDIR)$(CONFDIR);\
|
||||
fi\
|
||||
done
|
||||
|
||||
# Documentation:
|
||||
|
||||
@ -279,6 +323,7 @@ install-doc:
|
||||
|
||||
install-plugins: plugins
|
||||
@-for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do\
|
||||
echo; echo "*** Plugin $$i:";\
|
||||
$(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR=$(CWD) DESTDIR=$(DESTDIR) install;\
|
||||
done
|
||||
@if [ -d $(PLUGINDIR)/lib ] ; then\
|
||||
@ -306,6 +351,7 @@ install-pc: vdr.pc
|
||||
srcdoc:
|
||||
@cat $(DOXYFILE) > $(DOXYFILE).tmp
|
||||
@echo PROJECT_NUMBER = $(VDRVERSION) >> $(DOXYFILE).tmp
|
||||
@chmod +x $(DOXYFILE).filter
|
||||
$(DOXYGEN) $(DOXYFILE).tmp
|
||||
@rm $(DOXYFILE).tmp
|
||||
|
||||
@ -314,7 +360,7 @@ srcdoc:
|
||||
clean:
|
||||
@$(MAKE) --no-print-directory -C $(LSIDIR) clean
|
||||
@-rm -f $(OBJS) $(DEPFILE) vdr vdr.pc core* *~
|
||||
@-rm -rf $(LOCALEDIR) $(PODIR)/*.mo $(PODIR)/*.pot
|
||||
@-rm -rf $(LOCALEDIR) $(PODIR)/*~ $(PODIR)/*.mo $(PODIR)/*.pot
|
||||
@-rm -rf include
|
||||
@-rm -rf srcdoc
|
||||
CLEAN: clean
|
||||
|
295
PLUGINS.html
295
PLUGINS.html
@ -31,14 +31,11 @@ modified {
|
||||
<div class="center">
|
||||
<h1>The VDR Plugin System</h1>
|
||||
|
||||
<b>Version 2.0</b>
|
||||
<b>Version 2.7</b>
|
||||
<p>
|
||||
Copyright © 2013 Klaus Schmidinger<br>
|
||||
Copyright © 2021 Klaus Schmidinger<br>
|
||||
<a href="mailto:vdr@tvdr.de">vdr@tvdr.de</a><br>
|
||||
<a href="http://www.tvdr.de">www.tvdr.de</a>
|
||||
</div>
|
||||
<div class="center">
|
||||
<modified>Important modifications introduced since version 1.6 are marked like this.</modified>
|
||||
<a href="https://www.tvdr.de">www.tvdr.de</a>
|
||||
</div>
|
||||
<p>
|
||||
VDR provides an easy to use plugin interface that allows additional functionality
|
||||
@ -77,15 +74,15 @@ structures and allows it to hook itself into specific areas to perform special a
|
||||
<li><a href="#Main menu entry">Main menu entry</a>
|
||||
<li><a href="#User interaction">User interaction</a>
|
||||
<li><a href="#Housekeeping">Housekeeping</a>
|
||||
<li><a href="#Main thread hook">Main thread hook</a>
|
||||
<li><a href="#Activity">Activity</a>
|
||||
<li><a href="#Wakeup">Wakeup</a>
|
||||
<li><a href="#Setup parameters">Setup parameters</a>
|
||||
<li><a href="#The Setup menu">The Setup menu</a>
|
||||
<li><modified><a href="#Additional files">Additional files</modified></a>
|
||||
<li><a href="#Additional files">Additional files</a>
|
||||
<li><a href="#Internationalization">Internationalization</a>
|
||||
<li><a href="#Custom services">Custom services</a>
|
||||
<li><a href="#SVDRP commands">SVDRP commands</a>
|
||||
<li><a href="#Locking">Locking</a>
|
||||
<li><a href="#Loading plugins into VDR">Loading plugins into VDR</a>
|
||||
<li><a href="#Building the distribution package">Building the distribution package</a>
|
||||
</ul>
|
||||
@ -99,10 +96,12 @@ structures and allows it to hook itself into specific areas to perform special a
|
||||
<li><a href="#Skins">Skins</a>
|
||||
<li><a href="#Themes">Themes</a>
|
||||
<li><a href="#Devices">Devices</a>
|
||||
<li><a href="#Positioners">Positioners</a>
|
||||
<li><a href="#Audio">Audio</a>
|
||||
<li><a href="#Remote Control">Remote Control</a>
|
||||
<li><a href="#Conditional Access">Conditional Access</a>
|
||||
<li><modified><a href="#Electronic Program Guide">Electronic Program Guide</modified></a>
|
||||
<li><a href="#Electronic Program Guide">Electronic Program Guide</a>
|
||||
<li><a href="#The video directory">The video directory</a>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
@ -166,28 +165,26 @@ is used:
|
||||
VDR/PLUGINS/src
|
||||
VDR/PLUGINS/src/hello
|
||||
VDR/PLUGINS/lib
|
||||
VDR/PLUGINS/lib/libvdr-hello.so.1.1.0
|
||||
VDR/PLUGINS/lib/libvdr-hello.so.1
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
The <tt>src</tt> directory contains one subdirectory for each plugin, which carries
|
||||
the name of that plugin (in the above example that would be <tt>hello</tt>).
|
||||
What's inside the individual source directory of a
|
||||
plugin is entirely up to the author of that plugin. The only prerequisites are
|
||||
that there is a <tt>Makefile</tt> that provides the targets <tt>all</tt><modified>, <tt>install</tt></modified> and
|
||||
that there is a <tt>Makefile</tt> that provides the targets <tt>all</tt>, <tt>install</tt> and
|
||||
<tt>clean</tt>, and that a call to <tt>make all</tt> actually produces a dynamically
|
||||
loadable library file for that plugin (we'll get to the details later).
|
||||
<modified>
|
||||
The dynamically loadable library file for the plugin shall be located directly under
|
||||
the plugin's source directory.
|
||||
See the section <a href="#Initializing a new plugin directory">Initializing a new plugin directory</a>
|
||||
for how to generate an example Makefile.
|
||||
</modified>
|
||||
<p>
|
||||
The <tt>lib</tt> directory contains the dynamically loadable libraries of all
|
||||
available plugins. Note that the names of these files are created by concatenating
|
||||
<p>
|
||||
<table border=2>
|
||||
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1.1.0</tt></b></td></tr>
|
||||
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1</tt></b></td></tr>
|
||||
<tr><td align=center><small>VDR plugin<br>library prefix</small></td><td align=center><small>name of<br>the plugin</small></td><td align=center><small>shared object<br>indicator</small></td><td align=center><small>API version number<br>this plugin was<br>compiled for</small></td></tr>
|
||||
</table>
|
||||
<p>
|
||||
@ -198,6 +195,11 @@ the current VDR version. That way minor fixes to VDR, that don't require changes
|
||||
to the VDR header files, can be made without requiring all plugins to be
|
||||
recompiled.
|
||||
<p>
|
||||
While in earlier versions of VDR the API version number was closely related to the
|
||||
VDR version number, starting with VDR version 2.7.2 the API version number was changed
|
||||
from a dot separated, three part number to a single integer, completely unrelated to
|
||||
the VDR version. This was done to avoid confusion.
|
||||
<p>
|
||||
The plugin library files can be stored in any directory. If the default organization
|
||||
is not used, the path to the plugin directory has be be given to VDR through the
|
||||
<b><tt>-L</tt></b> option.
|
||||
@ -393,13 +395,7 @@ just like shown in the above example. This is a convention that allows the <tt>M
|
||||
to extract the version number when generating the file name for the distribution archive.
|
||||
<p>
|
||||
A new plugin project should start with version number <tt>0.0.1</tt> and should reach
|
||||
version <tt>1.0.0</tt> once it is completely operative and well tested. Following the
|
||||
Linux kernel version numbering scheme, versions with <i>even</i> release numbers
|
||||
(like <tt>1.0.x</tt>, <tt>1.2.x</tt>, <tt>1.4.x</tt>...) should be stable releases,
|
||||
while those with <i>odd</i> release numbers (like <tt>1.1.x</tt>, <tt>1.3.x</tt>,
|
||||
<tt>1.5.x</tt>...) are usually considered "under development". The three parts of
|
||||
a version number are not limited to single digits, so a version number of <tt>1.2.15</tt>
|
||||
would be acceptable.
|
||||
version <tt>1.0.0</tt> once it is completely operative and well tested.
|
||||
|
||||
<hr><h2><a name="Description">Description</a></h2>
|
||||
|
||||
@ -583,6 +579,31 @@ esyslog("pluginname: error #%d has occurred", ErrorNumber);
|
||||
|
||||
Note that the log messages will be given as provided, the plugin's name will not
|
||||
automatically be added, so make sure your log messages are obvious enough.
|
||||
<p>
|
||||
Only use the above logging functions for occasional log messages. Do not use
|
||||
them unconditionally for frequent messages that produce long sequences of lines
|
||||
in the log file every few seconds. That might make it hard to work on other plugins
|
||||
or the core VDR code, watching their log entries while they are permanently
|
||||
interspersed with unrelated stuff.<br>
|
||||
<br>
|
||||
The recommended behavior for a plugin that does logging is to implement a command
|
||||
line option that controls the level of log messages, preferably '-l N, --log=N',
|
||||
where 'N' is in the range 0...3, with 0 meaning no logging whatsoever, 1 log only
|
||||
errors, 2 log errors and informational messages, and 3 also log debug information.<br>
|
||||
<br>
|
||||
If a plugin can output extensive data for special debugging purposes (either to
|
||||
the log file or stdout/stderr), this should be enabled by setting proper switches
|
||||
in one of its source files (see for example how the communication between VDR and
|
||||
CAMs can be monitored in VDR/ci.c).<br>
|
||||
<br>
|
||||
Under no circumstances must a plugin print anything to stdout or stderr during
|
||||
normal operation! The only exceptions being special debug information as described
|
||||
above, fatal error messages that will cause VDR to abort, or if it is the sole
|
||||
purpose of the plugin to display something on stdout, like for instance the
|
||||
<i>skincurses</i> plugin, which displays the OSD at the console.<br>
|
||||
<br>
|
||||
Please make any log messages in <b>ENGLISH</b>! Logs are usually sent to the developers
|
||||
of a program, and they may not be able to read them if they are in an exotic language.
|
||||
|
||||
<hr><h2><a name="Main menu entry">Main menu entry</a></h2>
|
||||
|
||||
@ -670,27 +691,6 @@ interaction is possible. If a specific action takes longer than a few seconds,
|
||||
the plugin should launch a separate thread to do this.
|
||||
</b>
|
||||
|
||||
<hr><h2><a name="Main thread hook">Main thread hook</a></h2>
|
||||
|
||||
<div class="blurb">Pushing in...</div><p>
|
||||
|
||||
Normally a plugin only reacts on user input if directly called through its
|
||||
<a href="#Main menu entry">main menu entry</a>, or performs some background
|
||||
activity in a separate thread. However, sometimes a plugin may need to do
|
||||
something in the context of the main program thread, without being explicitly
|
||||
called up by the user. In such a case it can implement the function
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
virtual void MainThreadHook(void);
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
in which it can do this. This function is called for every plugin once during
|
||||
every cycle of VDR's main program loop, which typically happens once every
|
||||
second.
|
||||
<b>Be very careful when using this function, and make sure you return from it
|
||||
as soon as possible! If you spend too much time in this function, the user
|
||||
interface performance will become sluggish!</b>
|
||||
|
||||
<hr><h2><a name="Activity">Activity</a></h2>
|
||||
|
||||
<div class="blurb">Now is not a good time!</div><p>
|
||||
@ -891,70 +891,51 @@ You can first assign the temporary values to the global variables and then do th
|
||||
your setup parameters and use that one to copy all parameters with one single statement
|
||||
(like VDR does with its cSetup class).
|
||||
|
||||
<hr><h2><modified><a name="Additional files">Additional files</a></modified></h2>
|
||||
<hr><h2><a name="Additional files">Additional files</a></h2>
|
||||
|
||||
<div class="blurb">I want my own stuff!</div><p>
|
||||
|
||||
<modified>
|
||||
There may be situations where a plugin requires files of its own. While the plugin is
|
||||
free to store such files anywhere it sees fit, it might be a good idea to put them in a common
|
||||
place, preferably where such data already exists.
|
||||
</modified>
|
||||
<p>
|
||||
<modified>
|
||||
<i>configuration files</i>, maybe for data that can't be stored in the simple
|
||||
<a href="#Setup parameters">setup parameters</a> of VDR, or maybe because it needs to
|
||||
launch other programs that simply need a separate configuration file.
|
||||
</modified>
|
||||
<p>
|
||||
<modified>
|
||||
<i>cache files</i>, to store data so that future requests for that data can be served faster. The data
|
||||
that is stored within a cache might be values that have been computed earlier or duplicates of
|
||||
original values that are stored elsewhere.
|
||||
</modified>
|
||||
<p>
|
||||
<modified>
|
||||
<i>resource files</i>, for providing additional files, like pictures, movie clips or channel logos.
|
||||
</modified>
|
||||
<p>
|
||||
<modified>
|
||||
Therefore VDR provides the functions
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
<modified>
|
||||
const char *ConfigDirectory(const char *PluginName = NULL);
|
||||
const char *CacheDirectory(const char *PluginName = NULL);
|
||||
const char *ResourceDirectory(const char *PluginName = NULL);
|
||||
</modified>
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
<modified>
|
||||
each of which returns a string containing the directory that VDR uses for its own
|
||||
files (defined through the options in the call to VDR), extended by
|
||||
</modified>
|
||||
<tt>"/plugins"</tt>. So assuming the VDR configuration directory is <tt>/video</tt>
|
||||
(the default if no <tt><b>-c</b></tt> or <tt><b>-v</b></tt> option is given),
|
||||
a call to <tt>ConfigDirectory()</tt> will return <tt>/video/plugins</tt>. The first
|
||||
call to <tt>ConfigDirectory()</tt> will automatically make sure that the <tt>plugins</tt>
|
||||
subdirectory will exist. If, for some reason, this cannot be achieved, <tt>NULL</tt>
|
||||
will be returned.
|
||||
<modified>
|
||||
The behavior of <tt>CacheDirectory()</tt> and <tt>ResourceDirectory()</tt> is similar.
|
||||
</modified>
|
||||
<p>
|
||||
The additional <tt>plugins</tt> directory is used to keep files from plugins apart
|
||||
from those of VDR itself, making sure there will be no name clashes. If a plugin
|
||||
<modified>
|
||||
needs only one extra file, it is suggested that this file be named <tt>name.*</tt>,
|
||||
where <i>name</i> shall be the name of the plugin.
|
||||
</modified>
|
||||
<p>
|
||||
If a plugin needs more than one such file, it is suggested that the plugin stores
|
||||
these in a subdirectory of its own, named after the plugin. To easily get such a name
|
||||
<modified>
|
||||
the functions can be given an additional string that will be appended to the returned
|
||||
directory name, as in
|
||||
</modified>
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
const char *MyConfigDir = ConfigDirectory(Name());
|
||||
@ -965,16 +946,12 @@ plugin's name. Again, VDR will make sure that the requested directory will exist
|
||||
(or return <tt>NULL</tt> in case of an error).
|
||||
<p>
|
||||
<b>
|
||||
<modified>
|
||||
The returned strings are statically allocated and will be overwritten by subsequent calls!
|
||||
</modified>
|
||||
</b>
|
||||
<p>
|
||||
<modified>
|
||||
The <tt>ConfigDirectory()</tt>, <tt>CacheDirectory()</tt> and <tt>ResourceDirectory()</tt>
|
||||
functions are static member functions of the <tt>cPlugin</tt> class. This allows them to be
|
||||
called even from outside any member function of the derived plugin class, by writing
|
||||
</modified>
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
const char *MyConfigDir = cPlugin::ConfigDirectory();
|
||||
@ -1184,6 +1161,60 @@ The returned string may consist of several lines, separated by the newline chara
|
||||
('<tt>\n</tt>'). Each of these lines will be preceded with the <tt>ReplyCode</tt>
|
||||
when presenting them to the caller, and the continuation character ('<tt>-</tt>')
|
||||
will be set for all but the last one.
|
||||
<p>
|
||||
<b>The SVDRP functions are called from the separate "SVDRP server handler" thread.
|
||||
Therefore the plugin needs to take care of proper <a href="#Locking">locking</a> if it accesses any
|
||||
global data.</b>
|
||||
|
||||
<hr><h2><a name="Locking">Locking</a></h2>
|
||||
|
||||
<div class="blurb">U can't touch this</div><p>
|
||||
|
||||
When accessing global data structures, proper locking is absolutely necessary.
|
||||
<p>
|
||||
There are several macros that allow for easy locking and unlocking. They all
|
||||
follow the naming convention <tt>LOCK_*_READ|WRITE</tt>, where <tt>'*'</tt> is the name
|
||||
of the global data structure, which can be one of <tt>TIMERS</tt>, <tt>CHANNELS</tt>,
|
||||
<tt>RECORDINGS</tt> or <tt>SCHEDULES</tt>. To implicitly avoid deadlocks in case you
|
||||
need to lock more than one structure, always make sure you use these macros in
|
||||
this sequence!
|
||||
<p>
|
||||
Using one of these macros sets a lock on the structure, creates a local pointer to the
|
||||
respective structure and makes sure the lock is released at the end of the current
|
||||
block:
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
if (some condition) {
|
||||
LOCK_TIMERS_READ; // creates local const cTimers *Timers
|
||||
for (const cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) {
|
||||
// do something with Timer
|
||||
}
|
||||
}
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
Note the naming convention: TIMERS -> Timers etc.
|
||||
<p>
|
||||
The <tt>LOCK_*_READ</tt> macros create pointers that are '<tt>const</tt>', while
|
||||
the <tt>LOCK_*_WRITE</tt> macros allow modifications to the data structures.
|
||||
Both wait indefinitely to obtain the lock. However, if <tt>LOCK_*_WRITE</tt> is
|
||||
used twice in the same block, the second call will not obtain a lock and
|
||||
immediately return <tt>NULL</tt>, which may lead to a crash. In such cases a
|
||||
warning and backtrace is logged.
|
||||
<p>
|
||||
You may keep pointers to objects in such lists, even after releasing
|
||||
the lock. However, you may only access such objects if you are
|
||||
holding a proper lock again. If an object has been deleted from the list
|
||||
while you did not hold a lock (for instance by an other thread), the
|
||||
object will still be there, but no longer within this list (it is then
|
||||
stored in the ListGarbageCollector for a few seconds). That way even if you
|
||||
access the object after it has been deleted, you won't cause a segfault.
|
||||
You can call the Contains() function to check whether an object you are
|
||||
holding a pointer to is still in the list. Note that the garbage collector
|
||||
is purged when the usual housekeeping is done.
|
||||
<p>
|
||||
See tools.h, class <tt>cListBase</tt> for more documentation and information on how
|
||||
to use locking with timeouts, and thread.h, classes <tt>cStateLock</tt> and
|
||||
<tt>cStateKey</tt> on how to easily react to changes in such lists.
|
||||
|
||||
<hr><h2><a name="Loading plugins into VDR">Loading plugins into VDR</a></h2>
|
||||
|
||||
@ -1265,10 +1296,10 @@ If a plugin wants to get informed on various events in VDR, it can derive a clas
|
||||
|
||||
class cMyStatusMonitor : public cStatus {
|
||||
protected:
|
||||
virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber<modified>, bool LiveView</modified>);
|
||||
virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView);
|
||||
};
|
||||
|
||||
void cMyStatusMonitor::ChannelSwitch(const cDevice *Device, int ChannelNumber<modified>, bool LiveView</modified>)
|
||||
void cMyStatusMonitor::ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView)
|
||||
{
|
||||
if (ChannelNumber)
|
||||
dsyslog("channel switched to %d on DVB %d", ChannelNumber, Device->CardIndex());
|
||||
@ -1525,13 +1556,11 @@ public:
|
||||
cMyReceiver(int Pid);
|
||||
};
|
||||
|
||||
<modified>
|
||||
cMyReceiver::cMyReceiver(int Pid)
|
||||
:cReceiver(NULL, -1)
|
||||
{
|
||||
AddPid(Pid);
|
||||
}
|
||||
</modified>
|
||||
|
||||
cMyReceiver::~cMyReceiver()
|
||||
{
|
||||
@ -1557,7 +1586,7 @@ The above example sets up a receiver that wants to receive data from only one
|
||||
PID (for example the Teletext PID). In order to not interfere with other recording
|
||||
operations, it sets its priority to <tt>-1</tt> (any negative value will allow
|
||||
a <tt>cReceiver</tt> to be detached from its <tt>cDevice</tt> at any time
|
||||
<modified>in favor of a timer recording or live viewing</modified>).
|
||||
in favor of a timer recording or live viewing).
|
||||
<p>
|
||||
Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
|
||||
a <tt>cDevice</tt>:
|
||||
@ -1573,9 +1602,7 @@ the receiver is attached to the device that actually receives the current live
|
||||
video stream (this may be different from the primary device in case of <i>Transfer
|
||||
Mode</i>).
|
||||
<p>
|
||||
<modified>
|
||||
The <tt>cReceiver</tt> must be detached from its device before it is deleted.
|
||||
</modified>
|
||||
|
||||
<hr><h2><a name="Filters">Filters</a></h2>
|
||||
|
||||
@ -1704,7 +1731,7 @@ restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuA
|
||||
function, or any of the skin classes a plugin might implement.
|
||||
<p>
|
||||
If a plugin runs a separate thread and wants to issue a message directly from
|
||||
within that tread, it can call
|
||||
within that thread, it can call
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0);
|
||||
@ -1853,7 +1880,7 @@ If the new device can receive, it most likely needs to provide a way of
|
||||
selecting which channel it shall tune to:
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
<modified>virtual int NumProvidedSystems(void) const;</modified>
|
||||
virtual int NumProvidedSystems(void) const;
|
||||
virtual bool ProvidesSource(int Source) const;
|
||||
virtual bool ProvidesTransponder(const cChannel *Channel) const;
|
||||
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
|
||||
@ -1902,9 +1929,9 @@ virtual bool HasDecoder(void) const;
|
||||
virtual bool CanReplay(void) const;
|
||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||
virtual int64_t GetSTC(void);
|
||||
<modified>virtual bool IsPlayingVideo(void) const;</modified>
|
||||
virtual bool IsPlayingVideo(void) const;
|
||||
virtual bool HasIBPTrickSpeed(void);
|
||||
virtual void TrickSpeed(int Speed);
|
||||
virtual void TrickSpeed(int Speed, bool Forward);
|
||||
virtual void Clear(void);
|
||||
virtual void Play(void);
|
||||
virtual void Freeze(void);
|
||||
@ -1931,7 +1958,7 @@ the functions
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
|
||||
<modified>virtual int ReadFilter(int Handle, void *Buffer, size_t Length);</modified>
|
||||
virtual int ReadFilter(int Handle, void *Buffer, size_t Length);
|
||||
virtual void CloseFilter(int Handle);
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
@ -1987,7 +2014,6 @@ user - whether this goes through OSD facilities of the physical device (like
|
||||
a "full featured" DVB card) or through a graphics adapter that overlays its
|
||||
output with the video signal, doesn't matter.
|
||||
<p>
|
||||
<div class="modified">
|
||||
In order to be able to determine the proper size of the OSD, the device
|
||||
should implement the function
|
||||
|
||||
@ -1996,7 +2022,6 @@ virtual void GetOsdSize(int &Width, int &Height, double &Aspect);
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
By default, an OSD size of 720x480 with an aspect ratio of 1.0 is assumed.
|
||||
</div modified>
|
||||
|
||||
<p>
|
||||
<b>Initializing new devices</b>
|
||||
@ -2017,14 +2042,13 @@ Nothing needs to be done to shut down the devices. VDR will automatically
|
||||
shut down (delete) all devices when the program terminates. It is therefore
|
||||
important that the devices are created on the heap, using the <tt>new</tt>
|
||||
operator!
|
||||
|
||||
<div class="modified">
|
||||
<p>
|
||||
<b>Device hooks</b>
|
||||
<p>
|
||||
VDR has builtin facilities that select which device is able to provide a given
|
||||
transponder. However, there may be situations where the setup is so special
|
||||
that it requires considerations that exceed the scope of the core VDR code.
|
||||
transponder, or, which device may provide EIT data. However, there may be
|
||||
situations where the setup is so special that it requires considerations that
|
||||
exceed the scope of the core VDR code.
|
||||
This is where <i>device hooks</i> can be used.
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
@ -2032,6 +2056,7 @@ class cMyDeviceHook : public cDeviceHook {
|
||||
public:
|
||||
cMyDeviceHook(void);
|
||||
virtual bool DeviceProvidesTransponder(const cDevice *Device, const cChannel *Channel) const;
|
||||
virtual bool DeviceProvidesEIT(const cDevice *Device) const;
|
||||
};
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
@ -2048,6 +2073,19 @@ bool cMyDeviceHook::DeviceProvidesTransponder(const cDevice *Device, const cChan
|
||||
}
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
In its <tt>DeviceProvidesEIT()</tt> function the device hook can take
|
||||
whatever actions are necessary to determine whether the given Device can
|
||||
provide EIT data, as in
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
bool cMyDeviceHook::DeviceProvidesEIT(const cDevice *Device) const
|
||||
{
|
||||
if (<i>condition where Device can't provide EIT data</i>)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
A plugin that creates a derived cDeviceHook shall do so in its <tt>Initialize()</tt>
|
||||
function, as in
|
||||
|
||||
@ -2056,7 +2094,56 @@ new cMyDeviceHook;
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
and shall not delete this object. It will be automatically deleted when the program ends.
|
||||
</div modified>
|
||||
<p>
|
||||
<b>Power management</b>
|
||||
<p>
|
||||
A device that can be put into a power save mode can implement the function
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
virtual void SetPowerSaveMode(bool On);
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
If On is true, power save mode shall be activated, if it is false,
|
||||
normal operating mode shall be restored.
|
||||
|
||||
<hr><h2><a name="Positioners">Positioners</a></h2>
|
||||
|
||||
<div class="blurb">Now you see me - now you don't!</div><p>
|
||||
|
||||
If you are using a positioner (also known as "motor" or "rotor") to move your
|
||||
satellite dish to receive various satellites, you will be using the 'P' command
|
||||
in the <tt>diseqc.conf</tt> file. This command sends the necessary data to the
|
||||
positioner to move the dish to the satellite's orbital position. By default VDR
|
||||
uses its builtin DiSEqC positioner control. If your positioner requires a different
|
||||
method of controlling (like maybe via a serial link), you can derive a class
|
||||
from <tt>cPositioner</tt>, as in
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
#include <vdr/positioner.h>
|
||||
|
||||
class cMyPositioner : public cPositioner {
|
||||
public:
|
||||
cMyPositioner(void);
|
||||
virtual void Drive(ePositionerDirection Direction);
|
||||
virtual void Step(ePositionerDirection Direction, uint Steps = 1);
|
||||
virtual void Halt(void);
|
||||
virtual void SetLimit(ePositionerDirection Direction);
|
||||
virtual void DisableLimits(void);
|
||||
virtual void EnableLimits(void);
|
||||
virtual void StorePosition(uint Number);
|
||||
virtual void RecalcPositions(uint Number);
|
||||
virtual void GotoPosition(uint Number, int Longitude);
|
||||
virtual void GotoAngle(int Longitude);
|
||||
};
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
See the implementation of <tt>cDiseqcPositioner</tt> in <tt>diseqc.c</tt> for details.
|
||||
<p>
|
||||
You should create your derived positioner object in the
|
||||
<a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
|
||||
Note that the object has to be created on the heap (using <tt>new</tt>),
|
||||
and you shall not delete it at any point (it will be deleted automatically
|
||||
when the program ends).
|
||||
|
||||
<hr><h2><a name="Audio">Audio</a></h2>
|
||||
|
||||
@ -2222,12 +2309,10 @@ Put(uint64 Code, bool Repeat = false, bool Release = false);
|
||||
|
||||
The other parameters have the same meaning as in the first version of this function.
|
||||
<p>
|
||||
<modified>
|
||||
If your remote control has a repeat function that automatically repeats key events
|
||||
if a key is held pressed down for a while, your derived class should use the global
|
||||
parameters <tt>Setup.RcRepeatDelay</tt> and <tt>Setup.RcRepeatDelta</tt> to allow
|
||||
users to configure the behavior of this function.
|
||||
</modified>
|
||||
|
||||
<hr><h2><a name="Conditional Access">Conditional Access</a></h2>
|
||||
|
||||
@ -2264,7 +2349,6 @@ virtual bool Assign(cDevice *Device, bool Query = false);
|
||||
|
||||
See the description of this function in <tt>ci.h</tt> for details.
|
||||
|
||||
<div class="modified">
|
||||
<hr><h2><a name="Electronic Program Guide">Electronic Program Guide</a></h2>
|
||||
|
||||
<div class="blurb">The grass is always greener on the other side...</div><p>
|
||||
@ -2294,7 +2378,40 @@ where <tt>DescriptionFromDatabase()</tt> would derive the description of the
|
||||
to signal VDR that no other EPG handlers shall be queried after this one.
|
||||
<p>
|
||||
See <tt>VDR/epg.h</tt> for details.
|
||||
</div modified>
|
||||
|
||||
<hr><h2><a name="The video directory">The video directory</a></h2>
|
||||
|
||||
<div class="blurb">Bits and pieces...</div><p>
|
||||
|
||||
By default VDR assumes that the video directory consists of one large
|
||||
volume, on which it can store its recordings. If you want to distribute your
|
||||
recordings over several physical drives, you can derive from <tt>cVideoDirectory</tt>,
|
||||
as in
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
#include <vdr/videodir.h>
|
||||
|
||||
class cMyVideoDirectory : public cVideoDirectory {
|
||||
public:
|
||||
cMyVideoDirectory(void);
|
||||
virtual ~cMyVideoDirectory();
|
||||
virtual int FreeMB(int *UsedMB = NULL);
|
||||
virtual bool Register(const char *FileName);
|
||||
virtual bool Rename(const char *OldName, const char *NewName);
|
||||
virtual bool Move(const char *FromName, const char *ToName);
|
||||
virtual bool Remove(const char *Name);
|
||||
virtual void Cleanup(const char *IgnoreFiles[] = NULL);
|
||||
virtual bool Contains(const char *Name);
|
||||
};
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
See the description in <tt>videodir.h</tt> for details.
|
||||
<p>
|
||||
You should create your derived video directory object in the
|
||||
<a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
|
||||
Note that the object has to be created on the heap (using <tt>new</tt>),
|
||||
and you shall not delete it at any point (it will be deleted automatically
|
||||
when the program ends).
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
@ -1,47 +0,0 @@
|
||||
VDR Plugin 'dvbsddevice' Revision History
|
||||
-----------------------------------------
|
||||
|
||||
2009-12-28: Version 0.0.1
|
||||
|
||||
- Initial revision.
|
||||
|
||||
2010-01-04: Version 0.0.2
|
||||
|
||||
- Calling the MakePrimaryDevice() function of the base class to allow
|
||||
the cDevice to stop displaying subtitles.
|
||||
- Added support for DVB cards with multiple fontends.
|
||||
|
||||
2010-01-30: Version 0.0.3
|
||||
|
||||
- The PCR pid is now recorded for channels where this is different from the
|
||||
video PID.
|
||||
|
||||
2011-04-17: Version 0.0.4
|
||||
|
||||
- Removed an obsolete local variable in dvbsdffosd.c (thanks to Paul Menzel).
|
||||
|
||||
2011-08-27: Version 0.0.5
|
||||
|
||||
- Added option --outputonly to use the device only for output (thanks to Udo Richter).
|
||||
|
||||
2012-03-07: Version 0.0.6
|
||||
|
||||
- Removed the call to EITScanner.UsesDevice(this) from dvbsddevice.c, because
|
||||
the code following these calls is only executed if LiveView is true, which is
|
||||
never the case when the EITScanner switches to a channel.
|
||||
|
||||
2012-12-27: Version 0.0.7
|
||||
|
||||
- Adapted Makefile to changes introduced in recent VDR versions.
|
||||
|
||||
2013-01-12: Version 0.0.8
|
||||
|
||||
- Adapted Makefile to changes introduced in recent VDR versions.
|
||||
|
||||
2013-01-25: Version 0.0.9
|
||||
|
||||
- Returning 0 from cDvbSdFfDevice::NumProvidedSystems() if option --outputonly is given.
|
||||
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
@ -1,94 +0,0 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 1.20 2013/01/12 13:45:01 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
# By default the main source file also carries this name.
|
||||
|
||||
PLUGIN = dvbsddevice
|
||||
|
||||
### The version number of this plugin (taken from the main source file):
|
||||
|
||||
VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
|
||||
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
TMPDIR ?= /tmp
|
||||
|
||||
### The compiler options:
|
||||
|
||||
export CFLAGS = $(call PKGCFG,cflags)
|
||||
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
||||
|
||||
### The version number of VDR's plugin API:
|
||||
|
||||
APIVERSION = $(call PKGCFG,apiversion)
|
||||
|
||||
### Allow user defined options to overwrite defaults:
|
||||
|
||||
-include $(PLGCFG)
|
||||
|
||||
### The name of the distribution archive:
|
||||
|
||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||
PACKAGE = vdr-$(ARCHIVE)
|
||||
|
||||
### The name of the shared object file:
|
||||
|
||||
SOFILE = libvdr-$(PLUGIN).so
|
||||
|
||||
### Includes and Defines (add further entries here):
|
||||
|
||||
INCLUDES +=
|
||||
|
||||
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
||||
|
||||
### The object files (add further files here):
|
||||
|
||||
OBJS = $(PLUGIN).o dvbsdffdevice.o dvbsdffosd.o
|
||||
|
||||
### The main target:
|
||||
|
||||
all: $(SOFILE)
|
||||
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
MAKEDEP = $(CXX) -MM -MG
|
||||
DEPFILE = .dependencies
|
||||
$(DEPFILE): Makefile
|
||||
@$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
|
||||
|
||||
-include $(DEPFILE)
|
||||
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
||||
install: install-lib
|
||||
|
||||
dist: clean
|
||||
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
||||
@mkdir $(TMPDIR)/$(ARCHIVE)
|
||||
@cp -a * $(TMPDIR)/$(ARCHIVE)
|
||||
@tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
|
||||
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
||||
@echo Distribution package created as $(PACKAGE).tgz
|
||||
|
||||
clean:
|
||||
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
@ -1,20 +0,0 @@
|
||||
This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
|
||||
Latest version available at: ftp://ftp.tvdr.de/vdr
|
||||
|
||||
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.
|
||||
See the file COPYING for more information.
|
||||
|
||||
Description:
|
||||
|
||||
The 'dvbsddevice' plugin implements the output device for the
|
||||
"Full Featured" DVB cards based on the TechnoTrend/Fujitsu-Siemens
|
||||
design. This code was originally part of the core VDR source, and
|
||||
was moved into this plugin in VDR version 1.7.11.
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* dvbsddevice.c: A plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: dvbsddevice.c 1.10 2013/03/31 09:30:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <vdr/plugin.h>
|
||||
#include "dvbsdffdevice.h"
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *DESCRIPTION = "SD Full Featured DVB device";
|
||||
|
||||
class cPluginDvbsddevice : public cPlugin {
|
||||
private:
|
||||
cDvbSdFfDeviceProbe *probe;
|
||||
public:
|
||||
cPluginDvbsddevice(void);
|
||||
virtual ~cPluginDvbsddevice();
|
||||
virtual const char *Version(void) { return VERSION; }
|
||||
virtual const char *Description(void) { return DESCRIPTION; }
|
||||
virtual const char *CommandLineHelp(void);
|
||||
virtual bool ProcessArgs(int argc, char *argv[]);
|
||||
};
|
||||
|
||||
cPluginDvbsddevice::cPluginDvbsddevice(void)
|
||||
{
|
||||
probe = new cDvbSdFfDeviceProbe;
|
||||
}
|
||||
|
||||
cPluginDvbsddevice::~cPluginDvbsddevice()
|
||||
{
|
||||
delete probe;
|
||||
}
|
||||
|
||||
const char *cPluginDvbsddevice::CommandLineHelp(void)
|
||||
{
|
||||
return " -o --outputonly do not receive, just use as output device\n";
|
||||
}
|
||||
|
||||
bool cPluginDvbsddevice::ProcessArgs(int argc, char *argv[])
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
{ "outputonly", no_argument, NULL, 'o' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'o': probe->SetOutputOnly(true);
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
VDRPLUGINCREATOR(cPluginDvbsddevice); // Don't touch this!
|
@ -1,799 +0,0 @@
|
||||
/*
|
||||
* dvbsdffdevice.h: The DVB SD Full Featured device interface
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: dvbsdffdevice.c 2.35 2013/02/17 13:16:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbsdffdevice.h"
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <vdr/eitscan.h>
|
||||
#include <vdr/transfer.h>
|
||||
#include "dvbsdffosd.h"
|
||||
|
||||
// --- cDvbSdFfDevice --------------------------------------------------------
|
||||
|
||||
int cDvbSdFfDevice::devVideoOffset = -1;
|
||||
|
||||
cDvbSdFfDevice::cDvbSdFfDevice(int Adapter, int Frontend, bool OutputOnly)
|
||||
:cDvbDevice(Adapter, Frontend)
|
||||
{
|
||||
spuDecoder = NULL;
|
||||
digitalAudio = false;
|
||||
playMode = pmNone;
|
||||
outputOnly = OutputOnly;
|
||||
|
||||
// Devices that are only present on cards with decoders:
|
||||
|
||||
fd_osd = DvbOpen(DEV_DVB_OSD, adapter, frontend, O_RDWR);
|
||||
fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
|
||||
fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
|
||||
fd_stc = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR);
|
||||
|
||||
// The offset of the /dev/video devices:
|
||||
|
||||
if (devVideoOffset < 0) { // the first one checks this
|
||||
FILE *f = NULL;
|
||||
char buffer[PATH_MAX];
|
||||
for (int ofs = 0; ofs < 100; ofs++) {
|
||||
snprintf(buffer, sizeof(buffer), "/proc/video/dev/video%d", ofs);
|
||||
if ((f = fopen(buffer, "r")) != NULL) {
|
||||
if (fgets(buffer, sizeof(buffer), f)) {
|
||||
if (strstr(buffer, "DVB Board")) { // found the _first_ DVB card
|
||||
devVideoOffset = ofs;
|
||||
dsyslog("video device offset is %d", devVideoOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (devVideoOffset < 0)
|
||||
devVideoOffset = 0;
|
||||
if (f)
|
||||
fclose(f);
|
||||
}
|
||||
devVideoIndex = devVideoOffset >= 0 ? devVideoOffset++ : -1;
|
||||
}
|
||||
|
||||
cDvbSdFfDevice::~cDvbSdFfDevice()
|
||||
{
|
||||
delete spuDecoder;
|
||||
// We're not explicitly closing any device files here, since this sometimes
|
||||
// caused segfaults. Besides, the program is about to terminate anyway...
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::MakePrimaryDevice(bool On)
|
||||
{
|
||||
if (On)
|
||||
new cDvbOsdProvider(fd_osd);
|
||||
cDvbDevice::MakePrimaryDevice(On);
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::HasDecoder(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::AvoidRecording(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
cSpuDecoder *cDvbSdFfDevice::GetSpuDecoder(void)
|
||||
{
|
||||
if (!spuDecoder && IsPrimaryDevice())
|
||||
spuDecoder = new cDvbSpuDecoder();
|
||||
return spuDecoder;
|
||||
}
|
||||
|
||||
uchar *cDvbSdFfDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
|
||||
{
|
||||
if (devVideoIndex < 0)
|
||||
return NULL;
|
||||
char buffer[PATH_MAX];
|
||||
snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, devVideoIndex);
|
||||
int videoDev = open(buffer, O_RDWR);
|
||||
if (videoDev >= 0) {
|
||||
uchar *result = NULL;
|
||||
// set up the size and RGB
|
||||
v4l2_format fmt;
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fmt.fmt.pix.width = SizeX;
|
||||
fmt.fmt.pix.height = SizeY;
|
||||
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||
if (ioctl(videoDev, VIDIOC_S_FMT, &fmt) == 0) {
|
||||
v4l2_requestbuffers reqBuf;
|
||||
memset(&reqBuf, 0, sizeof(reqBuf));
|
||||
reqBuf.count = 2;
|
||||
reqBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
reqBuf.memory = V4L2_MEMORY_MMAP;
|
||||
if (ioctl(videoDev, VIDIOC_REQBUFS, &reqBuf) >= 0) {
|
||||
v4l2_buffer mbuf;
|
||||
memset(&mbuf, 0, sizeof(mbuf));
|
||||
mbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
mbuf.memory = V4L2_MEMORY_MMAP;
|
||||
if (ioctl(videoDev, VIDIOC_QUERYBUF, &mbuf) == 0) {
|
||||
int msize = mbuf.length;
|
||||
unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
|
||||
if (mem && mem != (unsigned char *)-1) {
|
||||
v4l2_buffer buf;
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = 0;
|
||||
if (ioctl(videoDev, VIDIOC_QBUF, &buf) == 0) {
|
||||
v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (ioctl (videoDev, VIDIOC_STREAMON, &type) == 0) {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = 0;
|
||||
if (ioctl(videoDev, VIDIOC_DQBUF, &buf) == 0) {
|
||||
if (ioctl(videoDev, VIDIOC_STREAMOFF, &type) == 0) {
|
||||
// make RGB out of BGR:
|
||||
int memsize = fmt.fmt.pix.width * fmt.fmt.pix.height;
|
||||
unsigned char *mem1 = mem;
|
||||
for (int i = 0; i < memsize; i++) {
|
||||
unsigned char tmp = mem1[2];
|
||||
mem1[2] = mem1[0];
|
||||
mem1[0] = tmp;
|
||||
mem1 += 3;
|
||||
}
|
||||
|
||||
if (Quality < 0)
|
||||
Quality = 100;
|
||||
|
||||
dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||
if (Jpeg) {
|
||||
// convert to JPEG:
|
||||
result = RgbToJpeg(mem, fmt.fmt.pix.width, fmt.fmt.pix.height, Size, Quality);
|
||||
if (!result)
|
||||
esyslog("ERROR: failed to convert image to JPEG");
|
||||
}
|
||||
else {
|
||||
// convert to PNM:
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||
int l = strlen(buf);
|
||||
int bytes = memsize * 3;
|
||||
Size = l + bytes;
|
||||
result = MALLOC(uchar, Size);
|
||||
if (result) {
|
||||
memcpy(result, buf, l);
|
||||
memcpy(result + l, mem, bytes);
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: failed to convert image to PNM");
|
||||
}
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_STREAMOFF failed");
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_DQBUF failed");
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_STREAMON failed");
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_QBUF failed");
|
||||
munmap(mem, msize);
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: failed to memmap video device");
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_QUERYBUF failed");
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_REQBUFS failed");
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: video device VIDIOC_S_FMT failed");
|
||||
close(videoDev);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
LOG_ERROR_STR(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
|
||||
{
|
||||
cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
|
||||
if (Setup.VideoFormat) {
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX));
|
||||
}
|
||||
else {
|
||||
switch (VideoDisplayFormat) {
|
||||
case vdfPanAndScan:
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_PAN_SCAN));
|
||||
break;
|
||||
case vdfLetterBox:
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX));
|
||||
break;
|
||||
case vdfCenterCutOut:
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_CENTER_CUT_OUT));
|
||||
break;
|
||||
default: esyslog("ERROR: unknown video display format %d", VideoDisplayFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::SetVideoFormat(bool VideoFormat16_9)
|
||||
{
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, VideoFormat16_9 ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3));
|
||||
SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
|
||||
}
|
||||
|
||||
eVideoSystem cDvbSdFfDevice::GetVideoSystem(void)
|
||||
{
|
||||
eVideoSystem VideoSystem = vsPAL;
|
||||
if (fd_video >= 0) {
|
||||
video_size_t vs;
|
||||
if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
|
||||
if (vs.h == 480 || vs.h == 240)
|
||||
VideoSystem = vsNTSC;
|
||||
}
|
||||
else
|
||||
LOG_ERROR;
|
||||
}
|
||||
return VideoSystem;
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::GetVideoSize(int &Width, int &Height, double &VideoAspect)
|
||||
{
|
||||
if (fd_video >= 0) {
|
||||
video_size_t vs;
|
||||
if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
|
||||
Width = vs.w;
|
||||
Height = vs.h;
|
||||
switch (vs.aspect_ratio) {
|
||||
default:
|
||||
case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0; break;
|
||||
case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0; break;
|
||||
case VIDEO_FORMAT_221_1: VideoAspect = 2.21; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
LOG_ERROR;
|
||||
}
|
||||
cDevice::GetVideoSize(Width, Height, VideoAspect);
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
|
||||
{
|
||||
if (fd_video >= 0) {
|
||||
video_size_t vs;
|
||||
if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
|
||||
Width = 720;
|
||||
if (vs.h != 480 && vs.h != 240)
|
||||
Height = 576; // PAL
|
||||
else
|
||||
Height = 480; // NTSC
|
||||
switch (Setup.VideoFormat ? vs.aspect_ratio : VIDEO_FORMAT_4_3) {
|
||||
default:
|
||||
case VIDEO_FORMAT_4_3: PixelAspect = 4.0 / 3.0; break;
|
||||
case VIDEO_FORMAT_221_1: // FF DVB cards only distinguish between 4:3 and 16:9
|
||||
case VIDEO_FORMAT_16_9: PixelAspect = 16.0 / 9.0; break;
|
||||
}
|
||||
PixelAspect /= double(Width) / Height;
|
||||
return;
|
||||
}
|
||||
else
|
||||
LOG_ERROR;
|
||||
}
|
||||
cDevice::GetOsdSize(Width, Height, PixelAspect);
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::SetAudioBypass(bool On)
|
||||
{
|
||||
if (setTransferModeForDolbyDigital != 1)
|
||||
return false;
|
||||
return ioctl(fd_audio, AUDIO_SET_BYPASS_MODE, On) == 0;
|
||||
}
|
||||
|
||||
// ptAudio ptVideo ptPcr ptTeletext ptDolby ptOther
|
||||
static dmx_pes_type_t PesTypes[] = { DMX_PES_AUDIO, DMX_PES_VIDEO, DMX_PES_PCR, DMX_PES_TELETEXT, DMX_PES_OTHER, DMX_PES_OTHER };
|
||||
|
||||
bool cDvbSdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
|
||||
{
|
||||
if (Handle->pid) {
|
||||
dmx_pes_filter_params pesFilterParams;
|
||||
memset(&pesFilterParams, 0, sizeof(pesFilterParams));
|
||||
if (On) {
|
||||
if (Handle->handle < 0) {
|
||||
Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
|
||||
if (Handle->handle < 0) {
|
||||
LOG_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pesFilterParams.pid = Handle->pid;
|
||||
pesFilterParams.input = DMX_IN_FRONTEND;
|
||||
pesFilterParams.output = (Type <= ptTeletext && Handle->used <= 1) ? DMX_OUT_DECODER : DMX_OUT_TS_TAP;
|
||||
pesFilterParams.pes_type= PesTypes[Type < ptOther ? Type : ptOther];
|
||||
pesFilterParams.flags = DMX_IMMEDIATE_START;
|
||||
if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
|
||||
LOG_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!Handle->used) {
|
||||
CHECK(ioctl(Handle->handle, DMX_STOP));
|
||||
if (Type <= ptTeletext) {
|
||||
pesFilterParams.pid = 0x1FFF;
|
||||
pesFilterParams.input = DMX_IN_FRONTEND;
|
||||
pesFilterParams.output = DMX_OUT_DECODER;
|
||||
pesFilterParams.pes_type= PesTypes[Type];
|
||||
pesFilterParams.flags = DMX_IMMEDIATE_START;
|
||||
CHECK(ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams));
|
||||
if (PesTypes[Type] == DMX_PES_VIDEO) // let's only do this once
|
||||
SetPlayMode(pmNone); // necessary to switch a PID from DMX_PES_VIDEO/AUDIO to DMX_PES_OTHER
|
||||
}
|
||||
close(Handle->handle);
|
||||
Handle->handle = -1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::ProvidesSource(int Source) const
|
||||
{
|
||||
if (outputOnly)
|
||||
return false;
|
||||
else
|
||||
return cDvbDevice::ProvidesSource(Source);
|
||||
}
|
||||
|
||||
int cDvbSdFfDevice::NumProvidedSystems(void) const
|
||||
{
|
||||
if (outputOnly)
|
||||
return 0;
|
||||
return cDvbDevice::NumProvidedSystems();
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::TurnOffLiveMode(bool LiveView)
|
||||
{
|
||||
if (LiveView) {
|
||||
// Avoid noise while switching:
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true));
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||
CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
|
||||
}
|
||||
|
||||
// Turn off live PIDs:
|
||||
|
||||
DetachAll(pidHandles[ptAudio].pid);
|
||||
DetachAll(pidHandles[ptVideo].pid);
|
||||
DetachAll(pidHandles[ptPcr].pid);
|
||||
DetachAll(pidHandles[ptTeletext].pid);
|
||||
DelPid(pidHandles[ptAudio].pid);
|
||||
DelPid(pidHandles[ptVideo].pid);
|
||||
DelPid(pidHandles[ptPcr].pid, ptPcr);
|
||||
DelPid(pidHandles[ptTeletext].pid);
|
||||
DelPid(pidHandles[ptDolby].pid);
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
||||
{
|
||||
int apid = Channel->Apid(0);
|
||||
int vpid = Channel->Vpid();
|
||||
int dpid = Channel->Dpid(0);
|
||||
|
||||
bool DoTune = !IsTunedToTransponder(Channel);
|
||||
|
||||
bool pidHandlesVideo = pidHandles[ptVideo].pid == vpid;
|
||||
bool pidHandlesAudio = pidHandles[ptAudio].pid == apid;
|
||||
|
||||
bool TurnOffLivePIDs = DoTune
|
||||
|| !IsPrimaryDevice()
|
||||
|| LiveView // for a new live view the old PIDs need to be turned off
|
||||
|| pidHandlesVideo // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
|
||||
;
|
||||
|
||||
bool StartTransferMode = IsPrimaryDevice() && !DoTune
|
||||
&& (LiveView && HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ? pidHandles[ptAudio].pid != dpid : true)))// the PID is already set as DMX_PES_OTHER
|
||||
|| !LiveView && (pidHandlesVideo || pidHandlesAudio) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
|
||||
);
|
||||
if (CamSlot() && !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlot()->SlotNumber()))
|
||||
StartTransferMode |= LiveView && IsPrimaryDevice() && Channel->Ca() >= CA_ENCRYPTED_MIN;
|
||||
|
||||
bool TurnOnLivePIDs = !StartTransferMode && LiveView;
|
||||
|
||||
// Turn off live PIDs if necessary:
|
||||
|
||||
if (TurnOffLivePIDs)
|
||||
TurnOffLiveMode(LiveView);
|
||||
|
||||
// Set the tuner:
|
||||
|
||||
if (!cDvbDevice::SetChannelDevice(Channel, LiveView))
|
||||
return false;
|
||||
|
||||
// PID settings:
|
||||
|
||||
if (TurnOnLivePIDs) {
|
||||
SetAudioBypass(false);
|
||||
if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo) && AddPid(apid, ptAudio))) {
|
||||
esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
|
||||
return false;
|
||||
}
|
||||
if (IsPrimaryDevice())
|
||||
AddPid(Channel->Tpid(), ptTeletext);
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schluessler <marco@lordzodiac.de> this works
|
||||
// to avoid missing audio after replaying a DVD; with 'false' there is an audio disturbance when switching
|
||||
// between two channels on the same transponder on DVB-S
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
||||
}
|
||||
else if (StartTransferMode)
|
||||
cControl::Launch(new cTransferControl(this, Channel));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int cDvbSdFfDevice::GetAudioChannelDevice(void)
|
||||
{
|
||||
audio_status_t as;
|
||||
CHECK(ioctl(fd_audio, AUDIO_GET_STATUS, &as));
|
||||
return as.channel_select;
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::SetAudioChannelDevice(int AudioChannel)
|
||||
{
|
||||
CHECK(ioctl(fd_audio, AUDIO_CHANNEL_SELECT, AudioChannel));
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::SetVolumeDevice(int Volume)
|
||||
{
|
||||
if (digitalAudio)
|
||||
Volume = 0;
|
||||
audio_mixer_t am;
|
||||
// conversion for linear volume response:
|
||||
am.volume_left = am.volume_right = 2 * Volume - Volume * Volume / 255;
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_MIXER, &am));
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::SetDigitalAudioDevice(bool On)
|
||||
{
|
||||
if (digitalAudio != On) {
|
||||
if (digitalAudio)
|
||||
cCondWait::SleepMs(1000); // Wait until any leftover digital data has been flushed
|
||||
digitalAudio = On;
|
||||
SetVolumeDevice(On || IsMute() ? 0 : CurrentVolume());
|
||||
}
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::SetAudioTrackDevice(eTrackType Type)
|
||||
{
|
||||
const tTrackId *TrackId = GetTrack(Type);
|
||||
if (TrackId && TrackId->id) {
|
||||
SetAudioBypass(false);
|
||||
if (IS_AUDIO_TRACK(Type) || (IS_DOLBY_TRACK(Type) && SetAudioBypass(true))) {
|
||||
if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) {
|
||||
DetachAll(pidHandles[ptAudio].pid);
|
||||
if (CamSlot())
|
||||
CamSlot()->SetPid(pidHandles[ptAudio].pid, false);
|
||||
pidHandles[ptAudio].pid = TrackId->id;
|
||||
SetPid(&pidHandles[ptAudio], ptAudio, true);
|
||||
if (CamSlot()) {
|
||||
CamSlot()->SetPid(pidHandles[ptAudio].pid, true);
|
||||
CamSlot()->StartDecrypting();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IS_DOLBY_TRACK(Type)) {
|
||||
if (setTransferModeForDolbyDigital == 0)
|
||||
return;
|
||||
// Currently this works only in Transfer Mode
|
||||
ForceTransferMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::CanReplay(void) const
|
||||
{
|
||||
return cDevice::CanReplay();
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
{
|
||||
if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) {
|
||||
// reopen the devices
|
||||
fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
|
||||
fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
|
||||
SetVideoFormat(Setup.VideoFormat);
|
||||
}
|
||||
|
||||
switch (PlayMode) {
|
||||
case pmNone:
|
||||
// special handling to return from PCM replay:
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
|
||||
CHECK(ioctl(fd_video, VIDEO_PLAY));
|
||||
|
||||
CHECK(ioctl(fd_video, VIDEO_STOP, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_STOP, true));
|
||||
CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
|
||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||
CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
|
||||
break;
|
||||
case pmAudioVideo:
|
||||
case pmAudioOnlyBlack:
|
||||
if (playMode == pmNone)
|
||||
TurnOffLiveMode(true);
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, PlayMode == pmAudioVideo));
|
||||
CHECK(ioctl(fd_audio, AUDIO_PLAY));
|
||||
CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
|
||||
CHECK(ioctl(fd_video, VIDEO_PLAY));
|
||||
break;
|
||||
case pmAudioOnly:
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_STOP, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
|
||||
CHECK(ioctl(fd_audio, AUDIO_PLAY));
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
|
||||
break;
|
||||
case pmVideoOnly:
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_video, VIDEO_STOP, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
|
||||
CHECK(ioctl(fd_audio, AUDIO_PLAY));
|
||||
CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
|
||||
CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
|
||||
CHECK(ioctl(fd_video, VIDEO_PLAY));
|
||||
break;
|
||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||
close(fd_video);
|
||||
close(fd_audio);
|
||||
fd_video = fd_audio = -1;
|
||||
break;
|
||||
default: esyslog("ERROR: unknown playmode %d", PlayMode);
|
||||
}
|
||||
playMode = PlayMode;
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t cDvbSdFfDevice::GetSTC(void)
|
||||
{
|
||||
if (fd_stc >= 0) {
|
||||
struct dmx_stc stc;
|
||||
stc.num = 0;
|
||||
if (ioctl(fd_stc, DMX_GET_STC, &stc) == -1) {
|
||||
esyslog("ERROR: stc %d: %m", CardIndex() + 1);
|
||||
return -1;
|
||||
}
|
||||
return stc.stc / stc.base;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::TrickSpeed(int Speed)
|
||||
{
|
||||
if (fd_video >= 0)
|
||||
CHECK(ioctl(fd_video, VIDEO_SLOWMOTION, Speed));
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::Clear(void)
|
||||
{
|
||||
if (fd_video >= 0)
|
||||
CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
|
||||
if (fd_audio >= 0)
|
||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||
cDevice::Clear();
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::Play(void)
|
||||
{
|
||||
if (playMode == pmAudioOnly || playMode == pmAudioOnlyBlack) {
|
||||
if (fd_audio >= 0)
|
||||
CHECK(ioctl(fd_audio, AUDIO_CONTINUE));
|
||||
}
|
||||
else {
|
||||
if (fd_audio >= 0) {
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_CONTINUE));
|
||||
}
|
||||
if (fd_video >= 0)
|
||||
CHECK(ioctl(fd_video, VIDEO_CONTINUE));
|
||||
}
|
||||
cDevice::Play();
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::Freeze(void)
|
||||
{
|
||||
if (playMode == pmAudioOnly || playMode == pmAudioOnlyBlack) {
|
||||
if (fd_audio >= 0)
|
||||
CHECK(ioctl(fd_audio, AUDIO_PAUSE));
|
||||
}
|
||||
else {
|
||||
if (fd_audio >= 0) {
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
|
||||
CHECK(ioctl(fd_audio, AUDIO_PAUSE));
|
||||
}
|
||||
if (fd_video >= 0)
|
||||
CHECK(ioctl(fd_video, VIDEO_FREEZE));
|
||||
}
|
||||
cDevice::Freeze();
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::Mute(void)
|
||||
{
|
||||
if (fd_audio >= 0) {
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true));
|
||||
}
|
||||
cDevice::Mute();
|
||||
}
|
||||
|
||||
void cDvbSdFfDevice::StillPicture(const uchar *Data, int Length)
|
||||
{
|
||||
if (!Data || Length < TS_SIZE)
|
||||
return;
|
||||
if (Data[0] == 0x47) {
|
||||
// TS data
|
||||
cDevice::StillPicture(Data, Length);
|
||||
}
|
||||
else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
|
||||
// PES data
|
||||
char *buf = MALLOC(char, Length);
|
||||
if (!buf)
|
||||
return;
|
||||
int i = 0;
|
||||
int blen = 0;
|
||||
while (i < Length - 6) {
|
||||
if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
|
||||
int len = Data[i + 4] * 256 + Data[i + 5];
|
||||
if ((Data[i + 3] & 0xF0) == 0xE0) { // video packet
|
||||
// skip PES header
|
||||
int offs = i + 6;
|
||||
// skip header extension
|
||||
if ((Data[i + 6] & 0xC0) == 0x80) {
|
||||
// MPEG-2 PES header
|
||||
if (Data[i + 8] >= Length)
|
||||
break;
|
||||
offs += 3;
|
||||
offs += Data[i + 8];
|
||||
len -= 3;
|
||||
len -= Data[i + 8];
|
||||
if (len < 0 || offs + len > Length)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// MPEG-1 PES header
|
||||
while (offs < Length && len > 0 && Data[offs] == 0xFF) {
|
||||
offs++;
|
||||
len--;
|
||||
}
|
||||
if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
|
||||
offs += 2;
|
||||
len -= 2;
|
||||
}
|
||||
if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
|
||||
offs += 5;
|
||||
len -= 5;
|
||||
}
|
||||
else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
|
||||
offs += 10;
|
||||
len -= 10;
|
||||
}
|
||||
else if (offs < Length && len > 0) {
|
||||
offs++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
if (blen + len > Length) // invalid PES length field
|
||||
break;
|
||||
memcpy(&buf[blen], &Data[offs], len);
|
||||
i = offs + len;
|
||||
blen += len;
|
||||
}
|
||||
else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF) // other PES packets
|
||||
i += len + 6;
|
||||
else
|
||||
i++;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
video_still_picture sp = { buf, blen };
|
||||
CHECK(ioctl(fd_video, VIDEO_STILLPICTURE, &sp));
|
||||
free(buf);
|
||||
}
|
||||
else {
|
||||
// non-PES data
|
||||
video_still_picture sp = { (char *)Data, Length };
|
||||
CHECK(ioctl(fd_video, VIDEO_STILLPICTURE, &sp));
|
||||
}
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::Poll(cPoller &Poller, int TimeoutMs)
|
||||
{
|
||||
Poller.Add((playMode == pmAudioOnly || playMode == pmAudioOnlyBlack) ? fd_audio : fd_video, true);
|
||||
return Poller.Poll(TimeoutMs);
|
||||
}
|
||||
|
||||
bool cDvbSdFfDevice::Flush(int TimeoutMs)
|
||||
{
|
||||
//TODO actually this function should wait until all buffered data has been processed by the card, but how?
|
||||
return true;
|
||||
}
|
||||
|
||||
int cDvbSdFfDevice::PlayVideo(const uchar *Data, int Length)
|
||||
{
|
||||
return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
|
||||
}
|
||||
|
||||
int cDvbSdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
|
||||
{
|
||||
return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10);
|
||||
}
|
||||
|
||||
int cDvbSdFfDevice::PlayTsVideo(const uchar *Data, int Length)
|
||||
{
|
||||
return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
|
||||
}
|
||||
|
||||
int cDvbSdFfDevice::PlayTsAudio(const uchar *Data, int Length)
|
||||
{
|
||||
return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10);
|
||||
}
|
||||
|
||||
// --- cDvbSdFfDeviceProbe ---------------------------------------------------
|
||||
|
||||
cDvbSdFfDeviceProbe::cDvbSdFfDeviceProbe(void)
|
||||
{
|
||||
outputOnly = false;
|
||||
}
|
||||
|
||||
bool cDvbSdFfDeviceProbe::Probe(int Adapter, int Frontend)
|
||||
{
|
||||
static uint32_t SubsystemIds[] = {
|
||||
0x110A0000, // Fujitsu Siemens DVB-C
|
||||
0x13C20000, // Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C
|
||||
0x13C20001, // Technotrend/Hauppauge WinTV DVB-T rev1.X
|
||||
0x13C20002, // Technotrend/Hauppauge WinTV DVB-C rev2.X
|
||||
0x13C20003, // Technotrend/Hauppauge WinTV Nexus-S rev2.X
|
||||
0x13C20004, // Galaxis DVB-S rev1.3
|
||||
0x13C20006, // Fujitsu Siemens DVB-S rev1.6
|
||||
0x13C20008, // Technotrend/Hauppauge DVB-T
|
||||
0x13C2000A, // Technotrend/Hauppauge WinTV Nexus-CA rev1.X
|
||||
0x13C2000E, // Technotrend/Hauppauge WinTV Nexus-S rev2.3
|
||||
0x13C21002, // Technotrend/Hauppauge WinTV DVB-S rev1.3 SE
|
||||
0x00000000
|
||||
};
|
||||
uint32_t SubsystemId = GetSubsystemId(Adapter, Frontend);
|
||||
for (uint32_t *sid = SubsystemIds; *sid; sid++) {
|
||||
if (*sid == SubsystemId) {
|
||||
dsyslog("creating cDvbSdFfDevice");
|
||||
new cDvbSdFfDevice(Adapter, Frontend, outputOnly);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* dvbsdffdevice.h: The DVB SD Full Featured device interface
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: dvbsdffdevice.h 2.16 2013/02/17 13:16:29 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DVBSDFFDEVICE_H
|
||||
#define __DVBSDFFDEVICE_H
|
||||
|
||||
#include <vdr/dvbdevice.h>
|
||||
#include <vdr/dvbspu.h>
|
||||
|
||||
/// The cDvbSdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API.
|
||||
|
||||
class cDvbSdFfDevice : public cDvbDevice {
|
||||
private:
|
||||
int fd_osd, fd_audio, fd_video, fd_stc;
|
||||
bool outputOnly;
|
||||
protected:
|
||||
virtual void MakePrimaryDevice(bool On);
|
||||
public:
|
||||
cDvbSdFfDevice(int Adapter, int Frontend, bool OutputOnly);
|
||||
virtual ~cDvbSdFfDevice();
|
||||
virtual bool HasDecoder(void) const;
|
||||
virtual bool AvoidRecording(void) const;
|
||||
|
||||
// SPU facilities
|
||||
|
||||
private:
|
||||
cDvbSpuDecoder *spuDecoder;
|
||||
public:
|
||||
virtual cSpuDecoder *GetSpuDecoder(void);
|
||||
|
||||
// Channel facilities
|
||||
|
||||
public:
|
||||
virtual bool ProvidesSource(int Source) const;
|
||||
virtual int NumProvidedSystems(void) const;
|
||||
private:
|
||||
void TurnOffLiveMode(bool LiveView);
|
||||
protected:
|
||||
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
|
||||
|
||||
// PID handle facilities
|
||||
|
||||
private:
|
||||
bool SetAudioBypass(bool On);
|
||||
protected:
|
||||
virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
|
||||
|
||||
// Image Grab facilities
|
||||
|
||||
private:
|
||||
static int devVideoOffset;
|
||||
int devVideoIndex;
|
||||
public:
|
||||
virtual uchar *GrabImage(int &Size, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
|
||||
|
||||
// Video format facilities
|
||||
|
||||
public:
|
||||
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat);
|
||||
virtual void SetVideoFormat(bool VideoFormat16_9);
|
||||
virtual eVideoSystem GetVideoSystem(void);
|
||||
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect);
|
||||
virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect);
|
||||
|
||||
// Track facilities
|
||||
|
||||
protected:
|
||||
virtual void SetAudioTrackDevice(eTrackType Type);
|
||||
|
||||
// Audio facilities
|
||||
|
||||
private:
|
||||
bool digitalAudio;
|
||||
protected:
|
||||
virtual int GetAudioChannelDevice(void);
|
||||
virtual void SetAudioChannelDevice(int AudioChannel);
|
||||
virtual void SetVolumeDevice(int Volume);
|
||||
virtual void SetDigitalAudioDevice(bool On);
|
||||
|
||||
// Player facilities
|
||||
|
||||
protected:
|
||||
ePlayMode playMode;
|
||||
virtual bool CanReplay(void) const;
|
||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||
virtual int PlayVideo(const uchar *Data, int Length);
|
||||
virtual int PlayAudio(const uchar *Data, int Length, uchar Id);
|
||||
virtual int PlayTsVideo(const uchar *Data, int Length);
|
||||
virtual int PlayTsAudio(const uchar *Data, int Length);
|
||||
public:
|
||||
virtual int64_t GetSTC(void);
|
||||
virtual void TrickSpeed(int Speed);
|
||||
virtual void Clear(void);
|
||||
virtual void Play(void);
|
||||
virtual void Freeze(void);
|
||||
virtual void Mute(void);
|
||||
virtual void StillPicture(const uchar *Data, int Length);
|
||||
virtual bool Poll(cPoller &Poller, int TimeoutMs = 0);
|
||||
virtual bool Flush(int TimeoutMs = 0);
|
||||
};
|
||||
|
||||
class cDvbSdFfDeviceProbe : public cDvbDeviceProbe {
|
||||
private:
|
||||
bool outputOnly;
|
||||
public:
|
||||
cDvbSdFfDeviceProbe(void);
|
||||
void SetOutputOnly(bool On) { outputOnly = On; }
|
||||
virtual bool Probe(int Adapter, int Frontend);
|
||||
};
|
||||
|
||||
#endif //__DVBSDFFDEVICE_H
|
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* dvbsdffosd.c: Implementation of the DVB SD Full Featured On Screen Display
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: dvbsdffosd.c 2.3 2011/04/17 12:55:09 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbsdffosd.h"
|
||||
#include <linux/dvb/osd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
// --- cDvbSdFfOsd -----------------------------------------------------------
|
||||
|
||||
#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
|
||||
#define MAXOSDMEMORY 92000 // number of bytes available to the OSD (for unmodified DVB cards)
|
||||
|
||||
class cDvbSdFfOsd : public cOsd {
|
||||
private:
|
||||
int osdDev;
|
||||
int osdMem;
|
||||
bool shown;
|
||||
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
||||
protected:
|
||||
virtual void SetActive(bool On);
|
||||
public:
|
||||
cDvbSdFfOsd(int Left, int Top, int OsdDev, uint Level);
|
||||
virtual ~cDvbSdFfOsd();
|
||||
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
|
||||
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
|
||||
virtual void Flush(void);
|
||||
};
|
||||
|
||||
cDvbSdFfOsd::cDvbSdFfOsd(int Left, int Top, int OsdDev, uint Level)
|
||||
:cOsd(Left, Top, Level)
|
||||
{
|
||||
osdDev = OsdDev;
|
||||
shown = false;
|
||||
if (osdDev < 0)
|
||||
esyslog("ERROR: invalid OSD device handle (%d)!", osdDev);
|
||||
else {
|
||||
osdMem = MAXOSDMEMORY;
|
||||
#ifdef OSD_CAP_MEMSIZE
|
||||
// modified DVB cards may have more OSD memory:
|
||||
osd_cap_t cap;
|
||||
cap.cmd = OSD_CAP_MEMSIZE;
|
||||
if (ioctl(osdDev, OSD_GET_CAPABILITY, &cap) == 0)
|
||||
osdMem = cap.val;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
cDvbSdFfOsd::~cDvbSdFfOsd()
|
||||
{
|
||||
SetActive(false);
|
||||
}
|
||||
|
||||
void cDvbSdFfOsd::SetActive(bool On)
|
||||
{
|
||||
if (On != Active()) {
|
||||
cOsd::SetActive(On);
|
||||
if (On) {
|
||||
// must clear all windows here to avoid flashing effects - doesn't work if done
|
||||
// in Flush() only for the windows that are actually used...
|
||||
for (int i = 0; i < MAXNUMWINDOWS; i++) {
|
||||
Cmd(OSD_SetWindow, 0, i + 1);
|
||||
Cmd(OSD_Clear);
|
||||
}
|
||||
if (GetBitmap(0)) // only flush here if there are already bitmaps
|
||||
Flush();
|
||||
}
|
||||
else if (shown) {
|
||||
for (int i = 0; GetBitmap(i); i++) {
|
||||
Cmd(OSD_SetWindow, 0, i + 1);
|
||||
Cmd(OSD_Close);
|
||||
}
|
||||
shown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eOsdError cDvbSdFfOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
|
||||
{
|
||||
eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
|
||||
if (Result == oeOk) {
|
||||
if (NumAreas > MAXNUMWINDOWS)
|
||||
return oeTooManyAreas;
|
||||
int TotalMemory = 0;
|
||||
for (int i = 0; i < NumAreas; i++) {
|
||||
if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8)
|
||||
return oeBppNotSupported;
|
||||
if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0)
|
||||
return oeWrongAlignment;
|
||||
if (Areas[i].Width() < 1 || Areas[i].Height() < 1 || Areas[i].Width() > 720 || Areas[i].Height() > 576)
|
||||
return oeWrongAreaSize;
|
||||
TotalMemory += Areas[i].Width() * Areas[i].Height() / (8 / Areas[i].bpp);
|
||||
}
|
||||
if (TotalMemory > osdMem)
|
||||
return oeOutOfMemory;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
eOsdError cDvbSdFfOsd::SetAreas(const tArea *Areas, int NumAreas)
|
||||
{
|
||||
if (shown) {
|
||||
for (int i = 0; GetBitmap(i); i++) {
|
||||
Cmd(OSD_SetWindow, 0, i + 1);
|
||||
Cmd(OSD_Close);
|
||||
}
|
||||
shown = false;
|
||||
}
|
||||
return cOsd::SetAreas(Areas, NumAreas);
|
||||
}
|
||||
|
||||
void cDvbSdFfOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
|
||||
{
|
||||
if (osdDev >= 0) {
|
||||
osd_cmd_t dc;
|
||||
dc.cmd = cmd;
|
||||
dc.color = color;
|
||||
dc.x0 = x0;
|
||||
dc.y0 = y0;
|
||||
dc.x1 = x1;
|
||||
dc.y1 = y1;
|
||||
dc.data = (void *)data;
|
||||
ioctl(osdDev, OSD_SEND_CMD, &dc);
|
||||
}
|
||||
}
|
||||
|
||||
void cDvbSdFfOsd::Flush(void)
|
||||
{
|
||||
if (!Active())
|
||||
return;
|
||||
cBitmap *Bitmap;
|
||||
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||
Cmd(OSD_SetWindow, 0, i + 1);
|
||||
if (!shown)
|
||||
Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden!
|
||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
if (!shown || Bitmap->Dirty(x1, y1, x2, y2)) {
|
||||
if (!shown) {
|
||||
x1 = y1 = 0;
|
||||
x2 = Bitmap->Width() - 1;
|
||||
y2 = Bitmap->Height() - 1;
|
||||
}
|
||||
//TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple
|
||||
//TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8.
|
||||
//TODO Fix driver (should be able to handle any size bitmaps!)
|
||||
while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7) {
|
||||
if (x2 < Bitmap->Width() - 1)
|
||||
x2++;
|
||||
else if (x1 > 0)
|
||||
x1--;
|
||||
}
|
||||
//TODO "... / 2" <==> Bpp???
|
||||
while ((y1 > 0 || y2 < Bitmap->Height() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) {
|
||||
if (y2 < Bitmap->Height() - 1)
|
||||
y2++;
|
||||
else if (y1 > 0)
|
||||
y1--;
|
||||
}
|
||||
while ((x1 > 0 || x2 < Bitmap->Width() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) {
|
||||
if (x2 < Bitmap->Width() - 1)
|
||||
x2++;
|
||||
else if (x1 > 0)
|
||||
x1--;
|
||||
}
|
||||
// commit colors:
|
||||
int NumColors;
|
||||
const tColor *Colors = Bitmap->Colors(NumColors);
|
||||
if (Colors) {
|
||||
//TODO this should be fixed in the driver!
|
||||
tColor colors[NumColors];
|
||||
for (int i = 0; i < NumColors; i++) {
|
||||
// convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way):
|
||||
colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16);
|
||||
}
|
||||
Colors = colors;
|
||||
//TODO end of stuff that should be fixed in the driver
|
||||
Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors);
|
||||
}
|
||||
// commit modified data:
|
||||
Cmd(OSD_SetBlock, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1));
|
||||
}
|
||||
Bitmap->Clean();
|
||||
}
|
||||
if (!shown) {
|
||||
// Showing the windows in a separate loop to avoid seeing them come up one after another
|
||||
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||
Cmd(OSD_SetWindow, 0, i + 1);
|
||||
Cmd(OSD_MoveWindow, 0, Left() + Bitmap->X0(), Top() + Bitmap->Y0());
|
||||
}
|
||||
shown = true;
|
||||
}
|
||||
}
|
||||
|
||||
// --- cDvbOsdProvider -------------------------------------------------------
|
||||
|
||||
cDvbOsdProvider::cDvbOsdProvider(int OsdDev)
|
||||
{
|
||||
osdDev = OsdDev;
|
||||
}
|
||||
|
||||
cOsd *cDvbOsdProvider::CreateOsd(int Left, int Top, uint Level)
|
||||
{
|
||||
return new cDvbSdFfOsd(Left, Top, osdDev, Level);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* dvbsdffosd.h: Implementation of the DVB SD Full Featured On Screen Display
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: dvbsdffosd.h 2.2 2012/12/03 13:43:55 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DVBSDFFODF_H
|
||||
#define __DVBSDFFODF_H
|
||||
|
||||
#include <vdr/osd.h>
|
||||
|
||||
class cDvbOsdProvider : public cOsdProvider {
|
||||
private:
|
||||
int osdDev;
|
||||
public:
|
||||
cDvbOsdProvider(int OsdDev);
|
||||
virtual cOsd *CreateOsd(int Left, int Top, uint Level);
|
||||
};
|
||||
|
||||
#endif //__DVBSDFFODF_H
|
@ -16,3 +16,19 @@ VDR Plugin 'epgtableid0' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 1.13 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
@ -61,7 +62,8 @@ all: $(SOFILE)
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -75,7 +77,8 @@ $(DEPFILE): Makefile
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,13 +3,13 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: epgtableid0.c 1.4 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: epgtableid0.c 4.1 2018/04/10 13:00:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include <vdr/epg.h>
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "EPG handler for events with table id 0x00";
|
||||
|
||||
// --- cTable0Handler --------------------------------------------------------
|
||||
|
@ -86,3 +86,20 @@ VDR Plugin 'hello' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Updated the French OSD texts (thanks to Bernard Jaulin).
|
||||
- Official release.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.18 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
LOCDIR = $(call PKGCFG,locdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
@ -62,7 +63,8 @@ all: $(SOFILE) i18n
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -82,13 +84,16 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU
|
||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||
|
||||
%.mo: %.po
|
||||
msgfmt -c -o $@ $<
|
||||
@echo MO $@
|
||||
$(Q)msgfmt -c -o $@ $<
|
||||
|
||||
$(I18Npot): $(wildcard *.c)
|
||||
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||
@echo GT $@
|
||||
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||
|
||||
%.po: $(I18Npot)
|
||||
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@echo PO $@
|
||||
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@touch $@
|
||||
|
||||
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
|
||||
@ -102,7 +107,8 @@ install-i18n: $(I18Nmsgs)
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: hello.c 2.6 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: hello.c 4.1 2018/04/10 13:00:22 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -12,7 +12,7 @@
|
||||
#include <vdr/interface.h>
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = trNOOP("A friendly greeting");
|
||||
static const char *MAINMENUENTRY = trNOOP("Hello");
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Marc Rovira Vall <tm05462@salleURL.edu>, 2003
|
||||
# Ramon Roca <ramon.roca@xcombo.com>, 2003
|
||||
@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Mogens Elneff <mogens@elneff.dk>, 2004
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Klaus Schmidinger <vdr@tvdr.de>, 2000
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Dimitrios Dimitrakos <mail@dimitrios.de>, 2002
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Ruben Nunez Francisco <ruben.nunez@tang-it.com>, 2002
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,35 +1,35 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Arthur Konovalov <kasjas@hot.ee>, 2004
|
||||
# Arthur Konovalov <artlov@gmail.com>, 2004, 2015
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
"Last-Translator: Arthur Konovalov <kasjas@hot.ee>\n"
|
||||
"Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
|
||||
"Language-Team: Estonian <vdr@linuxtv.org>\n"
|
||||
"Language: et\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-13\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "A friendly greeting"
|
||||
msgstr ""
|
||||
msgstr "Sõbralik tervitus"
|
||||
|
||||
msgid "Hello"
|
||||
msgstr ""
|
||||
msgstr "Tere"
|
||||
|
||||
msgid "Greeting time (s)"
|
||||
msgstr ""
|
||||
msgstr "Tervituse kestus (s)"
|
||||
|
||||
msgid "Use alternate greeting"
|
||||
msgstr ""
|
||||
msgstr "Vahelduv tervitus"
|
||||
|
||||
msgid "Howdy folks!"
|
||||
msgstr ""
|
||||
msgstr "Kuidas käsi käib?"
|
||||
|
||||
msgid "Hello world!"
|
||||
msgstr ""
|
||||
msgstr "Tere, maailm!"
|
||||
|
@ -1,5 +1,5 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Hannu Savolainen <hannu@opensound.com>, 2002
|
||||
# Jaakko Hyvätti <jaakko@hyvatti.iki.fi>, 2002
|
||||
@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,18 +1,19 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Jean-Claude Repetto <jc@repetto.org>, 2001
|
||||
# Olivier Jacques <jacquesolivier@hotmail.com>, 2003
|
||||
# Gregoire Favre <greg@magma.unil.ch>, 2003
|
||||
# Nicolas Huillard <nhuillard@e-dition.fr>, 2005
|
||||
# Bernard Jaulin <bernard.jaulin@gmail.com>, 2018
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
"Last-Translator: Nicolas Huillard <nhuillard@e-dition.fr>\n"
|
||||
"PO-Revision-Date: 2018-04-14 8:34+0200\n"
|
||||
"Last-Translator: Bernard Jaulin <bernard.jaulin@gmail.com>\n"
|
||||
"Language-Team: French <vdr@linuxtv.org>\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -20,19 +21,19 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "A friendly greeting"
|
||||
msgstr ""
|
||||
msgstr "Bien le bonjour"
|
||||
|
||||
msgid "Hello"
|
||||
msgstr ""
|
||||
msgstr "Hello"
|
||||
|
||||
msgid "Greeting time (s)"
|
||||
msgstr ""
|
||||
msgstr "Durée pour le salut (s)"
|
||||
|
||||
msgid "Use alternate greeting"
|
||||
msgstr ""
|
||||
msgstr "Changer de salutation"
|
||||
|
||||
msgid "Howdy folks!"
|
||||
msgstr ""
|
||||
msgstr "Bonjour à tous !"
|
||||
|
||||
msgid "Hello world!"
|
||||
msgstr ""
|
||||
msgstr "Bonjour le monde !"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Adrian Caval <anrxc@sysphere.org>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2008-03-17 19:52+0100\n"
|
||||
|
@ -1,12 +1,12 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Istvan Koenigsberger <istvnko@hotmail.com>, 2002
|
||||
# Guido Josten <guido.josten@t-online.de>, 2002
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Diego Pierotto <vdr-italian@tiscali.it>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2008-01-27 20:11+0100\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Valdemaras Pipiras <varas@ambernet.lt>, 2009
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2009-12-08 12:18+0200\n"
|
||||
|
@ -1,5 +1,5 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com>, 2001
|
||||
# Hans Dingemans <hans.dingemans@tacticalops.nl>, 2003
|
||||
@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,12 +1,12 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Jørgen Tvedt <pjtvedt@online.no>, 2001
|
||||
# Truls Slevigen <truls@slevigen.no>, 2002
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,35 +1,38 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Michael Rakowski <mrak@gmx.de>, 2002
|
||||
# Tomasz Maciej Nowak <tmn505@gmail.com>, 2018
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
"Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
|
||||
"PO-Revision-Date: 2018-02-19 00:41+0100\n"
|
||||
"Last-Translator: Tomasz Maciej Nowak <tmn505@gmail.com>\n"
|
||||
"Language-Team: Polish <vdr@linuxtv.org>\n"
|
||||
"Language: pl\n"
|
||||
"Language: pl_PL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=ISO-8859-2\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
|
||||
msgid "A friendly greeting"
|
||||
msgstr ""
|
||||
msgstr "Przyjazne pozdrowienie"
|
||||
|
||||
msgid "Hello"
|
||||
msgstr ""
|
||||
msgstr "Witaj"
|
||||
|
||||
msgid "Greeting time (s)"
|
||||
msgstr ""
|
||||
msgstr "Czas pozdrowienia (s)"
|
||||
|
||||
msgid "Use alternate greeting"
|
||||
msgstr ""
|
||||
msgstr "Użyj alternatywnego pozdrowienia"
|
||||
|
||||
msgid "Howdy folks!"
|
||||
msgstr ""
|
||||
msgstr "Siema ziomy!"
|
||||
|
||||
msgid "Hello world!"
|
||||
msgstr ""
|
||||
msgstr "Witaj świecie!"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Paulo Lopes <pmml@netvita.pt>, 2001
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,12 +1,12 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Paul Lacatus <paul@campina.iiruc.ro>, 2002
|
||||
# Lucian Muresan <lucianm@users.sourceforge.net>, 2004
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Vyacheslav Dikonov <sdiconov@mail.ru>, 2004
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Vladimír Bárta <vladimir.barta@k2atmitec.cz>, 2006
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2009-09-30 09:48+0100\n"
|
||||
|
@ -1,12 +1,12 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Miha Setina <mihasetina@softhome.net>, 2000
|
||||
# Matjaz Thaler <matjaz.thaler@guest.arnes.si>, 2003
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,12 +1,12 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Tomas Prybil <tomas@prybil.se>, 2002
|
||||
# Jan Ekholm <chakie@infa.abo.fi>, 2003
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2007-08-11 12:34+0200\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Oktay Yolgeçen <oktay_73@yahoo.de>, 2007
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2008-05-12 22:34:4800\n"
|
||||
|
@ -1,14 +1,14 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Marc Rovira Vall <tm05462@salleURL.edu>, 2003
|
||||
# Ramon Roca <ramon.roca@xcombo.com>, 2003
|
||||
# Jordi Vilà <jvila@tinet.org>, 2003
|
||||
# Nan Feng VDR <nfgx@21cn.com>, 2009.2
|
||||
# Nan Feng VDR <nfgx@21cn.com>, 2009
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-hello 0.2.5\n"
|
||||
"Project-Id-Version: vdr-hello 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"PO-Revision-Date: 2009-01-23 09:48+0800\n"
|
||||
|
@ -59,3 +59,35 @@ VDR Plugin 'osddemo' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2014-02-06: Version 2.1.2
|
||||
|
||||
- Fixed flickering if subtitles are active while the OSD demo is running.
|
||||
- Fixed a possible crash in the OSD demo (reported by Christopher Reimer).
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2015-03-08: Version 2.3.1
|
||||
|
||||
- Now using cOsd::MaxPixmapSize().
|
||||
- Fixed a vertical black line in the "TiledPixmaps" area on the rpihddevice OSD with
|
||||
1280x800 pixel (thanks to Thomas Reufer).
|
||||
- Added a demo case for storing images (thanks to Thomas Reufer).
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2020-10-12: Version 2.4.1
|
||||
|
||||
- Added test cases for alignment of semi-circles (press key '4').
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.16 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
@ -61,7 +62,8 @@ all: $(SOFILE)
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -75,7 +77,8 @@ $(DEPFILE): Makefile
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,13 +3,13 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: osddemo.c 2.12 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: osddemo.c 4.5 2020/10/14 20:32:41 kls Exp $
|
||||
*/
|
||||
|
||||
#include <vdr/osd.h>
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.1";
|
||||
static const char *DESCRIPTION = "Demo of arbitrary OSD setup";
|
||||
static const char *MAINMENUENTRY = "Osd Demo";
|
||||
|
||||
@ -90,6 +90,137 @@ void DrawSlopes(cOsd *Osd)
|
||||
Osd->Flush();
|
||||
}
|
||||
|
||||
// --- DrawImages ------------------------------------------------------------
|
||||
|
||||
struct tOsdImageRef {
|
||||
int image;
|
||||
cSize size;
|
||||
};
|
||||
|
||||
#define NUMOSDIMAGES 16
|
||||
#define NUMOSDIMAGEVARIANTS 8
|
||||
|
||||
void DrawImages(cOsd *Osd)
|
||||
{
|
||||
// Create images:
|
||||
cImage *images[NUMOSDIMAGEVARIANTS];
|
||||
for (int i = 0; i < NUMOSDIMAGEVARIANTS; i++) {
|
||||
images[i] = new cImage(cSize(
|
||||
i == 0 || i == 1 ? Osd->MaxPixmapSize().Width() + 1 : rand() % Osd->Width(),
|
||||
i == 0 || i == 2 ? Osd->MaxPixmapSize().Height() + 1 : rand() % Osd->Height()));
|
||||
for (int x = 0; x < images[i]->Width(); x++) {
|
||||
for (int y = 0; y < images[i]->Height(); y++) {
|
||||
images[i]->SetPixel(cPoint(x, y),
|
||||
(!x || !y || x == images[i]->Width() - 1 || y == images[i]->Height() - 1) ? clrWhite :
|
||||
(x > images[i]->Width() / 2 ?
|
||||
(y > images[i]->Height() / 2 ? clrBlue : clrGreen) :
|
||||
(y > images[i]->Height() / 2 ? clrRed : clrYellow)));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Store images:
|
||||
tOsdImageRef osdImages[NUMOSDIMAGES];
|
||||
for (int i = 0; i < NUMOSDIMAGES; i++) {
|
||||
osdImages[i].image = cOsdProvider::StoreImage(*images[i % NUMOSDIMAGEVARIANTS]);
|
||||
osdImages[i].size.Set(images[i % NUMOSDIMAGEVARIANTS]->Size());
|
||||
}
|
||||
// Delete images:
|
||||
for (int i = 0; i < NUMOSDIMAGEVARIANTS; i++)
|
||||
delete images[i];
|
||||
// Draw images:
|
||||
for (int i = 0; i < NUMOSDIMAGES; i++)
|
||||
Osd->DrawImage(cPoint(rand() % (Osd->Width() + osdImages[i].size.Width()), rand() % (Osd->Height() + osdImages[i].size.Height())).Shifted(-osdImages[i].size.Width(), -osdImages[i].size.Height()), osdImages[i].image);
|
||||
// Drop image references:
|
||||
for (int i = 0; i < NUMOSDIMAGES; i++)
|
||||
cOsdProvider::DropImage(osdImages[i].image);
|
||||
Osd->Flush();
|
||||
}
|
||||
|
||||
// --- DrawEllipseAlignments -------------------------------------------------
|
||||
|
||||
void DrawEllipseAlignments(cOsd *Osd)
|
||||
{
|
||||
cFont *Font = cFont::CreateFont(Setup.FontOsd, 20);
|
||||
int xa = 0;
|
||||
int ya = 0;
|
||||
int xb = Osd->Width() - 1;
|
||||
int yb = Osd->Height() - 1;
|
||||
Osd->DrawRectangle(xa, ya, xb, yb, clrBlack);
|
||||
int d = 50;
|
||||
int a = d / 2 + 1;
|
||||
int t = a * 2;
|
||||
int n = 30;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Osd->DrawRectangle(a, t, a + d - 1, t + d - 1, clrGreen);
|
||||
Osd->DrawEllipse(a, t - d / 2, a + d - 1, t, clrGreen, 6);
|
||||
Osd->DrawEllipse(a, t + d, a + d - 1, t + d + d / 2, clrGreen, 8);
|
||||
Osd->DrawText(a + d / 3, t + d / 3, itoa(d), clrRed, clrGreen, Font);
|
||||
a += d + 5;
|
||||
d++;
|
||||
}
|
||||
d = 50;
|
||||
a = d * 3;
|
||||
n = 20;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Osd->DrawRectangle(t, a, t + d - 1, a + d - 1, clrGreen);
|
||||
Osd->DrawEllipse(t - d / 2, a, t, a + d - 1, clrGreen, 7);
|
||||
Osd->DrawEllipse(t + d, a, t + d + d / 2, a + d - 1, clrGreen, 5);
|
||||
Osd->DrawText(t + d / 3, a + d / 3, itoa(d), clrRed, clrGreen, Font);
|
||||
a += d + 5;
|
||||
d++;
|
||||
}
|
||||
d = 50;
|
||||
a = d * 3;
|
||||
t = d * 5;
|
||||
n = 30;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Osd->DrawRectangle(a, t, a + d - 1, t + d - 1, clrGreen);
|
||||
Osd->DrawEllipse(a, t - d, a + d - 1, t, clrGreen, 2);
|
||||
Osd->DrawEllipse(a, t + d, a + d - 1, t + d + d, clrGreen, 3);
|
||||
Osd->DrawText(a + d / 3, t + d / 3, itoa(d), clrRed, clrGreen, Font);
|
||||
a += d + 5;
|
||||
d++;
|
||||
}
|
||||
d = 50;
|
||||
a = d * 3;
|
||||
t = d * 9;
|
||||
n = 30;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Osd->DrawRectangle(a, t, a + d - 1, t + d - 1, clrGreen);
|
||||
Osd->DrawEllipse(a, t - d, a + d - 1, t, clrGreen, 1);
|
||||
Osd->DrawEllipse(a, t + d, a + d - 1, t + d + d, clrGreen, 4);
|
||||
Osd->DrawText(a + d / 3, t + d / 3, itoa(d), clrRed, clrGreen, Font);
|
||||
a += d + 5;
|
||||
d++;
|
||||
}
|
||||
d = 50;
|
||||
a = d * 12;
|
||||
t = d * 5;
|
||||
n = 20;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Osd->DrawRectangle(t, a, t + d - 1, a + d - 1, clrGreen);
|
||||
Osd->DrawEllipse(t - d, a, t, a + d - 1, clrGreen, 2);
|
||||
Osd->DrawEllipse(t + d, a, t + d + d, a + d - 1, clrGreen, 1);
|
||||
Osd->DrawText(t + d / 3, a + d / 3, itoa(d), clrRed, clrGreen, Font);
|
||||
a += d + 5;
|
||||
d++;
|
||||
}
|
||||
d = 50;
|
||||
a = d * 12;
|
||||
t = d * 9;
|
||||
n = 20;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Osd->DrawRectangle(t, a, t + d - 1, a + d - 1, clrGreen);
|
||||
Osd->DrawEllipse(t - d, a, t, a + d - 1, clrGreen, 3);
|
||||
Osd->DrawEllipse(t + d, a, t + d + d, a + d - 1, clrGreen, 4);
|
||||
Osd->DrawText(t + d / 3, a + d / 3, itoa(d), clrRed, clrGreen, Font);
|
||||
a += d + 5;
|
||||
d++;
|
||||
}
|
||||
Osd->Flush();
|
||||
delete Font;
|
||||
}
|
||||
|
||||
// --- cLineGame -------------------------------------------------------------
|
||||
|
||||
class cLineGame : public cOsdObject {
|
||||
@ -119,7 +250,7 @@ cLineGame::~cLineGame()
|
||||
|
||||
void cLineGame::Show(void)
|
||||
{
|
||||
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop(), 50);
|
||||
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
|
||||
if (osd) {
|
||||
int x1 = cOsd::OsdWidth() - 1;
|
||||
int y1 = cOsd::OsdHeight() - 1;
|
||||
@ -210,7 +341,7 @@ cPixmap *cTrueColorDemo::CreateTextPixmap(const char *s, int Line, int Layer, tC
|
||||
if (Pixmap) {
|
||||
Pixmap->Clear();
|
||||
Pixmap->SetAlpha(0);
|
||||
Pixmap->DrawText(cPoint(0, 0), s, ColorFg, ColorBg, Font);
|
||||
Pixmap->DrawText(cPoint(0, 0), s, ColorFg, ColorBg, Font, w);
|
||||
}
|
||||
return Pixmap;
|
||||
}
|
||||
@ -427,16 +558,20 @@ void cTrueColorDemo::Action(void)
|
||||
const int Size = SmlFont->Width(Text) + 10;
|
||||
const int NumDots = 12;
|
||||
const int AnimFrames = NumDots;
|
||||
int Rows = min(osd->MaxPixmapSize().Height() / Size, AnimFrames);
|
||||
int Cols = (AnimFrames + Rows - 1) / Rows;
|
||||
// Temporarily using pixmap layer 0 to have the text alpha blended:
|
||||
AnimPixmap = osd->CreatePixmap(0, cRect((osd->Width() - Size) / 2, StartLine, Size, Size), cRect(0, 0, Size, Size * AnimFrames));
|
||||
AnimPixmap = osd->CreatePixmap(0, cRect((osd->Width() - Size) / 2, StartLine, Size, Size), cRect(0, 0, Size * Cols, Size * Rows));
|
||||
if (AnimPixmap) {
|
||||
AnimPixmap->SetAlpha(0);
|
||||
AnimPixmap->Clear();
|
||||
const int Diameter = Size / 5;
|
||||
int xc = Size / 2 - Diameter / 2;
|
||||
for (int Frame = 0; Frame < AnimFrames; Frame++) {
|
||||
AnimPixmap->DrawEllipse(cRect(0, Frame * Size, Size, Size), 0xDDFFFFFF);
|
||||
int yc = Frame * Size + Size / 2 - Diameter / 2;
|
||||
int x0 = Frame / Rows * Size;
|
||||
int y0 = Frame % Rows * Size;
|
||||
AnimPixmap->DrawEllipse(cRect(x0, y0, Size, Size), 0xDDFFFFFF);
|
||||
int xc = x0 + Size / 2 - Diameter / 2;
|
||||
int yc = y0 + Size / 2 - Diameter / 2;
|
||||
int Color = 0xFF;
|
||||
int Delta = Color / NumDots / 3;
|
||||
for (int a = 0; a < NumDots; a++) {
|
||||
@ -446,7 +581,7 @@ void cTrueColorDemo::Action(void)
|
||||
AnimPixmap->DrawEllipse(cRect(x, y, Diameter, Diameter), ArgbToColor(0xFF, Color, Color, Color));
|
||||
Color -= Delta;
|
||||
}
|
||||
AnimPixmap->DrawText(cPoint(0, Frame * Size), Text, clrBlack, clrTransparent, SmlFont, Size, Size, taCenter);
|
||||
AnimPixmap->DrawText(cPoint(x0, y0), Text, clrBlack, clrTransparent, SmlFont, Size, Size, taCenter);
|
||||
}
|
||||
AnimPixmap->SetLayer(3); // now setting the actual pixmap layer
|
||||
FadeInPixmap = AnimPixmap;
|
||||
@ -480,6 +615,8 @@ void cTrueColorDemo::Action(void)
|
||||
if (Delta < FrameTime)
|
||||
cCondWait::SleepMs(FrameTime - Delta);
|
||||
}
|
||||
destroyablePixmap = NULL;
|
||||
toggleablePixmap = NULL;
|
||||
delete OsdFont;
|
||||
delete SmlFont;
|
||||
delete LrgFont;
|
||||
@ -496,7 +633,7 @@ bool cTrueColorDemo::SetArea(void)
|
||||
|
||||
void cTrueColorDemo::Show(void)
|
||||
{
|
||||
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop(), 50);
|
||||
osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
|
||||
if (osd) {
|
||||
if (SetArea()) {
|
||||
osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, clrGray50);
|
||||
@ -534,6 +671,14 @@ eOSState cTrueColorDemo::ProcessKey(eKeys Key)
|
||||
SetArea();
|
||||
DrawSlopes(osd);
|
||||
break;
|
||||
case k3: Cancel(3);
|
||||
SetArea();
|
||||
DrawImages(osd);
|
||||
break;
|
||||
case k4: Cancel(3);
|
||||
SetArea();
|
||||
DrawEllipseAlignments(osd);
|
||||
return osContinue;
|
||||
case kBack:
|
||||
case kOk: return osEnd;
|
||||
default: return state;
|
||||
|
@ -87,3 +87,36 @@ VDR Plugin 'pictures' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2013-07-01:
|
||||
|
||||
- Added option -x to pic2mpg.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2015-07-23: Version 2.3.1
|
||||
|
||||
- Added a missing 'const'.
|
||||
|
||||
2017-10-06: Version 2.3.2
|
||||
|
||||
- Adapted the pic2mpg script to new ffmpeg options.
|
||||
- No longer using 'convert' to scale/rotate the pictures.
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2022-12-05: Version 2.6.1
|
||||
|
||||
Fixed initializing cPictureControl.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.18 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
LOCDIR = $(call PKGCFG,locdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
@ -62,7 +63,8 @@ all: $(SOFILE) i18n
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -82,13 +84,16 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU
|
||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||
|
||||
%.mo: %.po
|
||||
msgfmt -c -o $@ $<
|
||||
@echo MO $@
|
||||
$(Q)msgfmt -c -o $@ $<
|
||||
|
||||
$(I18Npot): $(wildcard *.c)
|
||||
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||
@echo GT $@
|
||||
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||
|
||||
%.po: $(I18Npot)
|
||||
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@echo PO $@
|
||||
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@touch $@
|
||||
|
||||
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
|
||||
@ -102,7 +107,8 @@ install-i18n: $(I18Nmsgs)
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: menu.c 1.1 2008/01/13 11:35:18 kls Exp $
|
||||
* $Id: menu.c 4.1 2015/07/17 10:13:56 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -85,7 +85,7 @@ eOSState cPictureMenu::SelectItem(const char *Path, bool SlideShow)
|
||||
if (Item) {
|
||||
const cList<cPictureEntry> *l = pictureEntry->Entries();
|
||||
if (l) {
|
||||
cPictureEntry *pe = l->Get(Current());
|
||||
const cPictureEntry *pe = l->Get(Current());
|
||||
if (pe) {
|
||||
if (SlideShow) {
|
||||
cControl::Launch(new cPictureControl(pictures, pe, true));
|
||||
|
@ -7,7 +7,7 @@
|
||||
#
|
||||
# See the README file for copyright information and how to reach the author.
|
||||
#
|
||||
# $Id: pic2mpg 2.5 2013/02/17 13:17:13 kls Exp $
|
||||
# $Id: pic2mpg 4.1 2017/10/06 14:42:18 kls Exp $
|
||||
|
||||
use File::Path;
|
||||
use File::Spec;
|
||||
@ -23,9 +23,10 @@ Options: -f Force conversion
|
||||
-o percent overscan in percent
|
||||
-s size Screen size (WIDTHxHEIGHT, default is 1920x1080)
|
||||
-v num Verbose (0=none, 1=list files, 2=detailed)
|
||||
-x dir[,...] eXclude the given directories
|
||||
};
|
||||
|
||||
getopts("fho:s:v:") || die $Usage;
|
||||
getopts("fho:s:v:x:") || die $Usage;
|
||||
|
||||
die $Usage if $opt_h;
|
||||
|
||||
@ -33,6 +34,7 @@ $Force = $opt_f;
|
||||
$Overscan = $opt_o || 0;
|
||||
$Size = $opt_s || "1920x1080";
|
||||
$Verbose = $opt_v;
|
||||
@Exclude = split(',', $opt_x || "");
|
||||
|
||||
$ListFiles = $Verbose >= 1;
|
||||
$Detailed = $Verbose >= 2;
|
||||
@ -85,7 +87,11 @@ chdir($PICDIR) || die "$PICDIR: $!\n";
|
||||
@Pictures = `find -type f | sort`;
|
||||
chomp(@Pictures);
|
||||
|
||||
PIC:
|
||||
for $pic (@Pictures) {
|
||||
for (@Exclude) {
|
||||
next PIC if ($pic =~ /\/$_\//);
|
||||
}
|
||||
my $mpg = "$MPGDIR/$pic.mpg";
|
||||
if ($Force || !-e $mpg || -M $mpg > -M $pic) {
|
||||
(my $dir = $mpg) =~ s/\/[^\/]*$//;
|
||||
@ -122,7 +128,7 @@ for ($i = 0; $i < 10; $i++) { # dirs might become empty when removing empty subd
|
||||
for $dir (@Dirs) {
|
||||
$dir = EscapeMeta($dir);
|
||||
print "removing $dir\n";
|
||||
!system("rm -rf $dir") || die "$dir: $!\n";
|
||||
Exec("rm -rf $dir");
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,17 +142,18 @@ sub ConvertFile
|
||||
my $Exif = ImageInfo($Pict);
|
||||
my $Orientation = $$Exif{"Orientation"};
|
||||
my ($Degrees) = $Orientation =~ /Rotate ([0-9]+)/;
|
||||
my $Rotate = $Degrees ? "-rotate $Degrees" : "";
|
||||
my $Rotate = ($Degrees == 90) ? "transpose=clock" : ($Degrees == 180) ? "hflip,vflip" : ($Degrees == 270) ? "transpose=cclock" : "";
|
||||
$Rotate .= ',' if ($Rotate);
|
||||
my $Background = '#000000@1';
|
||||
print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed);
|
||||
$Pict = EscapeMeta($Pict);
|
||||
$Mpeg = EscapeMeta($Mpeg);
|
||||
print "$Pict -> $Mpeg $Rotate\n" if $ListFiles;
|
||||
my $Cmd = "convert $Pict -background '#000000' $Rotate -resize $Size -gravity center -extent $Extent ppm:- | "
|
||||
. "ffmpeg -f image2pipe -vcodec ppm -i pipe:0 -an -vcodec libx264 -vpre baseline -s $Size -qscale 2 -f mpegts -y $Mpeg "
|
||||
my $Cmd = "ffmpeg -i $Pict -vf '${Rotate}scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:$Background' -c:v libx264 -pix_fmt yuv420p -f mpegts -y $Mpeg "
|
||||
. ($Detailed ? "" : "2>/dev/null");
|
||||
!system($Cmd) || die "$Cmd: $!\n";
|
||||
Exec($Cmd);
|
||||
$Cmd = "touch -r $Pict $Mpeg";
|
||||
!system($Cmd) || die "$Cmd: $!\n";
|
||||
Exec($Cmd);
|
||||
}
|
||||
|
||||
sub EscapeMeta
|
||||
@ -156,3 +163,10 @@ sub EscapeMeta
|
||||
$s =~ s/([$META])/\\$1/g;
|
||||
return $s;
|
||||
}
|
||||
|
||||
sub Exec
|
||||
{
|
||||
my $Cmd = shift;
|
||||
print "==> '$Cmd'\n" if ($Verbose);
|
||||
!system($Cmd) || die "$Cmd: $!\n";
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: pictures.c 2.9 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: pictures.c 5.1 2022/12/05 15:26:23 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -11,7 +11,7 @@
|
||||
#include "menu.h"
|
||||
#include "player.h"
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.6.1";
|
||||
static const char *DESCRIPTION = trNOOP("A simple picture viewer");
|
||||
static const char *MAINMENUENTRY = trNOOP("Pictures");
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: player.c 2.2 2012/04/28 11:58:15 kls Exp $
|
||||
* $Id: player.c 5.1 2022/12/05 15:26:23 kls Exp $
|
||||
*/
|
||||
|
||||
#include "player.h"
|
||||
@ -96,8 +96,10 @@ int cPictureControl::active = 0;
|
||||
cString cPictureControl::lastDisplayed;
|
||||
|
||||
cPictureControl::cPictureControl(cPictureEntry *Pictures, const cPictureEntry *PictureEntry, bool SlideShow)
|
||||
:cControl(player = new cPicturePlayer)
|
||||
:cControl(NULL)
|
||||
{
|
||||
player = new cPicturePlayer;
|
||||
SetPlayer(player);
|
||||
pictures = Pictures;
|
||||
pictureEntry = PictureEntry;
|
||||
osd = NULL;
|
||||
@ -211,7 +213,7 @@ cString cPictureControl::GetHeader(void)
|
||||
|
||||
eOSState cPictureControl::ProcessKey(eKeys Key)
|
||||
{
|
||||
switch (Key) {
|
||||
switch (int(Key)) {
|
||||
case kUp:
|
||||
case kPlay: slideShowDelay.Set();
|
||||
slideShow = true;
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Klaus Schmidinger <vdr@tvdr.de>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2008-01-12 17:41+0100\n"
|
||||
|
33
PLUGINS/src/pictures/po/et_EE.po
Normal file
33
PLUGINS/src/pictures/po/et_EE.po
Normal file
@ -0,0 +1,33 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Arthur Konovalov <artlov@gmail.com>, 2015
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2008-01-12 17:41+0100\n"
|
||||
"Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
|
||||
"Language-Team: Estonian <vdr@linuxtv.org>\n"
|
||||
"Language: et\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Pictures"
|
||||
msgstr "Pildid"
|
||||
|
||||
msgid "A simple picture viewer"
|
||||
msgstr "Lihtne pildivaatur"
|
||||
|
||||
msgid "Picture directory"
|
||||
msgstr "Pildikaust"
|
||||
|
||||
msgid "Slide show delay (s)"
|
||||
msgstr "Slaidiseanssi viide (s)"
|
||||
|
||||
msgid "No picture directory has been defined!"
|
||||
msgstr "Pildikaust on määramata!"
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2008-01-12 17:41+0100\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Patrice Staudt <patrice.staudt@laposte.net>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2008-01-12 17:41+0100\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Diego Pierotto <vdr-italian@tiscali.it>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2008-01-27 20:22+0100\n"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Valdemaras Pipiras <varas@ambernet.lt>, 2009
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2009-12-08 12:41+0100\n"
|
||||
|
34
PLUGINS/src/pictures/po/pl_PL.po
Normal file
34
PLUGINS/src/pictures/po/pl_PL.po
Normal file
@ -0,0 +1,34 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Tomasz Maciej Nowak <tmn505@gmail.com>, 2018
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2018-02-19 00:48+0100\n"
|
||||
"PO-Revision-Date: 2018-02-19 00:53+0100\n"
|
||||
"Last-Translator: Tomasz Maciej Nowak <tmn505@gmail.com>\n"
|
||||
"Language-Team: Polish <vdr@linuxtv.org>\n"
|
||||
"Language: pl_PL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
|
||||
msgid "Pictures"
|
||||
msgstr "Zdjęcia"
|
||||
|
||||
msgid "A simple picture viewer"
|
||||
msgstr "Prosta przeglądarka zdjęć"
|
||||
|
||||
msgid "Picture directory"
|
||||
msgstr "Katalog ze zdjęciami"
|
||||
|
||||
msgid "Slide show delay (s)"
|
||||
msgstr "Pokaz slajdów opóźnienie (s)"
|
||||
|
||||
msgid "No picture directory has been defined!"
|
||||
msgstr "Nie zdefiniowano katalogu ze zdjęciami!"
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Alexander Gross <Bikalexander@gmail.com>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2008-03-14 00:45+0100\n"
|
||||
@ -28,7 +28,7 @@ msgid "Picture directory"
|
||||
msgstr "ºÐâÐÛÞÓ Ø×ÞÑàÐÖÕÝØÙ"
|
||||
|
||||
msgid "Slide show delay (s)"
|
||||
msgstr "·ÐÔÕàÖÚÐ áÛÐÙÔ-èÞã (áÕÚ)"
|
||||
msgstr "·ÐÔÕàÖÚÐ áÛÐÙÔ-èÞã (áÕÚ)"
|
||||
|
||||
msgid "No picture directory has been defined!"
|
||||
msgstr "½Õ ÞßàÕÔÕÛñÝ ÚÐâÐÛÞÓ Ø×ÞÑàÐÖÕÝØÙ!"
|
||||
|
@ -1,11 +1,11 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Klaus Schmidinger <vdr@tvdr.de>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-pictures 0.1.3\n"
|
||||
"Project-Id-Version: vdr-pictures 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 12:57+0100\n"
|
||||
"PO-Revision-Date: 2009-09-30 12:54+0100\n"
|
||||
|
@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
@ -1,22 +0,0 @@
|
||||
VDR Plugin 'rcu' Revision History
|
||||
---------------------------------
|
||||
|
||||
2012-02-27: Version 0.0.1
|
||||
|
||||
- Initial revision.
|
||||
|
||||
2012-03-07: Version 0.0.2
|
||||
|
||||
- Added new parameter LiveView to ChannelSwitch().
|
||||
|
||||
2012-12-27: Version 0.0.3
|
||||
|
||||
- Adapted Makefile to changes introduced in recent VDR versions.
|
||||
|
||||
2013-01-12: Version 0.0.4
|
||||
|
||||
- Adapted Makefile to changes introduced in recent VDR versions.
|
||||
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
@ -1,94 +0,0 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 1.13 2013/01/12 13:45:01 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
# By default the main source file also carries this name.
|
||||
|
||||
PLUGIN = rcu
|
||||
|
||||
### The version number of this plugin (taken from the main source file):
|
||||
|
||||
VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
|
||||
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
TMPDIR ?= /tmp
|
||||
|
||||
### The compiler options:
|
||||
|
||||
export CFLAGS = $(call PKGCFG,cflags)
|
||||
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
||||
|
||||
### The version number of VDR's plugin API:
|
||||
|
||||
APIVERSION = $(call PKGCFG,apiversion)
|
||||
|
||||
### Allow user defined options to overwrite defaults:
|
||||
|
||||
-include $(PLGCFG)
|
||||
|
||||
### The name of the distribution archive:
|
||||
|
||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||
PACKAGE = vdr-$(ARCHIVE)
|
||||
|
||||
### The name of the shared object file:
|
||||
|
||||
SOFILE = libvdr-$(PLUGIN).so
|
||||
|
||||
### Includes and Defines (add further entries here):
|
||||
|
||||
INCLUDES +=
|
||||
|
||||
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
||||
|
||||
### The object files (add further files here):
|
||||
|
||||
OBJS = $(PLUGIN).o
|
||||
|
||||
### The main target:
|
||||
|
||||
all: $(SOFILE)
|
||||
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
MAKEDEP = $(CXX) -MM -MG
|
||||
DEPFILE = .dependencies
|
||||
$(DEPFILE): Makefile
|
||||
@$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
|
||||
|
||||
-include $(DEPFILE)
|
||||
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
||||
install: install-lib
|
||||
|
||||
dist: clean
|
||||
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
||||
@mkdir $(TMPDIR)/$(ARCHIVE)
|
||||
@cp -a * $(TMPDIR)/$(ARCHIVE)
|
||||
@tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
|
||||
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
||||
@echo Distribution package created as $(PACKAGE).tgz
|
||||
|
||||
clean:
|
||||
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
@ -1,19 +0,0 @@
|
||||
This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de/remote.htm
|
||||
|
||||
Latest version available at: http://www.tvdr.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.
|
||||
See the file COPYING for more information.
|
||||
|
||||
Description:
|
||||
============
|
||||
|
||||
The "Remote Control Unit" used to be part of the core VDR source
|
||||
code, and has been moved into a separate plugin in version 1.7.25.
|
@ -1,420 +0,0 @@
|
||||
/*
|
||||
* rcu.c: A plugin for the Video Disk Recorder
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: rcu.c 1.5 2013/03/31 09:30:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <vdr/plugin.h>
|
||||
#include <vdr/remote.h>
|
||||
#include <vdr/status.h>
|
||||
#include <vdr/thread.h>
|
||||
#include <vdr/tools.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *DESCRIPTION = "Remote Control Unit";
|
||||
|
||||
#define REPEATLIMIT 150 // ms
|
||||
#define REPEATDELAY 350 // ms
|
||||
#define HANDSHAKETIMEOUT 20 // ms
|
||||
#define DEFAULTDEVICE "/dev/ttyS1"
|
||||
|
||||
class cRcuRemote : public cRemote, private cThread, private cStatus {
|
||||
private:
|
||||
enum { modeH = 'h', modeB = 'b', modeS = 's' };
|
||||
int f;
|
||||
unsigned char dp, code, mode;
|
||||
int number;
|
||||
unsigned int data;
|
||||
bool receivedCommand;
|
||||
bool SendCommand(unsigned char Cmd);
|
||||
int ReceiveByte(int TimeoutMs = 0);
|
||||
bool SendByteHandshake(unsigned char c);
|
||||
bool SendByte(unsigned char c);
|
||||
bool SendData(unsigned int n);
|
||||
void SetCode(unsigned char Code);
|
||||
void SetMode(unsigned char Mode);
|
||||
void SetNumber(int n, bool Hex = false);
|
||||
void SetPoints(unsigned char Dp, bool On);
|
||||
void SetString(const char *s);
|
||||
bool DetectCode(unsigned char *Code);
|
||||
virtual void Action(void);
|
||||
virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView);
|
||||
virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On);
|
||||
public:
|
||||
cRcuRemote(const char *DeviceName);
|
||||
virtual ~cRcuRemote();
|
||||
virtual bool Ready(void);
|
||||
virtual bool Initialize(void);
|
||||
};
|
||||
|
||||
cRcuRemote::cRcuRemote(const char *DeviceName)
|
||||
:cRemote("RCU")
|
||||
,cThread("RCU remote control")
|
||||
{
|
||||
dp = 0;
|
||||
mode = modeB;
|
||||
code = 0;
|
||||
number = 0;
|
||||
data = 0;
|
||||
receivedCommand = false;
|
||||
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
||||
struct termios t;
|
||||
if (tcgetattr(f, &t) == 0) {
|
||||
cfsetspeed(&t, B9600);
|
||||
cfmakeraw(&t);
|
||||
if (tcsetattr(f, TCSAFLUSH, &t) == 0) {
|
||||
SetNumber(8888);
|
||||
const char *Setup = GetSetup();
|
||||
if (Setup) {
|
||||
code = *Setup;
|
||||
SetCode(code);
|
||||
isyslog("connecting to %s remote control using code %c", Name(), code);
|
||||
}
|
||||
Start();
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG_ERROR_STR(DeviceName);
|
||||
close(f);
|
||||
}
|
||||
else
|
||||
LOG_ERROR_STR(DeviceName);
|
||||
f = -1;
|
||||
}
|
||||
|
||||
cRcuRemote::~cRcuRemote()
|
||||
{
|
||||
Cancel();
|
||||
}
|
||||
|
||||
bool cRcuRemote::Ready(void)
|
||||
{
|
||||
return f >= 0;
|
||||
}
|
||||
|
||||
bool cRcuRemote::Initialize(void)
|
||||
{
|
||||
if (f >= 0) {
|
||||
unsigned char Code = '0';
|
||||
isyslog("trying codes for %s remote control...", Name());
|
||||
for (;;) {
|
||||
if (DetectCode(&Code)) {
|
||||
code = Code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
isyslog("established connection to %s remote control using code %c", Name(), code);
|
||||
char buffer[16];
|
||||
snprintf(buffer, sizeof(buffer), "%c", code);
|
||||
PutSetup(buffer);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cRcuRemote::Action(void)
|
||||
{
|
||||
#pragma pack(1)
|
||||
union {
|
||||
struct {
|
||||
unsigned short address;
|
||||
unsigned int command;
|
||||
} data;
|
||||
unsigned char raw[6];
|
||||
} buffer;
|
||||
#pragma pack()
|
||||
|
||||
time_t LastCodeRefresh = 0;
|
||||
cTimeMs FirstTime;
|
||||
unsigned char LastCode = 0, LastMode = 0;
|
||||
uint64_t LastCommand = ~0; // 0x00 might be a valid command
|
||||
unsigned int LastData = 0;
|
||||
bool repeat = false;
|
||||
|
||||
while (Running() && f >= 0) {
|
||||
if (ReceiveByte(REPEATLIMIT) == 'X') {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int b = ReceiveByte();
|
||||
if (b >= 0) {
|
||||
buffer.raw[i] = b;
|
||||
if (i == 5) {
|
||||
unsigned short Address = ntohs(buffer.data.address); // the PIC sends bytes in "network order"
|
||||
uint64_t Command = ntohl(buffer.data.command);
|
||||
if (code == 'B' && Address == 0x0000 && Command == 0x00004000)
|
||||
// Well, well, if it isn't the "d-box"...
|
||||
// This remote control sends the above command before and after
|
||||
// each keypress - let's just drop this:
|
||||
break;
|
||||
Command |= uint64_t(Address) << 32;
|
||||
if (Command != LastCommand) {
|
||||
LastCommand = Command;
|
||||
repeat = false;
|
||||
FirstTime.Set();
|
||||
}
|
||||
else {
|
||||
if (FirstTime.Elapsed() < REPEATDELAY)
|
||||
break; // repeat function kicks in after a short delay
|
||||
repeat = true;
|
||||
}
|
||||
Put(Command, repeat);
|
||||
receivedCommand = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (repeat) { // the last one was a repeat, so let's generate a release
|
||||
Put(LastCommand, false, true);
|
||||
repeat = false;
|
||||
LastCommand = ~0;
|
||||
}
|
||||
else {
|
||||
unsigned int d = data;
|
||||
if (d != LastData) {
|
||||
SendData(d);
|
||||
LastData = d;
|
||||
}
|
||||
unsigned char c = code;
|
||||
if (c != LastCode) {
|
||||
SendCommand(c);
|
||||
LastCode = c;
|
||||
}
|
||||
unsigned char m = mode;
|
||||
if (m != LastMode) {
|
||||
SendCommand(m);
|
||||
LastMode = m;
|
||||
}
|
||||
LastCommand = ~0;
|
||||
}
|
||||
if (!repeat && code && time(NULL) - LastCodeRefresh > 60) {
|
||||
SendCommand(code); // in case the PIC listens to the wrong code
|
||||
LastCodeRefresh = time(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cRcuRemote::ReceiveByte(int TimeoutMs)
|
||||
{
|
||||
// Returns the byte if one was received within a timeout, -1 otherwise
|
||||
if (cFile::FileReady(f, TimeoutMs)) {
|
||||
unsigned char b;
|
||||
if (safe_read(f, &b, 1) == 1)
|
||||
return b;
|
||||
else
|
||||
LOG_ERROR;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool cRcuRemote::SendByteHandshake(unsigned char c)
|
||||
{
|
||||
if (f >= 0) {
|
||||
int w = write(f, &c, 1);
|
||||
if (w == 1) {
|
||||
for (int reply = ReceiveByte(HANDSHAKETIMEOUT); reply >= 0;) {
|
||||
if (reply == c)
|
||||
return true;
|
||||
else if (reply == 'X') {
|
||||
// skip any incoming RC code - it will come again
|
||||
for (int i = 6; i--;) {
|
||||
if (ReceiveByte() < 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
LOG_ERROR;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cRcuRemote::SendByte(unsigned char c)
|
||||
{
|
||||
for (int retry = 5; retry--;) {
|
||||
if (SendByteHandshake(c))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cRcuRemote::SendData(unsigned int n)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!SendByte(n & 0x7F))
|
||||
return false;
|
||||
n >>= 8;
|
||||
}
|
||||
return SendCommand(mode);
|
||||
}
|
||||
|
||||
void cRcuRemote::SetCode(unsigned char Code)
|
||||
{
|
||||
code = Code;
|
||||
}
|
||||
|
||||
void cRcuRemote::SetMode(unsigned char Mode)
|
||||
{
|
||||
mode = Mode;
|
||||
}
|
||||
|
||||
bool cRcuRemote::SendCommand(unsigned char Cmd)
|
||||
{
|
||||
return SendByte(Cmd | 0x80);
|
||||
}
|
||||
|
||||
void cRcuRemote::SetNumber(int n, bool Hex)
|
||||
{
|
||||
number = n;
|
||||
if (!Hex) {
|
||||
char buf[8];
|
||||
sprintf(buf, "%4d", n & 0xFFFF);
|
||||
n = 0;
|
||||
for (char *d = buf; *d; d++) {
|
||||
if (*d == ' ')
|
||||
*d = 0xF;
|
||||
n = (n << 4) | ((*d - '0') & 0x0F);
|
||||
}
|
||||
}
|
||||
unsigned int m = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
m <<= 8;
|
||||
m |= ((i & 0x03) << 5) | (n & 0x0F) | (((dp >> i) & 0x01) << 4);
|
||||
n >>= 4;
|
||||
}
|
||||
data = m;
|
||||
}
|
||||
|
||||
void cRcuRemote::SetString(const char *s)
|
||||
{
|
||||
const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
|
||||
int n = 0;
|
||||
|
||||
for (int i = 0; *s && i < 4; s++, i++) {
|
||||
n <<= 4;
|
||||
for (const char *c = chars; *c; c++) {
|
||||
if (*c == *s) {
|
||||
n |= c - chars;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetNumber(n, true);
|
||||
}
|
||||
|
||||
void cRcuRemote::SetPoints(unsigned char Dp, bool On)
|
||||
{
|
||||
if (On)
|
||||
dp |= Dp;
|
||||
else
|
||||
dp &= ~Dp;
|
||||
SetNumber(number);
|
||||
}
|
||||
|
||||
bool cRcuRemote::DetectCode(unsigned char *Code)
|
||||
{
|
||||
// Caller should initialize 'Code' to 0 and call DetectCode()
|
||||
// until it returns true. Whenever DetectCode() returns false
|
||||
// and 'Code' is not 0, the caller can use 'Code' to display
|
||||
// a message like "Trying code '%c'". If false is returned and
|
||||
// 'Code' is 0, all possible codes have been tried and the caller
|
||||
// can either stop calling DetectCode() (and give some error
|
||||
// message), or start all over again.
|
||||
if (*Code < 'A' || *Code > 'D') {
|
||||
*Code = 'A';
|
||||
return false;
|
||||
}
|
||||
if (*Code <= 'D') {
|
||||
SetMode(modeH);
|
||||
char buf[5];
|
||||
sprintf(buf, "C0D%c", *Code);
|
||||
SetString(buf);
|
||||
SetCode(*Code);
|
||||
cCondWait::SleepMs(2 * REPEATDELAY);
|
||||
if (receivedCommand) {
|
||||
SetMode(modeB);
|
||||
SetString("----");
|
||||
return true;
|
||||
}
|
||||
if (*Code < 'D') {
|
||||
(*Code)++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*Code = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView)
|
||||
{
|
||||
if (ChannelNumber && LiveView)
|
||||
SetNumber(cDevice::CurrentChannel());
|
||||
}
|
||||
|
||||
void cRcuRemote::Recording(const cDevice *Device, const char *Name, const char *FileName, bool On)
|
||||
{
|
||||
SetPoints(1 << Device->DeviceNumber(), Device->Receiving());
|
||||
}
|
||||
|
||||
class cPluginRcu : public cPlugin {
|
||||
private:
|
||||
// Add any member variables or functions you may need here.
|
||||
const char *device;
|
||||
public:
|
||||
cPluginRcu(void);
|
||||
virtual const char *Version(void) { return VERSION; }
|
||||
virtual const char *Description(void) { return DESCRIPTION; }
|
||||
virtual const char *CommandLineHelp(void);
|
||||
virtual bool ProcessArgs(int argc, char *argv[]);
|
||||
virtual bool Start(void);
|
||||
};
|
||||
|
||||
cPluginRcu::cPluginRcu(void)
|
||||
{
|
||||
// Initialize any member variables here.
|
||||
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
|
||||
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
||||
device = DEFAULTDEVICE;
|
||||
}
|
||||
|
||||
const char *cPluginRcu::CommandLineHelp(void)
|
||||
{
|
||||
// Return a string that describes all known command line options.
|
||||
return " -d DEV, --device=DEV set the device to use (default is " DEFAULTDEVICE ")\n";
|
||||
}
|
||||
|
||||
bool cPluginRcu::ProcessArgs(int argc, char *argv[])
|
||||
{
|
||||
// Implement command line argument processing here if applicable.
|
||||
static struct option long_options[] = {
|
||||
{ "dev", required_argument, NULL, 'd' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "d:", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'd': device = optarg;
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cPluginRcu::Start(void)
|
||||
{
|
||||
// Start any background activities the plugin shall perform.
|
||||
new cRcuRemote(device);
|
||||
return true;
|
||||
}
|
||||
|
||||
VDRPLUGINCREATOR(cPluginRcu); // Don't touch this!
|
@ -21,3 +21,19 @@ VDR Plugin 'servicedemo' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.14 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -17,7 +17,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN1).c | awk '{ pr
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
@ -58,7 +59,8 @@ all: libvdr-$(PLUGIN1).so libvdr-$(PLUGIN2).so
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -72,10 +74,12 @@ $(DEPFILE): Makefile
|
||||
### Targets:
|
||||
|
||||
libvdr-$(PLUGIN1).so: $(PLUGIN1).o
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN1).o -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN1).o -o $@
|
||||
|
||||
libvdr-$(PLUGIN2).so: $(PLUGIN2).o
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN2).o -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(PLUGIN2).o -o $@
|
||||
|
||||
install-lib: libvdr-$(PLUGIN1).so libvdr-$(PLUGIN2).so
|
||||
install -D libvdr-$(PLUGIN1).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN1).so.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Udo Richter <udo_richter@gmx.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,14 +3,14 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: svccli.c 2.4 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: svccli.c 4.1 2018/04/10 13:00:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vdr/interface.h>
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "Service demo client";
|
||||
static const char *MAINMENUENTRY = "Service demo";
|
||||
|
||||
|
@ -3,14 +3,14 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: svcsvr.c 2.4 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: svcsvr.c 4.1 2018/04/10 13:00:57 kls Exp $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vdr/interface.h>
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "Service demo server";
|
||||
|
||||
class cPluginSvcSvr : public cPlugin {
|
||||
|
@ -118,3 +118,46 @@ VDR Plugin 'skincurses' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-08: Version 2.1.2
|
||||
|
||||
- Added a missing trailing blank in some translations.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2016-12-22: Version 2.3.2
|
||||
|
||||
- Added cFont::Width(void) to get the default character width and allow stretched
|
||||
font drawing in high level OSDs (dummy for skincurses).
|
||||
- Fixed truncated date/time strings in the skins on multi-byte UTF-8 systems
|
||||
(reported by Sergey Chernyavskiy).
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2019-03-12: Version 2.4.1
|
||||
|
||||
- Changes for ncurses version 6 (thanks to Ulrick Eckhardt).
|
||||
|
||||
2020-05-11: Version 2.4.2
|
||||
|
||||
- Fixed 'Changes for ncurses version 6'.
|
||||
- Reacting to changes in screen size.
|
||||
- Simplified color handling.
|
||||
- Using 'stdscr' directly instead of an additional window.
|
||||
|
||||
2021-07-01: Version 2.4.3
|
||||
|
||||
- The number of errors (if any) of a recording is now displayed in the recording's
|
||||
Info menu.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.18 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
LOCDIR = $(call PKGCFG,locdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
@ -62,7 +63,8 @@ all: $(SOFILE) i18n
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -82,13 +84,16 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU
|
||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||
|
||||
%.mo: %.po
|
||||
msgfmt -c -o $@ $<
|
||||
@echo MO $@
|
||||
$(Q)msgfmt -c -o $@ $<
|
||||
|
||||
$(I18Npot): $(wildcard *.c)
|
||||
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||
@echo GT $@
|
||||
$(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
|
||||
|
||||
%.po: $(I18Npot)
|
||||
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@echo PO $@
|
||||
$(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
|
||||
@touch $@
|
||||
|
||||
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
|
||||
@ -102,7 +107,8 @@ install-i18n: $(I18Nmsgs)
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lncursesw -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -lncursesw -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Klaus Schmidinger <vdr@tvdr.de>, 2007
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 0.1.12\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2007-08-15 16:07+0200\n"
|
||||
"Last-Translator: Klaus Schmidinger <vdr@tvdr.de>\n"
|
||||
"Language-Team: German <vdr@linuxtv.org>\n"
|
||||
@ -19,11 +19,15 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Eine reine Text-Oberfläche"
|
||||
|
||||
msgid "errors"
|
||||
msgstr "Fehler"
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Stumm"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Lautstärke"
|
||||
msgstr "Lautstärke "
|
||||
|
||||
msgid "Text mode"
|
||||
msgstr "Text-Modus"
|
||||
|
33
PLUGINS/src/skincurses/po/et_EE.po
Normal file
33
PLUGINS/src/skincurses/po/et_EE.po
Normal file
@ -0,0 +1,33 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Arthur Konovalov <artlov@gmail.com>, 2015
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2007-08-14 20:48+0300\n"
|
||||
"Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
|
||||
"Language-Team: Estonian <vdr@linuxtv.org>\n"
|
||||
"Language: et\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "A text only skin"
|
||||
msgstr "Tekstipõhine kest"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Hääletu"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Helitugevus "
|
||||
|
||||
msgid "Text mode"
|
||||
msgstr "Tekst"
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>, 2007
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 0.1.12\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2007-08-14 20:48+0300\n"
|
||||
"Last-Translator: Rolf Ahrenberg <Rolf.Ahrenberg@sci.fi>\n"
|
||||
"Language-Team: Finnish <vdr@linuxtv.org>\n"
|
||||
@ -19,9 +19,13 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Tekstipohjainen ulkoasu"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Mykistys"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Äänenvoimakkuus "
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Diego Pierotto <vdr-italian@tiscali.it>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 0.1.12\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2008-01-27 20:35+0100\n"
|
||||
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
|
||||
"Language-Team: Italian <vdr@linuxtv.org>\n"
|
||||
@ -19,9 +19,13 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Una interfaccia solo testo"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Muto"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Volume "
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Valdemaras Pipiras <varas@ambernet.lt>, 2010
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 0.1.12\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2010-02-22 18:18+0200\n"
|
||||
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
|
||||
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
|
||||
@ -19,9 +19,13 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Tekstinis apvalkalas"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Išjungti garsą"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Garsas "
|
||||
|
||||
|
35
PLUGINS/src/skincurses/po/pl_PL.po
Normal file
35
PLUGINS/src/skincurses/po/pl_PL.po
Normal file
@ -0,0 +1,35 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Tomasz Maciej Nowak <tmn505@gmail.com>, 2018
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2018-02-19 01:02+0100\n"
|
||||
"Last-Translator: Tomasz Maciej Nowak <tmn505@gmail.com>\n"
|
||||
"Language-Team: Polish <vdr@linuxtv.org>\n"
|
||||
"Language: pl_PL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
|
||||
msgid "A text only skin"
|
||||
msgstr "Skóra tekstowa"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Wycisz"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Głośność "
|
||||
|
||||
msgid "Text mode"
|
||||
msgstr "Tryb tekstowy"
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Alexander Gross <Bikalexander@gmail.com>, 2008
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 0.1.12\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2008-03-14 00:21+0100\n"
|
||||
"Last-Translator: Alexander Gross <Bikalexander@gmail.com>\n"
|
||||
"Language-Team: Russian <vdr@linuxtv.org>\n"
|
||||
@ -20,11 +20,15 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "¿àÞáâÞ âÕÚáâÞÒëÙ ØÝâÕàäÕÙá"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "²ëÚÛ. ÓàÞÜÚÞáâì"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "³àÞÜÚÞáâì"
|
||||
msgstr "³àÞÜÚÞáâì "
|
||||
|
||||
msgid "Text mode"
|
||||
msgstr "ÀÕÖØÜ âÕÚáâÐ"
|
||||
|
@ -1,13 +1,13 @@
|
||||
# VDR plugin language source file.
|
||||
# Copyright (C) 2013 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# Copyright (C) 2021 Klaus Schmidinger <vdr@tvdr.de>
|
||||
# This file is distributed under the same license as the VDR package.
|
||||
# Klaus Schmidinger <vdr@tvdr.de>, 2007
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: vdr-skincurses 0.1.12\n"
|
||||
"Project-Id-Version: vdr-skincurses 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <see README>\n"
|
||||
"POT-Creation-Date: 2012-12-18 14:04+0100\n"
|
||||
"POT-Creation-Date: 2021-07-01 17:28+0200\n"
|
||||
"PO-Revision-Date: 2009-09-30 12:52+0100\n"
|
||||
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
|
||||
"Language-Team: Slovak <vdr@linuxtv.org>\n"
|
||||
@ -19,11 +19,15 @@ msgstr ""
|
||||
msgid "A text only skin"
|
||||
msgstr "Iba text vzhµadu"
|
||||
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
|
||||
msgid "Key$Mute"
|
||||
msgstr "Stlmi» zvuk"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
msgstr "Hlasitos»"
|
||||
msgstr "Hlasitos» "
|
||||
|
||||
msgid "Text mode"
|
||||
msgstr "Textový re¾im"
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: skincurses.c 2.13 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: skincurses.c 5.1 2021/07/01 15:40:46 kls Exp $
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
@ -12,7 +12,7 @@
|
||||
#include <vdr/skins.h>
|
||||
#include <vdr/videodir.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.3";
|
||||
static const char *DESCRIPTION = trNOOP("A text only skin");
|
||||
static const char *MAINMENUENTRY = NULL;
|
||||
|
||||
@ -20,6 +20,7 @@ static const char *MAINMENUENTRY = NULL;
|
||||
|
||||
class cCursesFont : public cFont {
|
||||
public:
|
||||
virtual int Width(void) const { return 1; }
|
||||
virtual int Width(uint c) const { return 1; }
|
||||
virtual int Width(const char *s) const { return s ? Utf8StrLen(s) : 0; }
|
||||
virtual int Height(void) const { return 1; }
|
||||
@ -59,9 +60,7 @@ static int ScOsdHeight = 20;
|
||||
class cCursesOsd : public cOsd {
|
||||
private:
|
||||
WINDOW *savedRegion;
|
||||
WINDOW *window;
|
||||
enum { MaxColorPairs = 16 };
|
||||
int colorPairs[MaxColorPairs];
|
||||
cVector<int> colorPairs;
|
||||
void SetColor(int colorFg, int colorBg = clrBackground);
|
||||
public:
|
||||
cCursesOsd(int Left, int Top);
|
||||
@ -78,40 +77,34 @@ cCursesOsd::cCursesOsd(int Left, int Top)
|
||||
{
|
||||
savedRegion = NULL;
|
||||
|
||||
memset(colorPairs, 0x00, sizeof(colorPairs));
|
||||
start_color();
|
||||
leaveok(stdscr, true);
|
||||
refresh(); // to react on changes to screen size
|
||||
|
||||
window = subwin(stdscr, ScOsdHeight, ScOsdWidth, 0, 0);
|
||||
syncok(window, true);
|
||||
int begy, begx;
|
||||
int maxy, maxx;
|
||||
getmaxyx(stdscr, maxy, maxx);
|
||||
getbegyx(stdscr, begy, begx);
|
||||
ScOsdWidth = maxx - begx;
|
||||
ScOsdHeight = maxy - begy;
|
||||
}
|
||||
|
||||
cCursesOsd::~cCursesOsd()
|
||||
{
|
||||
if (window) {
|
||||
werase(window);
|
||||
Flush();
|
||||
delwin(window);
|
||||
window = NULL;
|
||||
}
|
||||
erase();
|
||||
Flush();
|
||||
}
|
||||
|
||||
void cCursesOsd::SetColor(int colorFg, int colorBg)
|
||||
{
|
||||
int color = (colorBg << 16) | colorFg | 0x80000000;
|
||||
for (int i = 0; i < MaxColorPairs; i++) {
|
||||
if (!colorPairs[i]) {
|
||||
colorPairs[i] = color;
|
||||
init_pair(i + 1, colorFg, colorBg);
|
||||
//XXX??? attron(COLOR_PAIR(WHITE_ON_BLUE));
|
||||
wattrset(window, COLOR_PAIR(i + 1));
|
||||
break;
|
||||
}
|
||||
else if (color == colorPairs[i]) {
|
||||
wattrset(window, COLOR_PAIR(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i = colorPairs.IndexOf(color);
|
||||
if (i < 0) {
|
||||
colorPairs.Append(color);
|
||||
i = colorPairs.Size() - 1;
|
||||
init_pair(i + 1, colorFg, colorBg);
|
||||
}
|
||||
attrset(COLOR_PAIR(i + 1));
|
||||
}
|
||||
|
||||
void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
|
||||
@ -121,13 +114,14 @@ void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
|
||||
savedRegion = NULL;
|
||||
}
|
||||
savedRegion = newwin(y2 - y1 + 1, x2 - x1 + 1, y1, x1);
|
||||
copywin(window, savedRegion, y1, x1, 0, 0, y2 - y1, x2 - x1, false);
|
||||
if (savedRegion)
|
||||
copywin(stdscr, savedRegion, y1, x1, 0, 0, y2 - y1, x2 - x1, false);
|
||||
}
|
||||
|
||||
void cCursesOsd::RestoreRegion(void)
|
||||
{
|
||||
if (savedRegion) {
|
||||
copywin(savedRegion, window, 0, 0, savedRegion->_begy, savedRegion->_begx, savedRegion->_maxy - savedRegion->_begy, savedRegion->_maxx - savedRegion->_begx, false);
|
||||
overwrite(savedRegion, stdscr);
|
||||
delwin(savedRegion);
|
||||
savedRegion = NULL;
|
||||
}
|
||||
@ -167,18 +161,22 @@ void cCursesOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Co
|
||||
}
|
||||
}
|
||||
SetColor(ColorFg, ColorBg);
|
||||
wmove(window, y, x); // ncurses wants 'y' before 'x'!
|
||||
waddnstr(window, s, Width ? Width : ScOsdWidth - x);
|
||||
mvaddnstr(y, x, s, Width ? Width : ScOsdWidth - x);
|
||||
}
|
||||
|
||||
void cCursesOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
|
||||
{
|
||||
SetColor(Color, Color);
|
||||
for (int y = y1; y <= y2; y++) {
|
||||
wmove(window, y, x1); // ncurses wants 'y' before 'x'!
|
||||
whline(window, ' ', x2 - x1 + 1);
|
||||
}
|
||||
wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
if (dx >= dy) {
|
||||
for (int y = y1; y <= y2; y++)
|
||||
mvhline(y, x1, ' ', dx + 1);
|
||||
}
|
||||
else {
|
||||
for (int x = x1; x <= x2; x++)
|
||||
mvvline(y1, x, ' ', dy + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cCursesOsd::Flush(void)
|
||||
@ -407,8 +405,7 @@ void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event)
|
||||
return;
|
||||
int y = 2;
|
||||
cTextScroller ts;
|
||||
char t[32];
|
||||
snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
|
||||
cString t = cString::sprintf("%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
|
||||
ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
|
||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||
cString buffer = cString::sprintf(" VPS: %s", *Event->GetVpsString());
|
||||
@ -450,9 +447,18 @@ void cSkinCursesDisplayMenu::SetRecording(const cRecording *Recording)
|
||||
cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : "");
|
||||
ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
|
||||
y += ts.Height();
|
||||
int xt = ScOsdWidth;
|
||||
if (Info->GetEvent()->ParentalRating()) {
|
||||
cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
|
||||
osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font);
|
||||
int w = Utf8StrLen(buffer);
|
||||
osd->DrawText(xt - w, y, buffer, clrBlack, clrYellow, &Font);
|
||||
xt -= w + 1;
|
||||
}
|
||||
if (Info->Errors() > 0) {
|
||||
cString buffer = cString::sprintf(" %d %s ", Info->Errors(), tr("errors"));
|
||||
int w = Utf8StrLen(buffer);
|
||||
osd->DrawText(xt - w, y, buffer, clrBlack, clrYellow, &Font);
|
||||
xt -= w + 1;
|
||||
}
|
||||
y += 1;
|
||||
const char *Title = Info->Title();
|
||||
@ -614,6 +620,7 @@ void cSkinCursesDisplayVolume::SetVolume(int Current, int Total, bool Mute)
|
||||
osd->DrawText(0, 0, tr("Key$Mute"), clrGreen, clrBackground, &Font);
|
||||
}
|
||||
else {
|
||||
// TRANSLATORS: note the trailing blank!
|
||||
const char *Prompt = tr("Volume ");
|
||||
int l = Utf8StrLen(Prompt);
|
||||
int p = (ScOsdWidth - l) * Current / Total;
|
||||
@ -826,12 +833,8 @@ bool cPluginSkinCurses::ProcessArgs(int argc, char *argv[])
|
||||
bool cPluginSkinCurses::Initialize(void)
|
||||
{
|
||||
// Initialize any background activities the plugin shall perform.
|
||||
WINDOW *w = initscr();
|
||||
if (w) {
|
||||
ScOsdWidth = w->_maxx - w->_begx + 1;
|
||||
ScOsdHeight = w->_maxy - w->_begy + 1;
|
||||
if (initscr())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -60,3 +60,26 @@ VDR Plugin 'status' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2025-02-10: Version 2.6.1
|
||||
|
||||
- Added cStatus::OsdItem2().
|
||||
- Activated logging of OsdItem2().
|
||||
- Added cStatus::OsdCurrentItem2().
|
||||
- Added cStatus::OsdStatusMessage2().
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.15 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
@ -61,7 +62,8 @@ all: $(SOFILE)
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -75,7 +77,8 @@ $(DEPFILE): Makefile
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,13 +3,13 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: status.c 2.4 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: status.c 5.4 2025/02/12 21:18:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include <vdr/plugin.h>
|
||||
#include <vdr/status.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.6.1";
|
||||
static const char *DESCRIPTION = "Status monitor test";
|
||||
static const char *MAINMENUENTRY = NULL;
|
||||
|
||||
@ -27,10 +27,10 @@ protected:
|
||||
virtual void SetSubtitleTrack(int Index, const char * const *Tracks);
|
||||
virtual void OsdClear(void);
|
||||
virtual void OsdTitle(const char *Title);
|
||||
virtual void OsdStatusMessage(const char *Message);
|
||||
virtual void OsdStatusMessage2(eMessageType Type, const char *Message);
|
||||
virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue);
|
||||
virtual void OsdItem(const char *Text, int Index);
|
||||
virtual void OsdCurrentItem(const char *Text);
|
||||
virtual void OsdItem2(const char *Text, int Index, bool Selectable);
|
||||
virtual void OsdCurrentItem2(const char *Text, int Index);
|
||||
virtual void OsdTextItem(const char *Text, bool Scroll);
|
||||
virtual void OsdChannel(const char *Text);
|
||||
virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
|
||||
@ -86,9 +86,9 @@ void cStatusTest::OsdTitle(const char *Title)
|
||||
dsyslog("status: cStatusTest::OsdTitle '%s'", Title);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdStatusMessage(const char *Message)
|
||||
void cStatusTest::OsdStatusMessage2(eMessageType Type, const char *Message)
|
||||
{
|
||||
dsyslog("status: cStatusTest::OsdStatusMessage '%s'", Message);
|
||||
dsyslog("status: cStatusTest::OsdStatusMessage2 %d '%s'", Type, Message);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||
@ -96,14 +96,14 @@ void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Ye
|
||||
dsyslog("status: cStatusTest::OsdHelpKeys %s - %s - %s - %s", Red, Green, Yellow, Blue);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdItem(const char *Text, int Index)
|
||||
void cStatusTest::OsdItem2(const char *Text, int Index, bool Selected)
|
||||
{
|
||||
//dsyslog("status: cStatusTest::OsdItem %s %d", Text, Index);
|
||||
dsyslog("status: cStatusTest::OsdItem2 %s %d %d", Text, Index, Selected);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdCurrentItem(const char *Text)
|
||||
void cStatusTest::OsdCurrentItem2(const char *Text, int Index)
|
||||
{
|
||||
dsyslog("status: cStatusTest::OsdCurrentItem %s", Text);
|
||||
dsyslog("status: cStatusTest::OsdCurrentItem %s %d", Text, Index);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdTextItem(const char *Text, bool Scroll)
|
||||
|
@ -25,3 +25,19 @@ VDR Plugin 'svdrpdemo' Revision History
|
||||
2013-03-31: Version 2.0.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2014-01-01: Version 2.1.1
|
||||
|
||||
- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
|
||||
|
||||
2015-02-19: Version 2.2.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2018-04-15: Version 2.4.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for a Video Disk Recorder plugin
|
||||
#
|
||||
# $Id: Makefile 2.15 2013/01/12 13:45:01 kls Exp $
|
||||
# $Id: Makefile 4.3 2020/06/22 15:08:46 kls Exp $
|
||||
|
||||
# The official name of this plugin.
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
@ -16,7 +16,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
|
||||
### The directory environment:
|
||||
|
||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
|
||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr))
|
||||
LIBDIR = $(call PKGCFG,libdir)
|
||||
PLGCFG = $(call PKGCFG,plgcfg)
|
||||
#
|
||||
@ -61,7 +62,8 @@ all: $(SOFILE)
|
||||
### Implicit rules:
|
||||
|
||||
%.o: %.c
|
||||
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
@echo CC $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
### Dependencies:
|
||||
|
||||
@ -75,7 +77,8 @@ $(DEPFILE): Makefile
|
||||
### Targets:
|
||||
|
||||
$(SOFILE): $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
@echo LD $@
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
|
||||
|
||||
install-lib: $(SOFILE)
|
||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.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
|
||||
|
@ -3,12 +3,12 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: svdrpdemo.c 2.3 2013/03/31 09:30:18 kls Exp $
|
||||
* $Id: svdrpdemo.c 4.1 2018/04/10 13:01:07 kls Exp $
|
||||
*/
|
||||
|
||||
#include <vdr/plugin.h>
|
||||
|
||||
static const char *VERSION = "2.0.0";
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *DESCRIPTION = "How to add SVDRP support to a plugin";
|
||||
|
||||
class cPluginSvdrpdemo : public cPlugin {
|
||||
|
6
README
6
README
@ -4,7 +4,7 @@ Video Disk Recorder ('VDR')
|
||||
These files contain the source code of the "Video Disk Recorder",
|
||||
which is based on the DVB driver of the LinuxTV project (http://linuxtv.org).
|
||||
For details about the "Video Disk Recorder" project please
|
||||
refer to http://www.tvdr.de.
|
||||
refer to https://www.tvdr.de.
|
||||
|
||||
Please see the INSTALL file for details on how to install
|
||||
this program on your computer.
|
||||
@ -32,6 +32,10 @@ of commercial set-top boxes usually are a lot more fancy than
|
||||
the ones in this system, but here we have the full source code
|
||||
and can modify the menus in whatever way desired.
|
||||
|
||||
If you actually use VDR, please add yourself to the "VDR User Counter"
|
||||
at https://www.tvdr.de/counter.htm. You can also like VDR on facebook
|
||||
at https://www.facebook.com/VideoDiskRecorder.
|
||||
|
||||
|
||||
"VDR Video Disk Recorder" is a registered trademark of Klaus Schmidinger.
|
||||
"TVDR TV Done Right" is a registered trademark of Klaus Schmidinger.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user